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.emplace_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.emplace_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 TRestVolumeHits newHits;
305 newHits.RemoveHits();
306
307 Int_t tck1 = tracks[0][0];
308 Int_t tck2 = tracks[1][0];
309
310 /* {{{ Rejoins the closest sub-track extremes into 1-single track */
311 if (tracks[0][1] == 0 && tracks[1][1] == 0) {
312 // We invert the first and add the second
313 for (int n = nHits[tck1] - 1; n >= 0; n--) newHits.AddHit(hitSets[tck1], n);
314
315 for (int n = 0; n < nHits[tck2]; n++) newHits.AddHit(hitSets[tck2], n);
316 } else if (tracks[0][1] == 1 && tracks[1][1] == 0) {
317 // We add the first and then the second
318
319 for (int n = 0; n < nHits[tck1]; n++) newHits.AddHit(hitSets[tck1], n);
320
321 for (int n = 0; n < nHits[tck2]; n++) newHits.AddHit(hitSets[tck2], n);
322 } else if (tracks[0][1] == 0 && tracks[1][1] == 1) {
323 // We add the second and then the first
324
325 for (int n = 0; n < nHits[tck2]; n++) newHits.AddHit(hitSets[tck2], n);
326
327 for (int n = 0; n < nHits[tck1]; n++) newHits.AddHit(hitSets[tck1], n);
328 } else {
329 // We add the first and invert the second
330
331 for (int n = 0; n < nHits[tck1]; n++) newHits.AddHit(hitSets[tck1], n);
332
333 for (int n = nHits[tck2] - 1; n >= 0; n--) newHits.AddHit(hitSets[tck2], n);
334 }
335
336 hitSets.erase(hitSets.begin() + tck2);
337 hitSets.erase(hitSets.begin() + tck1);
338 hitSets.emplace_back(newHits);
339
340 nSubTracks = hitSets.size();
341
343 cout << "New subtracks : " << nSubTracks << endl;
344
345 cout << "AFTER REMOVAL" << endl;
346 cout << "--------" << endl;
347 for (int i = 0; i < nSubTracks; i++) {
348 cout << "Subset : " << i << endl;
349 cout << " Sub hits : " << nHits[i] << endl;
350
351 hitSets[i].PrintHits();
352 }
353 cout << "--------" << endl;
355 }
356
357 if (nSubTracks > 1) ReconnectTracks(hitSets);
358
360 cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << endl;
361}
362
363Int_t TRestTrackReconnectionProcess::GetTrackBranches(TRestHits& h, Double_t nSigma) {
364 Int_t breaks = 0;
365 Int_t nHits = h.GetNumberOfHits();
366
367 for (int n = 1; n < nHits; n++)
368 if (h.GetDistance(n - 1, n) > fMeanDistance + nSigma * fSigma) breaks++;
369 return breaks;
370}
371
373
375 if (GetParameter("splitTrack", "false") == "true")
376 fSplitTrack = true;
377 else
378 fSplitTrack = false;
379
380 fNSigmas = StringToDouble(GetParameter("nSigmas", "5"));
381}
382
383void TRestTrackReconnectionProcess::SetDistanceMeanAndSigma(TRestHits* h) {
384 Int_t nHits = h->GetNumberOfHits();
385
386 fMeanDistance = 0;
387 for (int n = 1; n < nHits; n++) fMeanDistance += h->GetDistance(n - 1, n);
388 fMeanDistance /= nHits;
389
390 fSigma = TMath::Sqrt(fMeanDistance);
391
393 cout << "-----> Node distance average ; " << fMeanDistance << endl;
394 cout << "-----> Node distance sigma : " << fSigma << endl;
395 cout << endl;
396 }
397}
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.