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 cout <<
"Aborting execution." << endl;
179 size_t waveform_bytes =
static_cast<size_t>(
binNumber) *
sizeof(
short);
185 size_t nchannels_first = 10 + header_line.find(
"ACQUIRED: ", nsamples_first);
186 size_t nchannels_last = header_line.find_first_of(
' ', nchannels_first);
187 string nchannels_str = header_line.substr(nchannels_first, nchannels_last - nchannels_first);
190 if (debug_header) printf(
" |- nchannels = %d\n",
nchannels);
192 size_t sp_first = 8 + header_line.find(
"Period:");
193 size_t sp_last = header_line.find(
" ps");
194 float sampling_period = atof(header_line.substr(sp_first, sp_last - sp_first).data());
195 if (debug_header) printf(
"sampling period = %f ps\n", sampling_period);
196 SP = sampling_period * 1e-3;
200 if (v_major ==2 && v_minor == 9 && v_patch <= 13) {
202 has_measurement =
true;
205 size_t has_measurement_first = 14 + header_line.find(
"MEASUREMENTS: ", nsamples_first);
206 size_t has_measurement_last = header_line.find_first_of(
' ', has_measurement_first);
207 string has_measurement_str = header_line.substr(has_measurement_first, has_measurement_last - has_measurement_first);
208 has_measurement = atoi(has_measurement_str.data());
211 if (debug_header) printf(
" `- measurement = %d\n", has_measurement);
217 while (input_file.read((
char*)(&an_event),
sizeof(an_event))) {
219 if (debug_data) printf(
"%03d has %d channels\n", an_event.EventNumber, an_event.nchannelstored);
221 output_event = an_event.EventNumber;
222 output_nbchannels = an_event.nchannelstored;
224 if (debug_data && output_event % 200 == 0) printf(
"EventNr: %d, nCh: %d\n", output_event, output_nbchannels);
226 cout <<
"ERROR:\nThe number of channels in the data is " << output_nbchannels
227 <<
", which is larger than the maximum allowed number of channels which is set to " <<
nChannelsWC
228 <<
"\nPlease set the parameter nChannelsWC=" << output_nbchannels << endl;
331 cout <<
"\nAnalysis completed." <<
endl;
351 mgsums->SetTitle(
"channel sums; t [ns]; amplitude [mV]");
352 if (
normalize)
mgsums->SetTitle(
"channel sums; t [ns]; amplitude [arb.]");
368 double tmp_min = TMath::MinElement(
gr->GetN(),
gr->GetY());
370 double tmp_max = TMath::MaxElement(
gr->GetN(),
gr->GetY());
392 sumc->BuildLegend(0.85, 0.70, .99, .95);
413 mgav->SetTitle(
"channel averages; t [ns]; amplitude [mV]");
414 if (
normalize)
mgav->SetTitle(
"channel averages; t[ns]; amplitude[arb.]");
436 double tmp_min = TMath::MinElement(
gr->GetN(),
gr->GetY());
438 double tmp_max = TMath::MaxElement(
gr->GetN(),
gr->GetY());
461 avc->BuildLegend(0.85, 0.70, .99, .95);
484 h2->GetXaxis()->SetTitle(
"t [ns]");
485 h2->GetYaxis()->SetTitle(
"I [arb.]");
486 h2->GetZaxis()->SetTitle(
"entries");
560 gPad->SetTopMargin(.1);
561 gPad->SetBottomMargin(.1);
562 gPad->SetLeftMargin(.15);
563 gPad->SetRightMargin(.15);
570 if (
z_opt ==
"COLZ0")
h2->Draw(
"COLZ0");
571 else h2->Draw(
"CONT4Z");
573 if (
z_opt ==
"log") {
577 else if (
z_max > 0)
h2->GetZaxis()->SetRangeUser(0,
z_max);
594 cout <<
"Smoothing all non-skipped waveforms..." <<
endl;
596 #pragma omp parallel for
597 for (
int j = 0;
j <
nwf;
j++) {
616 cout <<
"\nSmoothing all non-skipped waveforms:" <<
endl;
618 #pragma omp parallel for
619 for (
int j = 0;
j <
nwf;
j++) {
638 cout <<
"\nFiltering all waveforms..." <<
endl;
640 #pragma omp parallel for
641 for (
int j = 0;
j <
nwf;
j++) {
658 cout <<
"\nShifting all waveforms to the average constant fraction time for each channel:" <<
endl;
665 for (
int j = 0;
j <
nwf;
j++) {
677 #pragma omp parallel for
678 for (
int j = 0;
j <
nwf;
j++) {
708 cout <<
"\nPerforming simple baseline correction in fixed time window."
709 <<
"This method is only suitable for measurements without dark counts!" <<
endl;
716 cout <<
"Baseline correction (" <<
nwf <<
" waveforms):" <<
endl;
719 #pragma omp parallel for
720 for (
int j = 0;
j <
nwf;
j++) {
787 cout <<
"\nBaseline correction (minimum slope variation method, " <<
nwf <<
" waveforms):" <<
endl;
788 if (
window.empty())
cout <<
"\nWarning: Window not set in CorrectBaselineMinSlopeRMS. Will use default values." <<
endl;
789 if (
sigma != 0.)
cout <<
"\nNotification: Using smoothing in CorrectBaselineMinSlopeRMS." <<
endl;
803 cout <<
"\nNotification: Using dynamic search window in CorrectBaselineMinSlopeRMS." <<
endl;
810 #pragma omp parallel for
811 for (
int j = 0;
j <
nwf;
j++) {
912 cout <<
"WARNING: This is a deprecated version of CorrectBaselineMinSlopeRMS. "
913 <<
"It will be removed in future releases. Parameter bool smooth=" <<
smooth <<
" will be ignored." <<
endl;
930 cout <<
"WARNING: This is a deprecated version of CorrectBaselineMinSlopeRMS. "
931 <<
"It will be removed in future releases. Parameter increment=" <<
increment <<
" will be ignored." <<
endl;
959 cout <<
"\nBaseline correction (minimal sum method, " <<
nwf <<
" waveforms):" <<
endl;
960 if (
window.empty())
cout <<
"\nWarning: Window not set in CorrectBaselineMin. Will use default values." <<
endl;
961 if (
sigma != 0.)
cout <<
"\nNotification: Using smoothing in CorrectBaselineMin." <<
endl;
975 cout <<
"\nNotification: Using dynamic search window in CorrectBaselineMin." <<
endl;
982 #pragma omp parallel for
983 for (
int j = 0;
j <
nwf;
j++) {
1052 cout <<
"WARNING: This is a deprecated version of CorrectBaselineMin. It will be removed in future releases." <<
endl;
1068 cout <<
"WARNING: This is a deprecated version of CorrectBaselineMin. It will be removed in future releases." <<
endl;
1126 his->GetYaxis()->SetTitle(
"#Entries");
1127 his->GetXaxis()->SetTitle(
"amplitude in mV");
1130 his->Fit(
"gaus",
"M",
"same");
1146 cout <<
"\nError: baseline_correction_result empty. Call baseline correction first." <<
endl;
1182 ctitle =
"Correction values in mV";
1192 his->GetYaxis()->SetTitle(
"#Entries");
1193 his->GetXaxis()->SetTitle(
ctitle.c_str());
1195 his->Fit(
"gaus",
"WWM",
"same");
1224void 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) {
1231 cout <<
"\nGet timing at " << (
cf_r > 0 &&
cf_r <= 1 ?
"CF=" :
"threshold=");
1239 #pragma omp parallel for
1240 for (
int j = 0;
j <
nwf;
j++) {
1323 cout <<
"\n Removing events if the event-wise time difference between the main peaks in ch"
1335 #pragma omp parallel for reduction(+:counter)
1372 cout <<
"\n Removing events with individual amplitude threshold per channel:" <<
endl;
1379 #pragma omp parallel for reduction(+:counter)
1380 for (
int j = 0;
j <
nwf;
j++) {
1427void ReadRun::IntegralFilter(vector<float> thresholds, vector<bool> g_thr,
float windowlow,
float windowhi,
float start,
float end,
bool use_AND_condition ,
bool verbose) {
1429 if (
thresholds.empty() ||
g_thr.empty())
cout <<
"\nERROR: thresholds or g_thr are empty in ReadRun::IntegralFilter().";
1433 cout <<
"\n\nRemoving events with individual integral threshold per channel:" <<
endl;
1437 #pragma omp parallel for reduction(+:counter)
1438 for (
int j = 0;
j <
nwf;
j++) {
1495 cout <<
"\n\nAll event cuts were removed" <<
endl;
1552 cout <<
"\nError: Start=" <<
istart <<
" or end=" <<
iend <<
" of GetIntWindow() out of range. Fix integration window." <<
endl;
1587array<int, 3>
ReadRun::GetIntWindow(
const vector<float>& waveform,
float windowlow,
float windowhi,
float start,
float end,
int channel) {
1623array<int, 3>
ReadRun::GetIntWindow(
const vector<float>& waveform,
int windowlow,
int windowhi,
int start,
int end,
int channel) {
1687float ReadRun::GetPeakIntegral(
const vector<float>& waveform,
float windowlow,
float windowhi,
float start,
float end,
int channel_index) {
1728 gPad->SetTopMargin(.01);
1740 low->SetLineColor(2);
1742 hi->SetLineColor(2);
1744 zero->SetLineColor(1);
1797float*
ReadRun::ChargeList(
int channel_index,
float windowlow,
float windowhi,
float start,
float end,
bool negative_vals) {
1800 #pragma omp parallel for
1830 else charge_list_mg->SetTitle(
"event-wise amplitudes; Event number; amplitude [mV]");
1874void ReadRun::ChargeCorrelation(
float windowlow,
float windowhi,
float start,
float end,
float rangestart,
float rangeend,
int nbins,
int channel1,
int channel2,
bool ignore_skipped_events) {
1875 gStyle->SetOptStat(1111);
1918TH1F*
ReadRun::ChargeSpectrum(
int channel_index,
float windowlow,
float windowhi,
float start,
float end,
float rangestart,
float rangeend,
int nbins) {
1936 #pragma omp parallel
1990void 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) {
1993 cout <<
"Creating charge spectrum ..." <<
endl;
1995 gStyle->SetOptStat(
"ne");
2027 his->GetYaxis()->SetTitle(
"#Entries");
2029 else his->GetXaxis()->SetTitle(
"Amplitude in mV");
2032 cout <<
"Charge spectrum for channel index " <<
i <<
" will be normalized using a gain of "
2034 his->GetXaxis()->SetTitle(
"Number of photoelectrons");
2048 f->SetParName(0,
"Width");
f->SetParameter(0, 35);
2049 f->SetParName(1,
"MPV");
f->SetParameter(1, 1000);
2050 f->SetParName(2,
"Area");
f->SetParameter(2, 10000);
2051 f->SetParName(3,
"#sigma_{Gauss}");
f->SetParameter(3, 100);
2056 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2066 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2067 f->SetParName(1,
"#mu");
f->SetParameter(1, 2.);
2068 f->SetParName(2,
"#lambda");
f->SetParameter(2, .04);
2069 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 2.1);
2070 f->SetParName(4,
"#sigma_{1}");
f->SetParameter(4, 3.4);
2071 f->SetParName(5,
"Gain");
f->SetParameter(5, 30.);
2072 f->SetParName(6,
"Pedestal");
f->SetParameter(6, 2.);
2073 f->SetParName(7,
"norm_{0}");
f->SetParameter(7, 0.7);
2074 f->SetParName(8,
"x_{0}");
f->SetParameter(8, 5.);
2079 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2095 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2096 f->SetParName(1,
"#mu");
f->SetParameter(1, 2.);
2097 f->SetParName(2,
"#lambda");
f->SetParameter(2, .04);
2098 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 2.1);
2099 f->SetParName(4,
"#sigma_{1}");
f->SetParameter(4, 3.4);
2100 f->SetParName(5,
"Gain");
f->SetParameter(5, 30.);
2101 f->SetParName(6,
"Pedestal");
f->SetParameter(6, 2.);
2102 f->SetParName(7,
"#alpha");
f->SetParameter(7, .1);
2103 f->SetParName(8,
"#beta");
f->SetParameter(8, 80.);
2108 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2118 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2119 f->SetParName(1,
"#mu");
f->SetParameter(1, 1.);
2120 f->SetParName(2,
"#sigma");
f->SetParameter(2, 5.);
2121 f->SetParName(3,
"gain");
f->SetParameter(3, 10.);
2126 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2136 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2137 f->SetParName(1,
"w");
f->SetParameter(1, .05);
f->SetParLimits(1, 1.e-99, 4.e-1);
2138 f->SetParName(2,
"#alpha");
f->SetParameter(2, .05);
f->SetParLimits(2, 1.e-99, 5.e-2);
2139 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 5.);
f->SetParLimits(3, 1.e-9, 1.e3);
2140 f->SetParName(4,
"Q_{0}");
f->SetParameter(4, 0.);
2141 f->SetParName(5,
"#mu");
f->SetParameter(5, 1.);
2142 f->SetParName(6,
"#sigma_{1}");
f->SetParameter(6, 5.);
f->SetParLimits(6, 1.e-9, 1.e3);
2143 f->SetParName(7,
"Q_{1}");
f->SetParameter(7, 10.);
2148 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2158 f->SetParName(0,
"A");
f->SetParameter(0,
his->Integral());
2159 f->SetParName(1,
"w");
f->SetParameter(1, .05);
f->SetParLimits(1, 1.e-9, 4.e-1);
2160 f->SetParName(2,
"#alpha");
f->SetParameter(2, .05);
f->SetParLimits(2, 1.e-9, 5.e-2);
2161 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 5.);
f->SetParLimits(3, 1.e-9, 1.e3);
2162 f->SetParName(4,
"Q_{0}");
f->SetParameter(4, 0.);
f->SetParLimits(4, -1.e2, 1.e2);
2163 f->SetParName(5,
"#mu");
f->SetParameter(5, 1.);
f->SetParLimits(5, 1.e-9, 1.e2);
2164 f->SetParName(6,
"#sigma_{1}");
f->SetParameter(6, 5.);
f->SetParLimits(6, 1.e-9, 1.e3);
2165 f->SetParName(7,
"Q_{1}");
f->SetParameter(7, 10.);
f->SetParLimits(7, 1.e-9, 1.e9);
2166 f->SetParName(8,
"A_{0}");
f->SetParameter(8, 1.);
f->SetParLimits(8, 1.e-9, 1.e1);
2171 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2181 f->SetParName(0,
"A");
f->SetParameter(0,
his->Integral());
2182 f->SetParName(1,
"w");
f->SetParameter(1, .05);
f->SetParLimits(1, 1.e-9, 4.e-1);
2183 f->SetParName(2,
"#alpha");
f->SetParameter(2, .05);
f->SetParLimits(2, 1.e-9, 5.e-2);
2184 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 5.);
f->SetParLimits(3, 1.e-9, 1.e3);
2185 f->SetParName(4,
"Q_{0}");
f->SetParameter(4, 0.);
f->SetParLimits(4, -1.e2, 1.e2);
2186 f->SetParName(5,
"#mu");
f->SetParameter(5, 1.);
f->SetParLimits(5, 1.e-9, 1.e2);
2187 f->SetParName(6,
"#sigma_{1}");
f->SetParameter(6, 5.);
f->SetParLimits(6, 1.e-9, 1.e3);
2188 f->SetParName(7,
"#mu_darkcount");
f->SetParameter(7, .1);
f->SetParLimits(7, 1.e-9, 1.);
2189 f->SetParName(8,
"N_{0}_darkcount");
f->SetParameter(8, .05);
f->SetParLimits(8, 1.e-9, .3);
2194 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2204 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2205 f->SetParName(1,
"#mu");
f->SetParameter(1, 2.);
2206 f->SetParName(2,
"#lambda");
f->SetParameter(2, .04);
2207 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 2.1);
2208 f->SetParName(4,
"#sigma_{1}");
f->SetParameter(4, 3.4);
2209 f->SetParName(5,
"Gain");
f->SetParameter(5, 30.);
2210 f->SetParName(6,
"Pedestal");
f->SetParameter(6, 2.);
2215 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2240void ReadRun::PrintDCR(
float windowlow,
float windowhi,
float rangestart,
float rangeend,
double threshold) {
2264TH1F*
ReadRun::TimeDist(
int channel_index,
float from,
float to,
float rangestart,
float rangeend,
int nbins,
int which,
float cf_r) {
2280 else if (
which == 1) {
2305 if (
which == 1)
h1->Fit(
"gaus",
"WWM",
"same");
2328 gStyle->SetOptStat(1111);
2340 his->GetYaxis()->SetTitle(
"#Entries");
2341 his->GetXaxis()->SetTitle(
"time [ns]");
2344 his->SetTitle(
name.str().c_str());
2368 g3d->SetTitle(
"waveforms; t [ns]; max. amplitude [mv]; amplitude [mV]");
2369 g3d->SetMarkerStyle(7);
2402 auto max_dist_c =
new TCanvas(
"wf grouped by maximum",
"wf grouped by maximum", 600, 400);
2453 gStyle->SetOptStat(1111);
2465 his->GetYaxis()->SetTitle(
"#Entries");
2466 his->GetXaxis()->SetTitle(
"time [ns]");
2469 int end =
his->GetNbinsX();
2470 for (
int k = 1;
k <=
end;
k++) {
2471 if (
his->GetBinContent(
k) < 2)
his->SetBinError(
k, 1);
2503 name <<
"GetTimingCFD_diff <";
2514 else cout <<
"\n\n ERROR: channels2 = " <<
entry <<
" does not exist in data. Check parameters for Print_GetTimingCFD_diff()\n\n";
2527 else cout <<
"\n\n ERROR: channels1 = " <<
entry <<
" does not exist in data. Check parameters for Print_GetTimingCFD_diff()\n\n";
2593void 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) {
2609 his->GetYaxis()->SetTitle(
"#Entries");
2610 his->GetXaxis()->SetTitle(
"time [ns]");
2613 int end =
his->GetNbinsX();
2614 for (
int i = 1;
i <=
end;
i++) {
2615 if (
his->GetBinContent(
i) < 2)
his->SetBinError(
i, 1);
2628 if (
do_fit == 2)
cout <<
"\nWARNING: Print_GetTimingCFD_diff\nFITTING GAUSS INSTEAD OF GAUSS x EXP CONVOLUTION BC SYMMETRY" <<
endl;
2640 else expgconv->SetParLimits(0, -5., -.15);
2673 mean->SetLineColor(1);
mean->SetLineWidth(2);
2679 two_gauss->SetTitle(
"Sum of two gauss");
2680 float posmax =
his->GetXaxis()->GetBinCenter(
his->GetMaximumBin());
2777 cout <<
"WARNING: Event number " <<
eventnr <<
" for GetEventIndex() does not exist in data.\n"
2778 <<
"Please check the events in the data or set discard_original_eventnr = true before calling ReadFile()." <<
endl;
2783 cout <<
"Found event number " <<
eventnr <<
" in data and will use it." <<
endl;
2798 cout <<
"\n\n\tERROR: channel " <<
channel_number <<
" does not exist in data. Will continue with first channel\n\n";
2837 if (
y1 ==
y2)
return {(
x1 +
x2) * 0.5,
false};
2840 cout <<
"\nError in LinearInterpolation: Value ym=" <<
ym <<
" out of range (" <<
y1 <<
"|" <<
y2 <<
")." <<
endl;
2841 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.