def plot_fwhm(f_grid,f_opt,d_out,efilter, verbose=False): """ select the best energy resolution, plot best result fit and fwhm vs parameters """ print("Grid file:",f_grid) df_grid = pd.read_hdf(f_grid) f_res = f"{d_out}/{efilter}_results.h5" if 'trapE' in efilter: df = pd.DataFrame(columns=['ged','rise','flat','rc','fwhm','fwhmerr']) if efilter == 'zacE' or efilter == 'cuspE': df = pd.DataFrame(columns=['ged','sigma','flat','decay','fwhm','fwhmerr']) f = h5py.File(f_opt,'r') for chn, ged in enumerate(f.keys()): d_det = f"{d_out}/{ged}" try: os.mkdir(d_det) except: pass d_det = f"{d_det}/{efilter}" try: os.mkdir(d_det) except: pass data = f[ged]['data'] try: # find fwhm minimum values df_grid = df_grid.loc[(df_grid[f"rchi2_{ged}"]<100)&(df_grid[f"fwhm_{ged}"]>0)] minidx = df_grid[f'fwhm_{ged}'].idxmin() df_min = df_grid.loc[minidx] #plot best result fit energies = data[f"{efilter}_{minidx}"][()] mean = np.mean(energies) bins = 12000 hE, xE, vE = ph.get_hist(energies,bins,(mean/2,mean*2)) mu = xE[np.argmax(hE)] hmax = hE[np.argmax(hE)] idx = np.where(hE > hmax/2) ilo, ihi = idx[0][0], idx[0][-1] sig = (xE[ihi] - xE[ilo]) / 2.355 idx = np.where(((xE-mu) > -8 * sig) & ((xE-mu) < 8 * sig)) ilo, ihi = idx[0][0], idx[0][-1] xE, hE, vE = xE[ilo:ihi+1], hE[ilo:ihi], vE[ilo:ihi] x0 = [hmax, mu, sig, 1, 0] xF, xF_cov = pf.fit_hist(pf.gauss_step, hE, xE, var=vE, guess=x0) xF_err = np.sqrt(np.diag(xF_cov)) fwhm = xF[2] * 2.355 * 2614.5 / mu fwhmerr = xF_err[2] * 2.355 * 2614.5 / mu plt.plot(xE, pf.gauss_step(xE, *xF), c='r', label='peakshape') gaus, step = pf.gauss_step(xE, *xF, components=True) gaus = np.array(gaus) step = np.array(step) plt.plot(xE, gaus, ls="--", lw=2, c='g', label="gaus") plt.plot(xE, step, ls='--', lw=2, c='m', label='step + bg') plt.plot(xE[1:], hE, lw=1, c='b', label=f"data {ged}") plt.xlabel(f"ADC channels", ha='right', x=1) plt.ylabel("Counts", ha='right', y=1) plt.legend(loc=2, fontsize=10,title=f"FWHM = {fwhm:.2f} $\pm$ {fwhmerr:.2f} keV") plt.savefig(f"{d_det}/Fit_{ged}-{efilter}.pdf") plt.cla() except: print("FWHM minimum not find for detector",ged) continue if efilter=='zacE' or efilter=='cuspE': #try: sigma, flat, decay = df_min[:3] results = [ged, f'{sigma:.2f}', f'{flat:.2f}', f'{decay:.2f}', f'{fwhm:.2f}', f'{fwhmerr:.2f}'] # 1. vary the sigma cusp df_sigma = df_grid.loc[(df_grid.flat==flat)&(df_grid.decay==decay)&(df_grid.decay==decay)] x, y, err = df_sigma['sigma'], df_sigma[f'fwhm_{ged}'], df_sigma[f'fwhmerr_{ged}'] plt.errorbar(x,y,err,fmt='o') plt.xlabel("Sigma Cusp ($\mu$s)", ha='right', x=1) plt.ylabel(r"FWHM (keV)", ha='right', y=1) plt.savefig(f"{d_det}/FWHM_vs_Sigma_{ged}-{efilter}.pdf") plt.cla() # 2. vary the flat time df_flat = df_grid.loc[(df_grid.sigma==sigma)&(df_grid.decay==decay)] x, y, err = df_flat['flat'], df_flat[f'fwhm_{ged}'], df_flat[f'fwhmerr_{ged}'] plt.errorbar(x,y,err,fmt='o') plt.xlabel("Flat Top ($\mu$s)", ha='right', x=1) plt.ylabel("FWHM (keV)", ha='right', y=1) plt.savefig(f"{d_det}/FWHM_vs_Flat_{ged}-{efilter}.pdf") plt.cla() # 3. vary the rc constant df_decay = df_grid.loc[(df_grid.sigma==sigma)&(df_grid.flat==flat)] x, y, err = df_decay[f'decay'], df_decay[f'fwhm_{ged}'], df_decay[f'fwhmerr_{ged}'] plt.errorbar(x,y,err,fmt='o') plt.xlabel("Decay constant ($\mu$s)", ha='right', x=1) plt.ylabel(r"FWHM (keV)", ha='right', y=1) plt.savefig(f"{d_det}/FWHM_vs_Decay_{ged}-{efilter}.pdf") plt.cla() #except: #print("") if 'trapE' in efilter: rise, flat, rc = df_min[:3] results = [ged, f'{rise:.2f}', f'{flat:.2f}', f'{rc:.2f}', f'{fwhm:.2f}', f'{fwhmerr:.2f}'] # 1. vary the rise time df_rise = df_grid.loc[(df_grid.flat==flat)&(df_grid.rc==rc)] x, y, err = df_rise['rise'], df_rise[f'fwhm_{ged}'], df_rise[f'fwhmerr_{ged}'] #plt.plot(x,y,".b") plt.errorbar(x,y,err,fmt='o') plt.xlabel("Ramp time ($\mu$s)", ha='right', x=1) plt.ylabel(r"FWHM (kev)", ha='right', y=1) # plt.ylabel(r"FWHM", ha='right', y=1) plt.savefig(f"{d_det}/FWHM_vs_Rise_{ged}-{efilter}.pdf") plt.cla() # 2. vary the flat time df_flat = df_grid.loc[(df_grid.rise==rise)&(df_grid.rc==rc)] x, y, err = df_flat['flat'], df_flat[f'fwhm_{ged}'], df_flat[f'fwhmerr_{ged}'] #plt.plot(x,y,'.b') plt.errorbar(x,y,err,fmt='o') plt.xlabel("Flat time ($\mu$s)", ha='right', x=1) plt.ylabel("FWHM (keV)", ha='right', y=1) plt.savefig(f"{d_det}/FWHM_vs_Flat_{ged}-{efilter}.pdf") plt.cla() # 3. vary the rc constant df_rc = df_grid.loc[(df_grid.rise==rise)&(df_grid.flat==flat)] x, y, err = df_rc['rc'], df_rc[f'fwhm_{ged}'], df_rc[f'fwhmerr_{ged}'] #plt.plot(x,y,'.b') plt.errorbar(x,y,err,fmt='o') plt.xlabel("RC constant ($\mu$s)", ha='right', x=1) plt.ylabel(r"FWHM (keV)", ha='right', y=1) plt.savefig(f"{d_det}/FWHM_vs_RC_{ged}-{efilter}.pdf") plt.cla() df.loc[chn] = results print("Results file:",f_res) df.to_hdf(f_res, key='results',mode='w') print(df) dets = range(len(df['fwhm'])) fwhm = np.array([float(df['fwhm'][i]) for i in dets]) fwhm_err = np.array([float(df['fwhmerr'][i]) for i in dets]) plt.cla() plt.errorbar(dets,fwhm,fwhm_err,fmt='o',c='red',label=f'{efilter} filter') plt.xlabel("detector number", ha='right', x=1) plt.ylabel("FWHM (keV)", ha='right', y=1) plt.legend() plt.savefig(f"{d_out}/FWHM_{efilter}.pdf")
def get_fwhm(f_grid, f_opt, efilter, verbose=False): """ this code fits the 2.6 MeV peak using the gauss+step function and writes new columns to the df_grid "fwhm", "fwhmerr" """ print("Grid file:",f_grid) print("DSP file:",f_opt) df_grid = pd.read_hdf(f_grid) f = h5py.File(f_opt,'r') for ged in f.keys(): print("Detector:",ged) data = f[ged]['data'] # declare some new columns for df_grid cols = [f"fwhm_{ged}", f"fwhmerr_{ged}", f"rchi2_{ged}"] for col in cols: df_grid[col] = np.nan for i, row in df_grid.iterrows(): try: energies = data[f"{efilter}_{i}"][()] mean = np.mean(energies) bins = 12000 hE, xE, vE = ph.get_hist(energies,bins,(mean/2,mean*2)) except: print("Energy not find in",ged,"and entry",i) # set histogram centered and symmetric on the peak try: mu = xE[np.argmax(hE)] imax = np.argmax(hE) hmax = hE[imax] idx = np.where(hE > hmax/2) # fwhm ilo, ihi = idx[0][0], idx[0][-1] sig = (xE[ihi] - xE[ilo]) / 2.355 idx = np.where(((xE-mu) > -8 * sig) & ((xE-mu) < 8 * sig)) idx0 = np.where(((xE-mu) > -4.5 * sig) & ((xE-mu) < 4.5 * sig)) ilo, ihi = idx[0][0], idx[0][-1] ilo0, ihi0 = idx0[0][0], idx0[0][-1] xE, hE, vE = xE[ilo:ihi+1], hE[ilo:ihi], vE[ilo:ihi] except: continue # set initial guesses for the peakshape function hstep = 0 tau = np.mean(hE[:10]) bg0 = 1 x0 = [hmax, mu, sig, bg0, hstep] try: xF, xF_cov = pf.fit_hist(pf.gauss_step, hE, xE, var=vE, guess=x0) xF_err = np.sqrt(np.diag(xF_cov)) # goodness of fit chisq = [] for j, h in enumerate(hE): model = pf.gauss_step(xE[j], *xF) diff = (model - h)**2 / model chisq.append(abs(diff)) # update the master dataframe fwhm = xF[2] * 2.355 * 2614.5 / mu fwhmerr = xF_err[2] * 2.355 * 2614.5 / mu rchi2 = sum(np.array(chisq) / len(hE)) df_grid.at[i, f"fwhm_{ged}"] = fwhm df_grid.at[i, f"fwhmerr_{ged}"] = fwhmerr df_grid.at[i, f"rchi2_{ged}"] = rchi2 print(fwhm,fwhmerr,rchi2) except: print("Fit not computed for detector",ged,"and entry",i) if verbose: plt.cla() plt.plot(xE, pf.gauss_step(xE, *xF), c='r', label='peakshape') gaus, step = pf.gauss_step(xE, *xF, components=True) gaus = np.array(gaus) step = np.array(step) plt.plot(xE, gaus, ls="--", lw=2, c='g', label="gaus") plt.plot(xE, step, ls='--', lw=2, c='m', label='step + bg') plt.plot(xE[1:], hE, lw=1, c='b', label=f"data {ged}") plt.xlabel(f"ADC channels", ha='right', x=1) plt.ylabel("Counts", ha='right', y=1) plt.legend(loc=2, fontsize=10,title=f"FWHM = {fwhm:.2f} $\pm$ {fwhmerr:.2f} keV") plt.show() # write the updated df_grid to the output file. if not verbose: df_grid.to_hdf(f_grid, key="pygama_optimization") if not verbose: print("Update grid file:",f_grid,"with detector",ged) print(df_grid)