30 if (tag.
tag[0] ==
'B')
32 o << tag.
tag[0] << tag.
tag[1] << *(
short *)(tag.
tag + 2);
34 else if (tag.
tag[0] ==
'T' and tag.
tag[1] ==
'#')
36 o << tag.
tag[0] << tag.
tag[1] << *(
short *)(tag.
tag + 2);
55 o <<
"Date: " << eh.
year <<
"/" << eh.
month <<
"/" << eh.
day << endl;
56 o <<
"Hour: " << eh.
hour <<
":" << eh.
min <<
":" << eh.
sec <<
"." << eh.
ms << endl;
104 if (board < 0 or channel < 0)
106 cerr <<
"!! Error: board and channel ID number(s) must be positive integers" << endl;
110 else if (
ch_.first == board and
ch_.second == channel)
121 ch_ = {board, channel};
125 cerr <<
"!! Error: invalid channel, max channel ID number for this board is " <<
volts_[board].size() - 1 << endl;
132 ch_ = {board, channel};
135 cerr <<
"!! Error: invalid board, max board ID number is " <<
volts_.size() - 1 << endl;
153 config_.SetPedInterval(pair<int, int>{a, b},
ch_.first,
ch_.second);
157 config_.SetPedInterval(pair<int, int>{a, b});
221 cerr <<
"!! Error: select a channel using DAQEvent::GetChannel()" << endl;
227 cerr <<
"!! Error: no event read yet" << endl;
234 cerr <<
"!! Error: invalid times passed as integration window" << endl;
238 config_.
intWindow_[
ch_.first][
ch_.second].first = distance(times.begin(), lower_bound(times.begin(), times.end(), a));
241 config_.
intWindow_[
ch_.first][
ch_.second].second = distance(times.begin(), lower_bound(times.begin() + iw_first, times.end(), b));
257 cerr <<
"!! Error: no event read yet" << endl;
263 cerr <<
"!! Error: select a channel using DAQEvent::GetChannel()" << endl;
268 return any_of(volts.begin() + 2, volts.end() - 2, [](
float val)
269 { return (val < -0.499) || (val > +0.499); });
284 cerr <<
"!! Error: no event read yet" << endl;
288 (*this).EvalPedestal();
290 (*this).EvalIntegrationBounds();
299 for (
int i =
iw_.first; i <
iw_.second; ++i)
301 charge += (volts[i + 1] + volts[i] - 2 *
ped_.first) / (2 * (times[i + 1] - times[i]));
316 cerr <<
"!! Error: no event read yet" << endl;
320 (*this).EvalPedestal();
342 cerr <<
"!! Error: no event read yet" << endl;
348 cerr <<
"!! Error: select a channel using DAQEvent::GetChannel()" << endl;
352 (*this).EvalPedestal();
358 if (thr <
ped_.first)
378 auto time = times[i] + (thr - volts[i]) * (times[i + 1] - times[i]) / (volts[i + 1] - volts[i]);
395 cerr <<
"!! Error: no event read yet" << endl;
399 if (CF <= 0 or CF > 1)
401 cerr <<
"!! Error: CF value must be in range (0, 1)" << endl;
405 (*this).EvalPedestal();
410 return (*this).GetTime(thr);
422 cerr <<
"!! Error: no event read yet" << endl;
426 return (*this).GetTimeCF(0.9) - (*this).GetTimeCF(0.1);
438 cerr <<
"!! Error: no event read yet" << endl;
444 cerr <<
"!! Error: select a channel with DAQEvent::GetChannel()" << endl;
448 (*this).EvalPedestal();
465 cerr <<
"!! Error: no event read yet" << endl;
471 cerr <<
"!! Error: select a channel with DAQEvent::GetChannel()" << endl;
491 cerr <<
"!! Error: no event read yet" << endl;
497 cerr <<
"!! Error: select a channel with DAQEvent::GetChannel()" << endl;
514 cerr <<
"!! Error: no event read yet" << endl;
517 (*this).EvalPedestal();
534 cerr <<
"!! Error: no event read yet" << endl;
540 (*this).EvalPedestal();
542 (*this).EvalIntegrationBounds();
566 vector<float> ×_ij =
times_[i][j];
567 rotate(times_ij.begin(), times_ij.begin() + tCell, times_ij.end());
568 partial_sum(times_ij.begin(), times_ij.end(), times_ij.begin());
582 cerr <<
"!! Error: select a channel using DAQEvent::GetChannel()" << endl;
589 if (
routine_[0] && same_ch && same_evt)
602 const vector<float> &volts =
volts_[
ch_.first][
ch_.second];
607 ped_.second += pow(volts[i] -
ped_.first, 2);
609 ped_.second = sqrt(
ped_.second / ped_interval_dist);
623 cerr <<
"!! Error: select a channel using DAQEvent::GetChannel()" << endl;
635 if (
routine_[2] && same_ch && same_evt)
648 const vector<float> &volts =
volts_[
ch_.first][
ch_.second];
649 auto lower_bound =
ped_.first - 5 *
ped_.second;
651 if (
peak_.first < lower_bound)
653 while (volts[
iw_.first] < lower_bound and
iw_.first > 10)
677 cerr <<
"!! Error: select a channel using DAQEvent::GetChannel()" << endl;
684 if (
routine_[1] && same_ch && same_evt)
705 index_min = distance(volts.begin(), min_element(volts.begin() +
iw_.first, volts.begin() +
iw_.second));
710 index_min = distance(volts.begin() + 10, min_element(volts.begin() + 10, volts.end() - 10)) + 10;
711 bool signal, min_left, min_right, at_least;
714 signal = abs(volts[i] -
ped_.first) > 5 *
ped_.second;
715 min_left = abs(volts[i]) > abs(volts[i - 1]) +
ped_.second;
716 min_right = abs(volts[i]) > abs(volts[i + 1]) +
ped_.second;
719 at_least = abs(volts[i] -
ped_.first) > abs(volts[index_min] -
ped_.first) * 0.5;
726 if (signal and min_left and min_right and at_least)
735 { return i > index_min; });
742 index_min = distance(volts.begin() + 10, min_element(volts.begin() + 10, volts.end() - 10)) + 10;
761const string DRSEvent::type_ =
"DRS";
773const string WDBEvent::type_ =
"WDB";
807 cerr <<
"!! Error : File was not initialised, use DAQFile::Open()" << endl;
812 for (
auto &[bKey, bVal] : file.
times_)
814 for (
auto &[cKey, cVal] : bVal)
830 cout <<
"----- CONFIGURATION SETTINGS -----" << endl;
833 for (
auto &[cKey, cVal] : bVal)
835 cout <<
" - Board/Channel ID : " << bKey <<
"/" << cKey << endl
836 <<
" - Integration window : (" <<
intWindow_[bKey][cKey].first <<
", " <<
intWindow_[bKey][cKey].second <<
")" << endl
837 <<
" - Pedestal interval : (" <<
pedInterval_[bKey][cKey].first <<
", " <<
pedInterval_[bKey][cKey].second <<
")" << endl
838 <<
" - Peak threshold : " << cVal <<
" V" << endl;
852void DAQConfig::SetIntWindow(pair<int, int> intWindow,
int b,
int c)
856 cerr <<
"!! Error : Configuration class not initialised, use DAQEvent::MakeConfig()" << endl;
860 if (intWindow.first < 0 || intWindow.first > intWindow.second || intWindow.second >
SAMPLES_PER_WAVEFORM - 1)
862 cerr <<
"!! Error : Integration window has invalid value" << endl
863 <<
" Values must be in interval (0, " <<
SAMPLES_PER_WAVEFORM <<
"), passed values are ( " << intWindow.first <<
", " << intWindow.second <<
")" << endl;
876 cerr <<
"!! Error : Couldn't find board-channel of ID (" << b <<
", " << c <<
")" << endl;
888void DAQConfig::SetIntWindow(pair<int, int> intWindow)
892 cerr <<
"!! Error : Configuration class not initialised, use DAQEvent::MakeConfig()" << endl;
896 if (intWindow.first < 0 || intWindow.first > intWindow.second || intWindow.second >
SAMPLES_PER_WAVEFORM - 1)
898 cerr <<
"!! Error : Integration window has invalid value" << endl
899 <<
" Values must be in interval (0, " <<
SAMPLES_PER_WAVEFORM <<
"), passed values are ( " << intWindow.first <<
", " << intWindow.second <<
")" << endl;
905 for (
auto &[cKey, cVal] : bVal)
922void DAQConfig::SetPedInterval(pair<int, int> pedInterval,
int b,
int c)
926 cerr <<
"!! Error : Configuration class not initialised, use DAQEvent::MakeConfig()" << endl;
930 if (pedInterval.first < 0 || pedInterval.first > pedInterval.second || pedInterval.second >
SAMPLES_PER_WAVEFORM - 1)
932 cerr <<
"!! Error : Pedestal interval has invalid value" << endl
933 <<
" Values must be in interval (0, " <<
SAMPLES_PER_WAVEFORM <<
"), passed values are ( " << pedInterval.first <<
", " << pedInterval.second <<
")" << endl;
945 cerr <<
"!! Error : Couldn't find board-channel of ID (" << b <<
", " << c <<
")" << endl;
956void DAQConfig::SetPedInterval(pair<int, int> pedInterval)
960 cerr <<
"!! Error : Configuration class not initialised, use DAQEvent::MakeConfig()" << endl;
964 if (pedInterval.first < 0 || pedInterval.first > pedInterval.second || pedInterval.second >
SAMPLES_PER_WAVEFORM - 1)
966 cerr <<
"!! Error : Pedestal interval has invalid value" << endl
967 <<
" Values must be in interval (0, " <<
SAMPLES_PER_WAVEFORM <<
"), passed values are ( " << pedInterval.first <<
", " << pedInterval.second <<
")";
973 for (
auto &[cKey, cVal] : bVal)
993 cerr <<
"!! Error : Configuration class not initialised, use DAQEvent::MakeConfig()" << endl;
997 if (thr < -0.5 || thr > +0.5)
999 cerr <<
"!! Error : Peak threshold has invalid value" << endl
1000 <<
" Values must be in interval (-0.5, +0.5), passed values is " << thr << endl;
1012 cerr <<
"!! Error : Couldn't find board-channel of ID (" << b <<
", " << c <<
")" << endl;
1027 cerr <<
"!! Error : Configuration class not initialised, use DAQEvent::MakeConfig()" << endl;
1031 if (thr < -0.5 || thr > +0.5)
1033 cerr <<
"!! Error : Peak threshold has invalid value" << endl
1034 <<
" Values must be in interval (-0.5, +0.5), passed values is " << thr << endl;
1038 for (
auto &[bKey, bVal] :
peakThr_)
1040 for (
auto &[cKey, cVal] : bVal)
1059 std::cout <<
"Created DAQFile, open a file using DAQFile::Open()" << endl;
1072 in_.open(fname, std::ios::in | std::ios::binary);
1073 std::cout <<
"Created DAQFile, opened file " << fname << std::endl;
1076 (*this).Initialise();
1090 cerr <<
"!! Error: file not open --> use DAQFile(filename)" << endl;
1102 cout <<
"Initializing file " <<
filename_ << endl;
1105 if (bTag.
tag[0] ==
'D' && bTag.
tag[1] ==
'R' && bTag.
tag[2] ==
'S')
1108 if (bTag.tag[3] ==
'8')
1110 cout <<
" --> WaveDREAM Board" << endl;
1115 cout <<
" --> DRS Evaluation Board" << endl;
1120 else if (strcmp(bTag.
tag,
"TIME") == 0)
1122 cout <<
"LAB-DRS" << endl;
1128 cerr <<
"!! Error: invalid file header --> expected \"DRS\", found " << bTag << endl;
1129 cerr <<
"Initialisation failed" << endl;
1132 if (strcmp(bTag.
tag,
"TIME") != 0)
1134 cerr <<
"!! Error: invalid time header --> expected \"TIME\", found " << cTag << endl;
1135 cerr <<
"Initialisation failed" << endl;
1141 while (file >> bTag)
1143 cout << bTag <<
":" << endl;
1145 while (file >> cTag)
1147 cout <<
" --> " << cTag << endl;
1172 cout <<
"Closing file " <<
filename_ <<
"..." << endl;
1177 cout <<
"File is already closed" << endl;
1193 in_.open(fname, std::ios::in | std::ios::binary);
1194 std::cout << std::endl
1195 <<
"Created DAQFile, opened file " << fname << std::endl;
1201 std::cerr <<
"!! Error: File is already opened --> " <<
filename_ << std::endl;
1217 cerr <<
"Warning: file is not initialised. Nothing to reset..." << endl;
1248 while (strcmp(tag.
tag,
"EHDR") != 0)
1253 next_evt_pos =
in_.tellg();
1255 cout <<
"Event size: " << evt_size << endl;
1259 file_size =
in_.tellg();
1267 cerr <<
"!! Error : Invalid position reached, out of bounds of file" << endl
1268 <<
"Reset position to first event header..." << endl;
1273 cout <<
"Moving to event: " << evt_id << endl;
1275 evt_id_pos =
in_.tellg();
1278 in_.seekg(evt_id_pos);
1336 if (
type_ != event.type_)
1338 cerr <<
"!! Error: Invalid type of class used" << endl
1339 <<
"Type expected: " <<
type_ << endl
1340 <<
"Event given: " <<
event.type_ << endl;
1346 cout <<
"Autocall to: DAQEvent::MakeConfig()...";
1347 event.MakeConfig(*
this);
1348 cout <<
" Done!" << endl;
1352 TAG bTag, cTag, tag;
1360 cout <<
"Event serial number: " <<
event.eh_.serialNumber << endl;
1363 event.is_init_ =
true;
1364 event.routine_ = {
false,
false,
false};
1366 while (file >> bTag)
1369 auto tCell = *(
unsigned short *)(tag.tag + 2);
1371 while (file >> cTag)
1378 event.volts_[i][j] = volts;
1379 event.TimeCalibration(tCell,
times_[i][j], i, j);
1407 if (
type_ != event.type_)
1409 cerr <<
"!! Error: Invalid type of class used" << endl
1410 <<
"Type expected: " <<
type_ << endl
1411 <<
"Event given: " <<
event.type_ << endl;
1417 cout <<
"Autocall to: DAQEvent::MakeConfig()...";
1418 event.MakeConfig(*
this);
1419 cout <<
" Done!" << endl;
1423 TAG bTag, cTag, tag;
1431 cout <<
"Event serial number: " <<
event.eh_.serialNumber << endl;
1434 event.is_init_ =
true;
1435 event.routine_ = {
false,
false,
false};
1437 while (file >> bTag)
1440 while (file >> cTag)
1444 auto tCell = *(
unsigned short *)(tag.tag + 2);
1446 event.volts_[i][j] = volts;
1447 event.TimeCalibration(tCell,
times_[i][j], i, j);
1476 in_.read((
char *)&eh,
sizeof(eh));
1487 for (
int i = 0; i < vec.size(); ++i)
1489 in_.read((
char *)&vec.at(i),
sizeof(
float));
1502void DAQFile::Read(vector<float> &vec,
const unsigned short &range_center)
1505 for (
int i = 0; i < vec.size(); ++i)
1507 in_.read((
char *)&val,
sizeof(
unsigned short));
1508 vec[i] = val / 65536. + range_center / 1000. - 0.5;
1523DAQFile::operator bool()
1525 map<char, char> header{{
'E',
'B'}, {
'B',
'C'}, {
'C',
'B'}};
1528 cout <<
"End of file reached" << endl;
1531 else if (n_ ==
'T' or n_ ==
'D')
1535 else if (n_ == header[o_])
1540 else if (n_ ==
'E' and initialization_ == 0)
1542 cout <<
"Initialization done --> EHDR next" << endl;
1543 initialization_ = 1;
std::map< int, std::map< int, float > > peakThr_
Data member to hold peak threshold values of various channels.
void MakeConfig(DAQFile &)
Initialise the configuration class with the default values for any board and any channel.
bool is_makeconfig_
Flag to check if the method DAQConfig::MakeConfig() has been called at least once.
void ShowConfig()
Simple method to print on stream the current settings of the class.
std::map< int, std::map< int, std::pair< int, int > > > intWindow_
Data member to hold integration windows intervals of various channels.
std::map< int, std::map< int, std::pair< int, int > > > pedInterval_
Data member to hold pedestal intervals of various channels.
std::map< int, std::map< int, bool > > user_iw_
Data member to hold which integration windows were set by the user.
void SetPeakThr(float, int, int)
Method to set the peak threshold given the peak threshold in Volts and the board/channel IDs.
DAQConfig()
Construct a new DAQConfig::DAQConfig object.
Main class to store voltage and time values.
void SetPeakThr(float)
Set the threshold in volt by the user.
bool is_iw_
Flag to check if integration window has been evaluated once.
DAQConfig config_
Class to hold settings about pedestal and integration window intervals.
MAP volts_
Structure to hold voltage values of all boards and channels.
void SetPedInterval(int, int)
Function to set the interval where to perform pedestal evaluation.
std::pair< float, float > ped_
Pair to hold pedestal mean and pedestal std.dev..
const std::vector< float > & GetTimes()
Getter method read-only for the waveform's times selected.
DAQEvent & EvalPedestal()
Method to evaluate the pedestal of the currently selected waveform.
DAQEvent & TimeCalibration(const unsigned short &, const std::vector< float > &, int, int)
Function to perform the time calibration.
const std::pair< float, float > & GetPedestal()
Getter method read-only for the attribute DAQEvent::ped_.
std::pair< int, int > iw_
Pair to hold indices as boundary edges where integration is performed by DAQEvent::GetCharge().
bool is_init_
Flag to check if the file is initialised.
std::pair< int, int > ch_old_
Pair to store last channel on which routines were made.
DAQEvent()
Construct a new DAQEvent() object.
std::pair< int, int > ch_
Pair to hold indices of board and channel selected;.
float GetRiseTime()
Evaluate the risetime of the waveform.
const std::pair< int, int > & GetIntegrationBounds()
unsigned int evtserial_old_
Value to store last event read.
bool is_ped_
Flag to check if pedestal has been evaluated once.
float GetTimeCF(float)
Find the time at which the waveform goes under a given percentage of the waveform peak value.
float GetTime(float)
Find the time at which the waveform goes under a given threshold level.
DAQEvent & EvalIntegrationBounds()
Method to evaluate the integration window of the currently selected waveform.
float peak_threshold_
Value to store the threshold in volts passed by the user.
float GetCharge()
Method to evaluate charge in the integration region.
const std::vector< float > & GetVolts()
Getter method read-only for the waveform's voltages selected.
std::pair< float, float > peak_
Pair to hold value of voltage and time at the peak.
bool IsSaturated()
Check if in the selected channel there is (or not) saturation.
DAQEvent & FindPeaks()
Method to find peaks in the integration window.
std::vector< int > indexMin_
Indices of local minima found.
std::pair< int, int > ped_interval_
Pair to hold indices as boundary edges where pedestal is evaluated.
void SetIntWindow(int, int)
Set the integration window passing two indices that go from 0 to SAMPLES_PER_WAVEFORM.
DAQEvent & GetChannel(const int &, const int &)
Select the channel to analyze.
const std::vector< int > & GetPeakIndices()
bool is_getch_
Flag to check if the method DAQEvent::GetChannel() has been called.
std::vector< bool > routine_
bool is_peak_
Flag to check if peaks have been found once.
MAP times_
Structure to hold integrated times values of all boards and channels.
float GetAmplitude()
Method to evaluate amplitude in the integration region.
Class to manage the file and the outputing of data in a DAQEvent instance.
bool initialization_
Flag to store if DAQFile::Initialise() was already called.
std::string type_
Flag to store the type of the board.
DAQFile & Reset()
Method to reset the file.
char o_
The initial letter of the previous tag read.
std::string filename_
The name of the file.
char n_
The initial letter of the newest tag read.
bool is_lab_
Flag to check if the board is from LAB or not.
DAQFile()
Construct a new DAQFile::DAQFile object.
DAQFile & GetEvent(int)
Method to select what event must be read next.
DAQFile & Open(const std::string &)
Method to open a file given the file path and name.
DAQFile & Close()
Method to close the file.
MAP times_
Struct to hold read from the TIMEpart of the file.
void Read(TAG &)
Read a tag.
bool operator>>(DRSEvent &)
Read into a DRSEvent.
DAQFile & Initialise()
Initialise the file reading the TIME block.
int first_evt_pos_
Position of first event header.
std::ifstream in_
The input file to read.
Specialization of DAQEvent to a DRS board.
Specialization of DAQEvent to a WaveDREAM board.
ostream & operator<<(ostream &o, const TAG &tag)
Function to print a TAG istance easily on stream::cout.
Declaration of classes and methods.
#define SAMPLES_PER_WAVEFORM
The number of samples made by the waveforms, both DRS and WDB.
5 char long word ended with '\0' for simple printing.
char tag[5]
The array of char.