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()
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 __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 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 __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
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)
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
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)
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)
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))
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
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
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)
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]
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)
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()
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}})
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()
def __init__(self, name, config): SamplingCounter.__init__(self, name, None) tango_uri = config["uri"] self.__control = DeviceProxy(tango_uri)
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")
def __init__(self, device, attributes=None): if attributes is not None: self.attributes = attributes self.device = DeviceProxy(device)
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)
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)
def __is_tango_device(name): try: return DeviceProxy(name) is not None except: pass return False
def initialize(self): # Get a proxy on Insertion Device device server of the beamline. self.device = DeviceProxy(self.ds_name)
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
def init(self): self._debug("TangoDeviceServer::init()") if self._proxy is None: self._proxy = DeviceProxy(self._tango_url)
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
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 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"))
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)