TrigCounter.py 4.18 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# -*- coding: utf-8 -*-
#
# This file is part of the bliss project
#
# Copyright (c) 2016 Beamline Control Unit, ESRF
# Distributed under the GNU LGPLv3. See LICENSE for more info.

"""
YAML_ configuration example:

.. code-block:: yaml
    - class: TrigCounter
      package: pel.TrigCounter
      name: interf
      trigger_device:
          type: opiom
          name: $OPIOM_NAME
          counter_number: 1     # CNT 1
"""
import gevent
from bliss.common.measurement import IntegratingCounter
from bliss.config.settings import HashSetting
from bliss.scanning.chain import AcquisitionMaster

bliss administrator's avatar
bliss administrator committed
25

26 27
class TrigCounter(IntegratingCounter):
    def __init__(self, name, config):
bliss administrator's avatar
bliss administrator committed
28

29
        IntegratingCounter.__init__(self, name, None, self)
bliss administrator's avatar
bliss administrator committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

        trig_config = config["trigger_device"]

        self._opiom_card = trig_config.get("name")
        self._opiom_counter = trig_config.get("counter_number", 1)  # default 1
        high_time = trig_config.get("high_time", 1)
        period = trig_config.get("period", 1)
        nb_pulses = trig_config.get("nb_pulses", 1)

        self.__trigger_clock = config.get("_clock", 2000000)

        self._counter_config = HashSetting(
            "%s:counter_config" % self.name,
            default_values={
                "high_time": high_time,
                "period": period,
                "nb_pulses": nb_pulses,
            },
        )

50 51 52
    @property
    def clock(self):
        return self.__trigger_clock
bliss administrator's avatar
bliss administrator committed
53

54 55 56 57 58
    @property
    def high_time(self):
        """
        High time in second for the pulse
        """
bliss administrator's avatar
bliss administrator committed
59 60
        return self._counter_config["high_time"]

61 62
    @high_time.setter
    def high_time(self, value):
bliss administrator's avatar
bliss administrator committed
63
        self._counter_config["high_time"] = value
64 65 66 67 68 69

    @property
    def period(self):
        """
        period in second for the pulse (high + low level)
        """
bliss administrator's avatar
bliss administrator committed
70 71
        return self._counter_config["period"]

72 73
    @period.setter
    def period(self, value):
bliss administrator's avatar
bliss administrator committed
74
        self._counter_config["period"] = value
75 76 77 78 79 80

    @property
    def nb_pulses(self):
        """
        Nb pulses generated when trigged
        """
bliss administrator's avatar
bliss administrator committed
81 82
        return self._counter_config["nb_pulses"]

83 84
    @nb_pulses.setter
    def nb_pulses(self, value):
bliss administrator's avatar
bliss administrator committed
85
        self._counter_config["nb_pulses"] = value
86 87 88 89 90

    def get_value(self, from_index=0):
        return [self.nb_pulses]

    def create_master_device(self, scan_pars, **settings):
bliss administrator's avatar
bliss administrator committed
91 92
        npoints = scan_pars.get("npoints", 1)
        count_time = scan_pars.get("count_time", 1)
93

bliss administrator's avatar
bliss administrator committed
94 95 96
        return _TrigCounterAcqMaster(
            self, self.name, npoints=npoints, count_time=count_time
        )
97 98

    def __repr__(self):
bliss administrator's avatar
bliss administrator committed
99 100 101
        params = " ".join(
            ["%s=%s" % (k, v) for k, v in self._counter_config.iteritems()]
        )
102 103
        return "TrigCounter %s: %s" % (self.name, params)

bliss administrator's avatar
bliss administrator committed
104

105 106
class _TrigCounterAcqMaster(AcquisitionMaster):
    def __init__(self, device, name, npoints=None, count_time=None):
bliss administrator's avatar
bliss administrator committed
107 108 109
        AcquisitionMaster.__init__(
            self, device, name, npoints=npoints, prepare_once=True, start_once=True
        )
110 111 112 113 114 115 116 117 118
        self._count_time = count_time

    def prepare(self):
        opiom = self.device._opiom_card
        counter = self.device._opiom_counter
        high_time = self.device.high_time * self.device.clock
        low_time = (self.device.period - self.device.high_time) * self.device.clock
        nb_pulses = self.device.nb_pulses
        opiom.comm("CNT %d RESET" % counter)
bliss administrator's avatar
bliss administrator committed
119 120 121
        opiom.comm(
            "CNT %d CLK2 PULSE %d %d %d" % (counter, high_time, low_time, nb_pulses)
        )
122 123 124

    def add_counter(self, counter):
        pass
bliss administrator's avatar
bliss administrator committed
125

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
    def start(self):
        if not self.parent:
            self.trigger()

    def stop(self):
        opiom = self.device._opiom_card
        counter = self.device._opiom_counter
        opiom.comm("#CNT %d STOP" % counter)

    def trigger(self):
        self.trigger_slaves()
        opiom = self.device._opiom_card
        counter = self.device._opiom_counter
        opiom.comm("CNT %d START" % counter)

    def wait_ready(self):
        opiom = self.device._opiom_card
        counter = self.device._opiom_counter
        comm = "?SCNT %d" % counter
        while True:
            running = opiom.comm(comm) == "RUN"
            if not running:
                break
            gevent.idle()