13 #include <evt/Event.h>
14 #include <evt/ShowerRecData.h>
15 #include <evt/ShowerSRecData.h>
16 #include <evt/ShowerFRecData.h>
17 #include <evt/ShowerSimData.h>
19 #include <sevt/SEvent.h>
20 #include <sevt/StationRecData.h>
21 #include <sevt/EventTrigger.h>
22 #include <sevt/Station.h>
24 #include <fevt/FEvent.h>
25 #include <fevt/Header.h>
27 #include <fevt/Telescope.h>
28 #include <fevt/EyeHeader.h>
29 #include <fevt/EyeRecData.h>
31 #include <det/Detector.h>
33 #include <sdet/SDetector.h>
34 #include <sdet/Station.h>
35 #include <sdet/STimeVariance.h>
37 #include <fdet/FDetector.h>
39 #include <fdet/Telescope.h>
41 #include <fwk/LocalCoordinateSystem.h>
42 #include <fwk/CentralConfig.h>
44 #include <utl/CoordinateSystem.h>
45 #include <utl/PhysicalConstants.h>
46 #include <utl/PhysicalFunctions.h>
47 #include <utl/ErrorLogger.h>
48 #include <utl/TabulatedFunctionErrors.h>
49 #include <utl/TimeStamp.h>
50 #include <utl/AxialVector.h>
52 #include <utl/Reader.h>
57 #include <CLHEP/Matrix/Matrix.h>
58 #include <CLHEP/Matrix/Vector.h>
63 using namespace LDFFinderOG;
71 using CLHEP::HepMatrix;
72 using CLHEP::HepVector;
73 using CLHEP::HepRotation;
76 #define OUT(x) if ((x) <= fInfoLevel) cerr << " "
95 namespace LDFFinderOG {
102 const double scal = axis*station;
103 return station*station - scal*scal;
124 << g.GetX(cs)/
meter <<
", "
125 << g.GetY(cs)/
meter <<
", "
126 << g.GetZ(cs)/
meter <<
") [m]";
129 << g.GetX(cs) <<
", "
130 << g.GetY(cs) <<
", "
131 << g.GetZ(cs) <<
')';
139 fS1000(0), fS1000Err(0),
141 fFixedBeta(false), fBeta(0), fBetaErr(0),
142 fFixedGamma(false), fGamma(0), fGammaErr(0),
143 fEnergy(0), fEnergyErr(0),
144 fChi2(0), fNdof(0), fRecStage(0)
163 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
168 if (sIt->IsCandidate()) {
173 cout <<
" candidate " << sIt->GetId() <<
": " << r <<
' '
174 << sIt->GetRecData().GetTotalSignal() <<
' '
177 }
else if (sIt->IsSilent()) {
182 cout <<
" silent " << sIt->GetId() <<
": " << r <<
' '
192 const ShowerSRecData& recShower =
event.GetRecShower().GetSRecShower();
195 <<
"***** Final reconstructed shower data *****\n"
199 det::Detector::GetInstance().GetSiteCoordinateSystem()) <<
" (site)\n"
210 const double rc = 1/curv;
213 <<
"axis = (" << uvw.get<0>() <<
", " << uvw.get<1>() <<
", " << uvw.get<2>()
214 <<
") (bary)" <<
"\n"
229 <<
"Ropt = " << rOpt/
meter <<
" [m]\n";
242 if (fInfoLevel < eNone || fInfoLevel >
eMinuit) {
243 ERROR(
"<infoLevel> out of bounds");
253 if (fMaxTheta <= 0 || fMaxTheta > 90*
degree) {
254 ERROR(
"<maxTheta> does not make sense");
264 ERROR(
"<NKGFermiMu> must be > 0");
270 ERROR(
"<NKGFermiTau> must be > 0");
283 ERROR(
"<silentMaxRadius> must be > 0");
289 ERROR(
"<silentRadiusTransition> must be > 0");
297 ERROR(
"<maxBaryToCoreDistance> must be > 0");
322 info <<
"LDF type: " << (
fgLDFType ==
ePL ?
"PL" : (fgLDFType ==
eNKG ?
"NKG" :
"NKGFermi"))
323 <<
", minimization: " << (
fUseMaxLike ?
"Maximum-Likelihood" :
"Chi2");
358 <<
" S1000 = " << fi.
fS1000 <<
", "
359 "beta = " << fi.
fBeta <<
", "
360 "gamma = " << fi.
fGamma <<
'\n';
371 <<
" using barycenter as core\n";
375 <<
" energy = " << fi.
fEnergy/
EeV <<
" [EeV]\n";
402 <<
" Chi2/NDOF = " << nchi2 <<
" exceeds the limit "
410 <<
" Distance to core " << d/
km <<
" [km] is above the limit.\n";
417 <<
" chi2 = " << fi.
fChi2 <<
" / " << fi.
fNdof <<
"\n "
445 if (!(event.
HasSEvent() &&
event.HasRecShower() &&
446 event.GetRecShower().HasSRecShower()))
449 const SEvent& sEvent =
event.GetSEvent();
452 const ShowerSRecData& showerRec =
event.GetRecShower().GetSRecShower();
461 if (sIt->IsCandidate()) {
463 if (sIt->IsLowGainSaturation())
465 }
else if (sIt->IsSilent())
469 <<
"# candidate stations = " << nStations
470 <<
" (" << nSaturated <<
" saturated), " << nSilent <<
" silent\n";
476 <<
"Not enough stations.\n";
510 <<
" theta = " << theta/
degree <<
" is > than limit "
523 <<
" [ns] (to event time)\n "
526 "theta = " << theta/
degree <<
" [deg] (bary)\n "
530 <<
"local/site zenith angle diff. = "
540 best.
fRecStage = ShowerSRecData::kLDFEstimate;
542 <<
"Stage " << best.
fRecStage <<
": estimate beta, gamma, S1000\n";
551 bool useSilentStations = (nStations > 4);
554 useSilentStations = !useSilentStations;
556 const string stationType = useSilentStations ?
"candidate+silents" :
"candidates";
561 fi.
fRecStage = (useSilentStations ? ShowerSRecData::kLDFSilents : ShowerSRecData::kLDF);
570 <<
"Stage " << fi.
fRecStage <<
": fit " << stationType <<
" for S1000, core\n";
572 if (
FitLDF(fi, nStations))
574 else if (failOnError)
595 <<
"Stage " << fi.
fRecStage <<
": fit " << stationType <<
" for S1000, core"
599 if (
FitLDF(fi, nStations)) {
600 const bool fixBeta =
FixBeta(fi);
612 if (
FitLDF(fi, nStations))
614 else if (failOnError)
618 }
else if (failOnError)
638 cfi.
fRc = parameterizedRc;
645 <<
"Fit for axis with fixed Rc = " << cfi.
fRc/
kilometer <<
" [km]\n";
650 <<
"Fit for shower-front curvature and axis.\n";
654 <<
" Fit failed, retrying with fixed Rc = " << parameterizedRc <<
" [km]\n";
656 cfi.
fRc = parameterizedRc;
665 <<
" Last fit failed.\n";
671 " axis diff = " << diff/
degree <<
" [deg] (to plain-front fit)\n "
676 <<
" Opening-angle axis difference is above the limit.\n";
686 <<
" theta = " << newTheta/
degree <<
" is > than limit "
697 if (best.
fRecStage == ShowerSRecData::kLDFEstimate) {
699 <<
"Redo Stage " << best.
fRecStage <<
": estimate beta, gamma, S1000\n";
701 best.
fRecStage = ShowerSRecData::kLDFEstimateAndCurvature;
703 const string stationType = fi.
fUseSilents ?
"candidate+silents" :
"candidates";
705 <<
"Redo Stage " << fi.
fRecStage <<
": fit " << stationType <<
" for S1000, core"
712 if (
FitLDF(fi, nStations)) {
718 const double newRc = coreCenter.
GetMag();
720 cbest.
fAxis = coreCenter / newRc;
734 const double finalBeta = best.
fBeta;
741 const double deltap = (stopp - startp) / (
fRoptN - 1);
743 <<
"Ropt determination: \n";
744 for (
int i = 0; i <
fRoptN; ++i) {
746 const double p = startp + i*deltap;
761 const double dS1000_dBeta = (vS1000[0] - vS1000[fRoptN-1]) / (vBeta[0] - vBeta[fRoptN-1]);
784 ERROR(
"The event is not a simulated shower.");
795 ERROR(
"The event has no FD shower.");
800 const bool stereoRec =
801 event.HasRecShower() &&
event.GetRecShower().HasFRecShower();
803 double bestErrorEllipse = 0;
807 showerFRec = &
event.GetRecShower().GetFRecShower();
810 eyeIt != fEvent.
EyesEnd(ComponentSelector::eHasData); ++eyeIt) {
813 if (!eyeIt->HasRecData())
826 const fdet::Eye& dEye = det::Detector::GetInstance().GetFDetector().GetEye(*eyeIt);
831 const double rp = eyeRec.
GetRp();
833 const double t0 = eyeRec.
GetTZero();
838 const double distEyeCore = vecEyeCore.
GetMag();
843 const double sinChi0 = sin(chi0);
844 const double errorInSDP =
sqrt(
Sqr(rpErr/sinChi0) +
845 Sqr((chi0Err*distEyeCore)/(cos(chi0)*sinChi0)) +
846 rhoChi0Rp * rpErr * chi0Err);
849 const double errorPerpSDP = distEyeCore * sin(sdpPhiErr);
852 const double coreErrorEllipse = errorInSDP * errorPerpSDP *
kPi;
856 if (bestErrorEllipse && bestErrorEllipse < coreErrorEllipse)
859 bestErrorEllipse = coreErrorEllipse;
863 const Vector vertical(0,0,1, eyeCS);
864 const double alpha = 0.5*kPi -
Angle(vertical, vecEyeCore);
865 const double cosBeta =
CosAngle(axis, vecEyeCore);
869 refTime = eyeIt->GetHeader().GetTimeStamp() +
879 core = coreReference -
880 (localNormal * (coreReference -
fgBarycenter)) / (localNormal*axis) * axis;
885 err <<
"Bary-centric distance to core " << d/
kilometer
886 <<
" [km] is above the limit.";
907 vector<int> candidates;
911 if (!sIt->IsLowGainSaturation() || sIt->GetRecData().GetRecoveredSignal())
912 candidates.push_back(sIt->GetId());
914 const int nStations = candidates.size();
917 <<
"FixBeta = " <<
true
918 <<
": nStations = " << nStations <<
'\n';
922 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
923 int nStationsInRange = 0;
924 double maxDistance = 0;
926 for (vector<int>::const_iterator sIt = candidates.begin();
927 sIt != candidates.end(); ++sIt) {
936 for (vector<int>::const_iterator sJt = sIt + 1;
937 sJt != candidates.end(); ++sJt) {
943 const double distance = fabs(r - rr);
944 if (distance > maxDistance)
945 maxDistance = distance;
951 const bool fixBeta = !((nStationsInRange > 1 && maxDistance > 500*
meter) ||
952 (nStationsInRange > 2 && maxDistance > 400*
meter) ||
953 (nStationsInRange > 3 && maxDistance > 300*
meter));
955 <<
"FixBeta = " << fixBeta
956 <<
": nStations (InRange) = " << nStations <<
" (" << nStationsInRange
957 <<
"), maxDistance = " << maxDistance/
meter <<
" [m]\n";
968 vector<int> candidates;
972 if (!sIt->IsLowGainSaturation() || sIt->GetRecData().GetRecoveredSignal())
973 candidates.push_back(sIt->GetId());
975 const int nStations = candidates.size();
978 <<
"FixGamma = " <<
true
979 <<
": nStations = " << nStations <<
'\n';
983 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
984 int nStationsInRange = 0;
985 double maxDistance = 0;
987 for (vector<int>::const_iterator sIt = candidates.begin();
988 sIt != candidates.end(); ++sIt) {
997 for (vector<int>::const_iterator sJt = sIt + 1;
998 sJt != candidates.end(); ++sJt) {
1004 const double distance = fabs(r - rr);
1005 if (distance > maxDistance)
1006 maxDistance = distance;
1012 const bool fixGamma = !((nStationsInRange > 1 && maxDistance > 500*
meter) ||
1013 (nStationsInRange > 2 && maxDistance > 400*
meter) ||
1014 (nStationsInRange > 3 && maxDistance > 300*
meter));
1016 <<
"FixGamma = " << fixGamma
1017 <<
": nStations (InRange) = " << nStations <<
" (" << nStationsInRange
1018 <<
"), maxDistance = " << maxDistance/
meter <<
" [m]\n";
1029 const double k1000m = 1000*
meter;
1031 double rClosest = k1000m;
1034 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
1043 if (
abs(r - k1000m) < rMin) {
1044 rMin = fabs(r - k1000m);
1045 signal = sIt->GetRecData().GetTotalSignal();
1059 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
1061 double nStations = 0;
1066 if (sIt->IsCandidate())
1094 const double s = log10(fi.
fS1000);
1095 const double s2 =
Sqr(s);
1100 const double offset = 7.418 - 3.0613*s + 2.5262*s2;
1101 const double slope = 3.9779 + 3.2245*s + 4.5705*s2;
1103 return (offset + slope*sec1) *
kilometer;
1113 event.GetRecShower().GetSRecShower();
1116 det::Detector::GetInstance().GetSDetector();
1118 const double s1000 = lfi.
fS1000;
1119 const double beta = lfi.
fBeta;
1120 const double gamma = lfi.
fGamma;
1124 SEvent& sEvent =
event.GetSEvent();
1126 const bool haveCurvature = (cfi.
fRc != 0);
1128 const double ct0 = cfi.
fct0;
1137 LocalCoordinateSystem::Create(lfi.
fCore)
1142 HepMatrix hepErrMatrix(3,3,0);
1149 for (
int i = 0; i < 2; ++i)
1150 for (
int j = 0; j < 2; ++j)
1151 hepErrMatrix[i][j] = (i == j);
1157 HepMatrix hepRotationMatrix(3,3);
1158 for (
int i = 0; i < 3; ++i)
1159 for (
int j = 0; j < 3; ++j)
1160 hepRotationMatrix[i][j] = r[i][j];
1162 HepMatrix hepRotatedErrMatrix(3,3);
1163 hepRotatedErrMatrix = hepRotationMatrix * hepErrMatrix * hepRotationMatrix.T();
1172 if (sIt->HasRecData()) {
1176 const double rho =
sqrt(rho2);
1182 const double sigma = sigmaFactor *
sqrt(funcval);
1184 const double drho2 =
1185 (
Sqr(sPos.
GetX(showerPlaneCS)) * hepRotatedErrMatrix[0][0] +
1186 Sqr(sPos.
GetY(showerPlaneCS)) * hepRotatedErrMatrix[1][1] +
1187 2 * sPos.
GetX(showerPlaneCS) * sPos.
GetY(showerPlaneCS) * hepRotatedErrMatrix[0][1]) / rho2;
1189 const double drho =
sqrt(drho2);
1196 if (haveCurvature) {
1198 const Vector stationOrigin = showerOrigin - sPos;
1199 const double distOrigin = stationOrigin.
GetMag();
1200 const double predictedTime = (distOrigin + ct0) /
kSpeedOfLight;
1201 const double stationCosTheta = stationOrigin.
GetZ(
fgLocalCS) / distOrigin;
1202 const double sigma =
1204 const double residual = (measuredTime - predictedTime)/sigma;
1206 if (sIt->IsCandidate())
1212 double minRho = 0.5 * minMaxRho.
GetMin();
1213 double maxRho = 1.2 * minMaxRho.
GetMax();
1214 if (maxRho < 1200*
meter)
1215 maxRho = 1200*
meter;
1222 const int nLDFPoints = 200;
1223 const double dRho = (maxRho - minRho)/(nLDFPoints - 1);
1224 for (
int i = 0; i < nLDFPoints; ++i) {
1225 const double rho = minRho + i*dRho;
1227 const double sigma = sigmaFactor *
sqrt(funcval);
1228 ldf.
PushBack(rho, 0, funcval, sigma);
1232 if (haveCurvature) {
1234 const double rc = cfi.
fRc;
1238 const double timeMean = timeStat.
GetAverage();
1242 const int ndof = timeStat.
GetN()
1271 double energyErr = 0;
1298 minuit.mnexcm(
"SET PRINTOUT", argList, 1, errFlag);
1299 minuit.mnexcm(
"SET NOWARNINGS", argList, 0, errFlag);
1300 minuit.SetPrintLevel(-1);
1310 minuit.mnexcm(
"SET ERRORDEF", argList, 1, errFlag);
1312 minuit.mnparm(0,
"s1000", fi.
fS1000, 1., 0, 0, errFlag);
1315 minuit.mnparm(3,
"beta", fi.
fBeta, 0.1, 0, 0, errFlag);
1316 minuit.mnparm(4,
"gamma", fi.
fGamma, 0.02, 0, 0, errFlag);
1319 minuit.FixParameter(1);
1320 minuit.FixParameter(2);
1324 minuit.FixParameter(3);
1326 minuit.FixParameter(4);
1330 minuit.mnexcm(
"CALI", argList, 1, errFlag);
1333 minuit.mnexcm(
"MINIMIZE", argList, 1, errFlag);
1336 <<
" minuit minimize error: " << errFlag <<
'\n';
1337 minuit.mnexcm(
"MINOS", argList, 0, errFlag);
1340 <<
" minuit minos error: " << errFlag <<
'\n';
1352 minuit.GetParameter(1, x, xErr);
1353 minuit.GetParameter(2, y, yErr);
1370 if (minuit.fNpar > 5) {
1372 err <<
"Number of parameters used in Minuit covarince matrix larger "
1373 "than size of matrix fErrMatrix";
1381 return minuit.fAmin;
1395 minuit.mnexcm(
"SET PRINTOUT", argList, 1, errFlag);
1396 minuit.mnexcm(
"SET NOWARNINGS", argList, 0, errFlag);
1397 minuit.SetPrintLevel(-1);
1406 minuit.mnexcm(
"SET ERRORDEF", argList, 1, errFlag);
1408 minuit.mnparm(0,
"s1000", fi.
fS1000, 0, 0, 0, errFlag);
1411 minuit.mnparm(3,
"beta", fi.
fBeta, 0, 0, 0, errFlag);
1412 minuit.mnparm(4,
"gamma", fi.
fGamma, 0, 0, 0, errFlag);
1415 minuit.mnexcm(
"CALI", argList, 1, errFlag);
1422 <<
" minuit get chi2 error: " << errFlag <<
'\n';
1426 return minuit.fAmin;
1433 double*
const par,
const int iFlag)
1445 const double& x = par[1];
1446 const double& y = par[2];
1447 const double s1000 = par[0];
1463 static vector<bool> sIsCandidate;
1464 static vector<Point> sPosition;
1465 static vector<double> sSignal;
1466 static vector<double> sSignalError;
1467 static vector<bool> sIsSaturation;
1471 sIsCandidate.clear();
1474 sSignalError.clear();
1475 sIsSaturation.clear();
1477 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
1482 if (sIt->IsCandidate()) {
1484 sIsCandidate.push_back(
true);
1486 const bool saturated = sIt->IsLowGainSaturation();
1487 if (saturated && sIt->GetRecData().GetRecoveredSignal()) {
1488 sSignal.push_back(sIt->GetRecData().GetRecoveredSignal());
1489 sSignalError.push_back(sIt->GetRecData().GetRecoveredSignalError());
1491 sSignal.push_back(sIt->GetRecData().GetTotalSignal());
1492 sSignalError.push_back(0);
1494 sIsSaturation.push_back(saturated);
1498 sIsCandidate.push_back(
false);
1500 sSignal.push_back(0);
1501 sSignalError.push_back(0);
1502 sIsSaturation.push_back(
false);
1508 const int nStations = sIsCandidate.size();
1512 const double poissonFactor =
max(1., 1/
Sqr(sigmaFactor));
1516 double logLikelihood = 0;
1518 for (
int i = 0; i < nStations; ++i) {
1520 if (sIsCandidate[i]) {
1527 const bool hasRecovery = (!
fgLowerLimit && sSignalError[i]);
1529 const double particlesInStation = (sIsSaturation[i] && !hasRecovery) ?
1530 poissonFactor * (sSignal[i] - sSignalError[i]) :
1531 poissonFactor * sSignal[i];
1534 const double particlePrediction = poissonFactor * signalPrediction;
1537 const double sigma = (sIsSaturation[i] && hasRecovery) ?
1538 poissonFactor *
sqrt(
Sqr(sSignalError[i]) +
Sqr(sigmaFactor) * signalPrediction) :
1539 poissonFactor * sigmaFactor *
sqrt(signalPrediction);
1542 if (sIsSaturation[i] && !hasRecovery && nStations > 3)
1546 else if (particlesInStation > 30)
1554 logLikelihood += particlesInStation * log(particlePrediction) - particlePrediction;
1556 double logarithmicFactor = 0;
1557 const int stop = int(particlesInStation + 0.5);
1558 for (
int j = 1; j <= stop; ++j)
1559 logarithmicFactor += log(
double(j));
1561 logLikelihood -= logarithmicFactor;
1565 }
else if (s1000 > 0) {
1569 const double particlePrediction = poissonFactor * signalPrediction;
1571 logLikelihood += particlePrediction > 0.03 ?
1572 -particlePrediction +
1574 particlePrediction * (1 +
1575 0.5*particlePrediction * (1 +
1576 (1./3)*particlePrediction
1579 -(1./24)*
Sqr(
Sqr(particlePrediction));
1586 value = -logLikelihood;
1592 double*
const par,
const int iFlag)
1594 const double& x = par[1];
1595 const double& y = par[2];
1596 const double s1000 = par[0];
1599 static int nStations = 0;
1600 static vector<bool> sIsCandidate;
1601 static vector<Point> sPosition;
1602 static vector<double> sSignal;
1603 static vector<double> sSignalError;
1604 static vector<double> sIsSaturation;
1611 sIsCandidate.clear();
1614 sSignalError.clear();
1615 sIsSaturation.clear();
1617 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
1622 if (sIt->IsCandidate()) {
1624 sIsCandidate.push_back(
true);
1626 const bool saturation = sIt->IsLowGainSaturation();
1627 if (saturation && sIt->GetRecData().GetRecoveredSignal()) {
1628 sSignal.push_back(sIt->GetRecData().GetRecoveredSignal());
1629 sSignalError.push_back(sIt->GetRecData().GetRecoveredSignalError());
1631 sSignal.push_back(sIt->GetRecData().GetTotalSignal());
1632 sSignalError.push_back(0.);
1634 sIsSaturation.push_back(saturation);
1638 sIsCandidate.push_back(
false);
1640 sSignal.push_back(0.);
1644 nStations = sIsCandidate.size();
1659 for (
int i = 0; i < nStations; ++i)
1661 if (sIsCandidate[i]) {
1665 const double secDerivative =
1667 const double sigma =
1668 (sIsSaturation[i] && sSignalError[i] && secDerivative <
fgNoRecovery) ?
1669 sqrt(
Sqr(sSignalError[i]) +
Sqr(sigmaFactor) * predictedSignal) :
1670 sigmaFactor *
sqrt(predictedSignal);
1673 if (!sIsSaturation[i] || (sSignalError[i] && secDerivative < 1)) {
1675 (predictedSignal > numeric_limits<double>::min() ?
1676 (sSignal[i] - predictedSignal) / sigma :
1678 const double dev2 =
Sqr(dev);
1700 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
1731 const double mi2 = 0.5*(xi.
GetMag2() -
Sqr(cti));
1740 if (sIt->GetId() < sJt->GetId()) {
1744 const Vector xij(xi - xj);
1752 const double cdtij = cti - ctj;
1754 const double mj2 = 0.5*(xj.
GetMag2() -
Sqr(ctj));
1756 const double dmij2 = mi2 - mj2;
1777 HepMatrix delta(3,3);
1778 delta[0][0] = dxx; delta[0][1] = dxy; delta[0][2] = -dxt;
1779 delta[1][0] = dxy; delta[1][1] = dyy; delta[1][2] = -dyt;
1780 delta[2][0] = -dxt; delta[2][1] = -dyt; delta[2][2] = dtt;
1790 HepVector
p(delta*k);
1792 const double& rcu = p[0];
1793 const double& rcv = p[1];
1794 const double& ct0 = p[2];
1796 const double rc2 = 2*(rcu*sx + rcv*sy - ct0*st - sm2) +
Sqr(ct0);
1802 const double rc =
sqrt(rc2);
1803 const double rcw2 = rc2 -
Sqr(rcu) -
Sqr(rcv);
1808 const double rcw =
sqrt(rcw2);
1811 cfi.
fAxis = curvAxis;
1826 namespace LDFFinderOG {
1847 minuit.mnexcm(
"SET PRINTOUT", argList, 1, errFlag);
1848 minuit.mnexcm(
"SET NOWARNINGS", argList, 0, errFlag);
1849 minuit.SetPrintLevel(-1);
1855 minuit.mnexcm(
"SET ERRORDEF", argList, 1, errFlag);
1859 minuit.mnparm(2,
"Rc", cfi.
fRc, 10*
meter, 0, 0, errFlag);
1860 minuit.mnparm(3,
"ct0", cfi.
fct0+ cfi.
fRc, 10*
meter, 0, 0, errFlag);
1863 minuit.FixParameter(0);
1864 minuit.FixParameter(1);
1868 minuit.FixParameter(2);
1872 minuit.mnexcm(
"CALI", argList, 1, errFlag);
1874 bool fatalError =
false;
1877 minuit.mnexcm(
"MINIMIZE", argList, 1, errFlag);
1880 <<
" minuit minimize error: " << errFlag <<
'\n';
1881 minuit.mnexcm(
"MINOS", argList, 0, errFlag);
1884 <<
" minuit minos error: " << errFlag <<
'\n';
1902 minuit.GetParameter(0, u, uErr);
1905 minuit.GetParameter(1, v, vErr);
1906 const double w2 = 1 -
Sqr(u) -
Sqr(v);
1909 <<
" Fit failed due to unphysical angle cosines.\n";
1915 minuit.GetParameter(2, cfi.
fRc, cfi.
fRcErr);
1918 <<
" Fit failed due to Rc <= 0.\n";
1923 <<
" Rc too large, reverting to plane fit.\n";
1929 minuit.GetParameter(3, ct0, ct0Err);
1935 minuit.mnemat(&emat[0][0], 4);
1944 namespace LDFFinderOG {
1958 double*
const par,
const int flag)
1960 const double& u = par[0];
1961 const double& v = par[1];
1962 const double& rc = par[2];
1963 const double& ct0 = par[3];
1965 static vector<CurvatureFitStationInfo> sStationInfo;
1970 sStationInfo.clear();
1971 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
1983 sStationInfo.push_back(si);
1987 timeVariance = &sdet::STimeVariance::GetInstance();
1991 const double w2 = 1 -
Sqr(u) -
Sqr(v);
2001 const double w =
sqrt(w2);
2004 const Vector rcAxis = rc * axis;
2008 for (vector<CurvatureFitStationInfo>::const_iterator siIt = sStationInfo.begin();
2009 siIt != sStationInfo.end(); ++siIt) {
2011 const Vector stationCenter = rcAxis - siIt->fPosition;
2012 const double drc = stationCenter.
GetMag();
2014 const double stationCosTheta = stationCenter.
GetZ(
fgLocalCS) / drc;
2016 const double sigma2 =
2019 const double cdt = siIt->fCTiming - ct0 - drc + rc;
2021 chi2 +=
Sqr(cdt) / sigma2;
double LogarithmOfNormalComplementCDF(const double x)
Class to access station level reconstructed data.
double GetCorrelationXY() const
void SetCurvature(const double curvature, const double error)
gaussian curvature = 1 / Rc
static utl::Vector fgShowerAxis
static bool fgUseSilentStations
double GetCurvatureError() const
StationIterator StationsEnd()
End of all stations.
void SetTotalSignal(const double signal, const double sErr=0)
Total integrated signal in VEM unit, averaged over pmts.
void SetShowerSize(const double value, const double error)
constexpr T Sqr(const T &x)
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
const utl::TimeStamp & GetTimeStamp() const
Get the TimeStamp of the absolute shower core-time.
double GetRpError() const
double GetAngleNdof() const
double LDFFunction(const LDFFunctionType type, const double r, const double beta, const double gamma=0, const double mu=2660.*meter, const double tau=242.*meter)
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
double GetCurvature() const
gaussian curvature = 1 / Rc
void SetBeta(const double beta, const double error)
double RPerp(const Vector &axis, const Vector &station)
Report success to RunController.
static utl::Point fgBarycenter
void EstimateBetaGamma(double &beta, double &gamma, const LDFFunctionType type, const double cosTheta, const double s1000=0)
static double fgNoRecovery
double SigmaForFixedBeta(const double s1000)
Interface class to access to the SD Reconstruction of a Shower.
bool FixGamma(const LDFFitInterface &fi) const
void SetLDFOptimumDistance(const double rOpt)
boost::filter_iterator< ComponentSelector, ConstAllEyeIterator > ConstEyeIterator
const utl::TabulatedFunctionErrors & GetLDF() const
boost::tuple< double, double, double > Triple
Coordinate triple for easy getting or setting of coordinates.
Interface class to access to the SD part of an event.
double GetBetaError() const
const utl::TimeStamp & GetBarytime() const
void SetAzimuthShowerPlane(const double azimuth)
Azimuth in shower plane coordinates.
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
double GetChiZero() const
double ParameterizedRc(const LDFFitInterface &fi) const
double FitCurvatureDriver(CurvatureFitInterface &fi) const
Skip remaining modules in the current loop and continue with next iteration of the loop...
double GetAngleChi2() const
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
unsigned int GetSDPFitNDof() const
bool HasSimShower() const
EventTrigger & GetTrigger()
Get the object with central trigger data, throw if n.a.
EyeIterator EyesEnd(const ComponentSelector::Status status)
const utl::CoordinateSystemPtr & GetBarycenterCoordinateSystem() const
origin = GetBarycenter(), z-axis = local vertical, x-axis = east
unsigned int GetTimeFitNDof() const
bool EstimateCurvature(CurvatureFitInterface &fi) const
const utl::Vector & GetCoreError() const
#define INFO(message)
Macro for logging informational messages.
struct LDFFinderOG::LDFFinder::Stage3 fStage3
void SetAngleChi2(const double chi2, const double ndof)
static const sevt::SEvent * fgCurrentSEvent
double fMaxAxisAngleDifference
double GetShowerSize() const
bool FixBeta(const LDFFitInterface &fi) const
Base class for exceptions trying to access non-existing components.
Detector description interface for Eye-related data.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
double pow(const double x, const unsigned int i)
double InverseNormalCDF(const double p)
Inverse of the comulative normal distribution. Taken from http://home.online.no/~pjacklam/notes/invno...
void SetBetaSystematics(const double betasys)
double NormalCDF(const double x)
double GetSDPPhiError() const
static LDFFunctionType fgLDFType
void SetLDFChi2(const double chi2, const double ndof)
double GetEnergyError() const
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
double GetChiZeroError() const
A TimeStamp holds GPS second and nanosecond for some event.
struct LDFFinderOG::LDFFinder::Stage1 fStage1
static double fgSilentMaxRadius
Exception for reporting variable out of valid range.
void SetAngleErrors(const utl::Vector::Triple &u_v_w, const utl::Vector::Triple &sigma_u2_uv_v2)
utl::Point GetPosition() const
Tank position.
void SetTimeResidualMean(const double mean)
Interface class to access Shower Simulated parameters.
struct LDFFinderOG::LDFFinder::Stage0 fStage0
CandidateStationIterator CandidateStationsBegin()
double GetStandardDeviation() const
void SetCoreError(const utl::Vector &coreerr)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
void EstimateEnergy(LDFFitInterface &fi) const
Class representing a document branch.
void SetResidual(const double residual)
Residual of geometry fit.
void EstimateLDF(LDFFitInterface &fi, const utl::Point &core) const
double Fermi(const double x)
Encapsulation of the Minuit fit for Ropt.
void SetLDFResidual(const double LDFresidual)
Residual of lateral fit.
void OutputStations(const LDFFitInterface &fi) const
utl::TimeStamp GetSignalStartTime() const
Start time of the signal.
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
double LDFFunctionSecondDerivative(const LDFFunctionType type, const double r, const double beta, const double gamma=0, const double mu=2660.*meter, const double tau=242.*meter)
double GetX(const CoordinateSystemPtr &coordinateSystem) const
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
constexpr double nanosecond
const utl::TimeStamp & GetCoreTime() const
time when shower front passes through the core point
double abs(const SVector< n, T > &v)
void SetAxis(const utl::Vector &axis)
double GetTotalSignal() const
Total integrated signal in VEM unit, averaged over pmts.
const utl::Point & GetPosition() const
Get the position of the shower core.
const utl::Point & GetBarycenter() const
bool HasFRecShower() const
Check if reconstructed shower info has been allocated.
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
EyeIterator EyesBegin(const ComponentSelector::Status status)
void SetShowerSizeSystematics(const double sysError)
double GetTimeResidualSpread() const
double GetLDFRecStage() const
double GetThetaError() const
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
const utl::Vector & GetAxis() const
double GetPhiError() const
static double fgNKGFermiMu
void PushBack(const double x, const double xErr, const double y, const double yErr)
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
static utl::TimeStamp fgBaryTime
Top of Fluorescence Detector event hierarchy.
Eye-specific shower reconstruction data.
void SetCoreTime(const utl::TimeStamp &coreTime, const utl::TimeInterval &coreTimeErr)
bool FitLDF(LDFFitInterface &fi, const int nStations) const
const char * complexWMessage
double GetSumOfSquares() const
int fMinNumberForFullCurvatureFit
static utl::CoordinateSystemPtr fgLocalCS
static void CurvatureFitFnc(int &nPar, double *const grad, double &value, double *const par, const int iFlag)
double GetRpChi0Correlation() const
double GetY(const CoordinateSystemPtr &coordinateSystem) const
const utl::TimeInterval & GetCoreTimeError() const
constexpr double kSpeedOfLight
double GetGammaError() const
A TimeInterval is used to represent time elapsed between two events.
utl::TimeStamp GetTime() const
Get time of the trigger.
void SetRecData(evt::Event &event, const LDFFitInterface &lfi, const CurvatureFitInterface &cfi) const
ResultFlag
Flag returned by module methods to the RunController.
void SetTimeResidualSpread(const double spread)
double GetLDFOptimumDistance() const
static double fgSilentSignalThreshold
double GetAverage() const
void SetNumberOfActiveStations(const int nstations)
double GetCorrelationThetaPhi() const
string ToString(const G &g, const CoordinateSystemPtr cs, bool units=true)
std::pair< double, double > Fit(const LDFFunctionType type, const int n, const double *const s1000, const double *const beta, const bool verbose=false)
StationIterator StationsBegin()
Beginning of all stations.
double RPerp2(const Vector &axis, const Vector &station)
constexpr double kilometer
double EstimateChi2(const LDFFitInterface &fi) const
Estimate Chi2 using Minuit.
static void LDFFitMaxLikeFnc(int &nPar, double *const grad, double &value, double *const par, const int iFlag)
Likelihood function to minimize.
Interface class to access to Fluorescence reconstruction of a Shower.
Detector description interface for SDetector-related data.
double GetShowerSizeError() const
static double fgNKGFermiTau
double SignalUncertaintyFactor(const ESignalVarianceModel model, const double cosTheta)
double CosAngle(const Vector &l, const Vector &r)
Report failure to RunController, causing RunController to terminate execution.
const utl::Point & GetCorePosition() const
void SetCorePosition(const utl::Point &core)
Main configuration utility.
boost::indirect_iterator< InternalStationIterator, Station & > StationIterator
Iterator over all stations.
void SetNKGFermiParameters(const double mu, const double tau)
void SetLDFLikelihood(const double likelihood)
Accumulates and calculates standard deviation.
CandidateStationIterator CandidateStationsEnd()
void SetShowerSizeType(const ShowerSizeType type)
void SetGamma(const double gamma, const double error)
double fMaxBaryToCoreDistance
void SetEnergy(const double energy, const double error)
void GetEnergy(const double cosTheta, const double s1000, const double s1000Err, double &energy, double &energyErr) const
EnergyConversion fEnergyConversion
bool FixCore(const evt::Event &event, Point &core, TimeStamp &coreTime, Vector &axis) const
void SetLDFRecStage(const double stage)
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
void SetCorrelationXY(const double corr)
const Station & GetStation(const int stationId) const
Get station by Station Id.
boost::indirect_iterator< InternalConstStationIterator, const Station & > ConstStationIterator
void SetSPDistance(const double distance, const double error)
Distance from core in shower plane coordinates.
#define ERROR(message)
Macro for logging error messages.
double GetTimeResidualMean() const
void EstimateS1000(LDFFitInterface &fi) const
First guess of S1000 to give a starting point.
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
double LogarithmOfNormalPDF(const double x)
utl::Point GetPosition() const
Eye position.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
struct LDFFinderOG::LDFFinder::Stage2 fStage2
static void LDFFitChi2Fnc(int &nPar, double *const grad, double &value, double *const par, const int iFlag)
boost::filter_iterator< CandidateStationFilter, ConstStationIterator > ConstCandidateStationIterator
double FitLDFDriver(LDFFitInterface &fi) const
Fit using Minuit.
void OutputResults(const evt::Event &event) const
double EstimateNStationsInFit(const LDFFitInterface &fi) const
static double fgSilentRadiusTransition
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.
double GetTimeSigma2(const double signal, const double t50, const double cosTheta, const double distance=0) const