Esempio n. 1
0
class tango_keithley(SamplingCounter):
    def __init__(self, name, config):
        SamplingCounter.__init__(self, name, None)
        tango_uri = config["uri"]
        self.__control = DeviceProxy(tango_uri)

    def read(self):
        self.__control.MeasureSingle()
        self.__control.WaitAcq()
        value = self.__control.ReadData
        if isinstance(value, numpy.ndarray):
            value = value[0]
        return value

    def autorange(self, autorange_on=None):
        if autorange_on is None:
            return self.__control.autorange
        else:
            self.__control.autorange = autorange_on

    def autozero(self, autozero_on=None):
        if autozero_on is None:
            return self.__control.autozero
        else:
            self.__control.autozero = autozero_on

    def init(self):
        return self.__control.init()
Esempio n. 2
0
    def __init__(self, *args, **kwargs):
        Controller.__init__(self, *args, **kwargs)

        self._axis_moves = {}

        self.factor = 1

        # config
        _target_attribute_name = self.config.get("target_attribute")
        _gating_ds = self.config.get("gating_ds")

        try:
            self.target_attribute = AttributeProxy(_target_attribute_name)
        except:
            elog.error("Unable to connect to attrtribute %s " %
                       _target_attribute_name)

        # External DS to use for gating.
        # ex: PI-E517 for zap of HPZ.
        if _gating_ds is not None:
            self.gating_ds = DeviceProxy(_gating_ds)
            self.external_gating = True
            elog.info("external gating True ; gating ds= %s " % _gating_ds)
        else:
            # No external gating by default.
            self.external_gating = False

        # _pos0 must be in controller unit.
        self._pos0 = self.target_attribute.read().value * self.factor
        elog.info("initial position : %g (in ctrl units)" % self._pos0)
Esempio n. 3
0
 def __init__(self, name, config):
     tango_uri = config.get("uri")
     self.__control = DeviceProxy(tango_uri)
     try:
         self.manual = config.get("attr_mode")
     except:
         self.manual = False
Esempio n. 4
0
    def read_all(self, *counters):
        if self._control is None:
            self._control = DeviceProxy(self._tango_uri)

        dev_attrs = self._control.read_attributes(
            [cnt.attribute for cnt in counters])
        #Check error
        for attr in dev_attrs:
            error = attr.get_err_stack()
            if error:
                raise PyTango.DevFailed(*error)

        return [dev_attr.value for dev_attr in dev_attrs]
Esempio n. 5
0
    def __init__(self,name,config_tree):
        """Lima controller.

        name -- the controller's name
        config_tree -- controller configuration
        in this dictionary we need to have:
        tango_url -- tango main device url (from class LimaCCDs)
        """
        self._proxy = DeviceProxy(config_tree.get("tango_url"))
        self.name = name
        self.__bpm = None
        self.__roi_counters = None
        self._camera = None
        self._image = None
        self._acquisition = None
Esempio n. 6
0
   def __init__(self, name, config):
       self.name = name
       self.__counters_grouped_read_handler = BpmGroupedReadHandler(self)

       tango_uri = config.get("uri")
       tango_lima_uri = config.get("lima_uri")
       foil_actuator_name = config.get("foil_name")

       self.__control = DeviceProxy(tango_uri)
       if tango_lima_uri:
           self.__lima_control = DeviceProxy(tango_lima_uri)
       else:
           self.__lima_control = None
       self._acquisition_event = event.Event()
       self._acquisition_event.set()
       self.__diode_actuator = None
       self.__led_actuator = None
       self.__foil_actuator  = None

       bpm_properties = self.__control.get_property_list('*')

       if 'wago_ip' in bpm_properties:
           self.__diode_actuator = Actuator(self.__control.In, 
                                            self.__control.Out,
                                            lambda: self.__control.YagStatus == "in",
                                            lambda: self.__control.YagStatus == "out")
           self.__led_actuator  = Actuator(self.__control.LedOn,
                                           self.__control.LedOff,
                                           lambda: self.__control.LedStatus > 0)
           def diode_current(*args):
               return BpmDiodeCounter("diode_current", self, self.__control)
           add_property(self, "diode_current", diode_current)
           def diode_actuator(*args):
               return self.__diode_actuator
           add_property(self, "diode", diode_actuator)
           def led_actuator(*args):
               return self.__led_actuator
           add_property(self, "led", led_actuator)
       if 'has_foils' in bpm_properties:
           self.__foil_actuator  = Actuator(self.__control.FoilIn,
                                            self.__control.FoilOut,
                                            lambda: self.__control.FoilStatus == "in",
                                            lambda: self.__control.FoilStatus == "out")
           def foil_actuator(*args):
               return self.__foil_actuator
           if not foil_actuator_name:
               foil_actuator_name = 'foil'
           add_property(self, foil_actuator_name, foil_actuator)
Esempio n. 7
0
 def __init__(self, name, config):
    tango_uri = config.get("uri")
    self.__control = DeviceProxy(tango_uri)
    try:
       self.manual = config.get("attr_mode")
    except:
       self.manual = False
Esempio n. 8
0
class tango_keithley(SamplingCounter):
    def __init__(self, name, config):
        SamplingCounter.__init__(self, name, None)
        tango_uri = config["uri"]
        self.__control = DeviceProxy(tango_uri)

    def read(self):
        self.__control.MeasureSingle()
        self.__control.WaitAcq()
        value = self.__control.ReadData
        if isinstance(value,  numpy.ndarray):
            value = value[0]
        return value

    def autorange(self, autorange_on=None):
        if autorange_on is None:
            return self.__control.autorange   
        else:
            self.__control.autorange = autorange_on

    def autozero(self, autozero_on=None):
        if autozero_on is None:
            return self.__control.autozero
        else:
            self.__control.autozero = autozero_on

    def init(self):
        return self.__control.init()
Esempio n. 9
0
class DeviceStatus(object):

    attributes = ()

    def __init__(self, device, attributes=None):
        if attributes is not None:
            self.attributes = attributes
        self.device = DeviceProxy(device)

    def __call__(self, cli):
        n = len(self.attributes)
        try:
            values = self.device.read_attributes([a.attr_name
                                                  for a in self.attributes])
        except Exception as e:
            values = n*[None]
        result = []
        for i, (attr, value) in enumerate(zip(self.attributes, values)):
            if i > 0:
                result.append(Separator)
            token, value = tango_value(attr, value)
            if cli.python_input.bliss_bar_format != 'compact':
                result.append((StatusToken, attr.label))
            value = '{0}{1}'.format(value, attr.unit)
            result.append((token, value))
        return result
Esempio n. 10
0
class _CtrGroupRead(object):
    def __init__(self,tango_uri):
        self._tango_uri = tango_uri
        self._control = None
        self._counter_names = list()

    @property
    def name(self):
        return ','.join(self._counter_names)

    def read_all(self,*counters):
        if self._control is None:
            self._control = DeviceProxy(self._tango_uri)

        dev_attrs = self._control.read_attributes([cnt.attribute for cnt in counters])
        #Check error
        for attr in dev_attrs:
            error = attr.get_err_stack()
            if error:
                raise PyTango.DevFailed(*error)

        return [dev_attr.value for dev_attr in dev_attrs]
    
    def add_counter(self,counter_name):
        self._counter_names.append(counter_name)
Esempio n. 11
0
class _CtrGroupRead(object):
    def __init__(self, tango_uri):
        self._tango_uri = tango_uri
        self._control = None
        self._counter_names = list()

    @property
    def name(self):
        return ','.join(self._counter_names)

    def read_all(self, *counters):
        if self._control is None:
            self._control = DeviceProxy(self._tango_uri)

        dev_attrs = self._control.read_attributes(
            [cnt.attribute for cnt in counters])
        #Check error
        for attr in dev_attrs:
            error = attr.get_err_stack()
            if error:
                raise PyTango.DevFailed(*error)

        return [dev_attr.value for dev_attr in dev_attrs]

    def add_counter(self, counter_name):
        self._counter_names.append(counter_name)
Esempio n. 12
0
    def __init__(self, dev_name, out_stream=sys.stdout, err_stream=sys.stderr):
        self.__dev = DeviceProxy(dev_name)
        self.__out_stream = out_stream
        self.__err_stream = err_stream
        self.__curr_cmd = None

        for cmd in ('execute', 'is_running', 'stop', 'init'):
            setattr(self, cmd, functools.partial(self.__dev.command_inout, cmd))
Esempio n. 13
0
def __tango_apply_config(name):
    try:
        device = DeviceProxy(name)
        device.command_inout("ApplyConfig", True)
        msg = "'%s' configuration saved and applied to server!" % name
        msg_type = "success"
    except PyTango.DevFailed as df:
        msg = "'%s' configuration saved but <b>NOT</b> applied to " \
              " server:\n%s" % (name, df[0].desc)
        msg_type = "warning"
        sys.excepthook(*sys.exc_info())
    except Exception as e:
        msg = "'%s' configuration saved but <b>NOT</b> applied to " \
              " server:\n%s" % (name, str(e))
        msg_type = "warning"
        sys.excepthook(*sys.exc_info())
    return msg, msg_type
Esempio n. 14
0
 def __init__(self, name, config):
     tango_uri = config.get("uri")
     self.__control = None
     try:
         self.__control = DeviceProxy(tango_uri)
     except PyTango.DevFailed, traceback:
         last_error = traceback[-1]
         print "%s: %s" % (tango_uri, last_error['desc'])
         self.__control = None
Esempio n. 15
0
 def _get_proxy(self,type_name):
     device_name = self._proxy.getPluginDeviceNameFromType(type_name)
     if not device_name:
         return
     if not device_name.startswith("//"):
         # build 'fully qualified domain' name
         # '.get_fqdn()' doesn't work
         db_host = self._proxy.get_db_host()
         db_port = self._proxy.get_db_port()
         device_name = "//%s:%s/%s" % (db_host, db_port, device_name)
     return DeviceProxy(device_name)
Esempio n. 16
0
    def read_all(self,*counters):
        if self._control is None:
            self._control = DeviceProxy(self._tango_uri)

        dev_attrs = self._control.read_attributes([cnt.attribute for cnt in counters])
        #Check error
        for attr in dev_attrs:
            error = attr.get_err_stack()
            if error:
                raise PyTango.DevFailed(*error)

        return [dev_attr.value for dev_attr in dev_attrs]
Esempio n. 17
0
class TangoDeviceServer:
    def __init__(self,cnt,**keys):
        self._logger = logging.getLogger(str(self))
        self._debug = self._logger.debug
        url = keys.pop('url')
        url_tocken = 'tango_gpib_device_server://'
        if not url.startswith(url_tocken):
            raise GpibError("Tango_Gpib_Device_Server: url is not valid (%s)" % url)
        self._tango_url = url[len(url_tocken):]
        self.name = self._tango_url
        self._proxy = None
        self._gpib_kwargs = keys
        self._pad = keys['pad']
        self._sad = keys.get('sad',0)
        self._pad_sad = self._pad + (self._sad << 8)
        
    def init(self):
        self._debug("TangoDeviceServer::init()")
        if self._proxy is None:
            self._proxy = DeviceProxy(self._tango_url)
        
    def close(self):
        self._proxy = None

    def ibwrt(self, cmd):
        self._debug("Sent: %s" % cmd)
        ncmd = numpy.zeros(4 + len(cmd),dtype=numpy.uint8)
        ncmd[3] = self._pad
        ncmd[2] = self._sad
        ncmd[4:] = [ord(x) for x in cmd]
        self._proxy.SendBinData(ncmd)

    def ibrd(self, length) :
        self._proxy.SetTimeout([self._pad_sad,self._gpib_kwargs.get('tmo',12)])
        msg = self._proxy.ReceiveBinData([self._pad_sad,length])
        self._debug("Received: %s" % msg)
        return msg.tostring()

    def _raw(self, length):
        return self.ibrd(length)
Esempio n. 18
0
 def __iter__(self):
     self._update()
     try:
         proxy = DeviceProxy(
             self.server_url) if self.server_url else None
     except Exception:
         proxy = None
     for image_nb in range(self.from_index, self.last_index):
         data = self._get_from_server_memory(proxy, image_nb)
         if data is None:
             yield self._get_from_file(image_nb)
         else:
             yield data
         self._update()
Esempio n. 19
0
    def initialize_encoder(self, encoder):
        self.encoder_proxy = DeviceProxy(self.ds_name)

        encoder.config.config_dict.update({"steps_per_unit": {"value": self.encoder_proxy.steps_per_unit}})
Esempio n. 20
0
class tango_bpm(object):
   def __init__(self, name, config):
       self.name = name
       self.__counters_grouped_read_handler = BpmGroupedReadHandler(self)

       tango_uri = config.get("uri")
       tango_lima_uri = config.get("lima_uri")
       foil_actuator_name = config.get("foil_name")

       self.__control = DeviceProxy(tango_uri)
       if tango_lima_uri:
           self.__lima_control = DeviceProxy(tango_lima_uri)
       else:
           self.__lima_control = None
       self._acquisition_event = event.Event()
       self._acquisition_event.set()
       self.__diode_actuator = None
       self.__led_actuator = None
       self.__foil_actuator  = None

       bpm_properties = self.__control.get_property_list('*')

       if 'wago_ip' in bpm_properties:
           self.__diode_actuator = Actuator(self.__control.In, 
                                            self.__control.Out,
                                            lambda: self.__control.YagStatus == "in",
                                            lambda: self.__control.YagStatus == "out")
           self.__led_actuator  = Actuator(self.__control.LedOn,
                                           self.__control.LedOff,
                                           lambda: self.__control.LedStatus > 0)
           def diode_current(*args):
               return BpmDiodeCounter("diode_current", self, self.__control)
           add_property(self, "diode_current", diode_current)
           def diode_actuator(*args):
               return self.__diode_actuator
           add_property(self, "diode", diode_actuator)
           def led_actuator(*args):
               return self.__led_actuator
           add_property(self, "led", led_actuator)
       if 'has_foils' in bpm_properties:
           self.__foil_actuator  = Actuator(self.__control.FoilIn,
                                            self.__control.FoilOut,
                                            lambda: self.__control.FoilStatus == "in",
                                            lambda: self.__control.FoilStatus == "out")
           def foil_actuator(*args):
               return self.__foil_actuator
           if not foil_actuator_name:
               foil_actuator_name = 'foil'
           add_property(self, foil_actuator_name, foil_actuator)

   @property
   def tango_proxy(self):
       return self.__control

   @property
   def x(self):
     return BpmCounter("x", self, 2, grouped_read_handler=self.__counters_grouped_read_handler)

   @property
   def y(self):
     return BpmCounter("y", self, 3, grouped_read_handler=self.__counters_grouped_read_handler)

   @property
   def intensity(self):
     return BpmCounter("intensity", self, 1, grouped_read_handler=self.__counters_grouped_read_handler)

   @property
   def fwhm_x(self):
     return BpmCounter("fwhm_x", self, 4, grouped_read_handler=self.__counters_grouped_read_handler)
 
   @property
   def fwhm_y(self):
     return BpmCounter("fwhm_y", self, 5, grouped_read_handler=self.__counters_grouped_read_handler)

   @property
   def image(self):
     return BpmImage(self, grouped_read_handler=self.__counters_grouped_read_handler)

   @property 
   def exposure_time(self):
     return self.__control.ExposureTime 

   def set_exposure_time(self, exp_time):
     self.__control.ExposureTime = exp_time
   
   @property 
   def diode_range(self):
     return  self.__control.DiodeRange
   
   def set_diode_range(self, range):
     self.__control.DiodeRange = range

   def live(self, video=False):
     if video and self.__lima_control:
         self.__lima_control.video_live = True
     else:
         return self.__control.Live()

   def is_acquiring(self):
       return str(self.__control.State()) == 'MOVING'

   def is_live(self):
       return str(self.__control.LiveState) == 'RUNNING'

   def is_video_live(self):
       return self.__lima_control and self.__lima_control.video_live

   def stop(self, video=False):
     if video and self.__lima_control:
         self.__lima_control.video_live = False
     else:
         self.__control.Stop()      

   def set_in(self):
     return self.__control.In()

   def set_out(self):
     return self.__control.Out()

   def is_in(self):
     return self.__control.YagStatus == 'in'
 
   def is_out(self):
     return self.__control.YagStatus == 'out'

   def save_images(self, save):
     if save:
         scan_saving = ScanSaving()
         directory = scan_saving.get_path()
         image_acq_counter_setting = SimpleSetting(self.name + ".image", None, int, int, default_value=0)
         image_acq_counter_setting += 1
         prefix = self.name + "_image_%d_" % image_acq_counter_setting.get()
         self.__control.EnableAutoSaving([directory, prefix])
     else:
         self.__control.DisableAutoSaving()
Esempio n. 21
0
 def __init__(self, name, config):
     SamplingCounter.__init__(self, name, None)
     tango_uri = config["uri"]
     self.__control = DeviceProxy(tango_uri)
Esempio n. 22
0
class setpoint(Controller):
    def __init__(self, *args, **kwargs):
        Controller.__init__(self, *args, **kwargs)

        self._axis_moves = {}

        self.factor = 1

        # config
        _target_attribute_name = self.config.get("target_attribute")
        _gating_ds = self.config.get("gating_ds")

        try:
            self.target_attribute = AttributeProxy(_target_attribute_name)
        except:
            elog.error("Unable to connect to attrtribute %s " %
                       _target_attribute_name)

        # External DS to use for gating.
        # ex: PI-E517 for zap of HPZ.
        if _gating_ds is not None:
            self.gating_ds = DeviceProxy(_gating_ds)
            self.external_gating = True
            elog.info("external gating True ; gating ds= %s " % _gating_ds)
        else:
            # No external gating by default.
            self.external_gating = False

        # _pos0 must be in controller unit.
        self._pos0 = self.target_attribute.read().value * self.factor
        elog.info("initial position : %g (in ctrl units)" % self._pos0)

    def move_done_event_received(self, state):
        if self.external_gating:
            if state:
                elog.debug("movement is finished  %f" % time.time())
                self.gating_ds.SetGate(False)
            else:
                elog.debug("movement is starting  %f" % time.time())
                self.gating_ds.SetGate(True)

    """
    Controller initialization actions.
    """

    def initialize(self):
        pass

    """
    Axes initialization actions.
    """

    def initialize_axis(self, axis):
        self._axis_moves[axis] = {"end_t": 0, "end_pos": self._pos0}

        # "end of move" event
        event.connect(axis, "move_done", self.move_done_event_received)

    """
    Actions to perform at controller closing.
    """

    def finalize(self):
        pass

    def start_all(self, *motion_list):
        t0 = time.time()
        for motion in motion_list:
            self.start_one(motion, t0=t0)

    def start_one(self, motion, t0=None):
        axis = motion.axis
        t0 = t0 or time.time()
        pos = self.read_position(axis)

        v = self.read_velocity(axis) * axis.steps_per_unit
        self._axis_moves[axis] = {
            "start_pos": pos,
            "delta": motion.delta,
            "end_pos": motion.target_pos,
            "end_t": t0 + math.fabs(motion.delta) / float(v),
            "t0": t0
        }

    def read_position(self, axis):
        """
        Returns the position taken from controller
        in controller unit (steps).
        """
        # Always return position
        if self._axis_moves[axis]["end_t"]:
            # motor is moving
            t = time.time()
            v = self.read_velocity(axis) * axis.steps_per_unit
            d = math.copysign(1, self._axis_moves[axis]["delta"])
            dt = t - self._axis_moves[axis]["t0"]
            pos = self._axis_moves[axis]["start_pos"] + d * dt * v

            self.target_attribute.write(pos)

            return pos
        else:
            _end_pos = self._axis_moves[axis]["end_pos"] / axis.steps_per_unit

            self.target_attribute.write(_end_pos)
            return _end_pos

    def read_encoder(self, encoder):
        return self.target_attribute.read().value * self.factor

    def read_velocity(self, axis):
        """
        Returns the current velocity taken from controller
        in motor units.
        """
        _user_velocity = axis.settings.get('velocity')
        _mot_velocity = _user_velocity * axis.steps_per_unit
        return float(_mot_velocity)

    def set_velocity(self, axis, new_velocity):
        """
        <new_velocity> is in motor units
        Returns velocity in motor units.
        """
        _user_velocity = new_velocity / axis.steps_per_unit
        axis.settings.set('velocity', _user_velocity)

        return new_velocity

    def read_acceleration(self, axis):
        return 1

    def set_acceleration(self, axis, new_acc):
        pass

    """
    Always return the current acceleration time taken from controller
    in seconds.
    """

    def read_acctime(self, axis):
        return float(axis.settings.get('acctime'))

    def set_acctime(self, axis, new_acctime):
        axis.settings.set('acctime', new_acctime)
        return new_acctime

    """
    """

    def state(self, axis):
        if self._axis_moves[axis]["end_t"] > time.time():
            return AxisState("MOVING")
        else:
            self._axis_moves[axis]["end_t"] = 0
            return AxisState("READY")

    """
    Must send a command to the controller to abort the motion of given axis.
    """

    def stop(self, axis):
        self._axis_moves[axis]["end_pos"] = self.read_position(axis)
        self._axis_moves[axis]["end_t"] = 0

    def stop_all(self, *motion_list):
        for motion in motion_list:
            axis = motion.axis
            self._axis_moves[axis]["end_pos"] = self.read_position(axis)
            self._axis_moves[axis]["end_t"] = 0

    def home_search(self, axis, switch):
        self._axis_moves[axis]["end_pos"] = 0
        self._axis_moves[axis]["end_t"] = 0
        self._axis_moves[axis]["home_search_start_time"] = time.time()

#    def home_set_hardware_position(self, axis, home_pos):
#        raise NotImplementedError

    def home_state(self, axis):
        if (time.time() -
                self._axis_moves[axis]["home_search_start_time"]) > 2:
            return AxisState("READY")
        else:
            return AxisState("MOVING")
Esempio n. 23
0
 def __init__(self, device, attributes=None):
     if attributes is not None:
         self.attributes = attributes
     self.device = DeviceProxy(device)
Esempio n. 24
0
class Lima(object):
    ROI_COUNTERS = 'roicounter'
    BPM = 'beamviewer'

    class Image(object):
        ROTATION_0,ROTATION_90,ROTATION_180,ROTATION_270 = range(4)

        def __init__(self,proxy):
            self._proxy = proxy
        @property
        def proxy(self):
            return self._proxy

        @property
        def bin(self):
            return self._proxy.image_bin
        @bin.setter
        def bin(self,values):
            self._proxy.image_bin = values

        @property
        def flip(self):
            return self._proxy.image_flip
        @flip.setter
        def flip(self,values):
            self._proxy.image_flip = values

        @property
        def roi(self):
            return Roi(*self._proxy.image_roi)
        @roi.setter
        def roi(self,roi_values):
            if len(roi_values) == 4:
                self._proxy.image_roi = roi_values
            elif isinstance(roi_values[0],Roi):
                roi = roi_values[0]
                self._proxy.image_roi = (roi.x,roi.y,
                                         roi.width,roi.height)
            else:
                raise TypeError("Lima.image: set roi only accepts roi (class)"
                                " or (x,y,width,height) values")

        @property
        def rotation(self):
            rot_str = self._proxy.image_rotation
            return {'NONE' : self.ROTATION_0,
                    '90' : self.ROTATION_90,
                    '180' : self.ROTATION_180,
                    '270' : self.ROTATION_270}.get(rot_str)
        @rotation.setter
        def rotation(self,rotation):
            if isinstance(rotation,(str,unicode)):
                self._proxy.image_rotation = rotation
            else:
                rot_str = {self.ROTATION_0 : 'NONE',
                           self.ROTATION_90 : '90',
                           self.ROTATION_180 : '180',
                           self.ROTATION_270 : '270'}.get(rotation)
                if rot_str is None:
                    raise ValueError("Lima.image: rotation can only be 0,90,180 or 270")
                self._proxy.image_rotation = rot_str

    class Acquisition(object):
        ACQ_MODE_SINGLE,ACQ_MODE_CONCATENATION,ACQ_MODE_ACCUMULATION = range(3)

        def __init__(self,proxy):
            self._proxy = proxy
            acq_mode = (("SINGLE",self.ACQ_MODE_SINGLE),
                        ("CONCATENATION",self.ACQ_MODE_CONCATENATION),
                        ("ACCUMULATION",self.ACQ_MODE_ACCUMULATION))
            self.__acq_mode_from_str = dict(acq_mode)
            self.__acq_mode_from_enum = dict(((y,x) for x,y in acq_mode))
        @property
        def exposition_time(self):
            """
            exposition time for a frame
            """
            return self._proxy.acq_expo_time
        @exposition_time.setter
        def exposition_time(self,value):
            self._proxy.acq_expo_time = value

        @property
        def mode(self):
            """
            acquisition mode (SINGLE,CONCATENATION,ACCUMULATION)
            """
            acq_mode = self._proxy.acq_mode
            return self.__acq_mode_from_str.get(acq_mode)
        @mode.setter
        def mode(self,value):
            mode_str = self.__acq_mode_from_enum.get(value)
            if mode_str is None:
                possible_modes = ','.join(('%d -> %s' % (y,x)
                                           for x,y in self.__acq_mode_from_str.iteritems()))
                raise ValueError("lima: acquisition mode can only be: %s" % possible_modes)
            self._proxy.acq_mode = mode_str
        @property
        def trigger_mode(self):
            """
            Trigger camera mode
            """
            pass
        @trigger_mode.setter
        def trigger_mode(self,value):
            pass

    def __init__(self,name,config_tree):
        """Lima controller.

        name -- the controller's name
        config_tree -- controller configuration
        in this dictionary we need to have:
        tango_url -- tango main device url (from class LimaCCDs)
        """
        self._proxy = DeviceProxy(config_tree.get("tango_url"))
        self.name = name
        self.__bpm = None
        self.__roi_counters = None
        self._camera = None
        self._image = None
        self._acquisition = None

    @property
    def proxy(self):
        return self._proxy

    @property
    def image(self):
        if self._image is None:
            self._image = Lima.Image(self._proxy)
        return self._image

    @property
    def shape(self):
        return (-1, -1)

    @property
    def acquisition(self):
        if self._acquisition is None:
            self._acquisition = Lima.Acquisition(self._proxy)
        return self._acquisition

    @property
    def roi_counters(self):
        if self.__roi_counters is None:
            roi_counters_proxy = self._get_proxy(self.ROI_COUNTERS)
            self.__roi_counters = RoiCounters(self.name, roi_counters_proxy, self)
        return self.__roi_counters

    @property
    def camera(self):
        if self._camera is None:
            camera_type = self._proxy.lima_type
            proxy = self._get_proxy(camera_type)
            camera_module = importlib.import_module('.%s' % camera_type,__package__)
            self._camera = camera_module.Camera(self.name, proxy)
        return self._camera

    @property
    def camera_type(self):
        return self._proxy.camera_type

    @property
    def bpm(self):
        if self.__bpm is None:
          bpm_proxy = self._get_proxy(self.BPM)
          self.__bpm = Bpm(self.name, bpm_proxy, self)
        return self.__bpm

    @property
    def available_triggers(self):
        """
        This will returns all availables triggers for the camera
        """
        return self._proxy.getAttrStringValueList('acq_trigger_mode')

    def prepareAcq(self):
        self._proxy.prepareAcq()

    def startAcq(self):
        self._proxy.startAcq()

    def _get_proxy(self,type_name):
        device_name = self._proxy.getPluginDeviceNameFromType(type_name)
        if not device_name:
            return
        if not device_name.startswith("//"):
            # build 'fully qualified domain' name
            # '.get_fqdn()' doesn't work
            db_host = self._proxy.get_db_host()
            db_port = self._proxy.get_db_port()
            device_name = "//%s:%s/%s" % (db_host, db_port, device_name)
        return DeviceProxy(device_name)
Esempio n. 25
0
class TangoEMot(Controller):
    def __init__(self, *args, **kwargs):
        Controller.__init__(self, *args, **kwargs)

        # Gets DS name from xml config.
        self.ds_name = self.config.get("ds_name")

        # tests if DS is responding.

    def initialize(self):
        pass

    def finalize(self):
        pass

    def initialize_axis(self, axis):
        self.axis_proxy = DeviceProxy(self.ds_name)

        axis.config.set("steps_per_unit", self.axis_proxy.steps_per_unit)
        axis.config.set("acceleration", self.axis_proxy.ReadConfig("acceleration"))
        axis.config.set("velocity", self.axis_proxy.ReadConfig("velocity"))

    def initialize_encoder(self, encoder):
        self.encoder_proxy = DeviceProxy(self.ds_name)

        encoder.config.config_dict.update({"steps_per_unit": {"value": self.encoder_proxy.steps_per_unit}})

    def read_position(self, axis):
        """
        Returns the position (measured or desired) taken from controller
        in *controller unit* (steps for example).
        """
        return self.axis_proxy.position * axis.steps_per_unit

    def read_encoder(self, encoder):
        return self.encoder_proxy.Measured_Position * encoder.steps_per_unit

    def read_velocity(self, axis):
        _vel = self.axis_proxy.velocity * abs(axis.steps_per_unit)
        return _vel

    def set_velocity(self, axis, new_velocity):
        self.axis_proxy.velocity = new_velocity / abs(axis.steps_per_unit)

    def read_acctime(self, axis):
        return self.axis_proxy.acctime

    def set_acctime(self, axis, new_acc_time):
        self.axis_proxy.acctime = new_acc_time

    def read_acceleration(self, axis):
        return self.axis_proxy.acceleration * abs(axis.steps_per_unit)

    def set_acceleration(self, axis, new_acceleration):
        self.axis_proxy.acceleration = new_acceleration / abs(axis.steps_per_unit)

    def state(self, axis):
        _state = self.axis_proxy.state()
        if _state == DevState.ON:
            return AxisState("READY")
        elif _state == DevState.MOVING:
            return AxisState("MOVING")
        else:
            return AxisState("READY")

    def prepare_move(self, motion):
        pass

    def start_one(self, motion):
        """
        Called on a single axis motion,
        returns immediately,
        positions in motor units
        """
        self.axis_proxy.position = float(motion.target_pos / motion.axis.steps_per_unit)

    def stop(self, axis):
        self.axis_proxy.Abort()

    def home_search(self, axis, switch):
        self.axis_proxy.GoHome()

    def home_state(self, axis):
        return self.state(axis)
Esempio n. 26
0
def __is_tango_device(name):
    try:
        return DeviceProxy(name) is not None
    except:
        pass
    return False
Esempio n. 27
0
 def initialize(self):
     # Get a proxy on Insertion Device device server of the beamline.
     self.device = DeviceProxy(self.ds_name)
Esempio n. 28
0
class Undulator(Controller):
    def __init__(self, *args, **kwargs):
        Controller.__init__(self, *args, **kwargs)

        self.axis_info = dict()

        try:
            self.ds_name = self.config.get("ds_name")
        except:
            elog.debug("no 'ds_name' defined in config for %s" %
                       self.config.get('name'))

    """
    Controller initialization actions.
    """

    def initialize(self):
        # Get a proxy on Insertion Device device server of the beamline.
        self.device = DeviceProxy(self.ds_name)

    """
    Axes initialization actions.
    """

    def initialize_axis(self, axis):
        attr_pos_name = axis.config.get("attribute_position", str)
        attr_vel_name = axis.config.get("attribute_velocity", str)
        attr_acc_name = axis.config.get("attribute_acceleration", str)
        self.axis_info[axis] = {
            "attr_pos_name": attr_pos_name,
            "attr_vel_name": attr_vel_name,
            "attr_acc_name": attr_acc_name
        }
        elog.debug("axis initilized--------------------------")

    """
    Actions to perform at controller closing.
    """

    def finalize(self):
        pass

    def _set_attribute(self, axis, attribute_name, value):
        self.device.write_attribute(self.axis_info[axis][attribute_name],
                                    value)

    def _get_attribute(self, axis, attribute_name):
        return self.device.read_attribute(
            self.axis_info[axis][attribute_name]).value

    def start_one(self, motion, t0=None):
        self._set_attribute(
            motion.axis, "attr_pos_name",
            float(motion.target_pos / motion.axis.steps_per_unit))

    def read_position(self, axis):
        """
        Returns the position taken from controller
        in controller unit (steps).
        """
        return self._get_attribute(axis, "attr_pos_name")

    """
    VELOCITY
    """

    def read_velocity(self, axis):
        """
        Returns the current velocity taken from controller
        in motor units.
        """
        return self._get_attribute(axis, "attr_vel_name")

    def set_velocity(self, axis, new_velocity):
        """
        <new_velocity> is in motor units
        """
        self._set_attribute(axis, "attr_vel_name", new_velocity)

    """
    ACCELERATION
    """

    def read_acceleration(self, axis):
        return self._get_attribute(axis, "attr_acc_name")

    def set_acceleration(self, axis, new_acceleration):
        self._set_attribute(axis, "attr_acc_name", new_acceleration)

    """
    STATE
    """

    def state(self, axis):
        _state = self.device.state()

        if _state == DevState.ON:
            return AxisState("READY")
        elif _state == DevState.MOVING:
            return AxisState("MOVING")
        else:
            return AxisState("READY")

    """
    Must send a command to the controller to abort the motion of given axis.
    """

    def stop(self, axis):
        self.device.abort()

    def stop_all(self, *motion_list):
        self.device.abort()

    def get_info(self, axis):
        info_str = ""
        info_str = "DEVICE SERVER : %s \n" % self.ds_name
        info_str += self.ds.state() + "\n"
        info_str += "status=\"%s\"\n" % str(self.ds.status()).strip()
        info_str += "state=%s\n" % self.ds.state()
        info_str += "mode=%s\n" % str(self.ds.mode)
        info_str += ("undu states= %s" %
                     " ".join(map(str, self.ds.UndulatorStates)))

        return info_str
Esempio n. 29
0
 def init(self):
     self._debug("TangoDeviceServer::init()")
     if self._proxy is None:
         self._proxy = DeviceProxy(self._tango_url)
Esempio n. 30
0
class tango_shutter:
    def __init__(self, name, config):
        tango_uri = config.get("uri")
        self.__control = DeviceProxy(tango_uri)
        try:
            self.manual = config.get("attr_mode")
        except:
            self.manual = False

    def get_status(self):
        print self.__control._status()

    def get_state(self):
        return str(self.__control._state())

    def open(self):
        state = self.get_state()
        if state == 'CLOSE':
            try:
                self.__control.command_inout("Open")
                self._wait('OPEN', 5)
            except:
                raise RuntimeError("Cannot open shutter")
        else:
            print self.__control._status()

    def close(self):
        state = self.get_state()
        if state == 'OPEN' or state == 'RUNNING':
            try:
                self.__control.command_inout("Close")
                self._wait('CLOSE', 5)
            except:
                raise RuntimeError("Cannot close shutter")
        else:
            print self.__control._status()

    def automatic(self):
        if self.manual:
            state = self.get_state()
            if state == 'CLOSE' or state == 'OPEN':
                try:
                    self.__control.command_inout("Automatic")
                    self._wait_mode()
                except:
                    raise RuntimeError("Cannot open shutter in automatic mode")
            else:
                print self.__control._status()

    def manual(self):
        if self.manual:
            state = self.get_state()
            if state == 'CLOSE' or state == 'RUNNING':
                try:
                    self.__control.command_inout("Manual")
                    self._wait_mode()
                except:
                    raise RuntimeError("Cannot set shutter in manual mode")
            else:
                print self.__control._status()

    def _wait(self, state, timeout=3):
        tt = time.time()
        stat = self.get_state()
        while stat != state or time.time() - tt < timeout:
            time.sleep(1)
            stat = self.get_state()

    def _wait_mode(self, timeout=3):
        tt = time.time()
        stat = self.__control.read_attribute(self.manual).value
        while stat is False or time.time() - tt < timeout:
            time.sleep(1)
            stat = self.__control.read_attribute(self.manual).value
Esempio n. 31
0
    def centrebeam(self):
        self.lightout()
        self._simultaneous_move(self.bstopz, -80)
        self.detcover.set_in()
        self.fshut.open()
        self.i1.autorange(True)

        diode_values = []

        def restore_att(old_transmission=self.transmission.get()):
            self.transmission.set(old_transmission)

        with error_cleanup(restore_att, self.fshut.close):
            for t in (1, 10, 100):
                self.transmission.set(t)
                diode_values.append(self.i1.read())

            if (diode_values[1] / diode_values[0]) <= 12 and (
                    diode_values[1] / diode_values[0]) >= 8:
                if (diode_values[2] / diode_values[1]) <= 12 and (
                        diode_values[2] / diode_values[1]) >= 8:
                    pass
                else:
                    raise RuntimeError("Wrong intensity, hint: is there beam?")
            else:
                raise RuntimeError("Wrong intensity, hint: is there beam?")

        def restore_slits(saved_pos=(self.hgap, self.hgap.position(),
                                     self.vgap, self.vgap.position())):
            print 'restoring slits to saved positions', saved_pos
            self._simultaneous_move(*saved_pos)

        self.bv_device = DeviceProxy(self.beamviewer_server)
        self.sample_video_device = DeviceProxy(self.sample_video_server)

        def restore_live():
            self.sample_video_device.video_live = True

        img_width = self.sample_video_device.image_width
        img_height = self.sample_video_device.image_height
        # look for pixels per mm calibration data, depending on zoom level
        zoom_pos = self.zoom.position()
        for pos in self.zoom_positions:
            if abs(float(pos.get("offset")) - zoom_pos) < 0.001:
                px_mm_y, px_mm_z = float(pos.get("pixelsPerMmY")) or 0, float(
                    pos.get("pixelsPerMmZ")) or 0
                break
        else:
            raise RuntimeError("Could not get pixels/mm calibration")

        def restore_table(saved_pos=(self.tz1, self.tz1.position(), self.tz2,
                                     self.tz2.position(), self.tz3,
                                     self.tz3.position(), self.ttrans,
                                     self.ttrans.position())):
            print 'restoring table to saved positions', saved_pos
            self._simultaneous_move(*saved_pos)

        def do_centrebeam():
            with cleanup(restore_live):
                self.sample_video_device.video_live = False
                res = self.bv_device.GetPosition()

            by = res[2]
            bz = res[3]
            if -1 in (by, bz):
                raise RuntimeError("Could not find beam")

            dy = (by - (img_width / 2)) / px_mm_y
            dz = (bz - (img_height / 2)) / px_mm_z
            if abs(dy) > 0.1 or abs(dz) > 0.1:
                raise RuntimeError(
                    "Aborting centrebeam, displacement is too much")

            with error_cleanup(restore_table):
                print "moving ttrans by", -dy
                print "moving tz1,tz2,tz3 by", -dz
                self._simultaneous_rmove(self.ttrans, -dy, self.tz1, -dz,
                                         self.tz2, -dz, self.tz3, -dz)
            return dy, dz

        with cleanup(restore_slits, restore_att, self.fshut.close):
            self.transmission.set(0.5)
            self.detcover.set_in()
            self.move_beamstop_out()
            self.fshut.open()
            self._simultaneous_move(self.hgap, 2, self.vgap, 2)

            for i in range(5):
                dy, dz = do_centrebeam()
                if abs(dy) < 0.001 and abs(dz) < 0.001:
                    break
Esempio n. 32
0
 def __init__(self, name, config):
     SamplingCounter.__init__(self, name, None)
     tango_uri = config["uri"]
     self.__control = DeviceProxy(tango_uri)
Esempio n. 33
0
    def initialize_axis(self, axis):
        self.axis_proxy = DeviceProxy(self.ds_name)

        axis.config.set("steps_per_unit", self.axis_proxy.steps_per_unit)
        axis.config.set("acceleration", self.axis_proxy.ReadConfig("acceleration"))
        axis.config.set("velocity", self.axis_proxy.ReadConfig("velocity"))
Esempio n. 34
0
class tango_shutter:
   def __init__(self, name, config):
      tango_uri = config.get("uri")
      self.__control = DeviceProxy(tango_uri)
      try:
         self.manual = config.get("attr_mode")
      except:
         self.manual = False

   def get_status(self):
      print self.__control._status()

   def get_state(self):
      return str(self.__control._state())

   def open(self):
      state = self.get_state()
      if state == 'CLOSE':
         try:
            self.__control.command_inout("Open")
            self._wait('OPEN', 5)
         except:
            raise RuntimeError("Cannot open shutter")
      else:
         print self.__control._status()

   def close(self):
      state = self.get_state()
      if state == 'OPEN' or state == 'RUNNING':
         try:
            self.__control.command_inout("Close")
            self._wait('CLOSE', 5)
         except:
            raise RuntimeError("Cannot close shutter")
      else:
         print self.__control._status()

   def automatic(self):
      if self.manual:
         state = self.get_state()
         if state == 'CLOSE' or state == 'OPEN':
            try:
               self.__control.command_inout("Automatic")
               self._wait_mode()
            except:
               raise RuntimeError("Cannot open shutter in automatic mode")
         else:
            print self.__control._status()

   def manual(self):
      if self.manual:
         state = self.get_state()
         if state == 'CLOSE' or state == 'RUNNING':
            try:
               self.__control.command_inout("Manual")
               self._wait_mode()
            except:
               raise RuntimeError("Cannot set shutter in manual mode")
         else:
            print self.__control._status()
         
   def _wait(self, state, timeout=3):
      tt = time.time()
      stat = self.get_state()
      while stat != state or time.time() - tt < timeout:
         time.sleep(1)
         stat = self.get_state()

   def _wait_mode(self, timeout=3):
      tt = time.time()
      stat = self.__control.read_attribute(self.manual).value
      while stat is False or time.time() - tt < timeout:
         time.sleep(1)
         stat = self.__control.read_attribute(self.manual).value
Esempio n. 35
0
class MD2M:
    def __init__(self, name, config):
        self.beamviewer_server = str(config.get("beamviewer_server"))
        self.sample_video_server = str(config.get("sample_video_server"))
        self.shutter_predelay = float(config.get("shutter_predelay"))
        self.shutter_postdelay = float(config.get("shutter_postdelay"))
        self.musst_sampling = int(config.get("musst_sampling"))
        self.diagfile = config.get("diagfile")
        self.diag_n = 0
        self.init_offsets = dict()
        for motor_name, value in config.get("init_offsets").iteritems():
            self.init_offsets[motor_name] = float(value)
        self.zoom_positions = config.get("zoom_positions")
        self.oscil_mprg = config.get("oscil_mprg")
        self.members_state = {'light': None, 'cryo': None, 'fluodet': None}

    @task
    def _simultaneous_move(self, *args):
        axis_list = []
        for axis, target in grouped(args, 2):
            axis_list.append(axis)
        g = Group(*axis_list)
        g.move(*args)

    @task
    def _simultaneous_rmove(self, *args):
        axis_list = []
        targets = []
        for axis, target in grouped(args, 2):
            axis_list.append(axis)
            targets.append(axis.position() + target)
        g = Group(*axis_list)
        g.move(dict(zip(axis_list, targets)))

    def _wait_ready(self, *axes, **kwargs):
        timeout = int(kwargs.get("timeout", 3))
        with gevent.Timeout(
                timeout,
                RuntimeError("Timed out waiting for motors to be READY")):
            for axis in axes:
                axis.wait_move()

    def move_beamstop_out(self):
        self.bstopz.move(-80)

    def move_beamstop_in(self):
        pass

    def full_init(self):
        # add sample changer check?
        print 'Please wait while doing full initialization of MD2M...'
        print 'Homing fast shutter'
        self.musst.putget("#ABORT")
        self.fshut.home()
        print '  done.'
        self.omega_init()
        self.translation_table_init()
        self.centring_table_init()
        self.zoom_init()
        self.kappa_init()

    def omega_init(self):
        print 'Homing omega axis'
        self.omega.apply_config()
        self.omega.home()
        self.omega.dial(float(self.init_offsets["omega"]))
        self.omega.position(float(self.init_offsets["omega"]))
        time.sleep(1)
        self.musst.putget("#ABORT")  #in case a program is running
        self.omega.move(0)
        self.musst.putget("#CH CH2 0")
        print '  done.'

    def kappa_init(self):
        pass

    def _reset_axes_settings(self, *axes):
        for axis in axes:
            axis.apply_config()

    def translation_table_init(self):
        print 'Doing translation table init.'
        table_axes = (self.phix, self.phiy, self.phiz)
        self._reset_axes_settings(*table_axes)
        print "  searching for phix, phiy and phiz negative limits, and setting init pos."
        [axis.hw_limit(-1, wait=False) for axis in table_axes]
        [axis.wait_move() for axis in table_axes]
        for axis in table_axes:
            axis.dial(self.init_offsets[axis.name])
            axis.position(self.init_offsets[axis.name])
        [axis.apply_config() for axis in table_axes]
        #[axis.limits() for axis in table_axes]
        self._simultaneous_move(self.phix, 0, self.phiy, 0, self.phiz, 0)
        self.phiy.position(22)
        print '  done.'

    def centring_table_init(self):
        print 'Doing centring table init.'
        table_axes = (self.sampx, self.sampy)
        self._reset_axes_settings(*table_axes)
        print "  searching for sampx and sampy positive limits, and setting init pos."
        [axis.hw_limit(+1) for axis in table_axes]
        [axis.wait_move() for axis in table_axes]
        for axis in table_axes:
            axis.dial(self.init_offsets[axis.name])
            axis.position(self.init_offsets[axis.name])
        [axis.apply_config() for axis in table_axes]
        self._simultaneous_move(self.sampx, 0, self.sampy, 0)
        print '  done.'

    def zoom_init(self):
        print 'Homing zoom axis'
        self.zoom.velocity(self.zoom.velocity(from_config=True))
        self.zoom.acceleration(self.zoom.acceleration(from_config=True))
        print "  searching for zoom home switch"
        self.zoom.home()
        self.zoom.dial(6.1)
        self.zoom.position(6.1)
        self.zoom.move(1)
        print '  done.'

    def _musst_oscil(self, e1, e2, esh1, esh2, trigger):
        delta = self.musst_sampling

        self.musst.putget("#VAR E1 %d" % e1)
        self.musst.putget("#VAR E2 %d" % e2)
        self.musst.putget("#VAR ESH1 %d" % esh1)
        self.musst.putget("#VAR ESH2 %d" % esh2)
        self.musst.putget("#VAR DE %d" % delta)
        self.musst.putget("#VAR DETTRIG %d" % trigger)
        self.musst.putget("#CH CH3 0")
        print "\ne1=", e1, "e2=", e2, "esh1=", esh1, "esh2=", esh2, "delta=", delta, "trigger=", trigger

        self.musst.putget("#RUN OSCILLPX")

    def _musst_prepare(self, e1, e2, esh1, esh2, pixel_detector_trigger_steps):
        self.musst.putget("#ABORT")
        self.musst.putget("#CHCFG CH2 ENC ALIAS PHI")
        self.musst.putget("#CHCFG CH1 ENC ALIAS SHUTSTATE")
        oscil_program = open(self.oscil_mprg, "r")
        self.musst.upload_program(oscil_program.read())

        self._musst_oscil(e1, e2, esh1, esh2, pixel_detector_trigger_steps)

    def _helical_calc(self, helical_pos, exp_time):
        hp = copy.deepcopy(helical_pos)
        start = hp['1']
        end = hp['2']
        logging.info("%r", hp)

        # phiz has to move if chi==90 for example, phiy has to move if chi==0
        helical = {
            "phiy": {
                "trajectory": end.get("phiy", 0) - start.get('phiy', 0),
                "motor": self.phiy,
                "start": start.get("phiy")
            },
            "sampx": {
                "trajectory": end["sampx"] - start["sampx"],
                "motor": self.sampx,
                "start": start.get("sampx")
            },
            "sampy": {
                "trajectory": end["sampy"] - start["sampy"],
                "motor": self.sampy,
                "start": start.get("sampy")
            }
        }
        for motor_name in helical.keys():
            hm = helical[motor_name]
            hm["distance"] = abs(hm["trajectory"])
            if hm["distance"] <= 5E-3:
                del helical[motor_name]
                continue
            hm["d"] = math.copysign(1, hm["trajectory"])
            hm["velocity"] = helical[motor_name]["distance"] / float(exp_time)

        return helical

    def helical_oscil(self,
                      start_ang,
                      stop_ang,
                      helical_pos,
                      exp_time,
                      save_diagnostic=True,
                      operate_shutter=True):
        def oscil_cleanup(omega_v=self.omega.velocity(from_config=True),
                          omega_a=self.omega.acceleration(from_config=True),
                          phiy_v=self.phiy.velocity(from_config=True),
                          phiy_a=self.phiy.acceleration(from_config=True),
                          sampx_v=self.sampx.velocity(from_config=True),
                          sampx_a=self.sampx.acceleration(from_config=True),
                          sampy_v=self.sampy.velocity(from_config=True),
                          sampy_a=self.sampy.acceleration(from_config=True)):
            for motor_name in ("omega", "phiy", "sampx", "sampy"):
                getattr(self, motor_name).velocity(locals()[motor_name + "_v"])
                getattr(self,
                        motor_name).acceleration(locals()[motor_name + "_a"])

        helical = self._helical_calc(helical_pos, exp_time)
        d, calc_velocity, acc_time, acc_ang = self._oscil_calc(
            start_ang, stop_ang, exp_time)

        encoder_step_size = -self.omega.steps_per_unit
        pixel_detector_trigger_steps = encoder_step_size * start_ang
        shutter_predelay_steps = math.fabs(
            float(self.shutter_predelay * calc_velocity * encoder_step_size))
        shutter_postdelay_steps = math.fabs(
            float(self.shutter_postdelay * calc_velocity * encoder_step_size))
        omega_prep_time = self.shutter_predelay * float(calc_velocity)
        oscil_start = start_ang - d * (
            acc_ang + shutter_predelay_steps / encoder_step_size)
        oscil_final = stop_ang + d * acc_ang

        with cleanup(oscil_cleanup):
            self.fshut.close()

            moves = []
            for motor_name, helical_info in helical.iteritems():
                motor = helical_info["motor"]
                start = helical_info["start"]
                v = helical_info["velocity"]
                dd = helical_info["d"]
                step_size = abs(motor.steps_per_unit)
                prep_distance = (v * (omega_prep_time -
                                      (acc_time / 2.0))) / float(step_size)
                deceleration_distance = (
                    (acc_time * v) / 2.0) / float(step_size)
                helical_info[
                    "distance"] += prep_distance + deceleration_distance
                #logging.info("relative move for motor %s of: %f, prep_dist=%f", motor_name, start-motor.position()-dd*prep_distance, dd*prep_distance)
                moves += [motor, start - dd * prep_distance]

            self._simultaneous_move(self.omega, oscil_start, *moves)

            self.omega.velocity(calc_velocity)
            self.omega.acctime(acc_time)
            for motor_name, helical_info in helical.iteritems():
                v = helical_info["velocity"]
                m = helical_info["motor"]
                if v > 0:
                    #print 'setting velocity and acctime for motor %s to:' % motor_name, v, acc_time
                    if v > 0.4:
                        raise RuntimeError(
                            "Wrong parameter for helical, velocity is too high; hint: increase number of images or exposure time and reduce transmission."
                        )
                    m.velocity(v)
                    m.acctime(acc_time)

            e1 = oscil_start * encoder_step_size + 5
            e2 = oscil_final * encoder_step_size - 5
            esh1 = start_ang * encoder_step_size - d * shutter_predelay_steps
            esh2 = stop_ang * encoder_step_size - d * shutter_postdelay_steps

            if (esh1 < esh2 and esh1 < e1) or (esh1 > esh2 and esh1 > e1):
                raise RuntimeError("acc_margin too small")

            if operate_shutter:
                self._musst_prepare(e1, e2, esh1, esh2,
                                    pixel_detector_trigger_steps)

            moves = dict()
            for motor_name, helical_info in helical.iteritems():
                m = helical_info["motor"]
                moves[m] = m.position(
                ) + helical_info["d"] * helical_info["distance"]

            axes_group = Group(self.phiy, self.sampx, self.sampy)

            def abort_all():
                self.omega.stop()
                axes_group.stop()
                self.musst.putget("#ABORT")

            with error_cleanup(abort_all):
                self.omega.move(oscil_final, wait=False)
                axes_group.move(moves)
                self.omega.wait_move()

            if save_diagnostic:
                self.save_diagnostic(wait=False)

    def _oscil_calc(self, start_ang, stop_ang, exp_time):
        abs_ang = math.fabs(stop_ang - start_ang)
        if stop_ang > start_ang:
            d = 1
        else:
            raise RuntimeError("cannot do reverse oscillation")
        osctime = float(exp_time)
        step_size = math.fabs(self.omega.steps_per_unit)
        calc_velocity = float(abs_ang) / osctime
        acc_time = 0.1
        acc_ang = (acc_time * calc_velocity) / 2
        return d, calc_velocity, acc_time, acc_ang  #oscil_start, oscil_final, calc_velocity, acc_time, acc_ang

    def oscil(self,
              start_ang,
              stop_ang,
              exp_time,
              save_diagnostic=True,
              operate_shutter=True,
              helical=False):
        d, calc_velocity, acc_time, acc_ang = self._oscil_calc(
            start_ang, stop_ang, exp_time)

        def oscil_cleanup(v=self.omega.velocity(from_config=True),
                          a=self.omega.acceleration(from_config=True)):
            self.omega.velocity(v)
            self.omega.acceleration(a)

        with cleanup(oscil_cleanup):
            self.fshut.close()

            encoder_step_size = -self.omega.steps_per_unit
            pixel_detector_trigger_steps = encoder_step_size * start_ang
            shutter_predelay_steps = math.fabs(
                float(self.shutter_predelay * calc_velocity *
                      encoder_step_size))
            shutter_postdelay_steps = math.fabs(
                float(self.shutter_postdelay * calc_velocity *
                      encoder_step_size))
            #max_step_ang = max(encoder_step_size * acc_ang + self.acc_margin, shutter_predelay_steps)
            #max_step_ang = max(encoder_step_size * acc_ang, shutter_predelay_steps)
            #max_ang = max_step_ang / encoder_step_size
            oscil_start = start_ang - d * (
                acc_ang + shutter_predelay_steps / encoder_step_size)
            oscil_final = stop_ang + d * acc_ang
            #oscil_start = start_ang - d*(max_ang + self.acc_margin/encoder_step_size)
            #oscil_final = stop_ang + d*(max_ang + self.acc_margin/encoder_step_size)

            self.omega.move(oscil_start)
            self.omega.velocity(calc_velocity)
            self.omega.acctime(acc_time)

            #phi_encoder_pos = self.omega.position()*encoder_step_size

            e1 = oscil_start * encoder_step_size + 5
            e2 = oscil_final * encoder_step_size - 5
            #e1 = start_ang*encoder_step_size - d*(max_step_ang + 5)
            #e2 = stop_ang*encoder_step_size + d*(max_step_ang - 5)
            esh1 = start_ang * encoder_step_size - d * shutter_predelay_steps
            esh2 = stop_ang * encoder_step_size - d * shutter_postdelay_steps

            if operate_shutter:
                self._musst_prepare(e1, e2, esh1, esh2,
                                    pixel_detector_trigger_steps)

            self.omega.move(oscil_final)

            if save_diagnostic:
                self.save_diagnostic(wait=False)

    def _get_diagnostic(self, phi_encoder_pos):
        npoints = int(self.musst.putget("?VAR NPOINTS"))
        nlines = npoints  #variable name should be changed in musst program
        diag_data = numpy.zeros((nlines, 9), dtype=numpy.float)
        data = self.musst.get_data(8)

        # first column contains time in microseconds,
        # convert it to milliseconds
        diag_data[:, 0] = data[:, 0] / 1000.0

        # velocity in
        #     v(i) = [ x(i) - x(i-1) ] /  [ t(i) - t(i-1) ]
        # then convert from steps/microsec into deg/sec
        step_size = math.fabs(self.omega.steps_per_unit)
        diag_data[1:, 1] = [
            xi - prev_xi for xi, prev_xi in zip(data[:, 2][1:], data[:, 2])
        ]
        diag_data[1:, 1] /= [
            float(ti - prev_ti)
            for ti, prev_ti in zip(data[:, 0][1:], data[:, 0])
        ]
        diag_data[:, 1] *= 1E6 / float(step_size)
        diag_data[0, 1] = diag_data[1, 1]

        # save pos in degrees
        diag_data[:, 2] = data[:, 2] / float(step_size)

        # I0 values
        #diag_data[:,3]=10*(data[:,4]/float(0x7FFFFFFF))
        #diag_data[:,3]=10*(data[:,5]/float(0x7FFFFFFF))
        diag_data[:, 3] = -data[:, 4] / 20000.0

        # I1 values
        #diag_data[:,4]=10*(data[:,5]/float(0x7FFFFFFF))
        diag_data[:, 4] = -10 * (data[:, 6] / float(0x7FFFFFFF))

        # shutter cmd (Btrig)
        #diag_data[:,5]=data[:,6]
        diag_data[:, 5] = data[:, 7]

        # shutter status
        diag_data[:, 6] = data[:, 1]  # & 0x0001)/0x0001

        # detector is acquiring status
        diag_data[:, 7] = data[:, 3]

        # save SAMP step
        diag_data[:, 8] = -data[:, 5] / 20000.0

        return diag_data

    @task
    def save_diagnostic(self, phi_encoder_pos=0):
        diag_data = self._get_diagnostic(phi_encoder_pos)
        self.diag_n += 1
        rows, cols = diag_data.shape
        with open(self.diagfile, "a+") as diagfile:
            diagfile.write(
                "\n#S %d\n#D %s\n" %
                (self.diag_n,
                 datetime.datetime.now().strftime("%a %b %d %H:%M:%S %Y")))
            diagfile.write("#N %d\n" % cols)
            diagfile.write(
                "#L Time(ms)  Speed  Phi  PhiY  I1  Shut Cmd  Shut State  Detector Acquiring  PhiZ\n"
            )
            numpy.savetxt(diagfile, diag_data)
            diagfile.write("\n\n")

    def _set_light(self, set_in):
        set_in = bool(set_in)
        self.wago.set("lightoff", not set_in)
        self.wago.set("lightin", set_in)
        with gevent.Timeout(
                3,
                RuntimeError("Light %s switch is not activated" %
                             ('in' if set_in else 'out'))):
            while not self.wago.get(
                    "light_is_in" if set_in else "light_is_out"):
                time.sleep(0.1)
            self.members_state['light'] = set_in

    def _get_light(self):
        if self.wago.get("light_is_in"):
            return True
        if self.wago.get("light_is_out"):
            return False
        return None

    def light(self, state=None):
        if state is not None:
            self._set_light(state)
        else:
            return self.members_state['light']

    def lightin(self):
        return self._set_light(True)

    def lightout(self):
        return self._set_light(False)

    def _set_cryo(self, set_in):
        set_in = bool(set_in)
        self.wago.set("cryoin", set_in)
        with gevent.Timeout(
                3,
                RuntimeError("Cryo %s switch is not activated" %
                             ('in' if set_in else 'out'))):
            while not self.wago.get("cryoin" if set_in else "cryobck"):
                time.sleep(0.1)
            self.members_state['cryo'] = set_in

    def cryo(self, state=None):
        if state is not None:
            self._set_cryo(state)
        else:
            return self.members_state['cryo']

    def cryoin(self):
        return self._set_cryo(True)

    def cryoout(self):
        return self._set_cryo(False)

    def fluodet(self, state=None):
        if state is not None:
            self._set_fluodet(state)
        else:
            return self.members_state['fluodet']

    def _set_fluodet(self, set_in):
        set_in = bool(set_in)
        self.wago.set("fldin", set_in)
        with gevent.Timeout(
                3,
                RuntimeError(
                    "Fluorescense detector %s switch is not activated" %
                    ('in' if set_in else 'out'))):
            while self.wago.get('fldbck') is not set_in:
                time.sleep(0.1)
            self.members_state['fluodet'] = set_in

    def centrebeam(self):
        self.lightout()
        self._simultaneous_move(self.bstopz, -80)
        self.detcover.set_in()
        self.fshut.open()
        self.i1.autorange(True)

        diode_values = []

        def restore_att(old_transmission=self.transmission.get()):
            self.transmission.set(old_transmission)

        with error_cleanup(restore_att, self.fshut.close):
            for t in (1, 10, 100):
                self.transmission.set(t)
                diode_values.append(self.i1.read())

            if (diode_values[1] / diode_values[0]) <= 12 and (
                    diode_values[1] / diode_values[0]) >= 8:
                if (diode_values[2] / diode_values[1]) <= 12 and (
                        diode_values[2] / diode_values[1]) >= 8:
                    pass
                else:
                    raise RuntimeError("Wrong intensity, hint: is there beam?")
            else:
                raise RuntimeError("Wrong intensity, hint: is there beam?")

        def restore_slits(saved_pos=(self.hgap, self.hgap.position(),
                                     self.vgap, self.vgap.position())):
            print 'restoring slits to saved positions', saved_pos
            self._simultaneous_move(*saved_pos)

        self.bv_device = DeviceProxy(self.beamviewer_server)
        self.sample_video_device = DeviceProxy(self.sample_video_server)

        def restore_live():
            self.sample_video_device.video_live = True

        img_width = self.sample_video_device.image_width
        img_height = self.sample_video_device.image_height
        # look for pixels per mm calibration data, depending on zoom level
        zoom_pos = self.zoom.position()
        for pos in self.zoom_positions:
            if abs(float(pos.get("offset")) - zoom_pos) < 0.001:
                px_mm_y, px_mm_z = float(pos.get("pixelsPerMmY")) or 0, float(
                    pos.get("pixelsPerMmZ")) or 0
                break
        else:
            raise RuntimeError("Could not get pixels/mm calibration")

        def restore_table(saved_pos=(self.tz1, self.tz1.position(), self.tz2,
                                     self.tz2.position(), self.tz3,
                                     self.tz3.position(), self.ttrans,
                                     self.ttrans.position())):
            print 'restoring table to saved positions', saved_pos
            self._simultaneous_move(*saved_pos)

        def do_centrebeam():
            with cleanup(restore_live):
                self.sample_video_device.video_live = False
                res = self.bv_device.GetPosition()

            by = res[2]
            bz = res[3]
            if -1 in (by, bz):
                raise RuntimeError("Could not find beam")

            dy = (by - (img_width / 2)) / px_mm_y
            dz = (bz - (img_height / 2)) / px_mm_z
            if abs(dy) > 0.1 or abs(dz) > 0.1:
                raise RuntimeError(
                    "Aborting centrebeam, displacement is too much")

            with error_cleanup(restore_table):
                print "moving ttrans by", -dy
                print "moving tz1,tz2,tz3 by", -dz
                self._simultaneous_rmove(self.ttrans, -dy, self.tz1, -dz,
                                         self.tz2, -dz, self.tz3, -dz)
            return dy, dz

        with cleanup(restore_slits, restore_att, self.fshut.close):
            self.transmission.set(0.5)
            self.detcover.set_in()
            self.move_beamstop_out()
            self.fshut.open()
            self._simultaneous_move(self.hgap, 2, self.vgap, 2)

            for i in range(5):
                dy, dz = do_centrebeam()
                if abs(dy) < 0.001 and abs(dz) < 0.001:
                    break

    def move_to_sample_loading_position(self, holder_length=22):
        move_task = self._simultaneous_move(self.phix,
                                            1.25,
                                            self.phiy,
                                            22,
                                            self.phiz,
                                            0,
                                            self.sampx,
                                            0,
                                            self.sampy,
                                            0,
                                            self.omega,
                                            0,
                                            self.zoom,
                                            1,
                                            wait=False)
        self.wago.set("swpermit", 0)
        self.wago.set("SCcryoctrl", 0)
        self.wago.set("fldin", 0)
        self.wago.set("scntin", 0)
        self.wago.set("laserin", 0)
        self.wago.set("cryosh", 0)
        self.move_beamstop_out()
        self.lightout()
        self.wago.set("swpermit", 1)
        self.wago.set("SCcryoctrl", 1)
        move_task.get()

        if not self.wago.get("mdpermit"):
            raise RuntimeError("Sample changer: transfer refused")

    def prepare_centring(self):
        self.wago.set("swpermit", 0)
        move_task = self._simultaneous_move(self.bstopz,
                                            -80,
                                            self.phix,
                                            0.0,
                                            self.phiy,
                                            22,
                                            self.phiz,
                                            0,
                                            self.sampx,
                                            0,
                                            self.sampy,
                                            0,
                                            self.omega,
                                            0,
                                            self.zoom,
                                            1,
                                            wait=False)
        try:
            self.lightin()
            self.wago.set("lightctrl", 0.3)
        finally:
            move_task.get()

    def quick_realign(self):
        self.centrebeam()
        self.i1.autorange(True)

        def restore(old_transmission=self.transmission.get(),
                    old_slits=(self.hgap, self.hgap.position(), self.vgap,
                               self.vgap.position())):
            self.transmission.set(old_transmission)
            self._simultaneous_move(*old_slits)
            self.fshut.close()

        with cleanup(restore):
            self._simultaneous_move(self.hgap, 1.6, self.vgap, 0.2)
            self.move_beamstop_in()
            self.transmission.set(10)

            dscan(self.vtrans, -0.2 * 1.5, 0.2 * 1.5, 20, 0, self.i1)
            a = last_scan_data()
            vtrans_max = a[numpy.argmax(a[:, 1]), 0]
            print "moving vert. trans to", vtrans_max
            self.vtrans.move(vtrans_max)

            dscan(self.htrans, -1.6 * 1.5, 1.6 * 1.5, 20, 0, self.i1)
            a = last_scan_data()
            htrans_max = a[numpy.argmax(a[:, 1]), 0]
            print "moving hor. trans to", htrans_max
            self.htrans.move(htrans_max)