REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestTrackReconnectionProcess.cxx
1
11
12#include "TRestTrackReconnectionProcess.h"
13
14using namespace std;
15
17
18TRestTrackReconnectionProcess::TRestTrackReconnectionProcess() { Initialize(); }
19
20TRestTrackReconnectionProcess::TRestTrackReconnectionProcess(const char* configFilename) {
21 Initialize();
22
23 if (LoadConfigFromFile(configFilename) == -1) LoadDefaultConfig();
25}
26
27TRestTrackReconnectionProcess::~TRestTrackReconnectionProcess() { delete fOutputTrackEvent; }
28
29void TRestTrackReconnectionProcess::LoadDefaultConfig() {
30 SetName("trackReconnectionProcess");
31 SetTitle("Default config");
32}
33
35 SetSectionName(this->ClassName());
36 SetLibraryVersion(LIBRARY_VERSION);
37
38 fInputTrackEvent = nullptr;
39 fOutputTrackEvent = new TRestTrackEvent();
40
41 fSplitTrack = false;
42}
43
44void TRestTrackReconnectionProcess::LoadConfig(const string& configFilename, const string& name) {
45 if (LoadConfigFromFile(configFilename, name) == -1) LoadDefaultConfig();
46
48}
49
50void TRestTrackReconnectionProcess::InitProcess() { TRestEventProcess::ReadObservables(); }
51
53 Int_t trackBranches = 0;
54
55 fInputTrackEvent = (TRestTrackEvent*)inputEvent;
56
57 // Copying the input tracks to the output track
58 for (int tck = 0; tck < fInputTrackEvent->GetNumberOfTracks(); tck++)
59 fOutputTrackEvent->AddTrack(fInputTrackEvent->GetTrack(tck));
60
61 for (int tck = 0; tck < fInputTrackEvent->GetNumberOfTracks(); tck++) {
62 if (!fInputTrackEvent->isTopLevel(tck)) continue;
63 Int_t tckId = fInputTrackEvent->GetTrack(tck)->GetTrackID();
64
65 TRestVolumeHits* hits = fInputTrackEvent->GetTrack(tck)->GetVolumeHits();
66
67 /* {{{ Debug output */
69 cout << "TRestTrackReconnectionProcess. Input hits" << endl;
70 Int_t pId = fInputTrackEvent->GetTrack(tck)->GetParentID();
71 cout << "Track : " << tck << " TrackID : " << tckId << " ParentID : " << pId << endl;
72 cout << "-----------------" << endl;
73 }
74 /* }}} */
75
76 SetDistanceMeanAndSigma((TRestHits*)hits);
77
78 if (fMeanDistance == 0) continue; // We have just 1-hit
79
80 TRestVolumeHits initialHits = *hits;
81 vector<TRestVolumeHits> subHitSets;
82 Int_t tBranches;
83
84 // We do 3 times the break and re-connect process
85 // Although another option would be to do it until we observe no change
86 // Most of the times even 1-round is more than enough.
87 for (int n = 0; n < 1; n++) {
88 // The required distance between hits to break a track is increased in
89 // each iteration
90 BreakTracks(&initialHits, subHitSets, 1.5 * (n + 1));
91 ReconnectTracks(subHitSets);
92
93 TRestVolumeHits resultHits = subHitSets[0];
94 SetDistanceMeanAndSigma(&resultHits);
95 tBranches = GetTrackBranches(resultHits, fNSigmas);
96
98 cout << "Break and reconnect finished" << endl;
99 cout << "Branches : " << tBranches << endl;
101 }
102
103 initialHits = resultHits;
104 }
105
106 // For the observable We just take the value for the track with more number
107 // of branches
108 if (tBranches > trackBranches) trackBranches = tBranches;
109
110 // A fine tunning applied to consecutive hits
111 for (unsigned int n = 0; n < subHitSets[0].GetNumberOfHits(); n++) {
112 if (n > 0 && n < subHitSets[0].GetNumberOfHits() - 1) {
113 Double_t distance = subHitSets[0].GetHitsPathLength(n - 2, n + 2);
114
115 subHitSets[0].SwapHits(n - 1, n);
116
117 Double_t distanceAfter = subHitSets[0].GetHitsPathLength(n - 2, n + 2);
118
119 if (distanceAfter < distance) continue;
120
121 subHitSets[0].SwapHits(n - 1, n);
122 }
123 }
124
125 if (fSplitTrack) {
126 BreakTracks(&initialHits, subHitSets, fNSigmas);
127
129 cout << " **** Splitting track : " << endl;
130 cout << "Number of subHitSets : " << subHitSets.size() << endl;
132 }
133 }
134
135 for (unsigned int n = 0; n < subHitSets.size(); n++) {
136 TRestTrack aTrack;
137 // We create the new track and add it giving its parent ID
138 aTrack.SetTrackID(fOutputTrackEvent->GetNumberOfTracks() + 1);
139
140 aTrack.SetParentID(tckId);
141
142 aTrack.SetVolumeHits(subHitSets[n]);
143
144 fOutputTrackEvent->AddTrack(&aTrack);
145 }
146 }
147
148 SetObservableValue("branches", trackBranches);
149 // cout << "Track branches : " << trackBranches << endl;
150
152 cout << "++++++++++++++++++++++++++++++++" << endl;
153 fOutputTrackEvent->PrintEvent();
154 cout << "++++++++++++++++++++++++++++++++" << endl;
156 }
157
158 return fOutputTrackEvent;
159}
160
164void TRestTrackReconnectionProcess::BreakTracks(TRestVolumeHits* hits, vector<TRestVolumeHits>& hitSets,
165 Double_t nSigma) {
166 hitSets.clear();
168 cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << endl;
169 cout << "BreakTracks. Breaking tracks into hits subsets." << endl;
170 }
171
172 TRestVolumeHits subHits;
173 for (unsigned int n = 0; n < hits->GetNumberOfHits(); n++) {
174 Double_t x = hits->GetX(n);
175 Double_t y = hits->GetY(n);
176 Double_t z = hits->GetZ(n);
177 Double_t sX = hits->GetSigmaX(n);
178 Double_t sY = hits->GetSigmaY(n);
179 Double_t sZ = hits->GetSigmaZ(n);
180 Double_t energy = hits->GetEnergy(n);
181
183 cout << "Distance : " << hits->GetDistance(n - 1, n);
184 if (hits->GetDistance(n - 1, n) > fMeanDistance + nSigma * fSigma) cout << " BREAKKKK";
185 cout << endl;
186 }
187
188 if (n > 0 && hits->GetDistance(n - 1, n) > fMeanDistance + nSigma * fSigma) {
189 hitSets.push_back(subHits);
190 subHits.RemoveHits();
191 }
192
193 subHits.AddHit(x, y, z, energy, 0, hits->GetType(n), sX, sY, sZ);
194
196 cout << "H : " << n << " X : " << x << " Y : " << y << " Z : " << z << endl;
197 }
198
199 hitSets.push_back(subHits);
200
202 cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << endl;
203}
204
205void TRestTrackReconnectionProcess::ReconnectTracks(vector<TRestVolumeHits>& hitSets) {
207 cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << endl;
208 cout << "ReconnectTracks. Connecting back sub tracks " << endl;
209 }
210
211 Int_t nSubTracks = hitSets.size();
212
213 if (nSubTracks == 1) return;
214
215 Double_t minDistance = 1.e10;
216
217 Int_t tracks[2][2] = {{0, 0}, {0, 0}};
218
219 vector<Int_t> nHits(nSubTracks);
220 for (int i = 0; i < nSubTracks; i++) nHits[i] = hitSets[i].GetNumberOfHits();
221
223 cout << "ORIGINAL" << endl;
224 cout << "--------" << endl;
225 for (int i = 0; i < nSubTracks; i++) {
226 cout << "Subset : " << i << endl;
227 cout << " Sub hits : " << nHits[i] << endl;
228
229 hitSets[i].PrintHits();
230 }
231 cout << "--------" << endl;
232 }
233
234 /* {{{ Finds the closest sub-track extremes */
235 for (int i = 0; i < nSubTracks; i++) {
236 for (int j = 0; j < nSubTracks; j++) {
237 if (i != j) {
238 Int_t x1_0 = hitSets[i].GetX(0);
239 Int_t x1_1 = hitSets[i].GetX(nHits[i] - 1);
240
241 Int_t y1_0 = hitSets[i].GetY(0);
242 Int_t y1_1 = hitSets[i].GetY(nHits[i] - 1);
243
244 Int_t z1_0 = hitSets[i].GetZ(0);
245 Int_t z1_1 = hitSets[i].GetZ(nHits[i] - 1);
246
247 Int_t x2_0 = hitSets[j].GetX(0);
248 Int_t x2_1 = hitSets[j].GetX(nHits[j] - 1);
249
250 Int_t y2_0 = hitSets[j].GetY(0);
251 Int_t y2_1 = hitSets[j].GetY(nHits[j] - 1);
252
253 Int_t z2_0 = hitSets[j].GetZ(0);
254 Int_t z2_1 = hitSets[j].GetZ(nHits[j] - 1);
255
256 Double_t d;
257 d = TMath::Sqrt((x1_0 - x2_0) * (x1_0 - x2_0) + (y1_0 - y2_0) * (y1_0 - y2_0) +
258 (z1_0 - z2_0) * (z1_0 - z2_0));
259
260 if (d < minDistance) {
261 tracks[0][0] = i;
262 tracks[0][1] = 0;
263 tracks[1][0] = j;
264 tracks[1][1] = 0;
265 minDistance = d;
266 }
267
268 d = TMath::Sqrt((x1_0 - x2_1) * (x1_0 - x2_1) + (y1_0 - y2_1) * (y1_0 - y2_1) +
269 (z1_0 - z2_1) * (z1_0 - z2_1));
270
271 if (d < minDistance) {
272 tracks[0][0] = i;
273 tracks[0][1] = 0;
274 tracks[1][0] = j;
275 tracks[1][1] = 1;
276 minDistance = d;
277 }
278
279 d = TMath::Sqrt((x1_1 - x2_0) * (x1_1 - x2_0) + (y1_1 - y2_0) * (y1_1 - y2_0) +
280 (z1_1 - z2_0) * (z1_1 - z2_0));
281
282 if (d < minDistance) {
283 tracks[0][0] = i;
284 tracks[0][1] = 1;
285 tracks[1][0] = j;
286 tracks[1][1] = 0;
287 minDistance = d;
288 }
289
290 d = TMath::Sqrt((x1_1 - x2_1) * (x1_1 - x2_1) + (y1_1 - y2_1) * (y1_1 - y2_1) +
291 (z1_1 - z2_1) * (z1_1 - z2_1));
292
293 if (d < minDistance) {
294 tracks[0][0] = i;
295 tracks[0][1] = 1;
296 tracks[1][0] = j;
297 tracks[1][1] = 1;
298 minDistance = d;
299 }
300 }
301 }
302 }
303 /* }}} */
304
305 /* {{{ Debug output
306 cout << "Tracks" << endl;
307 cout << tracks[0][0] << " ::: " << tracks[0][1] << endl;
308 cout << tracks[1][0] << " ::: " << tracks[1][1] << endl;
309 }}} */
310
311 TRestVolumeHits newHits;
312 newHits.RemoveHits();
313
314 Int_t tck1 = tracks[0][0];
315 Int_t tck2 = tracks[1][0];
316
317 /* {{{ Rejoins the closest sub-track extremes into 1-single track */
318 if (tracks[0][1] == 0 && tracks[1][1] == 0) {
319 // We invert the first and add the second
320 for (int n = nHits[tck1] - 1; n >= 0; n--) newHits.AddHit(hitSets[tck1], n);
321
322 for (int n = 0; n < nHits[tck2]; n++) newHits.AddHit(hitSets[tck2], n);
323 } else if (tracks[0][1] == 1 && tracks[1][1] == 0) {
324 // We add the first and then the second
325
326 for (int n = 0; n < nHits[tck1]; n++) newHits.AddHit(hitSets[tck1], n);
327
328 for (int n = 0; n < nHits[tck2]; n++) newHits.AddHit(hitSets[tck2], n);
329 } else if (tracks[0][1] == 0 && tracks[1][1] == 1) {
330 // We add the second and then the first
331
332 for (int n = 0; n < nHits[tck2]; n++) newHits.AddHit(hitSets[tck2], n);
333
334 for (int n = 0; n < nHits[tck1]; n++) newHits.AddHit(hitSets[tck1], n);
335 } else {
336 // We add the first and invert the second
337
338 for (int n = 0; n < nHits[tck1]; n++) newHits.AddHit(hitSets[tck1], n);
339
340 for (int n = nHits[tck2] - 1; n >= 0; n--) newHits.AddHit(hitSets[tck2], n);
341 }
342
343 hitSets.erase(hitSets.begin() + tck2);
344 hitSets.erase(hitSets.begin() + tck1);
345 hitSets.push_back(newHits);
346 /* }}} */
347
348 nSubTracks = hitSets.size();
349
351 cout << "New subtracks : " << nSubTracks << endl;
352
353 cout << "AFTER REMOVAL" << endl;
354 cout << "--------" << endl;
355 for (int i = 0; i < nSubTracks; i++) {
356 cout << "Subset : " << i << endl;
357 cout << " Sub hits : " << nHits[i] << endl;
358
359 hitSets[i].PrintHits();
360 }
361 cout << "--------" << endl;
363 }
364
365 if (nSubTracks > 1) ReconnectTracks(hitSets);
366
368 cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << endl;
369}
370
371Int_t TRestTrackReconnectionProcess::GetTrackBranches(TRestHits& h, Double_t nSigma) {
372 Int_t breaks = 0;
373 Int_t nHits = h.GetNumberOfHits();
374
375 for (int n = 1; n < nHits; n++)
376 if (h.GetDistance(n - 1, n) > fMeanDistance + nSigma * fSigma) breaks++;
377 return breaks;
378}
379
381
383 if (GetParameter("splitTrack", "false") == "true")
384 fSplitTrack = true;
385 else
386 fSplitTrack = false;
387
388 fNSigmas = StringToDouble(GetParameter("nSigmas", "5"));
389}
390
391void TRestTrackReconnectionProcess::SetDistanceMeanAndSigma(TRestHits* h) {
392 Int_t nHits = h->GetNumberOfHits();
393
394 fMeanDistance = 0;
395 for (int n = 1; n < nHits; n++) fMeanDistance += h->GetDistance(n - 1, n);
396 fMeanDistance /= nHits;
397
398 fSigma = TMath::Sqrt(fMeanDistance);
399
401 cout << "-----> Node distance average ; " << fMeanDistance << endl;
402 cout << "-----> Node distance sigma : " << fSigma << endl;
403 cout << endl;
404 }
405}
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
It saves a 3-coordinate position and an energy for each punctual deposition.
Definition: TRestHits.h:39
Double_t GetHitsPathLength(Int_t n=0, Int_t m=0) const
It determines the distance required to travel from hit n to hit m adding all the distances of the hit...
Definition: TRestHits.cxx:1179
Int_t LoadConfigFromFile(const std::string &configFilename, const std::string &sectionName="")
Give the file name, find out the corresponding section. Then call the main starter.
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
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.
@ REST_Debug
+show the defined debug messages
void EndProcess() override
To be executed at the end of the run (outside event loop)
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
Process one event.
void BreakTracks(TRestVolumeHits *hits, std::vector< TRestVolumeHits > &hitSets, Double_t nSigma=2.)
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
void Initialize() override
Making default settings.
void PrintMetadata() override
Implemented it in the derived metadata class to print out specific metadata information.
void RemoveHits()
It removes all hits inside the class.
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
Double_t StringToDouble(std::string in)
Gets a double from a string.