Skip to content

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 if prepare should be called only once per scan (bool)

  • start_once: a flag to tell if start 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 if prepare should be called only once per scan (bool)

  • start_once: a flag to tell if start 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 if prepare should be called only once per scan (bool)

  • start_once: a flag to tell if start 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 if prepare should be called only once per scan (bool)

  • start_once: a flag to tell if start 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

IntegratingCounterAcquisitionSlave

see IntegratingCounterAcquisitionSlave