2#include "TRestRawPeaksFinderProcess.h"
20 if (fReadoutMetadata ==
nullptr) {
21 fReadoutMetadata = fInputEvent->GetReadoutMetadata();
24 if (fReadoutMetadata ==
nullptr && !fChannelTypes.empty()) {
25 cerr <<
"TRestRawPeaksFinderProcess::ProcessEvent: readout metadata is null, cannot filter "
26 "the process by signal type"
31 vector<tuple<UShort_t, UShort_t, double>> eventPeaks;
34 double BaseLineMean = 0.0;
35 double BaseLineSigmaMean = 0.0;
36 unsigned int countTPC = 0;
38 for (
int signalIndex = 0; signalIndex < fInputEvent->GetNumberOfSignals(); signalIndex++) {
39 const auto signal = fInputEvent->GetSignal(signalIndex);
42 const string channelType = fReadoutMetadata->GetTypeForChannelDaqId(signalId);
43 const string channelName = fReadoutMetadata->GetNameForChannelDaqId(signalId);
46 if (fChannelTypes.find(channelType) == fChannelTypes.end()) {
51 if (channelType ==
"tpc") {
54 BaseLineMean += signal->GetBaseLine();
55 BaseLineSigmaMean += signal->GetBaseLineSigma();
62 BaseLineMean /= countTPC;
63 BaseLineSigmaMean /= countTPC;
66 for (
int signalIndex = 0; signalIndex < fInputEvent->GetNumberOfSignals(); signalIndex++) {
67 const auto signal = fInputEvent->GetSignal(signalIndex);
70 const string channelType = fReadoutMetadata->GetTypeForChannelDaqId(signalId);
71 const string channelName = fReadoutMetadata->GetNameForChannelDaqId(signalId);
74 if (fChannelTypes.find(channelType) == fChannelTypes.end()) {
79 if (channelType ==
"tpc") {
83 const double threshold =
87 cerr <<
"TRestRawPeaksFinderProcess::ProcessEvent: TPC count is 0 in TPC loop, this should "
92 const auto peaks = signal->GetPeaks(threshold,
fDistance);
94 for (
const auto& [time, amplitude] : peaks) {
95 eventPeaks.emplace_back(signalId, time, amplitude);
97 }
else if (channelType ==
"veto") {
100 signal->CalculateBaseLine(0, 511,
"OUTLIERS");
105 for (
const auto& [time, amplitude] : peaks) {
106 eventPeaks.emplace_back(signalId, time, amplitude);
112 sort(eventPeaks.begin(), eventPeaks.end(),
113 [](
const tuple<UShort_t, UShort_t, double>& a,
const tuple<UShort_t, UShort_t, double>& b) {
114 return tie(get<1>(a), get<0>(a)) < tie(get<1>(b), get<0>(b));
117 vector<UShort_t> peaksChannelId;
118 vector<UShort_t> peaksTime;
119 vector<double> peaksAmplitude;
121 double peaksEnergy = 0.0;
122 UShort_t peaksCount = 0;
123 UShort_t peaksCountUnique = 0;
125 set<UShort_t> uniquePeaks;
126 for (
const auto& [channelId, time, amplitude] : eventPeaks) {
127 peaksChannelId.push_back(channelId);
128 peaksTime.push_back(time);
129 peaksAmplitude.push_back(amplitude);
131 peaksEnergy += amplitude;
134 if (uniquePeaks.find(channelId) == uniquePeaks.end()) {
135 uniquePeaks.insert(channelId);
148 vector<UShort_t> windowPeakIndex(eventPeaks.size(), std::numeric_limits<UShort_t>::max());
149 vector<UShort_t> windowPeakCenter(eventPeaks.size(), 0);
150 vector<UShort_t> windowPeakMultiplicity(eventPeaks.size(), 0);
152 UShort_t window_index = 0;
153 for (
size_t peakIndex = 0; peakIndex < eventPeaks.size(); peakIndex++) {
154 const auto& [channelId, time, amplitude] = eventPeaks[peakIndex];
155 const auto windowTimeStart = time -
fWindow / 2;
156 const auto windowTimeEnd = time +
fWindow / 2;
159 if (windowPeakIndex[peakIndex] != std::numeric_limits<UShort_t>::max()) {
163 UShort_t window_center_time = time;
165 set<UShort_t> windowPeaksIndex;
168 windowPeaksIndex.insert(peakIndex);
171 for (
size_t otherPeakIndex = peakIndex + 1; otherPeakIndex < eventPeaks.size(); otherPeakIndex++) {
172 const auto& [otherChannelId, otherTime, otherAmplitude] = eventPeaks[otherPeakIndex];
174 if (otherTime < windowTimeStart) {
178 if (otherTime > windowTimeEnd) {
182 windowPeaksIndex.insert(otherPeakIndex);
185 for (
const auto& index : windowPeaksIndex) {
186 windowPeakIndex[index] = window_index;
187 windowPeakCenter[index] = window_center_time;
188 windowPeakMultiplicity[index] = windowPeaksIndex.size();
198 vector<UShort_t> windowCenter;
199 vector<UShort_t> windowMultiplicity;
201 set<UShort_t> windowPeaksIndexInserted;
202 for (
size_t peakIndex = 0; peakIndex < eventPeaks.size(); peakIndex++) {
203 const auto& window_peak_index = windowPeakIndex[peakIndex];
204 if (windowPeaksIndexInserted.find(window_peak_index) != windowPeaksIndexInserted.end()) {
208 windowPeaksIndexInserted.insert(window_peak_index);
210 windowCenter.push_back(windowPeakCenter[peakIndex]);
211 windowMultiplicity.push_back(windowPeakMultiplicity[peakIndex]);
217 if (fTimeBinToTimeFactorMultiplier != 0.0) {
218 vector<Double_t> windowCenterTime(windowCenter.size(), 0.0);
219 vector<Double_t> windowPeakCenterTime(windowPeakCenter.size(), 0.0);
220 vector<Double_t> peaksTimePhysical(peaksTime.size(), 0.0);
223 auto timeBinToTime = [
this](UShort_t timeBin) {
224 if (!fTimeConversionElectronics) {
225 return fTimeBinToTimeFactorMultiplier * timeBin - fTimeBinToTimeFactorOffset;
228 double zero = -1 + (512 * fTimeBinToTimeFactorMultiplier - fTimeBinToTimeFactorOffset -
229 fTimeBinToTimeFactorOffsetTCM) /
230 fTimeBinToTimeFactorMultiplier;
231 return fTimeBinToTimeFactorMultiplier * (timeBin - zero);
235 for (
size_t i = 0; i < windowCenter.size(); i++) {
236 windowCenterTime[i] = timeBinToTime(windowCenter[i]);
239 for (
size_t i = 0; i < windowPeakCenter.size(); i++) {
240 windowPeakCenterTime[i] = timeBinToTime(windowPeakCenter[i]);
243 for (
size_t i = 0; i < peaksTime.size(); i++) {
244 peaksTimePhysical[i] = timeBinToTime(peaksTime[i]);
252 if (fADCtoEnergyFactor != 0.0 || !fChannelIDToADCtoEnergyFactor.empty()) {
253 vector<Double_t> peaksEnergyPhysical(peaksAmplitude.size(), 0.0);
254 Double_t peaksEnergySum = 0.0;
256 if (fADCtoEnergyFactor != 0.0) {
258 for (
size_t i = 0; i < peaksAmplitude.size(); i++) {
259 peaksEnergyPhysical[i] = peaksAmplitude[i] * fADCtoEnergyFactor;
260 peaksEnergySum += peaksEnergyPhysical[i];
264 for (
size_t i = 0; i < peaksAmplitude.size(); i++) {
265 const auto channelId = peaksChannelId[i];
267 if (fChannelIDToADCtoEnergyFactor.find(channelId) == fChannelIDToADCtoEnergyFactor.end()) {
268 cerr <<
"TRestRawPeaksFinderProcess::ProcessEvent: channel id " << channelId
269 <<
" not found in the map of ADC to energy factors" << endl;
272 const auto factor = fChannelIDToADCtoEnergyFactor[channelId];
274 peaksEnergyPhysical[i] = peaksAmplitude[i] * factor;
275 peaksEnergySum += peaksEnergyPhysical[i];
285 set<UShort_t> peakSignalIds;
286 for (
const auto& [channelId, time, amplitude] : eventPeaks) {
287 peakSignalIds.insert(channelId);
290 vector<UShort_t> signalsToRemove;
291 for (
int signalIndex = 0; signalIndex < fInputEvent->GetNumberOfSignals(); signalIndex++) {
292 const auto signal = fInputEvent->GetSignal(signalIndex);
294 const string signalType = fReadoutMetadata->GetTypeForChannelDaqId(signalId);
296 if (signalType ==
"veto" && peakSignalIds.find(signalId) == peakSignalIds.end()) {
297 signalsToRemove.push_back(signalId);
302 for (
const auto& signalId : signalsToRemove) {
303 fInputEvent->RemoveSignalWithId(signalId);
309 vector<UShort_t> signalsToRemove;
310 for (
int signalIndex = 0; signalIndex < fInputEvent->GetNumberOfSignals(); signalIndex++) {
311 const auto signal = fInputEvent->GetSignal(signalIndex);
313 const string signalType = fReadoutMetadata->GetTypeForChannelDaqId(signalId);
315 if (signalType ==
"veto") {
316 signalsToRemove.push_back(signalId);
321 for (
const auto& signalId : signalsToRemove) {
322 fInputEvent->RemoveSignalWithId(signalId);
329std::map<UShort_t, double> parseStringToMap(
const std::string& input) {
330 std::map<UShort_t, double> my_map;
331 std::string cleaned_input;
334 for (
char c : input) {
335 if (!std::isspace(c) && c !=
'{' && c !=
'}') {
341 std::stringstream ss(cleaned_input);
343 while (std::getline(ss, pair,
',')) {
345 size_t colon_pos = pair.find(
':');
346 if (colon_pos != std::string::npos) {
348 int key = std::stoi(pair.substr(0, colon_pos));
349 double value = std::stod(pair.substr(colon_pos + 1));
358 const auto filterType =
GetParameter(
"channelType",
"");
359 if (!filterType.empty()) {
360 fChannelTypes.insert(filterType);
363 if (fChannelTypes.empty()) {
375 fTimeBinToTimeFactorMultiplier = GetDblParameterWithUnits(
"sampling", fTimeBinToTimeFactorMultiplier);
376 fTimeBinToTimeFactorOffset = GetDblParameterWithUnits(
"trigDelay", fTimeBinToTimeFactorOffset);
377 fTimeBinToTimeFactorOffsetTCM = GetDblParameterWithUnits(
"trigDelayTCM", fTimeBinToTimeFactorOffsetTCM);
378 fTimeConversionElectronics =
379 StringToBool(
GetParameter(
"trigDelayElectronics", fTimeConversionElectronics));
381 fADCtoEnergyFactor = GetDblParameterWithUnits(
"adcToEnergyFactor", fADCtoEnergyFactor);
382 const string fChannelIDToADCtoEnergyFactorAsString =
GetParameter(
"channelIDToADCtoEnergyFactor",
"");
383 if (!fChannelIDToADCtoEnergyFactorAsString.empty()) {
386 fChannelIDToADCtoEnergyFactor = parseStringToMap(fChannelIDToADCtoEnergyFactorAsString);
389 if (fADCtoEnergyFactor != 0 && !fChannelIDToADCtoEnergyFactor.empty()) {
390 cerr <<
"TRestRawPeaksFinderProcess::InitFromConfigFile: both adcToEnergyFactor and "
391 "channelIDToADCtoEnergyFactor are defined. Please, remove one of them."
397 cerr <<
"TRestRawPeaksFinderProcess::InitProcess: baseline range is not sorted or < 0" << endl;
402 cerr <<
"TRestRawPeaksFinderProcess::InitProcess: threshold over baseline is < 0" << endl;
407 cerr <<
"TRestRawPeaksFinderProcess::InitProcess: sigma over baseline is < 0" << endl;
412 cerr <<
"TRestRawPeaksFinderProcess::InitProcess: distance is < 0" << endl;
417 cerr <<
"TRestRawPeaksFinderProcess::InitProcess: window is < 0" << endl;
422 cerr <<
"TRestRawPeaksFinderProcess::InitProcess: removing veto signals only makes sense when the "
423 "process is applied to veto signals. Remove \"removePeaklessVetoes\" parameter"
432 RESTMetadata <<
"Applying process to channel types: ";
433 for (
const auto& type : fChannelTypes) {
434 RESTMetadata << type <<
" ";
TRestRun * GetRunInfo() const
Return the pointer of the hosting TRestRun object.
void BeginPrintProcess()
[name, cut range]
void SetObservableValue(const std::string &name, const T &value)
Set observable value for AnalysisTree.
A base class for any REST event.
virtual void InitializeReferences(TRestRun *run)
Initialize dynamical references when loading the event from a root file.
Double_t fSigmaOverBaseline
choose times the sigma of the baseline must be overcome to consider a peak
UShort_t fDistance
distance between two peaks to consider them as different (ADC units)
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
Bool_t fRemovePeaklessVetoes
option to remove peak-less veto signals after finding the peaks
Double_t fThresholdOverBaseline
threshold over baseline to consider a peak
UShort_t fWindow
window size to calculate the peak amplitude (time bins)
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
Process one event.
TVector2 fBaselineRange
range of samples to calculate baseline for peak finding
void PrintMetadata() override
Implemented it in the derived metadata class to print out specific metadata information.
Bool_t fRemoveAllVetoes
option to remove all veto signals after finding the peaks
An event container for time rawdata signals with fixed length.
Int_t GetSignalID() const
Returns the value of signal ID.