help='Print data used for fitting, do not fit nor plot') args = parser.parse_args() binx = args.binx[0] biny = args.biny[0] if (not (binx != 0 and ((binx & (binx - 1)) == 0)) or not (biny != 0 and ((biny & (biny - 1)) == 0))): print('Binning factor must be a power of 2') exit() shift = args.shift[0] energy_low_cut = args.cut[0] energy_high_cut = args.cut[1] try: his = hisfile.HisFile(args.infile) except GeneralError as err: print(err.msg) exit() dim, x_axis, y_axis, data = his.load_histogram(args.his[0]) if dim != 2: print('Data must be a 2D histogram!') exit() # Rebinng histogram using reshape trick x_axis = x_axis.reshape((x_axis.shape[0] // binx, binx)).mean(1) y_axis = y_axis.reshape((y_axis.shape[0] // biny, biny)).mean(1) data_rebinned = data.reshape( (data.shape[0] // binx, binx, data.shape[1] // biny, -1)).sum(3).sum(1)
def load(self, file_name): """Load his file (also tar gzipped files)""" self.hisfile = hisfile.HisFile(file_name)
def process(self, pause, show, verbose, rounding): """For each file in file_list, for each spectrum in a given files performes fit and adds result to entry in the dict """ for file_name, spectra in self.file_list.items(): his = hisfile.HisFile(file_name, rounding) for hisId, lines in spectra.items(): data = his.load_histogram(hisId) for line in lines: xmin = line['min'] xmax = line['max'] if data[0] != 1: raise GeneralError('Only 1D histograms are suitable' + 'for this calibration') data_x, data_y = data[1][xmin:xmax], data[3][xmin:xmax] data_dy = numpy.sqrt(numpy.abs(data[3][xmin:xmax])) # 0 counts have error 1 (poisson!) for i, dy in enumerate(data_dy): if dy == 0: data_dy[i] = 1 try: fitter = peak_fitter.PeakFitter(line['model']) result = fitter.fit(data_x, data_y, data_dy) except ValueError: msg = ('Fit problems with spectrum {} line {}: {}') raise GeneralError( msg.format(hisId, line['line'], 'numerical issue encountered')) except peak_fitter.GeneralError as err: msg = ('Fit problems with spectrum {} line {}: {}') raise GeneralError( msg.format(hisId, line['line'], err.msg)) if line['model'].startswith("gauss_doublet"): line['dx'] = result.params['mu'].stderr line['x0'] = result.params['mu'].value line['x1'] = result.params['mu1'].value line['Area'] = result.params['A'].value line['Area1'] = result.params['A1'].value line['dA'] = result.params['A'].stderr line['dA1'] = result.params['A1'].stderr else: x0 = result.params['mu'].value dx = result.params['mu'].stderr line['x0'] = x0 line['dx'] = dx line['Area'], line['dA'] = self._find_area( fitter, x0, dx, xmin, data_x, data_y) line['redchi'] = result.redchi if result.params['mu'].stderr == 0: msg = ('Warning, line {} in spectrum {}:' + ' could not determine uncertainity\n') sys.stderr.write(msg.format(line['line'], hisId)) if show == 'plot' or show == 'png': x = numpy.linspace(data_x[0], data_x[-1], 1000) y0 = fitter.fit_func(result.params, x) plt.clf() plt.xlabel('Channel') plt.ylabel('Counts') plt.title('Spectrum {} line {}'.format( hisId, line['line'])) plt.plot(x, y0) plt.errorbar(data_x, data_y, data_dy, fmt='o') xpos = (plt.xlim()[0] + (plt.xlim()[1] - plt.xlim()[0]) * 0.1) ypos = (plt.ylim()[1] - (plt.ylim()[1] - plt.ylim()[0]) * 0.1) text = ('$\mu$ = {0:.2f}\n' + '$\chi^2/\mathcal{{N}}$' + ' = {1:.2f}').format(result.params['mu'].value, result.redchi) plt.text(xpos, ypos, r'{}'.format(text)) if show == 'png': png_name = '{}_{}_{:.0f}.png'.format( file_name, hisId, float(line['line'])) plt.savefig(png_name) print('File', png_name, 'saved') elif show == 'plot': plt.draw() time.sleep(pause) elif show == 'text': msg = ('Line {} in spectrum {},' + ' x0 = {:.2f},' + ' redchi = {:.2f}\n').format( line['line'], hisId, result.params['mu'].value, result.redchi) sys.stderr.write(msg) elif show == 'quiet': pass else: raise GeneralException( 'Unknown show method {}'.format(show)) if verbose: sys.stderr.write('{}\n'.format(20 * '-')) sys.stderr.write('Line {} spectrum {}\n'.format( line['line'], hisId)) sys.stderr.write('Reduced Chi2: {:.3f}\n'.format( result.redchi)) for key, par in result.params.items(): sys.stderr.write('{} {:.3f} +/- {:.3f}\n'.format( key, par.value, par.stderr)) fwhm_factor = 2 * math.sqrt(math.log(2) * 2) sys.stderr.write('{} {:.3f} +/- {:.3f}\n'.format( 'FWHM', fwhm_factor * result.params['s'].value, fwhm_factor * result.params['s'].stderr))