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
67
68#include "TRestTrackLinearizationProcess.h"
69
70#include "TRestTrackReductionProcess.h"
71using namespace std;
72
74
79
84
90 SetSectionName(this->ClassName());
91 SetLibraryVersion(LIBRARY_VERSION);
92
93 fTrackEvent = nullptr;
94 fOutTrackEvent = new TRestTrackEvent();
95}
96
101
106 fTrackEvent = (TRestTrackEvent*)inputEvent;
107
108 for (int t = 0; t < fTrackEvent->GetNumberOfTracks(); t++)
109 fOutTrackEvent->AddTrack(fTrackEvent->GetTrack(t));
110
111 for (int t = 0; t < fTrackEvent->GetNumberOfTracks(); t++) {
112 if (fTrackEvent->GetLevel(t) > 1) continue;
113 TRestTrack* track = fTrackEvent->GetTrack(t);
114 TRestVolumeHits* hits = track->GetVolumeHits();
115 TRestVolumeHits vHits;
116 // Perform track linearization
117 GetHitsProjection(hits, fMaxNodes, vHits);
118 if (vHits.GetNumberOfHits() == 0) continue;
119
120 RESTDebug << "Adding track " << RESTendl;
121 // Store tracks after tinearization
122 TRestTrack newTrack;
123 newTrack.SetTrackID(fOutTrackEvent->GetNumberOfTracks() + 1);
124 newTrack.SetParentID(track->GetTrackID());
125 newTrack.SetVolumeHits(vHits);
126
127 RESTDebug << "Is XZ " << newTrack.isXZ() << " Is YZ " << newTrack.isYZ() << RESTendl;
128
129 fOutTrackEvent->AddTrack(&newTrack);
130 }
131
132 RESTDebug << "NTracks X " << fOutTrackEvent->GetNumberOfTracks("X") << " Y "
133 << fOutTrackEvent->GetNumberOfTracks("Y") << " " << fOutTrackEvent->GetNumberOfTracks("X")
134 << RESTendl;
135
136 fOutTrackEvent->SetLevels();
137 return fOutTrackEvent;
138}
139
147 TRestVolumeHits& vHits) {
148 const int nHits = hits->GetNumberOfHits();
149 const REST_HitType hType = hits->GetType(0);
150 vHits.RemoveHits();
151
152 RESTDebug << "NHits " << nHits << " hits Type " << hType << RESTendl;
153
154 if (hType == XZ) {
155 auto cl = GetBestNodes(hits->GetX(), hits->GetZ(), hits->GetEnergyVector(), nodes);
156 for (const auto& [xy, z] : cl) {
157 vHits.AddHit(xy, hits->GetY(0), z, 0, 0, hType, 0, 0, 0);
158 }
159 } else if (hType == YZ) {
160 auto cl = GetBestNodes(hits->GetY(), hits->GetZ(), hits->GetEnergyVector(), nodes);
161 for (const auto& [xy, z] : cl) {
162 vHits.AddHit(hits->GetX(0), xy, z, 0, 0, hType, 0, 0, 0);
163 }
164 } else if (hType == XY) {
165 auto cl = GetBestNodes(hits->GetX(), hits->GetY(), hits->GetEnergyVector(), nodes);
166 for (const auto& [xy, z] : cl) {
167 vHits.AddHit(xy, z, hits->GetZ(0), 0, 0, hType, 0, 0, 0);
168 }
169 } else {
170 RESTWarning << "Track linearization not implemented for XYZ tracks" << RESTendl;
171 return;
172 }
173
174 TRestVolumeHits::kMeansClustering(hits, vHits, 1, fFixBoundaries);
175
177 for (unsigned int i = 0; i < vHits.GetNumberOfHits(); i++)
178 RESTDebug << i << " " << vHits.GetX(i) << " " << vHits.GetY(i) << " " << vHits.GetZ(i) << " "
179 << vHits.GetType(i) << RESTendl;
180}
181
188std::vector<std::pair<double, double>> TRestTrackLinearizationProcess::GetBestNodes(
189 const std::vector<Float_t>& fXY, const std::vector<Float_t>& fZ, const std::vector<Float_t>& fEn,
190 const int& nodes) {
191 const int nHits = fXY.size();
192
193 const double max[2] = {TMath::MaxElement(fXY.size(), fXY.data()),
194 TMath::MaxElement(fZ.size(), fZ.data())};
195 const double min[2] = {TMath::MinElement(fXY.size(), fXY.data()),
196 TMath::MinElement(fZ.size(), fZ.data())};
197
198 double totEn = 0;
199 for (const auto& en : fEn) totEn += en;
200
201 RESTDebug << "Max " << max[0] << " " << max[1] << RESTendl;
202 RESTDebug << "Min " << min[0] << " " << min[1] << RESTendl;
203
204 TGraph gr[2];
205
206 const int hitAvg = std::round(totEn / (double)nHits / 10.);
207 int c = 0;
208 for (int h = 0; h < nHits; h++) {
209 double en = fEn.at(h);
210 for (int e = 0; e < en; e += hitAvg) {
211 gr[0].SetPoint(c, fXY.at(h), fZ.at(h));
212 gr[1].SetPoint(c, fZ.at(h), fXY.at(h));
213 c++;
214 }
215 }
216
217 RESTDebug << "Points graph " << c << " Hits " << nHits << RESTendl;
218
219 int bestIndex = 0;
220 double bestFit;
221 double slope;
222 double intercept;
223
224 std::string fitOpt = "";
226
227 for (int l = 0; l < 2; l++) {
228 TF1 f1("f1", "[0] * x + [1]", min[l], max[l]);
229 gr[l].Fit(&f1, fitOpt.c_str());
230 double fitGoodness = f1.GetChisquare();
231
232 if (l == 0) {
233 bestFit = fitGoodness;
234 slope = f1.GetParameter(0);
235 intercept = f1.GetParameter(1);
236 continue;
237 } else if (fitGoodness < bestFit) {
238 bestFit = fitGoodness;
239 bestIndex = l;
240 slope = f1.GetParameter(0);
241 intercept = f1.GetParameter(1);
242 }
243 }
244
245 RESTDebug << "Best fit " << bestFit << " " << bestIndex << RESTendl;
246 RESTDebug << "Slope " << slope << " Intercept " << intercept << RESTendl;
247
248 std::vector<std::pair<double, double>> cluster(nodes);
249 for (int i = 0; i < nodes; i++) {
250 double first = min[bestIndex] + ((double)i) * (max[bestIndex] - min[bestIndex]) / (double)(nodes - 1);
251 double second = first * slope + intercept;
252 if (bestIndex == 0)
253 cluster[i] = std::make_pair(first, second);
254 else
255 cluster[i] = std::make_pair(second, first);
256 }
257
258 return cluster;
259}
260
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.