REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestDetectorHitsReadoutAnalysisProcess.cxx
1//
2// Created by lobis on 03-Sep-23.
3//
4
5#include "TRestDetectorHitsReadoutAnalysisProcess.h"
6
7#include <numeric>
8
9using namespace std;
10
12 fInputHitsEvent = (TRestDetectorHitsEvent*)inputEvent;
13
14 vector<TVector3> hitPosition;
15 vector<double> hitEnergy;
16 double energyInFiducial = 0;
17
18 for (int hitIndex = 0; hitIndex < static_cast<int>(fInputHitsEvent->GetNumberOfHits()); hitIndex++) {
19 const auto position = fInputHitsEvent->GetPosition(hitIndex);
20 const auto energy = fInputHitsEvent->GetEnergy(hitIndex);
21 const auto time = fInputHitsEvent->GetTime(hitIndex);
22 const auto type = fInputHitsEvent->GetType(hitIndex);
23
24 if (energy <= 0) {
25 // this should never happen
26 cerr << "TRestDetectorHitsReadoutAnalysisProcess::ProcessEvent() : "
27 << "Negative or zero energy found in hit " << hitIndex << endl;
28 exit(1);
29 }
30
31 const auto daqId = fReadout->GetDaqId(position, false);
32 const auto channelType = fReadout->GetTypeForChannelDaqId(daqId);
33 const bool isValidHit = channelType == fChannelType;
34
35 // we need to add all hits to preserve the input event
36 fOutputHitsEvent->AddHit(position, energy, time, type);
37
38 if (!isValidHit) {
39 continue;
40 }
41
42 hitPosition.push_back(position);
43 hitEnergy.push_back(energy);
44
45 if (fFiducialDiameter > 0) {
46 TVector3 relativePosition = position - fFiducialPosition;
47 relativePosition.SetZ(0); // TODO: this should be relative to readout normal
48 const double distance = relativePosition.Mag();
49 if (distance > fFiducialDiameter / 2) {
50 continue;
51 }
52 energyInFiducial += energy;
53 }
54 }
55
56 const double readoutEnergy = accumulate(hitEnergy.begin(), hitEnergy.end(), 0.0);
57
58 if (fRemoveZeroEnergyEvents && readoutEnergy <= 0) {
59 // events not depositing any energy in the readout are removed
60 return nullptr;
61 }
62
63 TVector3 positionAverage;
64 for (size_t i = 0; i < hitPosition.size(); i++) {
65 positionAverage += hitPosition[i] * hitEnergy[i];
66 }
67 positionAverage *= 1.0 / readoutEnergy;
68
69 // standard deviation weighted with energy
70 TVector3 positionSigma;
71 for (size_t i = 0; i < hitPosition.size(); i++) {
72 TVector3 diff2 = hitPosition[i] - positionAverage;
73 diff2.SetX(diff2.X() * diff2.X());
74 diff2.SetY(diff2.Y() * diff2.Y());
75 diff2.SetZ(diff2.Z() * diff2.Z());
76 positionSigma += diff2 * hitEnergy[i];
77 }
78 positionSigma *= 1.0 / readoutEnergy;
79 positionSigma.SetX(sqrt(positionSigma.X()));
80 positionSigma.SetY(sqrt(positionSigma.Y()));
81 positionSigma.SetZ(sqrt(positionSigma.Z()));
82
83 const auto positionSigmaXY =
84 sqrt(positionSigma.X() * positionSigma.X() + positionSigma.Y() * positionSigma.Y());
85 const auto positionSigmaXYBalance =
86 (positionSigma.X() - positionSigma.Y()) / (positionSigma.X() + positionSigma.Y());
87
88 TVector3 positionSkewness;
89 for (size_t i = 0; i < hitPosition.size(); i++) {
90 TVector3 diff3 = hitPosition[i] - positionAverage;
91 diff3.SetX(diff3.X() * diff3.X() * diff3.X());
92 diff3.SetY(diff3.Y() * diff3.Y() * diff3.Y());
93 diff3.SetZ(diff3.Z() * diff3.Z() * diff3.Z());
94 positionSkewness += diff3 * hitEnergy[i];
95 }
96 positionSkewness *= 1.0 / readoutEnergy;
97 const auto positionSkewnessXY =
98 (positionSkewness.X() + positionSkewness.Y()) / (positionSigmaXY * positionSigmaXY * positionSigmaXY);
99 positionSkewness.SetX(positionSkewness.X() / (positionSigma.X() * positionSigma.X() * positionSigma.X()));
100 positionSkewness.SetY(positionSkewness.Y() / (positionSigma.Y() * positionSigma.Y() * positionSigma.Y()));
101 positionSkewness.SetZ(positionSkewness.Z() / (positionSigma.Z() * positionSigma.Z() * positionSigma.Z()));
102
103 SetObservableValue("readoutEnergy", readoutEnergy);
104 SetObservableValue("readoutNumberOfHits", hitEnergy.size());
105
106 SetObservableValue("readoutAveragePositionX", positionAverage.X());
107 SetObservableValue("readoutAveragePositionY", positionAverage.Y());
108 SetObservableValue("readoutAveragePositionZ", positionAverage.Z());
109
110 SetObservableValue("readoutSigmaPositionX", positionSigma.X());
111 SetObservableValue("readoutSigmaPositionY", positionSigma.Y());
112 SetObservableValue("readoutSigmaPositionZ", positionSigma.Z());
113 SetObservableValue("readoutSigmaPositionXY", positionSigmaXY);
114
115 SetObservableValue("readoutSigmaPositionXYBalance", positionSigmaXYBalance);
116
117 SetObservableValue("readoutSkewnessPositionX", positionSkewness.X());
118 SetObservableValue("readoutSkewnessPositionY", positionSkewness.Y());
119 SetObservableValue("readoutSkewnessPositionZ", positionSkewness.Z());
120 SetObservableValue("readoutSkewnessPositionXY", positionSkewnessXY);
121
122 SetObservableValue("readoutEnergyInFiducial", energyInFiducial);
123
124 return fOutputHitsEvent;
125}
126
128 fReadout = dynamic_cast<TRestDetectorReadout*>(fRunInfo->GetMetadataClass("TRestDetectorReadout"));
129 if (!fReadout) {
130 cerr << "TRestDetectorHitsReadoutAnalysisProcess::InitProcess() : "
131 << "TRestDetectorReadout not found" << endl;
132 exit(1);
133 }
134
135 if (fChannelType.empty()) {
136 cerr << "TRestDetectorHitsReadoutAnalysisProcess::InitProcess() : "
137 << "Channel type not defined" << endl;
138 exit(1);
139 }
140}
141
143
146
147 RESTMetadata << "Channel type : " << fChannelType << RESTendl;
148 RESTMetadata << "Fiducial position : (" << fFiducialPosition.X() << " , " << fFiducialPosition.Y()
149 << " , " << fFiducialPosition.Z() << ")" << RESTendl;
150 RESTMetadata << "Fiducial diameter : " << fFiducialDiameter << RESTendl;
151
152 EndPrintProcess();
153}
154
156 fRemoveZeroEnergyEvents = StringToBool(GetParameter("removeZeroEnergyEvents", "false"));
157 fChannelType = GetParameter("channelType", fChannelType);
158 fFiducialPosition = Get3DVectorParameterWithUnits("fiducialPosition", fFiducialPosition);
159 fFiducialDiameter = GetDblParameterWithUnits("fiducialDiameter", fFiducialDiameter);
160}
161
163 SetSectionName(this->ClassName());
164 SetLibraryVersion(LIBRARY_VERSION);
165
166 fInputHitsEvent = nullptr;
167 fOutputHitsEvent = new TRestDetectorHitsEvent();
168}
void AddHit(Double_t x, Double_t y, Double_t z, Double_t en, Double_t t=0, REST_HitType type=XYZ)
Adds a new hit to this event.
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
Process one event.
std::string fChannelType
This process will only work on hits corresponding to this channel type (using readout)
void PrintMetadata() override
Implemented it in the derived metadata class to print out specific metadata information.
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
void EndProcess() override
To be executed at the end of the run (outside event loop)
A metadata class to generate/store a readout description.
Int_t GetDaqId(const TVector3 &position, bool check=true)
Returns the DaqID of the channel for position. If no channel is found returns -1.
void BeginPrintProcess()
[name, cut range]
TRestRun * fRunInfo
< Pointer to TRestRun object where to find metadata.
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
endl_t RESTendl
Termination flag object for TRestStringOutput.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
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.