REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
Loading...
Searching...
No Matches
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.
virtual Bool_t areXYZ() const
It will return true only if all the hits inside are of type XYZ.
Double_t GetEnergyX() const
It calculates the total energy of hits with a valid X coordinate.
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...
virtual Bool_t areYZ() const
It will return true only if all the hits inside are of type YZ.
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.
virtual Bool_t areXY() const
It will return true only if all the hits inside are of type XY.
Double_t GetMaximumHitEnergy() const
It returns the maximum hit energy.
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,...
Double_t GetMeanPositionZ() const
It calculates the mean Z position weighting with the energy of the hits with a valid Z coordinate.
Double_t GetMeanPositionX() const
It calculates the mean X position weighting with the energy of the hits with a valid X coordinate.
Double_t GetSkewXY() const
It returns the 2-dimensional skewness on the XY-plane which is a measure of the hits distribution asy...
Double_t GetHitsTwistWeighted(Int_t n, Int_t m) const
Same as GetHitsTwist but weighting with the energy.
TVector3 GetMeanPosition() const
It calculates the mean position weighting with the energy of the hits. Each coordinate is calculated ...
Double_t GetMeanPositionY() const
It calculates the mean Y position weighting with the energy of the hits with a valid Y coordinate.
virtual void RemoveHits()
It removes all hits inside the class.
Double_t GetMeanHitEnergy() const
It returns the mean hits energy.
Double_t GetTotalDistance() const
It determines the distance required to travel from the first to the last hit adding all the distances...
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...
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,...
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...
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...
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...
Bool_t isSortedByEnergy() const
It returns true if the hits are ordered in increasing energies.
Double_t GetSigmaX() const
It calculates the hits standard deviation in the X-coordinate.
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.
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 ...
virtual void RemoveHit(int n)
It removes the hit at position n from the list.
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.
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,...
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...
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 ...
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,...
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...
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.
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,...
Int_t GetMostEnergeticHitInRange(Int_t n, Int_t m) const
It returns the most energetic hit found between hits n and m.
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,...
void WriteHitsToTextFile(TString filename)
It writes the hits to a plain text file.
~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.
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...
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,...
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.
Int_t GetClosestHit(const TVector3 &position) const
It returns the closest hit to a given position.
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....
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 ...
Double_t GetSigmaZ2() const
It returns the hits distribution variance on the Z-axis.
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...
Double_t GetSkewZ() const
It returns the hits distribution skewness, or asymmetry on the Z-axis.
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,...
Double_t GetSigmaY() const
It calculates the hits standard deviation in the Y-coordinate.
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.
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,...
Double_t GetMaximumHitDistance() const
It returns the maximum distance between 2-hits.
Double_t GetDistance2(int n, int m) const
It returns the euclidian distance between hits n and m.
TVector3 GetPosition(int n) const
It returns the position of hit number n.
virtual void PrintHits(Int_t nHits=-1) const
It prints on screen the first nHits from the list.
Double_t GetMaximumHitDistance2() const
It returns the maximum squared distance between 2-hits.
Double_t GetSigmaXY2() const
It calculates the 2-dimensional hits variance.
Double_t GetMinimumHitEnergy() const
It returns the minimum hit energy.
Int_t GetNumberOfHitsY() const
It returns the number of hits with a valid Y coordinate.
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).
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.
Int_t GetNumberOfHitsX() const
It returns the number of hits with a valid X coordinate.
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...
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 ...
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 ...