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 _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 test_group_move(self): # group creation mymot1 = get_axis("mymot1") mymot2 = get_axis("mymot2") mygrp = Group(mymot1, mymot2) pos_list = mygrp.position() pos_list[mymot1] += 0.1 # waits for the end of motions mygrp.move(pos_list) self.assertEqual(mygrp.state(), "READY")
def test_group_move(self): # group creation mymot1 = get_axis("mymot1") mymot2= get_axis("mymot2") mygrp = Group(mymot1, mymot2) pos_list = mygrp.position() pos_list[mymot1] += 0.1 # waits for the end of motions mygrp.move(pos_list) self.assertEqual(mygrp.state(), "READY")
def test_group_stop(self): # group creation mymot1 = get_axis("mymot1") mymot2 = get_axis("mymot2") mygrp = Group(mymot1, mymot2) pos_list = mygrp.position() pos_list[mymot1] -= 0.1 # non blocking call mygrp.move(pos_list, wait=False) # waits for the end of motions mygrp.stop() self.assertEqual(mygrp.state(), "READY")
def test_group_stop(self): # group creation mymot1 = get_axis("mymot1") mymot2= get_axis("mymot2") mygrp = Group(mymot1, mymot2) pos_list = mygrp.position() pos_list[mymot1] -= 0.1 # non blocking call mygrp.move(pos_list, wait=False) # waits for the end of motions mygrp.stop() self.assertEqual(mygrp.state(), "READY")
def a2scan( motor1, start1, stop1, motor2, start2, stop2, npoints, count_time, * counters, **kwargs): save_flag = kwargs.get("save", True) dm = DataManager() filename = kwargs.get("filename", SCANFILE) logging.getLogger().info( "Scanning %s from %f to %f and %s from %f to %f in %d points" % (motor1.name, start1, stop1, motor2.name, start2, stop2, npoints)) motors = [motor1, motor2] scan = dm.new_scan(filename, motors, npoints, counters, save_flag) start_pos1 = motor1.position() start_pos2 = motor2.position() motor_group = Group(motor1, motor2) def scan_cleanup(): logging.getLogger().info( "Returning motor %s to %f and motor %s to %f" % (motor1.name, start_pos1, motor2.name, start_pos2)) motor_group.move(motor1, start_pos1, motor2, start_pos2) motor_group.move(motor1, start1, motor2, start2) ipoint = 0 countlabellen = len("{0:d}".format(npoints)) countformatstr = "{0:" + "{0:d}".format(countlabellen) + "d}" s1 = numpy.linspace(start1, stop1, npoints) s2 = numpy.linspace(start2, stop2, npoints) with cleanup(scan.end): with error_cleanup(scan_cleanup): for ii in range(npoints): ipoint = ipoint + 1 motor_group.move(motor1, s1[ii], motor2, s2[ii]) acquisitions = [] values = [m.position() for m in (motor1, motor2)] for counter in counters: acquisitions.append(gevent.spawn(counter.read, count_time)) gevent.joinall(acquisitions) values.extend([a.get() for a in acquisitions]) # print values scan.add(values)
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)
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 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)
class CalcController(Controller): def __init__(self, *args, **kwargs): Controller.__init__(self, *args, **kwargs) self._reals_group = None self._write_settings = False self._motion_control = False def initialize(self): for axis in self.pseudos: self.get_axis(axis.name) def _update_refs(self): Controller._update_refs(self) self.reals = [] for real_axis in self._tagged['real']: # check if real axis is really from another controller if real_axis.controller == self: raise RuntimeError( "Real axis '%s` doesn't exist" % real_axis.name) self.reals.append(real_axis) event.connect(real_axis, 'position', self._calc_from_real) event.connect(real_axis, 'state', self._update_state_from_real) self._reals_group = Group(*self.reals) event.connect(self._reals_group, 'move_done', self._real_move_done) self.pseudos = [ axis for axis_name, axis in self.axes.iteritems() if axis not in self.reals] def _updated_from_channel(self, setting_name): #print [axis.settings.get_from_channel(setting_name) for axis in self.reals] return any([axis.settings.get_from_channel(setting_name) for axis in self.reals]) def _do_calc_from_real(self): real_positions_by_axis = self._reals_group.position() real_positions = dict() for tag, axis_list in self._tagged.iteritems(): if len(axis_list) > 1: continue axis = axis_list[0] if axis in self.reals: real_positions[tag] = real_positions_by_axis[axis] return self.calc_from_real(real_positions) def _calc_from_real(self, *args, **kwargs): new_positions = self._do_calc_from_real() for tagged_axis_name, position in new_positions.iteritems(): axis = self._tagged[tagged_axis_name][0] if axis in self.pseudos: if self._write_settings and not self._motion_control: axis.settings.set("_set_position", axis.dial2user(position), write=True) #print 'calc from real', axis.name, position, self._write_settings axis.settings.set("dial_position", position, write=self._write_settings) axis.settings.set("position", axis.dial2user(position), write=False) else: raise RuntimeError("cannot assign position to real motor") def calc_from_real(self, real_positions): """Return a dict { pseudo motor tag: new position, ... }""" raise NotImplementedError def _update_state_from_real(self, *args, **kwargs): self._write_settings = not self._updated_from_channel('state') state = self._reals_group.state() for axis in self.pseudos: #print '_update_state_from_real', axis.name, str(state) axis.settings.set("state", state, write=self._write_settings) def _real_move_done(self, done): if done: #print 'MOVE DONE' self._motion_control = False self._write_settings = False for axis in self.pseudos: if axis.encoder: # check position and raise RuntimeError if encoder # position doesn't correspond to axis position # (MAXE_E) axis._do_encoder_reading() def initialize_axis(self, axis): if axis in self.pseudos: self._calc_from_real() self._update_state_from_real() def start_one(self, motion): positions_dict = dict() axis_tag = None for tag, axis_list in self._tagged.iteritems(): if len(axis_list) > 1: continue x = axis_list[0] if x in self.pseudos: if x == motion.axis: axis_tag = tag positions_dict[tag] = motion.target_pos else: positions_dict[tag] = x._set_position() move_dict = dict() for axis_tag, target_pos in self.calc_to_real(axis_tag, positions_dict).iteritems(): real_axis = self._tagged[axis_tag][0] move_dict[real_axis] = target_pos self._write_settings = True self._motion_control = True # force a global position update in case phys motors never move self._calc_from_real() self._reals_group.move(move_dict, wait=False) def calc_to_real(self, axis_tag, positions_dict): raise NotImplementedError def stop(self, axis): self._reals_group.stop() def read_position(self, axis): return axis.settings.get("dial_position") def state(self, axis, new_state=None): return self._reals_group.state() def set_position(self, axis, new_pos): if not axis in self.pseudos: raise RuntimeError("Cannot set dial position on motor '%s` from CalcController" % axis.name) dial_pos = new_pos / axis.steps_per_unit positions = self._do_calc_from_real() for tag, axis_list in self._tagged.iteritems(): if len(axis_list) > 1: continue if axis in axis_list: positions[tag]=dial_pos real_positions = self.calc_to_real(tag, positions) for real_axis_tag, user_pos in real_positions.iteritems(): self._tagged[real_axis_tag][0].position(user_pos) break self._calc_from_real() return axis.position()