示例#1
0
    def fit(self, xrange=None, bins=100, hist_nsig=3, dADU=150):
        if xrange is None:
            self._set_hist_range(dADU, bins, hist_nsig)
        else:
            self.xrange = xrange
        hist = np.histogram(self.signals, bins=bins, range=self.xrange)
        x = (hist[1][1:] + hist[1][:-1]) / 2.
        y = hist[0]
        ntot = sum(y)
        #
        # Starting values for two Gaussian fit. The relative
        # normalizations are initially set at the expected line ratio
        # of K-alpha/K-beta = 0.88/0.12.  The relative peak locations
        # and relative widths are fixed in fe55_lines(...) above.
        #
        p0 = (ntot * 0.88, self.median, self.stdev / 2., ntot * 0.12)
        self.pars, pcov = scipy.optimize.curve_fit(fe55_lines, x, y, p0=p0)

        kalpha_peak, kalpha_sigma = self.pars[1], self.pars[2]
        kalpha_peak_error = np.sqrt(pcov[1][1])
        # when there is only one peak, check if it is kalpha.
        if kalpha_peak < self.xrange[0] or (
                self.pars[3] > self.pars[0]
                and 6.49 / 5.889 * self.pars[1] < self.xrange[1]):
            kalpha_peak = 6.49 / 5.889 * self.pars[1]
            kalpha_peak_error = 6.49 / 5.889 * np.sqrt(pcov[1][1])
        fe55_yield = Fe55Yield(self.ccdtemp)
        Ne, Ne_error = fe55_yield.alpha()
        self.gain = Ne / kalpha_peak
        #        self.gain_error = float(self.gain*np.sqrt((Ne_error/Ne)**2 +
        #                                                  (kalpha_peak_error/kalpha_peak)**2))
        self.gain_error = float(self.gain * kalpha_peak_error / kalpha_peak)
        return kalpha_peak, kalpha_sigma
示例#2
0
 def __init__(self, imfile, mask_files=(), ccdtemp_par=-100):
     self.ccd = MaskedCCD(imfile, mask_files=mask_files)
     self.md = afwImage.readMetadata(imfile, 0)
     try:
         ccdtemp = self.md.get('CCDTEMP')
     except:
         ccdtemp = ccdtemp_par
     self.fe55_yield = Fe55Yield(ccdtemp).alpha()
     self._footprint_signal = self._footprint_signal_spans
示例#3
0
 def __init__(self, image, ccdtemp=None):
     if (image.getWidth() == imUtils.full_segment.getWidth()
             and image.getHeight() == imUtils.full_segment.getHeight()):
         # Trim to imaging area.
         self.image = image.Factory(image, imUtils.imaging)
     else:
         message = "XrayCte constructor: must pass an untrimmed image"
         raise RuntimeError(message)
     self.imarr = image.getArray()
     stat_control = afwMath.MEANCLIP | afwMath.STDEVCLIP | afwMath.STDEV
     stats = afwMath.makeStatistics(image, stat_control)
     self.mean = stats.getValue(afwMath.MEANCLIP)
     self.stdev = stats.getValue(afwMath.STDEVCLIP)
     #        self.stdev = stats.getValue(afwMath.STDEV)
     self.fe55_yield = Fe55Yield(ccdtemp).alpha()
示例#4
0
 def __init__(self, ccd, amp, bg_reg=(10, 10)):
     self.ccd = ccd
     self.amp = amp
     self.ccdtemp = ccd.md.get('CCDTEMP')
     self.fe55_yield = Fe55Yield(self.ccdtemp)
     raw_image = ccd[amp]
     try:
         self.imarr = raw_image.getArray()
     except AttributeError:
         self.imarr = raw_image.getImage().getArray()
     self.image = imutils.trim(raw_image, imaging=ccd.amp_geom.imaging)
     self.image -= self._bg_image(*bg_reg)
     flags = afwMath.MEANCLIP | afwMath.STDEVCLIP
     stats = afwMath.makeStatistics(self.image, flags, self.ccd.stat_ctrl)
     self.mean = stats.getValue(afwMath.MEANCLIP)
     self.stdev = stats.getValue(afwMath.STDEVCLIP)
     self.footprint_signal = self._footprint_signal_spans
示例#5
0
 def __init__(self,
              exptime=1,
              gain=5,
              ccdtemp=-95,
              full_well=None,
              geometry=AmplifierGeometry()):
     self.exptime = exptime
     self.gain = gain
     self.ccdtemp = ccdtemp
     self.full_well = full_well
     self.geometry = geometry
     self.fe55_yield = Fe55Yield(ccdtemp)
     self.image = afwImage.ImageF(geometry.full_segment)
     self.imarr = self.image.Factory(self.image,
                                     geometry.imaging).getArray()
     self.ny, self.nx = self.imarr.shape
     self.npix = self.nx * self.ny
     self._sigma = -1
示例#6
0
def fe55_gain_fitter(signals,
                     ccdtemp=-95,
                     make_plot=False,
                     xrange=None,
                     bins=100,
                     hist_nsig=10,
                     title='',
                     plot_filename=None,
                     interactive=True,
                     ylog=True):
    """
    Function to fit the distribution of charge cluster DN values from
    a Fe55 dataset.  A two Gaussian model of Mn K-alpha and K-beta
    lines is assumed with the ratio between the K-alpha and K-beta
    energies fixed at 5.889/6.49 and the the Gaussian width of the
    lines set equal.

    The gain (Ne/DN), location and sigma of the K-alpha peak (in units
    of DN) are returned as a tuple.

    If make_plot=True, then a matplotlib plot of the distribution and
    fit is displayed.

    If xrange is not None, then that 2-element tuple is used as the
    histogram x-range.

    If xrange is None, then the histogram x-range is set to 
    +/- hist_nsig*clipped_stdev about the median of the signal
    distribution.
    """
    flags = afwMath.MEDIAN | afwMath.STDEVCLIP
    try:
        stats = afwMath.makeStatistics(signals.tolist(), flags)
    except:
        print signals
        raise
    median = stats.getValue(afwMath.MEDIAN)
    stdev = stats.getValue(afwMath.STDEVCLIP)
    if xrange is None:
        # Set range of histogram to include both Kalpha and Kbeta peaks.
        xmin = max(median - hist_nsig * stdev, 200)
        xmax = min(median * 1785. / 1620. + hist_nsig * stdev, 1000)
        xrange = xmin, xmax
    # Save pylab interactive state.
    pylab_interactive_state = pylab.isinteractive()
    # Determine distribution mode and take that as the location of the
    # Kalpha peak
    hist = np.histogram(signals, bins=bins, range=xrange)
    xpeak = hist[1][np.where(hist[0] == max(hist[0]))][0]
    xrange = max(0, xpeak - 200), xpeak * 1785. / 1620. + 200
    hist = np.histogram(signals, bins=bins, range=xrange)
    yrange = 1, max(hist[0]) * 1.5
    if make_plot:
        if interactive:
            pylab.ion()
        else:
            pylab.ioff()
#        fig = pylab.figure()
#        axes = fig.add_subplot(111)
        win = plot.Window()
        hist = pylab.hist(signals,
                          bins=bins,
                          range=xrange,
                          histtype='bar',
                          color='b',
                          log=ylog)
        if ylog:
            plot.setAxis(xrange, yrange)
    else:
        pylab.ioff()


#        hist = np.histogram(signals, bins=bins, range=xrange)
    x = (hist[1][1:] + hist[1][:-1]) / 2.
    y = hist[0]
    ntot = sum(y)
    #
    # Starting values for two Gaussian fit. The relative
    # normalizations are initially set at the expected line ratio
    # of K-alpha/K-beta = 0.88/0.12.  The relative peak locations
    # and relative widths are fixed in fe55_lines(...) above.
    #
    p0 = (ntot * 0.88, median, stdev / 2., ntot * 0.12)
    pars, _ = scipy.optimize.curve_fit(fe55_lines, x, y, p0=p0)

    kalpha_peak, kalpha_sigma = pars[1], pars[2]
    fe55_yield = Fe55Yield(ccdtemp)
    gain = fe55_yield.alpha()[0] / kalpha_peak

    if make_plot:
        pylab.xlabel('Bias Corrected Event Signal (DN)')
        pylab.ylabel('Entries / bin')
        xx = np.linspace(x[0], x[-1], 1000)
        pylab.plot(xx, fe55_lines(xx, *pars), 'r--', markersize=3, linewidth=1)
        pylab.annotate(("K-alpha peak = %i DN\n\n" + "Gain = %.2f e-/DN\n\n") %
                       (kalpha_peak, gain), (0.5, 0.7),
                       xycoords='axes fraction')
        win.set_title(title)
        if plot_filename is not None:
            pylab.savefig(plot_filename)
    # Restore pylab interactive state.
    pylab.interactive(pylab_interactive_state)
    return gain, kalpha_peak, kalpha_sigma