118#include "TRestRawSignalEvent.h"
122#include "TRestStringHelper.h"
128TRestRawSignalEvent::TRestRawSignalEvent() {
133TRestRawSignalEvent::~TRestRawSignalEvent() {
143 fMinValue = numeric_limits<Double_t>::max();
144 fMaxValue = numeric_limits<Double_t>::min();
145 fMinTime = numeric_limits<Double_t>::max();
146 fMaxTime = numeric_limits<Double_t>::min();
152 <<
" already exists. Signal will not be added to signal event" << endl;
159 fSignal.emplace_back(s);
162void TRestRawSignalEvent::RemoveSignalWithId(Int_t sId) {
163 Int_t index = GetSignalIndex(sId);
166 cout <<
"Warning. Signal ID : " << sId
167 <<
" does not exist. Signal will not be removed from signal event" << endl;
171 fSignal.erase(fSignal.begin() + index);
174Int_t TRestRawSignalEvent::GetSignalIndex(Int_t signalID) {
175 for (
int i = 0; i < GetNumberOfSignals(); i++)
176 if (fSignal[i].GetSignalID() == signalID)
return i;
180Double_t TRestRawSignalEvent::GetIntegral() {
183 for (
int i = 0; i < GetNumberOfSignals(); i++) sum += fSignal[i].GetIntegral();
197 if (GetNumberOfSignals() <= 0)
return nullptr;
199 Double_t max = fSignal[0].GetIntegral();
202 for (
int i = 0; i < GetNumberOfSignals(); i++) {
203 Int_t integ = fSignal[i].GetIntegral();
210 return &fSignal[sId];
213Double_t TRestRawSignalEvent::GetSlopeIntegral() {
216 for (
int i = 0; i < GetNumberOfSignals(); i++) sum += fSignal[i].GetSlopeIntegral();
221Double_t TRestRawSignalEvent::GetRiseSlope() {
225 for (
int i = 0; i < GetNumberOfSignals(); i++) {
227 sum += fSignal[i].GetSlopeIntegral();
232 if (n == 0)
return 0;
237Double_t TRestRawSignalEvent::GetRiseTime() {
241 for (
int i = 0; i < GetNumberOfSignals(); i++) {
243 sum += fSignal[i].GetRiseTime();
248 if (n == 0)
return 0;
253Double_t TRestRawSignalEvent::GetTripleMaxIntegral() {
256 for (
int i = 0; i < GetNumberOfSignals(); i++)
262Double_t TRestRawSignalEvent::GetBaseLineAverage() {
263 Double_t baseLineMean = 0;
265 for (
int signal = 0; signal < GetNumberOfSignals(); signal++) {
266 Double_t baseline = GetSignal(signal)->
GetBaseLine();
267 baseLineMean += baseline;
270 return baseLineMean / GetNumberOfSignals();
273Int_t TRestRawSignalEvent::GetLowestWidth(Double_t minPeakAmplitude) {
274 Int_t low = 10000000;
276 for (
int signal = 0; signal < GetNumberOfSignals(); signal++) {
279 if (low > lW) low = lW;
286Double_t TRestRawSignalEvent::GetAverageWidth(Double_t minPeakAmplitude) {
289 for (
int signal = 0; signal < GetNumberOfSignals(); signal++) {
302Double_t TRestRawSignalEvent::GetLowAverageWidth(Int_t nSignals, Double_t minPeakAmplitude) {
303 std::vector<Double_t> widths;
305 for (
int signal = 0; signal < GetNumberOfSignals(); signal++)
309 if (widths.size() == 0)
return 0;
311 std::sort(widths.begin(), widths.end());
313 Int_t nMax = nSignals;
314 if (widths.size() < (
unsigned int)nSignals) nMax = widths.size();
317 for (
int n = 0; n < nMax; n++) avg += widths[n];
319 return avg / nSignals;
322Double_t TRestRawSignalEvent::GetBaseLineSigmaAverage() {
323 Double_t baseLineSigmaMean = 0;
325 for (
int signal = 0; signal < GetNumberOfSignals(); signal++) {
327 baseLineSigmaMean += baselineSigma;
330 return baseLineSigmaMean / GetNumberOfSignals();
344 Int_t signalIndex = GetSignalIndex(signalID);
345 if (signalIndex == -1) {
346 signalIndex = GetNumberOfSignals();
353 fSignal[signalIndex].IncreaseBinBy(bin, value);
356void TRestRawSignalEvent::PrintEvent() {
359 for (
int i = 0; i < GetNumberOfSignals(); i++) {
360 cout <<
"================================================" << endl;
361 cout <<
"Signal ID : " << fSignal[i].GetSignalID() << endl;
362 cout <<
"Integral : " << fSignal[i].GetIntegral() << endl;
363 cout <<
"------------------------------------------------" << endl;
365 cout <<
"================================================" << endl;
371void TRestRawSignalEvent::SetMaxAndMin() {
372 fMinValue = numeric_limits<Double_t>::max();
373 fMaxValue = numeric_limits<Double_t>::min();
374 fMinTime = numeric_limits<Double_t>::max();
375 fMaxTime = numeric_limits<Double_t>::min();
377 for (
int s = 0; s < GetNumberOfSignals(); s++) {
378 if (fMinValue > fSignal[s].GetMinValue()) {
379 fMinValue = fSignal[s].GetMinValue();
381 if (fMaxValue < fSignal[s].GetMaxValue()) {
382 fMaxValue = fSignal[s].GetMaxValue();
386 if (GetNumberOfSignals() > 0) {
387 fMaxTime = fSignal[0].GetNumberOfPoints();
391Double_t TRestRawSignalEvent::GetMaxValue() {
396Double_t TRestRawSignalEvent::GetMinValue() {
401Double_t TRestRawSignalEvent::GetMinTime() {
return 0; }
403Double_t TRestRawSignalEvent::GetMaxTime() {
404 Double_t maxTime = 512;
406 if (GetNumberOfSignals() > 0) maxTime = fSignal[0].GetNumberOfPoints();
412Double_t fAuxiliar = 0;
413void TRestRawSignalEvent::SetAuxiliar(Double_t aux) { fAuxiliar = aux; }
414auto GetAuxiliar() {
return fAuxiliar; }
468 const int nSignals = GetNumberOfSignals();
470 if (fPad !=
nullptr) {
476 cout <<
"Empty event " << endl;
480 fMinValue = numeric_limits<Double_t>::max();
481 fMaxValue = numeric_limits<Double_t>::min();
482 fMinTime = numeric_limits<Double_t>::max();
483 fMaxTime = numeric_limits<Double_t>::min();
485 fPad =
new TPad(GetName(),
" ", 0, 0, 1, 1);
493 bool thresholdCheck =
false;
494 bool baselineCheck =
false;
495 bool sRangeID =
false;
496 bool printIDs =
false;
498 double signalTh = 0, pointTh = 0, nOver = 0;
499 int baseLineRangeInit = 0, baseLineRangeEnd = 0;
500 int sRangeInit = 0, sRangeEnd = 0;
502 for (
const auto& opt : optList) {
503 std::string str = (std::string)opt;
505 if (str.find(
"onlyGoodSignals[") != string::npos) {
506 size_t startPos = str.find(
'[');
507 size_t endPos = str.find(
']');
508 TString tmpStr = opt(startPos + 1, endPos - startPos - 1);
509 vector<TString> optList_2 = Vector_cast<string, TString>(
Split((
string)tmpStr,
","));
515 thresholdCheck =
true;
519 if (str.find(
"baseLineRange[") != string::npos) {
520 size_t startPos2 = str.find(
'[');
521 size_t endPos2 = str.find(
']');
522 TString tmpStr2 = opt(startPos2 + 1, endPos2 - startPos2 - 1);
523 vector<TString> optList_3 = Vector_cast<string, TString>(
Split((
string)tmpStr2,
","));
528 baselineCheck =
true;
532 if (str.find(
"signalRangeID[") != string::npos || str.find(
"ids[") != string::npos) {
533 size_t startPos3 = str.find(
'[');
534 size_t endPos3 = str.find(
']');
535 TString tmpStr3 = opt(startPos3 + 1, endPos3 - startPos3 - 1);
536 vector<TString> optList_4;
537 if (str.find(
',') != string::npos)
538 optList_4 = Vector_cast<string, TString>(
Split((
string)tmpStr3,
","));
539 else if (str.find(
'-') != string::npos)
540 optList_4 = Vector_cast<string, TString>(
Split((
string)tmpStr3,
"-"));
542 RESTError <<
"TRestRawSignalEvent::DrawEvent not valid ids format!" << RESTendl;
551 if (str.find(
"printIDs") != string::npos) {
553 cout <<
"IDs of printed signals: " << endl;
557 std::vector<int> signalIDs;
560 if ((optList.empty()) || !(
isANumber((
string)optList[0]))) {
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++) {
571 fSignal[n].CalculateBaseLine(baseLineRangeInit, baseLineRangeEnd);
572 fSignal[n].InitializePointsOverThreshold(TVector2(pointTh, signalTh), nOver);
573 if (fSignal[n].GetPointsOverThreshold().size() >= 2) {
574 signalIDs.push_back(fSignal[n].GetID());
579 for (
int n = 0; n < nSignals; n++) {
580 signalIDs.push_back(fSignal[n].GetID());
586 for (
auto it = signalIDs.begin(); it != signalIDs.end();)
587 if (*it >= sRangeInit && *it <= sRangeEnd) {
590 it = signalIDs.erase(it);
594 cout <<
"Number of drawn signals: " << signalIDs.size() << endl;
597 }
else if (
isANumber((
string)optList[0])) {
598 string str = (string)optList[0];
599 size_t separation = str.find(
'-');
602 if (separation != string::npos) {
603 TString firstSignal = optList[0](0, separation);
604 TString lastSignal = optList[0](separation + 1, str.size());
605 RESTDebug <<
"First signal: " << firstSignal << RESTendl;
606 RESTDebug <<
"Last signal: " << lastSignal << RESTendl;
609 fPad->SetTitle(
"No Such Signal");
610 cout <<
"No such last signal" << endl;
614 sprintf(title,
"Event ID %d", this->GetID());
616 if (thresholdCheck && baselineCheck) {
617 RESTDebug <<
"Draw only good signals with: " << RESTendl;
618 RESTDebug <<
" Signal threshold: " << signalTh << RESTendl;
619 RESTDebug <<
" Point threshold: " << pointTh << RESTendl;
620 RESTDebug <<
" Points over threshold: " << nOver << RESTendl;
621 RESTDebug <<
" Base line range: (" << baseLineRangeInit <<
"," << baseLineRangeEnd <<
")"
624 for (
int n = 0; n < nSignals; n++) {
627 fSignal[n].CalculateBaseLine(baseLineRangeInit, baseLineRangeEnd);
628 fSignal[n].InitializePointsOverThreshold(TVector2(pointTh, signalTh), nOver);
629 if (fSignal[n].GetPointsOverThreshold().size() >= 2) {
630 signalIDs.push_back(fSignal[n].GetID());
633 cout <<
"Number of good signals in range (" << firstSignal <<
"," << lastSignal
634 <<
"): " << signalIDs.size() << endl;
639 signalIDs.push_back(fSignal[n].GetID());
645 signalIDs.push_back(signalID);
649 if (signalIDs.empty()) {
650 fPad->SetTitle(
"No Such Signal");
651 cout <<
"No signals found" << endl;
656 cout <<
"SignalIDs:";
657 auto sortedSignalsIDs = signalIDs;
658 sort(sortedSignalsIDs.begin(), sortedSignalsIDs.end());
659 for (
const auto& signalID : sortedSignalsIDs) {
660 cout <<
" " << signalID;
676 int max = numeric_limits<Short_t>::min();
679 for (
const auto& s : signals) {
684 TGraph* graph = signal->
GetGraph(graphIndex++);
685 const double maxValue = TMath::MaxElement(graph->GetN(), graph->GetY());
686 if (maxValue > max) {
692 RESTDebug <<
"Max SID " << maxSID << RESTendl;
695 cout <<
"No signals ID found" << endl;
700 std::string title =
"Event ID " + std::to_string(GetID());
701 if (signals.size() == 1) {
702 title +=
" Signal ID " + std::to_string(maxSID);
705 signalMaxID->
fGraph->SetTitle(title.c_str());
706 signalMaxID->
fGraph->GetXaxis()->SetTitle(
"Time bin");
707 signalMaxID->
fGraph->GetYaxis()->SetTitleOffset(1.4);
708 signalMaxID->
fGraph->GetYaxis()->SetTitle(
"Amplitude [a.u.]");
711 signalMaxID->
fGraph->SetLineColor(kBlack);
712 signalMaxID->
fGraph->Draw(
"AL");
714 for (
const auto& signalID : signals) {
715 if (signalID == maxSID) {
720 signal->
fGraph->Draw(
"L");
747 int nSignals = this->GetNumberOfSignals();
749 if (fPad !=
nullptr) {
750 for (
int n = 0; n < nSignals; n++) {
751 delete fSignal[n].fGraph;
752 fSignal[n].fGraph =
nullptr;
759 cout <<
"Empty event " << endl;
765 double signalTh = 0, pointTh = 0, nOver = 0;
766 int baseLineRangeInit = 0, baseLineRangeEnd = 0;
768 for (
auto& opt : optList) {
769 string str = (string)opt;
772 size_t goodSigOpt = str.find(
"goodSignals[");
774 if (goodSigOpt != string::npos) {
775 size_t startPos = str.find(
'[');
776 size_t endPos = str.find(
']');
777 TString tmpStr = opt(startPos + 1, endPos - startPos - 1);
778 vector<TString> optList_2 = Vector_cast<string, TString>(
Split((
string)tmpStr,
","));
786 size_t BLOpt = str.find(
"baseLineRange[");
788 if (BLOpt != string::npos) {
789 size_t startPos2 = str.find(
'[');
790 size_t endPos2 = str.find(
']');
791 TString tmpStr2 = opt(startPos2 + 1, endPos2 - startPos2 - 1);
792 vector<TString> optList_3 = Vector_cast<string, TString>(
Split((
string)tmpStr2,
","));
799 fPad =
new TPad(this->GetName(),
" ", 0, 0, 1, 1);
803 TGraph* gr =
new TGraph();
809 RESTInfo <<
"Drawing signalID. Event ID : " << this->GetID() <<
" Signal ID : " << signal->
GetID()
813 gr->SetPoint(n, n, signal->
GetData(n));
818 TGraph* gr2 =
new TGraph();
820 gr2->SetLineWidth(2);
821 gr2->SetLineColor(2);
823 for (
int n = baseLineRangeInit; n < baseLineRangeEnd; n++) {
824 gr2->SetPoint(n - baseLineRangeInit, n, signal->
GetData(n));
833 gr3[nGraphs] =
new TGraph();
834 gr3[nGraphs]->SetLineWidth(2);
835 gr3[nGraphs]->SetLineColor(3);
837 Int_t nPoints = pOver.size();
838 for (
int n = 0; n < nPoints; n++) {
839 gr3[nGraphs]->SetPoint(point, pOver[n], signal->
GetData(pOver[n]));
841 if (n + 1 < nPoints && pOver[n + 1] - pOver[n] > 1) {
842 gr3[nGraphs]->Draw(
"CP");
844 if (nGraphs > 4) cout <<
"Ngraphs : " << nGraphs << endl;
846 gr3[nGraphs] =
new TGraph();
847 gr3[nGraphs]->SetLineWidth(2);
848 gr3[nGraphs]->SetLineColor(3);
853 gr3[nGraphs]->Draw(
"CP");
860 if (fRun ==
nullptr) {
861 RESTError <<
"TRestRawSignalEvent::GetReadoutMetadata: fRun is nullptr" << RESTendl;
868 return GetSignalEventForTypes({type});
876 auto metadata = readoutMetadata ? readoutMetadata : GetReadoutMetadata();
877 if (metadata ==
nullptr) {
881 for (
const auto& signal : fSignal) {
883 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.
Double_t GetBaseLineSigma() const
Int_t GetID() const
Returns the value of signal ID.
TGraph * fGraph
A TGraph pointer used to store the TRestRawSignal drawing.
Double_t GetMaxPeakValue()
It returns the amplitude of the signal maximum, baseline will be corrected if CalculateBaseLine was c...
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.
std::vector< Int_t > GetPointsOverThreshold() const
Returns a std::vector containing the indexes of data points over threshold.
Double_t GetBaseLine() const
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...
Int_t GetMaxPeakWidth()
It returns the temporal width of the peak with maximum amplitude inside the signal.
Double_t GetData(Int_t n) const
It returns the data value of point n including baseline correction.
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.