.. currentmodule:: sardana.pool.controller .. _sardana-1dcontroller-howto: ============================ How to write a 1D controller ============================ This chapter provides the necessary information to write a one dimensional (1D) experimental channel controller in Sardana. .. contents:: Table of contents :depth: 3 :backlinks: entry .. _sardana-1dcontroller-general-guide: General guide ------------- :ref:`1D experimental channels ` together with :ref:`2D experimental channels ` and :ref:`counter/timers ` belong to the same family of *timerable* experimental channels. To write a 1D controller class you can follow the :ref:`sardana-countertimercontroller` guide keeping in mind differences explained in continuation. .. _sardana-1dcontroller-general-guide-shape: Get 1D shape ~~~~~~~~~~~~ 1D controller should provide a shape of the spectrum which will be produced by acquisition. The shape can be either static e.g. defined by the detector's sensor size or dynamic e.g. depending on the detector's (or an intermediate control software layer e.g. `LImA`_) configuration like :term:`RoI` or binning. In any case you should provide the shape in the format of a one-element sequence with the length of the spectrum using the :meth:`~sardana.pool.controller.Controller.GetAxisPar` method. Here is an example of the possible implementation of :meth:`~sardana.pool.controller.Controller.GetAxisPar`: .. code-block:: python class SpringfieldOneDController(TwoDController): def GetAxisPar(self, axis, par): if par == "shape": return self.springfield.getShape(axis) For backwards compatibility, in case of not implementing the ``shape`` axis parameter, shape will be determined from the ``MaxDimSize`` of the ``Value`` attribute, currently (4096,). .. _sardana-1dcontroller-differences-countertimer: Differences with counter/timer controller ----------------------------------------- Class definition ~~~~~~~~~~~~~~~~ :ref:`The basics of the counter/timer controller ` chapter explains how to define the counter/timer controller class. Here you need to simply inherit from the `~sardana.pool.controller.OneDController` class: .. code-block:: python :emphasize-lines: 3 from sardana.pool.controller import OneDController class SpringfieldOneDController(OneDController): def __init__(self, inst, props, *args, **kwargs): super().__init__(inst, props, *args, **kwargs) .. _sardana-1dcontroller-getvalue: Get 1D value ~~~~~~~~~~~~ :ref:`Get counter value ` chapter explains how to read a counter/timer value using the :meth:`~sardana.pool.controller.Readable.ReadOne` method. Here you need to implement the same method but: * its return value must be a one-dimensional `numpy.array` (or eventually a `~sardana.sardanavalue.SardanaValue` object) containing the spectrum instead of a scalar value * sardana will not call :meth:`~sardana.pool.controller.Readable.ReadOne` at a given frequency during the acquisition to get the still changing result .. _sardana-1dcontroller-getvalues: Get 1D values ~~~~~~~~~~~~~ :ref:`Get counter values ` chapter explains how to read counter/timer values using the :meth:`~sardana.pool.controller.Readable.ReadOne` method while acquiring with external (hardware) synchronization. Here you need to implement the same method but its return value must be a sequence with one-dimensional `numpy.array` objects (or eventually with :obj:`~sardana.sardanavalue.SardanaValue` objects) containing spectrums instead of scalar values. Advanced topics --------------- .. _sardana-1dcontroller-valuereferencing: Working with value referencing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1D experimental channels may produce significant arrays of data at high frame rate. Reading this data and storing it using sardana is not always optimal. `SEP2`_ introduced data saving duality, optionally, leaving the data storage at the responsibility of the detector (or an intermediate software layer e.g. `LImA`_). In this case sardana just deals with the reference to the data. Please refer to :ref:`sardana-2dcontroller-valuereferencing` chapter from :ref:`sardana-2dcontroller-howto` guide in order to implement this feature for 1D controller. .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ .. _SEP2: http://www.sardana-controls.org/sep/?SEP2.md .. _LImA: https://lima1.readthedocs.io/en/latest/