Exemple #1
0
 def menu_line(self, roi):
    """ Private method """
    line = self.widgets.line[roi].get()
    energy = Xrf.lookup_xrf_line(line)
    if (energy == None):
       energy = Xrf.lookup_gamma_line(line)
    if (energy != None): 
       self.roi[roi].energy = energy
       self.widgets.energy[roi].setentry('%.3f' % energy)
Exemple #2
0
 def peak_label(self):
    peaks=self.fit.peaks
    label = self.widgets.label.get()
    label = label.strip()
    peaks[self.index].label = label
    energy = Xrf.lookup_xrf_line(label)
    if (energy == None): energy = Xrf.lookup_gamma_line(label)
    if (energy != None):
       peaks[self.index].initial_energy=energy
       # Set the energy flag to 0, since energy is known
       peaks[self.index].energy_flag=0
       # Set FWHM flag to 0, since peak width will be defined by
       # detector resolution
       peaks[self.index].fwhm_flag=0
    self.update_peaks()
Exemple #3
0
   def klm_markers(self, in_z):
      # Displays X-ray lines of element with atomic number Z.
      # Check that Z is within bounds.
      z = min(max(in_z, 1), 100)
      self.display.klm = z
      self.widgets.klm_element.selectitem(z-1, setentry=1)

      lines = []
      all_lines = self.display.k_lines + self.display.l_lines
      graph = self.widgets.plot
      for line in all_lines:
         marker = 'KLM'+line
         graph.marker_configure(marker, hide=1)
      element = self.widgets.klm_element.getcurselection()[0]
      show_lines = self.widgets.klm_line.getcurselection()
      if (show_lines == 'K') or (show_lines == 'K & L'):
         lines = lines + self.display.k_lines
      if (show_lines == 'L') or (show_lines == 'K & L'):
         lines = lines + self.display.l_lines
      length = .25
      # Convert marker sizes from fractions of display height to graph units
      (ymin,ymax) = graph.yaxis_limits()
      if (self.display.vlog):
         l = math.exp(length*(math.log(ymax) - math.log(ymin)))
      else:
         l = length*(ymax-ymin)
      for line in lines:
         marker = 'KLM'+line
         e = Xrf.lookup_xrf_line(element + ' ' + line)
         if (e != 0.):
            chan = self.foreground.scan.energy_to_channel(e, clip=1)
            data = self.foreground.data[chan]
            y = max(data, ymin+l)
            graph.marker_configure(marker, coords=(chan, '-Inf', chan, y),
                                   hide=0)
Exemple #4
0
 def save_file(self, file):
     self.widgets.status.configure(text='Saving Spectra...')
     self.widgets.elapsed_real.configure(text=' ')
     self.med.write_file(file)
     self.widgets.status.configure(text='Ready')
     self.next_file = Xrf.increment_filename(file)
     self.widgets.file.entryconfigure('Save Next*',
                                      label='Save Next = ' + self.next_file)
     self.widgets.save_next.configure(text='Save Next = ' + self.next_file)
Exemple #5
0
 def save_file(self, file):
    self.widgets.status.configure(text='Saving Spectra...')
    self.widgets.elapsed_real.configure(text=' ')
    self.med.write_file(file)
    self.widgets.status.configure(text='Ready')
    self.next_file = Xrf.increment_filename(file)
    self.widgets.file.entryconfigure('Save Next*', label='Save Next = ' +
                                                  self.next_file)
    self.widgets.save_next.configure(text='Save Next = ' + self.next_file)
Exemple #6
0
 def klm_mouse(self, event, marker):
    g = self.widgets.plot
    (x,y) = g.invtransform(event.x, event.y-25)
    if (event.type == '7'):  # Enter event - create a new text label
       line = self.widgets.klm_element.getcurselection()[0] + ' ' + marker[3:]
       energy = Xrf.lookup_xrf_line(line)
       text = line + '\n' + ('%.3f' % energy) + ' keV'
       g.marker_configure('klm_text', text=text, hide=0, coords=(x, y))
       g.marker_configure(marker, outline=self.colors.highlight_klm)
    elif (event.type == '8'):  # Leave event - delete text label
       g.marker_configure('klm_text', hide=1)
       g.marker_configure(marker, outline=self.colors.klm)
Exemple #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)
Exemple #8
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)
Exemple #9
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)
Exemple #10
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)
Exemple #11
0
      try:
         self.foreground.scan.write_file(file)
      except Exception, e:
         reply = tkMessageBox.showerror(title='scanDisplay error',
               message = 'Unable to open file: ' + file + ' ' + e)
         return

      self.options.save_done = 1
      if (self.options.inform_save):
         top = self.widgets.save_file_top = Toplevel()
         Pmw.MessageDialog(top, buttons=('OK',), defaultbutton=0,
                           message_text='Successfully saved as file: ' + file,
                           command=self.save_file_acknowledge)
         top.after(2000,self.save_file_acknowledge)

      self.file.next_filename = Xrf.increment_filename(file)
      self.widgets.file.entryconfigure('Save Next*', label='Save Next = ' +
                                                    self.file.next_filename)

   def save_file_acknowledge(self, button=None):
         self.widdgets.save_file_top.after_cancel()
         self.widgets.save_file_top.destroy()

   ############################################################
   def update_marker_text(self, marker):
      if (marker == 'cursor'):
         chan = self.display.cursor
         pos_widget = self.widgets.cur_pos
         count_widget = self.widgets.cur_counts
      elif (marker == 'left'):
         chan = self.display.lmarker
Exemple #12
0
   def __init__(self, mca, command=None):
      """
      Creates a new GUI window for calibrating energy for an Mca object.

      Inputs:
         mca:
            An Mca instance to be calibrated.  The Mca must have at least 2
            Regions of Interest (ROIs) defined for a linear calibration and
            2 ROIs defined for a quadratic calibration.

      Keywords:
         command:
            A callback command that will be executed if the OK button on
            the GUI window is pressed.  The callback will be invoked as:
               command(exit_status)
            where exit_status is 1 if OK was pressed, and 0 if Cancel was
            pressed or the window was closed with the window manager.

      Procedure:
         The calibration is done by determining the centroid position and
         energy of each ROI.

         The centroids positions are computed by fitting the
         ROI counts to a Gaussian, using CARSMath.fit_gaussian.

         The energy the ROI can be entered manually in the GUI window, or it
         can be determined automatically if the label of the ROI can be
         successfully used in Xrf.lookup_xrf_line() or Xrf.lookup_gamma_line().

         Each ROI can be selectively used or omitted when doing the calibration.

         The errors in the energy calibration and the FWHM of each ROI as a
         function of energy, can be plotted using BltPlot.
      """
      self.input_mca = mca
      self.mca = copy.copy(mca)
      self.exit_command = command
      self.roi = self.mca.get_rois()
      self.nrois = len(self.roi)
      if (self.nrois < 2):
         tkMessageBox.showerror(title='mcaCalibrateEnergy Error', 
                message='Must have at least two ROIs to perform calibration')
         return
      self.calibration = self.mca.get_calibration()
      self.fwhm_chan = Numeric.zeros(self.nrois, Numeric.Float)
      self.widgets = mcaCalibrateEnergy_widgets(self.nrois)
      self.data = self.mca.get_data()

      # Compute the centroid and FWHM of each ROI
      for i in range(self.nrois):
         left = self.roi[i].left
         right = self.roi[i].right+1
         total_counts = self.data[left:right]
         n_sel        = right - left
         sel_chans    = left + Numeric.arange(n_sel)
         left_counts  = self.data[left]
         right_counts = self.data[right]
         bgd_counts   = (left_counts + Numeric.arange(float(n_sel))/(n_sel-1) *
                                     (right_counts - left_counts))
         net_counts   = total_counts - bgd_counts
         net          = Numeric.sum(net_counts)
 
         if ((net > 0.) and (n_sel >= 3)):
            amplitude, centroid, fwhm = CARSMath.fit_gaussian(sel_chans, net_counts)
            self.roi[i].centroid = centroid
            self.fwhm_chan[i] = fwhm
         else:
            self.roi[i].centroid = (left + right)/2.
            self.fwhm_chan[i] = right-left
         self.roi[i].fwhm = (self.mca.channel_to_energy(self.roi[i].centroid + 
                                          self.fwhm_chan[i]/2.) - 
                             self.mca.channel_to_energy(self.roi[i].centroid - 
                                          self.fwhm_chan[i]/2.))

      self.widgets.top = t = Pmw.Dialog(command=self.menu_ok_cancel,
                     buttons=('OK', 'Apply', 'Cancel'),
                     title='mcaCalibrateEnergy')
      top = t.component('dialogchildsite')
      box = Frame(top, borderwidth=1, relief=SOLID); box.pack(fill=X, pady=3)
      t = Label(box, text='ROI'); t.grid(row=0, column=0)
      t = Label(box, text='Use?'); t.grid(row=0, column=1)
      t = Label(box, text='Centroid'); t.grid(row=0, column=2)
      t = Label(box, text='FWHM'); t.grid(row=0, column=3)
      t = Label(box, text='Energy'); t.grid(row=0, column=4)
      t = Label(box, text='Fluor. line'); t.grid(row=0, column=5)
      t = Label(box, text='Energy diff.'); t.grid(row=0, column=6)
      text_width=10
      for i in range(self.nrois):
         row=i+1
         t = Label(box, text=str(i)); 
         t.grid(row=row, column=0)
         self.widgets.use_flag[i] = t = Pmw.OptionMenu(box,
                        items=('No','Yes'),
                        initialitem = self.roi[i].use,
                        command=lambda e, s=self, r=i: s.menu_use(e,r))
         t.grid(row=row, column=1)
         self.widgets.centroid[i] = t = Pmw.EntryField(box, 
                        value=('%.3f' % self.roi[i].centroid),
                        entry_width=text_width, entry_justify=CENTER, 
                        command=lambda s=self, r=i: s.menu_centroid(r))
         t.grid(row=row, column=2)
         self.widgets.fwhm[i] = t = Label(box, 
                            text=('%.3f' % self.roi[i].fwhm), width=text_width,
                            justify=CENTER, borderwidth=1, relief=SOLID)
         t.grid(row=row, column=3)
         # If the ROI energy is zero, then try to use the label to lookup an
         # XRF line energy
         if (self.roi[i].energy == 0.0):
            self.roi[i].energy = Xrf.lookup_xrf_line(self.roi[i].label)
            if (self.roi[i].energy == None):
               self.roi[i].energy = Xrf.lookup_gamma_line(self.roi[i].label)
            if (self.roi[i].energy == None): self.roi[i].energy=0.0
         self.widgets.energy[i] = t = Pmw.EntryField(box, 
                        value=('%.3f' % self.roi[i].energy),
                        entry_width=text_width, entry_justify=CENTER, 
                        command=lambda s=self, r=i: s.menu_energy(r))
         t.grid(row=row, column=4)
         self.widgets.line[i] = t = Pmw.EntryField(box, 
                        value=str(self.roi[i].label),
                        entry_width=text_width, entry_justify=CENTER, 
                        command=lambda s=self, r=i: s.menu_line(r))
         t.grid(row=row, column=5)

         self.widgets.energy_diff[i] = t = Label(box, 
                            text=('%.3f' % 0.0), width=text_width,
                            justify=CENTER, borderwidth=1, relief=SOLID)
         t.grid(row=row, column=6)

      row = Frame(top, borderwidth=1, relief=SOLID); row.pack(fill=X, pady=3)
      self.widgets.fit_type = t = Pmw.OptionMenu(row, labelpos=N,
                                        label_text='Calibration type:',
                                        items=('Linear','Quadratic'))
      t.pack(side=LEFT, anchor=S)
      self.widgets.do_fit = t = Button(row, text='Compute calibration', 
                                        command=self.menu_do_fit)
      t.pack(side=LEFT, anchor=S)
      self.widgets.plot_cal = t = Button(row, text='Plot calibration error',
                                        command=self.menu_plot_calibration)
      t.pack(side=LEFT, anchor=S)
      self.widgets.plot_fwhm = t = Button(row, text='Plot FWHM',
                                        command=self.menu_plot_fwhm)
      t.pack(side=LEFT, anchor=S)

      row = Frame(top, borderwidth=1, relief=SOLID); row.pack(fill=X, pady=3)
      text_width=10
      t = Label(row, text='Calibration coefficients'); t.pack()
      self.widgets.cal_units = t = Pmw.EntryField(row, 
                            label_text='Units:', labelpos=W,
                            value=self.calibration.units,
                            entry_width=text_width, entry_justify=CENTER)
      t.pack(side=LEFT)
      self.widgets.cal_offset = t = Pmw.EntryField(row, 
                            label_text='Offset:', labelpos=W,
                            value=self.calibration.offset,
                            entry_width=text_width, entry_justify=CENTER)
      t.pack(side=LEFT)
      self.widgets.cal_slope = t = Pmw.EntryField(row, 
                            label_text='Slope:', labelpos=W,
                            value=self.calibration.slope,
                            entry_width=text_width, entry_justify=CENTER)
      t.pack(side=LEFT)
      self.widgets.cal_quad = t = Pmw.EntryField(row, 
                            label_text='Quadratic:', labelpos=W,
                            value=self.calibration.quad,
                            entry_width=text_width, entry_justify=CENTER)
      t.pack(side=LEFT)