64 #include "TRestRawSignalEvent.h"
68 #include "TRestStringHelper.h"
74 TRestRawSignalEvent::TRestRawSignalEvent() {
79 TRestRawSignalEvent::~TRestRawSignalEvent() {
89 fMinValue = numeric_limits<Double_t>::max();
90 fMaxValue = numeric_limits<Double_t>::min();
91 fMinTime = numeric_limits<Double_t>::max();
92 fMaxTime = numeric_limits<Double_t>::min();
98 <<
" already exists. Signal will not be added to signal event" << endl;
105 fSignal.emplace_back(s);
108 void TRestRawSignalEvent::RemoveSignalWithId(Int_t sId) {
109 Int_t index = GetSignalIndex(sId);
112 cout <<
"Warning. Signal ID : " << sId
113 <<
" does not exist. Signal will not be removed from signal event" << endl;
117 fSignal.erase(fSignal.begin() + index);
120 Int_t TRestRawSignalEvent::GetSignalIndex(Int_t signalID) {
121 for (
int i = 0; i < GetNumberOfSignals(); i++)
122 if (fSignal[i].GetSignalID() == signalID)
return i;
126 Double_t TRestRawSignalEvent::GetIntegral() {
129 for (
int i = 0; i < GetNumberOfSignals(); i++) sum += fSignal[i].GetIntegral();
138 for (
int i = 0; i < GetNumberOfSignals(); i++) sum += fSignal[i].GetThresholdIntegral();
143 if (GetNumberOfSignals() <= 0)
return nullptr;
148 for (
int i = 0; i < GetNumberOfSignals(); i++) {
149 Int_t integ = fSignal[i].GetIntegral();
156 return &fSignal[sId];
159 Double_t TRestRawSignalEvent::GetSlopeIntegral() {
162 for (
int i = 0; i < GetNumberOfSignals(); i++) sum += fSignal[i].GetSlopeIntegral();
167 Double_t TRestRawSignalEvent::GetRiseSlope() {
171 for (
int i = 0; i < GetNumberOfSignals(); i++) {
172 if (fSignal[i].GetThresholdIntegral() > 0) {
173 sum += fSignal[i].GetSlopeIntegral();
178 if (n == 0)
return 0;
183 Double_t TRestRawSignalEvent::GetRiseTime() {
187 for (
int i = 0; i < GetNumberOfSignals(); i++) {
188 if (fSignal[i].GetThresholdIntegral() > 0) {
189 sum += fSignal[i].GetRiseTime();
194 if (n == 0)
return 0;
199 Double_t TRestRawSignalEvent::GetTripleMaxIntegral() {
202 for (
int i = 0; i < GetNumberOfSignals(); i++)
203 if (fSignal[i].GetThresholdIntegral() > 0) sum += fSignal[i].GetTripleMaxIntegral();
208 Double_t TRestRawSignalEvent::GetBaseLineAverage() {
209 Double_t baseLineMean = 0;
211 for (
int signal = 0; signal < GetNumberOfSignals(); signal++) {
212 Double_t baseline = GetSignal(signal)->GetBaseLine();
213 baseLineMean += baseline;
216 return baseLineMean / GetNumberOfSignals();
219 Int_t TRestRawSignalEvent::GetLowestWidth(Double_t minPeakAmplitude) {
220 Int_t low = 10000000;
222 for (
int signal = 0; signal < GetNumberOfSignals(); signal++) {
223 if (GetSignal(signal)->GetMaxPeakValue() > minPeakAmplitude) {
224 Int_t lW = GetSignal(signal)->GetMaxPeakWidth();
225 if (low > lW) low = lW;
232 Double_t TRestRawSignalEvent::GetAverageWidth(Double_t minPeakAmplitude) {
235 for (
int signal = 0; signal < GetNumberOfSignals(); signal++) {
236 if (GetSignal(signal)->GetMaxPeakValue() > minPeakAmplitude) {
237 avg += GetSignal(signal)->GetMaxPeakWidth();
248 Double_t TRestRawSignalEvent::GetLowAverageWidth(Int_t nSignals, Double_t minPeakAmplitude) {
249 std::vector<Double_t> widths;
251 for (
int signal = 0; signal < GetNumberOfSignals(); signal++)
252 if (GetSignal(signal)->GetMaxPeakValue() > minPeakAmplitude)
253 widths.push_back(GetSignal(signal)->GetMaxPeakWidth());
255 if (widths.size() == 0)
return 0;
257 std::sort(widths.begin(), widths.end());
259 Int_t nMax = nSignals;
260 if (widths.size() < (
unsigned int)nSignals) nMax = widths.size();
263 for (
int n = 0; n < nMax; n++) avg += widths[n];
265 return avg / nSignals;
268 Double_t TRestRawSignalEvent::GetBaseLineSigmaAverage() {
269 Double_t baseLineSigmaMean = 0;
271 for (
int signal = 0; signal < GetNumberOfSignals(); signal++) {
272 Double_t baselineSigma = GetSignal(signal)->GetBaseLineSigma();
273 baseLineSigmaMean += baselineSigma;
276 return baseLineSigmaMean / GetNumberOfSignals();
290 Int_t signalIndex = GetSignalIndex(signalID);
291 if (signalIndex == -1) {
292 signalIndex = GetNumberOfSignals();
299 fSignal[signalIndex].IncreaseBinBy(bin, value);
302 void TRestRawSignalEvent::PrintEvent() {
305 for (
int i = 0; i < GetNumberOfSignals(); i++) {
306 cout <<
"================================================" << endl;
307 cout <<
"Signal ID : " << fSignal[i].GetSignalID() << endl;
308 cout <<
"Integral : " << fSignal[i].GetIntegral() << endl;
309 cout <<
"------------------------------------------------" << endl;
311 cout <<
"================================================" << endl;
317 void TRestRawSignalEvent::SetMaxAndMin() {
318 fMinValue = numeric_limits<Double_t>::max();
319 fMaxValue = numeric_limits<Double_t>::min();
320 fMinTime = numeric_limits<Double_t>::max();
321 fMaxTime = numeric_limits<Double_t>::min();
323 for (
int s = 0; s < GetNumberOfSignals(); s++) {
324 if (fMinValue > fSignal[s].GetMinValue()) {
325 fMinValue = fSignal[s].GetMinValue();
327 if (fMaxValue < fSignal[s].GetMaxValue()) {
328 fMaxValue = fSignal[s].GetMaxValue();
332 if (GetNumberOfSignals() > 0) {
333 fMaxTime = fSignal[0].GetNumberOfPoints();
337 Double_t TRestRawSignalEvent::GetMaxValue() {
342 Double_t TRestRawSignalEvent::GetMinValue() {
347 Double_t TRestRawSignalEvent::GetMinTime() {
return 0; }
349 Double_t TRestRawSignalEvent::GetMaxTime() {
350 Double_t maxTime = 512;
352 if (GetNumberOfSignals() > 0) maxTime = fSignal[0].GetNumberOfPoints();
358 Double_t fAuxiliar = 0;
359 void TRestRawSignalEvent::SetAuxiliar(Double_t aux) { fAuxiliar = aux; }
360 auto GetAuxiliar() {
return fAuxiliar; }
414 const int nSignals = GetNumberOfSignals();
416 if (fPad !=
nullptr) {
422 cout <<
"Empty event " << endl;
426 fMinValue = numeric_limits<Double_t>::max();
427 fMaxValue = numeric_limits<Double_t>::min();
428 fMinTime = numeric_limits<Double_t>::max();
429 fMaxTime = numeric_limits<Double_t>::min();
431 fPad =
new TPad(GetName(),
" ", 0, 0, 1, 1);
439 bool thresholdCheck =
false;
440 bool baselineCheck =
false;
441 bool sRangeID =
false;
442 bool printIDs =
false;
444 double signalTh = 0, pointTh = 0, nOver = 0;
445 int baseLineRangeInit = 0, baseLineRangeEnd = 0;
446 int sRangeInit = 0, sRangeEnd = 0;
448 for (
const auto& opt : optList) {
449 std::string str = (std::string)opt;
451 if (str.find(
"onlyGoodSignals[") != string::npos) {
452 size_t startPos = str.find(
'[');
453 size_t endPos = str.find(
']');
454 TString tmpStr = opt(startPos + 1, endPos - startPos - 1);
455 vector<TString> optList_2 = Vector_cast<string, TString>(
Split((
string)tmpStr,
","));
461 thresholdCheck =
true;
465 if (str.find(
"baseLineRange[") != string::npos) {
466 size_t startPos2 = str.find(
'[');
467 size_t endPos2 = str.find(
']');
468 TString tmpStr2 = opt(startPos2 + 1, endPos2 - startPos2 - 1);
469 vector<TString> optList_3 = Vector_cast<string, TString>(
Split((
string)tmpStr2,
","));
474 baselineCheck =
true;
478 if (str.find(
"signalRangeID[") != string::npos || str.find(
"ids[") != string::npos) {
479 size_t startPos3 = str.find(
'[');
480 size_t endPos3 = str.find(
']');
481 TString tmpStr3 = opt(startPos3 + 1, endPos3 - startPos3 - 1);
482 vector<TString> optList_4;
483 if (str.find(
',') != string::npos)
484 optList_4 = Vector_cast<string, TString>(
Split((
string)tmpStr3,
","));
485 else if (str.find(
'-') != string::npos)
486 optList_4 = Vector_cast<string, TString>(
Split((
string)tmpStr3,
"-"));
488 RESTError <<
"TRestRawSignalEvent::DrawEvent not valid ids format!" << RESTendl;
497 if (str.find(
"printIDs") != string::npos) {
499 cout <<
"IDs of printed signals: " << endl;
503 std::vector<int> signalIDs;
506 if ((optList.empty()) || !(
isANumber((
string)optList[0]))) {
508 if (thresholdCheck && baselineCheck) {
509 RESTDebug <<
"Draw only good signals with: " << RESTendl;
510 RESTDebug <<
" Signal threshold: " << signalTh << RESTendl;
511 RESTDebug <<
" Point threshold: " << pointTh << RESTendl;
512 RESTDebug <<
" Points over threshold: " << nOver << RESTendl;
513 RESTDebug <<
" Base line range: (" << baseLineRangeInit <<
"," << baseLineRangeEnd <<
")"
516 for (
int n = 0; n < nSignals; n++) {
517 fSignal[n].CalculateBaseLine(baseLineRangeInit, baseLineRangeEnd);
518 fSignal[n].InitializePointsOverThreshold(TVector2(pointTh, signalTh), nOver);
519 if (fSignal[n].GetPointsOverThreshold().size() >= 2) {
520 signalIDs.push_back(fSignal[n].GetID());
525 for (
int n = 0; n < nSignals; n++) {
526 signalIDs.push_back(fSignal[n].GetID());
532 for (
auto it = signalIDs.begin(); it != signalIDs.end();)
533 if (*it >= sRangeInit && *it <= sRangeEnd) {
536 it = signalIDs.erase(it);
540 cout <<
"Number of drawn signals: " << signalIDs.size() << endl;
543 }
else if (
isANumber((
string)optList[0])) {
544 string str = (string)optList[0];
545 size_t separation = str.find(
'-');
548 if (separation != string::npos) {
549 TString firstSignal = optList[0](0, separation);
550 TString lastSignal = optList[0](separation + 1, str.size());
551 RESTDebug <<
"First signal: " << firstSignal << RESTendl;
552 RESTDebug <<
"Last signal: " << lastSignal << RESTendl;
555 fPad->SetTitle(
"No Such Signal");
556 cout <<
"No such last signal" << endl;
560 sprintf(title,
"Event ID %d", this->GetID());
562 if (thresholdCheck && baselineCheck) {
563 RESTDebug <<
"Draw only good signals with: " << RESTendl;
564 RESTDebug <<
" Signal threshold: " << signalTh << RESTendl;
565 RESTDebug <<
" Point threshold: " << pointTh << RESTendl;
566 RESTDebug <<
" Points over threshold: " << nOver << RESTendl;
567 RESTDebug <<
" Base line range: (" << baseLineRangeInit <<
"," << baseLineRangeEnd <<
")"
570 for (
int n = 0; n < nSignals; n++) {
573 fSignal[n].CalculateBaseLine(baseLineRangeInit, baseLineRangeEnd);
574 fSignal[n].InitializePointsOverThreshold(TVector2(pointTh, signalTh), nOver);
575 if (fSignal[n].GetPointsOverThreshold().size() >= 2) {
576 signalIDs.push_back(fSignal[n].GetID());
579 cout <<
"Number of good signals in range (" << firstSignal <<
"," << lastSignal
580 <<
"): " << signalIDs.size() << endl;
585 signalIDs.push_back(fSignal[n].GetID());
591 signalIDs.push_back(signalID);
595 if (signalIDs.empty()) {
596 fPad->SetTitle(
"No Such Signal");
597 cout <<
"No signals found" << endl;
602 cout <<
"SignalIDs:";
603 auto sortedSignalsIDs = signalIDs;
604 sort(sortedSignalsIDs.begin(), sortedSignalsIDs.end());
605 for (
const auto& signalID : sortedSignalsIDs) {
606 cout <<
" " << signalID;
611 DrawSignals(fPad, signalIDs);
622 int max = numeric_limits<Short_t>::min();
625 for (
const auto& s : signals) {
630 TGraph* graph = signal->
GetGraph(graphIndex++);
631 const double maxValue = TMath::MaxElement(graph->GetN(), graph->GetY());
632 if (maxValue > max) {
638 RESTDebug <<
"Max SID " << maxSID << RESTendl;
641 cout <<
"No signals ID found" << endl;
646 std::string title =
"Event ID " + std::to_string(GetID());
647 if (signals.size() == 1) {
648 title +=
" Signal ID " + std::to_string(maxSID);
651 signalMaxID->
fGraph->SetTitle(title.c_str());
652 signalMaxID->
fGraph->GetXaxis()->SetTitle(
"Time bin");
653 signalMaxID->
fGraph->GetYaxis()->SetTitleOffset(1.4);
654 signalMaxID->
fGraph->GetYaxis()->SetTitle(
"Amplitude [a.u.]");
657 signalMaxID->
fGraph->SetLineColor(kBlack);
658 signalMaxID->
fGraph->Draw(
"AL");
660 for (
const auto& signalID : signals) {
661 if (signalID == maxSID) {
666 signal->
fGraph->Draw(
"L");
693 int nSignals = this->GetNumberOfSignals();
695 if (fPad !=
nullptr) {
696 for (
int n = 0; n < nSignals; n++) {
697 delete fSignal[n].fGraph;
698 fSignal[n].fGraph =
nullptr;
705 cout <<
"Empty event " << endl;
711 double signalTh = 0, pointTh = 0, nOver = 0;
712 int baseLineRangeInit = 0, baseLineRangeEnd = 0;
714 for (
auto& opt : optList) {
715 string str = (string)opt;
718 size_t goodSigOpt = str.find(
"goodSignals[");
720 if (goodSigOpt != string::npos) {
721 size_t startPos = str.find(
'[');
722 size_t endPos = str.find(
']');
723 TString tmpStr = opt(startPos + 1, endPos - startPos - 1);
724 vector<TString> optList_2 = Vector_cast<string, TString>(
Split((
string)tmpStr,
","));
732 size_t BLOpt = str.find(
"baseLineRange[");
734 if (BLOpt != string::npos) {
735 size_t startPos2 = str.find(
'[');
736 size_t endPos2 = str.find(
']');
737 TString tmpStr2 = opt(startPos2 + 1, endPos2 - startPos2 - 1);
738 vector<TString> optList_3 = Vector_cast<string, TString>(
Split((
string)tmpStr2,
","));
745 fPad =
new TPad(this->GetName(),
" ", 0, 0, 1, 1);
749 TGraph* gr =
new TGraph();
755 RESTInfo <<
"Drawing signalID. Event ID : " << this->GetID() <<
" Signal ID : " << signal->
GetID()
759 gr->SetPoint(n, n, signal->
GetData(n));
764 TGraph* gr2 =
new TGraph();
766 gr2->SetLineWidth(2);
767 gr2->SetLineColor(2);
769 for (
int n = baseLineRangeInit; n < baseLineRangeEnd; n++) {
770 gr2->SetPoint(n - baseLineRangeInit, n, signal->
GetData(n));
779 gr3[nGraphs] =
new TGraph();
780 gr3[nGraphs]->SetLineWidth(2);
781 gr3[nGraphs]->SetLineColor(3);
783 Int_t nPoints = pOver.size();
784 for (
int n = 0; n < nPoints; n++) {
785 gr3[nGraphs]->SetPoint(point, pOver[n], signal->
GetData(pOver[n]));
787 if (n + 1 < nPoints && pOver[n + 1] - pOver[n] > 1) {
788 gr3[nGraphs]->Draw(
"CP");
790 if (nGraphs > 4) cout <<
"Ngraphs : " << nGraphs << endl;
792 gr3[nGraphs] =
new TGraph();
793 gr3[nGraphs]->SetLineWidth(2);
794 gr3[nGraphs]->SetLineColor(3);
799 gr3[nGraphs]->Draw(
"CP");
806 if (fRun ==
nullptr) {
807 RESTError <<
"TRestRawSignalEvent::GetReadoutMetadata: fRun is nullptr" << RESTendl;
814 return GetSignalEventForTypes({type});
822 auto metadata = readoutMetadata ? readoutMetadata : GetReadoutMetadata();
823 if (metadata ==
nullptr) {
827 for (
const auto& signal : fSignal) {
829 types.find(metadata->GetTypeForChannelDaqId(signal.GetSignalID())) != types.end()) {
A base class for any REST event.
void SetEventInfo(TRestEvent *eve)
virtual void PrintEvent() const
virtual void Initialize()=0
An event container for time rawdata signals with fixed length.
void DrawSignals(TPad *pad, const std::vector< Int_t > &signals)
This method draws selected signal IDs, given by the vector passed as reference.
TPad * DrawEvent(const TString &option="")
This method draws current raw signal event in a TPad.
TPad * DrawSignal(Int_t signalID, const TString &option="")
This method draws selected signalID by ID, with baseline range and points over threshold highlighted.
void AddChargeToSignal(Int_t sgnlID, Int_t bin, Short_t value)
Double_t GetThresholdIntegral()
It defines a Short_t array with a physical parameter that evolves in time using a fixed time bin.
Int_t GetID() const
Returns the value of signal ID.
TGraph * fGraph
A TGraph pointer used to store the TRestRawSignal drawing.
void CalculateBaseLine(Int_t startBin, Int_t endBin, const std::string &option="")
This method calculates the average and fluctuation of the baseline in the specified range and writes ...
void SetSignalID(Int_t sID)
It sets the id number of the signal.
void InitializePointsOverThreshold(const TVector2 &thrPar, Int_t nPointsOver, Int_t nPointsFlat=512)
It initializes the fPointsOverThreshold array with the indexes of data points that are found over thr...
std::vector< Int_t > GetPointsOverThreshold() const
Returns a std::vector containing the indexes of data points over threshold.
Double_t GetData(Int_t n) const
It returns the data value of point n including baseline correction.
Double_t GetIntegral()
It returns the integral of points found in the region defined by fRange. If fRange was not defined th...
TGraph * GetGraph(Int_t color=1)
It builds a TGraph object that can be used for drawing.
Int_t GetSignalID() const
Returns the value of signal ID.
void SetRange(const TVector2 &range)
It sets/constrains the range for any calculation.
Int_t GetNumberOfPoints() const
Returns the actual number of points, or size of the signal.
std::vector< std::string > Split(std::string in, std::string separator, bool allowBlankString=false, bool removeWhiteSpaces=false, int startPos=-1)
Split the input string according to the given separator. Returning a vector of fragments.
Double_t StringToDouble(std::string in)
Gets a double from a string.
Int_t StringToInteger(std::string in)
Gets an integer from a string.
Int_t isANumber(std::string in)
Returns 1 only if a valid number is found in the string in. If not it returns 0.