REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestHits.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
75
76#include "TRestHits.h"
77
78#include <limits.h>
79
80#include "TFitResult.h"
81#include "TROOT.h"
82
83using namespace std;
84using namespace TMath;
85
86ClassImp(TRestHits);
87
91TRestHits::TRestHits() = default;
92
96TRestHits::~TRestHits() = default;
97
101Bool_t TRestHits::areXY() const {
102 for (unsigned int i = 0; i < GetNumberOfHits(); i++) {
103 if (fType[i] != XY) {
104 // all hits should fit this condition to be considered XY
105 return false;
106 } else if (i == GetNumberOfHits() - 1) {
107 return true;
108 }
109 }
110 return false;
111}
112
116Bool_t TRestHits::areXZ() const {
117 for (unsigned int i = 0; i < GetNumberOfHits(); i++) {
118 if (fType[i] != XZ) {
119 // all hits should fit this condition to be considered XY
120 return false;
121 } else if (i == GetNumberOfHits() - 1) {
122 return true;
123 }
124 }
125 return false;
126}
127
131Bool_t TRestHits::areYZ() const {
132 for (unsigned int i = 0; i < GetNumberOfHits(); i++) {
133 if (fType[i] != YZ) {
134 // all hits should fit this condition to be considered XY
135 return false;
136 } else if (i == GetNumberOfHits() - 1) {
137 return true;
138 }
139 }
140 return false;
141}
142
146Bool_t TRestHits::areXYZ() const {
147 for (unsigned int i = 0; i < GetNumberOfHits(); i++) {
148 if (fType[i] != XYZ) {
149 // all hits should fit this condition to be considered XY
150 return false;
151 } else if (i == GetNumberOfHits() - 1) {
152 return true;
153 }
154 }
155 return false;
156}
157
162Bool_t TRestHits::isNaN(Int_t n) const {
163 if (IsNaN(GetX(n)) && IsNaN(GetY(n)) && IsNaN(GetZ(n))) return true;
164 return false;
165}
166
176Bool_t TRestHits::isHitNInsidePrism(Int_t n, const TVector3& x0, const TVector3& x1, Double_t sizeX,
177 Double_t sizeY, Double_t theta) const {
178 TVector3 axis = x1 - x0;
179
180 Double_t prismLength = axis.Mag();
181
182 TVector3 hitPos = this->GetPosition(n) - x0;
183 hitPos.RotateZ(theta);
184 Double_t l = axis.Dot(hitPos) / prismLength;
185
186 if ((l > 0) && (l < prismLength)) {
187 if ((TMath::Abs(hitPos.X()) < sizeX / 2) && (TMath::Abs(hitPos.Y()) < sizeY / 2)) {
188 return true;
189 }
190 }
191
192 return false;
193}
194
200Double_t TRestHits::GetEnergyInPrism(const TVector3& x0, const TVector3& x1, Double_t sizeX, Double_t sizeY,
201 Double_t theta) const {
202 Double_t energy = 0;
203 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
204 if (isHitNInsidePrism(n, x0, x1, sizeX, sizeY, theta)) {
205 energy += this->GetEnergy(n);
206 }
207 }
208 return energy;
209}
210
216Int_t TRestHits::GetNumberOfHitsInsidePrism(const TVector3& x0, const TVector3& x1, Double_t sizeX,
217 Double_t sizeY, Double_t theta) const {
218 Int_t hits = 0;
219
220 for (unsigned int n = 0; n < GetNumberOfHits(); n++)
221 if (isHitNInsidePrism(n, x0, x1, sizeX, sizeY, theta)) hits++;
222
223 return hits;
224}
225
230Bool_t TRestHits::isHitNInsideCylinder(Int_t n, const TVector3& x0, const TVector3& x1,
231 Double_t radius) const {
232 TVector3 axis = x1 - x0;
233
234 Double_t cylLength = axis.Mag();
235
236 TVector3 hitPos = this->GetPosition(n) - x0;
237
238 Double_t l = axis.Dot(hitPos) / cylLength;
239
240 if (l > 0 && l < cylLength) {
241 Double_t hitPosNorm2 = hitPos.Mag2();
242 Double_t r = TMath::Sqrt(hitPosNorm2 - l * l);
243
244 if (r < radius) return true;
245 }
246
247 return false;
248}
249
254Double_t TRestHits::GetEnergyInCylinder(Int_t i, Int_t j, Double_t radius) const {
255 return GetEnergyInCylinder(this->GetPosition(i), this->GetPosition(j), radius);
256}
257
262Double_t TRestHits::GetEnergyInCylinder(const TVector3& x0, const TVector3& x1, Double_t radius) const {
263 Double_t energy = 0.;
264 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
265 if (isHitNInsideCylinder(n, x0, x1, radius)) energy += this->GetEnergy(n);
266 }
267
268 return energy;
269}
270
275Int_t TRestHits::GetNumberOfHitsInsideCylinder(Int_t i, Int_t j, Double_t radius) const {
276 return GetNumberOfHitsInsideCylinder(this->GetPosition(i), this->GetPosition(j), radius);
277}
278
283Int_t TRestHits::GetNumberOfHitsInsideCylinder(const TVector3& x0, const TVector3& x1,
284 Double_t radius) const {
285 Int_t hits = 0;
286 for (unsigned int n = 0; n < GetNumberOfHits(); n++)
287 if (isHitNInsideCylinder(n, x0, x1, radius)) hits++;
288
289 return hits;
290}
291
296Double_t TRestHits::GetEnergyInSphere(const TVector3& pos0, Double_t radius) const {
297 return GetEnergyInSphere(pos0.X(), pos0.Y(), pos0.Z(), radius);
298}
299
304Double_t TRestHits::GetEnergyInSphere(Double_t x0, Double_t y0, Double_t z0, Double_t radius) const {
305 Double_t sum = 0;
306 for (unsigned int i = 0; i < GetNumberOfHits(); i++) {
307 Double_t x = this->GetPosition(i).X();
308 Double_t y = this->GetPosition(i).Y();
309 Double_t z = this->GetPosition(i).Z();
310
311 Double_t dist = (x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0);
312
313 if (dist < radius * radius) sum += GetEnergy(i);
314 }
315 return sum;
316}
317
322Bool_t TRestHits::isHitNInsideSphere(Int_t n, const TVector3& pos0, Double_t radius) const {
323 return isHitNInsideSphere(n, pos0.X(), pos0.Y(), pos0.Z(), radius);
324}
325
330Bool_t TRestHits::isHitNInsideSphere(Int_t n, Double_t x0, Double_t y0, Double_t z0, Double_t radius) const {
331 Double_t x = this->GetPosition(n).X();
332 Double_t y = this->GetPosition(n).Y();
333 Double_t z = this->GetPosition(n).Z();
334
335 Double_t dist = (x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0);
336
337 if (dist < radius * radius) return kTRUE;
338
339 return kFALSE;
340}
341
345void TRestHits::AddHit(const TVector3& position, Double_t energy, Double_t time, REST_HitType type) {
346 fX.emplace_back(position.X());
347 fY.emplace_back(position.Y());
348 fZ.emplace_back(position.Z());
349 fTime.emplace_back(time);
350 fEnergy.emplace_back(energy);
351 fType.emplace_back(type);
352}
353
357void TRestHits::AddHit(TRestHits& hits, Int_t n) {
358 Double_t x = hits.GetX(n);
359 Double_t y = hits.GetY(n);
360 Double_t z = hits.GetZ(n);
361 Double_t en = hits.GetEnergy(n);
362 Double_t t = hits.GetTime(n);
363 REST_HitType type = hits.GetType(n);
364
365 AddHit({x, y, z}, en, t, type);
366}
367
372 fX.clear();
373 fY.clear();
374 fZ.clear();
375 fTime.clear();
376 fEnergy.clear();
377 fType.clear();
378}
379
383void TRestHits::Translate(Int_t n, double x, double y, double z) {
384 fX[n] += x;
385 fY[n] += y;
386 fZ[n] += z;
387}
388
393void TRestHits::RotateIn3D(Int_t n, Double_t alpha, Double_t beta, Double_t gamma, const TVector3& vMean) {
394 TVector3 position = GetPosition(n);
395 TVector3 vHit = position - vMean;
396
397 vHit.RotateZ(gamma);
398 vHit.RotateY(beta);
399 vHit.RotateX(alpha);
400
401 fX[n] = vHit[0] + vMean[0];
402 fY[n] = vHit[1] + vMean[1];
403 fZ[n] = vHit[2] + vMean[2];
404}
405
409void TRestHits::Rotate(Int_t n, Double_t alpha, const TVector3& vAxis, const TVector3& vMean) {
410 TVector3 vHit;
411
412 vHit[0] = fX[n] - vMean[0];
413 vHit[1] = fY[n] - vMean[1];
414 vHit[2] = fZ[n] - vMean[2];
415
416 vHit.Rotate(alpha, vAxis);
417
418 fX[n] = vHit[0] + vMean[0];
419 fY[n] = vHit[1] + vMean[1];
420 fZ[n] = vHit[2] + vMean[2];
421}
422
427 Double_t energy = 0;
428 for (unsigned int i = 0; i < GetNumberOfHits(); i++) {
429 if (GetEnergy(i) > energy) {
430 energy = GetEnergy(i);
431 }
432 }
433 return energy;
434}
435
440 Double_t energy = GetMaximumHitEnergy();
441 for (unsigned int i = 0; i < GetNumberOfHits(); i++) {
442 if (GetEnergy(i) < energy) {
443 energy = GetEnergy(i);
444 }
445 }
446 return energy;
447}
448
452Double_t TRestHits::GetMeanHitEnergy() const { return GetTotalEnergy() / GetNumberOfHits(); }
453
458void TRestHits::MergeHits(int n, int m) {
459 Double_t totalEnergy = fEnergy[n] + fEnergy[m];
460 fX[n] = (fX[n] * fEnergy[n] + fX[m] * fEnergy[m]) / totalEnergy;
461 fY[n] = (fY[n] * fEnergy[n] + fY[m] * fEnergy[m]) / totalEnergy;
462 fZ[n] = (fZ[n] * fEnergy[n] + fZ[m] * fEnergy[m]) / totalEnergy;
463 fTime[n] = (fTime[n] * fEnergy[n] + fTime[m] * fEnergy[m]) / totalEnergy;
464 fEnergy[n] += fEnergy[m];
465
466 fX.erase(fX.begin() + m);
467 fY.erase(fY.begin() + m);
468 fZ.erase(fZ.begin() + m);
469 fTime.erase(fTime.begin() + m);
470 fEnergy.erase(fEnergy.begin() + m);
471 fType.erase(fType.begin() + m);
472}
473
478void TRestHits::SwapHits(Int_t i, Int_t j) {
479 iter_swap(fX.begin() + i, fX.begin() + j);
480 iter_swap(fY.begin() + i, fY.begin() + j);
481 iter_swap(fZ.begin() + i, fZ.begin() + j);
482 iter_swap(fEnergy.begin() + i, fEnergy.begin() + j);
483 iter_swap(fType.begin() + i, fType.begin() + j);
484 iter_swap(fTime.begin() + i, fTime.begin() + j);
485}
486
491 for (unsigned int i = 0; i < GetNumberOfHits() - 1; i++) {
492 if (GetEnergy(i + 1) > GetEnergy(i)) {
493 return false;
494 }
495 }
496
497 return true;
498}
499
504 fX.erase(fX.begin() + n);
505 fY.erase(fY.begin() + n);
506 fZ.erase(fZ.begin() + n);
507 fTime.erase(fTime.begin() + n);
508 fEnergy.erase(fEnergy.begin() + n);
509 fType.erase(fType.begin() + n);
510}
511
515TVector3 TRestHits::GetPosition(int n) const {
516 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] == XY)) {
517 return {(Double_t)fX[n], (Double_t)fY[n], 0};
518 }
519 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] == XZ)) {
520 return {(Double_t)fX[n], 0, (Double_t)fZ[n]};
521 }
522 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] == YZ)) {
523 return {0, (Double_t)fY[n], (Double_t)fZ[n]};
524 }
525 return {(Double_t)fX[n], (Double_t)fY[n], (Double_t)fZ[n]};
526}
527
531TVector3 TRestHits::GetVector(int i, int j) const { return GetPosition(i) - GetPosition(j); }
532
537 Int_t nHitsX = 0;
538
539 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
540 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0)) {
541 nHitsX++;
542 }
543 }
544 return nHitsX;
545}
546
551 Int_t nHitsY = 0;
552
553 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
554 if ((fType.empty() ? !IsNaN(fY[n]) : fType[n] % Y == 0)) {
555 nHitsY++;
556 }
557 }
558 return nHitsY;
559}
560
564Double_t TRestHits::GetEnergyX() const {
565 Double_t totalEnergy = 0;
566 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
567 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0)) {
568 totalEnergy += fEnergy[n];
569 }
570 }
571
572 return totalEnergy;
573}
574
578Double_t TRestHits::GetEnergyY() const {
579 Double_t totalEnergy = 0;
580 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
581 if ((fType.empty() ? !IsNaN(fY[n]) : fType[n] % Y == 0)) {
582 totalEnergy += fEnergy[n];
583 }
584 }
585
586 return totalEnergy;
587}
588
594 Double_t meanX = 0;
595 Double_t totalEnergy = 0;
596 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
597 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0)) {
598 meanX += fX[n] * fEnergy[n];
599 totalEnergy += fEnergy[n];
600 }
601 }
602
603 if (totalEnergy == 0) {
604 return 0;
605 }
606 meanX /= totalEnergy;
607
608 return meanX;
609}
610
616 Double_t meanY = 0;
617 Double_t totalEnergy = 0;
618 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
619 if ((fType.empty() ? !IsNaN(fY[n]) : fType[n] % Y == 0)) {
620 meanY += fY[n] * fEnergy[n];
621 totalEnergy += fEnergy[n];
622 }
623 }
624
625 if (totalEnergy == 0) {
626 return 0;
627 }
628 meanY /= totalEnergy;
629
630 return meanY;
631}
632
638 Double_t meanZ = 0;
639 Double_t totalEnergy = 0;
640 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
641 if (!IsNaN(fZ[n])) {
642 meanZ += fZ[n] * fEnergy[n];
643 totalEnergy += fEnergy[n];
644 }
645 }
646
647 if (totalEnergy == 0) return 0;
648 meanZ /= totalEnergy;
649
650 return meanZ;
651}
652
660 return mean;
661}
662
666Double_t TRestHits::GetSigmaXY2() const {
667 Double_t sigmaXY2 = 0;
668 Double_t totalEnergy = this->GetTotalEnergy();
669 Double_t meanX = this->GetMeanPositionX();
670 Double_t meanY = this->GetMeanPositionY();
671 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
672 if ((fType.empty() ? !IsNaN(fY[n]) : fType[n] % Y == 0)) {
673 sigmaXY2 += fEnergy[n] * (meanY - fY[n]) * (meanY - fY[n]);
674 }
675 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0)) {
676 sigmaXY2 += fEnergy[n] * (meanX - fX[n]) * (meanX - fX[n]);
677 }
678 }
679 return sigmaXY2 /= totalEnergy;
680}
681
685Double_t TRestHits::GetSigmaX() const {
686 Double_t sigmaX2 = 0;
687 Double_t sigmaX = 0;
688 Double_t totalEnergy = this->GetTotalEnergy();
689 Double_t meanX = this->GetMeanPositionX();
690
691 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
692 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0))
693 sigmaX2 += fEnergy[n] * (meanX - fX[n]) * (meanX - fX[n]);
694 }
695 sigmaX2 /= totalEnergy;
696
697 return sigmaX = TMath::Sqrt(sigmaX2);
698}
699
703Double_t TRestHits::GetSigmaY() const {
704 Double_t sigmaY2 = 0;
705 Double_t sigmaY = 0;
706 Double_t totalEnergy = this->GetTotalEnergy();
707 Double_t meanY = this->GetMeanPositionY();
708
709 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
710 if ((fType.empty() ? !IsNaN(fY[n]) : fType[n] % Y == 0))
711 sigmaY2 += fEnergy[n] * (meanY - fY[n]) * (meanY - fY[n]);
712 }
713 sigmaY2 /= totalEnergy;
714
715 return sigmaY = TMath::Sqrt(sigmaY2);
716}
717
721void TRestHits::WriteHitsToTextFile(TString filename) {
722 FILE* fff = fopen(filename.Data(), "w");
723 for (unsigned int i = 0; i < GetNumberOfHits(); i++) {
724 if ((fType.empty() ? !IsNaN(fX[i]) : fType[i] % X == 0)) {
725 fprintf(fff, "%d\t%e\t%s\t%e\t%e\n", i, fX[i], "NaN", fZ[i], fEnergy[i]);
726 }
727 if ((fType.empty() ? !IsNaN(fY[i]) : fType[i] % Y == 0)) {
728 fprintf(fff, "%d\t%s\t%e\t%e\t%e\n", i, "NaN", fY[i], fZ[i], fEnergy[i]);
729 }
730 }
731 fclose(fff);
732}
733
738void TRestHits::GetBoundaries(std::vector<double>& dist, double& max, double& min, int& nBins,
739 double offset) {
740 std::sort(dist.begin(), dist.end());
741 max = dist.back();
742 min = dist.front();
743
744 double minDiff = 1E6;
745 double prevVal = 1E6;
746 for (const auto& h : dist) {
747 double diff = std::abs(h - prevVal);
748 if (diff > 0 && diff < minDiff) minDiff = diff;
749 prevVal = h;
750 }
751
752 max += offset * minDiff + minDiff / 2.;
753 min -= offset * minDiff + minDiff / 2.;
754 nBins = std::round((max - min) / minDiff);
755}
762Double_t TRestHits::GetGaussSigmaX(Double_t error, Int_t nHitsMin) {
763 Double_t gausSigmaX = 0;
764 Int_t nHits = GetNumberOfHits();
765 if (nHits <= 0) {
766 gausSigmaX = 0;
767 } else {
768 Int_t nAdd = 0;
769 // bool doHitCorrection = true;
770 // bool doHitCorrection = nHits <= 18; //in case we want to apply it only to the smaller events
771 bool doHitCorrection = nHits <= nHitsMin;
772 if (doHitCorrection) {
773 nAdd = 2;
774 }
775 Int_t nElems = nHits + nAdd;
776 vector<Double_t> x(nElems), y(nElems), ex(nElems), ey(nElems);
777 Int_t k = nAdd / 2;
778 Double_t xMin = std::numeric_limits<double>::max();
779 Double_t xMax = std::numeric_limits<double>::lowest();
780 for (unsigned int n = 0; n < GetNumberOfHits(); k++, n++) {
781 x[k] = fX[n];
782 y[k] = fEnergy[n];
783 ex[k] = 0;
784 xMin = min(xMin, x[k]);
785 xMax = max(xMax, x[k]);
786 if (y[k] != 0) {
787 ey[k] = 10 * sqrt(y[k]);
788 } else {
789 ey[k] = 0;
790 }
791 }
792 Int_t h = nHits + nAdd / 2;
793 if (doHitCorrection) {
794 x[0] = xMin - 0.5;
795 x[h] = xMax + 0.5;
796 y[0] = 0.0;
797 y[h] = 0.0;
798 ex[0] = 0.0;
799 ex[h] = 0.0;
800 ey[0] = error;
801 ey[h] = error;
802 }
803 TGraphErrors* grX = new TGraphErrors(nElems, &x[0], &y[0], &ex[0], &ey[0]);
804 // TCanvas *c = new TCanvas("c","X position fit",200,10,500,500);
805 // grX->Draw();
806 // Defining the starting parameters for the fit.
807 Double_t maxY = MaxElement(nElems, grX->GetY());
808 Double_t maxX = grX->GetX()[LocMax(nElems, grX->GetY())];
809 Double_t sigma = abs(x[0] - x[h]) / 2.0;
810 // std::cout << "maxX: " << maxX << ", maxY: " << maxY << ", sigma: " << sigma << std::endl;
811
812 TF1* fit = new TF1("", "gaus");
813 fit->SetParameter(0, maxY);
814 fit->SetParameter(1, maxX);
815 fit->SetParameter(2, sigma);
816 TFitResultPtr fitResult =
817 grX->Fit(fit, "QNBS"); // Q = quiet, no info in screen; N = no plot; B = no automatic start
818 // parameters; R = Use the Range specified in the function range; S = save
819 // and return the fit result.
820 if (fitResult->IsValid()) {
821 gausSigmaX = fit->GetParameter(2);
822 } else {
823 return -1.0; // the fit failed, return -1 to indicate failure
824 }
825
826 delete (grX);
827 delete (fit);
828 }
829
830 return abs(gausSigmaX);
831}
836Double_t TRestHits::GetGaussSigmaY(Double_t error, Int_t nHitsMin) {
837 Double_t gausSigmaY = 0;
838 Int_t nHits = GetNumberOfHits();
839 if (nHits <= 0) {
840 gausSigmaY = 0;
841 } else {
842 Int_t nAdd = 0;
843 bool doHitCorrection = nHits <= nHitsMin;
844 if (doHitCorrection) {
845 nAdd = 2;
846 }
847 Int_t nElems = nHits + nAdd;
848 vector<Double_t> x(nElems), y(nElems), ex(nElems), ey(nElems);
849 Int_t k = nAdd / 2;
850 Double_t xMin = std::numeric_limits<double>::max();
851 Double_t xMax = std::numeric_limits<double>::lowest();
852 for (unsigned int n = 0; n < GetNumberOfHits(); k++, n++) {
853 x[k] = fY[n];
854 y[k] = fEnergy[n];
855 ex[k] = 0;
856 xMin = min(xMin, x[k]);
857 xMax = max(xMax, x[k]);
858 if (y[k] != 0) {
859 ey[k] = 10 * sqrt(y[k]);
860 } else {
861 ey[k] = 0;
862 }
863 }
864 Int_t h = nHits + nAdd / 2;
865 if (doHitCorrection) {
866 x[0] = xMin - 0.5;
867 x[h] = xMax + 0.5;
868 y[0] = 0.0;
869 y[h] = 0.0;
870 ex[0] = 0.0;
871 ex[h] = 0.0;
872 ey[0] = error;
873 ey[h] = error;
874 }
875 TGraphErrors* grY = new TGraphErrors(nElems, &x[0], &y[0], &ex[0], &ey[0]);
876 // TCanvas *c = new TCanvas("c","Y position fit",200,10,500,500);
877 // grY->Draw();
878 // Defining the starting parameters for the fit.
879 Double_t maxY = MaxElement(nElems, grY->GetY());
880 Double_t maxX = grY->GetX()[LocMax(nElems, grY->GetY())];
881 Double_t sigma = abs(x[0] - x[h]) / 2.0;
882
883 TF1* fit = new TF1("", "gaus");
884 fit->SetParameter(0, maxY);
885 fit->SetParameter(1, maxX);
886 fit->SetParameter(2, sigma);
887 TFitResultPtr fitResult =
888 grY->Fit(fit, "QNBS"); // Q = quiet, no info in screen; N = no plot; B = no automatic start
889 // parameters; R = Use the Range specified in the function range; S = save
890 // and return the fit result.
891 if (fitResult->IsValid()) {
892 gausSigmaY = fit->GetParameter(2);
893 } else {
894 return -1.0; // the fit failed, return -1 to indicate failure
895 }
896
897 delete (grY);
898 delete (fit);
899 }
900
901 return abs(gausSigmaY);
902}
907Double_t TRestHits::GetGaussSigmaZ(Double_t error, Int_t nHitsMin) {
908 Double_t gausSigmaZ = 0;
909 Int_t nHits = GetNumberOfHits();
910 if (nHits <= 0) {
911 gausSigmaZ = 0;
912 } else {
913 Int_t nAdd = 0;
914 bool doHitCorrection = nHits <= nHitsMin;
915 if (doHitCorrection) {
916 nAdd = 2;
917 }
918 Int_t nElems = nHits + nAdd;
919 vector<Double_t> x(nElems), y(nElems), ex(nElems), ey(nElems);
920 Int_t k = nAdd / 2;
921 Double_t xMin = std::numeric_limits<double>::max();
922 Double_t xMax = std::numeric_limits<double>::lowest();
923 for (unsigned int n = 0; n < GetNumberOfHits(); k++, n++) {
924 x[k] = fZ[n];
925 y[k] = fEnergy[n];
926 ex[k] = 0;
927 xMin = min(xMin, x[k]);
928 xMax = max(xMax, x[k]);
929 if (y[k] != 0) {
930 ey[k] = 10 * sqrt(y[k]);
931 } else {
932 ey[k] = 0;
933 }
934 }
935 Int_t h = nHits + nAdd / 2;
936 if (doHitCorrection) {
937 x[0] = xMin - 0.5;
938 x[h] = xMax + 0.5;
939 y[0] = 0.0;
940 y[h] = 0.0;
941 ex[0] = 0.0;
942 ex[h] = 0.0;
943 ey[0] = error;
944 ey[h] = error;
945 }
946 TGraphErrors* grZ = new TGraphErrors(nElems, &x[0], &y[0], &ex[0], &ey[0]);
947 // TCanvas *c = new TCanvas("c","Z position fit",200,10,500,500);
948 // grZ->Draw();
949 // Defining the starting parameters for the fit.
950 Double_t maxY = MaxElement(nElems, grZ->GetY());
951 Double_t maxX = grZ->GetX()[LocMax(nElems, grZ->GetY())];
952 Double_t sigma = abs(x[0] - x[h]) / 2.0;
953
954 TF1* fit = new TF1("", "gaus");
955 fit->SetParameter(0, maxY);
956 fit->SetParameter(1, maxX);
957 fit->SetParameter(2, sigma);
958 TFitResultPtr fitResult =
959 grZ->Fit(fit, "QNBS"); // Q = quiet, no info in screen; N = no plot; B = no automatic start
960 // parameters; R = Use the Range specified in the function range; S = save
961 // and return the fit result.
962 if (fitResult->IsValid()) {
963 gausSigmaZ = fit->GetParameter(2);
964 } else {
965 return -1.0; // the fit failed, return -1 to indicate failure
966 }
967
968 delete (grZ);
969 delete (fit);
970 }
971
972 return abs(gausSigmaZ);
973}
974
979Double_t TRestHits::GetSkewXY() const {
980 Double_t skewXY = 0;
981 Double_t totalEnergy = this->GetTotalEnergy();
982 Double_t sigmaXY = TMath::Sqrt(this->GetSigmaXY2());
983 Double_t meanX = this->GetMeanPositionX();
984 Double_t meanY = this->GetMeanPositionY();
985 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
986 if ((fType.empty() ? !IsNaN(fY[n]) : fType[n] % Y == 0))
987 skewXY += fEnergy[n] * (meanY - fY[n]) * (meanY - fY[n]) * (meanY - fY[n]);
988 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0))
989 skewXY += fEnergy[n] * (meanX - fX[n]) * (meanX - fX[n]) * (meanX - fX[n]);
990 }
991 return skewXY /= (totalEnergy * sigmaXY * sigmaXY * sigmaXY);
992}
993
997Double_t TRestHits::GetSigmaZ2() const {
998 Double_t sigmaZ2 = 0;
999 Double_t totalEnergy = this->GetTotalEnergy();
1000 Double_t meanZ = this->GetMeanPositionZ();
1001
1002 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
1003 if (!IsNaN(fZ[n])) {
1004 sigmaZ2 += fEnergy[n] * (meanZ - fZ[n]) * (meanZ - fZ[n]);
1005 }
1006 }
1007 return sigmaZ2 /= totalEnergy;
1008}
1009
1013Double_t TRestHits::GetSkewZ() const {
1014 Double_t skewZ = 0;
1015 Double_t totalEnergy = this->GetTotalEnergy();
1016 Double_t sigmaZ = TMath::Sqrt(this->GetSigmaZ2());
1017 Double_t meanZ = this->GetMeanPositionZ();
1018
1019 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
1020 if (!IsNaN(fZ[n])) skewZ += fEnergy[n] * (meanZ - fZ[n]) * (meanZ - fZ[n]) * (meanZ - fZ[n]);
1021 }
1022 return skewZ /= (totalEnergy * sigmaZ * sigmaZ * sigmaZ);
1023}
1024
1030Double_t TRestHits::GetMeanPositionXInPrism(const TVector3& x0, const TVector3& x1, Double_t sizeX,
1031 Double_t sizeY, Double_t theta) const {
1032 Double_t meanX = 0;
1033 Double_t totalEnergy = 0;
1034 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
1035 if (((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0) &&
1036 (isHitNInsidePrism(n, x0, x1, sizeX, sizeY, theta)))) {
1037 meanX += fX[n] * fEnergy[n];
1038 totalEnergy += fEnergy[n];
1039 }
1040 }
1041
1042 meanX /= totalEnergy;
1043
1044 return meanX;
1045}
1046
1052Double_t TRestHits::GetMeanPositionYInPrism(const TVector3& x0, const TVector3& x1, Double_t sizeX,
1053 Double_t sizeY, Double_t theta) const {
1054 Double_t meanY = 0;
1055 Double_t totalEnergy = 0;
1056 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
1057 if (((fType.empty() ? !IsNaN(fY[n]) : fType[n] % Y == 0) &&
1058 (isHitNInsidePrism(n, x0, x1, sizeX, sizeY, theta)))) {
1059 meanY += fY[n] * fEnergy[n];
1060 totalEnergy += fEnergy[n];
1061 }
1062 }
1063
1064 meanY /= totalEnergy;
1065
1066 return meanY;
1067}
1068
1074Double_t TRestHits::GetMeanPositionZInPrism(const TVector3& x0, const TVector3& x1, Double_t sizeX,
1075 Double_t sizeY, Double_t theta) const {
1076 Double_t meanZ = 0;
1077 Double_t totalEnergy = 0;
1078 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
1079 if ((!IsNaN(fZ[n]) && (isHitNInsidePrism(n, x0, x1, sizeX, sizeY, theta)))) {
1080 meanZ += fZ[n] * fEnergy[n];
1081 totalEnergy += fEnergy[n];
1082 }
1083 }
1084
1085 meanZ /= totalEnergy;
1086
1087 return meanZ;
1088}
1089
1095TVector3 TRestHits::GetMeanPositionInPrism(const TVector3& x0, const TVector3& x1, Double_t sizeX,
1096 Double_t sizeY, Double_t theta) const {
1097 TVector3 mean(GetMeanPositionXInPrism(x0, x1, sizeX, sizeY, theta),
1098 GetMeanPositionYInPrism(x0, x1, sizeX, sizeY, theta),
1099 GetMeanPositionZInPrism(x0, x1, sizeX, sizeY, theta));
1100 return mean;
1101}
1102
1107Double_t TRestHits::GetMeanPositionXInCylinder(const TVector3& x0, const TVector3& x1,
1108 Double_t radius) const {
1109 Double_t meanX = 0;
1110 Double_t totalEnergy = 0;
1111 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
1112 if (((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0) &&
1113 (isHitNInsideCylinder(n, x0, x1, radius)))) {
1114 meanX += fX[n] * fEnergy[n];
1115 totalEnergy += fEnergy[n];
1116 }
1117 }
1118
1119 meanX /= totalEnergy;
1120
1121 return meanX;
1122}
1123
1128Double_t TRestHits::GetMeanPositionYInCylinder(const TVector3& x0, const TVector3& x1,
1129 Double_t radius) const {
1130 Double_t meanY = 0;
1131 Double_t totalEnergy = 0;
1132 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
1133 if (((fType.empty() ? !IsNaN(fY[n]) : fType[n] % Y == 0) &&
1134 (isHitNInsideCylinder(n, x0, x1, radius)))) {
1135 meanY += fY[n] * fEnergy[n];
1136 totalEnergy += fEnergy[n];
1137 }
1138 }
1139
1140 meanY /= totalEnergy;
1141
1142 return meanY;
1143}
1144
1149Double_t TRestHits::GetMeanPositionZInCylinder(const TVector3& x0, const TVector3& x1,
1150 Double_t radius) const {
1151 Double_t meanZ = 0;
1152 Double_t totalEnergy = 0;
1153 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
1154 if ((!IsNaN(fZ[n]) && (isHitNInsideCylinder(n, x0, x1, radius)))) {
1155 meanZ += fZ[n] * fEnergy[n];
1156 totalEnergy += fEnergy[n];
1157 }
1158 }
1159
1160 meanZ /= totalEnergy;
1161
1162 return meanZ;
1163}
1164
1169TVector3 TRestHits::GetMeanPositionInCylinder(const TVector3& x0, const TVector3& x1, Double_t radius) const {
1170 TVector3 mean(GetMeanPositionXInCylinder(x0, x1, radius), GetMeanPositionYInCylinder(x0, x1, radius),
1171 GetMeanPositionZInCylinder(x0, x1, radius));
1172 return mean;
1173}
1174
1179Double_t TRestHits::GetHitsPathLength(Int_t n, Int_t m) const {
1180 if (n < 0) n = 0;
1181 if (m > (int)GetNumberOfHits() - 1) m = GetNumberOfHits() - 1;
1182
1183 Double_t distance = 0;
1184 for (int i = n; i < m; i++) distance += TMath::Sqrt(GetDistance2(i, i + 1));
1185 return distance;
1186}
1187
1193 Double_t distance = 0;
1194 for (unsigned int i = 0; i < GetNumberOfHits() - 1; i++) distance += TMath::Sqrt(GetDistance2(i, i + 1));
1195 return distance;
1196}
1197
1201Double_t TRestHits::GetDistance2(int n, int m) const {
1202 Double_t dx = GetX(n) - GetX(m);
1203 Double_t dy = GetY(n) - GetY(m);
1204 Double_t dz = GetZ(n) - GetZ(m);
1205
1206 if (areXY()) return dx * dx + dy * dy;
1207 if (areXZ()) return dx * dx + dz * dz;
1208 if (areYZ()) return dy * dy + dz * dz;
1209
1210 return dx * dx + dy * dy + dz * dz;
1211}
1212
1217Double_t TRestHits::GetDistanceToNode(Int_t n) const {
1218 Double_t distance = 0;
1219 if (n > (int)GetNumberOfHits() - 1) n = GetNumberOfHits() - 1;
1220
1221 for (int hit = 0; hit < n; hit++) distance += GetVector(hit + 1, hit).Mag();
1222
1223 return distance;
1224}
1225
1229Int_t TRestHits::GetMostEnergeticHitInRange(Int_t n, Int_t m) const {
1230 Int_t maxEnergy = 0;
1231 Int_t hit = -1;
1232 for (int i = n; i < m; i++) {
1233 if (GetEnergy(i) > maxEnergy) {
1234 maxEnergy = GetEnergy(i);
1235 hit = i;
1236 }
1237 }
1238 return hit;
1239}
1240
1244Int_t TRestHits::GetClosestHit(const TVector3& position) const {
1245 Int_t closestHit = 0;
1246
1247 Double_t minDistance = 1.e30;
1248 for (unsigned int nHit = 0; nHit < GetNumberOfHits(); nHit++) {
1249 TVector3 vector = position - GetPosition(nHit);
1250
1251 Double_t distance = vector.Mag2();
1252 if (distance < minDistance) {
1253 closestHit = nHit;
1254 minDistance = distance;
1255 }
1256 }
1257
1258 return closestHit;
1259}
1260
1265TVector2 TRestHits::GetProjection(Int_t n, Int_t m, const TVector3& position) const {
1266 TVector3 nodesSegment = this->GetVector(n, m);
1267
1268 TVector3 origin = position - this->GetPosition(m);
1269
1270 if (origin == TVector3(0, 0, 0)) return {0, 0};
1271
1272 Double_t longitudinal = nodesSegment.Unit().Dot(origin);
1273 if (origin == nodesSegment) return {longitudinal, 0};
1274
1275 Double_t transversal = TMath::Sqrt(origin.Mag2() - longitudinal * longitudinal);
1276
1277 return {longitudinal, transversal};
1278}
1279
1284Double_t TRestHits::GetTransversalProjection(const TVector3& p0, const TVector3& direction,
1285 const TVector3& position) const {
1286 TVector3 oX = position - p0;
1287
1288 if (oX == TVector3(0, 0, 0)) return 0;
1289
1290 Double_t longitudinal = direction.Unit().Dot(oX);
1291
1292 return TMath::Sqrt(oX.Mag2() - longitudinal * longitudinal);
1293}
1294
1301Double_t TRestHits::GetHitsTwist(Int_t n, Int_t m) const {
1302 if (n < 0) n = 0;
1303 if (m == 0) m = this->GetNumberOfHits();
1304
1305 if (m - n < 2) return 0;
1306
1307 Double_t sum = 0;
1308 Int_t cont = 0;
1309 for (int N = n + 1; N < m - 1; N++) {
1310 TVector3 a = (this->GetPosition(N - 1) - this->GetPosition(N + 1)).Unit();
1311 TVector3 b = (this->GetPosition(N) - this->GetPosition(N + 1)).Unit();
1312
1313 sum += (1 - a.Dot(b)) / 2.;
1314 cont++;
1315 }
1316
1317 if (cont == 0) return -1;
1318
1319 return sum / cont;
1320}
1321
1325Double_t TRestHits::GetHitsTwistWeighted(Int_t n, Int_t m) const {
1326 if (n < 0) n = 0;
1327 if (m == 0) m = this->GetNumberOfHits();
1328
1329 if (m - n < 2) return 0;
1330
1331 Double_t sum = 0;
1332 Int_t cont = 0;
1333 for (int N = n + 1; N < m - 1; N++) {
1334 TVector3 a = (this->GetPosition(N - 1) - this->GetPosition(N)).Unit();
1335 TVector3 b = (this->GetPosition(N) - this->GetPosition(N + 1)).Unit();
1336
1337 Double_t weight = TMath::Abs(this->GetEnergy(N - 1) - this->GetEnergy(N));
1338 weight += TMath::Abs(this->GetEnergy(N) - this->GetEnergy(N + 1));
1339
1340 sum += weight * (1 - a.Dot(b)) / 2.;
1341 cont++;
1342 }
1343
1344 if (cont == 0) return -1;
1345
1346 return sum / cont;
1347}
1348
1353 Double_t maxDistance = 0;
1354 for (unsigned int n = 0; n < this->GetNumberOfHits(); n++)
1355 for (unsigned int m = n + 1; m < this->GetNumberOfHits(); m++) {
1356 Double_t d = this->GetDistance(n, m);
1357 if (d > maxDistance) maxDistance = d;
1358 }
1359
1360 return maxDistance;
1361}
1362
1367 Double_t maxDistance = 0;
1368 for (unsigned int n = 0; n < this->GetNumberOfHits(); n++)
1369 for (unsigned int m = n + 1; m < this->GetNumberOfHits(); m++) {
1370 Double_t d = this->GetDistance2(n, m);
1371 if (d > maxDistance) maxDistance = d;
1372 }
1373
1374 return maxDistance;
1375}
1376
1380void TRestHits::PrintHits(Int_t nHits) const {
1381 Int_t N = nHits;
1382
1383 if (N == -1) N = GetNumberOfHits();
1384 if (N > (int)GetNumberOfHits()) N = GetNumberOfHits();
1385
1386 for (int n = 0; n < N; n++) {
1387 cout << "Hit " << n << " X: " << GetX(n) << " Y: " << GetY(n) << " Z: " << GetZ(n)
1388 << " Energy: " << GetEnergy(n) << " T: " << GetTime(n);
1389 cout << endl;
1390 }
1391}
1392
1393Double_t TRestHits::GetTotalEnergy() const {
1394 double energy = 0;
1395 for (unsigned int n = 0; n < GetNumberOfHits(); n++) {
1396 energy += GetEnergy(n);
1397 }
1398 return energy;
1399}
1400
1402// Iterator methods
1403
1404TRestHits::TRestHits_Iterator::TRestHits_Iterator(TRestHits* h, int _index) {
1405 fHits = h;
1406 index = _index;
1407 maxIndex = fHits->GetNumberOfHits();
1408 if (index < 0) index = 0;
1409 if (index >= maxIndex) index = maxIndex;
1410}
1411
1412void TRestHits::TRestHits_Iterator::toaccessor() {
1413 _x = x();
1414 _y = y();
1415 _z = z();
1416 _t = t();
1417 _e = e();
1418 _type = type();
1419 isAccessor = true;
1420}
1421
1422TRestHits::TRestHits_Iterator TRestHits::TRestHits_Iterator::operator*() const {
1423 TRestHits_Iterator i(*this);
1424 i.toaccessor();
1425 return i;
1426}
1427
1428TRestHits::TRestHits_Iterator& TRestHits::TRestHits_Iterator::operator++() {
1429 index++;
1430 if (index >= maxIndex) index = maxIndex;
1431 return *this;
1432}
1433
1434TRestHits::TRestHits_Iterator& TRestHits::TRestHits_Iterator::operator+=(const int& n) {
1435 if (index + n >= maxIndex) {
1436 index = maxIndex;
1437 } else {
1438 index += n;
1439 }
1440 return *this;
1441}
1442
1443TRestHits::TRestHits_Iterator TRestHits::TRestHits_Iterator::operator+(const int& n) {
1444 if (index + n >= maxIndex) {
1445 return TRestHits_Iterator(fHits, maxIndex);
1446 } else {
1447 return TRestHits_Iterator(fHits, index + n);
1448 }
1449}
1450
1451TRestHits::TRestHits_Iterator& TRestHits::TRestHits_Iterator::operator--() {
1452 index--;
1453 if (index <= 0) index = 0;
1454 return *this;
1455}
1456
1457TRestHits::TRestHits_Iterator& TRestHits::TRestHits_Iterator::operator-=(const int& n) {
1458 if (index - n <= 0) {
1459 index = 0;
1460 } else {
1461 index -= n;
1462 }
1463 return *this;
1464}
1465
1466TRestHits::TRestHits_Iterator TRestHits::TRestHits_Iterator::operator-(const int& n) {
1467 if (index - n <= 0) {
1468 return TRestHits_Iterator(fHits, 0);
1469 } else {
1470 return TRestHits_Iterator(fHits, index - n);
1471 }
1472}
1473
1474TRestHits::TRestHits_Iterator& TRestHits::TRestHits_Iterator::operator=(const TRestHits_Iterator& iter) {
1475 if (isAccessor) {
1476 (fHits ? fHits->fX[index] : x()) = iter.x();
1477 (fHits ? fHits->fY[index] : y()) = iter.y();
1478 (fHits ? fHits->fZ[index] : z()) = iter.z();
1479 (fHits ? fHits->fEnergy[index] : e()) = iter.e();
1480 (fHits ? fHits->fTime[index] : t()) = iter.t();
1481 (fHits ? fHits->fType[index] : type()) = iter.type();
1482 } else {
1483 fHits = iter.fHits;
1484 index = iter.index;
1485 }
1486 return *this;
1487}
It saves a 3-coordinate position and an energy for each punctual deposition.
Definition: TRestHits.h:39
TVector3 GetVector(int i, int j) const
It returns the vector that goes from hit j to hit i.
Definition: TRestHits.cxx:531
virtual Bool_t areXYZ() const
It will return true only if all the hits inside are of type XYZ.
Definition: TRestHits.cxx:146
Double_t GetEnergyX() const
It calculates the total energy of hits with a valid X coordinate.
Definition: TRestHits.cxx:564
Double_t GetDistanceToNode(Int_t n) const
It determines the distance required to travel from the first hit to the hit n adding all the distance...
Definition: TRestHits.cxx:1217
virtual Bool_t areYZ() const
It will return true only if all the hits inside are of type YZ.
Definition: TRestHits.cxx:131
void Rotate(Int_t n, Double_t alpha, const TVector3 &vAxis, const TVector3 &vMean)
It rotates hit n by an angle akpha along the vAxis with center at vMean.
Definition: TRestHits.cxx:409
virtual Bool_t areXY() const
It will return true only if all the hits inside are of type XY.
Definition: TRestHits.cxx:101
Double_t GetMaximumHitEnergy() const
It returns the maximum hit energy.
Definition: TRestHits.cxx:426
Int_t GetNumberOfHitsInsidePrism(const TVector3 &x0, const TVector3 &x1, Double_t sizeX, Double_t sizeY, Double_t theta) const
It determines the total number of hits contained inside a prisma delimited between x0 and y0 vertex,...
Definition: TRestHits.cxx:216
Double_t GetMeanPositionZ() const
It calculates the mean Z position weighting with the energy of the hits with a valid Z coordinate.
Definition: TRestHits.cxx:637
Double_t GetMeanPositionX() const
It calculates the mean X position weighting with the energy of the hits with a valid X coordinate.
Definition: TRestHits.cxx:593
Double_t GetSkewXY() const
It returns the 2-dimensional skewness on the XY-plane which is a measure of the hits distribution asy...
Definition: TRestHits.cxx:979
Double_t GetHitsTwistWeighted(Int_t n, Int_t m) const
Same as GetHitsTwist but weighting with the energy.
Definition: TRestHits.cxx:1325
TVector3 GetMeanPosition() const
It calculates the mean position weighting with the energy of the hits. Each coordinate is calculated ...
Definition: TRestHits.cxx:658
Double_t GetMeanPositionY() const
It calculates the mean Y position weighting with the energy of the hits with a valid Y coordinate.
Definition: TRestHits.cxx:615
virtual void RemoveHits()
It removes all hits inside the class.
Definition: TRestHits.cxx:371
Double_t GetMeanHitEnergy() const
It returns the mean hits energy.
Definition: TRestHits.cxx:452
Double_t GetTotalDistance() const
It determines the distance required to travel from the first to the last hit adding all the distances...
Definition: TRestHits.cxx:1192
TVector3 GetMeanPositionInCylinder(const TVector3 &x0, const TVector3 &x1, Double_t radius) const
It determines the mean position using the hits contained inside a cylinder with a given radius and de...
Definition: TRestHits.cxx:1169
Double_t GetGaussSigmaX(Double_t error=150.0, Int_t nHitsMin=100000)
It computes the gaussian sigma in the X-coordinate. It adds a hit to the right and a hit to the left,...
Definition: TRestHits.cxx:762
Double_t GetMeanPositionYInPrism(const TVector3 &x0, const TVector3 &x1, Double_t sizeX, Double_t sizeY, Double_t theta) const
It determines the mean Y position of hits contained inside a prisma delimited between x0 and x1 verte...
Definition: TRestHits.cxx:1052
virtual void MergeHits(int n, int m)
It merges hits n and m being the resulting hit placed at the weighted center and being its final ener...
Definition: TRestHits.cxx:458
static void GetBoundaries(std::vector< double > &val, double &max, double &min, int &nBins, double offset=10)
TODO This method is not using any TRestHits member. This probably means that it should be placed some...
Definition: TRestHits.cxx:738
Bool_t isSortedByEnergy() const
It returns true if the hits are ordered in increasing energies.
Definition: TRestHits.cxx:490
Double_t GetSigmaX() const
It calculates the hits standard deviation in the X-coordinate.
Definition: TRestHits.cxx:685
Double_t GetTransversalProjection(const TVector3 &p0, const TVector3 &direction, const TVector3 &position) const
It returns the transversal projection of position to the line defined by position and direction.
Definition: TRestHits.cxx:1284
Double_t GetEnergyInCylinder(const TVector3 &x0, const TVector3 &x1, Double_t radius) const
It determines the total energy contained inside a cylinder with a given radius and delimited between ...
Definition: TRestHits.cxx:262
virtual void RemoveHit(int n)
It removes the hit at position n from the list.
Definition: TRestHits.cxx:503
std::vector< REST_HitType > fType
The type of hit X,Y,XY,XYZ, ...
Definition: TRestHits.h:62
std::vector< Float_t > fZ
Position on Z axis for each punctual deposition (units mm)
Definition: TRestHits.h:53
Double_t GetEnergyY() const
It calculates the total energy of hits with a valid Y coordinate.
Definition: TRestHits.cxx:578
Bool_t isHitNInsidePrism(Int_t n, const TVector3 &x0, const TVector3 &x1, Double_t sizeX, Double_t sizeY, Double_t theta) const
It determines if hit n is contained inside a prisma delimited between x0 and y0 vertex,...
Definition: TRestHits.cxx:176
Double_t GetMeanPositionZInPrism(const TVector3 &x0, const TVector3 &x1, Double_t sizeX, Double_t sizeY, Double_t theta) const
It determines the mean Z position of hits contained inside a prisma delimited between x0 and x1 verte...
Definition: TRestHits.cxx:1074
Double_t GetMeanPositionXInCylinder(const TVector3 &x0, const TVector3 &x1, Double_t radius) const
It determines the mean position X using the hits contained inside a cylinder with a given radius and ...
Definition: TRestHits.cxx:1107
Double_t GetHitsTwist(Int_t n, Int_t m) const
A parameter measuring how straight is a given sequence of hits. If the value is close to zero,...
Definition: TRestHits.cxx:1301
Double_t GetMeanPositionXInPrism(const TVector3 &x0, const TVector3 &x1, Double_t sizeX, Double_t sizeY, Double_t theta) const
It determines the mean X position of hits contained inside a prisma delimited between x0 and x1 verte...
Definition: TRestHits.cxx:1030
std::vector< Float_t > fY
Position on Y axis for each punctual deposition (units mm)
Definition: TRestHits.h:50
std::vector< Float_t > fX
Position on X axis for each punctual deposition (units mm)
Definition: TRestHits.h:47
Double_t GetEnergyInSphere(const TVector3 &pos0, Double_t radius) const
It determines the total energy contained in a sphere with position pos0 for a given spherical radius.
Definition: TRestHits.cxx:296
Double_t GetGaussSigmaZ(Double_t error=150.0, Int_t nHitsMin=100000)
It computes the gaussian sigma in the Z-coordinate. It adds a hit to the right and a hit to the left,...
Definition: TRestHits.cxx:907
Int_t GetMostEnergeticHitInRange(Int_t n, Int_t m) const
It returns the most energetic hit found between hits n and m.
Definition: TRestHits.cxx:1229
Double_t GetEnergyInPrism(const TVector3 &x0, const TVector3 &x1, Double_t sizeX, Double_t sizeY, Double_t theta) const
It determines the total hit energy contained inside a prisma delimited between x0 and y0 vertex,...
Definition: TRestHits.cxx:200
void WriteHitsToTextFile(TString filename)
It writes the hits to a plain text file.
Definition: TRestHits.cxx:721
~TRestHits()
Default destructor.
std::vector< Float_t > fEnergy
Energy deposited at each 3-coordinate position (units keV)
Definition: TRestHits.h:59
void AddHit(const TVector3 &position, Double_t energy, Double_t time=0, REST_HitType type=XYZ)
Adds a new hit to the list of hits using a TVector3.
Definition: TRestHits.cxx:345
TVector2 GetProjection(Int_t n, Int_t m, const TVector3 &position) const
It returns the longitudinal and transversal projections of position to the axis defined by the hits n...
Definition: TRestHits.cxx:1265
Double_t GetGaussSigmaY(Double_t error=150.0, Int_t nHitsMin=100000)
It computes the gaussian sigma in the Y-coordinate. It adds a hit to the right and a hit to the left,...
Definition: TRestHits.cxx:836
std::vector< Float_t > fTime
Absolute time information for each punctual deposition (units us, 0 is time of decay)
Definition: TRestHits.h:56
TRestHits()
Default constructor.
virtual Bool_t areXZ() const
It will return true only if all the hits inside are of type XZ.
Definition: TRestHits.cxx:116
Int_t GetClosestHit(const TVector3 &position) const
It returns the closest hit to a given position.
Definition: TRestHits.cxx:1244
void RotateIn3D(Int_t n, Double_t alpha, Double_t beta, Double_t gamma, const TVector3 &center)
It rotates hit n following rotations in Z, Y and X by angles gamma, beta and alpha....
Definition: TRestHits.cxx:393
Int_t GetNumberOfHitsInsideCylinder(const TVector3 &x0, const TVector3 &x1, Double_t radius) const
It determines the total number of hits contained inside a cylinder with a given radius and delimited ...
Definition: TRestHits.cxx:283
Double_t GetSigmaZ2() const
It returns the hits distribution variance on the Z-axis.
Definition: TRestHits.cxx:997
Bool_t isHitNInsideCylinder(Int_t n, const TVector3 &x0, const TVector3 &x1, Double_t radius) const
It determines if hit n is contained inside a cylinder with a given radius and delimited between x0 an...
Definition: TRestHits.cxx:230
Double_t GetSkewZ() const
It returns the hits distribution skewness, or asymmetry on the Z-axis.
Definition: TRestHits.cxx:1013
TVector3 GetMeanPositionInPrism(const TVector3 &x0, const TVector3 &x1, Double_t sizeX, Double_t sizeY, Double_t theta) const
It determines the mean position of hits contained inside a prisma delimited between x0 and x1 vertex,...
Definition: TRestHits.cxx:1095
Double_t GetSigmaY() const
It calculates the hits standard deviation in the Y-coordinate.
Definition: TRestHits.cxx:703
virtual void SwapHits(Int_t i, Int_t j)
It exchanges hits n and m affecting to the ordering of the hits inside the list of hits.
Definition: TRestHits.cxx:478
Bool_t isNaN(Int_t n) const
It will return true only if all the 3-coordinates of hit number n are not a number,...
Definition: TRestHits.cxx:162
Double_t GetMaximumHitDistance() const
It returns the maximum distance between 2-hits.
Definition: TRestHits.cxx:1352
Double_t GetDistance2(int n, int m) const
It returns the euclidian distance between hits n and m.
Definition: TRestHits.cxx:1201
TVector3 GetPosition(int n) const
It returns the position of hit number n.
Definition: TRestHits.cxx:515
virtual void PrintHits(Int_t nHits=-1) const
It prints on screen the first nHits from the list.
Definition: TRestHits.cxx:1380
Double_t GetMaximumHitDistance2() const
It returns the maximum squared distance between 2-hits.
Definition: TRestHits.cxx:1366
Double_t GetSigmaXY2() const
It calculates the 2-dimensional hits variance.
Definition: TRestHits.cxx:666
Double_t GetMinimumHitEnergy() const
It returns the minimum hit energy.
Definition: TRestHits.cxx:439
Int_t GetNumberOfHitsY() const
It returns the number of hits with a valid Y coordinate.
Definition: TRestHits.cxx:550
void Translate(Int_t n, Double_t x, Double_t y, Double_t z)
It moves hit n by a given amount (x,y,z).
Definition: TRestHits.cxx:383
Bool_t isHitNInsideSphere(Int_t n, const TVector3 &pos0, Double_t radius) const
It determines if the hit n is contained in a sphere with position pos0 for a given sphereical radius.
Definition: TRestHits.cxx:322
Int_t GetNumberOfHitsX() const
It returns the number of hits with a valid X coordinate.
Definition: TRestHits.cxx:536
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
Double_t GetMeanPositionYInCylinder(const TVector3 &x0, const TVector3 &x1, Double_t radius) const
It determines the mean position Y using the hits contained inside a cylinder with a given radius and ...
Definition: TRestHits.cxx:1128
Double_t GetMeanPositionZInCylinder(const TVector3 &x0, const TVector3 &x1, Double_t radius) const
It determines the mean position Z using the hits contained inside a cylinder with a given radius and ...
Definition: TRestHits.cxx:1149