Beispiel #1
0
 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)))
Beispiel #2
0
 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)))
Beispiel #3
0
    def test_group_get_position(self):
        # group creation
        mymot1 = get_axis("mymot1")
        mymot2 = get_axis("mymot2")
        mygrp = Group(mymot1, mymot2)

        #mymot1.controller.log_level(3)
        pos_list = mygrp.position()
        #mymot1.controller.log_level(3)
        for axis in pos_list:
            self.assertEqual(axis.position(), pos_list[axis])
Beispiel #4
0
    def test_group_get_position(self):
        # group creation
        mymot1 = get_axis("mymot1")
        mymot2= get_axis("mymot2")
        mygrp = Group(mymot1, mymot2)

        #mymot1.controller.log_level(3)
        pos_list = mygrp.position()
        #mymot1.controller.log_level(3)
        for axis in pos_list:
            self.assertEqual(axis.position(), pos_list[axis])
Beispiel #5
0
    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")
Beispiel #6
0
    def test_group_creation(self):
        # group creation
        mymot1 = get_axis("mymot1")
        mymot2 = get_axis("mymot2")
        mygrp = Group(mymot1, mymot2)

        self.assertTrue(mygrp)
Beispiel #7
0
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)
Beispiel #8
0
    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")
Beispiel #9
0
    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")
Beispiel #10
0
    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]
Beispiel #11
0
    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")
Beispiel #12
0
 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)
Beispiel #13
0
 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)
Beispiel #14
0
    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)
Beispiel #15
0
    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)
Beispiel #16
0
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()