26 cout <<
"\ninitializing ..." << endl;
28 if (max_no_of_bin_files_to_read > 0) {
29 cout <<
"will read " << max_no_of_bin_files_to_read - min_no_of_bin_files_to_read <<
" .bin files from file number "
30 << min_no_of_bin_files_to_read <<
" to file number " << max_no_of_bin_files_to_read << endl;
34 ROOT::EnableImplicitMT();
35 TH1::AddDirectory(kFALSE);
38 PrintChargeSpectrum_cnt = 0;
39 PlotChannelAverages_cnt = 0;
40 PrintWFProjection_cnt = 0;
41 PlotWFHeatmaps_cnt = 0;
66void ReadRun::ReadFile(
string path,
bool change_polarity,
int change_sign_from_to_ch_num,
string out_file_name,
bool debug) {
68 if (path.back() !=
'/') path +=
'/';
72 if (out_file_name ==
"") out_file_name =
"out.root";
73 printf(
"+++ saving analysis results in '%s' ...\n\n", out_file_name.c_str());
74 root_out = TFile::Open(out_file_name.c_str(),
"recreate");
77 rundata->BypassStreamer(kFALSE);
78 TClonesArray& testrundata = *
rundata;
81 bool debug_header = debug;
82 bool debug_data = debug;
84 unsigned short output_channel;
85 unsigned int output_event;
86 unsigned short output_nbchannels;
87 unsigned short read_channels = 0;
89 size_t length_of_waveform =
static_cast<size_t>(
binNumber) *
sizeof(
short);
99 stringstream inFileList;
101 if (debug) cout << inFileList.str() << endl;
103 int file_counter = -1;
105 int event_counter = 0;
107 while (inFileList >> fileName) {
114 fileName = path + fileName;
115 ifstream input_file(fileName.c_str(), ios::binary | ios::in);
117 bool has_measurement =
false;
119 if (!input_file.is_open()) {
120 printf(
"*** failed to open '%s'\n", fileName.c_str());
124 if (file_counter < 10 || file_counter % 10 == 0 || debug) printf(
"+++ reading '%s' ...\n", fileName.c_str());
132 getline(input_file, header_line,
'\n');
134 if (debug_header) printf(
"%s\n", header_line.data());
135 assert(header_line[0] ==
'=');
137 size_t header_version_first = header_line.find_last_of(
'V');
138 size_t header_version_last = header_line.find_first_of(
' ', header_version_first);
139 string software_version = header_line.substr(header_version_first, header_version_last - header_version_first);
140 if (debug_header) printf(
" |- data version = '%s'\n", software_version.data());
142 software_version.erase(0, 1);
143 int v_major, v_minor, v_patch;
144 istringstream software_version_iss(software_version);
146 software_version_iss >> v_major >> dot_ >> v_minor >> dot_ >> v_patch;
150 getline(input_file, header_line,
'\n');
152 if (debug_header) printf(
"%s\n", header_line.data());
153 assert(header_line[0] ==
'=');
157 getline(input_file, header_line,
'\n');
159 if (debug_header) printf(
"%s\n", header_line.data());
160 assert(header_line[0] ==
'=');
165 getline(input_file, header_line,
'\n');
167 if (debug_header) printf(
"%s\n", header_line.data());
168 assert(header_line[0] ==
'=');
170 size_t nsamples_first = 1 + header_line.find_last_of(
'[');
171 size_t nsamples_last = header_line.find_first_of(
']', nsamples_first);
172 string nsamples_str = header_line.substr(nsamples_first, nsamples_last - nsamples_first);
175 if (debug_header) printf(
" |- data sample = %d\n",
binNumber);
176 if (
binNumber != 1024) cout <<
"\nERROR: Measurement must have 1024 samples.\nCheck WaveCatcher setting!" << endl;
178 size_t nchannels_first = 10 + header_line.find(
"ACQUIRED: ", nsamples_first);
179 size_t nchannels_last = header_line.find_first_of(
' ', nchannels_first);
180 string nchannels_str = header_line.substr(nchannels_first, nchannels_last - nchannels_first);
183 if (debug_header) printf(
" |- nchannels = %d\n",
nchannels);
185 size_t sp_first = 8 + header_line.find(
"Period:");
186 size_t sp_last = header_line.find(
" ps");
187 float sampling_period = atof(header_line.substr(sp_first, sp_last - sp_first).data());
188 if (debug_header) printf(
"sampling period = %f ps\n", sampling_period);
189 SP = sampling_period * 1e-3;
192 if (v_major ==2 && v_minor == 9 && v_patch <= 13) {
194 has_measurement =
true;
197 size_t has_measurement_first = 14 + header_line.find(
"MEASUREMENTS: ", nsamples_first);
198 size_t has_measurement_last = header_line.find_first_of(
' ', has_measurement_first);
199 string has_measurement_str = header_line.substr(has_measurement_first, has_measurement_last - has_measurement_first);
200 has_measurement = atoi(has_measurement_str.data());
203 if (debug_header) printf(
" `- measurement = %d\n", has_measurement);
209 while (input_file.read((
char*)(&an_event),
sizeof(an_event))) {
211 if (debug_data) printf(
"%03d has %d channels\n", an_event.EventNumber, an_event.nchannelstored);
213 output_event = an_event.EventNumber;
214 output_nbchannels = an_event.nchannelstored;
216 if (debug_data && output_event % 200 == 0) printf(
"EventNr: %d, nCh: %d\n", output_event, output_nbchannels);
218 cout <<
"ERROR:\nThe number of channels in the data is " << output_nbchannels
219 <<
", which is larger than the maximum allowed number of channels which is set to " <<
nChannelsWC
220 <<
"\nPlease set the parameter nChannelsWC=" << output_nbchannels << endl;
329 hCh->SetBinContent(
s + 1,
val);
380 cout <<
"\ndeleting nothing currently..." <<
endl;
400 mgsums->SetTitle(
"channel sums; t [ns]; amplitude [mV]");
401 if (
normalize)
mgsums->SetTitle(
"channel sums; t [ns]; amplitude [arb.]");
403 double max = 0.,
min = 0.;
415 double tmp_min = TMath::MinElement(
gr->GetN(),
gr->GetY());
417 double tmp_max = TMath::MaxElement(
gr->GetN(),
gr->GetY());
438 sumc->BuildLegend(0.85, 0.70, .99, .95);
458 mgav->SetTitle(
"channel averages; t [ns]; amplitude [mV]");
459 if (
normalize)
mgav->SetTitle(
"channel averages; t[ns]; amplitude[arb.]");
461 double max = 0.,
min = 0.;
482 double tmp_min = TMath::MinElement(
gr->GetN(),
gr->GetY());
484 double tmp_max = TMath::MaxElement(
gr->GetN(),
gr->GetY());
505 else mgav->GetYaxis()->SetRangeUser(
min,
max);
506 avc->BuildLegend(0.85, 0.70, .99, .95);
528 h2->GetXaxis()->SetTitle(
"t [ns]");
529 h2->GetYaxis()->SetTitle(
"I [arb.]");
530 h2->GetZaxis()->SetTitle(
"entries");
559 string name(
"waveforms_heatmap_" +
to_string(PlotWFHeatmaps_cnt++));
568 gPad->SetTopMargin(.1);
569 gPad->SetBottomMargin(.1);
570 gPad->SetLeftMargin(.15);
571 gPad->SetRightMargin(.15);
577 if (
z_opt ==
"COLZ0")
h2->Draw(
"COLZ0");
578 else h2->Draw(
"CONT4Z");
579 if (
z_opt ==
"log") {
583 else if (
z_max > 0)
h2->GetZaxis()->SetRangeUser(0,
z_max);
600 cout <<
"\nSmoothing all non-skipped waveforms:" <<
endl;
601 for (
int j = 0;
j <
nwf;
j++) {
606 for (
int i = 1;
i <=
his->GetNbinsX();
i++)
his->SetBinContent(
i,
yvals[
i - 1]);
621 cout <<
"\nSmoothing all non-skipped waveforms:" <<
endl;
622 for (
int j = 0;
j <
nwf;
j++) {
642 cout <<
"\nFiltering all waveforms" <<
endl;
643 for (
int j = 0;
j <
nwf;
j++) {
662 cout <<
"\nShifting all waveforms to the average constant fraction time for each channel:" <<
endl;
669 for (
int j = 0;
j <
nwf;
j++) {
681 for (
int j = 0;
j <
nwf;
j++) {
710 cout <<
"\nPerforming simple baseline correction in fixed time window."
711 <<
"This method is only suitable for measurements without dark counts!" <<
endl;
718 cout <<
"Baseline correction (" <<
nwf <<
" waveforms):" <<
endl;
719 for (
int j = 0;
j <
nwf;
j++) {
746 for (
int i = 1;
i <=
his->GetNbinsX();
i++)
his->SetBinContent(
i,
his->GetBinContent(
i) -
corr);
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;
805 cout <<
"\nNotification: Using dynamic search window in CorrectBaselineMinSlopeRMS." <<
endl;
814 for (
int j = 0;
j <
nwf;
j++) {
905 cout <<
"Notification: This is a deprecated version of CorrectBaselineMinSlopeRMS. "
906 <<
"It will be removed in future releases. Parameter bool smooth=" <<
smooth <<
" will be ignored." <<
endl;
941 cout <<
"\nBaseline correction (minimal sum method, " <<
nwf <<
" waveforms):" <<
endl;
942 if (
window.empty())
cout <<
"\nWarning: Window not set in CorrectBaselineMin. Will use default values." <<
endl;
943 if (
sigma != 0.)
cout <<
"\nNotification: Using smoothing in CorrectBaselineMin." <<
endl;
959 cout <<
"\nNotification: Using dynamic search window in CorrectBaselineMin." <<
endl;
968 for (
int j = 0;
j <
nwf;
j++) {
1038 cout <<
"Notification: This is a deprecated version of CorrectBaselineMin. It will be removed in future releases." <<
endl;
1100 his->GetYaxis()->SetTitle(
"#Entries");
1101 his->GetXaxis()->SetTitle(
"amplitude in mV");
1104 his->Fit(
"gaus",
"WWM",
"same");
1120 cout <<
"\nError: baseline_correction_result empty. Call baseline correction first." <<
endl;
1147 ctitle =
"Correction values in mV";
1157 his->GetYaxis()->SetTitle(
"#Entries");
1158 his->GetXaxis()->SetTitle(
ctitle.c_str());
1160 his->Fit(
"gaus",
"WWM",
"same");
1188void 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) {
1194 cout <<
"\nGet timing at " << (
cf_r > 0 &&
cf_r <= 1 ?
"CF=" :
"threshold=");
1197 for (
int j = 0;
j <
nwf;
j++) {
1287 cout <<
"\n Removing events if the event-wise time difference between the main peaks in ch"
1340 cout <<
"\nSearching for fraction of events with " << (
max ?
"max" :
"min") << (
greater ?
" > " :
" < ") <<
threshold <<
" mV:" <<
endl;
1342 for (
int j = 0;
j <
nwf;
j++) {
1346 if (
from >= 0 &&
to > 0) {
1347 his->GetXaxis()->SetRange(
his->GetXaxis()->FindBin(
from),
his->GetXaxis()->FindBin(
to));
1378 cout <<
"Fraction of events w/ at least 2 channels above threshold: "
1380 <<
"For a total of " <<
nevents <<
" events" <<
endl;
1398 cout <<
"\n Removing events with individual amplitude threshold per channel:" <<
endl;
1403 for (
int j = 0;
j <
nwf;
j++) {
1443void ReadRun::IntegralFilter(vector<float> thresholds, vector<bool> highlow,
float windowlow,
float windowhi,
float start,
float end,
bool use_AND_condition,
bool verbose) {
1449 cout <<
"\n\nRemoving events with individual integral threshold per channel:" <<
endl;
1456 for (
int j = 0;
j <
nwf;
j++) {
1506 cout <<
"\n\nAll event cuts were removed" <<
endl;
1553 cout <<
"\nError: start or end out of range" <<
endl;
1631 low->SetLineColor(2);
1633 hi->SetLineColor(2);
1635 zero->SetLineColor(1);
1639 gPad->SetTopMargin(.01);
1697float*
ReadRun::ChargeList(
int channel_index,
float windowlow,
float windowhi,
float start,
float end,
bool negative_vals) {
1723 else charge_list_mg->SetTitle(
"event-wise amplitudes; Event number; amplitude [mV]");
1765void ReadRun::ChargeCorrelation(
float windowlow,
float windowhi,
float start,
float end,
float rangestart,
float rangeend,
int nbins,
int channel1,
int channel2,
bool ignore_skipped_events) {
1766 gStyle->SetOptStat(1111);
1807TH1F*
ReadRun::ChargeSpectrum(
int channel_index,
float windowlow,
float windowhi,
float start,
float end,
float rangestart,
float rangeend,
int nbins) {
1861void 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) {
1865 gStyle->SetOptStat(
"ne");
1871 string ctitle(
"\"charge\" spectra" +
to_string(PrintChargeSpectrum_cnt++));
1891 his->GetYaxis()->SetTitle(
"#Entries");
1893 else his->GetXaxis()->SetTitle(
"Amplitude in mV");
1896 cout <<
"Charge spectrum for channel index " <<
i <<
" will be normalized using a gain of "
1898 his->GetXaxis()->SetTitle(
"Number of photoelectrons");
1912 f->SetParName(0,
"Width");
f->SetParameter(0, 35);
1913 f->SetParName(1,
"MPV");
f->SetParameter(1, 1000);
1914 f->SetParName(2,
"Area");
f->SetParameter(2, 10000);
1915 f->SetParName(3,
"#sigma_{Gauss}");
f->SetParameter(3, 100);
1920 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
1930 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
1931 f->SetParName(1,
"#mu");
f->SetParameter(1, 2.);
1932 f->SetParName(2,
"#lambda");
f->SetParameter(2, .04);
1933 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 2.1);
1934 f->SetParName(4,
"#sigma_{1}");
f->SetParameter(4, 3.4);
1935 f->SetParName(5,
"Gain");
f->SetParameter(5, 30.);
1936 f->SetParName(6,
"Pedestal");
f->SetParameter(6, 2.);
1937 f->SetParName(7,
"norm_{0}");
f->SetParameter(7, 0.7);
1938 f->SetParName(8,
"x_{0}");
f->SetParameter(8, 5.);
1943 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
1959 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
1960 f->SetParName(1,
"#mu");
f->SetParameter(1, 2.);
1961 f->SetParName(2,
"#lambda");
f->SetParameter(2, .04);
1962 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 2.1);
1963 f->SetParName(4,
"#sigma_{1}");
f->SetParameter(4, 3.4);
1964 f->SetParName(5,
"Gain");
f->SetParameter(5, 30.);
1965 f->SetParName(6,
"Pedestal");
f->SetParameter(6, 2.);
1966 f->SetParName(7,
"#alpha");
f->SetParameter(7, .1);
1967 f->SetParName(8,
"#beta");
f->SetParameter(8, 80.);
1972 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
1982 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
1983 f->SetParName(1,
"#mu");
f->SetParameter(1, 1.);
1984 f->SetParName(2,
"#sigma");
f->SetParameter(2, 5.);
1985 f->SetParName(3,
"gain");
f->SetParameter(3, 10.);
1990 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2000 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2001 f->SetParName(1,
"w");
f->SetParameter(1, .05);
f->SetParLimits(1, 1.e-99, 4.e-1);
2002 f->SetParName(2,
"#alpha");
f->SetParameter(2, .05);
f->SetParLimits(2, 1.e-99, 5.e-2);
2003 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 5.);
f->SetParLimits(3, 1.e-9, 1.e3);
2004 f->SetParName(4,
"Q_{0}");
f->SetParameter(4, 0.);
2005 f->SetParName(5,
"#mu");
f->SetParameter(5, 1.);
2006 f->SetParName(6,
"#sigma_{1}");
f->SetParameter(6, 5.);
f->SetParLimits(6, 1.e-9, 1.e3);
2007 f->SetParName(7,
"Q_{1}");
f->SetParameter(7, 10.);
2012 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2022 f->SetParName(0,
"A");
f->SetParameter(0,
his->Integral());
2023 f->SetParName(1,
"w");
f->SetParameter(1, .05);
f->SetParLimits(1, 1.e-9, 4.e-1);
2024 f->SetParName(2,
"#alpha");
f->SetParameter(2, .05);
f->SetParLimits(2, 1.e-9, 5.e-2);
2025 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 5.);
f->SetParLimits(3, 1.e-9, 1.e3);
2026 f->SetParName(4,
"Q_{0}");
f->SetParameter(4, 0.);
f->SetParLimits(4, -1.e2, 1.e2);
2027 f->SetParName(5,
"#mu");
f->SetParameter(5, 1.);
f->SetParLimits(5, 1.e-9, 1.e2);
2028 f->SetParName(6,
"#sigma_{1}");
f->SetParameter(6, 5.);
f->SetParLimits(6, 1.e-9, 1.e3);
2029 f->SetParName(7,
"Q_{1}");
f->SetParameter(7, 10.);
f->SetParLimits(7, 1.e-9, 1.e9);
2030 f->SetParName(8,
"A_{0}");
f->SetParameter(8, 1.);
f->SetParLimits(8, 1.e-9, 1.e1);
2035 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2045 f->SetParName(0,
"A");
f->SetParameter(0,
his->Integral());
2046 f->SetParName(1,
"w");
f->SetParameter(1, .05);
f->SetParLimits(1, 1.e-9, 4.e-1);
2047 f->SetParName(2,
"#alpha");
f->SetParameter(2, .05);
f->SetParLimits(2, 1.e-9, 5.e-2);
2048 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 5.);
f->SetParLimits(3, 1.e-9, 1.e3);
2049 f->SetParName(4,
"Q_{0}");
f->SetParameter(4, 0.);
f->SetParLimits(4, -1.e2, 1.e2);
2050 f->SetParName(5,
"#mu");
f->SetParameter(5, 1.);
f->SetParLimits(5, 1.e-9, 1.e2);
2051 f->SetParName(6,
"#sigma_{1}");
f->SetParameter(6, 5.);
f->SetParLimits(6, 1.e-9, 1.e3);
2052 f->SetParName(7,
"#mu_darkcount");
f->SetParameter(7, .1);
f->SetParLimits(7, 1.e-9, 1.);
2053 f->SetParName(8,
"N_{0}_darkcount");
f->SetParameter(8, .05);
f->SetParLimits(8, 1.e-9, .3);
2058 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2068 f->SetParName(0,
"N_{0}");
f->SetParameter(0,
his->Integral());
2069 f->SetParName(1,
"#mu");
f->SetParameter(1, 2.);
2070 f->SetParName(2,
"#lambda");
f->SetParameter(2, .04);
2071 f->SetParName(3,
"#sigma_{0}");
f->SetParameter(3, 2.1);
2072 f->SetParName(4,
"#sigma_{1}");
f->SetParameter(4, 3.4);
2073 f->SetParName(5,
"Gain");
f->SetParameter(5, 30.);
2074 f->SetParName(6,
"Pedestal");
f->SetParameter(6, 2.);
2079 cout <<
"\n\n---------------------- Fit for channel " <<
active_channels[
i] <<
" ----------------------\n";
2103void ReadRun::PrintDCR(
float windowlow,
float windowhi,
float rangestart,
float rangeend,
double threshold) {
2127TH1F*
ReadRun::TimeDist(
int channel_index,
float from,
float to,
float rangestart,
float rangeend,
int nbins,
int which,
float cf_r) {
2144 else if (
which == 1) {
2169 if (
which == 1)
h1->Fit(
"gaus",
"WWM",
"same");
2192 gStyle->SetOptStat(1111);
2204 his->GetYaxis()->SetTitle(
"#Entries");
2205 his->GetXaxis()->SetTitle(
"time [ns]");
2208 his->SetTitle(
name.str().c_str());
2232 g3d->SetTitle(
"waveforms; t [ns]; max. amplitude [mv]; amplitude [mV]");
2237 if (
from >= 0 &&
to > 0)
his->GetXaxis()->SetRange(
his->GetXaxis()->FindBin(
from),
his->GetXaxis()->FindBin(
to));
2238 double max =
his->GetMaximum();
2256 auto max_dist_c =
new TCanvas(
"wf grouped by maximum",
"wf grouped by maximum", 600, 400);
2305 gStyle->SetOptStat(1111);
2317 his->GetYaxis()->SetTitle(
"#Entries");
2318 his->GetXaxis()->SetTitle(
"time [ns]");
2321 int end =
his->GetNbinsX();
2322 for (
int i = 1;
i <=
end;
i++) {
2323 if (
his->GetBinContent(
i) < 2)
his->SetBinError(
i, 1);
2355 name <<
"GetTimingCFD_diff <";
2366 else cout <<
"\n\n ERROR: channels2 = " <<
entry <<
" does not exist in data. Check parameters for Print_GetTimingCFD_diff()\n\n";
2379 else cout <<
"\n\n ERROR: channels1 = " <<
entry <<
" does not exist in data. Check parameters for Print_GetTimingCFD_diff()\n\n";
2438void 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) {
2454 his->GetYaxis()->SetTitle(
"#Entries");
2455 his->GetXaxis()->SetTitle(
"time [ns]");
2458 int end =
his->GetNbinsX();
2459 for (
int i = 1;
i <=
end;
i++) {
2460 if (
his->GetBinContent(
i) < 2)
his->SetBinError(
i, 1);
2473 if (
do_fit == 2)
cout <<
"\nWARNING: Print_GetTimingCFD_diff\nFITTING GAUSS INSTEAD OF GAUSS x EXP CONVOLUTION BC SYMMETRY" <<
endl;
2485 else expgconv->SetParLimits(0, -5., -.15);
2518 mean->SetLineColor(1);
mean->SetLineWidth(2);
2524 two_gauss->SetTitle(
"Sum of two gauss");
2525 float posmax =
his->GetXaxis()->GetBinCenter(
his->GetMaximumBin());
2572 xvals[
i] =
static_cast<double>(
SP) *
static_cast<double>(
i) +
shift;
2600 cout <<
"WARNING: Event number " <<
eventnr <<
" for GetEventIndex() does not exist in data.\n"
2601 <<
"Please check the events in the data or set discard_original_eventnr = true before calling ReadFile()." <<
endl;
2606 cout <<
"Found event number " <<
eventnr <<
" in data and will use it." <<
endl;
2621 cout <<
"\n\n\tERROR: channel " <<
channel_number <<
" does not exist in data. Will continue with first channel\n\n";
2659 if (
y1 ==
y2)
return {(
x1 +
x2) / 2.,
false};
2661 cout <<
"\nError in LinearInterpolation: Value ym=" <<
ym <<
" out of range (" <<
y1 <<
"|" <<
y2 <<
").\n"
2662 <<
"Will return x1. Increase window for search.\n";
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 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 void ShiftTH1F(TH1F *&, int=0)
Shift a histogram in x.
static int rcolor(unsigned int)
Translate a random number into a useful root color https://root.cern.ch/doc/master/classTColor....
static void PrintProgressBar(int, int)
Print progress bar for a loop in steps of 10 percent.
static double * gety(TH1F *)
Get array of y values for a histogram.
static string ListFiles(const char *, const char *)
Helper. Creates a list of .bin data files in data folder to be read in.
TH1F * Getwf(int)
Helper that returns the waveform histogram for a certain waveform number number.
int maxNWF
Maximum possible number of waveforms in data: number of active channels x number of events.
void Print_GetTimingCFD(float=100, float=140, int=0, int=-999, string="S", bool=true)
Plot results of GetTimingCFD()
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.
int nevents
Number of triggered events in data.
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.
void checkData() const
Primitive check to see if data has been loaded.
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.
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 tWF_CF_lo
Start of range of bins where the signal is expected for ReadRun::Shift_WFs_in_file_loop.
int nChannelsWC
Wavecatcher hardware max. number of channels (reduce/increase if not using the 64 channel crate)
void FractionEventsAboveThreshold(float=4, bool=true, bool=true, double=0., double=0., bool=false)
Find events with max/min above/below a certain threshold.
void CorrectBaselineMinSlopeRMS(vector< float >, double=0, int=2, int=3)
Baseline correction method searching for non-monotonic, rather constant regions.
void PrintBaselineCorrectionResults(float=-5, float=5, int=200)
Print histogram of the baseline correction values for all channels.
vector< float > PrintChargeSpectrum_pars
Starting values of the fit parameters for PrintChargeSpectrum()
ReadRun(int max_no_of_bin_files_to_read=0, int min_no_of_bin_files_to_read=0)
Constructor of the class.
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.
int Nevents_good()
Number of good events that are not skipped.
void ReadFile(string, bool=false, int=9, string="out.root", bool=false)
Routine to read files created by the wavecatcher.
int MaxNoOfBinFilesToRead
Number of last .bin file to be read in.
int tWF_CF_hi
End of range of bins where the signal is expected for ReadRun::Shift_WFs_in_file_loop.
int start_read_at_channel
Do analysis only for limited range of channels to reduce memory usage.
int * GetIntWindow(TH1F *, float, float, float, float, int=0)
Determine indices for integration window for peaks.
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...
float tWF_CF
Constant fraction of maximum (between ~0.1 and 1) for ReadRun::Shift_WFs_in_file_loop.
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.
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.
void GetTimingCFD(float=.3, float=100, float=140, double=0., bool=true, int=2, bool=false)
Determine the timing of the maximum peak with constant fraction discrimination.
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 IntegralFilter(vector< float >, vector< bool >, float, float, float=50, float=250, bool=false, bool=false)
Skip events with threshold on integral.
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.
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.
void CorrectBaselineMin(vector< float >, double=0, int=2, int=2)
Baseline correction using minimum sum ( mean) in range for correction.
int binNumber
Number of bins (always 1024 samples per waveform). Do not change!
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.
void SkipEventsPerChannel(vector< float >, float=0, float=0, bool=false)
Skip events above/below individual thresholds per channel.
string data_path
Path to data.
TClonesArray * rundata
Stores 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.
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.
void PlotWFHeatmaps(float=-20, float=200, int=880, string="", float=0, EColorPalette=kGistEarth)
Plot stacks of all non-skipped waveforms for all active channels.
int GetCurrentEvent(int)
Get the current event index for a certain waveform index.
int tWF_CF_bin
Time bin all events will be shifted to for ReadRun::Shift_WFs_in_file_loop Needs to be 300<"tWF_CF_bi...
virtual ~ReadRun()
Destructor.
void PlotChannelSums(bool=false, bool=false, double=0., double=0., int=2)
Plot sums of all raw waveforms for each channel.
void CorrectBaseline_function(TH1F *, float, float, int)
Helper function called by CorrectBaseline()
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.
float ** amplValuessum
Collects sums of all waveforms for each channel.
vector< int > plot_active_channels
Stores the numbers of the active channels which should be plotted.
static pair< float, bool > LinearInterpolation(float, float, float, float, float)
Simple linear interpolation for x.
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 ...
int GetCurrentChannel(int)
Get the current channel index for a certain waveform index.
int MinNoOfBinFilesToRead
Number first of .bin file to be read in.
void PrintSkippedEvents()
Prints a list of all skipped events into the terminal for diagnostics.
double * getx(double=0.)
Get array of x axis (time) for standard wavecatcher settings.
int * maxSumBin
Stores bin numbers where the sum of waveforms have their maximum.
bool Shift_WFs_in_file_loop
Shift waveforms with CFD so that all events start at the same time Call after initializing class and ...
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.