Acquisition objects¶
This section describes the base classes available in BLISS to implement an acquisition object. More information about the role of these objects and their link with the scan acquisition chain can be found here.
Acquisition objects are bound to a device acting as a data producer. At each scan iteration
specific acquisition object’s methods are called (prepare
, start
, wait_ready
, stop
, …).
This methods must be implemented in order to describe data acquisition behavior and triggering workflow.
Gathered data are passed to AcquisitionChannel
objects that will take care of transmitting
data toward the live data container (e.g. REDIS).
AcquisitionObject
base class¶
The base class for all acquisition objects. Developers should not use this object
directly but start from AcquisitionMaster
or AcquisitionSlave
instead.
Signature (from bliss.scanning.chain)
class AcquisitionObject():
def __init__(self,
*devices,
name=None,
npoints=1,
trigger_type=TRIGGER_MODE_ENUM.SOFTWARE,
prepare_once=False,
start_once=False,
ctrl_params=None,):
-
devices
: list of input object(s) that will be managed during the scan, it could be:- an empty list
- a list of one CounterController or a list of counters
- a list of one Group of axes or an axes list
-
name
: a name (str) -
npoints
: a number of acquisition points (integer) -
trigger_type
: type of triggering (TRIGGER_MODE_ENUM: SOFTWARE or HARDWARE) -
prepare_once
: a flag to tell ifprepare
should be called only once per scan (bool) -
start_once
: a flag to tell ifstart
should be called only once per scan (bool) -
ctrl_params
: optional controller parameters (dict)
```
Properties
@property
def name(self):
""" Return object's name. If no name was given, it returns the device name.
For axes it returns 'axis' and for counters it returns the counters
controller name.
"""
@property
def npoints(self):
""" Return the number of acquisition points (integer). Usually it corresponds
to scan steps/iterations or number of expected measurements """
@property
def trigger_type(self):
""" Return the trigger type as a TRIGGER_MODE_ENUM (HARDWARE or SOFTWARE)"""
@property
def prepare_once(self):
""" A boolean flag to tell if the prepare method should be called only
once, at the first scan iteration.
"""
@property
def start_once(self):
""" A boolean flag to tell if the start method should be called only
once, at the first scan iteration.
"""
@property
def ctrl_params(self):
""" The completed controller parameters dictionary """
@property
def device(self):
""" The associated data producer device, either a counter controller, an axes
Group or None.
"""
@property
def parent(self):
""" Return the acquisition object above this one in the acquisition chain tree
Could be None if this object is at the root position in the acquisition chain.
This attribute is set by the chain when adding this object into the chain.
"""
@property
def channels(self):
""" The list of registered AcquisitionChannels """
Methods to override
def acq_prepare(self):
""" Called at the prepare phase of a scan iteration.
Called only once at first iteration if prepare_once == True.
Must call self.prepare().
"""
raise NotImplementedError
def acq_start(self):
""" Called at the start phase of a scan iteration.
Called only once at first iteration if start_once == True.
Must call self.start().
"""
raise NotImplementedError
def acq_stop(self):
""" Called at the end of a scan.
Must call self.stop().
"""
raise NotImplementedError
def prepare(self):
raise NotImplementedError
def start(self):
raise NotImplementedError
def stop(self):
raise NotImplementedError
def wait_ready(self):
""" block/wait until ready for next iteration """
pass
AcquisitionMaster
class¶
This object is designed for 2 purposes:
-
control data production of the associated device (with or without channels emission)
-
manage the triggering workflow along the acquisition chain tree (by triggering slaves)
Configure and control data production by implementing the prepare
, start
, trigger
and stop
methods.
Call trigger_slaves()
while implementing the trigger
method to call the trigger method on slave acquisition objects (objects below this object in the acquisition chain tree) that are using a SOFTWARE
trigger type.
Signature (from bliss.scanning.chain)
class AcquisitionMaster(AcquisitionObject):
def __init__(self,
*devices,
name=None,
npoints=1,
trigger_type=TRIGGER_MODE_ENUM.SOFTWARE,
prepare_once=False,
start_once=False,
ctrl_params=None,):
-
devices
: list of input object(s) that will be managed during the scan, it could be:- an empty list
- a list of one CounterController or a list of counters
- a list of one Group of axes or an axes list
-
name
: a name (str) -
npoints
: a number of acquisition points (integer) -
trigger_type
: type of triggering (TRIGGER_MODE_ENUM: SOFTWARE or HARDWARE) -
prepare_once
: a flag to tell ifprepare
should be called only once per scan (bool) -
start_once
: a flag to tell ifstart
should be called only once per scan (bool) -
ctrl_params
: optional controller parameters (dict)
```
Properties (see AcquisitionObject class for inherited properties)
@property
def slaves(self):
""" Return the list of acquisition object just below this one in the
acquisition chain tree.
"""
def trigger_slaves(self):
""" Call the 'acq_trigger' method on slaves using
trigger_type == TRIGGER_MODE_ENUM.SOFTWARE
"""
Methods to override
def prepare(self):
""" Prepare the associated device for the scanning procedure.
Called only once if prepare_once == True.
"""
raise NotImplementedError
def start(self):
""" Start data production on associated device or put the device
in a state ready for producing data on triggers (hardware or software).
Called only once if start_once == True.
"""
raise NotImplementedError
def stop(self):
""" Stop data production """
raise NotImplementedError
def wait_ready(self):
""" block/wait until ready for next scan iteration """
pass
def trigger(self):
""" Trigger device data production and eventually trigger slaves """
raise NotImplementedError
def trigger_ready(self):
""" Return if ready for next trigger """
return True
AcquisitionSlave
class¶
This object is designed for 2 purposes:
-
control data production of the associated device
-
gathering and emitting counters data by implementing the
reading
method
Configure and control data production by implementing the prepare
, start
, trigger
and stop
methods. If this device is associated to a master which already controls data production, implementing
the reading
method to poll the device and gather counters data could be enough.
Important note about the reading
method
If not already alive, thereading
method is automatically spawned in the acq_start
and acq_trigger
class methods.
Developers must take care of the acquisition channels data emission in the reading method (example self.channels.update_from_iterable(data)
).
Signature (from bliss.scanning.chain)
class AcquisitionSlave(AcquisitionObject):
def __init__(self,
*devices,
name=None,
npoints=1,
trigger_type=TRIGGER_MODE_ENUM.SOFTWARE,
prepare_once=False,
start_once=False,
ctrl_params=None,):
-
devices
: list of input object(s) that will be managed during the scan, it could be:- an empty list
- a list of one CounterController or a list of counters
- a list of one Group of axes or an axes list
-
name
: a name (str) -
npoints
: a number of acquisition points (integer) -
trigger_type
: type of triggering (TRIGGER_MODE_ENUM: SOFTWARE or HARDWARE) -
prepare_once
: a flag to tell ifprepare
should be called only once per scan (bool) -
start_once
: a flag to tell ifstart
should be called only once per scan (bool) -
ctrl_params
: optional controller parameters (dict)
```
Methods to override
def prepare(self):
""" Prepare the associated device for the scanning procedure.
Called only once if prepare_once == True.
"""
raise NotImplementedError
def start(self):
""" Start data production on associated device or put the device
in a state ready for producing data on triggers (hardware or software).
Called only once if start_once == True.
"""
raise NotImplementedError
def stop(self):
""" Stop data production """
raise NotImplementedError
def wait_ready(self):
""" block/wait until ready for next scan iteration """
pass
def trigger(self):
""" Trigger device data production and eventually trigger slaves """
raise NotImplementedError
def trigger_ready(self):
""" Return if ready for next trigger """
return True
def reading(self):
""" Access the device to gather counters data
It might be necessary to synchronized with triggering events
"""
pass
BaseCounterAcquisitionSlave
¶
A base class for SamplingCounterAcquisitionSlave
and IntegratingCounterAcquisitionSlave
.
Signature (from bliss.scanning.acquisition.counter)
class BaseCounterAcquisitionSlave(AcquisitionSlave):
def __init__(self,
*counters,
count_time=None,
npoints=1,
trigger_type=AcquisitionSlave.SOFTWARE,
prepare_once=False,
start_once=False,
ctrl_params=None,):
-
counters
: a list of one CounterController or a list of counters -
count_time
: the scan step counting time (float) -
npoints
: the scan steps number (integer) -
trigger_type
: type of triggering (TRIGGER_MODE_ENUM: SOFTWARE or HARDWARE) -
prepare_once
: a flag to tell ifprepare
should be called only once per scan (bool) -
start_once
: a flag to tell ifstart
should be called only once per scan (bool) -
ctrl_params
: optional controller parameters
Properties and methods
@staticmethod
def get_param_validation_schema():
""" An acquisition parameters validation scheme"""
acq_params_schema = {
"count_time": {"type": "numeric"},
"npoints": {"type": "int"},
}
schema = {"acq_params": {"type": "dict", "schema": acq_params_schema}}
return schema
@property
def npoints(self):
return self.__npoints
@property
def count_time(self):
return self.__count_time
def _emit_new_data(self, data):
self.channels.update_from_iterable(data)
Customizable methods (optional)
def prepare_device(self):
pass
def start_device(self):
pass
def stop_device(self):
pass
SamplingCounterAcquisitionSlave
¶
see SamplingCounterAcquisitionSlave