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