Scripting Automated Acquisitions

Note: Running Asynchronous Code

The Open Beam Interface software makes extensive use of asyncio. Any code that moves data to or from the OBI must be run in an asynchronous context:

import asyncio

async def main():
    ...

asyncio.run(main())

Opening a Connection to OBI

With Direct Access

from obi.transfer import GlasgowConnection

conn = GlasgowConnection()

With Server Access

In order to run scripts that communicate with OBI via the TCP server, you will need to launch the server with pdm run server. The server endpoint can be configured.

from obi.transfer import TCPConnection

# TCP server must be running at this port
conn = TCPConnection('localhost', 2224)

Acquiring an Image

Initialize a Frame Buffer:

fb = FrameBuffer(conn)

Define a DAC Range: In this example, we will use the same DAC range for the X and Y directions.

arange = DACCodeRange.from_resolution(2048)

Capture a frame with desired parameters:

frame = await fb.capture_frame(x_range=arange, y_range=arange, dwell_time=10)

In this example, the resulting scan will traverse the full output range of the X and Y DACs in 2048 discrete steps, stopping at each pixel for 10 cycles of 125 ns for a total of 1250 ns. The full scan will take 2.56 ms.

Putting it all together

import asyncio

from obi.transfer import GlasgowConnection
from obi.macros import FrameBuffer
from obi.commands import DACCodeRange

async def main():
    # Open Connection
    conn = GlasgowConnection()
    # Create Frame Buffer
    fb = FrameBuffer(conn)
    # Create DAC range
    arange = DACCodeRange.from_resolution(2048)
    # Capture frame with parameters
    frame = await fb.capture_frame(x_range=arange, y_range=arange, dwell_time=10)

if __name__ == "__main__":
    asyncio.run(main())