REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRawSignalAnalysisProcess.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
249
250#include "TRestRawSignalAnalysisProcess.h"
251
252using namespace std;
253
255
260
265
271 SetSectionName(this->ClassName());
272 SetLibraryVersion(LIBRARY_VERSION);
273
274 fInputEvent = nullptr;
275}
276
281 if (fSignalsRange.X() != -1 && fSignalsRange.Y() != -1) {
282 fRangeEnabled = true;
283 }
284}
285
288 const auto filterType = GetParameter("channelType", "");
289 if (!filterType.empty()) {
290 fChannelTypes.insert(filterType);
291 }
292}
293
298 fInputEvent = dynamic_cast<TRestRawSignalEvent*>(inputEvent);
299
300 const auto run = GetRunInfo();
301 if (run != nullptr) {
303 }
304
305 if (fReadoutMetadata == nullptr) {
306 fReadoutMetadata = fInputEvent->GetReadoutMetadata();
307 }
308
309 if (fReadoutMetadata == nullptr && !fChannelTypes.empty()) {
310 cerr << "TRestRawSignalAnalysisProcess::ProcessEvent: readout metadata is null, cannot filter "
311 "the process by signal type"
312 << endl;
313 exit(1);
314 }
315
316 auto event = fInputEvent->GetSignalEventForTypes(fChannelTypes, fReadoutMetadata);
317
318 // we save some complex typed analysis result
319 map<int, Double_t> baseline;
320 map<int, Double_t> baselinesigma;
321 map<int, Double_t> ampsgn_maxmethod;
322 map<int, Double_t> ampsgn_intmethod;
323 map<int, int> risetime;
324 map<int, int> peak_time;
325 map<int, int> npointsot;
326 vector<int> saturatedchnId;
327
328 baseline.clear();
329 baselinesigma.clear();
330 ampsgn_maxmethod.clear();
331 ampsgn_intmethod.clear();
332 risetime.clear();
333 npointsot.clear();
334
335 Int_t nGoodSignals = 0;
336
339 // This will affect the calculation of observables, but not the stored
340 // TRestRawSignal data.
342 event.SetRange(fIntegralRange);
343
344 for (int s = 0; s < event.GetNumberOfSignals(); s++) {
345 TRestRawSignal* sgnl = event.GetSignal(s);
346
350
351 if (fRangeEnabled && (sgnl->GetID() < fSignalsRange.X() || sgnl->GetID() > fSignalsRange.Y())) {
352 continue;
353 }
354
355 // We do not want that signals that are not identified as such contribute to
356 // define our observables
357 // nkx: we still need to store all the signals in baseline/rise time maps in
358 // case for noise analysis
359 // if (sgnl->GetPointsOverThreshold().size() < 2) continue;
360 if (sgnl->GetPointsOverThreshold().size() >= 2) nGoodSignals++;
361
362 // Now TRestRawSignal returns directly baseline subtracted values
363 baseline[sgnl->GetID()] = sgnl->GetBaseLine();
364 baselinesigma[sgnl->GetID()] = sgnl->GetBaseLineSigma();
365 ampsgn_intmethod[sgnl->GetID()] = sgnl->GetThresholdIntegral();
366 ampsgn_maxmethod[sgnl->GetID()] = sgnl->GetMaxPeakValue();
367 risetime[sgnl->GetID()] = sgnl->GetRiseTime();
368 peak_time[sgnl->GetID()] = sgnl->GetMaxPeakBin();
369 npointsot[sgnl->GetID()] = sgnl->GetPointsOverThreshold().size();
370 if (sgnl->IsADCSaturation()) saturatedchnId.push_back(sgnl->GetID());
371 }
372
373 SetObservableValue("pointsoverthres_map", npointsot);
374 SetObservableValue("risetime_map", risetime);
375 SetObservableValue("peak_time_map", peak_time);
376 SetObservableValue("baseline_map", baseline);
377 SetObservableValue("baselinesigma_map", baselinesigma);
378 SetObservableValue("max_amplitude_map", ampsgn_maxmethod);
379 SetObservableValue("thr_integral_map", ampsgn_intmethod);
380 SetObservableValue("SaturatedChannelID", saturatedchnId);
381
382 Double_t baseLineMean = event.GetBaseLineAverage();
383 SetObservableValue("BaseLineMean", baseLineMean);
384
385 Double_t baseLineSigma = event.GetBaseLineSigmaAverage();
386 SetObservableValue("BaseLineSigmaMean", baseLineSigma);
387
388 Double_t timeDelay = event.GetMaxTime() - event.GetMinTime();
389 SetObservableValue("TimeBinsLength", timeDelay);
390
391 Int_t nSignals = event.GetNumberOfSignals();
392 SetObservableValue("NumberOfSignals", nSignals);
393 SetObservableValue("NumberOfGoodSignals", nGoodSignals);
394
395 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
396 // SubstractBaselines
397 // After this the signal gets zero-ed, for the following analysis
398 // Keep in mind, to add raw signal analysis, we must write code at before
399 // This is where most of the problems occur
400 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
401 // Javier: I believe we should not substract baseline in the analysis process
402 // then ...
403 // ... of course we need to consider baseline substraction for each
404 // observable. TRestRawSignal methods
405 // should do that internally. I have updated that to be like that, but we need
406 // to be with open eyes for
407 // some period.
408 // Baseline substraction will always happen when we transfer a TRestRawSignal
409 // to TRestDetectorSignal
410 //
411 // We do not substract baselines then now, as it was done before
412 //
413 // fInputEvent->SubstractBaselines(fBaseLineRange.X(), fBaseLineRange.Y());
414 //
415 // Methods in TRestRawSignal have been updated to consider baseline.
416 // TRestRawSignal now implements that internally. We need to define the
417 // baseline range, and the range
418 // where calculations take place. All we need is to call at some point to the
419 // following methods.
420 //
421 // TRestRawSignalEvent::SetBaseLineRange and TRestRawSignalEvent::SetRange.
422 //
423 // Then, if any method accepts a different range it will be given in the
424 // method name,
425 // for example: GetIntegralInRange( Int_t startBin, Int_t endBin );
426 //
427
428 Double_t fullIntegral = event.GetIntegral();
429 SetObservableValue("FullIntegral", fullIntegral);
430
431 Double_t thrIntegral = event.GetThresholdIntegral();
432 SetObservableValue("ThresholdIntegral", thrIntegral);
433
434 Double_t riseSlope = event.GetRiseSlope();
435 SetObservableValue("RiseSlopeAvg", riseSlope);
436
437 Double_t slopeIntegral = event.GetSlopeIntegral();
438 SetObservableValue("SlopeIntegral", slopeIntegral);
439
440 Double_t rateOfChange = riseSlope / slopeIntegral;
441 if (slopeIntegral == 0) rateOfChange = 0;
442 SetObservableValue("RateOfChangeAvg", rateOfChange);
443
444 Double_t riseTime = event.GetRiseTime();
445 SetObservableValue("RiseTimeAvg", riseTime);
446
447 Double_t tripleMaxIntegral = event.GetTripleMaxIntegral();
448 SetObservableValue("TripleMaxIntegral", tripleMaxIntegral);
449
450 Double_t integralRatio = (fullIntegral - thrIntegral) / (fullIntegral + thrIntegral);
451 SetObservableValue("IntegralBalance", integralRatio);
452
453 Double_t maxValue = 0;
454 Double_t minValue = 1.e6;
455 Double_t maxValueIntegral = 0;
456 Double_t minDownValue = 1.e6;
457
458 Double_t minPeakTime = 1000; // TODO substitute this for something better
459 Double_t maxPeakTime = 0;
460 Double_t peakTimeAverage = 0;
461
462 for (int s = 0; s < event.GetNumberOfSignals(); s++) {
463 TRestRawSignal* sgnl = event.GetSignal(s);
464
465 if (fRangeEnabled && (sgnl->GetID() < fSignalsRange.X() || sgnl->GetID() > fSignalsRange.Y()))
466 continue;
467
468 if (sgnl->GetPointsOverThreshold().size() > 1) {
469 Double_t value = event.GetSignal(s)->GetMaxValue();
470 maxValueIntegral += value;
471
472 if (value > maxValue) maxValue = value;
473 if (value < minValue) minValue = value;
474
475 Double_t peakBin = sgnl->GetMaxPeakBin();
476 peakTimeAverage += peakBin;
477
478 if (minPeakTime > peakBin) minPeakTime = peakBin;
479 if (maxPeakTime < peakBin) maxPeakTime = peakBin;
480 }
481 Double_t mindownvalue = event.GetSignal(s)->GetMinValue();
482 if (mindownvalue < minDownValue) {
483 minDownValue = mindownvalue;
484 }
485 }
486
487 if (nGoodSignals > 0) peakTimeAverage /= nGoodSignals;
488
489 Double_t ampIntRatio = thrIntegral / maxValueIntegral;
490 if (maxValueIntegral == 0) ampIntRatio = 0;
491
492 SetObservableValue("AmplitudeIntegralRatio", ampIntRatio);
493 SetObservableValue("MinPeakAmplitude", minValue);
494 SetObservableValue("MaxPeakAmplitude", maxValue);
495 SetObservableValue("PeakAmplitudeIntegral", maxValueIntegral);
496
497 SetObservableValue("MinEventValue", minDownValue);
498
499 Double_t amplitudeRatio = maxValueIntegral / maxValue;
500 if (maxValue == 0) amplitudeRatio = 0;
501
502 SetObservableValue("AmplitudeRatio", amplitudeRatio);
503 SetObservableValue("MaxPeakTime", maxPeakTime);
504 SetObservableValue("MinPeakTime", minPeakTime);
505
506 Double_t peakTimeDelay = maxPeakTime - minPeakTime;
507
508 SetObservableValue("MaxPeakTimeDelay", peakTimeDelay);
509 SetObservableValue("AveragePeakTime", peakTimeAverage);
510
512 for (const auto& i : fObservablesDefined) {
513 fAnalysisTree->PrintObservable(i.second);
514 }
515 }
516
517 // If cut condition matches the event will be not registered.
518 if (ApplyCut()) {
519 return nullptr;
520 }
521
522 return fInputEvent;
523}
virtual void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
TRestAnalysisTree * fAnalysisTree
TRestRun * GetRunInfo() const
Return the pointer of the hosting TRestRun object.
std::map< std::string, int > fObservablesDefined
Stores the list of all the appeared process observables in the code.
void SetObservableValue(const std::string &name, const T &value)
Set observable value for AnalysisTree.
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 SetLibraryVersion(TString version)
Set the library version of this metadata class.
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
void SetSectionName(std::string sName)
set the section name, clear the section content
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.
An analysis process to extract valuable information from a TRestRawSignalEvent.
void InitProcess() override
Process initialization.
TVector2 fSignalsRange
It defines the signals id range where analysis is applied.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
Double_t fPointThreshold
The number of sigmas over baseline fluctuations to identify a point over threshold.
std::string fBaseLineOption
Option for calculation of baseline parameters, can be set to "ROBUST".
TRestRawSignalEvent * fInputEvent
A pointer to the specific TRestRawSignalEvent input.
void Initialize() override
Function to initialize input/output event members and define the section name.
Double_t fSignalThreshold
A parameter to define a minimum signal fluctuation. Measured in sigmas.
Bool_t fRangeEnabled
Just a flag to quickly determine if we have to apply the range filter.
Int_t fPointsOverThreshold
The minimum number of points over threshold to identify a signal as such.
TVector2 fIntegralRange
The range where the observables will be calculated.
TVector2 fBaseLineRange
The range where the baseline range will be calculated.
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
An event container for time rawdata signals with fixed length.
void SetBaseLineRange(TVector2 blRange, std::string option="")
It defines a Short_t array with a physical parameter that evolves in time using a fixed time bin.
Double_t GetBaseLineSigma() const
Double_t GetThresholdIntegral()
It returns the integral of points identified over threshold. InitializePointsOverThreshold should hav...
Int_t GetID() const
Returns the value of signal ID.
Double_t GetMaxValue()
Returns the maximum value found in the data points. It includes baseline correction.
Double_t GetMaxPeakValue()
It returns the amplitude of the signal maximum, baseline will be corrected if CalculateBaseLine was c...
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 GetRiseTime()
It returns the time required from the signal to reach the maximum. InitializePointsOverThreshold shou...
Bool_t IsADCSaturation(int Nflat=3)
It returns whether the signal has ADC saturation.
Int_t GetMaxPeakBin()
It returns the bin at which the maximum peak amplitude happens.
@ REST_Debug
+show the defined debug messages