diff --git a/scripts/analyze_waveform.py b/scripts/analyze_waveform.py index 8c63f4c53617f2f6d2b79f569db90fb7d72c5c80..1597b4ea18410e49f01ca834aaca5be70d1289cb 100644 --- a/scripts/analyze_waveform.py +++ b/scripts/analyze_waveform.py @@ -26,32 +26,10 @@ def get_channels(json_path): parser = argparse.ArgumentParser('Raw waveform analysis') parser.add_argument('root_file', help='a root file of waveform data') -parser.add_argument('output_dir', help='output directory') -parser.add_argument('--prefix', dest='prefix', help='prefix for the output files', default='') -parser.add_argument('--peak-thres', dest='pthres', help='sigma threshold for finding the peak, default 8', type=float, default=8) -parser.add_argument('--peak-min', dest='pmin', help='lower limit of the peak adc value, default 10', type=int, default=10) -parser.add_argument('--peak-max', dest='pmax', help='upper limit of the peak adc value, default 8000', type=int, default=8000) -parser.add_argument('--time-min', dest='tmin', help='lower limit of the time window, default 0', type=int, default=0) -parser.add_argument('--time-max', dest='tmax', help='upper limit of the time window, default 63', type=int, default=63) +parser.add_argument('output', help='path to the output csv file') args = parser.parse_args() -# figsize = (24, 16) -# nrows, ncols = 3, 4 -# ch = [ -# 'S2_1', 'S2_2', 'S2_3', 'S2_4', -# 'S2_5', 'S2_6', 'S2_7', 'S2_8', -# 'S2_9', 'S2_10', 'S2_11', -# ] - -# figsize = (16, 16) -# nrows, ncols = 3, 3 -# ch = [ -# 'C4', 'C6_4', 'C7_4', -# 'C5_4', 'C9_4', 'C8_4', -# 'C1', 'C2', 'C3', -# ] - figsize = (16, 16) nrows, ncols = 4, 4 ch = [ @@ -61,9 +39,27 @@ ch = [ 'Cer41_5', 'Cer42_5', 'Cer43_5', 'Cer44_5', ] +ch_pos = [ + -15.5, -14.5, -15.5, -15.5, + -10.5, -9.5, -10.5, -14.5, + -14.5, -14.5, -14.5, -14.5, + -14.5, -14.5, -21.5, -9.5 +] +pos_width = 3 + +# trigger channels +# tr = ['S2_1', 'S2_2', 'S2_3', 'S2_4', 'S2_5', 'S2_6', 'S2_7', 'S2_8', 'S2_9', 'S2_10', 'S2_11'] +# tr_time = (17, 23) +tr = ['C1', 'C2', 'C3', 'C4', 'C5_1', 'C5_2', 'C5_3', 'C5_4', 'C6_1', 'C6_2', 'C6_3', 'C6_4', + 'C7_1', 'C7_2', 'C7_3', 'C7_4', 'C8_1', 'C8_2', 'C8_3', 'C8_4', 'C9_1', 'C9_2', 'C9_3', 'C9_4'] +tr_time = (28, 32) + f = ROOT.TFile.Open(args.root_file, 'read') tree = f.EvTree +trg_ch = np.ndarray(shape=(tree.GetEntries(), ), dtype=object) +trg_val = np.ndarray(shape=(tree.GetEntries(), 2), dtype='float64') +ch_val = np.ndarray(shape=(tree.GetEntries(), len(ch)*2), dtype='float64') props = {c: [np.array([]), np.array([])] for c in ch} for iev in np.arange(0, tree.GetEntries()): @@ -71,44 +67,58 @@ for iev in np.arange(0, tree.GetEntries()): if iev % 1000 == 0: print('processed {}'.format(iev), end='\r') + # triggers + ev_trg_peaks, ev_trg_poses = [], [] + for c in tr: + peaks = branch_to_array1d(tree.__getattr__(c + '_Ppeak'), np.float32) + poses = branch_to_array1d(tree.__getattr__(c + '_Ptime'), np.float32) + tpeak, tpos = 0, 0 + for peak, pos in zip(peaks, poses): + if pos <= tr_time[1] and pos >= tr_time[0] and peak > tpeak: + tpeak = peak + tpos = pos + ev_trg_peaks.append(tpeak) + ev_trg_poses.append(tpos) + + # no triggers + if not len(ev_trg_peaks): + continue + + # get the maximum peak from all trigger channels + ich = np.argmax(ev_trg_peaks) + trg_ch[iev] = tr[ich] + trg_val[iev] = (ev_trg_peaks[ich], ev_trg_poses[ich]) + # channels - evpeaks, evposes = [], [] - for c, prop in props.items(): - prop[0] = np.concatenate((prop[0], branch_to_array1d(tree.__getattr__(c + '_Ppeak'), np.float32))) - prop[1] = np.concatenate((prop[1], branch_to_array1d(tree.__getattr__(c + '_Ptime'), np.float32))) + for i, c in enumerate(ch): + peaks = branch_to_array1d(tree.__getattr__(c + '_Ppeak'), np.float32) + poses = branch_to_array1d(tree.__getattr__(c + '_Ptime'), np.float32) + props[c][0] = np.concatenate((props[c][0], peaks)) + props[c][1] = np.concatenate((props[c][1], poses - ev_trg_poses[ich])) + + # check timing + cpeak, cpos = 0, 0 + for peak, pos in zip(peaks, poses): + pos -= ev_trg_poses[ich] + if pos <= ch_pos[i] + pos_width and pos >= ch_pos[i] - pos_width and peak > cpeak: + cpeak = peak + cpos = pos + ch_val[iev][[i, len(ch) + i]] = (cpeak, cpos) + print('processed {}'.format(iev)) +result = pd.DataFrame(index=np.arange(0, tree.GetEntries()), + columns=['trg_peak', 'trg_pos'] + [c + '_peak' for c in ch] + [c + '_pos' for c in ch], + data=np.concatenate((trg_val, ch_val), axis=1)) +result.loc[:, 'trg_ch'] = trg_ch +result.to_csv(args.output) + bins = np.arange(0, 5000, step=1) indices = (bins[1:] + bins[:-1])/2. -peaks = pd.DataFrame(index=indices, data={c: np.histogram(prop[0], bins)[0] for c, prop in props.items()}) +pd.DataFrame(index=indices, data={c: np.histogram(prop[0], bins)[0] for c, prop in props.items()}).to_csv('peaks.csv') -bins = np.arange(0, 64, step=1) +bins = np.arange(-64, 64, step=1) indices = (bins[1:] + bins[:-1])/2. -poses = pd.DataFrame(index=indices, data={c: np.histogram(prop[1], bins)[0] for c, prop in props.items()}) - - -# plot -def plot_hist(df, ny, nx, x_label, y_label, fs=(16, 16), fontsize=18): - box = dict(boxstyle='round', facecolor='wheat', alpha=0.3) - fig, axs = plt.subplots(ny, nx, figsize=fs) - for i, ax in enumerate(axs.flat): - if i >= len(df.columns): - continue - ax.text(0.75, 0.90, df.columns[i], transform=ax.transAxes, fontsize=fontsize - 4, verticalalignment='top', bbox=box) - ax.bar(df.index.values, df.iloc[:, i].values, width=pd.Series(data=df.index).diff(1).mean()) - # ax.patch.set_facecolor('wheat') - # ax.patch.set_alpha(0.05) - # ax.set_yscale('log') - fig.tight_layout(rect=(0.03, 0.05, 0.98, 0.95)) - fig.text(0.5, 0.02, x_label, ha='center', fontsize=fontsize) - fig.text(0.02, 0.5, y_label, ha='center', rotation=90, fontsize=fontsize) - return fig - - -plot_hist(peaks, nrows, ncols, 'ADC Value', 'Counts', figsize).savefig(os.path.join(args.output_dir, args.prefix + 'peaks.png')) -plot_hist(poses, nrows, ncols, 'Sample Number', 'Counts', figsize).savefig(os.path.join(args.output_dir, args.prefix + 'timings.png')) - -peaks.to_csv(os.path.join(args.output_dir, args.prefix + 'peaks.csv')) -poses.to_csv(os.path.join(args.output_dir, args.prefix + 'timings.csv')) +pd.DataFrame(index=indices, data={c: np.histogram(prop[1], bins)[0] for c, prop in props.items()}).to_csv('timings.csv') diff --git a/src/esb_analyze.cpp b/src/esb_analyze.cpp index ed1334ff42cd7845218c75646431d220b9c373a8..f69262601e5381b2d15d32f419d528f800ac1f2a 100644 --- a/src/esb_analyze.cpp +++ b/src/esb_analyze.cpp @@ -315,7 +315,7 @@ void waveform_analysis(const std::vector<uint32_t> &raw, BranchData &res) // find peaks TSpectrum s; s.SetResolution(0.5); - int npeaks = s.SearchHighRes(wfbuf, bkbuf, res.nraw, 3.0, 10, false, 5, true, 3); + int npeaks = s.SearchHighRes(wfbuf, bkbuf, res.nraw, 3.0, 20, false, 5, true, 3); // fill branch data double *pos = s.GetPositionX();