示例#1
0
    def __init__(self, name, pgm_grat_pitch, pgm_mirr_pitch, pgmpvroot, energy, idupvroot, iddpvroot, move_pgm=True, move_id=True): # motors, maybe also detector to set the delay time
        self.logger = LoggerFactory.getLogger("ContinuousPgmGratingIDGapEnergyMoveController:%s" % name)
        self.verbose = False
        self.setName(name)
        self._start_event = threading.Event()
        self._movelog_time = datetime.now()
        #PGM
        self._pgm_grat_pitch = pgm_grat_pitch
        self._pgm_mirr_pitch = pgm_mirr_pitch
        self._pgm_grat_pitch_speed_orig = None
        self._pgm_runupdown_time = None
        self._move_pgm = move_pgm
        self._move_id  = move_id

        self.pvs = PvManager({'grating_density':                'NLINES',
                              'cff':                            'CFF',
                              'grating_offset':                 'GRTOFFSET',
                              'plane_mirror_offset':            'MIROFFSET',
                              'pgm_energy':                     'ENERGY',
                              'grating_pitch':                  'GRT:PITCH',
                              'mirror_pitch':                   'MIR:PITCH',
                              'energy_calibration_gradient':    'MX',
                              'energy_calibration_reference':   'REFERENCE'}, pgmpvroot)
        if installation.isLive():
            self.pvs.configure()
            
        #ID
        self.energy = energy
        self.idd = energy.idd
        self.idu = energy.idu
        self._id_gap_speed_orig=None
        self._id_runupdown_time = None
        self.idupvs = PvManager({'vel':'BLGSETVEL',
                                'acc':'IDGSETACC'}, idupvroot)
        if installation.isLive():
            self.idupvs.configure()
            
        self.iddpvs = PvManager({'vel':'BLGSETVEL',
                                'acc':'IDGSETACC'}, iddpvroot)
        if installation.isLive():
            self.iddpvs.configure()
            
        self.grating_pitch_positions=[]
        self.mirror_pitch_positions=[]
        self.pgm_energy_positions=[]
        self._start_time = None
        self.idspeedfactor=1.0
        self.pgmspeedfactor=1.0
        self.idstartdelaytime=0.0
        self._move_start = 0.0
        self._move_end = 1.0
        self._move_step = 0.1
        self._triggerPeriod = 0.0
        self.idcontrols = None
        self.continuousMovingStarted = False
示例#2
0
    def prepareID(self, idcontrols, idpvs):
        if installation.isLive():
            self._id_gap_speed_orig = float(idpvs['vel'].caget())
        else:
            self._id_gap_speed_orig = idcontrols['gap'].speed
            
        # Calculate the energy midpoint
        energy_midpoint = (self._move_end + self._move_start) / 2.
        if self.verbose:
            self.logger.info('prepareID: energy_midpoint = %r ' % (energy_midpoint))
        # Calculate phase position for current X-ray source and polarisation at energy midpoint
        gap_midpoint, phase_midpoint = self.energy.get_ID_gap_phase_at_current_source_polarisation(energy_midpoint)  # @UnusedVariable
        
        # Calculate ID gap at start energy and end energy for current X-ray source and polarisation
        self._id_gap_start, phase_start = self.energy.get_ID_gap_phase_at_current_source_polarisation(self._move_start)  # @UnusedVariable
        self._id_gap_end, phase_end = self.energy.get_ID_gap_phase_at_current_source_polarisation(self._move_end)  # @UnusedVariable
        
        ### Calculate main cruise move speed from start/end/step
        self._id_gap_speed = abs(self._id_gap_end - self._id_gap_start) / self.getTotalTime()*self.idspeedfactor
        
        ### Calculate ramp distance from required speed and ramp times
        # check to ensure speed within limits
        if self._id_gap_speed<0.004 or self._id_gap_speed>1.0:
            raise ValueError("Calculated ID gap speed %f is outside limits [%f, %f]!" % (self._id_gap_speed, 0.004, 1.0))
        
        if installation.isLive():
            # Cannot set id_gap.speed through soft motor which in EPICS is read-only 
            idpvs['vel'].caput(self._id_gap_speed)
        else:
            idcontrols['gap'].speed = self._id_gap_speed 
            
        #acceleration time per axis
        self._id_axis_speed=self._id_gap_speed/2
        self._id_runupdown_time_per_axis=self._id_axis_speed*4
        # Should really be / | | | | | \ not /| | | | |\
        self._id_runupdown_per_axis = self._id_axis_speed / 2 * self._id_runupdown_time_per_axis
        self._id_gap_runupdown = self._id_runupdown_per_axis * 2

        ### Move motor at full speed to start position
        if installation.isLive():
            idpvs['vel'].caput(self._id_gap_speed_orig)
        else:
            idcontrols['gap'].speed = self._id_gap_speed_orig 
            
        if self.getIDGapMoveDirectionPositive():
            if self.verbose:
                self.logger.info('prepareID:move_id_to_positions([%s, %f, %f, %s]) @ %r mm/sec (+ve)' % (self.energy.source.getPosition(), (self._id_gap_start - self._id_gap_runupdown), phase_midpoint, self.energy.polarisation, self._id_gap_speed_orig))
            self.energy.move_id_to_positions(idcontrols, self._id_gap_start - self._id_gap_runupdown, phase_midpoint, self.energy.polarisation)
        else:
            if self.verbose:
                self.logger.info('prepareID:move_id_to_positions([%s, %f, %f, %s]) @ %r mm/sec (-ve)' % (self.energy.source.getPosition(), (self._id_gap_start + self._id_gap_runupdown), phase_midpoint, self.energy.polarisation, self._id_gap_speed_orig))
            self.energy.move_id_to_positions(idcontrols, self._id_gap_start + self._id_gap_runupdown, phase_midpoint, self.energy.polarisation)
示例#3
0
 def _restore_orig_speed(self):
     if self.isPGMMoveEnabled():
         if self._pgm_grat_pitch_speed_orig:
             if self.verbose:
                 self.logger.info(
                     'Restoring original PGM Grating Pitch speed %r, was %r'
                     % (self._pgm_grat_pitch_speed_orig,
                        self._pgm_grat_pitch.speed))
             self._pgm_grat_pitch.speed = self._pgm_grat_pitch_speed_orig
             self._pgm_grat_pitch_speed_orig = None
     if self.isIDMoveEnabled():
         if self._id_gap_speed_orig:
             if installation.isLive():
                 if self.verbose:
                     self.logger.info(
                         'Restoring original ID gap speed %r, was %r' %
                         (self._id_gap_speed_orig,
                          self.idpvs['vel'].caget()))
                 self.idpvs['vel'].caput(self._id_gap_speed_orig)
             else:
                 if self.verbose:
                     self.logger.info(
                         'Restoring original ID gap speed %r, was %r' %
                         (self._id_gap_speed_orig, self._id_gap.speed))
                 self._id_gap.speed = self._id_gap_speed_orig
             self._id_gap_speed_orig = None
示例#4
0
    def __init__(
            self, name, pgm_grat_pitch, pgm_mirr_pitch,
            pgmpvroot):  # motors, maybe also detector to set the delay time
        self.logger = LoggerFactory.getLogger(
            "ContinuousPgmGratingEnergyMoveController:%s" % name)
        self.verbose = False

        self.name = name
        self._pgm_grat_pitch = pgm_grat_pitch
        self._pgm_mirr_pitch = pgm_mirr_pitch
        self._start_event = threading.Event()
        self._pgm_grat_pitch_speed_orig = None
        self._movelog_time = datetime.now()
        self._pgm_runupdown_time = None

        self.pvs = PvManager(
            {
                'grating_density': 'NLINES',
                'cff': 'CFF',
                'grating_offset': 'GRTOFFSET',
                'plane_mirror_offset': 'MIROFFSET',
                'pgm_energy': 'ENERGY',
                'grating_pitch': 'GRT:PITCH',
                'mirror_pitch': 'MIR:PITCH',
                'energy_calibration_gradient': 'MX',
                'energy_calibration_reference': 'REFERENCE'
            }, pgmpvroot)
        if installation.isLive():
            self.pvs.configure()
示例#5
0
 def configure(self):
     if installation.isLive():
         self.pv_waveform.configure()
         self.pv_count.configure()
     else:
         self.logger.info("DUMMY mode: pv_count at configure() is %r" %
                          self.pv_count)
示例#6
0
 def erase_and_start(self):
     if self.verbose:
         self.logger.info("%s %s" % (self.name, 'erase_and_start()...'))
     if installation.isLive():
         self.pv_stop.caput(1)  # scaler won't start if already running
         if self.channelAdvanceInternalNotExternal:
             self.pv_dwell.caput(
                 TIMEOUT, self.exposure_time
             )  # Set the exposure time per nominal position
             self.pv_channeladvance.caput(TIMEOUT,
                                          self.channelAdvanceInternal)
             self.pv_presetReal.caput(
                 (self.number_of_positions * self.exposure_time) +
                 self.exposure_time_offset)  # Set the total capture time
         else:
             self.pv_channeladvance.caput(TIMEOUT,
                                          self.channelAdvanceExternal)
         self.pv_erasestart.caput(TIMEOUT, 1)
     else:
         #Scaler not used in Dummy mode
         pass
     # Since the mca NORD value could take some time to be updated and will continue returning the NORD of the last acquire,
     # wait before setting started to True, so WaveformChannelPollingInputStream doesn't try to use stale data.
     startedTimer = Timer(
         1.5, self._delayed_start_complete)  # Failed at 0.5s, Ok at 1.5s.
     startedTimer.start()
     if self.verbose:
         self.logger.info("%s %s" % (self.name, '...erase_and_start()'))
示例#7
0
    def startMove(self):
        if self.verbose: self.logger.info('startMove()...')

        # Notify all position callables to start waiting for their time
        self._start_time = datetime.now()
        self._start_event.set()
        # Start threads to start ID & PGM and at the correct times
        if self.isMonoMoveEnabled():
            self._mono_energy.speed = self._mono_energy_speed

        if self.isIDMoveEnabled():
            if installation.isLive():
                self.idpvs['vel'].caput(self._id_gap_speed)
            else:
                self._id_gap.speed = self._id_gap_speed

        if self.isMonoMoveEnabled():
            if self.isEnergyMoveDirectionPositive():
                if self.verbose:
                    self.logger.info(
                        'startMove Mono Energy: _mono_energy.asynchronousMoveTo(%r) @ %r (+ve)'
                        % ((self._move_end * self.energy_scale +
                            self._mono_runupdown), self._mono_energy_speed))
                self._mono_energy.asynchronousMoveTo(
                    (self._move_end * self.energy_scale +
                     self._mono_runupdown))
            else:
                if self.verbose:
                    self.logger.info(
                        'startMove Mono Energy: _mono_energy.asynchronousMoveTo(%r) @ %r (-ve)'
                        % ((self._move_end * self.energy_scale -
                            self._mono_runupdown), self._mono_energy_speed))
                self._mono_energy.asynchronousMoveTo(
                    (self._move_end * self.energy_scale -
                     self._mono_runupdown))

        if self.isIDMoveEnabled():
            sleep(self.getIDStartDelayTime())
            if self.isIDGapMoveDirectionPositive():
                if self.verbose:
                    self.logger.info(
                        'startMove ID Gap: _id_gap.asynchronousMoveTo(%r) @ %r (+ve)'
                        % ((self._id_gap_end + ID_GAP_END_OFFSET +
                            self._id_gap_runupdown), self._id_gap_speed))
                self._id_gap.asynchronousMoveTo(
                    (self._id_gap_end + ID_GAP_END_OFFSET +
                     self._id_gap_runupdown))
            else:
                if self.verbose:
                    self.logger.info(
                        'startMove ID Gap: _id_gap.asynchronousMoveTo(%r) @ %r (-ve)'
                        % ((self._id_gap_end - ID_GAP_END_OFFSET -
                            self._id_gap_runupdown), self._id_gap_speed))
                self._id_gap.asynchronousMoveTo(
                    (self._id_gap_end - ID_GAP_END_OFFSET -
                     self._id_gap_runupdown))

        self.continuousMovingStarted = True
        if self.verbose: self.logger.info('...startMove')
示例#8
0
 def erase_and_start(self):
     if self.verbose:
         self.logger.info("%s %s" % (self.name, 'erase_and_start()...'))
     if installation.isLive():
         self.pv_erasestart.caput(1)
     self.started = True
     if self.verbose:
         self.logger.info("%s %s" % (self.name, '...erase_and_start()'))
示例#9
0
 def read(self, max_to_read_in_one_go):
     if self.verbose:
         self.logger.info('read(%r)...  elements_read=%r' %
                          (max_to_read_in_one_go, self.elements_read))
     if self.hardwareTriggerProvider is None:
         self.hardwareTriggerProvider = self._controller.getHardwareTriggerProvider(
         )
     if installation.isLive():
         new_available = self._waitForNewElements()
         all_data = self.pv_waveform.cagetArrayDouble(self.elements_read +
                                                      new_available)
     else:
         if self.hardwareTriggerProvider._start_time is not None and not self.startTimeSet:
             self.start_time = time.time()
             self.startTimeSet = True
         new_available = self._waitForNewElements()
         if self.channel in ['GRT:PITCH:', 'MIR:PITCH:', 'PGM:ENERGY:']:
             if self.channel == 'GRT:PITCH:':
                 #                     print "%s waveform is %r" % (self.channel, self.hardwareTriggerProvider.grating_pitch_positions)
                 all_data = self.hardwareTriggerProvider.grating_pitch_positions[:
                                                                                 self
                                                                                 .
                                                                                 elements_read
                                                                                 +
                                                                                 new_available]
             elif self.channel == 'MIR:PITCH:':
                 #                     print "%s waveform is %r" % (self.channel, self.hardwareTriggerProvider.mirror_pitch_positions)
                 all_data = self.hardwareTriggerProvider.mirror_pitch_positions[:
                                                                                self
                                                                                .
                                                                                elements_read
                                                                                +
                                                                                new_available]
             elif self.channel == 'PGM:ENERGY:':
                 #                     print "%s waveform is %r" % (self.channel, self.hardwareTriggerProvider.pgm_energy_positions)
                 all_data = self.hardwareTriggerProvider.pgm_energy_positions[:
                                                                              self
                                                                              .
                                                                              elements_read
                                                                              +
                                                                              new_available]
         else:
             all_data = self.pv_waveform.generateData(
                 self.channel, self.elements_read + new_available)
             self.logger.debug("DUMMY mode: generate %r elements" %
                               (new_available))
     new_data = all_data[self.elements_read:self.elements_read +
                         new_available]
     self.elements_read += new_available
     if self.verbose:
         self.logger.info('...read() all_data[0:6] = %r' % (all_data[0:6]))
     if self.verbose:
         self.logger.info(
             '...read() (elements_read=%r) new data = %r' %
             (self.elements_read,
              java.util.Vector([self.type(el) for el in new_data])))
     return java.util.Vector([self.type(el) for el in new_data])
示例#10
0
 def getChannelInputStreamCAClients(self, channel_pv_suffix):
     if installation.isLive():
         pv_waveform = CAClient(self.binpoint_root_pv + channel_pv_suffix +
                                'BINPOINT')
         pv_count = CAClient(self.binpoint_root_pv + channel_pv_suffix +
                             'BINPOINT:NLAST.B')
     else:
         pv_waveform = []
         pv_count = self.number_of_positions
     return pv_waveform, pv_count
示例#11
0
 def stop(self):
     if self.verbose: self.logger.info("%s %s" % (self.name, 'stop()...'))
     if installation.isLive():
         self.pv_stop.caput(1)
     else:
         #MCA not available in Dummy mode
         pass
     if self.stream:
         self.stream.stop()  # stop waveform polling stream.
     self.started = False
     if self.verbose: self.logger.info("%s %s" % (self.name, '...stop()'))
示例#12
0
 def stop(self):
     if self.verbose: self.logger.info("%s %s" % (self.name, 'stop()...'))
     if installation.isLive():
         self.pv_stop.caput(1)
     else:
         #MCA not available in Dummy mode
         pass
     if self.stream:
         self.stream.stop(
         )  # enable stop the element polling loop when stop is called.
     self.started = False
     if self.verbose: self.logger.info("%s %s" % (self.name, '...stop()'))
示例#13
0
    def startMove(self):
        if self.verbose: self.logger.info('startMove()...')

        # Notify all position callables to start waiting for their time
        self._start_time = datetime.now()
        self._start_event.set()
        # Start threads to start ID & PGM and at the correct times
        if self.isPGMMoveEnabled():
            self._pgm_grat_pitch.speed = self._pgm_grat_pitch_speed

        if self.isIDMoveEnabled():
            if installation.isLive():
                self.idpvs['vel'].caput(self._id_gap_speed)
            else:
                self._id_gap.speed = self._id_gap_speed

        if self.isPGMMoveEnabled():
            if self.getGratingMoveDirectionPositive():
                if self.verbose:
                    self.logger.info(
                        'startMove PGM Grating Pitch: asynchronousMoveTo(%r) @ %r (+ve)'
                        % ((self._grat_pitch_end + self._pgm_runupdown) *
                           1000., self._pgm_grat_pitch_speed))
                self._pgm_grat_pitch.asynchronousMoveTo(
                    (self._grat_pitch_end + self._pgm_runupdown) * 1000.)
            else:
                if self.verbose:
                    self.logger.info(
                        'startMove PGM Grating Pitch: asynchronousMoveTo(%r) @ %r (-ve)'
                        % ((self._grat_pitch_end - self._pgm_runupdown) *
                           1000., self._pgm_grat_pitch_speed))
                self._pgm_grat_pitch.asynchronousMoveTo(
                    (self._grat_pitch_end - self._pgm_runupdown) * 1000.)
        if self.isIDMoveEnabled():
            sleep(self.getIDStartDelayTime())
            if self.getIDGapMoveDirectionPositive():
                if self.verbose:
                    self.logger.info(
                        'startMove ID Gap: asynchronousMoveTo(%r) @ %r (+ve)' %
                        ((self._id_gap_end + 0.05 + self._id_gap_runupdown),
                         self._id_gap_speed))
                self._id_energy.id_gap.asynchronousMoveTo(
                    (self._id_gap_end + 0.05 + self._id_gap_runupdown))
            else:
                if self.verbose:
                    self.logger.info(
                        'startMove ID Gap: asynchronousMoveTo(%r) @ %r (-ve)' %
                        ((self._id_gap_end - 0.05 - self._id_gap_runupdown),
                         self._id_gap_speed))
                self._id_energy.id_gap.asynchronousMoveTo(
                    (self._id_gap_end - 0.05 - self._id_gap_runupdown))
        # How do we trigger the detectors, since they are 'HardwareTriggerable'?
        if self.verbose: self.logger.info('...startMove')
示例#14
0
 def configure(self):
     if self.verbose:
         self.logger.info("%s %s" % (self.name, 'configure()...'))
     if installation.isLive():
         self.pv_stop.configure()
         self.pv_dwell.configure()
         self.pv_channeladvance.configure()
         self.pv_presetReal.configure()
         self.pv_erasestart.configure()
     else:
         if self.verbose:
             self.logger.info("configure '%s' for dummy operation...')" %
                              (countTimer.getName()))
示例#15
0
 def getChannelInputStreamCAClients(self, channel):
     if installation.isLive():
         pv_waveform = CAClient(self.mca_root_pv + 'mca' + ` channel `)
         pv_count = CAClient(self.mca_root_pv + 'mca' + ` channel ` +
                             '.NORD')
     else:
         waveform = WaveformDataGenerator()
         waveform.useGaussian = True
         if waveform.useGaussian and waveform.gaussian is None:
             waveform.initializeGaussian()
         waveform.data = []
         waveform.channel = channel
         pv_waveform = waveform
         pv_count = self.number_of_positions
     return pv_waveform, pv_count
示例#16
0
 def read(self, max_to_read_in_one_go):
     if self.verbose:
         self.logger.info('read(%r)...  elements_read=%r' %
                          (max_to_read_in_one_go, self.elements_read))
     if self.hardwareTriggerProvider is None:
         self.hardwareTriggerProvider = self._controller.getHardwareTriggerProvider(
         )
     new_available = self._waitForNewElements()
     if installation.isLive() and new_available is not None:
         all_data = self.pv_waveform.cagetArrayDouble(self.elements_read +
                                                      new_available)
     else:
         if self.channel in ['B1:', 'B2:', 'B4:', 'B5:'
                             ] and new_available is not None:
             if self.channel in ['B2:', 'B5:']:
                 all_data = self.hardwareTriggerProvider.id_gap_positions[:
                                                                          self
                                                                          .
                                                                          elements_read
                                                                          +
                                                                          new_available]
             elif self.channel in ['B1:', 'B4:']:
                 all_data = self.hardwareTriggerProvider.mono_energy_positions[:
                                                                               self
                                                                               .
                                                                               elements_read
                                                                               +
                                                                               new_available]
         else:
             all_data = self.pv_waveform.generateData(
                 self.channel, self.elements_read + new_available)
             self.logger.debug("DUMMY mode: generate %r elements" %
                               (new_available))
     new_data = all_data[self.elements_read:self.elements_read +
                         new_available]
     self.elements_read += new_available
     if self.verbose:
         self.logger.info('...read() all_data[0:6] = %r' % (all_data[0:6]))
     if self.verbose:
         self.logger.info(
             '...read() (elements_read=%r) new data = %r' %
             (self.elements_read,
              java.util.Vector([self.type(el) for el in new_data])))
     return java.util.Vector([self.type(el) for el in new_data])
示例#17
0
    def __init__(
            self,
            name,
            energy,
            idgap,
            idpvroot,
            move_mono=True,
            move_id=True):  # motors, maybe also detector to set the delay time
        self.logger = LoggerFactory.getLogger(
            "ContinuousEnergyMoveController:%s" % name)
        self.verbose = False
        self.setName(name)
        self._start_event = threading.Event()
        self._movelog_time = datetime.now()
        self._energy = energy
        #PGM
        self._mono_energy = energy.mono_energy
        self._mono_energy_speed_orig = None
        self._mono_runupdown_time = None
        #ID
        self._id_gap = idgap
        self._id_gap_speed_orig = None
        self._id_runupdown_time = None
        self.idpvs = PvManager({
            'vel': 'BLGSETVEL',
            'acc': 'IDGSETACC'
        }, idpvroot)
        if installation.isLive():
            self.idpvs.configure()

        self.mono_energy_positions = []
        self.id_gap_positions = []
        self._start_time = None

        #behaviour properties
        self._move_mono = move_mono
        self._move_id = move_id
        self.idspeedfactor = 1.0
        self.monospeedfactor = 1.0
        self.idstartdelaytime = 0.0
        self.continuousMovingStarted = False
示例#18
0
 def _restore_orig_speed(self):
     if self.isMonoMoveEnabled() and self._mono_energy_speed_orig:
         if self.verbose:
             self.logger.info(
                 'Restoring original PGM Energy speed %r, was %r' %
                 (self._mono_energy_speed_orig, self._mono_energy.speed))
         self._mono_energy.speed = self._mono_energy_speed_orig
         self._mono_energy_speed_orig = None
     if self.isIDMoveEnabled() and self._id_gap_speed_orig:
         if installation.isLive():
             if self.verbose:
                 self.logger.info(
                     'Restoring original ID gap speed %r, was %r' %
                     (self._id_gap_speed_orig, self.idpvs['vel'].caget()))
             self.idpvs['vel'].caput(self._id_gap_speed_orig)
         else:
             if self.verbose:
                 self.logger.info(
                     'Restoring original ID gap speed %r, was %r' %
                     (self._id_gap_speed_orig, self._id_gap.speed))
             self._id_gap.speed = self._id_gap_speed_orig
         self._id_gap_speed_orig = None
示例#19
0
    def PrepareIDForMove(self):
        if installation.isLive():
            self._id_gap_speed_orig = float(self.idpvs['vel'].caget())
        else:
            self._id_gap_speed_orig = self._id_gap.speed
            
        # Calculate the energy midpoint
        energy_midpoint = (self._move_end + self._move_start) / 2.
        if self.verbose:
            self.logger.info('prepareIDForMove:energy_midpoint=%r ' % (energy_midpoint))

        # Calculate rowphase motor positions for given polarisation at energy midpoint
        self.id_rowphase1_midpoint = self._id_energy.rowphase1_from_energy(energy_midpoint)
        self.id_rowphase2_midpoint = self._id_energy.rowphase2_from_energy(energy_midpoint)
        self.id_rowphase3_midpoint = self._id_energy.rowphase3_from_energy(energy_midpoint)
        self.id_rowphase4_midpoint = self._id_energy.rowphase4_from_energy(energy_midpoint)
        
        # Calculate grating angles for given grating density, energy, mirror angle and offsets
        self._id_gap_start = self._id_energy.gap_from_energy(self._move_start)
        self._id_gap_end = self._id_energy.gap_from_energy(self._move_end)
        
            ### Calculate main cruise moves & speeds from start/end/step
        self._id_gap_speed = abs(self._id_gap_end - self._id_gap_start) / self.getTotalTime()
        
        print self._id_gap_speed
        self._id_gap_speed_rounded = Math.round(self._id_gap_speed*500.0)/500.0
        print self._id_gap_speed_rounded
        
        self.k=self._id_gap_speed_rounded/self._id_gap_speed
        
        ### Calculate ramp distance from required speed and ramp times
        #check speed within limits
        if self._id_gap_speed_rounded<0.004 or self._id_gap_speed_rounded>1.0:
            raise Exception("Calculated ID gap speed %f is outside limits [%f, %f]!" % (self._id_gap_speed_rounded, 0.004, 1.0))
        if installation.isLive():
            #self._id_gap.speed = self._id_gap_speed #Cannot set id_gap.speed through soft motor which in EPICS is read-only 
            self.idpvs['vel'].caput(self._id_gap_speed_rounded)
        else:
            self._id_gap.speed = self._id_gap_speed_rounded 
            
        #acceleration time per axis
        self._id_axis_speed=self._id_gap_speed_rounded/2
        self._id_runupdown_time_per_axis=self._id_axis_speed*4
        # Should really be / | | | | | \ not /| | | | |\
        self._id_runupdown_per_axis = self._id_axis_speed / 2 * self._id_runupdown_time_per_axis
        self._id_gap_runupdown = self._id_runupdown_per_axis * 2
        ### Move motor at full speed to start position
        if self.verbose:
            self.logger.info('prepareIDForMove:%s.asynchronousMoveTo(%r) ' % (self._id_energy.id_rowphase1.getName(),self.id_rowphase1_midpoint))
            self.logger.info('prepareIDForMove:%s.asynchronousMoveTo(%r) ' % (self._id_energy.id_rowphase2.getName(),self.id_rowphase2_midpoint))
            self.logger.info('prepareIDForMove:%s.asynchronousMoveTo(%r) ' % (self._id_energy.id_rowphase3.getName(),self.id_rowphase3_midpoint))
            self.logger.info('prepareIDForMove:%s.asynchronousMoveTo(%r) ' % (self._id_energy.id_rowphase4.getName(),self.id_rowphase4_midpoint))
        self._id_energy.id_rowphase1.asynchronousMoveTo(self.id_rowphase1_midpoint)
        self._id_energy.id_rowphase2.asynchronousMoveTo(self.id_rowphase2_midpoint)
        self._id_energy.id_rowphase3.asynchronousMoveTo(self.id_rowphase3_midpoint)
        self._id_energy.id_rowphase4.asynchronousMoveTo(self.id_rowphase4_midpoint)
        
        if installation.isLive():
            self.idpvs['vel'].caput(self._id_gap_speed_orig)
        else:
            self._id_gap.speed = self._id_gap_speed_orig 
            
        if self.getIDGapMoveDirectionPositive():
            if self.verbose:
                self.logger.info('prepareIDForMove:asynchronousMoveTo(%r) @ %r (+ve)' % ((self._id_gap_start - self._id_gap_runupdown), self._id_gap_speed_orig))
            self._id_energy.id_gap.asynchronousMoveTo((self._id_gap_start - self._id_gap_runupdown))
        else:
            if self.verbose:
                self.logger.info('prepareIDForMove:asynchronousMoveTo(%r) @ %r (-ve)' % ((self._id_gap_start + self._id_gap_runupdown), self._id_gap_speed_orig))
            self._id_energy.id_gap.asynchronousMoveTo((self._id_gap_start + self._id_gap_runupdown))
示例#20
0
    def PreparePGMForMove(self):
        self._pgm_grat_pitch_speed_orig = 0.018
        self._pgm_grat_pitch.speed=self._pgm_grat_pitch_speed_orig
#         if self._pgm_grat_pitch_speed_orig != 0.018:
#             raise Exception("PGM Grit Pitch motor speed %f is not at maximum 0.018!" % (self._pgm_grat_pitch_speed_orig))
        
        # Calculate the energy midpoint
        energy_midpoint = (self._move_end + self._move_start) / 2.
        if self.verbose:
            self.logger.info('preparePGMForMove:energy_midpoint=%r ' % (energy_midpoint))

        if installation.isLive():
            self.grating_density, self.cff, self.grating_offset, self.plane_mirror_offset, self.energy_calibration_gradient, self.energy_calibration_reference = self.getPgmEnergyParameters()
        else:
            self.grating_density, self.cff, self.grating_offset, self.plane_mirror_offset, self.energy_calibration_gradient, self.energy_calibration_reference = self.getPgmEnergyParametersFixed()
            
        # Calculate plane mirror angle for given grating density, energy, cff and offsets
        self.mirr_pitch_midpoint = enecff2mirror(gd=self.grating_density, 
                                                 energy=energy_midpoint, 
                                                 cff=self.cff, 
                                                 groff=self.grating_offset, 
                                                 pmoff=self.plane_mirror_offset, 
                                                 ecg=self.energy_calibration_gradient, 
                                                 ecr=self.energy_calibration_reference)
        # Calculate grating angles for given grating density, energy, mirror angle and offsets
        self._grat_pitch_start = enemirror2grating(gd=self.grating_density, 
                                                   energy=self._move_start, 
                                                   pmang=self.mirr_pitch_midpoint, 
                                                   groff=self.grating_offset, 
                                                   pmoff=self.plane_mirror_offset, 
                                                   ecg=self.energy_calibration_gradient, 
                                                   ecr=self.energy_calibration_reference)
        self._grat_pitch_end = enemirror2grating(gd=self.grating_density, 
                                                 energy=self._move_end, 
                                                 pmang=self.mirr_pitch_midpoint, 
                                                 groff=self.grating_offset, 
                                                 pmoff=self.plane_mirror_offset, 
                                                 ecg=self.energy_calibration_gradient, 
                                                 ecr=self.energy_calibration_reference)
        if not self.isIDMoveEnabled():
            self.k=1.0
            
        
        print self.k
        ### Calculate main cruise moves & speeds from start/end/step
        self._pgm_grat_pitch_speed = abs(self._grat_pitch_end - self._grat_pitch_start) / self.getTotalTime()
        print self._pgm_grat_pitch_speed
        self._pgm_grat_pitch_speed=self._pgm_grat_pitch_speed*self.k * self.pgmspeedfactor
        print self._pgm_grat_pitch_speed
        
        ### Calculate ramp distance from required speed and ramp times
        #check speed within limits
        if self._pgm_grat_pitch_speed<=0.000 or self._pgm_grat_pitch_speed>0.018:
            raise Exception("Calculated PGM Grit Pitch motor speed %f is outside limits [%f, %f]!" % (self._pgm_grat_pitch_speed, 0.000, 0.018))
        
        # Set the speed before we read out ramp times in case it is dependent
        self._pgm_grat_pitch.speed = self._pgm_grat_pitch_speed 
        # Should really be / | | | | | \ not /| | | | |\
        self._pgm_runupdown_time = self._pgm_grat_pitch.timeToVelocity
        self._pgm_runupdown = self._pgm_grat_pitch_speed / 2 * self._pgm_runupdown_time
        ### Move motor at full speed to start position
        if self.verbose:
            self.logger.info('preparePGMForMove:_pgm_mirr_pitch.asynchronousMoveTo(%r) @ %r ' % (self.mirr_pitch_midpoint * 1000., self._pgm_mirr_pitch.speed))
        self._pgm_mirr_pitch.asynchronousMoveTo(self.mirr_pitch_midpoint * 1000.)
        self._pgm_grat_pitch.speed = self._pgm_grat_pitch_speed_orig
        if self.getGratingMoveDirectionPositive():
            if self.verbose:
                self.logger.info('preparePGMForMove:asynchronousMoveTo(%r) @ %r (+ve)' % ((self._grat_pitch_start - self._pgm_runupdown) * 1000., self._pgm_grat_pitch_speed_orig))
            self._pgm_grat_pitch.asynchronousMoveTo((self._grat_pitch_start - self._pgm_runupdown) * 1000.)
        else:
            if self.verbose:
                self.logger.info('preparePGMForMove:asynchronousMoveTo(%r) @ %r (-ve)' % ((self._grat_pitch_start + self._pgm_runupdown) * 1000., self._pgm_grat_pitch_speed_orig))
            self._pgm_grat_pitch.asynchronousMoveTo((self._grat_pitch_start + self._pgm_runupdown) * 1000.)
示例#21
0
    def _waitForNewElements(self):
        """return the number of new elements available, polling until some are"""
        #if self.verbose: self.logger.info('_waitForNewElements()... elements_read=%r' % (self.elements_read))
        acquiring_old = self._controller.getChannelInputStreamAcquiring()
        exposure_time = self._controller.getExposureTime()
        sleep_time = exposure_time if exposure_time > 0.2 else 0.2
        log_timeout = exposure_time + 5
        log_time = last_element_time = datetime.now()
        new_element_timeout = exposure_time + 20.0

        while True and not self.stoppedExplicitly:
            if installation.isLive():
                elements_available = int(float(self.pv_count.caget()))
                from scannable.waveform_channel.BinpointWaveformChannelController import BinpointWaveformChannelController
                if isinstance(self._controller,
                              BinpointWaveformChannelController):
                    elements_available = elements_available + 1  #BINPOINT:NLAST.B index starts at 0, -1 is waveform empty
            else:
                self.logger.info(
                    "DUMMY mode: number of positions set in WaveformChannelScannable to its controller is %r"
                    % self._controller.number_of_positions)
                #the following line does not ensure cvscan complete 100%
                #elements_available = sum(x<=float(self.hardwareTriggerProvider._pgm_grat_pitch.getPosition()/1000.0) for x in self.hardwareTriggerProvider.grating_pitch_positions)
                if not self.startTimeSet:
                    elements_available = int(
                        self._controller.number_of_positions)
                else:
                    elapsedTime = time.time() - self.start_time
                    if elapsedTime < self._controller.getHardwareTriggerProvider(
                    ).getTotalTime():
                        elements_available = int(
                            self._controller.number_of_positions *
                            elapsedTime / self._controller.
                            getHardwareTriggerProvider().getTotalTime())
                    else:
                        elements_available = int(
                            self._controller.number_of_positions)

            #print "self.elements_read = %d" % self.elements_read
            #print "element_available = %d" % elements_available
            # check continuous move started then poll the data so far
            acquiring = self._controller.getChannelInputStreamAcquiring()
            if acquiring:
                if acquiring_old <> acquiring:
                    self.logger.info(
                        '_waitForNewElements() elements_available=%r, elements_read=%r, acquiring now %r, was %r'
                        % (elements_available, self.elements_read, acquiring,
                           acquiring_old))
                    acquiring_old = acquiring
                    last_element_time = log_time = datetime.now()
                if elements_available > self.elements_read:
                    last_element_time = log_time = datetime.now()
                    if self.verbose:
                        self.logger.info(
                            '_waitForNewElements() elements_available=%r, elements_read=%r, acquiring %r, %r new_elements available'
                            %
                            (elements_available, self.elements_read, acquiring,
                             elements_available - self.elements_read))
                    return elements_available - self.elements_read
                elif (datetime.now() - last_element_time) > timedelta(
                        seconds=new_element_timeout):
                    self.logger.error(
                        "_waitForNewElements() no new elements for  %r seconds, raising an exception..."
                        % new_element_timeout)
                    raise NoSuchElementException(
                        "no new elements for  %r seconds" %
                        new_element_timeout)
            if self.verbose and (datetime.now() -
                                 log_time) > timedelta(seconds=log_timeout):
                self.logger.info(
                    '_waitForNewElements() elements_available=%r, elements_read=%r, acquiring %r, no new elements for %r seconds!'
                    % (elements_available, self.elements_read, acquiring,
                       log_timeout))
                log_time = datetime.now()
                if elements_available == self.elements_read and self.elements_read == self._controller.number_of_positions:
                    self.logger.info(
                        '_waitForNewElements() elements_available=%r, elements_read=%r, number_of_positions_expected=%r, Data collection should finish now!'
                        % (elements_available, self.elements_read,
                           self._controller.number_of_positions))
                    self.stop(
                    )  #all elements are already read, so this thread can stop
            time.sleep(sleep_time)
示例#22
0
 def configure(self):
     if self.verbose:
         self.logger.info("%s %s" % (self.name, 'configure()...'))
     if installation.isLive():
         self.pv_erasestart.configure()
示例#23
0
    def _waitForNewElements(self):
        """return the number of new elements available, polling until some are"""
        #if self.verbose: self.logger.info('_waitForNewElements()... elements_read=%r' % (self.elements_read))
        acquiring_old = self._controller.getChannelInputStreamAcquiring()
        exposure_time = self._controller.getExposureTime()
        sleep_time = exposure_time if exposure_time > 0.2 else 0.2
        log_timeout = exposure_time + 5
        log_time = last_element_time = datetime.now()
        new_element_timeout = exposure_time + 5.0  # it takes about 200 second to complete a full range move of pgm_grit_pitch.

        while True and not self.stoppedExplicitly:
            if installation.isLive():
                elements_available = int(float(self.pv_count.caget()))
            else:
                self.logger.info(
                    "DUMMY mode: number of positions set in WaveformChannelScannable to its controller is %r"
                    % self._controller.number_of_positions)
                elements_available = sum(
                    x <= float(
                        self.hardwareTriggerProvider._energy.getPosition()) for
                    x in self.hardwareTriggerProvider.mono_energy_positions)
            # Some waveform PVs keep returning old data for a short time even after a new acq is started and even retain the old count
            # for some time after the new acq has started, so check with the controller before trusting the count
            # check continuous move started then poll the data so far
            acquiring = self._controller.getChannelInputStreamAcquiring()
            if acquiring:
                if acquiring_old <> acquiring:
                    self.logger.info(
                        '_waitForNewElements() elements_available=%r, elements_read=%r, acquiring now %r, was %r'
                        % (elements_available, self.elements_read, acquiring,
                           acquiring_old))
                    acquiring_old = acquiring
                    last_element_time = log_time = datetime.now()
                if elements_available > self.elements_read:
                    last_element_time = log_time = datetime.now()
                    if self.verbose:
                        self.logger.info(
                            '_waitForNewElements() elements_available=%r, elements_read=%r, acquiring %r, %r new_elements available'
                            %
                            (elements_available, self.elements_read, acquiring,
                             elements_available - self.elements_read))
                    return elements_available - self.elements_read
                elif (datetime.now() - last_element_time) > timedelta(
                        seconds=new_element_timeout):
                    self.logger.error(
                        "_waitForNewElements() no new elements for  %r seconds, raising an exception..."
                        % new_element_timeout)
                    raise NoSuchElementException(
                        "no new elements for  %r seconds" %
                        new_element_timeout)
            if self.verbose and (datetime.now() -
                                 log_time) > timedelta(seconds=log_timeout):
                self.logger.info(
                    '_waitForNewElements() elements_available=%r, elements_read=%r, acquiring %r, no new elements for %r seconds!'
                    % (elements_available, self.elements_read, acquiring,
                       log_timeout))
                log_time = datetime.now()
                if elements_available == self.elements_read and self.elements_read == self._controller.number_of_positions:
                    self.logger.info(
                        '_waitForNewElements() elements_available=%r, elements_read=%r, number_of_positions_expected=%r, Data collection should finish now!'
                        % (elements_available, self.elements_read,
                           self._controller.number_of_positions))
                    self.stop(
                    )  #all elements are already read, so this thread can stop
            time.sleep(sleep_time)
示例#24
0
    def prepareForMove(self):
        if self.verbose: self.logger.info('prepareForMove()...')
        self._pgm_grat_pitch_speed_orig = self._pgm_grat_pitch.speed

        # Calculate the energy midpoint
        energy_midpoint = (self._move_end + self._move_start) / 2.
        if self.verbose:
            self.logger.info('prepareForMove:energy_midpoint=%r ' %
                             (energy_midpoint))

        if installation.isLive():
            (self.grating_density, self.cff, self.grating_offset,
             self.plane_mirror_offset, self.energy_calibration_gradient,
             self.energy_calibration_reference
             ) = self.getPgmEnergyParameters()
        else:
            (self.grating_density, self.cff, self.grating_offset,
             self.plane_mirror_offset, self.energy_calibration_gradient,
             self.energy_calibration_reference
             ) = self.getPgmEnergyParametersFixed()

        # Calculate plane mirror angle for given grating density, energy, cff and offsets
        self.mirr_pitch_midpoint = enecff2mirror(
            gd=self.grating_density,
            energy=energy_midpoint,
            cff=self.cff,
            groff=self.grating_offset,
            pmoff=self.plane_mirror_offset,
            ecg=self.energy_calibration_gradient,
            ecr=self.energy_calibration_reference)

        # Calculate grating angles for given grating density, energy, mirror angle and offsets
        self._grat_pitch_start = enemirror2grating(
            gd=self.grating_density,
            energy=self._move_start,
            pmang=self.mirr_pitch_midpoint,
            groff=self.grating_offset,
            pmoff=self.plane_mirror_offset,
            ecg=self.energy_calibration_gradient,
            ecr=self.energy_calibration_reference)

        self._grat_pitch_end = enemirror2grating(
            gd=self.grating_density,
            energy=self._move_end,
            pmang=self.mirr_pitch_midpoint,
            groff=self.grating_offset,
            pmoff=self.plane_mirror_offset,
            ecg=self.energy_calibration_gradient,
            ecr=self.energy_calibration_reference)

        ### Calculate main cruise moves & speeds from start/end/step
        self._pgm_grat_pitch_speed = (
            abs(self._grat_pitch_end - self._grat_pitch_start) /
            self.getTotalTime())
        ### Calculate ramp distance from required speed and ramp times
        # Set the speed before we read out ramp times in case it is dependent
        self._pgm_grat_pitch.speed = self._pgm_grat_pitch_speed
        # Should really be / | | | | | \ not /| | | | |\
        self._pgm_runupdown_time = self._pgm_grat_pitch.timeToVelocity
        self._pgm_runupdown = self._pgm_grat_pitch_speed / 2 * self._pgm_runupdown_time
        ### Move motor at full speed to start position
        if self.verbose:
            self.logger.info(
                'prepareForMove:_pgm_mirr_pitch.asynchronousMoveTo(%r) @ %r ' %
                (self.mirr_pitch_midpoint * 1000., self._pgm_mirr_pitch.speed))
        self._pgm_mirr_pitch.asynchronousMoveTo(self.mirr_pitch_midpoint *
                                                1000.)

        self._pgm_grat_pitch.speed = self._pgm_grat_pitch_speed_orig
        if self.getGratingMoveDirectionPositive():
            if self.verbose:
                self.logger.info(
                    'prepareForMove:asynchronousMoveTo(%r) @ %r (+ve)' %
                    ((self._grat_pitch_start - self._pgm_runupdown) * 1000.,
                     self._pgm_grat_pitch_speed_orig))
            self._pgm_grat_pitch.asynchronousMoveTo(
                (self._grat_pitch_start - self._pgm_runupdown) * 1000.)
        else:
            if self.verbose:
                self.logger.info(
                    'prepareForMove:asynchronousMoveTo(%r) @ %r (-ve)' %
                    ((self._grat_pitch_start + self._pgm_runupdown) * 1000.,
                     self._pgm_grat_pitch_speed_orig))
            self._pgm_grat_pitch.asynchronousMoveTo(
                (self._grat_pitch_start + self._pgm_runupdown) * 1000.)
        self.waitWhileMoving()
        ### Calculate trigger delays
        if self.verbose:
            self.logger.info('...prepareForMove')
示例#25
0
 def stop(self):
     self.mono_energy.stop()
     if installation.isLive():
         print("ID motion stop is not supported according to ID-Group instruction. Please wait for the Gap motion to complete!")
     else:  
         self.idscannable.stop()
示例#26
0
findpeak = FindScanPeak
findcentroid = FindScanCentroid

from gdascripts.scan.installStandardScansWithProcessing import *  #@UnusedWildImport
scan_processor.rootNamespaceDict = globals()

###############################################################################
###                   Configure camera bases                                    ###
###############################################################################

from pseudodevices.CameraExposureChanger import CameraExposureChanger

print "\nCreating camera exposure object ('sd1_camera_exposure')for SD1 camera"
sd1_camera_exposure = CameraExposureChanger(sd1_cam)

if installation.isLive():
    print "\nCreating camera exposure object ('sd3_camera_exposure')for SD3 camera"
    sd3_camera_exposure = PVScannable("sd3_camera_exposure",
                                      "BL09J-MO-SD-03:CAM:AcquireTime")
    sd3_camera_exposure.configure()

    print "\nCreating camera exposure object ('xbpm_camera_exposure')for XBPM camera"
    xbpm_camera_exposure = PVScannable("xbpm_camera_exposure",
                                       "BL09I-EA-XBPM-01:CAM:AcquireTime")
    xbpm_camera_exposure.configure()
else:
    print "\nCreating camera exposure object ('sd3_camera_exposure')for SD3 camera"
    sd3_camera_exposure = CameraExposureChanger(sd3_cam)

###############################################################################
###                   Configure scannable output formats                        ###
示例#27
0
    def PrepareIDForMove(self):
        GAP_SPEED_LOWER_LIMIT, GAP_SPEED_UPPER_LIMIT = self.id_speed_limits()

        if installation.isLive():
            #get ID gap speed from EPICS PV
            self._id_gap_speed_orig = float(self.idpvs['vel'].caget())
        else:
            self._id_gap_speed_orig = self._id_gap.speed

        #assume no row phase motors need to move during continuous energy move

        self._id_gap_start = self._energy.idgap(
            self._move_start)  #idgap calculation using energy in keV
        self._id_gap_end = self._energy.idgap(self._move_end)

        ### Calculate main cruise moves & speeds from start/end/step
        self._id_gap_speed = abs(self._id_gap_end - self._id_gap_start
                                 ) / self.getTotalTime() * self.idspeedfactor

        #check speed within limits
        if self._id_gap_speed < GAP_SPEED_LOWER_LIMIT or self._id_gap_speed > GAP_SPEED_UPPER_LIMIT:
            raise DeviceException(
                "Calculated ID gap speed %f is outside limits [%f, %f]!" %
                (self._id_gap_speed, GAP_SPEED_LOWER_LIMIT,
                 GAP_SPEED_UPPER_LIMIT))

        if installation.isLive():
            #Cannot set id_gap.speed through soft motor which in EPICS is read-only
            self.idpvs['vel'].caput(self._id_gap_speed)
        else:
            self._id_gap.speed = self._id_gap_speed

        ### Calculate ramp distance from required speed and ramp times
        #acceleration time per axis
        self._id_axis_speed = self._id_gap_speed / 2
        self._id_runupdown_time_per_axis = self._id_axis_speed * 4
        # Should really be / | | | | | \ not /| | | | |\
        self._id_runupdown_per_axis = self._id_axis_speed / 2 * self._id_runupdown_time_per_axis
        self._id_gap_runupdown = self._id_runupdown_per_axis * 2

        if installation.isLive():
            self.idpvs['vel'].caput(self._id_gap_speed_orig)
        else:
            self._id_gap.speed = self._id_gap_speed_orig

        if self.isIDGapMoveDirectionPositive():
            if self.verbose:
                self.logger.info(
                    'prepareIDForMove: _id_gap.asynchronousMoveTo(%r) @ %r (+ve)'
                    % ((self._id_gap_start - self._id_gap_runupdown),
                       self._id_gap_speed_orig))
            self._id_gap.asynchronousMoveTo(self._id_gap_start -
                                            self._id_gap_runupdown)
        else:
            if self.verbose:
                self.logger.info(
                    'prepareIDForMove: _id_gap.asynchronousMoveTo(%r) @ %r (-ve)'
                    % ((self._id_gap_start + self._id_gap_runupdown),
                       self._id_gap_speed_orig))
            self._id_gap.asynchronousMoveTo(self._id_gap_start +
                                            self._id_gap_runupdown)