REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestDetectorHits3DReconstructionProcess.cxx
1
11
12#include "TRestDetectorHits3DReconstructionProcess.h"
13
14#include "TFunction.h"
15#include "TLine.h"
16#include "TMarker.h"
17
18using namespace std;
19#define XWidth 96.7
20#define YWidth 96.3
21#define PITCH 6.2
22#define PlaneMaxX 800
23#define PlaneMaxY 800
24struct regionhit {
25 double x = 0;
26 double y = 0;
27 double e = 0;
28 bool iszombie() const { return e == 0; }
29 void add(const regionhit& h) {
30 x = (x * e + h.x * h.e) / (e + h.e);
31 y = (y * e + h.y * h.e) / (e + h.e);
32 e += h.e;
33 }
34 static double dist(const regionhit& h1, const regionhit& h2) {
35 return sqrt((h1.x - h2.x) * (h1.x - h2.x) + (h1.y - h2.y) * (h1.y - h2.y));
36 }
37};
38
39struct stripehit {
40 double x1 = 0;
41 double x2 = 0;
42 double y1 = 0;
43 double y2 = 0;
44 double e = 0;
45 REST_HitType type;
46
47 void Print() { cout << "x1: " << x1 << ", x2: " << x2 << ", y1: " << y1 << ", y2: " << y2 << endl; }
48
49 bool iszombie() const { return e == 0; }
50
51 static bool IsRectCross(const stripehit& s1, const stripehit& s2) {
52 bool ret = min(s1.x1, s1.x2) <= max(s2.x1, s2.x2) && min(s2.x1, s2.x2) <= max(s1.x1, s1.x2) &&
53 min(s1.y1, s1.y2) <= max(s2.y1, s2.y2) && min(s2.y1, s2.y2) <= max(s1.y1, s1.y2);
54 return ret;
55 }
56
57 static bool IsLineSegmentCross(const stripehit& s1, const stripehit& s2) {
58 if (((s2.x1 - s1.x1) * (s2.y1 - s2.y2) - (s2.y1 - s1.y1) * (s2.x1 - s2.x2)) *
59 ((s2.x1 - s1.x2) * (s2.y1 - s2.y2) - (s2.y1 - s1.y2) * (s2.x1 - s2.x2)) <
60 0 ||
61 ((s1.x1 - s2.x1) * (s1.y1 - s1.y2) - (s1.y1 - s2.y1) * (s1.x1 - s1.x2)) *
62 ((s1.x1 - s2.x2) * (s1.y1 - s1.y2) - (s1.y1 - s2.y2) * (s1.x1 - s1.x2)) <
63 0)
64 return true;
65 else
66 return false;
67 }
68
69 static bool GetCrossPoint(const stripehit& s1, const stripehit& s2, double& x, double& y) {
70 if (IsRectCross(s1, s2)) {
71 if (IsLineSegmentCross(s1, s2)) {
72 long tmpLeft, tmpRight;
73 tmpLeft = (s2.x2 - s2.x1) * (s1.y1 - s1.y2) - (s1.x2 - s1.x1) * (s2.y1 - s2.y2);
74 tmpRight = (s1.y1 - s2.y1) * (s1.x2 - s1.x1) * (s2.x2 - s2.x1) +
75 s2.x1 * (s2.y2 - s2.y1) * (s1.x2 - s1.x1) -
76 s1.x1 * (s1.y2 - s1.y1) * (s2.x2 - s2.x1);
77
78 x = (int)((double)tmpRight / (double)tmpLeft);
79
80 tmpLeft = (s1.x1 - s1.x2) * (s2.y2 - s2.y1) - (s1.y2 - s1.y1) * (s2.x1 - s2.x2);
81 tmpRight = s1.y2 * (s1.x1 - s1.x2) * (s2.y2 - s2.y1) +
82 (s2.x2 - s1.x2) * (s2.y2 - s2.y1) * (s1.y1 - s1.y2) -
83 s2.y2 * (s2.x1 - s2.x2) * (s1.y2 - s1.y1);
84 y = (int)((double)tmpRight / (double)tmpLeft);
85 return true;
86 }
87 }
88 return false;
89 }
90
91 static double dist(const stripehit& h1, const stripehit& h2) {
92 if (IsRectCross(h1, h2) && IsLineSegmentCross(h1, h2)) {
93 return 0;
94 } else {
95 double x = h1.x1;
96 double y = h1.y1;
97 double d1 = abs(((x - h2.x1) * (h2.y2 - h2.y1) - (h2.x2 - h2.x1) * (y - h2.y1)) /
98 sqrt((h2.x2 - h2.x1) * (h2.x2 - h2.x1) + (h2.y2 - h2.y1) * (h2.y2 - h2.y1)));
99
100 x = h1.x2;
101 y = h1.y2;
102 double d2 = abs(((x - h2.x1) * (h2.y2 - h2.y1) - (h2.x2 - h2.x1) * (y - h2.y1)) /
103 sqrt((h2.x2 - h2.x1) * (h2.x2 - h2.x1) + (h2.y2 - h2.y1) * (h2.y2 - h2.y1)));
104
105 x = h2.x1;
106 y = h2.y1;
107 double d3 = abs(((x - h1.x1) * (h1.y2 - h1.y1) - (h1.x2 - h1.x1) * (y - h1.y1)) /
108 sqrt((h1.x2 - h1.x1) * (h1.x2 - h1.x1) + (h1.y2 - h1.y1) * (h1.y2 - h1.y1)));
109
110 x = h2.x2;
111 y = h2.y2;
112 double d4 = abs(((x - h1.x1) * (h1.y2 - h1.y1) - (h1.x2 - h1.x1) * (y - h1.y1)) /
113 sqrt((h1.x2 - h1.x1) * (h1.x2 - h1.x1) + (h1.y2 - h1.y1) * (h1.y2 - h1.y1)));
114
115 return min({d1, d2, d3, d4});
116 }
117 }
118
119 friend regionhit operator&(const stripehit& s1, const stripehit& s2) {
120 if (s1.type * s2.type == XZ * YZ) {
121 if (!s1.iszombie() && !s2.iszombie()) {
122 double x;
123 double y;
124 if (stripehit::GetCrossPoint(s1, s2, x, y)) {
125 regionhit hit;
126 hit.x = x;
127 hit.y = y;
128 hit.e = s1.e + s2.e;
129 return hit;
130 }
131 }
132 }
133 return regionhit();
134 }
135
136 stripehit(TRestHits* hits, int i) {
137 type = hits->GetType(i);
138 if (type == XZ) {
139 y1 = hits->GetY(i) - YWidth;
140 y2 = hits->GetY(i) + YWidth;
141 x1 = hits->GetX(i);
142 x2 = hits->GetX(i);
143 } else if (type == YZ) {
144 y1 = hits->GetY(i);
145 y2 = hits->GetY(i);
146 x1 = hits->GetX(i) - XWidth;
147 x2 = hits->GetX(i) + XWidth;
148 } else {
149 return;
150 }
151 e = hits->GetEnergy(i);
152 }
153
154 stripehit(double x1, double x2, double y1, double y2, double e = 0, REST_HitType type = unknown) {
155 this->x1 = x1;
156 this->x2 = x2;
157 this->y1 = y1;
158 this->y2 = y2;
159 this->e = e;
160 this->type = type;
161 }
162};
163
165
166 TRestDetectorHits3DReconstructionProcess::TRestDetectorHits3DReconstructionProcess() {
167 Initialize();
168}
169
170TRestDetectorHits3DReconstructionProcess::~TRestDetectorHits3DReconstructionProcess() {
171 delete fOutputHitsEvent;
172}
173
175 SetSectionName(this->ClassName());
176 SetLibraryVersion(LIBRARY_VERSION);
177
178 fInputHitsEvent = nullptr;
179 fOutputHitsEvent = new TRestDetectorHitsEvent();
180}
181
185 // write here the information to print
186
188 EndPrintProcess();
189}
190
192 if (fDraw) {
193 htemp = new TH2D("hhits", "hhits", 100, -PlaneMaxX, PlaneMaxX, 100, -PlaneMaxY, PlaneMaxY);
194 CreateCanvas();
195 }
196#ifdef REST_Geant4Lib
197 fCompareProc = GetFriendLive("TRestGeant4ToDetectorHitsProcess");
198#endif
199}
200
202 fInputHitsEvent = (TRestDetectorHitsEvent*)inputEvent;
203
204 // sort with z from small to large
205 fInputHitsEvent->Sort();
206
207 double lastz = 0;
208 double totalambiguity = 0;
209 double Nlayers = 0;
210 for (unsigned int n = 0; n < fInputHitsEvent->GetNumberOfHits(); n++) {
211 double z = fInputHitsEvent->GetZ(n);
212 if (z == lastz) continue;
213
214 lastz = z;
215
216 // find the hits near this z slice
217 map<int, double> ids; //[id, weight]
218 ids[n] = 1;
219 for (int i = n - 1; i >= 0; i--) {
220 if (abs(fInputHitsEvent->GetZ(i) - z) < fZRange * 2) {
221 ids[i] = TMath::Gaus(abs(fInputHitsEvent->GetZ(i) - z), 0, fZRange);
222 } else {
223 break;
224 }
225 }
226 for (unsigned int i = n + 1; i < fInputHitsEvent->GetNumberOfHits(); i++) {
227 if (abs(fInputHitsEvent->GetZ(i) - z) < fZRange * 2) {
228 ids[i] = TMath::Gaus(abs(fInputHitsEvent->GetZ(i) - z), 0, fZRange);
229 } else {
230 break;
231 }
232 }
233
234 // extract stripe hits
235 vector<stripehit> stripehits;
236 for (auto i : ids) {
237 stripehit h = stripehit(fInputHitsEvent->GetHits(), i.first);
238 h.e *= i.second;
239 if (!h.iszombie()) {
240 if (stripehits.size() > 0) {
241 for (unsigned int k = 0; k < stripehits.size(); k++) {
242 stripehit& _h = stripehits[k];
243 if (_h.x1 == h.x1 && _h.x2 == h.x2 && _h.y1 == h.y1 && _h.y2 == h.y2) {
244 _h.e += h.e;
245 break;
246 } else if (k == stripehits.size() - 1) {
247 stripehits.push_back(h);
248 }
249 }
250 } else {
251 stripehits.push_back(h);
252 }
253 }
254 }
255
256 if (stripehits.size() > 50) {
257 RESTWarning << "(TRestDetectorHits3DReconstructionProcess) event id: " << fInputHitsEvent->GetID()
258 << ", z: " << z << ", bad frame, too much hits! (" << stripehits.size() << ")"
259 << RESTendl;
260 continue;
261 }
262
264 cout << "stripehits: ";
265 for (auto h : stripehits) {
266 cout << h.x1 << "," << h.y1 << "," << h.x2 << "," << h.y2 << "," << h.e << " ";
267 }
268 cout << endl;
269 }
270
271 // find all the crossing points of stripe hits
272 vector<regionhit> regionhits;
273 double layerambiguity = 0;
274 set<int> ambcalculatedstripes;
275 for (unsigned int i = 0; i < stripehits.size(); i++) {
276 vector<int> crossedids;
277 double crossedsumenergy = 0;
278 for (unsigned int j = 0; j < stripehits.size(); j++) {
279 if (i == j) continue;
280 if (stripehit::IsRectCross(stripehits[i], stripehits[j])) {
281 crossedids.push_back(j);
282 crossedsumenergy += stripehits[j].e;
283 }
284 }
285
286 for (int id : crossedids) {
287 regionhit rh = stripehits[i] & stripehits[id];
288 rh.e = stripehits[i].e * stripehits[id].e / crossedsumenergy;
289
290 if (regionhits.size() > 0) {
291 for (unsigned int k = 0; k < regionhits.size(); k++) {
292 regionhit& _rh = regionhits[k];
293 if (_rh.x == rh.x && _rh.y == rh.y) {
294 _rh.e += rh.e;
295 break;
296 } else if (k == regionhits.size() - 1) {
297 regionhits.push_back(rh);
298 }
299 }
300 } else {
301 regionhits.push_back(rh);
302 }
303 }
304
305 // calculate ambiguouity
306 if (ambcalculatedstripes.count(i) == 0 && crossedids.size() > 0) {
307 for (int id : crossedids) {
308 ambcalculatedstripes.insert(id);
309 }
310
311 auto line = stripehits[i];
312 auto newline = stripehits[crossedids[0]];
313 vector<int> crossedids_newline;
314 for (unsigned int j = 0; j < stripehits.size(); j++) {
315 if (j == (unsigned int)crossedids[0]) continue;
316 if (stripehit::IsRectCross(stripehits[j], newline)) {
317 crossedids_newline.push_back(j);
318 }
319 }
320 for (int id : crossedids_newline) {
321 ambcalculatedstripes.insert(id);
322 }
323
324 vector<pair<double, double>> V_PosE;
325 vector<pair<double, double>> H_PosE;
326
327 if (line.x1 == line.x2) {
328 // cout << "adding H from crossed lines of first crossed line(" << crossedids[0]
329 // << ") of line: " << i << endl;
330 for (int id : crossedids_newline) {
331 H_PosE.push_back({stripehits[id].x1, stripehits[id].e});
332 }
333 } else if (line.y1 == line.y2) {
334 // cout << "adding V from crossed lines of first crossed line(" << crossedids[0]
335 // << ") of line: " << i << endl;
336 for (int id : crossedids_newline) {
337 V_PosE.push_back({stripehits[id].y1, stripehits[id].e});
338 }
339 }
340
341 if (newline.x1 == newline.x2) {
342 // cout << "adding H from crossed lines of line: " << i << endl;
343 for (int id : crossedids) {
344 H_PosE.push_back({stripehits[id].x1, stripehits[id].e});
345 }
346 } else if (newline.y1 == newline.y2) {
347 // cout << "adding V from crossed lines of line: " << i << endl;
348 for (int id : crossedids) {
349 V_PosE.push_back({stripehits[id].y1, stripehits[id].e});
350 }
351 }
352
353 // sort with position form small to large
354 auto comp = [](const pair<double, double>& p1, const pair<double, double>& p2) -> bool {
355 return p1.first < p2.first;
356 };
357 sort(V_PosE.begin(), V_PosE.end(), comp);
358 sort(H_PosE.begin(), H_PosE.end(), comp);
359
360 for (unsigned int j = 1; j < V_PosE.size(); j++) {
361 if (V_PosE[j].first - V_PosE[j - 1].first > PITCH) {
362 V_PosE.insert(V_PosE.begin() + j, {(V_PosE[j].first + V_PosE[j - 1].first) / 2, 0});
363 j++;
364 }
365 }
366 V_PosE.insert(V_PosE.begin(), {(*V_PosE.begin()).first - 1, 0});
367 V_PosE.insert(V_PosE.end(), {(*(V_PosE.end() - 1)).first + 1, 0});
368
369 for (unsigned int j = 1; j < H_PosE.size(); j++) {
370 if (H_PosE[j].first - H_PosE[j - 1].first > PITCH) {
371 H_PosE.insert(H_PosE.begin() + j, {(H_PosE[j].first + H_PosE[j - 1].first) / 2, 0});
372 j++;
373 }
374 }
375 H_PosE.insert(H_PosE.begin(), {(*H_PosE.begin()).first - 1, 0});
376 H_PosE.insert(H_PosE.end(), {(*(H_PosE.end() - 1)).first + 1, 0});
377
379 cout << "V: ";
380 for (auto pose : V_PosE) {
381 cout << pose.first << "," << pose.second << " ";
382 }
383 cout << endl;
384
385 cout << "H: ";
386 for (auto pose : H_PosE) {
387 cout << pose.first << "," << pose.second << " ";
388 }
389 cout << endl;
390 }
391
392 int Vsegs = 0;
393 int Hsegs = 0;
394
395 for (unsigned int j = 1; j < V_PosE.size() - 1; j++) {
396 if (V_PosE[j].second > V_PosE[j - 1].second && V_PosE[j].second > V_PosE[j + 1].second) {
397 Vsegs++;
398 }
399 }
400
401 for (unsigned int j = 1; j < H_PosE.size() - 1; j++) {
402 if (H_PosE[j].second > H_PosE[j - 1].second && H_PosE[j].second > H_PosE[j + 1].second) {
403 Hsegs++;
404 }
405 }
406
408 cout << i << " z: " << z << " " << Vsegs << " " << Hsegs << " -> "
409 << LogAmbiguity(Vsegs, Hsegs) << endl;
410 cout << endl;
411 }
412
413 if (Vsegs == 0) Vsegs = 1;
414 if (Hsegs == 0) Hsegs = 1;
415
416 layerambiguity += LogAmbiguity(Vsegs, Hsegs);
417 }
418 }
419 // cout << "z: " << z << ", amb: " << layerambiguity << endl;
420 totalambiguity += layerambiguity;
421
422 // merge the cossing points
423 vector<regionhit> regionhits_merged;
424 set<int> mergeflag_all;
425 while (mergeflag_all.size() < regionhits.size()) {
426 // find the initial point(with max energy)
427 double max = 0;
428 int maxposition;
429 for (unsigned int i = 0; i < regionhits.size(); i++) {
430 if (mergeflag_all.count(i) == 0) {
431 if (regionhits[i].e > max) {
432 max = regionhits[i].e;
433 maxposition = i;
434 }
435 }
436 }
437 set<int> mergeflag;
438 mergeflag.insert(maxposition);
439
440 // loop over regionhits to find any hits that is **connected** to the initial point
441 for (auto _i = mergeflag.begin(); _i != mergeflag.end();) {
442 int i = *_i;
443
444 // cout << i << ": ";
445 // for (auto __i : mergeflag) cout << __i << " ";
446 // cout << endl;
447
448 bool inserted = false;
449 for (unsigned int j = 0; j < regionhits.size(); j++) {
450 if (regionhit::dist(regionhits[i], regionhits[j]) < PITCH &&
451 regionhits[i].e > regionhits[j].e && mergeflag_all.count(j) == 0) {
452 auto insertresult = mergeflag.insert(j);
453 inserted += insertresult.second;
454 }
455 }
456 // if inserted, we go back to the begin incase it is inserted to the former
457 if (inserted)
458 _i = mergeflag.begin();
459 else
460 _i++;
461 }
462
463 // cout << z << " " << regionhits.size() << " " << mergeflag.size() << endl;
464 // cout << endl;
465
466 // the collection of all the connected hits are merged
467 regionhit h;
468 for (auto i : mergeflag) {
469 mergeflag_all.insert(i);
470 h.add(regionhits[i]);
471 }
472 regionhits_merged.push_back(h);
473 }
474 if (regionhits_merged.size() > 0) Nlayers++;
475
476 if (fDraw && (layerambiguity > fDrawThres)) {
477 if (regionhits.size() == 0) continue;
478 double maxenergyofregionhits =
479 (*min_element(regionhits.begin(), regionhits.end(),
480 [](const regionhit& h1, const regionhit& h2) -> bool { return h1.e > h2.e; }))
481 .e;
482
483 fCanvas->Clear();
484 htemp->SetStats(false);
485 htemp->SetTitle(Form("event id %i, z = %.1f", fInputHitsEvent->GetID(), z));
486 htemp->Draw();
487 vector<TLine*> lines;
488 vector<TMarker*> markers;
489 for (auto h : stripehits) {
490 TLine* line = new TLine(h.x1, h.y1, h.x2, h.y2);
491 line->Draw();
492 lines.push_back(line);
493 }
494 for (auto rh : regionhits) {
495 TMarker* marker = new TMarker(rh.x, rh.y, kFullDotLarge);
496 marker->SetMarkerColor(kGreen);
497 marker->SetMarkerSize(rh.e / maxenergyofregionhits);
498 marker->Draw();
499 markers.push_back(marker);
500 }
501 for (auto rhm : regionhits_merged) {
502 TMarker* marker = new TMarker(rhm.x, rhm.y, kFullDotLarge);
503 marker->SetMarkerColor(kRed);
504 marker->Draw();
505 markers.push_back(marker);
506 }
507
508 fCanvas->Update();
509 GetChar();
510 for (auto l : lines) {
511 delete l;
512 }
513 for (auto m : markers) {
514 delete m;
515 }
516 }
517
518 // for (auto rh : regionhits) {
519 for (auto rh : regionhits_merged) {
520 fOutputHitsEvent->AddHit(rh.x, rh.y, z, rh.e, 0, XYZ);
521 }
522 }
523
524 // scale the total energy
525 if (fDoEnergyScaling) {
526 double e1 = fInputHitsEvent->GetTotalEnergy();
527 double e2 = fOutputHitsEvent->GetTotalEnergy();
528 for (auto h : *fOutputHitsEvent->GetHits()) {
529 h.e() = h.e() / e2 * e1;
530 }
531 }
532
533 SetObservableValue("MeanAmbiguity", totalambiguity / Nlayers);
534 SetObservableValue("DiffRecon", numeric_limits<double>::quiet_NaN());
535 if (fCompareProc != nullptr && fOutputHitsEvent->GetNumberOfHits() > 0 &&
536 (fObservablesDefined.count("DiffRecon") != 0 || fDynamicObs)) {
537 TRestDetectorHitsEvent* reference = (TRestDetectorHitsEvent*)fCompareProc->GetOutputEvent();
538 auto hits1 = *fOutputHitsEvent->GetHits();
539 auto hits2 = *reference->GetHits();
540
541 double maxz1 = (*min_element(hits1.begin(), hits1.end(),
542 [](const TRestHits::iterator& h1,
543 const TRestHits::iterator& h2) -> bool { return h1.z() > h2.z(); }))
544 .z();
545 double maxz2 = (*min_element(hits2.begin(), hits2.end(),
546 [](const TRestHits::iterator& h1,
547 const TRestHits::iterator& h2) -> bool { return h1.z() > h2.z(); }))
548 .z();
549 double dz = maxz2 - maxz1;
550
551 double mindistmean = std::numeric_limits<Double_t>::max();
552 for (double i = -fZRange * 2; i <= fZRange * 2; i += fZRange / 2) {
553 double distsum2 = 0;
554 for (auto hit : hits1) {
555 auto pos = TVector3(hit.x(), hit.y(), hit.z() + dz);
556 int n = hits2.GetClosestHit(pos);
557 auto dist2 = (pos - hits2.GetPosition(n)).Mag2();
558 distsum2 += dist2;
559 }
560 double distmean = sqrt(distsum2) / fOutputHitsEvent->GetNumberOfHits();
561 if (distmean < mindistmean) {
562 mindistmean = distmean;
563 }
564 }
565 SetObservableValue("DiffRecon", mindistmean);
566 }
567
568 return fOutputHitsEvent;
569}
570
571int TRestDetectorHits3DReconstructionProcess::Ambiguity(const int& n, const int& m) {
572 if (n <= 0 || m <= 0) return 0;
573 if (n == 1 || m == 1) return 1;
574 if (n > 5 && m > 5) return 1e9;
575 if (n > 8 || m > 8) return 1e9;
576
577 int N = min({n, m});
578 int M = max({n, m});
579
580 int ambiguity = pow(N, M);
581 for (int i = N - 1; i > 0; i--) {
582 // value of nC(n-i)
583 int combinations = Factorial(N) / Factorial(N - i) / Factorial(i);
584 ambiguity -= Ambiguity(i, M) * combinations;
585 }
586 return ambiguity;
587}
588
589int TRestDetectorHits3DReconstructionProcess::Factorial(const int& n) {
590 int result = n;
591 int N = n;
592 while (N > 1) result *= (--N);
593 return result;
594}
595
597 if (fDraw) {
598 delete htemp;
599 delete fCanvas;
600 }
601}
602
604 fZRange = StringToDouble(GetParameter("zRange", "5"));
605 fDraw = StringToBool(GetParameter("draw", "false"));
606 if (fDraw) fSingleThreadOnly = true;
607 fDrawThres = StringToDouble(GetParameter("drawThreshold", "3"));
608 fDoEnergyScaling = StringToBool(GetParameter("scaleE", "true"));
609
610 fCanvasSize = StringTo2DVector(GetParameter("canvasSize", "(800,600)"));
611}
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
void PrintMetadata() override
Implemented it in the derived metadata class to print out specific metadata information.
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
Process one event.
void EndProcess() override
To be executed at the end of the run (outside event loop)
Double_t GetZ(int n) const
Returns the Z-coordinate of hit entry n in mm.
void AddHit(Double_t x, Double_t y, Double_t z, Double_t en, Double_t t=0, REST_HitType type=XYZ)
Adds a new hit to this event.
TVector2 fCanvasSize
Canvas size.
void BeginPrintProcess()
[name, cut range]
TCanvas * fCanvas
< Canvas for some viewer event
void CreateCanvas()
Create the canvas.
bool fDynamicObs
It defines whether to use added observables only or all the observables appear in the code.
virtual RESTValue GetOutputEvent() const =0
Get pointer to output event. Must be implemented in the derived class.
std::map< std::string, int > fObservablesDefined
Stores the list of all the appeared process observables in the code.
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
endl_t RESTendl
Termination flag object for TRestStringOutput.
TRestStringOutput::REST_Verbose_Level fVerboseLevel
Verbose level used to print debug info.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
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
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.
TVector2 StringTo2DVector(std::string in)
Gets a 2D-vector from a string.