76 #include "TRestHits.h"
80 #include "TFitResult.h"
84 using namespace TMath;
102 for (
unsigned int i = 0; i < GetNumberOfHits(); i++) {
103 if (fType[i] != XY) {
106 }
else if (i == GetNumberOfHits() - 1) {
117 for (
unsigned int i = 0; i < GetNumberOfHits(); i++) {
118 if (fType[i] != XZ) {
121 }
else if (i == GetNumberOfHits() - 1) {
132 for (
unsigned int i = 0; i < GetNumberOfHits(); i++) {
133 if (fType[i] != YZ) {
136 }
else if (i == GetNumberOfHits() - 1) {
147 for (
unsigned int i = 0; i < GetNumberOfHits(); i++) {
148 if (fType[i] != XYZ) {
151 }
else if (i == GetNumberOfHits() - 1) {
163 if (IsNaN(GetX(n)) && IsNaN(GetY(n)) && IsNaN(GetZ(n)))
return true;
177 Double_t sizeY, Double_t theta)
const {
178 TVector3 axis = x1 - x0;
180 Double_t prismLength = axis.Mag();
182 TVector3 hitPos = this->GetPosition(n) - x0;
183 hitPos.RotateZ(theta);
184 Double_t l = axis.Dot(hitPos) / prismLength;
186 if ((l > 0) && (l < prismLength)) {
187 if ((TMath::Abs(hitPos.X()) < sizeX / 2) && (TMath::Abs(hitPos.Y()) < sizeY / 2)) {
201 Double_t theta)
const {
203 for (
unsigned int n = 0; n < GetNumberOfHits(); n++) {
204 if (isHitNInsidePrism(n, x0, x1, sizeX, sizeY, theta)) {
205 energy += this->GetEnergy(n);
217 Double_t sizeY, Double_t theta)
const {
220 for (
unsigned int n = 0; n < GetNumberOfHits(); n++)
221 if (isHitNInsidePrism(n, x0, x1, sizeX, sizeY, theta)) hits++;
231 Double_t radius)
const {
232 TVector3 axis = x1 - x0;
234 Double_t cylLength = axis.Mag();
236 TVector3 hitPos = this->GetPosition(n) - x0;
238 Double_t l = axis.Dot(hitPos) / cylLength;
240 if (l > 0 && l < cylLength) {
241 Double_t hitPosNorm2 = hitPos.Mag2();
242 Double_t r = TMath::Sqrt(hitPosNorm2 - l * l);
244 if (r < radius)
return true;
255 return GetEnergyInCylinder(this->GetPosition(i), this->GetPosition(j), radius);
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);
276 return GetNumberOfHitsInsideCylinder(this->GetPosition(i), this->GetPosition(j), radius);
284 Double_t radius)
const {
286 for (
unsigned int n = 0; n < GetNumberOfHits(); n++)
287 if (isHitNInsideCylinder(n, x0, x1, radius)) hits++;
297 return GetEnergyInSphere(pos0.X(), pos0.Y(), pos0.Z(), radius);
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();
311 Double_t dist = (x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0);
313 if (dist < radius * radius) sum += GetEnergy(i);
323 return isHitNInsideSphere(n, pos0.X(), pos0.Y(), pos0.Z(), radius);
331 Double_t x = this->GetPosition(n).X();
332 Double_t y = this->GetPosition(n).Y();
333 Double_t z = this->GetPosition(n).Z();
335 Double_t dist = (x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0);
337 if (dist < radius * radius)
return kTRUE;
345 void 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);
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);
365 AddHit({x, y, z}, en, t, type);
394 TVector3 position = GetPosition(n);
395 TVector3 vHit = position - vMean;
401 fX[n] = vHit[0] + vMean[0];
402 fY[n] = vHit[1] + vMean[1];
403 fZ[n] = vHit[2] + vMean[2];
412 vHit[0] = fX[n] - vMean[0];
413 vHit[1] = fY[n] - vMean[1];
414 vHit[2] = fZ[n] - vMean[2];
416 vHit.Rotate(alpha, vAxis);
418 fX[n] = vHit[0] + vMean[0];
419 fY[n] = vHit[1] + vMean[1];
420 fZ[n] = vHit[2] + vMean[2];
428 for (
unsigned int i = 0; i < GetNumberOfHits(); i++) {
429 if (GetEnergy(i) > energy) {
430 energy = GetEnergy(i);
440 Double_t energy = GetMaximumHitEnergy();
441 for (
unsigned int i = 0; i < GetNumberOfHits(); i++) {
442 if (GetEnergy(i) < energy) {
443 energy = GetEnergy(i);
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];
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);
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);
491 for (
unsigned int i = 0; i < GetNumberOfHits() - 1; i++) {
492 if (GetEnergy(i + 1) > GetEnergy(i)) {
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);
516 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] == XY)) {
517 return {(Double_t)fX[n], (Double_t)fY[n], 0};
519 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] == XZ)) {
520 return {(Double_t)fX[n], 0, (Double_t)fZ[n]};
522 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] == YZ)) {
523 return {0, (Double_t)fY[n], (Double_t)fZ[n]};
525 return {(Double_t)fX[n], (Double_t)fY[n], (Double_t)fZ[n]};
539 for (
unsigned int n = 0; n < GetNumberOfHits(); n++) {
540 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0)) {
553 for (
unsigned int n = 0; n < GetNumberOfHits(); n++) {
554 if ((fType.empty() ? !IsNaN(fY[n]) : fType[n] % Y == 0)) {
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];
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];
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];
603 if (totalEnergy == 0) {
606 meanX /= totalEnergy;
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];
625 if (totalEnergy == 0) {
628 meanY /= totalEnergy;
639 Double_t totalEnergy = 0;
640 for (
unsigned int n = 0; n < GetNumberOfHits(); n++) {
642 meanZ += fZ[n] * fEnergy[n];
643 totalEnergy += fEnergy[n];
647 if (totalEnergy == 0)
return 0;
648 meanZ /= totalEnergy;
659 TVector3 mean(GetMeanPositionX(), GetMeanPositionY(), GetMeanPositionZ());
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]);
675 if ((fType.empty() ? !IsNaN(fX[n]) : fType[n] % X == 0)) {
676 sigmaXY2 += fEnergy[n] * (meanX - fX[n]) * (meanX - fX[n]);
679 return sigmaXY2 /= totalEnergy;
686 Double_t sigmaX2 = 0;
688 Double_t totalEnergy = this->GetTotalEnergy();
689 Double_t meanX = this->GetMeanPositionX();
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]);
695 sigmaX2 /= totalEnergy;
697 return sigmaX = TMath::Sqrt(sigmaX2);
704 Double_t sigmaY2 = 0;
706 Double_t totalEnergy = this->GetTotalEnergy();
707 Double_t meanY = this->GetMeanPositionY();
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]);
713 sigmaY2 /= totalEnergy;
715 return sigmaY = TMath::Sqrt(sigmaY2);
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]);
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]);
740 std::sort(dist.begin(), dist.end());
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;
752 max += offset * minDiff + minDiff / 2.;
753 min -= offset * minDiff + minDiff / 2.;
754 nBins = std::round((max - min) / minDiff);
763 Double_t gausSigmaX = 0;
764 Int_t nHits = GetNumberOfHits();
771 bool doHitCorrection = nHits <= nHitsMin;
772 if (doHitCorrection) {
775 Int_t nElems = nHits + nAdd;
776 vector<Double_t> x(nElems), y(nElems), ex(nElems), ey(nElems);
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++) {
784 xMin = min(xMin, x[k]);
785 xMax = max(xMax, x[k]);
787 ey[k] = 10 * sqrt(y[k]);
792 Int_t h = nHits + nAdd / 2;
793 if (doHitCorrection) {
803 TGraphErrors* grX =
new TGraphErrors(nElems, &x[0], &y[0], &ex[0], &ey[0]);
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;
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");
820 if (fitResult->IsValid()) {
821 gausSigmaX = fit->GetParameter(2);
830 return abs(gausSigmaX);
837 Double_t gausSigmaY = 0;
838 Int_t nHits = GetNumberOfHits();
843 bool doHitCorrection = nHits <= nHitsMin;
844 if (doHitCorrection) {
847 Int_t nElems = nHits + nAdd;
848 vector<Double_t> x(nElems), y(nElems), ex(nElems), ey(nElems);
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++) {
856 xMin = min(xMin, x[k]);
857 xMax = max(xMax, x[k]);
859 ey[k] = 10 * sqrt(y[k]);
864 Int_t h = nHits + nAdd / 2;
865 if (doHitCorrection) {
875 TGraphErrors* grY =
new TGraphErrors(nElems, &x[0], &y[0], &ex[0], &ey[0]);
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;
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");
891 if (fitResult->IsValid()) {
892 gausSigmaY = fit->GetParameter(2);
901 return abs(gausSigmaY);
908 Double_t gausSigmaZ = 0;
909 Int_t nHits = GetNumberOfHits();
914 bool doHitCorrection = nHits <= nHitsMin;
915 if (doHitCorrection) {
918 Int_t nElems = nHits + nAdd;
919 vector<Double_t> x(nElems), y(nElems), ex(nElems), ey(nElems);
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++) {
927 xMin = min(xMin, x[k]);
928 xMax = max(xMax, x[k]);
930 ey[k] = 10 * sqrt(y[k]);
935 Int_t h = nHits + nAdd / 2;
936 if (doHitCorrection) {
946 TGraphErrors* grZ =
new TGraphErrors(nElems, &x[0], &y[0], &ex[0], &ey[0]);
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;
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");
962 if (fitResult->IsValid()) {
963 gausSigmaZ = fit->GetParameter(2);
972 return abs(gausSigmaZ);
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]);
991 return skewXY /= (totalEnergy * sigmaXY * sigmaXY * sigmaXY);
998 Double_t sigmaZ2 = 0;
999 Double_t totalEnergy = this->GetTotalEnergy();
1000 Double_t meanZ = this->GetMeanPositionZ();
1002 for (
unsigned int n = 0; n < GetNumberOfHits(); n++) {
1003 if (!IsNaN(fZ[n])) {
1004 sigmaZ2 += fEnergy[n] * (meanZ - fZ[n]) * (meanZ - fZ[n]);
1007 return sigmaZ2 /= totalEnergy;
1015 Double_t totalEnergy = this->GetTotalEnergy();
1016 Double_t sigmaZ = TMath::Sqrt(this->GetSigmaZ2());
1017 Double_t meanZ = this->GetMeanPositionZ();
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]);
1022 return skewZ /= (totalEnergy * sigmaZ * sigmaZ * sigmaZ);
1031 Double_t sizeY, Double_t theta)
const {
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];
1042 meanX /= totalEnergy;
1053 Double_t sizeY, Double_t theta)
const {
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];
1064 meanY /= totalEnergy;
1075 Double_t sizeY, Double_t theta)
const {
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];
1085 meanZ /= totalEnergy;
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));
1108 Double_t radius)
const {
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];
1119 meanX /= totalEnergy;
1129 Double_t radius)
const {
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];
1140 meanY /= totalEnergy;
1150 Double_t radius)
const {
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];
1160 meanZ /= totalEnergy;
1170 TVector3 mean(GetMeanPositionXInCylinder(x0, x1, radius), GetMeanPositionYInCylinder(x0, x1, radius),
1171 GetMeanPositionZInCylinder(x0, x1, radius));
1181 if (m > (
int)GetNumberOfHits() - 1) m = GetNumberOfHits() - 1;
1183 Double_t distance = 0;
1184 for (
int i = n; i < m; i++) distance += TMath::Sqrt(GetDistance2(i, i + 1));
1193 Double_t distance = 0;
1194 for (
unsigned int i = 0; i < GetNumberOfHits() - 1; i++) distance += TMath::Sqrt(GetDistance2(i, i + 1));
1202 Double_t dx = GetX(n) - GetX(m);
1203 Double_t dy = GetY(n) - GetY(m);
1204 Double_t dz = GetZ(n) - GetZ(m);
1206 if (areXY())
return dx * dx + dy * dy;
1207 if (areXZ())
return dx * dx + dz * dz;
1208 if (areYZ())
return dy * dy + dz * dz;
1210 return dx * dx + dy * dy + dz * dz;
1218 Double_t distance = 0;
1219 if (n > (
int)GetNumberOfHits() - 1) n = GetNumberOfHits() - 1;
1221 for (
int hit = 0; hit < n; hit++) distance += GetVector(hit + 1, hit).Mag();
1230 Int_t maxEnergy = 0;
1232 for (
int i = n; i < m; i++) {
1233 if (GetEnergy(i) > maxEnergy) {
1234 maxEnergy = GetEnergy(i);
1245 Int_t closestHit = 0;
1247 Double_t minDistance = 1.e30;
1248 for (
unsigned int nHit = 0; nHit < GetNumberOfHits(); nHit++) {
1249 TVector3 vector = position - GetPosition(nHit);
1251 Double_t distance = vector.Mag2();
1252 if (distance < minDistance) {
1254 minDistance = distance;
1266 TVector3 nodesSegment = this->GetVector(n, m);
1268 TVector3 origin = position - this->GetPosition(m);
1270 if (origin == TVector3(0, 0, 0))
return {0, 0};
1272 Double_t longitudinal = nodesSegment.Unit().Dot(origin);
1273 if (origin == nodesSegment)
return {longitudinal, 0};
1275 Double_t transversal = TMath::Sqrt(origin.Mag2() - longitudinal * longitudinal);
1277 return {longitudinal, transversal};
1285 const TVector3& position)
const {
1286 TVector3 oX = position - p0;
1288 if (oX == TVector3(0, 0, 0))
return 0;
1290 Double_t longitudinal = direction.Unit().Dot(oX);
1292 return TMath::Sqrt(oX.Mag2() - longitudinal * longitudinal);
1303 if (m == 0) m = this->GetNumberOfHits();
1305 if (m - n < 2)
return 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();
1313 sum += (1 - a.Dot(b)) / 2.;
1317 if (cont == 0)
return -1;
1327 if (m == 0) m = this->GetNumberOfHits();
1329 if (m - n < 2)
return 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();
1337 Double_t weight = TMath::Abs(this->GetEnergy(N - 1) - this->GetEnergy(N));
1338 weight += TMath::Abs(this->GetEnergy(N) - this->GetEnergy(N + 1));
1340 sum += weight * (1 - a.Dot(b)) / 2.;
1344 if (cont == 0)
return -1;
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;
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;
1383 if (N == -1) N = GetNumberOfHits();
1384 if (N > (
int)GetNumberOfHits()) N = GetNumberOfHits();
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);
1393 Double_t TRestHits::GetTotalEnergy()
const {
1395 for (
unsigned int n = 0; n < GetNumberOfHits(); n++) {
1396 energy += GetEnergy(n);
1404 TRestHits::TRestHits_Iterator::TRestHits_Iterator(
TRestHits* h,
int _index) {
1407 maxIndex = fHits->GetNumberOfHits();
1408 if (index < 0) index = 0;
1409 if (index >= maxIndex) index = maxIndex;
1412 void TRestHits::TRestHits_Iterator::toaccessor() {
1423 TRestHits_Iterator i(*
this);
1430 if (index >= maxIndex) index = maxIndex;
1435 if (index + n >= maxIndex) {
1444 if (index + n >= maxIndex) {
1445 return TRestHits_Iterator(fHits, maxIndex);
1447 return TRestHits_Iterator(fHits, index + n);
1453 if (index <= 0) index = 0;
1458 if (index - n <= 0) {
1467 if (index - n <= 0) {
1468 return TRestHits_Iterator(fHits, 0);
1470 return TRestHits_Iterator(fHits, index - n);
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();
It saves a 3-coordinate position and an energy for each punctual deposition.
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.
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...
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.
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,...
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 ¢er)
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 ...