30 cout <<
"\ninitializing ..." << endl;
32 if (last_bin_file > 0) {
33 cout <<
"will read " << last_bin_file - first_bin_file <<
" .bin files from file number "
34 << first_bin_file <<
" to file number " << last_bin_file << endl;
38 ROOT::EnableImplicitMT();
39 TH1::AddDirectory(kFALSE);
71void ReadRun::ReadFile(
string path,
bool change_polarity,
int change_sign_from_to_ch_num,
string out_file_name,
bool debug,
long long max_nevents_to_read) {
72 if (max_nevents_to_read <= 0) max_nevents_to_read =
static_cast<long long>(1e9);
74 if (path.back() !=
'/') path +=
'/';
78 if (out_file_name.empty()) out_file_name =
"out.root";
79 printf(
"+++ saving analysis results in '%s' ...\n\n", out_file_name.c_str());
80 root_out = TFile::Open(out_file_name.c_str(),
"recreate");
83 auto polarity_map =
PolarityMap(change_polarity, change_sign_from_to_ch_num);
86 bool debug_header = debug;
87 bool debug_data = debug;
89 unsigned short output_channel;
90 unsigned int output_event;
91 unsigned short output_nbchannels;
92 unsigned short read_channels = 0;
95 stringstream inFileList;
97 if (debug) cout << inFileList.str() << endl;
101 int event_counter = 0;
104 while (inFileList >> fileName) {
109 fileName = path + fileName;
110 ifstream input_file(fileName.c_str(), ios::binary | ios::in);
112 bool has_measurement =
false;
114 if (!input_file.is_open()) {
115 printf(
"*** failed to open '%s'\n", fileName.c_str());
119 if (file_counter < 10 || file_counter % 10 == 0 || debug) printf(
"+++ reading '%s' ...\n", fileName.c_str());
127 getline(input_file, header_line,
'\n');
129 if (debug_header) printf(
"%s\n", header_line.data());
130 assert(header_line[0] ==
'=');
132 size_t header_version_first = header_line.find_last_of(
'V');
133 size_t header_version_last = header_line.find_first_of(
' ', header_version_first);
134 string software_version = header_line.substr(header_version_first, header_version_last - header_version_first);
135 if (debug_header) printf(
" |- data version = '%s'\n", software_version.data());
137 software_version.erase(0, 1);
138 int v_major, v_minor, v_patch;
139 istringstream software_version_iss(software_version);
141 software_version_iss >> v_major >> dot_ >> v_minor >> dot_ >> v_patch;
145 getline(input_file, header_line,
'\n');
147 if (debug_header) printf(
"%s\n", header_line.data());
148 assert(header_line[0] ==
'=');
152 getline(input_file, header_line,
'\n');
154 if (debug_header) printf(
"%s\n", header_line.data());
155 assert(header_line[0] ==
'=');
160 getline(input_file, header_line,
'\n');
162 if (debug_header) printf(
"%s\n", header_line.data());
163 assert(header_line[0] ==
'=');
165 size_t nsamples_first = 1 + header_line.find_last_of(
'[');
166 size_t nsamples_last = header_line.find_first_of(
']', nsamples_first);
167 string nsamples_str = header_line.substr(nsamples_first, nsamples_last - nsamples_first);
170 if (debug_header) printf(
" |- data sample = %d\n",
binNumber);
171 if (file_counter == 0 &&
binNumber != 1024) {
172 cout <<
"\nWARNING: Measurement has " <<
binNumber <<
" samples, which is non-standard. Please report any bugs!" << endl;
173 cout <<
"If this was not intentional check the WaveCatcher settings!" << endl;
175 size_t waveform_bytes =
static_cast<size_t>(
binNumber) *
sizeof(
short);
181 size_t nchannels_first = 10 + header_line.find(
"ACQUIRED: ", nsamples_first);
182 size_t nchannels_last = header_line.find_first_of(
' ', nchannels_first);
183 string nchannels_str = header_line.substr(nchannels_first, nchannels_last - nchannels_first);
186 if (debug_header) printf(
" |- nchannels = %d\n",
nchannels);
188 size_t sp_first = 8 + header_line.find(
"Period:");
189 size_t sp_last = header_line.find(
" ps");
190 float sampling_period = atof(header_line.substr(sp_first, sp_last - sp_first).data());
191 if (debug_header) printf(
"sampling period = %f ps\n", sampling_period);
192 SP = sampling_period * 1e-3;
196 if (v_major ==2 && v_minor == 9 && v_patch <= 13) {
198 has_measurement =
true;
201 size_t has_measurement_first = 14 + header_line.find(
"MEASUREMENTS: ", nsamples_first);
202 size_t has_measurement_last = header_line.find_first_of(
' ', has_measurement_first);
203 string has_measurement_str = header_line.substr(has_measurement_first, has_measurement_last - has_measurement_first);
204 has_measurement = atoi(has_measurement_str.data());
207 if (debug_header) printf(
" `- measurement = %d\n", has_measurement);
213 while (input_file.read((
char*)(&an_event),
sizeof(an_event))) {
215 if (debug_data) printf(
"%03d has %d channels\n", an_event.EventNumber, an_event.nchannelstored);
217 output_event = an_event.EventNumber;
218 output_nbchannels = an_event.nchannelstored;
220 if (debug_data && output_event % 200 == 0) printf(
"EventNr: %d, nCh: %d\n", output_event, output_nbchannels);
222 cout <<
"ERROR:\nThe number of channels in the data is " << output_nbchannels
223 <<
", which is larger than the maximum allowed number of channels which is set to " <<
nChannelsWC
224 <<
"\nPlease set the parameter nChannelsWC=" << output_nbchannels << endl;
327 cout <<
"\nAnalysis completed." <<
endl;
347 mgsums->SetTitle(
"channel sums; t [ns]; amplitude [mV]");
348 if (
normalize)
mgsums->SetTitle(
"channel sums; t [ns]; amplitude [arb.]");
364 double tmp_min = TMath::MinElement(
gr->GetN(),
gr->GetY());
366 double tmp_max = TMath::MaxElement(
gr->GetN(),
gr->GetY());
388 sumc->BuildLegend(0.85, 0.70, .99, .95);
409 mgav->SetTitle(
"channel averages; t [ns]; amplitude [mV]");
410 if (
normalize)
mgav->SetTitle(
"channel averages; t[ns]; amplitude[arb.]");
432 double tmp_min = TMath::MinElement(
gr->GetN(),
gr->GetY());
434 double tmp_max = TMath::MaxElement(
gr->GetN(),
gr->GetY());
457 avc->BuildLegend(0.85, 0.70, .99, .95);
480 h2->GetXaxis()->SetTitle(
"t [ns]");
481 h2->GetYaxis()->SetTitle(
"I [arb.]");
482 h2->GetZaxis()->SetTitle(
"entries");
556 gPad->SetTopMargin(.1);
557 gPad->SetBottomMargin(.1);
558 gPad->SetLeftMargin(.15);
559 gPad->SetRightMargin(.15);
566 if (
z_opt ==
"COLZ0")
h2->Draw(
"COLZ0");
567 else h2->Draw(
"CONT4Z");
569 if (
z_opt ==
"log") {
573 else if (
z_max > 0)
h2->GetZaxis()->SetRangeUser(0,
z_max);
590 cout <<
"Smoothing all non-skipped waveforms..." <<
endl;
592 #pragma omp parallel for
593 for (
int j = 0;
j <
nwf;
j++) {
612 cout <<
"\nSmoothing all non-skipped waveforms:" <<
endl;
614 #pragma omp parallel for
615 for (
int j = 0;
j <
nwf;
j++) {
634 cout <<
"\nFiltering all waveforms..." <<
endl;
636 #pragma omp parallel for
637 for (
int j = 0;
j <
nwf;
j++) {
654 cout <<
"\nShifting all waveforms to the average constant fraction time for each channel:" <<
endl;
661 for (
int j = 0;
j <
nwf;
j++) {
673 #pragma omp parallel for
674 for (
int j = 0;
j <
nwf;
j++) {
704 cout <<
"\nPerforming simple baseline correction in fixed time window."
705 <<
"This method is only suitable for measurements without dark counts!" <<
endl;
712 cout <<
"Baseline correction (" <<
nwf <<
" waveforms):" <<
endl;
715 #pragma omp parallel for
716 for (
int j = 0;
j <
nwf;
j++) {
783 cout <<
"\nBaseline correction (minimum slope variation method, " <<
nwf <<
" waveforms):" <<
endl;
784 if (
window.empty())
cout <<
"\nWarning: Window not set in CorrectBaselineMinSlopeRMS. Will use default values." <<
endl;
785 if (
sigma != 0.)
cout <<
"\nNotification: Using smoothing in CorrectBaselineMinSlopeRMS." <<
endl;
799 cout <<
"\nNotification: Using dynamic search window in CorrectBaselineMinSlopeRMS." <<
endl;
806 #pragma omp parallel for
807 for (
int j = 0;
j <
nwf;
j++) {
908 cout <<
"WARNING: This is a deprecated version of CorrectBaselineMinSlopeRMS. "
909 <<
"It will be removed in future releases. Parameter bool smooth=" <<
smooth <<
" will be ignored." <<
endl;
926 cout <<
"WARNING: This is a deprecated version of CorrectBaselineMinSlopeRMS. "
927 <<
"It will be removed in future releases. Parameter increment=" <<
increment <<
" will be ignored." <<
endl;
955 cout <<
"\nBaseline correction (minimal sum method, " <<
nwf <<
" waveforms):" <<
endl;
956 if (
window.empty())
cout <<
"\nWarning: Window not set in CorrectBaselineMin. Will use default values." <<
endl;
957 if (
sigma != 0.)
cout <<
"\nNotification: Using smoothing in CorrectBaselineMin." <<
endl;
971 cout <<
"\nNotification: Using dynamic search window in CorrectBaselineMin." <<
endl;
978 #pragma omp parallel for
979 for (
int j = 0;
j <
nwf;
j++) {
1048 cout <<
"WARNING: This is a deprecated version of CorrectBaselineMin. It will be removed in future releases." <<
endl;
1064 cout <<
"WARNING: This is a deprecated version of CorrectBaselineMin. It will be removed in future releases." <<
endl;
1122 his->GetYaxis()->SetTitle(
"#Entries");
1123 his->GetXaxis()->SetTitle(
"amplitude in mV");
1126 his->Fit(
"gaus",
"M",
"same");
1142 cout <<
"\nError: baseline_correction_result empty. Call baseline correction first." <<
endl;
1178 ctitle =
"Correction values in mV";
1188 his->GetYaxis()->SetTitle(
"#Entries");
1189 his->GetXaxis()->SetTitle(
ctitle.c_str());
1191 his->Fit(
"gaus",
"WWM",
"same");
1220void ReadRun::GetTimingCFD(
float cf_r,
float start_at_t,
float end_at_t,
double sigma,
bool find_CF_from_start,
int smooth_method,
bool use_spline,
bool verbose) {
1227 cout <<
"\nGet timing at " << (
cf_r > 0 &&
cf_r <= 1 ?
"CF=" :
"threshold=");
1235 #pragma omp parallel for
1236 for (
int j = 0;
j <
nwf;
j++) {
1319 cout <<
"\n Removing events if the event-wise time difference between the main peaks in ch"
1331 #pragma omp parallel for reduction(+:counter)
1368 cout <<
"\n Removing events with individual amplitude threshold per channel:" <<
endl;
1375 #pragma omp parallel for reduction(+:counter)
1376 for (
int j = 0;
j <
nwf;
j++) {
1423void ReadRun::IntegralFilter(vector<float> thresholds, vector<bool> g_thr,
float windowlow,
float windowhi,
float start,
float end,
bool use_AND_condition ,
bool verbose) {
1425 if (
thresholds.empty() ||
g_thr.empty())
cout <<
"\nERROR: thresholds or g_thr are empty in ReadRun::IntegralFilter().";
1429 cout <<
"\n\nRemoving events with individual integral threshold per channel:" <<
endl;
1433 #pragma omp parallel for reduction(+:counter)
1434 for (
int j = 0;
j <
nwf;
j++) {
1491 cout <<
"\n\nAll event cuts were removed" <<
endl;
1548 cout <<
"\nError: Start=" <<
istart <<
" or end=" <<
iend <<
" of GetIntWindow() out of range. Fix integration window." <<
endl;
1583array<int, 3>
ReadRun::GetIntWindow(
const vector<float>& waveform,
float windowlow,
float windowhi,
float start,
float end,
int channel) {
1619array<int, 3>
ReadRun::GetIntWindow(
const vector<float>& waveform,
int windowlow,
int windowhi,
int start,
int end,
int channel) {
1683float ReadRun::GetPeakIntegral(
const vector<float>& waveform,
float windowlow,
float windowhi,
float start,
float end,
int channel_index) {
1724 gPad->SetTopMargin(.01);
1736 low->SetLineColor(2);
1738 hi->SetLineColor(2);
1740 zero->SetLineColor(1);
1793float*
ReadRun::ChargeList(
int channel_index,
float windowlow,
float windowhi,
float start,
float end,
bool negative_vals) {
1796 #pragma omp parallel for
1826 else charge_list_mg->SetTitle(
"event-wise amplitudes; Event number; amplitude [mV]");
1870void ReadRun::ChargeCorrelation(
float windowlow,
float windowhi,
float start,
float end,
float rangestart,
float rangeend,
int nbins,
int channel1,
int channel2,
bool ignore_skipped_events) {
1871 gStyle->SetOptStat(1111);
1914TH1F*
ReadRun::ChargeSpectrum(
int channel_index,
float windowlow,
float windowhi,
float start,
float end,
float rangestart,
float rangeend,
int nbins) {
1932 #pragma omp parallel
1986void ReadRun::PrintChargeSpectrum(
float windowlow,
float windowhi,
float start,
float end,
float rangestart,
float rangeend,
int nbins,
float fitrangestart,
float fitrangeend,
int max_channel_nr_to_fit,
int which_fitf,
bool use_log_y) {
1989 cout <<
"Creating charge spectrum ..." <<
endl;
1991 gStyle->SetOptStat(
"ne");
2023 his->GetYaxis()->SetTitle(
"#Entries");
2025 else his->GetXaxis()->SetTitle(
"Amplitude in mV");
2028 cout <<
"Charge spectrum for channel index " <<
i <<
" will be normalized using a gain of "
2030 his->GetXaxis()->SetTitle(
"Number of photoelectrons");
2044 f->SetParName(0,
"Width");
f->SetParameter(0, 35);
2045 f->SetParName(1,
"MPV");
f->SetParameter(1, 1000);
2046 f->SetParName(2,
"Area");
f->SetParameter(2, 10000);
2047 f->SetParName(3,
"#sigma_{Gauss}");
f->SetParameter(3, 100);
2052 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2062 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2063 f->SetParName(1,
"#mu");
f->SetParameter(1, 2.);
2064 f->SetParName(2,
"#lambda");
f->SetParameter(2, .04);
2065 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 2.1);
2066 f->SetParName(4,
"#sigma_{1}");
f->SetParameter(4, 3.4);
2067 f->SetParName(5,
"Gain");
f->SetParameter(5, 30.);
2068 f->SetParName(6,
"Pedestal");
f->SetParameter(6, 2.);
2069 f->SetParName(7,
"norm_{0}");
f->SetParameter(7, 0.7);
2070 f->SetParName(8,
"x_{0}");
f->SetParameter(8, 5.);
2075 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2091 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2092 f->SetParName(1,
"#mu");
f->SetParameter(1, 2.);
2093 f->SetParName(2,
"#lambda");
f->SetParameter(2, .04);
2094 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 2.1);
2095 f->SetParName(4,
"#sigma_{1}");
f->SetParameter(4, 3.4);
2096 f->SetParName(5,
"Gain");
f->SetParameter(5, 30.);
2097 f->SetParName(6,
"Pedestal");
f->SetParameter(6, 2.);
2098 f->SetParName(7,
"#alpha");
f->SetParameter(7, .1);
2099 f->SetParName(8,
"#beta");
f->SetParameter(8, 80.);
2104 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2114 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2115 f->SetParName(1,
"#mu");
f->SetParameter(1, 1.);
2116 f->SetParName(2,
"#sigma");
f->SetParameter(2, 5.);
2117 f->SetParName(3,
"gain");
f->SetParameter(3, 10.);
2122 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2132 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2133 f->SetParName(1,
"w");
f->SetParameter(1, .05);
f->SetParLimits(1, 1.e-99, 4.e-1);
2134 f->SetParName(2,
"#alpha");
f->SetParameter(2, .05);
f->SetParLimits(2, 1.e-99, 5.e-2);
2135 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 5.);
f->SetParLimits(3, 1.e-9, 1.e3);
2136 f->SetParName(4,
"Q_{0}");
f->SetParameter(4, 0.);
2137 f->SetParName(5,
"#mu");
f->SetParameter(5, 1.);
2138 f->SetParName(6,
"#sigma_{1}");
f->SetParameter(6, 5.);
f->SetParLimits(6, 1.e-9, 1.e3);
2139 f->SetParName(7,
"Q_{1}");
f->SetParameter(7, 10.);
2144 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2154 f->SetParName(0,
"A");
f->SetParameter(0,
his->Integral());
2155 f->SetParName(1,
"w");
f->SetParameter(1, .05);
f->SetParLimits(1, 1.e-9, 4.e-1);
2156 f->SetParName(2,
"#alpha");
f->SetParameter(2, .05);
f->SetParLimits(2, 1.e-9, 5.e-2);
2157 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 5.);
f->SetParLimits(3, 1.e-9, 1.e3);
2158 f->SetParName(4,
"Q_{0}");
f->SetParameter(4, 0.);
f->SetParLimits(4, -1.e2, 1.e2);
2159 f->SetParName(5,
"#mu");
f->SetParameter(5, 1.);
f->SetParLimits(5, 1.e-9, 1.e2);
2160 f->SetParName(6,
"#sigma_{1}");
f->SetParameter(6, 5.);
f->SetParLimits(6, 1.e-9, 1.e3);
2161 f->SetParName(7,
"Q_{1}");
f->SetParameter(7, 10.);
f->SetParLimits(7, 1.e-9, 1.e9);
2162 f->SetParName(8,
"A_{0}");
f->SetParameter(8, 1.);
f->SetParLimits(8, 1.e-9, 1.e1);
2167 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2177 f->SetParName(0,
"A");
f->SetParameter(0,
his->Integral());
2178 f->SetParName(1,
"w");
f->SetParameter(1, .05);
f->SetParLimits(1, 1.e-9, 4.e-1);
2179 f->SetParName(2,
"#alpha");
f->SetParameter(2, .05);
f->SetParLimits(2, 1.e-9, 5.e-2);
2180 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 5.);
f->SetParLimits(3, 1.e-9, 1.e3);
2181 f->SetParName(4,
"Q_{0}");
f->SetParameter(4, 0.);
f->SetParLimits(4, -1.e2, 1.e2);
2182 f->SetParName(5,
"#mu");
f->SetParameter(5, 1.);
f->SetParLimits(5, 1.e-9, 1.e2);
2183 f->SetParName(6,
"#sigma_{1}");
f->SetParameter(6, 5.);
f->SetParLimits(6, 1.e-9, 1.e3);
2184 f->SetParName(7,
"#mu_darkcount");
f->SetParameter(7, .1);
f->SetParLimits(7, 1.e-9, 1.);
2185 f->SetParName(8,
"N_{0}_darkcount");
f->SetParameter(8, .05);
f->SetParLimits(8, 1.e-9, .3);
2190 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2200 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2201 f->SetParName(1,
"#mu");
f->SetParameter(1, 2.);
2202 f->SetParName(2,
"#lambda");
f->SetParameter(2, .04);
2203 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 2.1);
2204 f->SetParName(4,
"#sigma_{1}");
f->SetParameter(4, 3.4);
2205 f->SetParName(5,
"Gain");
f->SetParameter(5, 30.);
2206 f->SetParName(6,
"Pedestal");
f->SetParameter(6, 2.);
2211 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2236void ReadRun::PrintDCR(
float windowlow,
float windowhi,
float rangestart,
float rangeend,
double threshold) {
2260TH1F*
ReadRun::TimeDist(
int channel_index,
float from,
float to,
float rangestart,
float rangeend,
int nbins,
int which,
float cf_r) {
2276 else if (
which == 1) {
2301 if (
which == 1)
h1->Fit(
"gaus",
"WWM",
"same");
2324 gStyle->SetOptStat(1111);
2336 his->GetYaxis()->SetTitle(
"#Entries");
2337 his->GetXaxis()->SetTitle(
"time [ns]");
2340 his->SetTitle(
name.str().c_str());
2364 g3d->SetTitle(
"waveforms; t [ns]; max. amplitude [mv]; amplitude [mV]");
2365 g3d->SetMarkerStyle(7);
2398 auto max_dist_c =
new TCanvas(
"wf grouped by maximum",
"wf grouped by maximum", 600, 400);
2449 gStyle->SetOptStat(1111);
2461 his->GetYaxis()->SetTitle(
"#Entries");
2462 his->GetXaxis()->SetTitle(
"time [ns]");
2465 int end =
his->GetNbinsX();
2466 for (
int k = 1;
k <=
end;
k++) {
2467 if (
his->GetBinContent(
k) < 2)
his->SetBinError(
k, 1);
2499 name <<
"GetTimingCFD_diff <";
2510 else cout <<
"\n\n ERROR: channels2 = " <<
entry <<
" does not exist in data. Check parameters for Print_GetTimingCFD_diff()\n\n";
2523 else cout <<
"\n\n ERROR: channels1 = " <<
entry <<
" does not exist in data. Check parameters for Print_GetTimingCFD_diff()\n\n";
2589void ReadRun::Print_GetTimingCFD_diff(vector<int> channels1, vector<int> channels2,
float rangestart,
float rangeend,
int do_fit,
int nbins,
float fitrangestart,
float fitrangeend,
string fitoption,
bool set_errors) {
2605 his->GetYaxis()->SetTitle(
"#Entries");
2606 his->GetXaxis()->SetTitle(
"time [ns]");
2609 int end =
his->GetNbinsX();
2610 for (
int i = 1;
i <=
end;
i++) {
2611 if (
his->GetBinContent(
i) < 2)
his->SetBinError(
i, 1);
2624 if (
do_fit == 2)
cout <<
"\nWARNING: Print_GetTimingCFD_diff\nFITTING GAUSS INSTEAD OF GAUSS x EXP CONVOLUTION BC SYMMETRY" <<
endl;
2636 else expgconv->SetParLimits(0, -5., -.15);
2669 mean->SetLineColor(1);
mean->SetLineWidth(2);
2675 two_gauss->SetTitle(
"Sum of two gauss");
2676 float posmax =
his->GetXaxis()->GetBinCenter(
his->GetMaximumBin());
2773 cout <<
"WARNING: Event number " <<
eventnr <<
" for GetEventIndex() does not exist in data.\n"
2774 <<
"Please check the events in the data or set discard_original_eventnr = true before calling ReadFile()." <<
endl;
2779 cout <<
"Found event number " <<
eventnr <<
" in data and will use it." <<
endl;
2794 cout <<
"\n\n\tERROR: channel " <<
channel_number <<
" does not exist in data. Will continue with first channel\n\n";
2833 if (
y1 ==
y2)
return {(
x1 +
x2) * 0.5,
false};
2836 cout <<
"\nError in LinearInterpolation: Value ym=" <<
ym <<
" out of range (" <<
y1 <<
"|" <<
y2 <<
")." <<
endl;
2837 cout <<
"Will return x1. Increase window for search." <<
endl;
int omp_get_max_threads()
Main class containing the file reader and most analysis functions.
static void ResponseFilter(double *&, int, double=.4, double=1.2, double=.25, double=.3125)
Custom filter emulating primitive response function.
static void SecondOrderUnderdampedFilter(double *&, int, double, double, double, double=.3125, bool=false)
Shifted second order underdamped filter.
static void SmoothArray(double *&, int, double=.625, string="Gaus", double=.3125, double=1.5)
Apply smoothing array of double with length nbins.
Ideal PMT charge spectrum.
Gauss-Poisson distribution for fit of PMT charge spectra.
Gauss-Poisson distribution for fit of PMT charge spectra.
Fit function for SiPMs missing after-pulses and dark counts but with biased pedestal.
Convolution of an exponential and a gaussian.
Default fit function for SiPMs with after-pulses missing dark counts.
Landau-Gauss-convolution.
Fit function for SiPMs missing after-pulses and dark counts but including additional dark count spect...
Default fit function for SiPMs missing after-pulses and dark counts.
static void SplitCanvas(TCanvas *&, vector< int >, vector< int >)
Helper to split canvas according to the number of channels to be plotted.
static double * gety(HistType *his)
Get array of y values for a histogram.
static void SetRangeCanvas(TCanvas *&, double, double, double=-999, double=-999)
Set consistent x-axis and y-axis range for all TH1 histograms on a canvas.
static int rcolor(unsigned int)
Translate a random number into a useful root color https://root.cern.ch/doc/master/classTColor....
static bool Contains(const vector< T > &vec, const T &val)
Returns true if vector vec contains value val.
static string ListFiles(const char *, const char *)
Helper. Creates a list of .bin data files in data folder to be read in.
int FirstBinFileToRead
Number first of .bin file to be read in.
static pair< float, bool > LinearInterpolation(float, float, float, float, float, bool=false)
Simple linear interpolation for x.
TH1F * Getwf(int)
Helper that returns the waveform histogram for a certain waveform number number.
void Print_GetTimingCFD(float=100, float=140, int=0, int=-999, string="S", bool=true)
Plot results of GetTimingCFD()
int PlotChannelAverages_cnt
Index for multiple executions of the same plotting function.
void ChargeCorrelation(float, float, float, float, float, float, int, int, int, bool=false)
Plot correlation of integrals/amplitudes between two channels.
float tCutEndg
End of time window for baseline correction when using ReadRun::Using_BaselineCorrection_in_file_loop.
TH1F * ChargeSpectrum(int, float, float, float=0, float=300, float=-50, float=600, int=750)
Histogram of the "charge" spectrum for one channel.
float DAQ_factor
DAQ conversion factor for wavecatcher output to mV.
void CorrectBaselineMin(vector< float >, double=0, int=2)
Baseline correction using minimum sum ( mean) in range for correction.
int nevents
Number of triggered events in data.
float IndexToTime(int)
Convert the bin number of the waveform to the time of the left bin edge
vector< bool > skip_event
Stores the event numbers which should be skipped in the analysis.
double * gety(int)
Get array of y values for a certain waveform.
vector< int > active_channels
Stores the numbers of the active channels.
vector< vector< float > > rundata
Stores waveforms.
void CorrectBaseline_function(vector< float > &, float, float, int)
Helper function called by CorrectBaseline()
vector< bool > PolarityMap(bool, int)
Channel map of polarity changes during reading. For parameters see ReadFile().
int TimeToIndex(float)
Convert time to the bin number of the waveform.
float GetPeakIntegral(TH1F *, float, float, float, float, int=0)
Calculate the integral around a peak with several options explained in GetIntWindow().
int GetEventIndex(unsigned int)
Returns index of a certain event number (if data files are read in parallel threads)
TH1F * His_GetTimingCFD(int, float, float, int=-999)
Plot results of GetTimingCFD()
void FilterAll(double=.3, double=.9, double=.2)
Filter all waveforms.
void PlotWFHeatmaps(float=-20, float=200, int=880, string="", float=0, EColorPalette=kRainBow)
Plot stacks of all non-skipped waveforms for all active channels.
int GetChannelIndex(int)
Match channel number (wavecatcher input channel) to channel index.
float tCutg
Start of time window for baseline correction when using ReadRun::Using_BaselineCorrection_in_file_loo...
float * ChargeList(int, float=20, float=80, float=0, float=300, bool=1)
Returns array with the individual "charge"/amplitude for all events of one channel.
TFile * root_out
Stores results of analysis.
int nChannelsWC
Wavecatcher hardware max. number of channels (reduce/increase if not using the 64 channel crate)
void PrintBaselineCorrectionResults(float=-5, float=5, int=200)
Print histogram of the baseline correction values for all channels.
virtual void ReadFile(string, bool=false, int=9, string="out.root", bool=false, long long=-1)
Routine to read files created by the wavecatcher.
virtual int GetWaveformIndex(int, int)
Returns index of a certain event number (if data files are read in parallel threads)
vector< float > PrintChargeSpectrum_pars
Starting values of the fit parameters for PrintChargeSpectrum()
bool Using_BaselineCorrection_in_file_loop
Set true for baseline correction during data reading. Needs to be called before ReadFile().
void PrintWFProjection(float=0, float=320, float=-50, float=50, int=200)
Plots waveform projection histograms of all channels.
void PlotChannelAverages(bool=false)
Plot averages only of the good, corrected waveforms for each channel.
bool PlotChannel(int)
Check if a channel index should be plotted according to ReadRun::plot_active_channels.
array< int, 3 > GetIntWindow(TH1F *, float, float, float, float, int=0)
Determine indices for integration window for peaks.
int PrintWFProjection_cnt
Index for multiple executions of the same plotting function.
int start_read_at_channel
Do analysis only for limited range of channels to reduce memory usage.
vector< int > maxSumBin
Stores bin numbers where the sum of waveforms have their maximum.
void PrintChargeSpectrumWF(float, float, float=0, float=300, int=1, float=0., float=0., float=0., float=0.)
Plot waveforms of all channels for a given event number and add the determined integration windows to...
vector< float > mean_integral
Stores the mean integral/lightyield from PrintChargeSpectrum() for all channels.
bool discard_original_eventnr
Can be used to discard the original event numbering of the data.
virtual int Nevents_good(int=0)
Number of good events that are not skipped.
vector< vector< float > > amplValuessum
Collects sums of all waveforms for each channel.
vector< int > switch_polarity_for_channels
Stores the channel number where the polarity should be inverted. Example use to switch polarity for c...
TH1F * WFProjectionChannel(int, int=0, int=1024, float=-50, float=50, int=200)
Waveform projections for one channel.
TGraph2D * MaxDist(int, float=0, float=300)
Finds maximum amplitude for a given channel in time window ["from", "to"] and creates 3d map of wavef...
int nwf
Total number of waveforms read from data: number of active channels x number of events.
TH1F * TimeDist(int, float=0, float=300, float=0, float=300, int=100, int=0, float=.3)
Time distribution of maximum, CFD, or 10% - 90% rise time in a certain time window.
void GetTimingCFD(float=.3, float=100, float=140, double=0., bool=true, int=2, bool=false, bool=false)
Determine the timing of the maximum peak with constant fraction discrimination.
void IntegralFilter(vector< float >, vector< bool >, float, float, float=50, float=250, bool=false, bool=false)
Skip events with threshold on integral.
ReadRun(int last_bin_file=0, int first_bin_file=0)
Constructor of the class.
TH1F * BaselineCorrectionResults(int, int, float=-5, float=5, int=200)
Histograms of the contents of baseline_correction_result.
void PrintDCR(float=15, float=85, float=0, float=300, double=3)
Calculate (SiPM) dark count rate.
int PrintChargeSpectrum_cnt
Index for multiple executions of the same plotting function.
void SmoothAll(double, int)
Smoothing all waveforms which are not skipped (for testing, careful when using for analysis!...
void CorrectBaseline(float, float=-999)
Baseline correction constant window.
int binNumber
Number of bins (usually 1024 samples per waveform).
vector< vector< float > > PrintChargeSpectrum_cal
Calibration values to normalize charge spectrum to number of photoelectrons Chennels must be ordered ...
vector< vector< float > > timing_results
Matrix to store timing of peaks from GetTimingCFD()
void SaveChargeLists(float=20, float=80, float=0, float=300, bool=1)
Saves TGraphs to root file with the individual "charge"/amplitude for all events and all channels.
vector< vector< float > > baseline_correction_result
Stores baseline correction results for CorrectBaseline() and related functions.
TH1F * His_GetTimingCFD_diff(vector< int >, vector< int >, float, float, int=-999)
Plot timing difference between the mean timings of two channel ranges.
void SkipEventsTimeDiffCut(int, int, double, double, bool=false)
Skip events where the time difference between two channels is outside of specified range.
int PlotWFHeatmaps_cnt
Index for multiple executions of the same plotting function.
void SkipEventsPerChannel(vector< float >, float=0, float=0, bool=false)
Skip events above/below individual thresholds per channel.
string data_path
Path to data.
void PrintMaxDist(float=0, float=300)
Finds maximum amplitude for a given channel in time window ["from", "to"] and creates 3d map of wavef...
void PrintChargeSpectrum(float, float, float=0, float=300, float=-50, float=600, int=750, float=0., float=0., int=99, int=0, bool=false)
Plots the "charge" spectrums of all channels.
virtual void checkData(bool isBaselineCorrection=false) const
Primitive check to see if data has been loaded.
int end_read_at_channel
See ReadRun::start_read_at_channel.
int nchannels
Number of active channels in data.
void UnskipAll()
Sets skip_event flag to false for all events, removing any previous cuts.
float SP
Sampling: ns per bin of data, sampling rate 3.2 GS/s -> 0.3125 ns.
vector< TFitResultPtr > timing_fit_results
Stores the fit results of Print_GetTimingCFD() for all channels.
T * getx(double shift=0.)
Get array of x axis (time of the bin centers) for standard wavecatcher settings.
virtual int GetCurrentEvent(int)
Get the current event index for a certain waveform index.
virtual ~ReadRun()
Destructor.
virtual bool SkipEvent(int, int=-1)
Check if event should be skipped.
void PlotChannelSums(bool=false, bool=false, double=0., double=0., int=2)
Plot sums of all raw waveforms for each channel.
int CheckBoundsX(int)
Check if index exists in time of waveforms.
void PrintTimeDist(float=0, float=300, float=0, float=300, int=100, int=0, float=.3)
Time distribution of maximum, CFD, or 10% - 90% rise time in a certain time window.
vector< int > plot_active_channels
Stores the numbers of the active channels which should be plotted.
void ShiftAllToAverageCF()
This function shifts all waveforms to the average signal starting times for each channel.
vector< TFitResultPtr > fit_results
Stores the fit results of PrintChargeSpectrum() for all channels and all function calls in ascending ...
virtual int GetCurrentChannel(int)
Get the current channel index for a certain waveform index.
void PrintSkippedEvents()
Prints a list of all skipped events into the terminal for diagnostics.
int LastBinFileToRead
Number of last .bin file to be read in.
void CorrectBaselineMinSlopeRMS(vector< float >, double=0, int=2)
Baseline correction method searching for non-monotonic, rather constant regions.
TH2F * WFHeatmapChannel(int, float=-20, float=200, int=880)
2D histogram of all non-skipped waveforms for one channel
void Print_GetTimingCFD_diff(vector< int >, vector< int >, float=100, float=140, int=0, int=-999, float=-999, float=-999, string="RS", bool=true)
Plot timing difference between the mean timings of two channel ranges.
vector< unsigned int > eventnr_storage
Events will be stored here in the order they have been read.