class wa(Macro): """Show all motor positions""" # TODO: duplication of the default value definition is a workaround # for #427. See commit message cc3331a for more details. param_def = [ ['filter', ParamRepeat(['filter', Type.String, '.*', 'a regular expression filter'], min=1), ['.*'], 'a regular expression filter'], ] def prepare(self, filter, **opts): self.all_motors = self.findObjs(filter, type_class=Type.Moveable) self.table_opts = {} def run(self, filter): nr_motors = len(self.all_motors) if nr_motors == 0: self.output('No motor defined') return show_dial = self.getViewOption(ViewOption.ShowDial) if show_dial: self.output('Current positions (user, dial) on %s' % datetime.datetime.now().isoformat(' ')) else: self.output('Current positions (user) on %s' % datetime.datetime.now().isoformat(' ')) self.output('') self.execMacro('_wm', self.all_motors, **self.table_opts)
class _ls(Macro): # TODO: duplication of the default value definition is a workaround # for #427. See commit message cc3331a for more details. param_def = [ ['filter', ParamRepeat(['filter', Type.String, ".*", 'a regular expression filter'], min=1), [".*"], 'a regular expression filter'], ] def get_column_names(self): cols = [] for col in self.cols: if isinstance(col, tuple): col = col[0] cols.append(col) return cols def get_column_members(self): cols = [] for col in self.cols: if isinstance(col, tuple): col = col[1] cols.append(col.lower()) return cols def run(self, *filter): self.warning('This macro is not intended to be executed directly by ' 'the user') return
class wa(Macro): """Show all motor positions""" param_def = [ [ 'filter', ParamRepeat( ['filter', Type.String, '.*', 'a regular expression filter'], min=1), '.*', 'a regular expression filter' ], ] def prepare(self, filter, **opts): self.all_motors = self.findObjs(filter, type_class=Type.Moveable) self.table_opts = {} def run(self, filter): nr_motors = len(self.all_motors) if nr_motors == 0: self.output('No motor defined') return show_dial = self.getViewOption(ViewOption.ShowDial) if show_dial: self.output('Current positions (user, dial) on %s' % datetime.datetime.now().isoformat(' ')) else: self.output('Current positions (user) on %s' % datetime.datetime.now().isoformat(' ')) self.output('') self.execMacro('_wm', self.all_motors, **self.table_opts)
class _wum(Macro): """Show user motor positions""" param_def = [ ['motor_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move']), None, 'List of motor to show'], ] def prepare(self, motor_list, **opts): self.table_opts = {} def run(self, motor_list): motor_width = 9 motor_names = [] motor_pos = [] motor_list = sorted(motor_list) for motor in motor_list: name = motor.getName() motor_names.append([name]) pos = motor.getPosition(force=True) if pos is None: pos = float('NAN') motor_pos.append((pos,)) motor_width = max(motor_width, len(name)) fmt = '%c*.%df' % ('%', motor_width - 5) table = Table(motor_pos, elem_fmt=[fmt], col_head_str=motor_names, col_head_width=motor_width, **self.table_opts) for line in table.genOutput(): self.output(line)
class defmeas(Macro): """Create a new measurement group. First channel in channel_list MUST be an internal sardana channel. At least one channel MUST be a Counter/Timer (by default, the first Counter/Timer in the list will become the master).""" param_def = [ ['name', Type.String, None, 'Measurement group name'], ['channel_list', ParamRepeat(['channel', Type.String, None, 'Measurement Channel'],), None, 'List of measurement channels'], ] def prepare(self, name, channel_list, **opts): mntgrp_list = self.findObjs(name, type_class=Type.MeasurementGroup) if len(mntgrp_list) != 0: raise Exception( 'A measurement group with that name already exists') def run(self, name, channel_list): channel0 = self.getObj(channel_list[0]) pool = channel0.getPoolObj() mg = pool.createMeasurementGroup(name, channel_list) self.print("Created %s" % str(mg))
class senv(Macro): """Sets the given environment variable to the given value""" param_def = [ [ 'name', Type.Env, None, 'Environment variable name. Can be one of the following:\n' ' - <name> - global variable\n' ' - <full door name>.<name> - variable value for a specific door\n' ' - <macro name>.<name> - variable value for a specific macro\n' ' - <full door name>.<macro name>.<name> - variable value for a specific macro running on a specific door' ], [ 'value_list', ParamRepeat(['value', Type.String, None, 'environment value item'], min=1), None, 'value(s). one item will eval to a single element. More than one item will eval to a tuple of elements' ], ] def run(self, env, value): if len(value) == 1: value = value[0] else: value = '(%s)' % ', '.join(value) k, v = self.setEnv(env, value) line = '%s = %s' % (k, str(v)) self.output(line)
class defctrl(Macro): """Creates a new controller 'role_prop' is a sequence of roles and/or properties. - A role is defined as <role name>=<role value> (only applicable to pseudo controllers) - A property is defined as <property name> <property value> If both roles and properties are supplied, all roles must come before properties. All controller properties that don't have default values must be given. Example of creating a motor controller (with a host and port properties): [1]: defctrl SuperMotorController myctrl host homer.springfield.com port 5000 Example of creating a Slit pseudo motor (sl2t and sl2b motor roles, Gap and Offset pseudo motor roles): [1]: defctrl Slit myslit sl2t=mot01 sl2b=mot02 Gap=gap01 Offset=offset01""" param_def = [['class', Type.ControllerClass, None, 'controller class'], ['name', Type.String, None, 'new controller name'], ['roles_props', ParamRepeat(['role_prop', Type.String, None, 'a role or property item'], min=0), None, 'roles and/or properties']] def run(self, ctrl_class, name, props): pool = ctrl_class.getPoolObj() elem = pool.createController(ctrl_class.name, name, *props) self.print("Created %s" % str(elem))
class mv(Macro): """Move motor(s) to the specified position(s)""" param_def = [ [ 'motor_pos_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move'], ['pos', Type.Float, None, 'Position to move to']), None, 'List of motor/position pairs' ], ] def run(self, motor_pos_list): motors, positions = [], [] for m, p in motor_pos_list: motors.append(m) positions.append(p) self.debug("Starting %s movement to %s", m.getName(), p) motion = self.getMotion(motors) state, pos = motion.move(positions) if state != DevState.ON: self.warning("Motion ended in %s", state) msg = [] for motor in motors: msg.append(motor.information()) self.info("\n".join(msg))
class wum(Macro): """Show the user position of the specified motors.""" param_def = [ ['motor_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to see where it is']), None, 'List of motor to show'], ] def prepare(self, motor_list, **opts): self.table_opts = {} def run(self, motor_list): motor_width = 10 motor_names = [] motor_pos = [] for motor in motor_list: name = motor.getName() motor_names.append([name]) posObj = motor.getPositionObj() upos = map(str, [posObj.getMaxValue(), motor.getPosition( force=True), posObj.getMinValue()]) pos_data = [''] + upos motor_pos.append(pos_data) elem_fmt = (['%*s'] + ['%*s'] * 3) * 2 row_head_str = ['User', ' High', ' Current', ' Low', ] table = Table(motor_pos, elem_fmt=elem_fmt, row_head_str=row_head_str, col_head_str=motor_names, col_head_width=motor_width, **self.table_opts) for line in table.genOutput(): self.output(line)
class reg2scan(Macro): """reg2scan. Do an absolute scan of the specified motors with different number of intervals for each region. It uses the gscan framework. All the motors will be drived to the same position in each step """ hints = {'scan': 'reg2scan'} env = ('ActiveMntGrp',) param_def = [ ['motor1', Type.Moveable, None, 'Motor to move'], ['motor2', Type.Moveable, None, 'Motor to move'], ['integ_time', Type.Float, None, 'Integration time'], ['start_pos', Type.Float, None, 'Start position'], ['step_region', ParamRepeat(['next_pos', Type.Float, None, 'next position'], ['region_nr_intervals', Type.Float, None, 'Region number of intervals']), None, 'List of tuples: (next_pos, region_nr_intervals'] ] def prepare(self, motor1, motor2, integ_time, start_pos, regions, **opts): self.name = 'reg2scan' self.integ_time = integ_time self.start_pos = start_pos self.regions = regions self.regions_count = len(self.regions) / 2 generator = self._generator moveables = [motor1, motor2] env = opts.get('env', {}) constrains = [] self._gScan = SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} step["integ_time"] = self.integ_time point_id = 0 region_start = self.start_pos for r in range(len(self.regions)): region_stop, region_nr_intervals = self.regions[ r][0], self.regions[r][1] positions = numpy.linspace( region_start, region_stop, region_nr_intervals + 1) if region_start != self.start_pos: # positions must be calculated from the start to the end of the region # but after the first region, the 'start' point must not be # repeated positions = positions[1:] for p in positions: step['positions'] = [p, p] step['point_id'] = point_id point_id += 1 yield step region_start = region_stop def run(self, *args): for step in self._gScan.step_scan(): yield step
class call_wm(Macro): param_def = [ ['motor_list', ParamRepeat(['motor', Type.Motor, None, 'Motor to move']), None, 'List of motor to show'], ] def run(self, m): self.macros.wm(m)
class pwm(Macro): """Show the position of the specified motors in a pretty table""" param_def = [ ['motor_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move']), None, 'List of motor to show'], ] def run(self, motor_list): self.execMacro('wm', motor_list, **Table.PrettyOpts)
class pwa(Macro): """Show all motor positions in a pretty table""" param_def = [ ['filter', ParamRepeat(['filter', Type.String, '.*', 'a regular expression filter'], min=1), '.*', 'a regular expression filter'], ] def run(self, filter): self.execMacro('wa', filter, **Table.PrettyOpts)
class udefelem(Macro): """Deletes an existing element(s)""" param_def = [ ['elements', ParamRepeat(['element', Type.Element, None, 'element name'], min=1), None, 'List of element(s) name'], ] def run(self, elements): for element in elements: pool = element.getPoolObj() pool.deleteElement(element.getName())
class usenv(Macro): """Unsets the given environment variable""" param_def = [ [ 'environment_list', ParamRepeat(['env', Type.Env, None, 'Environment variable name'], min=1), None, 'List of environment items to be removed' ], ] def run(self, env): self.unsetEnv(env) self.output("Success!")
class amptekConf(Macro, AmptekMacro): """ This macro configure the Amptek parameters: * Total Gain (GAIN) * Peaking Time (PT) * Low threshold (BGR) * Number of channels (MCAC): 512, 1024, 2046, 4096, 8192 If you don't pass any parameter the macro shows you the current configuration. """ PARAMS_CMD = {'GAIN': 'GAIN', 'PT': 'TPEA', 'MCAC': 'MCAC', 'BGR': 'THSL'} param_def = [[ 'param_list', ParamRepeat([ 'Param', Type.String, None, ('Name of the parameter (GAIN, MCAC, ' 'PT and BGD)') ], ['Value', Type.Float, None, 'Value '], min=0, max=4), None, 'List of parameters, example: sca1 100 800' ]] def prepare(self, *args): self.CMD_PARAMS = {} for param, cmd in self.PARAMS_CMD.items(): self.CMD_PARAMS[cmd] = param def run(self, *param_list): self.initAmptek(True) if param_list is not None: param_allow = self.PARAMS_CMD.keys() new_config = {} for param, value in param_list: param = param.upper() if param not in param_allow: raise ValueError('The allower paramters are: %s' % repr(param_allow)) cmd = self.PARAMS_CMD[param] new_config[cmd] = value self.info('Setting configuration....') self.writeConfig(new_config) config = self.readConfig(self.CMD_PARAMS.keys()) self.info('Amptek configuration') for cmd, value in config.items(): msg = '%s: %s' % (self.CMD_PARAMS[cmd], value) self.info(msg)
class pwa(Macro): """Show all motor positions in a pretty table""" # TODO: duplication of the default value definition is a workaround # for #427. See commit message cc3331a for more details. param_def = [ ['filter', ParamRepeat(['filter', Type.String, '.*', 'a regular expression filter'], min=1), ['.*'], 'a regular expression filter'], ] def run(self, filter): self.execMacro('wa', filter, **Table.PrettyOpts)
class send2ctrl(Macro): """Sends the given data directly to the controller""" param_def = [['controller', Type.Controller, None, 'Controller name'], ['data', ParamRepeat(['string item', Type.String, None, 'a string item'],), None, 'data to be sent']] def run(self, controller, data): name = controller.getName() pool = controller.getPoolObj() str_data = " ".join(data) res = pool.SendToController([name, str_data]) self.output(res)
class lsenv(Macro): """Lists the environment in alphabetical order""" param_def = [ [ 'macro_list', ParamRepeat(['macro', Type.MacroClass, None, 'macro name'], min=0), None, 'List of macros to show environment' ], ] def prepare(self, macro_list, **opts): self.table_opts = opts def run(self, macro_list): # list the environment for the current door if len(macro_list) == 0: # list All the environment for the current door out = List(['Name', 'Value', 'Type']) env = self.getAllDoorEnv() names_list = list(env.keys()) names_list.sort(key=str.lower) for k in names_list: str_val = self.reprValue(env[k]) type_name = type(env[k]).__name__ out.appendRow([k, str_val, type_name]) # list the environment for the current door for the given macros else: out = List(['Macro', 'Name', 'Value', 'Type']) for macro in macro_list: env = self.getEnv(key=None, macro_name=macro.name) names_list = list(env.keys()) names_list.sort(key=str.lower) for k in names_list: str_val = self.reprValue(env[k]) type_name = type(env[k]).__name__ out.appendRow([macro.name, k, str_val, type_name]) for line in out.genOutput(): self.output(line) def reprValue(self, v, max=54): # cut long strings v = str(v) if len(v) > max: v = '%s [...]' % v[:max] return v
class udefmeas(Macro): """Deletes existing measurement groups""" param_def = [ [ 'mntgrps', ParamRepeat([ 'mntgrp', Type.MeasurementGroup, None, 'Measurement group name' ], min=1), None, 'List of measurement group names' ], ] def run(self, mntgrps): for mntgrp in mntgrps: pool = mntgrp.getPoolObj() pool.deleteMeasurementGroup(mntgrp.getName())
class defgh(Macro): """Define general hook: >>> defgh "mv [[mot02 9]]" pre-scan >>> defgh "ct 0.1" pre-scan >>> defgh lsm pre-scan >>> defgh "mv mot03 10" pre-scan >>> defgh "Print 'Hello world'" pre-scan .. note:: The `defgh` macro has been included in Sardana on a provisional basis. Backwards incompatible changes (up to and including its removal) may occur if deemed necessary by the core developers. """ param_def = [ [ 'macro_name', Type.String, None, ('Macro name with parameters. ' 'Ex.: "mv exp_dmy01 10"') ], [ 'hookpos_list', ParamRepeat(['position', Type.String, None, 'macro name'], min=1), None, 'List of positions where the hook has to be executed' ], ] def run(self, macro_name, position): self.info("Defining general hook") self.output(macro_name) try: macros_list = self.getEnv("_GeneralHooks") except UnknownEnv: macros_list = [] hook_tuple = (macro_name, position) self.debug(hook_tuple) macros_list.append(hook_tuple) self.setEnv("_GeneralHooks", macros_list) self.debug("General hooks:") self.debug(macros_list)
class home_from_hardlimit(Macro): MAX_LIM_RETRY = 5 param_def = [[ "motor_list", ParamRepeat(['motor', Type.Motor, None, 'Motor to be homed.']), None, "List of motors to be homed" ]] result_def = [["homed", Type.Boolean, False, "Is operation successful"]] def prepare(self, *args, **kwargs): motor_list = args self.physical_motors = setup_motors_configuration(self, motor_list) def run(self, *args): res = execute_homing_from_hardlimit(self, self.physical_motors) return res
class pt9(Macro): """Same as macro pt7 but with old style ParamRepeat. If you are writing a macro with variable number of parameters for the first time don't even bother to look at this example since it is DEPRECATED. Usages from Spock, ex.: pt9 [[mot1 1][mot2 3]] pt9 mot1 1 mot2 3 """ param_def = [ [ 'm_p_pair', ParamRepeat(['motor', Type.Motor, None, 'Motor to move'], ['pos', Type.Float, None, 'Position to move to'], min=1, max=2), None, 'List of motor/position pairs' ], ] def run(self, *args, **kwargs): pass
class mvr(Macro): """Move motor(s) relative to the current position(s)""" param_def = [ ['motor_disp_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move'], ['disp', Type.Float, None, 'Relative displacement']), None, 'List of motor/displacement pairs'], ] def run(self, motor_disp_list): motor_pos_list = [] for motor, disp in motor_disp_list: pos = motor.getPosition(force=True) if pos is None: self.error("Cannot get %s position" % motor.getName()) return else: pos += disp motor_pos_list.append([motor, pos]) self.execMacro('mv', motor_pos_list)
class amptekRois(Macro, AmptekMacro): """ This macro configure the Amptek ROIs from the 1th to 7th hardware ROIs. If you don't pass any parameter the macro shows you the current configuration. """ #There is only for SCA connected to the NI6601 and it is the same as the GUI LAST_SCA = 4 param_def = [[ 'sca_list', ParamRepeat(['Number', Type.Integer, None, 'SCA channel'], ['Low_Value', Type.Integer, None, 'Low threshold '], ['High_Value', Type.Integer, None, 'High threshold'], min=0, max=6), None, 'List of SCA configuration, example: sca1 100 800' ]] def run(self, *sca_list): self.initAmptek() if sca_list is not None: for index, low_value, high_value in sca_list: if index < 0 or low_value < 0 or high_value < 0: raise ValueError('The values must be positive') if low_value >= high_value: raise self.setRoi(index, low_value, high_value) self.info('Setting SCAs...') self.writeRois() self.info('SCAs configuration') for i in range(self.FIRST_SCA, self.LAST_SCA + 1): low, high = self.getRoi(i) msg = 'ROI%d: [%d, %d]' % (i, low, high) self.info(msg)
class udefctrl(Macro): """Deletes existing controllers""" param_def = [ [ 'controllers', ParamRepeat( ['controller', Type.Controller, None, 'controller name'], min=1), None, 'List of controller(s) name(s)' ], ] def run(self, controllers): for controller in controllers: pool = controller.getPoolObj() ctrl_name = controller.getName() try: pool.deleteController(ctrl_name) except Exception: msg = "{0} and subsequent controllers (if any) "\ "could not be deleted".format(ctrl_name) self.error(msg) raise
class meas_enable_ch(Macro): """ Enable the Counter Timers selected """ param_def = [ [ 'MeasurementGroup', Type.MeasurementGroup, None, "Measurement Group to work" ], [ 'ChannelState', ParamRepeat([ 'channel', Type.ExpChannel, None, 'Channel to change ' 'state' ], min=1), None, 'List of channels to Enable' ], ] def run(self, mntGrp, channels): mg_manager = MGManager(self, mntGrp, channels) mg_manager.enable_channels()
class lima_image_header(Macro): """Defines a list of image headers Example: lima_image_header my_device "0;beam_x=1024|beam_y=1024" "1;beam_x=1024|beam_y=1024" ... """ param_def = [ ['dev', Type.String, None, 'Device name or alias'], [ 'header_list', ParamRepeat([ 'header', Type.String, None, 'Header definition syntax: IMAGE_ID;key1=value1|key2=value2|key3=value3 ...' ]), None, 'List of header definitions' ] ] # @catch_error def run(self, *args): dev = args[0] headers = args[1] lima = taurus.Device(dev) lima.write_attribute('saving_header_delimiter', ['=', '|', ';']) lima.setImageHeader(headers)
class _wm(Macro): """Show motor positions""" param_def = [ [ 'motor_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move']), None, 'List of motor to show' ], ] def run(self, motor_list): show_dial = self.getViewOption(ViewOption.ShowDial) show_ctrlaxis = self.getViewOption(ViewOption.ShowCtrlAxis) pos_format = self.getViewOption(ViewOption.PosFormat) motor_width = 9 motors = {} # dict(motor name: motor obj) requests = {} # dict(motor name: request id) data = {} # dict(motor name: list of motor data) # sending asynchronous requests: neither Taurus nor Sardana extensions # allow asynchronous requests - use PyTango asynchronous request model for motor in motor_list: name = motor.getName() motors[name] = motor args = ('position', ) if show_dial: args += ('dialposition', ) _id = motor.read_attributes_asynch(args) requests[name] = _id motor_width = max(motor_width, len(name)) data[name] = [] # get additional motor information (ctrl name & axis) if show_ctrlaxis: for name, motor in motors.iteritems(): ctrl_name = self.getController(motor.controller).name axis_nb = str(getattr(motor, "axis")) data[name].extend((ctrl_name, axis_nb)) motor_width = max(motor_width, len(ctrl_name), len(axis_nb)) # collect asynchronous replies while len(requests) > 0: req2delete = [] for name, _id in requests.iteritems(): motor = motors[name] try: attrs = motor.read_attributes_reply(_id) for attr in attrs: value = attr.value if value == None: value = float('NaN') data[name].append(value) req2delete.append(name) except PyTango.AsynReplyNotArrived, e: continue except PyTango.DevFailed: data[name].append(float('NaN')) if show_dial: data[name].append(float('NaN')) req2delete.append(name) self.debug('Error when reading %s position(s)' % name) self.debug('Details:', exc_info=1) continue # removing motors which alredy replied for name in req2delete: requests.pop(name)
class wm(Macro): """Show the position of the specified motors.""" param_def = [ [ 'motor_list', ParamRepeat( ['motor', Type.Moveable, None, 'Motor to see where it is']), None, 'List of motor to show' ], ] def prepare(self, motor_list, **opts): self.table_opts = {} def run(self, motor_list): motor_width = 10 motor_names = [] motor_pos = [] show_dial = self.getViewOption(ViewOption.ShowDial) show_ctrlaxis = self.getViewOption(ViewOption.ShowCtrlAxis) pos_format = self.getViewOption(ViewOption.PosFormat) for motor in motor_list: max_len = 0 if show_ctrlaxis: axis_nb = getattr(motor, "axis") ctrl_name = self.getController(motor.controller).name max_len = max(max_len, len(ctrl_name), len(str(axis_nb))) name = motor.getName() max_len = max(max_len, len(name)) max_len = max_len + 5 if max_len < 14: max_len = 14 # Length of 'Not specified' str_fmt = "%c%ds" % ('%', int(max_len)) name = str_fmt % name motor_names.append([name]) posObj = motor.getPositionObj() if pos_format > -1: fmt = '%c.%df' % ('%', int(pos_format)) try: val1 = fmt % motor.getPosition(force=True) val1 = str_fmt % val1 except: val1 = str_fmt % motor.getPosition(force=True) val2 = str_fmt % posObj.getMaxValue() val3 = str_fmt % posObj.getMinValue() if show_ctrlaxis: valctrl = str_fmt % (ctrl_name) valaxis = str_fmt % str(axis_nb) upos = map(str, [valctrl, valaxis, ' ', val2, val1, val3]) else: upos = map(str, ['', val2, val1, val3]) pos_data = upos if show_dial: try: val1 = fmt % motor.getDialPosition(force=True) val1 = str_fmt % val1 except: val1 = str_fmt % motor.getDialPosition(force=True) dPosObj = motor.getDialPositionObj() val2 = str_fmt % dPosObj.getMaxValue() val3 = str_fmt % dPosObj.getMinValue() dpos = map(str, [val2, val1, val3]) pos_data += [''] + dpos motor_pos.append(pos_data) elem_fmt = (['%*s'] + ['%*s'] * 5) * 2 row_head_str = [] if show_ctrlaxis: row_head_str += ['Ctrl', 'Axis'] row_head_str += ['User', ' High', ' Current', ' Low'] if show_dial: row_head_str += ['Dial', ' High', ' Current', ' Low'] table = Table(motor_pos, elem_fmt=elem_fmt, row_head_str=row_head_str, col_head_str=motor_names, col_head_width=motor_width, **self.table_opts) for line in table.genOutput(): self.output(line)