def _generateSequence(self, target): seq = [] current = [int(dev.read(0)) for dev in self._attached_ephvs] if all(v == 0 for v in target): # shut down without ramp via capacitors subseq = [] for (i, dev) in enumerate(self._attached_ephvs): if current[i] <= 10: continue subseq.append(SeqMethod(dev, 'start', 0)) if subseq: seq.append(subseq) seq.append(SeqMethod(self, '_wait_for_shutdown')) else: while True: subseq = [] for (i, dev) in enumerate(self._attached_ephvs): if target[i] - 5 <= current[i] <= target[i] + 10: continue if target[i] > current[i]: setval = min(current[i] + self.voltagestep, target[i]) elif target[i] < current[i]: setval = max(current[i] - self.voltagestep, target[i]) subseq.append(SeqMethod(dev, 'start', setval)) current[i] = setval if not subseq: break seq.extend(subseq) seq.append(SeqSleep(self.stepsettle)) # final settle if seq: seq.append(SeqSleep(self.finalsettle)) return seq
def _generateSequence(self, target): seq = [] if not self.isAtTarget(self.read(0)): # self.reset() # session.delay(2) # switch on hardware if True or self.autoonoff: # ask why on/off automatic is needed seq.append(SeqDev(self._attached_a2_powvalunit, 1)) seq.append(SeqSleep(2)) seq.append(SeqDev(self._attached_a2_lgon, 1)) seq.append(SeqSleep(2)) # necessary for initialisation of logo seq.append(SeqDev(self._attached_a2_press, 1)) seq.append(SeqSleep(2)) seq.append(SeqMethod(self, '_checkpower', 1)) # we have to make a case differentiation because # the order of execution is important ! if target == 'cover': seq.append(SeqDev(self._attached_frame, 'out')) seq.append(SeqDev(self._attached_cover, 'in')) elif target == 'frame': seq.append(SeqDev(self._attached_cover, 'out')) seq.append(SeqDev(self._attached_frame, 'in')) elif target == 'open': seq.append(SeqDev(self._attached_cover, 'out')) seq.append(SeqDev(self._attached_frame, 'out')) if self.autoonoff: # and self.doStatus(0)[0] == status.OK seq.append(SeqDev(self._attached_a2_powvalunit, 0)) seq.append(SeqDev(self._attached_a2_lgon, 0)) seq.append(SeqDev(self._attached_a2_press, 0)) seq.append(SeqSleep(self.chkmotiontime)) seq.append(SeqMethod(self, '_checkpower', 0)) return seq
def _generateSequence(self, target): seq = [] pos = self.read(0) self._save_pos() xpos = self._beamstop_pos[pos] seq.append((SeqDev(self._attached_y, -450), SeqDev(self._attached_x, xpos))) seq.append(SeqMethod(self, '_testArrival', xpos, -450.)) seq.append(SeqLimDev(self._attached_y, -549, -549)) seq.append(SeqMethod(self, '_testArrival', xpos, -549.)) xpos = self._beamstop_pos[int(target)] seq.append(SeqDev(self._attached_x, xpos)) seq.append(SeqMethod(self, '_testArrival', xpos, -549.)) seq.append(SeqLimDev(self._attached_y, -450, -450)) seq.append(SeqMethod(self, '_testArrival', xpos, -450)) seq.append((SeqDev(self._attached_y, self._in_y), SeqDev(self._attached_x, self._in_x))) return seq
def park(self, blocking=True): """Move device to the ``park`` position. The park position is given by the ``parkposition`` parameter. It generate ands starts a sequence if none is running. The call blocks the daemon execution if ``blocking`` is set to True. """ if self._seq_is_running(): if self._mode == SIMULATION: self._seq_thread.join() self._seq_thread = None else: raise MoveError( self, 'Cannot park device, sequence is still ' 'running (at %s)!' % self._seq_status[1]) self._startSequence([ SeqMethod(self, '_move_guides_to_zero_pos'), SeqMethod(self, '_move_detectors', self.parkpos), ] + [ SeqDev(d, p) for d, p in zip(self._rotguide1, self.parkpos[11:][::-1]) ]) if blocking: # block the move to be sure that the device has reached target # before it can be dismounted or the position sensitive detectors # can be used self.wait()
def _gen_lift2mag(self, magpos=None): seq = [] if magpos is None: magpos = self._attached_magazine.read(0) else: seq.append(SeqDev(self._attached_magazine, magpos)) # check preconditions seq.append( SeqCall(self.log.info, 'checking preconditions for Lift2Magazin')) seq.append(SeqCheckStatus(self._attached_magazine, status.OK)) seq.append(SeqCheckStatus(self._attached_lift, status.OK)) seq.append(SeqCheckPosition(self._attached_lift, '2')) seq.append(SeqCheckPosition(self._attached_liftclamp, 'close')) seq.append(SeqCheckPosition(self._attached_magazine, magpos)) seq.append(SeqCheckPosition(self._attached_magazineclamp, 'close')) seq.append(SeqMethod(self, 'CheckMagazinSlotEmpty', magpos)) # there needs to be a mono in the lift seq.append( SeqCall(self.log.info, 'checking if there is a mono in lift')) seq.append( SeqCheckAttr(self, 'mono_in_lift', values=[m for m in self.monos if m != 'None'])) # prepare magazin seq.append(SeqCall(self.log.info, 'testing magazin grab')) seq.append(SeqDev(self._attached_magazineclamp, 'open')) seq.append(SeqDev(self._attached_magazineclamp, 'close')) seq.append(SeqDev(self._attached_magazineclamp, 'open')) seq.append(SeqDev(self._attached_magazineclamp, 'close')) seq.append(SeqDev(self._attached_magazineclamp, 'open')) # transfer mono to lift seq.append(SeqCall(self.log.info, 'moving lift to top position')) seq.append(SeqDev(self._attached_lift, '4')) # top position seq.append( SeqCall(self.log.info, 'closing the magazin grab and rattling lift')) seq.append(SeqMethod(self._attached_magazineclamp, 'start', 'close')) # rattle a little seq.append(SeqDev(self._attached_lift, '3')) # almost top position seq.append(SeqDev(self._attached_lift, '4')) # top position seq.append(SeqDev(self._attached_lift, '3')) # almost top position seq.append(SeqDev(self._attached_lift, '4')) # top position seq.append(SeqDev(self._attached_lift, '3')) # almost top position seq.append(SeqDev(self._attached_magazineclamp, 'close')) seq.append(SeqMethod(self, 'CheckMagazinSlotUsed', magpos)) seq.append(SeqCall(self.log.info, 'opening lift clamp')) seq.append(SeqMethod(self._attached_liftclamp, 'start', 'open')) seq.append(SeqDev(self._attached_lift, '4')) # top position seq.append(SeqDev(self._attached_lift, '3')) # top position seq.append(SeqDev(self._attached_liftclamp, 'open')) seq.append(SeqCall(self.log.info, 'moving lift to park position')) seq.append(SeqDev(self._attached_lift, '2')) # park position seq.append(SeqCall(self.log.info, 'closing lift clamp')) seq.append(SeqDev(self._attached_liftclamp, 'close')) # move (without mono) to parking position seq.append(SeqSetAttr(self, 'mono_in_lift', 'None')) # Magazin should not contain a mono now seq.append(SeqMethod(self, 'CheckMagazinSlotUsed', magpos)) return seq
def doReference(self): """Reference the NOK in a sophisticated way. First we try to reach the lowest point ever needed for referencing, then we reference the lower refpoint first, and the higher later. After referencing is done, we go to (0, 0). """ # XXX: EXTRA BIG TODO !!! if self._seq_is_running(): raise MoveError(self, 'Cannot reference device, it is still ' 'moving!') devices = self._devices refpos = [d.refpos for d in devices] # referencing is easier if device[0].refpos is always lower than # device[1].refpos if refpos[1] < refpos[0]: # wrong order: flip oder of entries devices.reverse() refpos.reverse() # go below lowest interesting point minpos = min(self.read() + refpos + [t + self.backlash for t in refpos]) # build a referencing sequence sequence = [] # go to lowest position first sequence.append([SeqDevMin(d, minpos) for d in devices]) # if one of the motors should have triggered the low-level-switch # move them up a little and wait until the movement has finished sequence.append([ SeqMoveOffLimitSwitch(d, backoffby=self.backlash / 4.) for d in devices ]) # ref lowest position, should finish at refpos[0] # The move should be first, as the referencing may block! sequence.append([ SeqDev(devices[1], refpos[0]), SeqMethod(devices[0], 'reference') ]) # ref highest position, should finish at refpos[1] sequence.append([ SeqDev(devices[0], refpos[1]), SeqMethod(devices[1], 'reference') ]) # fun: move both to 0 sequence.append([SeqDev(d, 0) for d in devices]) # GO self._startSequence(sequence)
def _generateSequence(self, target): hvdev = self._attached_supply disdev = self._attached_discharger seq = [SeqMethod(hvdev, 'stop'), SeqMethod(hvdev, 'wait')] now = currenttime() # below first rampstep is treated as poweroff if target <= self.rampsteps[0][0]: # fast ramp seq.append(SeqParam(hvdev, 'ramp', self.fastramp)) seq.append(SeqDev(disdev, 1 if self.read() > target else 0)) if self.read() > self.rampsteps[0][0]: seq.append(SeqDev(hvdev, self.rampsteps[0][0])) seq.append(SeqMethod(hvdev, 'start', target)) return seq # check off time if self.lasthv and now - self.lasthv <= self.maxofftime: # short ramp up sequence seq.append(SeqParam(hvdev, 'ramp', self.fastramp)) seq.append(SeqDev(disdev, 1 if self.read() > target else 0)) seq.append(SeqDev(hvdev, target)) # retry if target not reached seq.append(SeqMethod(hvdev, 'start', target)) return seq # long sequence self.log.warning( 'Voltage was down for more than %.2g hours, ' 'ramping up slowly, be patient!', self.maxofftime / 3600) self.log.info( 'Voltage will be ready around %s', strftime('%X', localtime(now + self.doTime(self.doRead(0), target)))) seq.append(SeqParam(hvdev, 'ramp', self.slowramp)) seq.append(SeqDev(disdev, 0)) for voltage, minutes in self.rampsteps: # check for last point in sequence if target <= voltage: seq.append(SeqDev(hvdev, target)) seq.append( SeqSleep(minutes * 60, 'Stabilizing HV for %d minutes' % minutes)) break else: # append seq.append(SeqDev(hvdev, voltage)) seq.append( SeqSleep(minutes * 60, 'Stabilizing HV for %d minutes' % minutes)) seq.append(SeqDev(hvdev, target)) # be sure... seq.append(SeqMethod(hvdev, 'poll')) # force a read return seq
def doReference(self, *args): if self._seq_is_running(): if self._mode == SIMULATION: self._seq_thread.join() self._seq_thread = None else: raise MoveError(self, 'Cannot reference device, device is ' 'still moving (at %s)!' % self._seq_status[1]) with self._allowed(): self._startSequence([SeqMethod(self, '_checkedRefRot'), SeqMethod(self, '_checkedRefTrans')])
def _generateSequence(self, target, indexes, code): self.log.debug('DoubleMotorBeckhoff Seq generated %s %s 0x%X', target, indexes, code) seq = [SeqMethod(self, '_HW_wait_while_HOT')] for i in indexes: seq.append( SeqMethod(self, '_awriteDestination', self._aphys2steps(target[i], self.ruler[i]), self.addresses[i])) seq.append( SeqMethod(self, '_awriteControlBit', 0, code, 10, self.addresses[i])) return seq
def _generateSequence(self, target): """Move multidetector to correct scattering angle of multi analyzer. It takes account into the different origins of the analyzer blades. """ # check if requested positions already reached within precision if self.isAtTarget(target): self.log.debug('device already at position, nothing to do!') return [] return [ SeqMethod(self, '_move_translations', target), SeqMethod(self, '_move_rotations', target), ]
def _generateSequence(self, target): seq = [] if self._attached_selector.read(0) > self.maxtiltspeed: seq.insert( 0, SeqDev(self._attached_selector, self.maxtiltspeed, stoppable=True)) seq.append(SeqMethod(self, '_check_speed')) seq.append(SeqMethod(self._attached_motor, 'release')) seq.append(SeqDev(self._attached_motor, target, stoppable=True)) seq.append( SeqMethod(self._attached_motor, 'fix', 'only move this using %s' % self)) return seq
def change(self, old, whereto): ''' cool kurze Wechselroutine Der Knackpunkt ist in den Hilfsroutinen!''' if not (old in self.monos + ['None']): raise UsageError( self, '\'%s\' is illegal value for Mono, use one ' 'of ' % old + ', '.join(self.monos + ['None'])) if not (whereto in self.monos + ['None']): raise UsageError( self, '\'%s\' is illegal value for Mono, use one ' 'of ' % whereto + ', '.join(self.monos + ['None'])) self.PrepareChange() if self.monos.index(whereto) == self.monos.index(old): # Nothing to do, requested Mono is supposed to be on the table return # Ok, we have a good state, the only thing we do not know is which mono # is on the table...... # for this we use the (cached) parameter mono_on_table if self.mono_on_table != old: raise UsageError( self, 'Mono %s is not supposed to be on the ' 'table, %s is!' % (old, self.mono_on_table)) seq = [] # 0) move magazine to mono position magpos_to_put = self.positions[self.monos.index(old)] seq.append(SeqMethod(self, 'CheckMagazinSlotEmpty', magpos_to_put)) seq.append(SeqDev(self._attached_magazine, magpos_to_put)) # 1) move away the old mono, if any if old != 'None': seq.extend(self._gen_table2lift()) seq.extend( self._gen_lift2mag(self.positions[self.monos.index(old)])) # 2) fetch the new mono (if any) from the magazin if whereto != 'None': seq.extend( self._gen_mag2lift(self.positions[self.monos.index(whereto)])) seq.extend(self._gen_lift2table()) seq.append( SeqDev(self._attached_magazine, self.shields[self.monos.index(whereto)])) # seq.append(SeqDev(self._attached_enable, 0)) - will be done in FinishChange seq.append(SeqMethod(self, 'FinishChange')) self._start(seq) self.wait()
def doReference(self): if self._seq_is_running(): raise MoveError(self, 'Cannot reference a moving device!') seq = self._gen_ref_sequence() if self.autopower == 'on': # disable if requested. seq.append(SeqMethod(self, '_HW_disable')) self._startSequence(seq)
def _gen_mag2lift(self, magpos=None): seq = [] if magpos is None: magpos = self._attached_magazine.read(0) else: seq.append(SeqDev(self._attached_magazine, magpos)) # check preconditions seq.append( SeqCall(self.log.info, 'checking preconditions for Magazin2Lift')) seq.append(SeqCheckStatus(self._attached_magazine, status.OK)) seq.append(SeqCheckStatus(self._attached_lift, status.OK)) seq.append(SeqCheckPosition(self._attached_lift, '2')) seq.append(SeqCheckPosition(self._attached_liftclamp, 'close')) seq.append(SeqCheckPosition(self._attached_magazine, magpos)) seq.append(SeqCheckPosition(self._attached_magazineclamp, 'close')) seq.append(SeqMethod(self, 'CheckMagazinSlotUsed', magpos)) seq.append(SeqCheckAttr(self, 'mono_in_lift', 'None')) # transfer mono to lift seq.append( SeqCall(self.log.info, 'transferring mono from magazine to lift')) seq.append(SeqDev(self._attached_liftclamp, 'open')) seq.append(SeqDev(self._attached_lift, '3')) # almost top position seq.append(SeqMethod(self._attached_liftclamp, 'start', 'close')) seq.append(SeqDev(self._attached_lift, '4')) # top position seq.append(SeqDev(self._attached_liftclamp, 'close')) seq.append(SeqMethod(self._attached_magazineclamp, 'start', 'open')) # rattle a little seq.append(SeqCall(self.log.info, 'rattle to release magazine grab')) seq.append(SeqDev(self._attached_lift, '3')) # almost top position seq.append(SeqDev(self._attached_lift, '4')) # top position seq.append(SeqDev(self._attached_lift, '3')) # almost top position seq.append(SeqDev(self._attached_lift, '4')) # top position seq.append(SeqDev(self._attached_magazineclamp, 'open')) seq.append(SeqMethod(self, 'CheckMagazinSlotEmpty', magpos)) # move (with mono) to parking position seq.append( SeqCall(self.log.info, 'moving with mono to parking position')) seq.append( SeqSetAttr(self, 'mono_in_lift', self.monos[self.positions.index(magpos)])) seq.append(SeqDev(self._attached_lift, '2')) # park position seq.append(SeqDev(self._attached_magazineclamp, 'close')) # Magazin should not contain a mono now seq.append(SeqMethod(self, 'CheckMagazinSlotEmpty', magpos)) return seq
def _generateSequence(self, target): theta, trans = self._calcMonoPosition(target) seq = [] seq.append((SeqDev(self._attached_mth1, self.safe_position), SeqDev(self._attached_mth2, self.safe_position))) seq.append(SeqMethod(self, '_checksafe')) seq.append(SeqMethod(self, '_runMtx', trans)) seq.append((SeqDev(self._attached_mth1, theta), SeqDev(self._attached_mth2, theta))) seq.append(SeqMethod(self, '_checkArrival')) return seq
def _generateSequence(self, target): seq = [] s = SeqMethod(self, '_release') seq.append(s) if target == 'out': seq.append(SeqMethod(self, '_save_pos')) seq.append(SeqDev(self._attached_x, self._out_x)) seq.append(SeqLimDev(self._attached_y, self._out_y, self._out_y)) seq.append(SeqMethod(self, '_fix')) else: seq.append(SeqMethod(self, '_release')) seq.append(SeqLimDev(self._attached_y, self._in_y, -450)) seq.append(SeqDev(self._attached_x, self._in_x)) return seq
def _gen_ref_sequence(self): seq = [] # try to mimic anatel: go to 5mm before refpos and then to the negative limit switch seq.append(SeqMethod(self, '_HW_enable')) seq.append(SeqMethod(self, '_HW_start', self.refpos + 5.)) seq.append(SeqMethod(self, '_HW_wait_while_BUSY')) seq.append( SeqMethod( self, '_HW_start', self.absmin if self.absmin < self.refpos else self.refpos - 100)) seq.append(SeqMethod(self, '_HW_wait_while_BUSY')) seq.append(SeqMethod(self, '_HW_reference')) seq.append(SeqMethod(self, '_HW_wait_while_BUSY')) seq.append(SeqMethod(self, 'doSetPosition', self.refpos)) return seq
def _gen_move_sequence(self, target): # now generate a sequence of commands to execute in order seq = [] # always enable before doing anything seq.append(SeqMethod(self, '_HW_enable')) # check autoreferencing feature if self.autozero is not None: currentpos = self.read(0) mindist = min(abs(currentpos - self.refpos), abs(target - self.refpos)) if mindist < self.autozero: seq.extend(self._gen_ref_sequence()) # now just go where commanded.... seq.append(SeqMethod(self, '_HW_start', target)) seq.append(SeqMethod(self, '_HW_wait_while_BUSY')) if self.autopower == 'on': # disable if requested. seq.append(SeqMethod(self, '_HW_disable')) return seq
def _generateSequence(self): seq = [] shutter_mode = self._attached_auto.read(0) if shutter_mode == 'auto': seq.append(SeqDev(self._attached_shutter, 'open')) # Wait for arm to become 0 seq.append(WaitPV(self, 'armpv', 0, timeout=self.arm_timeout)) # set valid 0 seq.append(PutPV(self, 'validpv', 0)) # wait for beam seq.append(Message(self, 'Waiting for beam...')) s = WaitThreshold(self, self._attached_beam_current, self._attached_rate_threshold.read()) seq.append(s) seq.append(Message(self, 'Beam is on, exposing...')) # Start the detector seq.append(PutPV(self, 'trigpv', 1)) # wait for the detector to actually start s = WaitNotPV(self, 'shutpv', 1, timeout=self.shutter_timeout) seq.append(s) # Reset the start signal seq.append(PutPV(self, 'trigpv', 0)) # Wait for counting to finish s = WaitPV(self, 'shutpv', 1, timeout=self.exposure_timeout) seq.append(s) # Write the metadata seq.append(SeqMethod(self, '_writeMetaData')) # Camini is tired, needs a little sleep seq.append(SeqSleep(.1)) # set valid 1 seq.append(PutPV(self, 'validpv', 1)) if shutter_mode == 'auto': seq.append(SeqDev(self._attached_shutter, 'closed')) return seq
def test_seqmethod(session): # method calling, use fix/relase here sm1 = session.getDevice('sm1') sm = SeqMethod(sm1, 'fix', 'blubb') assert repr(sm) == "sm1 fix" assert sm1.fixed == '' # pylint:disable=compare-to-empty-string sm.check() sm.run() while not sm.isCompleted(): pass assert 'blubb' in sm1.fixed sm1.release()
def _generateSequence(self, target): seq = [] seq.append(SeqMethod(self, '_HW_wait_while_BUSY')) seq.append(SeqMethod(self, '_HW_wait_while_HOT')) seq.append( SeqMethod(self, '_writeDestination', self._phys2steps(target))) seq.append(SeqMethod(self, '_HW_start')) seq.append(SeqSleep(1.1)) seq.append(SeqMethod(self, '_check_start_status')) seq.append(SeqMethod(self, '_HW_wait_while_BUSY')) self.log.debug('BeckhoffMotorBase Seq generated') return seq
def _generateSequence(self, target): return [ SeqDev(self._adevs['fg'], target), SeqMethod(self, '_tuneInput', target), SeqMethod(self, '_tuneCapacity', target), ]