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 using 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 
171  if (GetVerboseLevel() >= TRestStringOutput::REST_Verbose_Level::REST_Debug)
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 
183 std::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 = "";
220  if (GetVerboseLevel() < TRestStringOutput::REST_Verbose_Level::REST_Debug) fitOpt = "Q";
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
@ 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.