Esempio n. 1
0
    def __init__(self, name):
        """
      Creates a new scanParms instance.

      Inputs:
         name:
            The name of the EPICS motor record without any trailing period or field
            name.

      Example:
         m=scanParm('x12c:mon:scanParms')
      """
        self.pvs = {
            "step": epicsPV.epicsPV(name + ".STEP", wait=0),
            "sp": epicsPV.epicsPV(name + ".SP", wait=0),
            "ep": epicsPV.epicsPV(name + ".EP", wait=0),
            "np": epicsPV.epicsPV(name + ".NP", wait=0),
            "go": epicsPV.epicsPV(name + ".GO", wait=0),
            "ar": epicsPV.epicsPV(name + ".AR", wait=0),
            "aft": epicsPV.epicsPV(name + ".AFT", wait=0),
            "sm": epicsPV.epicsPV(name + ".SM", wait=0),
            "load": epicsPV.epicsPV(name + ".LOAD", wait=0),
        }
        # Wait for all PVs to connect
        self.pvs["load"].pend_io()
Esempio n. 2
0
    def __init__(self, prefix):
        self.image_listener = None
        self.image = None

        self.sizex = epicsPV(prefix + 'ArraySizeX_RBV', wait=False)
        self.sizey = epicsPV(prefix + 'ArraySizeY_RBV', wait=False)
        self.sizez = epicsPV(prefix + 'ArraySizeZ_RBV', wait=False)
        self.array = epicsPV(prefix + 'ArrayData', wait=True)

        self.sizex.setMonitor()
        self.sizey.setMonitor()
        self.sizez.setMonitor()
        self.array.add_masked_array_event(None,
                                          0,
                                          None,
                                          self._new_data,
                                          use_numpy=True)
        self.array.flush_io()
Esempio n. 3
0
    def __init__(self, name):
        """
      Creates a new epicsScaler instance.
      
      Inputs:
         name:
            The name of the EPICS scaler record, without the trailing period
            or field name.
            
      Example:
         s = epicsScaler('13IDC:scaler1')
      """
        self.nchans = epicsPV.epicsPV(name + '.NCH').getw()
        self.pvs = {
            'count': epicsPV.epicsPV(name + '.CNT'),
            'preset_time': epicsPV.epicsPV(name + '.TP'),
            'preset': [],
            'counts': [],
            'label': []
        }
        for i in range(1, self.nchans + 1):
            self.pvs['preset'].append(epicsPV.epicsPV(name + '.PR' + str(i)))
            self.pvs['counts'].append(epicsPV.epicsPV(name + '.S' + str(i)))
            self.pvs['label'].append(epicsPV.epicsPV(name + '.NM' + str(i)))


# Wait for all PVs to connect
        self.pvs['count'].pend_io()
Esempio n. 4
0
    def spectra_scan(self, first_file, scan_record):
        """
      PURPOSE:
         This procedures collects Med spectra and saves them to disk in
         conjunction with an EPICS scan record.
         epics_med.spectra_scan(first_file, scan_record)
      INPUTS:
         first_file:  
            The name of the first spectrum file to save.  Subsequent files 
            will be named using the INCREMENT_FILENAME()function.  The 
            filename must end in a numeric extension for this to work.
         scan_record:
            The name of the EPICS scan record which is controlling the scan.
            This scan record must be configure to start epicsMed data collection
            by writing "1" into the EraseStart record of the EPICS MED database.
      PROCEDURE:
         1) Wait for scan.EXSC = 1, meaning scan has started
         2) Wait for ClientWait=1, meaning acquisition has started
         3) Wait for Acquiring=0, meaning acquisition has completed
         4) Write data to disk with MED::WRITE_FILE, increment file name
         5) Reset ClientWait to 0 so scan will continue
         6) If scan.EXSC is still 1 go to 2.
      """
        file = first_file

        # Enable waiting for client
        self.pvs.enable_client_wait.putw(1)

        # Create PV for scan record executing
        scanPV = epicsPV.epicsPV(scan_record + '.EXSC')
        # Wait for scan to start
        while (scanPV.getw() == 0):
            time.sleep(.1)

        while (1):
            # If scan is complete, exit
            if (scanPV.getw() == 0): return

            # Wait for acquisition to start
            self.wait(start=1, stop=0)

            # Wait for acquisition to complete
            self.wait(start=0, stop=1)

            # Write file.  This resets the client wait flag
            self.write_file(file)
            print 'Saved file: ', file
            file = Xrf.increment_filename(file)
Esempio n. 5
0
   def spectra_scan(self, first_file, scan_record):
      """
      Collects Mca spectra and saves them to disk in conjunction with an EPICS scan record.

      Inputs:
         first_file:  
            The name of the first spectrum file to save.  Subsequent files 
            will be named using the Xrf.increment_filename()function.  The 
            filename must end in a numeric extension for this to work.
            
         scan_record:
            The name of the EPICS scan record which is controlling the scan.
            This scan record must be configure to start epicsMca data collection
            by writing "1" into the ERST field if the EPICS MCA.
            
      Procedure:
         1) Waits for scan.EXSC = 1, meaning scan has started
         2) Waits for ClientWait=1, meaning acquisition has started
         3) Waits for Acquiring=0, meaning acquisition has completed
         4) Writes data to disk with epicsMca::write_file, increment file name
         5) Resets ClientWait to 0 so scan will continue
         6) If scan.EXSC is still 1 go to 2.
      """
      file = first_file

      # Enable waiting for client
      self.pvs['acquire']['enable_wait'].putw(1)

      # Create PV for scan record executing
      scanPV = epicsPV.epicsPV(scan_record + '.EXSC')
      # Wait for scan to start
      while (scanPV.getw() == 0):
         time.sleep(.1)

      while (1):
         # If scan is complete, exit
         if (scanPV.getw() == 0): return

         # Wait for acquisition to start
         self.wait(start=1, stop=0)

         # Wait for acquisition to complete
         self.wait(start=0, stop=1)
 
         # Write file.  This will reset the client wait flag.
         self.write_file(file)
         print 'Saved file: ', file
         file = Xrf.increment_filename(file)
Esempio n. 6
0
   def spectra_scan(self, first_file, scan_record):
      """
      PURPOSE:
         This procedures collects Med spectra and saves them to disk in
         conjunction with an EPICS scan record.
         epics_med.spectra_scan(first_file, scan_record)
      INPUTS:
         first_file:  
            The name of the first spectrum file to save.  Subsequent files 
            will be named using the INCREMENT_FILENAME()function.  The 
            filename must end in a numeric extension for this to work.
         scan_record:
            The name of the EPICS scan record which is controlling the scan.
            This scan record must be configure to start epicsMed data collection
            by writing "1" into the EraseStart record of the EPICS MED database.
      PROCEDURE:
         1) Wait for scan.EXSC = 1, meaning scan has started
         2) Wait for ClientWait=1, meaning acquisition has started
         3) Wait for Acquiring=0, meaning acquisition has completed
         4) Write data to disk with MED::WRITE_FILE, increment file name
         5) Reset ClientWait to 0 so scan will continue
         6) If scan.EXSC is still 1 go to 2.
      """
      file = first_file

      # Enable waiting for client
      self.pvs.enable_client_wait.putw(1)

      # Create PV for scan record executing
      scanPV = epicsPV.epicsPV(scan_record + '.EXSC')
      # Wait for scan to start
      while (scanPV.getw() == 0):
         time.sleep(.1)

      while (1):
         # If scan is complete, exit
         if (scanPV.getw() == 0): return

         # Wait for acquisition to start
         self.wait(start=1, stop=0)

         # Wait for acquisition to complete
         self.wait(start=0, stop=1)

         # Write file.  This resets the client wait flag
         self.write_file(file)
         print 'Saved file: ', file
         file = Xrf.increment_filename(file)
Esempio n. 7
0
    def spectra_scan(self, first_file, scan_record):
        """
      Collects Mca spectra and saves them to disk in conjunction with an EPICS scan record.

      Inputs:
         first_file:  
            The name of the first spectrum file to save.  Subsequent files 
            will be named using the Xrf.increment_filename()function.  The 
            filename must end in a numeric extension for this to work.
            
         scan_record:
            The name of the EPICS scan record which is controlling the scan.
            This scan record must be configure to start epicsMca data collection
            by writing "1" into the ERST field if the EPICS MCA.
            
      Procedure:
         1) Waits for scan.EXSC = 1, meaning scan has started
         2) Waits for ClientWait=1, meaning acquisition has started
         3) Waits for Acquiring=0, meaning acquisition has completed
         4) Writes data to disk with epicsMca::write_file, increment file name
         5) Resets ClientWait to 0 so scan will continue
         6) If scan.EXSC is still 1 go to 2.
      """
        file = first_file

        # Enable waiting for client
        self.pvs['acquire']['enable_wait'].putw(1)

        # Create PV for scan record executing
        scanPV = epicsPV.epicsPV(scan_record + '.EXSC')
        # Wait for scan to start
        while (scanPV.getw() == 0):
            time.sleep(.1)

        while (1):
            # If scan is complete, exit
            if (scanPV.getw() == 0): return

            # Wait for acquisition to start
            self.wait(start=1, stop=0)

            # Wait for acquisition to complete
            self.wait(start=0, stop=1)

            # Write file.  This will reset the client wait flag.
            self.write_file(file)
            print 'Saved file: ', file
            file = Xrf.increment_filename(file)
Esempio n. 8
0
 def menu_input(self, file=None):
    """
    Reads a new input file.  
    
    Keywords:
       file:
          The name of the new input file. If the file is not specified then
          this function opens a file chooser window to select one.
    """
    if (file == None): 
       file = tkFileDialog.askopenfilename(parent=self.top, 
                              title='Input file',
                              filetypes=[('All files','*')])
    if (file == ''): return
    input = open(file, 'r')
    lines = input.readlines()
    input.close()
    self.pvs = []
    for line in lines:
       pv = {}
       words = line.split('|')
       pv['name']=words[0].strip()
       pv['epicsPV'] = epicsPV.epicsPV(pv['name'])
       pv['data_format']=words[1].strip()
       pv['description']=words[2].strip()
       pv['description_format']=words[3].strip()
       self.pvs.append(pv)
    line = ('%20s' % ' ')
    for pv in self.pvs:
       line = line + ' ' + (pv['description_format'] % pv['name'])
    # Enable writing to label widgets
    self.widgets['labels'].configure(state=NORMAL)
    self.widgets['labels'].delete('1.0', END)
    self.widgets['labels'].insert('1.0', line+'\n')
    line = ('%20s' % 'Date and time')
    for pv in self.pvs:
       line = line + ' ' + (pv['description_format'] % pv['description'])
    self.widgets['labels'].insert('2.0', line+'\n')
    self.widgets['labels'].configure(state=DISABLED)
    # Set the widget width to the length of the line plus a bit to allow for
    # width of vertical scroll bar
    self.widgets['labels'].configure(width=len(line)+6)
    if (self.output != None): self.write_output_headers()
    self.input_valid=1
    self.widgets['start'].configure(state=NORMAL)
Esempio n. 9
0
   def __init__(self, name):
      """
      Creates a new scanParms instance.

      Inputs:
         name:
            The name of the EPICS motor record without any trailing period or field
            name.

      Example:
         m=scanParm('x12c:mon:scanParms')
      """
      self.pvs = {'step' : epicsPV.epicsPV(name+'.STEP',  wait=0), 
                  'sp': epicsPV.epicsPV(name+'.SP', wait=0),
                  'ep': epicsPV.epicsPV(name+'.EP', wait=0),
                  'np' : epicsPV.epicsPV(name+'.NP',  wait=0),
                  'go' : epicsPV.epicsPV(name+'.GO',  wait=0),
                  'ar': epicsPV.epicsPV(name+'.AR', wait=0),
                  'aft': epicsPV.epicsPV(name+'.AFT', wait=0),
                  'sm': epicsPV.epicsPV(name+'.SM', wait=0),
                  'load': epicsPV.epicsPV(name+'.LOAD', wait=0),
                  }
      # Wait for all PVs to connect
      self.pvs['load'].pend_io() 
Esempio n. 10
0
 def __init__(self, name):
    """
    Creates a new epicsScaler instance.
    
    Inputs:
       name:
          The name of the EPICS scaler record, without the trailing period
          or field name.
          
    Example:
       s = epicsScaler('13IDC:scaler1')
    """
    self.nchans = epicsPV.epicsPV(name+'.NCH').getw()
    self.pvs = {'count': epicsPV.epicsPV(name+'.CNT'), 
                'preset_time': epicsPV.epicsPV(name+'.TP'),
                'preset':[], 'counts':[], 'label':[]}
    for i in range(1, self.nchans+1): 
       self.pvs['preset'].append(epicsPV.epicsPV(name+'.PR'+str(i)))
       self.pvs['counts'].append(epicsPV.epicsPV(name+'.S'+str(i)))
       self.pvs['label'].append(epicsPV.epicsPV(name+'.NM'+str(i)))
Esempio n. 11
0
      exit(1)

   if desired_objective == '4x':
      desired_magnification = 4.0
   if desired_objective == '10x':
      desired_magnification = 10.0  
   if desired_objective == '20x':
      desired_magnification = 20.0   

   '''
   -------------------------------------------------------
   (0) Define variables and Check state
   -------------------------------------------------------
   '''
   chFocus=epicsMotor('X02DA-ES1-MS1:FOC')
   chToggleLens=epicsPV("X02DA-ES1-MS1:LNS+")
   chMagnification=epicsPV("X02DA-ES1-MS:MAGNF")
   chLensSelector=epicsPV("X02DA-ES1-MS1:LNSSEL")
   chXBaseStage=epicsMotor("X02DA-ES1-SMP1:TRX")
   chZBaseStage=epicsMotor("X02DA-ES1-SMP1:TRZ")
   chTomoPanelSampleInPos=epicsPV("X02DA-SCAN-SCN1:SMPIN")
   chFESlits_H=epicsPV("X02DA-FE-SHsize")
   chFESlits_V=epicsPV("X02DA-FE-SVsize")

   foc_4x = 1820
   foc_10x = 2692
   foc_20x = 2685.0
   X_4x = -227
   X_10x = -114
   X_20x = 0.0
   FE4x_H = 1.484
Esempio n. 12
0
    def __init__(self, record_name, environment_file=None):
        """
      Creates a new epicsMca.
      
      Inputs:
         record_Name:
            The name of the EPICS MCA record for the MCA object being created, without
            a trailing period or field name.
            
      Keywords:
         environment_file:
            This keyword can be used to specify the name of a file which
            contains the names of EPICS process variables which should be saved
            in the header of files written with Mca.write_file().
            If this keyword is not specified then this function will attempt the
            following:
               - If the system environment variable MCA_ENVIRONMENT is set then
                 it will attempt to open that file
               - If this fails, it will attempt to open a file called
                 'catch1d.env' in the current directory.
                 This is done to be compatible with the data catcher program.
            This is an ASCII file with each line containing a process variable
            name, followed by a space and a description field.

      Example:
        >>> from epicsMca import *
        >>> mca = epicsMca('13IDC:mca1')
        >>> print mca.data
      """
        Mca.Mca.__init__(self)
        self.max_rois = 32
        self.record_name = record_name
        self.name = record_name
        self.sequence = 0
        self.pvs = {
            'calibration': {
                'calo': None,
                'cals': None,
                'calq': None,
                'tth': None,
                'egu': None
            },
            'presets': {
                'prtm': None,
                'pltm': None,
                'pct': None,
                'pctl': None,
                'pcth': None,
                'chas': None,
                'dwel': None,
                'pscl': None
            },
            'elapsed': {
                'ertm': None,
                'eltm': None,
                'act': None,
                'rtim': None,
                'stim': None
            },
            'acquire': {
                'strt': None,
                'stop': None,
                'eras': None,
                'acqg': None,
                'proc': None,
                'erst': None
            },
            'data': {
                'nuse': None,
                'nmax': None,
                'val': None
            }
        }
        for group in self.pvs.keys():
            for pv in self.pvs[group].keys():
                name = self.record_name + '.' + string.upper(pv)
                self.pvs[group][pv] = epicsPV.epicsPV(name, wait=0)
        # Construct the names of the PVs for the ROIs
        self.roi_def_pvs = []
        self.roi_data_pvs = []
        for i in range(self.max_rois):
            n = 'R' + str(i)
            r = {
                n + 'lo': None,
                n + 'hi': None,
                n + 'bg': None,
                n + 'nm': None
            }
            self.roi_def_pvs.append(r)
            r = {n: None, n + 'n': None}
            self.roi_data_pvs.append(r)
        for roi in range(self.max_rois):
            for pv in self.roi_def_pvs[roi].keys():
                name = self.record_name + '.' + string.upper(pv)
                self.roi_def_pvs[roi][pv] = epicsPV.epicsPV(name, wait=0)
            for pv in self.roi_data_pvs[roi].keys():
                name = self.record_name + '.' + string.upper(pv)
                self.roi_data_pvs[roi][pv] = epicsPV.epicsPV(name, wait=0)

        # Construct the names of the PVs for the environment
        environment_file = os.getenv('MCA_ENVIRONMENT')
        if (environment_file == None):
            environment_file = 'catch1d.env'
        self.read_environment_file(environment_file)
        self.env_pvs = []
        for env in self.environment:
            self.env_pvs.append(epicsPV.epicsPV(env.name, wait=0))

        # Wait for all PVs to connect.  30 second timeout is for WAN, but
        # even this does not seem to be long enough on DSL connection
        self.pvs['calibration']['calo'].pend_io(30.)

        # ClientWait does not exist in simple_mca.db, which is used
        # for multi-element detectors.  We see if it exists by trying to connect
        # with a short timeout.
        client_wait = epicsPV.epicsPV(self.record_name + 'ClientWait', wait=0)
        enable_wait = epicsPV.epicsPV(self.record_name + 'EnableWait', wait=0)
        try:
            client_wait.pend_io(.01)
            self.pvs['acquire']['client_wait'] = client_wait
            self.pvs['acquire']['enable_wait'] = enable_wait
        except:
            self.pvs['acquire']['client_wait'] = None
            self.pvs['acquire']['enable_wait'] = None

        # Put monitors on the ERTM, VAL, NUSE and ACQG fields
        self.pvs['data']['nuse'].setMonitor()
        self.pvs['data']['val'].setMonitor()
        self.pvs['acquire']['acqg'].setMonitor()
        self.pvs['elapsed']['ertm'].setMonitor()

        # Read all of the information from the record
        self.get_calibration()
        self.get_presets()
        self.get_elapsed()
        self.get_rois()
        self.get_data()
Esempio n. 13
0
def epv(recordName, fieldName):
    pv = epicsPV.epicsPV(recordName + '.' + fieldName.upper(), wait=0)
    return (pv)
Esempio n. 14
0
    def __init__(self, prefix, n_detectors=16, bad=None):
        """
      This is the initialization code which is invoked when a new object of
      type epicsMed is created.
      med = epicsMed(prefix, n_detectors=16, bad=None)
      INPUTS:
         Prefix:  The prefix of the EPICS process variables for this
                  multi-element detector database.  The records for the 
                  process variables must be named according to the
                  following rules:
         prefix + 'Start'  ; PV which starts acquisition when 1 is written to it
         prefix + 'Stop'   ; PV which stops acquisition when 1 is written to it
         prefix + 'EraseAll' ; PV which erases all MCAs when 1 is written to it
         prefix + 'ReadSeq' ; PV which reads all MCAs when 1 is written to it
         prefix + 'ElapsedLive' ; PV from which elapsed live time can be read
         prefix + 'ElapsedReal' ; PV from which elapsed real time can be read
         prefix + 'PresetLive'  ; PV to which preset live time can be written
         prefix + 'PresetReal'  ; PV to which preset real time can be written
         prefix + 'Acquiring'   ; PV which is 1 when any detector is acquiring,
                                ;   0 when they are all done acquiring
         prefix + 'mcaN'        ; Name of MCA record for each detector, e.g. 
                                ; prefix + 'mca1', prefix + 'mca2', etc.
      KEYORD INPUTS:
         n_detectors: The number of detectors in the Med.  Default is 16.
         bad:  A scalar or list the bad detectors, e.g. bad=[3,7].
               The detectors are numbered from 1 to n_detectors.
               These detectors will not be accessed by any of the MED methods.
               In the following example:
               med = epicsMed('13IDC:med:', 16, bad=[3,7])
               detectors 3 and 7, out of a total of 16, are bad.  All of the
               Med functions, such as get_calibration(), get_data(), etc.
               will return only 14 values, not 16.
      SIDE EFFECTS:
         The routine establishes channel access monitors on all of the fields
         in the records which the methods in this class will read.  This
         greatly improves the speed and efficiency.
      """
        class pvs:
            pass

        self.pvs = pvs()
        t = Med.Med.__init__(self,
                             n_detectors)  # Invoke base class initialization
        self.pvs.start = epicsPV.epicsPV(prefix + 'StartAll', wait=0)
        self.pvs.erasestart = epicsPV.epicsPV(prefix + 'EraseStart', wait=0)
        self.pvs.stop = epicsPV.epicsPV(prefix + 'StopAll', wait=0)
        self.pvs.erase = epicsPV.epicsPV(prefix + 'EraseAll', wait=0)
        self.pvs.read = epicsPV.epicsPV(prefix + 'ReadAll', wait=0)
        self.pvs.elive = epicsPV.epicsPV(prefix + 'ElapsedLive', wait=0)
        self.pvs.ereal = epicsPV.epicsPV(prefix + 'ElapsedReal', wait=0)
        self.pvs.plive = epicsPV.epicsPV(prefix + 'PresetLive', wait=0)
        self.pvs.preal = epicsPV.epicsPV(prefix + 'PresetReal', wait=0)
        self.pvs.dwell = epicsPV.epicsPV(prefix + 'Dwell', wait=0)
        self.pvs.channel_advance = epicsPV.epicsPV(prefix + 'ChannelAdvance',
                                                   wait=0)
        self.pvs.prescale = epicsPV.epicsPV(prefix + 'Prescale', wait=0)
        self.pvs.acquiring = epicsPV.epicsPV(prefix + 'Acquiring', wait=0)
        self.pvs.client_wait = epicsPV.epicsPV(prefix + 'ClientWait', wait=0)
        self.pvs.enable_client_wait = epicsPV.epicsPV(prefix +
                                                      'EnableClientWait',
                                                      wait=0)
        good_detectors = range(1, self.n_detectors + 1)
        if (bad != None):
            for b in bad:
                del good_detectors[b - 1]
        self.n_detectors = len(good_detectors)
        self.good_detectors = good_detectors
        for i in range(self.n_detectors):
            pv = prefix + 'mca' + str(self.good_detectors[i])
            self.mcas[i] = epicsMca.epicsMca(pv)
        self.pvs.elive.setMonitor()
        self.pvs.ereal.setMonitor()
        self.pvs.acquiring.setMonitor()
        self.pvs.client_wait.setMonitor()
        # Wait for all PVs to connect
        self.pvs.client_wait.pend_io(30.)
        # Read the first MCA to get the number of channels
        t = self.mcas[0].get_data()
        # Read the environment from the first MCA
        self.environment = self.mcas[0].get_environment()
Esempio n. 15
0
   def __init__(self, name):
      """
      Creates a new epicsMotor instance.

      Inputs:
         name:
            The name of the EPICS motor record without any trailing period or field
            name.

      Example:
         m=epicsMotor('13BMD:m38')
      """
      self.pvs = {'val' : epicsPV.epicsPV(name+'.VAL',  wait=0), 
                  'dval': epicsPV.epicsPV(name+'.DVAL', wait=0),
                  'rval': epicsPV.epicsPV(name+'.RVAL', wait=0),
                  'rlv' : epicsPV.epicsPV(name+'.RLV',  wait=0),
                  'rbv' : epicsPV.epicsPV(name+'.RBV',  wait=0),
                  'drbv': epicsPV.epicsPV(name+'.DRBV', wait=0),
                  'rrbv': epicsPV.epicsPV(name+'.RRBV', wait=0),
                  'dmov': epicsPV.epicsPV(name+'.DMOV', wait=0),
                  'stop': epicsPV.epicsPV(name+'.STOP', wait=0),
                  'velo': epicsPV.epicsPV(name+'.VELO', wait=0),
                  's': epicsPV.epicsPV(name+'.S', wait=0),
                  'urev': epicsPV.epicsPV(name+'.UREV', wait=0),
                  'vbas': epicsPV.epicsPV(name+'.VBAS', wait=0),
                  'accl': epicsPV.epicsPV(name+'.ACCL', wait=0),
                  'desc': epicsPV.epicsPV(name+'.DESC', wait=0),
                  'mres': epicsPV.epicsPV(name+'.MRES', wait=0),
                  'hlm':  epicsPV.epicsPV(name+'.HLM',  wait=0),
                  'llm':  epicsPV.epicsPV(name+'.LLM',  wait=0),
                  'dhlm': epicsPV.epicsPV(name+'.DHLM', wait=0),
                  'dllm': epicsPV.epicsPV(name+'.DLLM', wait=0),
                  'bdst': epicsPV.epicsPV(name+'.BDST', wait=0),
                  'set':  epicsPV.epicsPV(name+'.SET',  wait=0),
                  'lvio': epicsPV.epicsPV(name+'.LVIO', wait=0),
                  'lls':  epicsPV.epicsPV(name+'.LLS',  wait=0),
                  'hls':  epicsPV.epicsPV(name+'.HLS',  wait=0),
                  'off':  epicsPV.epicsPV(name+'.OFF',  wait=0)
                  }
      # Wait for all PVs to connect
      self.pvs['val'].pend_io() 
Esempio n. 16
0
   def __init__(self, record_name, environment_file=None):
      """
      Creates a new epicsMca.
      
      Inputs:
         record_Name:
            The name of the EPICS MCA record for the MCA object being created, without
            a trailing period or field name.
            
      Keywords:
         environment_file:
            This keyword can be used to specify the name of a file which
            contains the names of EPICS process variables which should be saved
            in the header of files written with Mca.write_file().
            If this keyword is not specified then this function will attempt the
            following:
               - If the system environment variable MCA_ENVIRONMENT is set then
                 it will attempt to open that file
               - If this fails, it will attempt to open a file called
                 'catch1d.env' in the current directory.
                 This is done to be compatible with the data catcher program.
            This is an ASCII file with each line containing a process variable
            name, followed by a space and a description field.

      Example:
        >>> from epicsMca import *
        >>> mca = epicsMca('13IDC:mca1')
        >>> print mca.data
      """
      Mca.Mca.__init__(self)
      self.max_rois = 32
      self.record_name = record_name
      self.name = record_name
      self.sequence = 0
      self.pvs = {'calibration': 
                    {'calo': None,
                     'cals': None,
                     'calq': None,
                     'tth' : None,
                     'egu' : None},
                  'presets':
                    {'prtm': None,
                     'pltm': None,
                     'pct':  None,
                     'pctl': None,
                     'pcth': None,
                     'chas': None,
                     'dwel': None,
                     'pscl': None},
                  'elapsed':
                    {'ertm': None,
                     'eltm': None,
                     'act' : None,
                     'rtim': None,
                     'stim': None},
                  'acquire':
                    {'strt': None,
                     'stop': None,
                     'eras': None,
                     'acqg': None,
                     'proc': None,
                     'erst': None},
                  'data':
                    {'nuse': None,
                     'nmax': None,
                     'val':  None}}
      for group in self.pvs.keys():
         for pv in self.pvs[group].keys():
            name = self.record_name + '.' + string.upper(pv)
            self.pvs[group][pv] = epicsPV.epicsPV(name, wait=0)
      # Construct the names of the PVs for the ROIs
      self.roi_def_pvs=[]
      self.roi_data_pvs=[]
      for i in range(self.max_rois):
         n = 'R'+str(i)
         r = {n+'lo'  : None,
              n+'hi'  : None,
              n+'bg'  : None,
              n+'nm'  : None}
         self.roi_def_pvs.append(r)
         r = {n       : None,
              n+'n'   : None}
         self.roi_data_pvs.append(r)
      for roi in range(self.max_rois):
         for pv in self.roi_def_pvs[roi].keys():
            name = self.record_name + '.' + string.upper(pv)
            self.roi_def_pvs[roi][pv] = epicsPV.epicsPV(name, wait=0)
         for pv in self.roi_data_pvs[roi].keys():
            name = self.record_name + '.' + string.upper(pv)
            self.roi_data_pvs[roi][pv] = epicsPV.epicsPV(name, wait=0)

      # Construct the names of the PVs for the environment
      environment_file = os.getenv('MCA_ENVIRONMENT')
      if (environment_file == None):
         environment_file = 'catch1d.env'
      self.read_environment_file(environment_file)
      self.env_pvs = []
      for env in self.environment:
         self.env_pvs.append(epicsPV.epicsPV(env.name, wait=0))

      # Wait for all PVs to connect.  30 second timeout is for WAN, but
      # even this does not seem to be long enough on DSL connection
      self.pvs['calibration']['calo'].pend_io(30.)

      # ClientWait does not exist in simple_mca.db, which is used
      # for multi-element detectors.  We see if it exists by trying to connect
      # with a short timeout.
      client_wait = epicsPV.epicsPV(self.record_name + 'ClientWait', wait=0)
      enable_wait = epicsPV.epicsPV(self.record_name + 'EnableWait', wait=0)
      try:
         client_wait.pend_io(.01)
         self.pvs['acquire']['client_wait'] = client_wait
         self.pvs['acquire']['enable_wait'] = enable_wait
      except:
         self.pvs['acquire']['client_wait'] = None
         self.pvs['acquire']['enable_wait'] = None

      # Put monitors on the ERTM, VAL, NUSE and ACQG fields
      self.pvs['data']['nuse'].setMonitor()
      self.pvs['data']['val'].setMonitor()
      self.pvs['acquire']['acqg'].setMonitor()
      self.pvs['elapsed']['ertm'].setMonitor()

      # Read all of the information from the record
      self.get_calibration()
      self.get_presets()
      self.get_elapsed()
      self.get_rois()
      self.get_data()
Esempio n. 17
0
    def __init__(self, detector='13GE1:med:', element=1):
        class widgets:
            pass

        self.widgets = widgets()
        self.detector = detector
        self.element = element
        self.status = 'Ready'
        self.path = '.'
        self.file = 'test.xrf'
        self.next_file = self.file
        self.pvs = {}
        self.pvs['ElapsedReal'] = epicsPV.epicsPV(detector + 'ElapsedReal',
                                                  wait=0)
        self.pvs['PresetReal'] = epicsPV.epicsPV(detector + 'PresetReal',
                                                 wait=0)
        self.pvs['StartAll'] = epicsPV.epicsPV(detector + 'StartAll', wait=0)
        self.pvs['StopAll'] = epicsPV.epicsPV(detector + 'StopAll', wait=0)
        self.pvs['EraseAll'] = epicsPV.epicsPV(detector + 'EraseAll', wait=0)
        self.pvs['EraseStart'] = epicsPV.epicsPV(detector + 'EraseStart',
                                                 wait=0)
        self.pvs['Acquiring'] = epicsPV.epicsPV(detector + 'Acquiring', wait=0)
        self.pvs['mca1.ERTM'] = epicsPV.epicsPV(detector + 'mca1.ERTM', wait=0)
        self.pvs['mca1.ERTM'].pend_io()

        self.preset_real = self.pvs['PresetReal'].getw()
        self.elapsed_real = self.pvs['ElapsedReal'].getw()
        self.update_time = .5

        # menus
        top = myTkTop.myTkTop()
        top.title('medDisplay')
        self.widgets.top = top
        frame = Frame(top, borderwidth=1, relief='raised')
        frame.pack(fill=X)
        mb = Pmw.MenuBar(frame)
        mb.pack(fill=X)
        mb.addmenu('File', '', side='left')
        self.widgets.file = mb.component('File-menu')
        mb.addmenuitem('File',
                       'command',
                       label='Save As ...',
                       command=self.menu_save)
        mb.addmenuitem('File',
                       'command',
                       label='Save Next = ' + self.next_file,
                       command=self.menu_save_next)
        mb.addmenuitem('File',
                       'command',
                       label='New MCA Display',
                       command=self.menu_new_display)
        mb.addmenuitem('File',
                       'command',
                       'Exit',
                       label='Exit',
                       command=self.menu_exit)
        mb.addmenu('Help', '', side='right')
        self.widgets.help = mb.component('Help-menu')
        mb.addmenuitem('Help',
                       'command',
                       label='Usage',
                       command=self.menu_help)
        mb.addmenuitem('Help',
                       'command',
                       label='About',
                       command=self.menu_about)

        mb.addmenu('Options', '', side='left')
        self.widgets.options = mb.component('Options-menu')
        self.erase_on_start = IntVar()
        self.erase_on_start.set(1)
        mb.addmenuitem('Options',
                       'checkbutton',
                       label='Erase on Start',
                       variable=self.erase_on_start)

        # main page
        main_frame = Frame(self.widgets.top)
        main_frame.pack()
        left_frame = Frame(main_frame, borderwidth=1, relief='solid')
        left_frame.pack(side=LEFT, anchor=N)
        self.widgets.left_frame = left_frame
        right_frame = Frame(main_frame, borderwidth=1, relief='solid')
        right_frame.pack(side=LEFT, anchor=N)
        self.widgets.right_frame = right_frame

        # Right Hand Side for control buttons
        row = Frame(right_frame)
        row.pack(side=TOP, anchor=W)
        t = Label(row, text='Preset Real Time (s):', width=22, anchor=E)
        t.pack(side=LEFT)
        self.widgets.preset_real = t = Pmw.EntryField(
            row,
            value=0,
            entry_width=9,
            entry_justify=CENTER,
            validate={'validator': 'real'},
            entry_background='light blue',
            command=self.menu_preset_real)
        t.pack(side=LEFT)

        row = Frame(right_frame)
        row.pack(side=TOP, anchor=W)
        t = Label(row, text='Elapsed Real Time (s):', width=22, anchor=E)
        t.pack(side=LEFT)
        self.widgets.elapsed_real = t = Label(row,
                                              text=str(self.elapsed_real),
                                              foreground='blue')
        t.pack(side=LEFT)
        self.widgets.preset_real.setentry(self.preset_real)

        row = Frame(right_frame)
        row.pack(side=TOP)
        t = Button(row, text='Start', command=self.menu_start)
        t.pack(side=LEFT)
        t = Button(row, text='Stop', command=self.menu_stop)
        t.pack(side=LEFT)
        t = Button(row, text='Erase', command=self.menu_erase)
        t.pack(side=LEFT)
        row = Frame(right_frame)
        row.pack(side=TOP)
        t = Button(row, text='Copy ROIS', command=self.menu_copy_rois)
        t.pack(side=LEFT)
        row = Frame(right_frame)
        row.pack(side=TOP, anchor=W)
        t = Button(row, text='Save As ...', command=self.menu_save)
        t.pack(side=LEFT)
        self.widgets.save_next = t = Button(row,
                                            text='Save Next = ' +
                                            self.next_file,
                                            command=self.menu_save_next)
        t.pack(side=LEFT)

        #
        row = Frame(right_frame)
        row.pack(side=TOP, anchor=W)
        t = Label(row, text='Viewing Element: ')
        t.pack(side=LEFT)
        self.widgets.element = t = Label(row,
                                         text=str(self.element),
                                         width=2,
                                         foreground='blue')
        t.pack(side=LEFT)

        row = Frame(right_frame)
        row.pack(side=TOP, anchor=W)
        t = Label(row, text='Status: ')
        t.pack(side=LEFT)
        self.widgets.status = t = Label(row,
                                        text='Initializing...',
                                        foreground='blue')
        t.pack(side=LEFT)
        t.pack(side=RIGHT)

        #
        # Left Hand Side shows Detector Element Layout
        #
        t = Label(left_frame, text='Detector Elements')
        t.pack(side=TOP)
        width = 230
        height = 230
        area = Frame(left_frame, width=width, height=height)
        area.pack(side=TOP)
        self.widgets.area = area
        self.detector_positions = localMedLayout.localMedLayout()
        self.n_detectors = len(self.detector_positions)
        button_width = 1
        button_height = 1
        self.geom_state = 0
        self.widgets.det_buttons = []
        for d in range(self.n_detectors):
            t = Button(area,
                       text=str(d + 1),
                       width=button_width,
                       height=button_height,
                       command=lambda s=self, d=d: s.menu_element(d + 1))
            self.widgets.det_buttons.append(t)
        self.layout_detector()

        # Finally, load real versions of the mca_display and EPICS_MED objects
        # This will take some time, so we start with 'Initializing ...' in the
        # status message

        self.widgets.elapsed_real.configure(text=' ')
        self.mcaDisplay = mcaDisplay.mcaDisplay()
        self.mca = self.detector + 'mca' + str(self.element)
        self.mcaDisplay.open_detector(self.mca)
        self.med = epicsMed.epicsMed(self.detector,
                                     n_detectors=self.n_detectors)

        # when objects are really created, report 'Ready'.
        self.widgets.status.configure(text='Ready')

        # Start the timer routine
        self.widgets.top.after(int(self.update_time * 1000), self.menu_timer)
Esempio n. 18
0
    def __init__(self, recordName, environmentFile=None):
        """
      Creates a new epicsScan.
      
      Inputs:
         record_Name:
            The name of the EPICS SSCAN record for the epicsScan object being
            created, without a trailing period or field name.
            
      Keywords:
         environment_file:
            This keyword can be used to specify the name of a file which
            contains the names of EPICS process variables which should be saved
            in the header of files written with .write_file().
            If this keyword is not specified then this function will attempt the            following:
               - If the system environment variable MCA_ENVIRONMENT is set then
                 it will attempt to open that file
               - If this fails, it will attempt to open a file called
                 'catch1d.env' in the current directory.
                 This is done to be compatible with the data catcher program.
            This is an ASCII file with each line containing a process variable
            name, followed by a space and a description field.

      Example:
        >>> from epicsScan import *
        >>> scan = epicsScan('13IDC:scan1')
        >>> print scan.detectors[0].data
      """
        Scan.Scan.__init__(self)
        #skinner - I reduced the following from 70->6 and from 4->1 to match what we use
        self.maxDetectors = 6
        self.maxPositioners = 1
        self.maxTriggers = 4
        self.recordName = recordName
        self.triggers = []
        # Construct the positioners
        for i in range(self.maxPositioners):
            self.positioners.append(epicsPositioner(recordName, i))

        # Construct the detectors
        for i in range(self.maxDetectors):
            self.detectors.append(epicsDetector(recordName, i))

        # Construct the triggers
        for i in range(self.maxTriggers):
            self.triggers.append(epicsTrigger(recordName, i))

        # PVs for fields other than positioners, detectors and triggers
        self.pvs = {
            'exsc': None,
            'paus': None,
            'busy': None,
            'data': None,
            'npts': None,
            'mpts': None,
            'cpt': None,
            'pdly': None,
            'ddly': None,
            'vers': None,
            'smsg': None,
            'cmnd': None,
            'alrt': None,
            'faze': None,
        }
        for pv in self.pvs.keys():
            self.pvs[pv] = epv(self.recordName, pv.upper())
        # Construct the names of the PVs for the environment
        environment_file = os.getenv('MCA_ENVIRONMENT')
        if (environment_file == None):
            environment_file = 'catch1d.env'
        self.read_environment_file(environment_file)
        self.env_pvs = []
        for env in self.environment:
            self.env_pvs.append(epicsPV.epicsPV(env.name, wait=0))

        # Wait for all PVs to connect.  30 second timeout is for WAN, but
        # even this does not seem to be long enough on DSL connection
        self.pvs['exsc'].pend_io(30.)

        # Set monitors on all of the fields
        for p in self.positioners:
            p.setMonitors()
        for d in self.detectors:
            d.setMonitors()
        for t in self.triggers:
            t.setMonitors()
        for pv in self.pvs.keys():
            self.pvs[pv].setMonitor()

        # Read all of the information from the record
        self.read()
Esempio n. 19
0
   def __init__(self, recordName, environmentFile=None):
      """
      Creates a new epicsScan.
      
      Inputs:
         record_Name:
            The name of the EPICS SSCAN record for the epicsScan object being
            created, without a trailing period or field name.
            
      Keywords:
         environment_file:
            This keyword can be used to specify the name of a file which
            contains the names of EPICS process variables which should be saved
            in the header of files written with .write_file().
            If this keyword is not specified then this function will attempt the            following:
               - If the system environment variable MCA_ENVIRONMENT is set then
                 it will attempt to open that file
               - If this fails, it will attempt to open a file called
                 'catch1d.env' in the current directory.
                 This is done to be compatible with the data catcher program.
            This is an ASCII file with each line containing a process variable
            name, followed by a space and a description field.

      Example:
        >>> from epicsScan import *
        >>> scan = epicsScan('13IDC:scan1')
        >>> print scan.detectors[0].data
      """
      Scan.Scan.__init__(self)
      self.maxDetectors = 70
      self.maxPositioners = 4
      self.maxTriggers = 4
      self.recordName = recordName
      self.triggers = []
      # Construct the positioners
      for i in range(self.maxPositioners):
         self.positioners.append(epicsPositioner(recordName, i))

      # Construct the detectors
      for i in range(self.maxDetectors):
         self.detectors.append(epicsDetector(recordName, i))

      # Construct the triggers
      for i in range(self.maxTriggers):
         self.triggers.append(epicsTrigger(recordName, i))

      # PVs for fields other than positioners, detectors and triggers
      self.pvs = {'exsc': None,
                  'paus': None,
                  'busy': None,
                  'data': None,
                  'npts': None,
                  'mpts': None,
                  'cpt':  None,
                  'pdly': None,
                  'ddly': None,
                  'vers': None,
                  'smsg': None,
                  'cmnd': None,
                  'alrt': None,
                  'faze': None,
                  }
      for pv in self.pvs.keys():
         self.pvs[pv] = epv(self.recordName, pv.upper())
      # Construct the names of the PVs for the environment
      environment_file = os.getenv('MCA_ENVIRONMENT')
      if (environment_file == None):
         environment_file = 'catch1d.env'
      self.read_environment_file(environment_file)
      self.env_pvs = []
      for env in self.environment:
         self.env_pvs.append(epicsPV.epicsPV(env.name, wait=0))

      # Wait for all PVs to connect.  30 second timeout is for WAN, but
      # even this does not seem to be long enough on DSL connection
      self.pvs['exsc'].pend_io(30.)

      # Set monitors on all of the fields
      for p in self.positioners:
         p.setMonitors()
      for d in self.detectors:
         d.setMonitors()
      for t in self.triggers:
         t.setMonitors()
      for pv in self.pvs.keys():
         self.pvs[pv].setMonitor()


      # Read all of the information from the record
      self.read()
Esempio n. 20
0
 def __init__(self, prefix, n_detectors=16, bad=None):
    """
    This is the initialization code which is invoked when a new object of
    type epicsMed is created.
    med = epicsMed(prefix, n_detectors=16, bad=None)
    INPUTS:
       Prefix:  The prefix of the EPICS process variables for this
                multi-element detector database.  The records for the 
                process variables must be named according to the
                following rules:
       prefix + 'Start'  ; PV which starts acquisition when 1 is written to it
       prefix + 'Stop'   ; PV which stops acquisition when 1 is written to it
       prefix + 'EraseAll' ; PV which erases all MCAs when 1 is written to it
       prefix + 'ReadSeq' ; PV which reads all MCAs when 1 is written to it
       prefix + 'ElapsedLive' ; PV from which elapsed live time can be read
       prefix + 'ElapsedReal' ; PV from which elapsed real time can be read
       prefix + 'PresetLive'  ; PV to which preset live time can be written
       prefix + 'PresetReal'  ; PV to which preset real time can be written
       prefix + 'Acquiring'   ; PV which is 1 when any detector is acquiring,
                              ;   0 when they are all done acquiring
       prefix + 'mcaN'        ; Name of MCA record for each detector, e.g. 
                              ; prefix + 'mca1', prefix + 'mca2', etc.
    KEYORD INPUTS:
       n_detectors: The number of detectors in the Med.  Default is 16.
       bad:  A scalar or list the bad detectors, e.g. bad=[3,7].
             The detectors are numbered from 1 to n_detectors.
             These detectors will not be accessed by any of the MED methods.
             In the following example:
             med = epicsMed('13IDC:med:', 16, bad=[3,7])
             detectors 3 and 7, out of a total of 16, are bad.  All of the
             Med functions, such as get_calibration(), get_data(), etc.
             will return only 14 values, not 16.
    SIDE EFFECTS:
       The routine establishes channel access monitors on all of the fields
       in the records which the methods in this class will read.  This
       greatly improves the speed and efficiency.
    """
    class pvs:
       pass
    self.pvs = pvs()
    t = Med.Med.__init__(self, n_detectors)  # Invoke base class initialization
    self.pvs.start = epicsPV.epicsPV(prefix + 'StartAll', wait=0)
    self.pvs.erasestart = epicsPV.epicsPV(prefix + 'EraseStart', wait=0)
    self.pvs.stop  = epicsPV.epicsPV(prefix + 'StopAll', wait=0)
    self.pvs.erase = epicsPV.epicsPV(prefix + 'EraseAll', wait=0)
    self.pvs.read  = epicsPV.epicsPV(prefix + 'ReadAll', wait=0)
    self.pvs.elive  = epicsPV.epicsPV(prefix + 'ElapsedLive', wait=0)
    self.pvs.ereal  = epicsPV.epicsPV(prefix + 'ElapsedReal', wait=0)
    self.pvs.plive  = epicsPV.epicsPV(prefix + 'PresetLive', wait=0)
    self.pvs.preal  = epicsPV.epicsPV(prefix + 'PresetReal', wait=0)
    self.pvs.dwell  = epicsPV.epicsPV(prefix + 'Dwell', wait=0)
    self.pvs.channel_advance  = epicsPV.epicsPV(prefix + 'ChannelAdvance', wait=0)
    self.pvs.prescale  = epicsPV.epicsPV(prefix + 'Prescale', wait=0)
    self.pvs.acquiring  = epicsPV.epicsPV(prefix + 'Acquiring', wait=0)
    self.pvs.client_wait  = epicsPV.epicsPV(prefix + 'ClientWait', wait=0)
    self.pvs.enable_client_wait  = epicsPV.epicsPV(prefix + 'EnableClientWait', wait=0)
    good_detectors = range(1, self.n_detectors+1)
    if (bad != None):
       for b in bad:
          del good_detectors[b-1]
    self.n_detectors = len(good_detectors)
    self.good_detectors = good_detectors
    for i in range(self.n_detectors):
       pv = prefix + 'mca' + str(self.good_detectors[i])
       self.mcas[i] = epicsMca.epicsMca(pv)
    self.pvs.elive.setMonitor()
    self.pvs.ereal.setMonitor()
    self.pvs.acquiring.setMonitor()
    self.pvs.client_wait.setMonitor()
    # Wait for all PVs to connect
    self.pvs.client_wait.pend_io(30.)
    # Read the first MCA to get the number of channels
    t = self.mcas[0].get_data()
    # Read the environment from the first MCA
    self.environment = self.mcas[0].get_environment()
Esempio n. 21
0
def epv(recordName, fieldName):
   pv = epicsPV.epicsPV(recordName + '.' + fieldName.upper(), wait=0)
   return(pv)
Esempio n. 22
0
   def __init__(self, detector='13GE1:med:', element=1):
      class widgets:
         pass
      self.widgets = widgets()
      self.detector = detector
      self.element = element
      self.status = 'Ready'
      self.path = '.'
      self.file = 'test.xrf'
      self.next_file = self.file
      self.pvs = {}
      self.pvs['ElapsedReal'] = epicsPV.epicsPV(detector + 'ElapsedReal', wait=0)
      self.pvs['PresetReal']  = epicsPV.epicsPV(detector + 'PresetReal', wait=0)
      self.pvs['StartAll']    = epicsPV.epicsPV(detector + 'StartAll', wait=0)
      self.pvs['StopAll']     = epicsPV.epicsPV(detector + 'StopAll', wait=0)
      self.pvs['EraseAll']    = epicsPV.epicsPV(detector + 'EraseAll', wait=0)
      self.pvs['EraseStart']  = epicsPV.epicsPV(detector + 'EraseStart', wait=0)
      self.pvs['Acquiring']  = epicsPV.epicsPV(detector + 'Acquiring', wait=0)
      self.pvs['mca1.ERTM']   = epicsPV.epicsPV(detector + 'mca1.ERTM', wait=0)
      self.pvs['mca1.ERTM'].pend_io()
      
      self.preset_real = self.pvs['PresetReal'].getw()
      self.elapsed_real = self.pvs['ElapsedReal'].getw()
      self.update_time = .5
      
      # menus
      top = myTkTop.myTkTop()
      top.title('medDisplay')
      self.widgets.top = top
      frame = Frame(top, borderwidth=1, relief='raised')
      frame.pack(fill=X)
      mb = Pmw.MenuBar(frame)
      mb.pack(fill=X)
      mb.addmenu('File', '', side='left')
      self.widgets.file = mb.component('File-menu')
      mb.addmenuitem('File', 'command',
                      label='Save As ...',
                      command=self.menu_save)
      mb.addmenuitem('File', 'command',
                      label='Save Next = ' + self.next_file,
                      command=self.menu_save_next)
      mb.addmenuitem('File', 'command',
                      label='New MCA Display',
                      command=self.menu_new_display)
      mb.addmenuitem('File', 'command', 'Exit', label='Exit',
                      command=self.menu_exit)
      mb.addmenu('Help', '', side='right')
      self.widgets.help = mb.component('Help-menu')
      mb.addmenuitem('Help', 'command', label='Usage',
                      command=self.menu_help)
      mb.addmenuitem('Help', 'command', label='About',
                      command=self.menu_about)

      mb.addmenu('Options', '', side='left')
      self.widgets.options = mb.component('Options-menu')
      self.erase_on_start = IntVar()
      self.erase_on_start.set(1)
      mb.addmenuitem('Options', 'checkbutton', label='Erase on Start',
                     variable=self.erase_on_start)
 
      # main page
      main_frame = Frame(self.widgets.top); main_frame.pack()
      left_frame = Frame(main_frame, borderwidth=1, relief='solid')
      left_frame.pack(side=LEFT, anchor=N)
      self.widgets.left_frame = left_frame
      right_frame = Frame(main_frame, borderwidth=1, relief='solid')
      right_frame.pack(side=LEFT, anchor=N)
      self.widgets.right_frame = right_frame

      # Right Hand Side for control buttons
      row = Frame(right_frame)
      row.pack(side=TOP, anchor=W)
      t = Label(row, text = 'Preset Real Time (s):', width=22, 
                anchor=E); 
      t.pack(side=LEFT)
      self.widgets.preset_real = t = Pmw.EntryField(row, value=0,
                            entry_width=9, entry_justify=CENTER,
                            validate={'validator':'real'},
                            entry_background='light blue',
                            command=self.menu_preset_real)
      t.pack(side=LEFT)

      row = Frame(right_frame); 
      row.pack(side=TOP, anchor=W)
      t = Label(row, text = 'Elapsed Real Time (s):', width=22, 
                anchor=E); 
      t.pack(side=LEFT)
      self.widgets.elapsed_real = t = Label(row, text=str(self.elapsed_real),
                                            foreground='blue')
      t.pack(side=LEFT)
      self.widgets.preset_real.setentry(self.preset_real)

      row = Frame(right_frame); row.pack(side=TOP)
      t = Button(row, text='Start', command=self.menu_start); t.pack(side=LEFT)
      t = Button(row, text='Stop', command=self.menu_stop); t.pack(side=LEFT)
      t = Button(row, text='Erase', command=self.menu_erase); t.pack(side=LEFT)
      row = Frame(right_frame); row.pack(side=TOP)
      t = Button(row, text='Copy ROIS', command=self.menu_copy_rois)
      t.pack(side=LEFT)
      row = Frame(right_frame); row.pack(side=TOP, anchor=W)
      t = Button(row, text='Save As ...', command=self.menu_save); t.pack(side=LEFT)
      self.widgets.save_next = t = Button(row, text='Save Next = ' + self.next_file,
                                          command=self.menu_save_next)
      t.pack(side=LEFT)

      #
      row = Frame(right_frame); row.pack(side=TOP, anchor=W)
      t = Label(row, text = 'Viewing Element: '); t.pack(side=LEFT)
      self.widgets.element = t = Label(row, text=str(self.element), width=2,
                                       foreground='blue')
      t.pack(side=LEFT)

      row = Frame(right_frame); row.pack(side=TOP, anchor=W)
      t = Label(row, text = 'Status: '); t.pack(side=LEFT)
      self.widgets.status = t = Label(row, text='Initializing...', 
                                      foreground='blue'); t.pack(side=LEFT)
      t.pack(side=RIGHT)

      #
      # Left Hand Side shows Detector Element Layout
      #
      t = Label(left_frame, text='Detector Elements'); t.pack(side=TOP)
      width = 230
      height = 230
      area = Frame(left_frame, width=width, height=height); area.pack(side=TOP)
      self.widgets.area = area
      self.detector_positions = localMedLayout.localMedLayout()
      self.n_detectors = len(self.detector_positions)
      button_width=1
      button_height=1
      self.geom_state= 0
      self.widgets.det_buttons = []
      for d in range(self.n_detectors):
         t = Button(area, text=str(d+1), width=button_width,
                    height=button_height,
                    command = lambda s=self, d=d: s.menu_element(d+1))
         self.widgets.det_buttons.append(t)
      self.layout_detector()

      # Finally, load real versions of the mca_display and EPICS_MED objects
      # This will take some time, so we start with 'Initializing ...' in the
      # status message

      self.widgets.elapsed_real.configure(text=' ')
      self.mcaDisplay = mcaDisplay.mcaDisplay()
      self.mca = self.detector + 'mca' + str(self.element)
      self.mcaDisplay.open_detector(self.mca)
      self.med = epicsMed.epicsMed(self.detector, n_detectors=self.n_detectors)

      # when objects are really created, report 'Ready'.
      self.widgets.status.configure(text='Ready')

      # Start the timer routine
      self.widgets.top.after(int(self.update_time*1000), self.menu_timer)