Basic Usage

The Daq class allows a user to connect to the LCLS1 daq and control it. For this to work, the daq must be up and allocated.

The most important method is Daq.begin. This will connect, configure, and start running the daq all in one call. Daq.stop can be used to stop acquiring data without ending a run. Daq.begin can be called again to resume a stopped run. Daq.end_run will end the run.

Daq.state can be used to inspect what the daq is currently doing. It will return one of the following possibilities:

State

Meaning

Disconnected

We are not controlling the daq

Connected

We are controlling the daq

Configured

Connected, and configure has been called

Open

Configured, and we are in a run

Running

Open, and we are collecting data

I will step through the basic options for Daq.begin below. You can consult the full api docs for more information.

Creating a Daq object

First, I will set up the Daq class in simulated mode. In practice, the Daq class will be set up for you in the hutch-python configuration.

from pcdsdaq.daq import Daq
from pcdsdaq.sim import set_sim_mode

set_sim_mode(True)
daq = Daq()

Running Until Stop

Calling Daq.begin with no arguments in the default configuration will run the daq indefinitely, until we manually stop it. You can also use Daq.begin_infinite to run the daq indefinitely with any configuration. Here I check Daq.state to verify that we’ve started running the daq.

In [1]: daq.state
Out[1]: 'Disconnected'

In [2]: start = time.time()

In [3]: daq.begin()

In [4]: daq.state
Out[4]: 'Running'

In [5]: time.sleep(1)

In [6]: daq.stop()

In [7]: print(time.time() - start)
1.003800868988037

In [8]: daq.state
Out[8]: 'Open'

In [9]: daq.end_run()

In [10]: daq.state
Out[10]: 'Configured'

Running for a Fixed Number of Events

Use the events argument to specify duration in number of events. The duration of this run will depend on the current beam rate. Optionally, we can call Daq.wait to pause until acquisition is complete.

In [11]: daq.state
Out[11]: 'Configured'

In [12]: start = time.time()

In [13]: daq.begin(events=240)  # 120Hz

In [14]: daq.state
Out[14]: 'Running'

In [15]: daq.wait()

In [16]: print(time.time() - start)
2.998228073120117

In [17]: daq.state
Out[17]: 'Open'

In [18]: daq.end_run()

In [19]: daq.state
Out[19]: 'Configured'

Runing for a Fixed Time Duration

Use the duration argument to specify duration in seconds. We can pass wait=True to skip the Daq.wait call.

In [20]: daq.state
Out[20]: 'Configured'

In [21]: start = time.time()

In [22]: daq.begin(duration=1.5, wait=True)

In [23]: print(time.time() - start)
2.4984123706817627

In [24]: daq.state
Out[24]: 'Open'

In [25]: daq.end_run()

In [26]: daq.state
Out[26]: 'Configured'

Ending a Run

As seen in the previous examples, Daq.end_run can be used to tell the daq that the current run is over. You can also do with with an argument to Daq.begin for a nice one-liner:

In [27]: daq.state
Out[27]: 'Configured'

In [28]: daq.begin(duration=1, wait=True, end_run=True)

In [29]: daq.state
Out[29]: 'Configured'

Recording Data

You can set Daq.record to True to record data. This is fairly simple:

In [30]: daq.record = True

After this call, future calls to Daq.begin will record data to disk. You can undo this by simply setting:

In [31]: daq.record = False

You can also record data for a single run using a keyword argument in Daq.begin:

In [32]: daq.record
Out[32]: False

In [33]: daq.begin(events=120, record=True)

In [34]: daq.record
Out[34]: False

Advanced Options

  • use_l3t=True: This will reinterpret the events argument as

    “the number of events that pass the level 3 trigger.”

  • controls=[motor1, motor2...]: This will post the name of each motor and

    the current position to the daq data stream. This is handled automatically with some of the bluesky tools.

  • begin_sleep=0.25: This configuration argument will set the empirically

    derived sleep time needed after a call to begin that ensures the daq is actually ready. If a valid argument for time.sleep, this will wait to end a begin call until the configured sleep time elapses. This may be useful if you have other devices that rely on a run to actually start before doing some action.