REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRawPeaksFinderProcess.cxx
1 //
2 // Created by lobis on 24-Aug-23.
3 //
4 
5 #include "TRestRawPeaksFinderProcess.h"
6 
7 #include <utility>
8 
9 #include "TRestRawReadoutMetadata.h"
10 
12 
13 using namespace std;
14 
16 
18  fSignalEvent = dynamic_cast<TRestRawSignalEvent*>(inputEvent);
19  fSignalEvent->InitializeReferences(GetRunInfo());
20  auto event = fSignalEvent->GetSignalEventForTypes(fChannelTypes, fReadoutMetadata);
21 
22  if (fReadoutMetadata == nullptr) {
23  fReadoutMetadata = fSignalEvent->GetReadoutMetadata();
24  }
25 
26  if (fReadoutMetadata == nullptr) {
27  cerr << "TRestRawPeaksFinderProcess::ProcessEvent: readout metadata is null" << endl;
28  exit(1);
29  }
30 
31  std::vector<tuple<UShort_t, UShort_t, double>> eventPeaks;
32 
33  for (int signalIndex = 0; signalIndex < event.GetNumberOfSignals(); signalIndex++) {
34  const auto signal = event.GetSignal(signalIndex);
35  const UShort_t signalId = signal->GetSignalID();
36 
37  const string channelType = fReadoutMetadata->GetTypeForChannelDaqId(signalId);
38  const string channelName = fReadoutMetadata->GetNameForChannelDaqId(signalId);
39 
40  // check if channel type is in the list of selected channel types
41  if (fChannelTypes.find(channelType) == fChannelTypes.end()) {
42  continue;
43  }
44 
45  signal->CalculateBaseLine(0, 5);
46  const auto peaks = signal->GetPeaks(signal->GetBaseLine() + 1.0, fDistance);
47 
48  for (const auto& [time, amplitude] : peaks) {
49  eventPeaks.emplace_back(signalId, time, amplitude);
50  }
51  /*
52  cout << "Signal ID: " << channelId << " Name: " << channelName << endl;
53  for (const auto& [time, amplitude] : peaks) {
54  cout << " - Peak at " << time << " with amplitude " << amplitude << endl;
55  }
56  */
57  }
58 
59  // sort eventPeaks by time, then signal id
60  sort(eventPeaks.begin(), eventPeaks.end(),
61  [](const tuple<UShort_t, UShort_t, double>& a, const tuple<UShort_t, UShort_t, double>& b) {
62  return std::tie(std::get<1>(a), std::get<0>(a)) < std::tie(std::get<1>(b), std::get<0>(b));
63  });
64 
65  SetObservableValue("peaks", eventPeaks);
66 
67  std::vector<UShort_t> windowIndex(eventPeaks.size(), 0); // Initialize with zeros
68  std::vector<UShort_t> windowCenter; // for each different window, the center of the window
69 
70  for (size_t peakIndex = 0; peakIndex < eventPeaks.size(); peakIndex++) {
71  const auto& [channelId, time, amplitude] = eventPeaks[peakIndex];
72  const auto windowTime = time - fWindow / 2;
73  const auto windowEnd = time + fWindow / 2;
74 
75  // check if the peak is already in a window
76  if (windowIndex[peakIndex] != 0) {
77  continue;
78  }
79 
80  // create a new window
81  windowCenter.push_back(time);
82 
83  // add the peak to the window
84  windowIndex[peakIndex] = windowCenter.size();
85 
86  // add the peaks that are in the window
87  for (size_t otherPeakIndex = peakIndex + 1; otherPeakIndex < eventPeaks.size(); otherPeakIndex++) {
88  const auto& [otherChannelId, otherTime, otherAmplitude] = eventPeaks[otherPeakIndex];
89 
90  if (otherTime < windowTime) {
91  continue;
92  }
93 
94  if (otherTime > windowEnd) {
95  break;
96  }
97 
98  windowIndex[otherPeakIndex] = windowCenter.size();
99  }
100  }
101 
102  // subtract 1 from windowIndex so it starts on 0
103  for (auto& index : windowIndex) {
104  index--;
105  }
106 
107  // validation
108  // check only values from 0 ... windowCenter.size() -1 are in windowIndex
109  // ALL values in this range should appear at least once
110  for (size_t index = 0; index < windowCenter.size(); index++) {
111  bool found = false;
112  for (const auto& window : windowIndex) {
113  if (window == index) {
114  found = true;
115  break;
116  }
117  }
118  if (!found) {
119  cerr << "TRestRawPeaksFinderProcess::ProcessEvent: window index " << index << " not found"
120  << endl;
121  exit(1);
122  }
123  }
124 
125  SetObservableValue("windowIndex", windowIndex);
126  SetObservableValue("windowCenter", windowCenter);
127 
128  return inputEvent;
129 }
130 
132  const auto filterType = GetParameter("channelType", "");
133  if (!filterType.empty()) {
134  fChannelTypes.insert(filterType);
135  }
136 
137  if (fChannelTypes.empty()) {
138  // if no channel type is specified, use all channel types
139  }
140 
141  fThresholdOverBaseline = StringToDouble(GetParameter("thresholdOverBaseline", fThresholdOverBaseline));
142  fBaselineRange = Get2DVectorParameterWithUnits("baselineRange", fBaselineRange);
143  fDistance = StringToDouble(GetParameter("distance", fDistance));
144  fWindow = StringToDouble(GetParameter("window", fWindow));
145 
146  if (fBaselineRange.X() > fBaselineRange.Y() || fBaselineRange.X() < 0 || fBaselineRange.Y() < 0) {
147  cerr << "TRestRawPeaksFinderProcess::InitProcess: baseline range is not sorted or < 0" << endl;
148  exit(1);
149  }
150 
151  if (fThresholdOverBaseline < 0) {
152  cerr << "TRestRawPeaksFinderProcess::InitProcess: threshold over baseline is < 0" << endl;
153  exit(1);
154  }
155 
156  if (fDistance <= 0) {
157  cerr << "TRestRawPeaksFinderProcess::InitProcess: distance is < 0" << endl;
158  exit(1);
159  }
160 
161  if (fWindow <= 0) {
162  cerr << "TRestRawPeaksFinderProcess::InitProcess: window is < 0" << endl;
163  exit(1);
164  }
165 }
166 
168  cout << "Applying process to channel types: ";
169  for (const auto& type : fChannelTypes) {
170  cout << type << " ";
171  }
172  cout << endl;
173 
174  cout << "Threshold over baseline: " << fThresholdOverBaseline << endl;
175  cout << "Baseline range: " << fBaselineRange.X() << " - " << fBaselineRange.Y() << endl;
176 
177  cout << "Distance: " << fDistance << endl;
178  cout << "Window: " << fWindow << endl;
179 }
A base class for any REST event.
Definition: TRestEvent.h:38
virtual void InitializeReferences(TRestRun *run)
Initialize dynamical references when loading the event from a root file.
Definition: TRestEvent.cxx:175
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
Process one event.
void PrintMetadata() override
Implemented it in the derived metadata class to print out specific metadata information.
An event container for time rawdata signals with fixed length.
Double_t StringToDouble(std::string in)
Gets a double from a string.