def show_wfs(dg): """ show waveforms in different enery regions. use the hit file to select events """ # get file list and load hit data lh5_dir = os.path.expandvars(dg.config['lh5_dir']) hit_list = lh5_dir + dg.file_keys['hit_path'] + '/' + dg.file_keys[ 'hit_file'] df_hit = lh5.load_dfs(hit_list, ['trapEmax'], 'ORSIS3302DecoderForEnergy/hit') print(df_hit) print(df_hit.columns) # settings etype = 'trapEmax_cal' nwfs = 20 # elo, ehi, epb = 0, 100, 0.2 # low-e region elo, ehi, epb = 0, 20, 0.2 # noise region # elo, ehi, epb = 1458, 1468, 1 # good physics events # elo, ehi, epb = 6175, 6250, 1 # overflow peak # elo, ehi, epb = 5000, 5200, 0.2 # lower overflow peak # # diagnostic plot # hE, xE, vE = pgh.get_hist(df_hit[etype], range=(elo, ehi), dx=epb) # plt.plot(xE[1:], hE, c='b', ds='steps') # plt.show() # exit() # select waveforms idx = df_hit[etype].loc[(df_hit[etype] >= elo) & (df_hit[etype] <= ehi)].index[:nwfs] raw_store = lh5.Store() tb_name = 'ORSIS3302DecoderForEnergy/raw' raw_list = lh5_dir + dg.file_keys['raw_path'] + '/' + dg.file_keys[ 'raw_file'] f_raw = raw_list.values[0] # fixme, only works for one file rn data_raw = raw_store.read_object(tb_name, f_raw, start_row=0, n_rows=idx[-1] + 1) wfs_all = data_raw['waveform']['values'].nda wfs = wfs_all[idx.values, :] ts = np.arange(0, wfs.shape[1], 1) # plot wfs for iwf in range(wfs.shape[0]): plt.plot(ts, wfs[iwf, :], lw=1) plt.xlabel('time (clock ticks)', ha='right', x=1) plt.ylabel('ADC', ha='right', y=1) plt.show()
def peak_drift(dg): """ show any drift of the 1460 peak (5 minute bins) """ lh5_dir = os.path.expandvars(dg.config['lh5_dir']) hit_list = lh5_dir + dg.file_keys['hit_path'] + '/' + dg.file_keys[ 'hit_file'] df_hit = lh5.load_dfs(hit_list, ['trapEmax'], 'ORSIS3302DecoderForEnergy/hit') df_hit.reset_index(inplace=True) rt_min = dg.file_keys['runtime'].sum() print(f'runtime: {rt_min:.2f} min') # settings elo, ehi, epb, etype = 1450, 1470, 1, 'trapEmax_cal' df_hit = df_hit.query( f'trapEmax_cal > {elo} and trapEmax_cal < {ehi}').copy() # # diagnostic plot # hE, xE, vE = pgh.get_hist(df_hit[etype], range=(elo, ehi), dx=epb) # plt.plot(xE[1:], hE, c='b', ds='steps') # plt.show() t0 = df_hit['ts_glo'].values[0] df_hit['ts_adj'] = (df_hit['ts_glo'] - t0) / 60 # minutes after 0 tlo, thi, tpb = 0, df_hit['ts_adj'].max(), 1 nbx = int((thi - tlo) / tpb) nby = int((ehi - elo) / epb) h = plt.hist2d(df_hit['ts_adj'], df_hit['trapEmax_cal'], bins=[nbx, nby], range=[[tlo, thi], [elo, ehi]], cmap='jet') plt.xlabel(f'Time ({tpb:.1f} min/bin)', ha='right', x=1) plt.ylabel('trapEmax_cal', ha='right', y=1) plt.tight_layout() # plt.show() plt.savefig('./plots/oppi_1460_drift.png', dpi=300)
def timepoints(runs): for run in runs: # get run files dg = DataGroup('cage.json', load=True) str_query = f'run=={run} and skip==False' dg.fileDB.query(str_query, inplace=True) #get runtime, startime, runtype runtype_list = np.array(dg.fileDB['runtype']) runtype = runtype_list[0] rt_min = dg.fileDB['runtime'].sum() u_start = dg.fileDB.iloc[0]['startTime'] t_start = pd.to_datetime(u_start, unit='s') # get scan position if runtype == 'alp': alphaDB = pd.read_hdf('alphaDB.h5') scan_pos = alphaDB.loc[alphaDB['run']==run] radius = np.array(scan_pos['radius'])[0] angle = np.array(scan_pos['angle'])[0] angle_det = 270 + angle print(f'Radius: {radius}; Angle: {angle}') else: radius = 'n/a' angle = 'n/a' angle_det = 'n/a' # get hit df lh5_dir = dg.lh5_user_dir #if user else dg.lh5_dir hit_list = lh5_dir + dg.fileDB['hit_path'] + '/' + dg.fileDB['hit_file'] df_hit = lh5.load_dfs(hit_list, ['trapEmax', 'trapEmax_cal', 'bl','bl_sig','A_10','AoE', 'ts_sec', 'dcr_raw', 'dcr_ftp', 'dcr_max', 'tp_0', 'tp_10', 'tp_50', 'tp_90', 'tp_max'], 'ORSIS3302DecoderForEnergy/hit') # use baseline cut df_cut = df_hit.query('bl > 8500 and bl < 10000').copy() #creat new DCR const = 0.0555 df_cut['dcr_linoff'] = df_cut['dcr_raw'] + const*df_cut['trapEmax'] #create 0-50 df_cut['tp0_50'] = df_cut['tp_50']- df_cut['tp_0'] #create 10-90 df_cut['10-90'] = df_cut['tp_90']- df_cut['tp_10'] #create 50-100 df_cut['50-100'] = df_cut['tp_max']- df_cut['tp_50'] #------------------------------------- # Plots before alpha cuts #-------------------- # DCR vs tp_50___________ fig, ax = plt.subplots() fig.suptitle(f'DCR vs 50% rise time', horizontalalignment='center', fontsize=16) dlo, dhi, dpb = -100, 200, 0.6 tlo, thi, tpb = 0, 700, 10 nbx = int((dhi-dlo)/dpb) nby = int((thi-tlo)/tpb) alpha_dcr_hist = plt.hist2d(df_cut['dcr_linoff'], df_cut['tp0_50'], bins=[nbx,nby], range=[[dlo, dhi], [tlo, thi]], cmap='viridis', norm=LogNorm()) cb = plt.colorbar() cb.set_label("counts", ha = 'right', va='center', rotation=270, fontsize=14) cb.ax.tick_params(labelsize=12) ax.set_xlabel('DCR (arb)', fontsize=16) ax.set_ylabel('tp 0-50 (ns)', fontsize=16) plt.setp(ax.get_xticklabels(), fontsize=14) plt.setp(ax.get_yticklabels(), fontsize=14) # plt.legend() ax.text(0.95, 0.83, f'r = {radius} mm \ntheta = {angle_det} deg', verticalalignment='bottom', horizontalalignment='right', transform=ax.transAxes, color='green', fontsize=14, bbox={'facecolor': 'white', 'alpha': 0.95, 'pad': 10}) plt.title(f'\n{runtype} run {run}, {rt_min:.2f} mins', fontsize=12) plt.tight_layout() plt.savefig(f'./plots/normScan/cal_normScan/{runtype}_dcr_vs_tp0_50_run{run}.png', dpi=200) # plt.show() plt.clf() plt.close() # DCR vs 10-90___________ fig, ax = plt.subplots() fig.suptitle(f'DCR vs 10-90% rise time', horizontalalignment='center', fontsize=16) dlo, dhi, dpb = -100, 200, 0.6 tlo, thi, tpb = 0, 600, 10 nbx = int((dhi-dlo)/dpb) nby = int((thi-tlo)/tpb) alpha_dcr_hist = plt.hist2d(df_cut['dcr_linoff'], df_cut['10-90'], bins=[nbx,nby], range=[[dlo, dhi], [tlo, thi]], cmap='viridis', norm=LogNorm()) cb = plt.colorbar() cb.set_label("counts", ha = 'right', va='center', rotation=270, fontsize=14) cb.ax.tick_params(labelsize=12) ax.set_xlabel('DCR (arb)', fontsize=16) ax.set_ylabel('tp 10-90 (ns)', fontsize=16) plt.setp(ax.get_xticklabels(), fontsize=14) plt.setp(ax.get_yticklabels(), fontsize=14) # plt.legend() ax.text(0.95, 0.83, f'r = {radius} mm \ntheta = {angle_det} deg', verticalalignment='bottom', horizontalalignment='right', transform=ax.transAxes, color='green', fontsize=14, bbox={'facecolor': 'white', 'alpha': 0.95, 'pad': 10}) plt.title(f'\n{runtype} run {run}, {rt_min:.2f} mins', fontsize=12) plt.tight_layout() plt.savefig(f'./plots/normScan/cal_normScan/{runtype}_dcr_vs_tp10_90_run{run}.png', dpi=200) # plt.show() plt.clf() plt.close() # DCR vs 50-100___________ fig, ax = plt.subplots() fig.suptitle(f'DCR vs 50-100% rise time', horizontalalignment='center', fontsize=16) dlo, dhi, dpb = -100, 200, 0.6 tlo, thi, tpb = 0, 1000, 10 nbx = int((dhi-dlo)/dpb) nby = int((thi-tlo)/tpb) alpha_dcr_hist = plt.hist2d(df_cut['dcr_linoff'], df_cut['50-100'], bins=[nbx,nby], range=[[dlo, dhi], [tlo, thi]], cmap='viridis', norm=LogNorm()) cb = plt.colorbar() cb.set_label("counts", ha = 'right', va='center', rotation=270, fontsize=14) cb.ax.tick_params(labelsize=12) ax.set_xlabel('DCR (arb)', fontsize=16) ax.set_ylabel('tp 10-90 (ns)', fontsize=16) plt.setp(ax.get_xticklabels(), fontsize=14) plt.setp(ax.get_yticklabels(), fontsize=14) # plt.legend() ax.text(0.95, 0.83, f'r = {radius} mm \ntheta = {angle_det} deg', verticalalignment='bottom', horizontalalignment='right', transform=ax.transAxes, color='green', fontsize=14, bbox={'facecolor': 'white', 'alpha': 0.95, 'pad': 10}) plt.title(f'\n{runtype} run {run}, {rt_min:.2f} mins', fontsize=12) plt.tight_layout() plt.savefig(f'./plots/normScan/cal_normScan/{runtype}_dcr_vs_tp50_100_run{run}.png', dpi=200) # plt.show() plt.clf() plt.close()
def pole_zero(dg): """ """ # load hit data lh5_dir = os.path.expandvars(dg.config['lh5_dir']) hit_list = lh5_dir + dg.file_keys['hit_path'] + '/' + dg.file_keys[ 'hit_file'] df_hit = lh5.load_dfs(hit_list, ['trapEmax'], 'ORSIS3302DecoderForEnergy/hit') df_hit.reset_index(inplace=True) rt_min = dg.file_keys['runtime'].sum() # print(f'runtime: {rt_min:.2f} min') # load waveforms etype = 'trapEmax_cal' nwfs = 20 elo, ehi = 1455, 1465 # select waveforms idx = df_hit[etype].loc[(df_hit[etype] >= elo) & (df_hit[etype] <= ehi)].index[:nwfs] raw_store = lh5.Store() tb_name = 'ORSIS3302DecoderForEnergy/raw' raw_list = lh5_dir + dg.file_keys['raw_path'] + '/' + dg.file_keys[ 'raw_file'] f_raw = raw_list.values[0] # fixme, only works for one file rn data_raw = raw_store.read_object(tb_name, f_raw, start_row=0, n_rows=idx[-1] + 1) wfs_all = data_raw['waveform']['values'].nda wfs = wfs_all[idx.values, :] df_wfs = pd.DataFrame(wfs) # print(df_wfs) # simple test function to compute pole-zero constant for a few wfs. # the final one should become a dsp processor clock = 1e8 # 100 MHz istart = 5000 iwinlo, iwinhi, iwid = 500, 2500, 20 # two-point slope # ts = np.arange(istart, df_wfs.shape[1]-1, 1) / 1e3 # usec ts = np.arange(0, df_wfs.shape[1] - 1 - istart, 1) / 1e3 # usec def get_rc(row): # two-point method wf = row[istart:-1].values wflog = np.log(wf) win1 = np.mean(np.log(row[istart + iwinlo:istart + iwinlo + iwid])) win2 = np.mean(np.log(row[istart + iwinhi:istart + iwinhi + iwid])) slope = (win2 - win1) / (ts[iwinhi] - ts[iwinlo]) tau = 1 / slope # # diagnostic plot: check against expo method # guess_tau = 60 # a = wf.max() # expdec = lambda x : a * np.exp(-x / guess_tau) # logdec = lambda x : np.log(a * np.exp(-x / guess_tau)) # slopeway = lambda x: wflog[0] + x / tau # plt.plot(ts, wflog, '-r', lw=1) # plt.plot(ts, logdec(ts), '-b', lw=1) # plt.plot(ts, slopeway(ts), '-k', lw=1) # plt.show() # exit() return tau # return tau res = df_wfs.apply(get_rc, axis=1) tau_avg, tau_std = res.mean(), res.std() print(f'average RC decay constant: {tau_avg:.2f} pm {tau_std:.2f}')
def data_cleaning(dg): """ using parameters in the hit file, plot 1d and 2d spectra to find cut values. columns in file: ['trapE', 'bl', 'bl_sig', 'A_10', 'AoE', 'packet_id', 'ievt', 'energy', 'energy_first', 'timestamp', 'crate', 'card', 'channel', 'energy_cal', 'trapE_cal'] note, 'energy_first' from first value of energy gate. """ i_plot = 0 # run all plots after this number # get file list and load hit data lh5_dir = os.path.expandvars(dg.config['lh5_dir']) hit_list = lh5_dir + dg.file_keys['hit_path'] + '/' + dg.file_keys[ 'hit_file'] df_hit = lh5.load_dfs(hit_list, ['trapEmax'], 'ORSIS3302DecoderForEnergy/hit') # print(df_hit) print(df_hit.columns) # get info about df -- 'describe' is very convenient dsc = df_hit[['bl', 'bl_sig', 'A_10', 'ts_sec']].describe() # print(dsc) # exit() if i_plot <= 0: # bl vs energy elo, ehi, epb = 0, 50, 1 blo, bhi, bpb = 0, 10000, 100 nbx = int((ehi - elo) / epb) nby = int((bhi - blo) / bpb) h = plt.hist2d(df_hit['trapEmax_cal'], df_hit['bl'], bins=[nbx, nby], range=[[elo, ehi], [blo, bhi]], cmap='jet') cb = plt.colorbar(h[3], ax=plt.gca()) plt.xlabel('trapEmax_cal', ha='right', x=1) plt.ylabel('bl', ha='right', y=1) plt.tight_layout() # plt.show() plt.savefig('./plots/oppi_bl_vs_e.png', dpi=300) cb.remove() plt.cla() # make a formal baseline cut from 1d histogram hE, bins, vE = pgh.get_hist(df_hit['bl'], range=(blo, bhi), dx=bpb) xE = bins[1:] plt.semilogy(xE, hE, c='b', ds='steps') bl_cut_lo, bl_cut_hi = 8000, 9500 plt.axvline(bl_cut_lo, c='r', lw=1) plt.axvline(bl_cut_hi, c='r', lw=1) plt.xlabel('bl', ha='right', x=1) plt.ylabel('counts', ha='right', y=1) # plt.show() plt.savefig('./plots/oppi_bl_cut.png') plt.cla() if i_plot <= 1: # A_10/trapEmax_cal vs trapEmax_cal (A/E vs E) # use baseline cut df_cut = df_hit.query('bl > 8000 and bl < 9500').copy() # add new A/E column df_cut['aoe'] = df_cut['A_10'] / df_cut['trapEmax_cal'] # alo, ahi, apb = -1300, 350, 1 # elo, ehi, epb = 0, 250, 1 alo, ahi, apb = 0, 0.4, 0.005 # elo, ehi, epb = 0, 3000, 10 elo, ehi, epb = 0, 6000, 10 nbx = int((ehi - elo) / epb) nby = int((ahi - alo) / apb) h = plt.hist2d(df_cut['trapEmax_cal'], df_cut['aoe'], bins=[nbx, nby], range=[[elo, ehi], [alo, ahi]], cmap='jet', norm=LogNorm()) plt.xlabel('trapEmax_cal', ha='right', x=1) plt.ylabel('A/E', ha='right', y=1) plt.tight_layout() # plt.show() plt.savefig('./plots/oppi_aoe_vs_e.png', dpi=300) plt.cla() if i_plot <= 2: # show effect of baseline cut on low-energy spectrum df_cut = df_hit.query('bl > 8000 and bl < 9500') etype = 'trapEmax_cal' elo, ehi, epb = 0, 250, 0.5 # no cuts h1, x1, v1 = pgh.get_hist(df_hit[etype], range=(elo, ehi), dx=epb) x1 = x1[1:] plt.plot(x1, h1, c='k', lw=1, ds='steps', label='raw') # baseline cut h2, x2, v2 = pgh.get_hist(df_cut[etype], range=(elo, ehi), dx=epb) plt.plot(x1, h2, c='b', lw=1, ds='steps', label='bl cut') plt.xlabel(etype, ha='right', x=1) plt.ylabel('counts', ha='right', y=1) plt.legend() # plt.show() plt.savefig('./plots/oppi_lowe_cut.png') plt.cla() if i_plot <= 3: # show DCR vs E etype = 'trapEmax_cal' elo, ehi, epb = 0, 6000, 10 dlo, dhi, dpb = -1000, 1000, 10 nbx = int((ehi - elo) / epb) nby = int((dhi - dlo) / dpb) h = plt.hist2d(df_cut['trapEmax_cal'], df_cut['dcr'], bins=[nbx, nby], range=[[elo, ehi], [dlo, dhi]], cmap='jet', norm=LogNorm()) plt.xlabel('trapEmax_cal', ha='right', x=1) plt.ylabel('DCR', ha='right', y=1) plt.tight_layout() # plt.show() plt.savefig('./plots/oppi_dcr_vs_e.png', dpi=300) plt.cla()