def step_info(self, **kwargs):
     message = Message(quiet=True, **kwargs)
     for attr in ['ROW', 'ANGLE']:
         item = self._pvs.get(attr)
         message('{:18}: {:8} {:6} (pv={:})'.format(item.get('desc'), getattr(self, attr), 
             item.get('units',''), item.get('pv')))
     
     return message
    def sample_info(self, **kwargs):
        message = Message(quiet=True, **kwargs)
        for attr in ['COMM', 'CHIP', 'TYPE', 'FREQ', 'HORIZONTALPITCH', 'VERTICALPITCH',
                     'PATT', 'ACC', 'CELLS', 'WINDOWS', 'GAP']:
            item = self._pvs.get(attr)
            message('{:18}: {:8} {:6} (pv={:})'.format(item.get('desc'), getattr(self, attr), 
                item.get('units',''), item.get('pv')))

        return message        
Exemple #3
0
    def show_info(self, **kwargs):
        from psmessage import Message
        message = Message(quiet=True, **kwargs)
        if self.alerts or self.warnings:
            header = '{:15} {:14} {:8} {:22}'.format('detector', 'parameter',
                                                     'level', 'error')
            message(header)
            message('-' * (len(header)))
        if self.alerts:
            for alias, alerts in self.get_alert_info().items():
                for attr, alert in alerts.items():
                    message('{:15} {:14} {:8} {:22}'.format(
                        alias, attr, 'alert', alert))
        if self.warnings:
            for alias, alerts in self.get_warning_info().items():
                for attr, alert in alerts.items():
                    message('{:15} {:14} {:8} {:22}'.format(
                        alias, attr, 'warning', alert))

        return message
    def start_run(self, 
            use_daq=False, use_steps=True, record=None, test=False, post=True, 
            gasdet_min=-1., readOnMotor=True, addDrop=True, configure=True,
            safe=False, **kwargs):
        """
        Runs the sequence for a row of samples in a loop until aborted.

        Each interation of the loop it waits to receive a rising edge signal from the motion controller 
        before starting to play the sequence. Once the sequence is started it sends a continous set of sync 
        triggers to the motion controller at the desired frequency.

        - gasdet_min:  minimum gas detector value (GDET:FEE1:241:ENRC) to start a row [mJ] (default: -1)
        - use_daq: this controls whether the script will start running the daq and take a calib cycle for each row (default: False).
        - use_steps:  u
        - test:    mode where pulse picker is not used
        - record:  this controls the recording state of the daq (only meaningful if 'use_daq' is set to True).
            * True:  force recording of the run.
            * False: force off recording of the run.
            * None:  use the option selected in the daq gui (default).
        
        - configure: Configure the Sequencer with the current set of PVS
        
        """
        ####
        safe=False
        ####
        nstart=self.ACC
        ncells=self.CELLS
        nwindows=self.WINDOWS
        ngap=self.GAP
        freq=self.FREQ
        sample_name=self.CHIP
        runstr = None
        istep = 0
        self.STOP = 0
        if configure:
            self.configure_sequencer()

        self.analog.monitor_start()
        
        try:
            # configure daq if being used
            if use_daq:
                env.daq.record = record
                calibcontrols=[
                                ('nstart', nstart),
                                ('ncells', ncells),
                                ('nwindows', nwindows),
                                ('freq', freq),
                                ('angle', self.ANGLE),
                                ('row', self.ROW),
                                ('horizontalpitch', self.HORIZONTALPITCH),
                                ('verticalpitch', self.VERTICALPITCH),
                                ('pattern', self.PATT),
                              ]
                env.daq.configure(controls=calibcontrols,events=0)
                if not use_steps:
                    env.daq.begin(events=0,controls=calibcontrols)
                    run_num = env.daq.runnumber()

            if test:
                runstr = 'Test No Beam'
            else:
                runstr = 'Run {:}'.format(env.daq.runnumber())
        
            printnow("if desired setup DAQ & wrote sample_name %s to PV; now waiting for ready signal\n"%sample_name)
            message = self.sample_info()
            
            if safe:
                printnow("Opening the UM6 shutter...")
                self.um6_shutter_cmd = 1
                while self.um6_shutter_opn != 1:
                    time.sleep(0.01)
                printnow("done\n")

            #Start new row, ignore past input triggers
            self.ready_for_row.clear()
            printnow('Ready to run')
            Message('-------------------',append=True)
    
            self.STARTROW = 0
            time.sleep(0.2)
            while self.STOP == 0:
                
                # Now using epics CXI:USR:STARTROW instead of analog AI
                if self.STARTROW == 1:
                    try:
                        print "Pontus debug: USE LASER STATUS", self.USELASER
                        if self.USELASER:
                            self.laser_enabled=1
                        else:
                            self.laser_enabled=0

                    except:
                        print "Pontus f****d up"
                    self.STARTROW = 0
                    while self.gasdet_sig < gasdet_min:
                        time.sleep(1.)
                        printnow("Low beam = {:} mJ -- Waiting for beam to return ...\n".format(self.gasdet_sig))
                        Message("Low beam = {:} mJ -- Waiting for beam to return ...\n".format(self.gasdet_sig), append=True)

                    start_time = time.time()
                    if use_daq and use_steps:
                        calibcontrols=[
                                        ('nstart', nstart),
                                        ('ncells', ncells),
                                        ('nwindows', nwindows),
                                        ('freq', freq),
                                        ('angle', self.ANGLE),
                                        ('row', self.ROW),
                                        ('horizontalpitch', self.HORIZONTALPITCH),
                                        ('verticalpitch', self.VERTICALPITCH),
                                        ('pattern', self.PATT),
                                      ]
                        nEventsRecord = ncells*nwindows
                        if readOnMotor:
                            nEventsRecord = nstart+ncells*nwindows+(nwindows-1)*ngap
                        env.daq.begin(events=nEventsRecord,controls=calibcontrols)


                    #What is this / Why is this here                    
                    if (time.time()-start_time) < 0.2:
                        time.sleep(0.2-(time.time()-start_time))

                    if use_daq and use_steps:
                        run_num = env.daq.runnumber()
                        runstr = 'Run {:}'.format(run_num)
                    
                    try:
                        laser_state = 'Laser {:}'.format({0:'Off',1:'On'}.get(self.laser_enabled,'Unknown'))
                    except:
                        laser_state = 'Laser Unknown'

                    print laser_state
                    print runstr
                    self.istep = istep
                    self.runstr = runstr
                    printnow("Starting {:} Step {:}: {:} Row {:}, {:} deg angle ...\n".format(runstr, \
                                istep, self.CHIP, self.ROW, self.ANGLE))
                    step_message = "Step {:}: {:} Row {:}, {:} deg angle, {:}".format(istep, \
                                self.CHIP, self.ROW, self.ANGLE, laser_state)
                    
                    #Clear ready flag
                    self.ready_for_row.clear()
                    
                    env.event.start()
                    if use_daq and use_steps:
                        printnow('Waiting for DAQ end calib cycle')
                        env.daq.wait()
                        printnow('... done\n')

                    printnow('Waiting for Event Sequencer')
                    env.event.wait()
                    self.laser_enabled=0
                    printnow('... done\n')
                    stop_time = time.time()
                    printnow("   ... Completed in %.2f s\n"%(stop_time-start_time))
                    Message("{:} -- Completed in {:8.3f} s".format(step_message,stop_time-start_time), append=True)
                    istep += 1
                
                #Do we really need this sleep?    
                time.sleep(0.001)
                        
            printnow("Received STOP signal!\n")

        except KeyboardInterrupt:
            printnow("\nStopping row runner...")
            # abort sequencer
            env.event.stop()
            self._pp.close()
        
        finally:
            #self.seq_state = False

            # clear STOP flag
            self.STOP = 0
            self.analog.monitor_stop()
            
            if safe:
                printnow("Closing the UM6 shutter...")
                self.um6_shutter_cmd = 0
                while self.um6_shutter_cls != 1:
                    time.sleep(0.01)
                printnow("done\n")

            if use_daq:
                # revert daq record setting to gui control and disconnect
                #env.daq.wait()
                env.daq.stop()
                if runstr and post:
                    Message('{:}: {:} rows'.format(runstr,istep), append=True)
                    message = self.sample_info(append=True)
                    if record:
                        message.post(run_num=run_num)

                env.daq.record = None
                env.daq.disconnect()
def banner(ds, base='ds', time0=None):
    message = Message()
    ds = getattr(sys.modules['__main__'], base)
    message.add("*"*80)
    message.add("")
    message.add('Data loaded for the psana data_source = {:}'.format(str(ds)))
    if ds.events:
        message.add('Total Events = {:}'.format(ds.nevents))
    
    if time0:
        message.add('Load time = {:5.1f} sec'.format(time.time()-time0))
    
    message.add("")
    ds.configData.show_info()
    evt = ds.events.next()
    message.add("")
    message.add("*"*80)
    message.add('{:} is a python friendly (i.e, tab accessible) form of the psana.DataSource.'.format(base))
    message.add('Event data is accessible through aliases (psana get and keys methods are also preserved),  e.g.,')
    message.add("")
    message.add('In [1]: evt = {:}.events.next()'.format(base))
    message.add('In [2]: evt.Evr.eventCodes')
    message.add('Out[2]: {:}'.format(str(evt.Evr.eventCodes)))
    message.add("")
    message.add("The current event is also available in the {:}.events object, e.g.,".format(base)) 
    message.add("")
    message.add('In [3]: ds.events.current.Evr.eventCodes')
    message.add('Out[3]: {:}'.format(str(ds.events.current.Evr.eventCodes)))
    message.add("")
    if ds.data_source.smd:
        message.add('For offline data (using smd small data access), one can also iterate through "calib cycle" steps.  e.g.,')
        message.add("In [4]: for events in {:}.steps:".format(base))
        message.add("            for evt in events:")
        message.add("                # Do something with events...")
        message.add("")
    
    message.add("*"*80)

    return message