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
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
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()
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
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
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