REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestTrackLinearizationProcess.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
62
63#include "TRestTrackLinearizationProcess.h"
64
65#include "TRestTrackReductionProcess.h"
66
67using namespace std;
68
70
75
80
86 SetSectionName(this->ClassName());
87 SetLibraryVersion(LIBRARY_VERSION);
88
89 fTrackEvent = nullptr;
90 fOutTrackEvent = new TRestTrackEvent();
91}
92
97
102 fTrackEvent = (TRestTrackEvent*)inputEvent;
103
104 for (int t = 0; t < fTrackEvent->GetNumberOfTracks(); t++)
105 fOutTrackEvent->AddTrack(fTrackEvent->GetTrack(t));
106
107 for (int t = 0; t < fTrackEvent->GetNumberOfTracks(); t++) {
108 if (fTrackEvent->GetLevel(t) > 1) continue;
109 TRestTrack* track = fTrackEvent->GetTrack(t);
110 TRestVolumeHits* hits = track->GetVolumeHits();
111 TRestVolumeHits vHits;
112 // Perform track linearization
113 GetHitsProjection(hits, fMaxNodes, vHits);
114 if (vHits.GetNumberOfHits() == 0) continue;
115
116 RESTDebug << "Adding track " << RESTendl;
117 // Store tracks after tinearization
118 TRestTrack newTrack;
119 newTrack.SetTrackID(fOutTrackEvent->GetNumberOfTracks() + 1);
120 newTrack.SetParentID(track->GetTrackID());
121 newTrack.SetVolumeHits(vHits);
122
123 RESTDebug << "Is XZ " << newTrack.isXZ() << " Is YZ " << newTrack.isYZ() << RESTendl;
124
125 fOutTrackEvent->AddTrack(&newTrack);
126 }
127
128 RESTDebug << "NTracks X " << fOutTrackEvent->GetNumberOfTracks("X") << " Y "
129 << fOutTrackEvent->GetNumberOfTracks("Y") << " " << fOutTrackEvent->GetNumberOfTracks("X")
130 << RESTendl;
131
132 fOutTrackEvent->SetLevels();
133 return fOutTrackEvent;
134}
135
143 TRestVolumeHits& vHits) {
144 const int nHits = hits->GetNumberOfHits();
145 const REST_HitType hType = hits->GetType(0);
146 vHits.RemoveHits();
147
148 RESTDebug << "NHits " << nHits << " hits Type " << hType << RESTendl;
149
150 if (hType == XZ) {
151 auto cl = GetBestNodes(hits->GetX(), hits->GetZ(), hits->GetEnergyVector(), nodes);
152 for (const auto& [xy, z] : cl) {
153 vHits.AddHit(xy, hits->GetY(0), z, 0, 0, hType, 0, 0, 0);
154 }
155 } else if (hType == YZ) {
156 auto cl = GetBestNodes(hits->GetY(), hits->GetZ(), hits->GetEnergyVector(), nodes);
157 for (const auto& [xy, z] : cl) {
158 vHits.AddHit(hits->GetX(0), xy, z, 0, 0, hType, 0, 0, 0);
159 }
160 } else if (hType == XY) {
161 auto cl = GetBestNodes(hits->GetX(), hits->GetY(), hits->GetEnergyVector(), nodes);
162 for (const auto& [xy, z] : cl) {
163 vHits.AddHit(xy, z, hits->GetZ(0), 0, 0, hType, 0, 0, 0);
164 }
165 } else {
166 RESTWarning << "Track linearization not implemented for XYZ tracks" << RESTendl;
167 return;
168 }
169
170 TRestVolumeHits::kMeansClustering(hits, vHits, 1);
171
173 for (unsigned int i = 0; i < vHits.GetNumberOfHits(); i++)
174 RESTDebug << i << " " << vHits.GetX(i) << " " << vHits.GetY(i) << " " << vHits.GetZ(i) << " "
175 << vHits.GetType(i) << RESTendl;
176}
177
184std::vector<std::pair<double, double>> TRestTrackLinearizationProcess::GetBestNodes(
185 const std::vector<Float_t>& fXY, const std::vector<Float_t>& fZ, const std::vector<Float_t>& fEn,
186 const int& nodes) {
187 const int nHits = fXY.size();
188
189 const double max[2] = {TMath::MaxElement(fXY.size(), fXY.data()),
190 TMath::MaxElement(fZ.size(), fZ.data())};
191 const double min[2] = {TMath::MinElement(fXY.size(), fXY.data()),
192 TMath::MinElement(fZ.size(), fZ.data())};
193
194 double totEn = 0;
195 for (const auto& en : fEn) totEn += en;
196
197 RESTDebug << "Max " << max[0] << " " << max[1] << RESTendl;
198 RESTDebug << "Min " << min[0] << " " << min[1] << RESTendl;
199
200 TGraph gr[2];
201
202 const int hitAvg = std::round(totEn / (double)nHits / 10.);
203 int c = 0;
204 for (int h = 0; h < nHits; h++) {
205 double en = fEn.at(h);
206 for (int e = 0; e < en; e += hitAvg) {
207 gr[0].SetPoint(c, fXY.at(h), fZ.at(h));
208 gr[1].SetPoint(c, fZ.at(h), fXY.at(h));
209 c++;
210 }
211 }
212
213 RESTDebug << "Points graph " << c << " Hits " << nHits << RESTendl;
214
215 int bestIndex = 0;
216 double bestFit;
217 double slope;
218 double intercept;
219
220 std::string fitOpt = "";
222
223 for (int l = 0; l < 2; l++) {
224 TF1 f1("f1", "[0] * x + [1]", min[l], max[l]);
225 gr[l].Fit(&f1, fitOpt.c_str());
226 double fitGoodness = f1.GetChisquare();
227
228 if (l == 0) {
229 bestFit = fitGoodness;
230 slope = f1.GetParameter(0);
231 intercept = f1.GetParameter(1);
232 continue;
233 } else if (fitGoodness < bestFit) {
234 bestFit = fitGoodness;
235 bestIndex = l;
236 slope = f1.GetParameter(0);
237 intercept = f1.GetParameter(1);
238 }
239 }
240
241 RESTDebug << "Best fit " << bestFit << " " << bestIndex << RESTendl;
242 RESTDebug << "Slope " << slope << " Intercept " << intercept << RESTendl;
243
244 std::vector<std::pair<double, double>> cluster(nodes);
245 for (int i = 0; i < nodes; i++) {
246 double first = min[bestIndex] + ((double)i) * (max[bestIndex] - min[bestIndex]) / (double)(nodes - 1);
247 double second = first * slope + intercept;
248 if (bestIndex == 0)
249 cluster[i] = std::make_pair(first, second);
250 else
251 cluster[i] = std::make_pair(second, first);
252 }
253
254 return cluster;
255}
256
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.
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
@ REST_Debug
+show the defined debug messages
A process to perform track linearization.
std::vector< std::pair< double, double > > GetBestNodes(const std::vector< Float_t > &fXY, const std::vector< Float_t > &fZ, const std::vector< Float_t > &fEn, const int &nodes)
This function performs a linear fit to the volumehits of the track weighthed by the energy of the hit...
void EndProcess() override
Function to include required actions after all events have been processed.
void Initialize() override
Function to initialize input/output event members and define the section name.
void GetHitsProjection(TRestVolumeHits *hits, const int &nodes, TRestVolumeHits &vHits)
This function performs the track linearization towards a given number of nodes the nodes are extracte...
void InitProcess() override
Process initialization. Nothing to do here.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
void RemoveHits()
It removes all hits inside the class.