7 #include <fwk/LocalCoordinateSystem.h>
8 #include <fwk/CentralConfig.h>
10 #include <utl/ErrorLogger.h>
11 #include <utl/MathConstants.h>
12 #include <utl/PhysicalConstants.h>
13 #include <utl/AugerUnits.h>
14 #include <utl/String.h>
15 #include <utl/NumericalErrorPropagator.h>
16 #include <utl/Transformation.h>
17 #include <utl/EquationSolver.h>
19 #include <tls/MuonProfile.h>
20 #include <tls/VTankResponse.h>
21 #include <tls/TankResponseFactory.h>
22 #include <tls/EMComponent.h>
24 #include <det/Detector.h>
26 #include <sdet/SDetector.h>
27 #include <sdet/STimeVariance.h>
29 #include <fdet/FDetector.h>
32 #include <evt/Event.h>
33 #include <evt/ShowerRecData.h>
34 #include <evt/ShowerSRecData.h>
35 #include <evt/ShowerFRecData.h>
36 #include <evt/ShowerSimData.h>
38 #include <fevt/FEvent.h>
40 #include <fevt/EyeRecData.h>
41 #include <fevt/FdComponentSelector.h>
43 #include <sevt/SEvent.h>
44 #include <sevt/EventTrigger.h>
45 #include <sevt/Station.h>
46 #include <sevt/StationRecData.h>
47 #include <sevt/SortCriteria.h>
48 #include <sevt/Header.h>
50 #include <Minuit2/MnMinimize.h>
51 #include <Minuit2/MnHesse.h>
52 #include <Minuit2/MnMinos.h>
53 #include <Minuit2/MnMigrad.h>
54 #include <Minuit2/FCNBase.h>
55 #include <Minuit2/FunctionMinimum.h>
56 #include <Minuit2/MnUserParameters.h>
57 #include <Minuit2/MnUserCovariance.h>
58 #include <Minuit2/MnPrint.h>
63 using namespace SdHorizontalReconstructionNS;
75 : fParent(parent), fEyeCS(eyeCS)
79 Transform(vector<double>& output,
const vector<double>& input)
82 const double sDPtheta = input[0];
83 const double sDPphi = input[1];
84 const double rp = input[2];
85 const double chi0 = input[3];
87 const Point eyePos(0, 0, 0, fEyeCS);
90 const Vector sdp(1.0, sDPtheta, sDPphi, fEyeCS, Vector::kSpherical);
92 const Vector vertical(0, 0, 1, fEyeCS);
96 const Vector core_eye_vec = rp / sin(
kPi - chi0) * horizontalInSDP;
97 Point core = eyePos + core_eye_vec;
101 const Vector axis(rot * horizontalInSDP);
104 core -= axis * core.
GetZ(fParent.fBaryCS)/axis.GetZ(fParent.fBaryCS);
108 output[
eThetaExt] = axis.GetTheta(fParent.fBaryCS);
109 output[
ePhiExt] = axis.GetPhi(fParent.fBaryCS);
121 const vector<Point>& posList)
122 : fParent(parent), fPosList(posList)
126 Transform(vector<double>& output,
const vector<double>& input)
129 const double coreX = input[0];
130 const double coreY = input[1];
131 const double theta = input[2];
132 const double phi = input[3];
133 const double distance = input[4];
134 const double ctime = input[5];
137 fParent.GetShowerAxis(core, origin, coreX, coreY, theta, phi, distance);
143 output[1] = showerAxis.
GetPhi(coreCS);
144 output[2] = showerAxis.
GetMag();
145 output[3] = ctime + showerAxis.
GetMag();
147 const size_t n = fPosList.size();
148 for (
size_t i = 0; i < n; ++i)
149 output[4 + i] =
GetRho(fPosList[i], core, origin);
164 topB.
GetChild(
"MaxRadiusNonTriggeringStations").
GetData(fMaxSilentRadius);
166 topB.
GetChild(
"MaxRelativeDistanceNonTriggeringStations").
GetData(fMaxSilentRelDistance);
168 topB.
GetChild(
"SilentSignalThreshold").
GetData(fSilentSignalThreshold);
170 topB.
GetChild(
"DropStationsBelowThreshold").
GetData(fDropStationsBelowThreshold);
175 string showerFrontModel;
177 if (showerFrontModel ==
"MuonArrival")
182 topB.
GetChild(
"MaxDistanceCoreToBarycenter").
GetData(fMaxDistanceCoreToBarycenter);
188 topB.
GetChild(
"MaxDistanceStationToExternalCore").
GetData(fMaxDistanceStationToExternalCore);
190 topB.
GetChild(
"MinStationsForEnergyFit").
GetData(fMinStationsForEnergyFit);
192 topB.
GetChild(
"MinStationsForProductionDistanceFit").
GetData(fMinStationsForProductionDistanceFit);
197 fMuonProfile = boost::shared_ptr<MuonProfile>(
new MuonProfile(muonProfileBranch));
202 fTankResponse = &TankResponseFactory::GetInstance().
203 GetTankResponse(tankResponseBranch);
208 fEMComponent = boost::shared_ptr<EMComponent>(
new EMComponent(EMComponentBranch));
215 fExternalGeometry =
eNone;
216 string externalGeometry;
218 if (externalGeometry ==
"MC") fExternalGeometry =
eMC;
219 if (externalGeometry ==
"FixHybrid") fExternalGeometry =
eFixHybrid;
220 if (externalGeometry ==
"SoftHybrid") fExternalGeometry =
eSoftHybrid;
222 topB.
GetChild(
"PropagateAxisUncertainty").
GetData(fPropagateAxisUncertainty);
227 msg <<
"\nParameters:\n"
228 <<
" Accepted theta angle range : [" << fMinTheta/
degree <<
" , " << fMaxTheta/
degree <<
" ] deg" <<
'\n'
229 <<
" Max. radius of non-triggering stations : " << fMaxSilentRadius/
km <<
" km\n"
230 <<
" Max. rel. distance of non-trig. stations : " << fMaxSilentRelDistance/
km <<
" km\n"
231 <<
" Silent signal threshold : " << fSilentSignalThreshold <<
" VEM\n"
232 <<
" Drop stations below threshold : " << (fDropStationsBelowThreshold ?
"yes" :
"no") <<
"\n"
233 <<
" Allowed distance core,barycenter : " << fMaxDistanceCoreToBarycenter/
km <<
" km"
234 << (fMaxDistanceCoreToBarycenter == 0 ?
" (check disabled)\n" :
"\n")
235 <<
" Allowed theta change : " << fMaxThetaDifference/
degree <<
" deg"
236 << (fMaxThetaDifference == 0 ?
" (check disabled)\n" :
"\n")
237 <<
" Required stations for energy fit : " << fMinStationsForEnergyFit <<
'\n'
238 <<
" Required stations for prod. distance fit : " << fMinStationsForProductionDistanceFit <<
'\n'
239 <<
" ShowerFrontModel : " << showerFrontModel <<
'\n'
240 <<
" MuonProfile : " << muonProfileBranch.
GetName()
241 <<
" Theta limits [" << fMuonProfile->GetThetaMin()/
degree <<
" , "
242 << fMuonProfile->GetThetaMax()/
degree <<
" ] deg" <<
"\n"
243 <<
" TankResponse : " << tankResponseBranch.
GetName()
244 <<
" Theta limits [" << fTankResponse->GetThetaMin()/
degree <<
" , "
245 << fTankResponse->GetThetaMax()/
degree <<
" ] deg" <<
"\n"
246 <<
" EMComponent : " << EMComponentBranch.
GetName()
247 <<
" Theta limits [" << fEMComponent->GetThetaMin()/
degree <<
" , "
248 << fEMComponent->GetThetaMax()/
degree <<
" ] deg" <<
"\n"
249 <<
" Applying empirical correction N19-unbiased = (1 + A + B*lg(N19))*N19\n"
250 <<
" A : " << fN19Correction[0] <<
"\n"
251 <<
" B : " << fN19Correction[1] <<
"\n"
252 <<
" Energy calibration\n"
253 <<
" EnergyConstant: " << fEnergyConstant/
EeV <<
" EeV\n"
254 <<
" Gamma : " << fGamma <<
"\n"
255 <<
" External geometry : " << externalGeometry <<
"\n"
256 <<
" Max. time offset [ext.geom.] : " << fMaxTimeSigma <<
" sigma\n"
257 <<
" Allowed station distance [ext.geom.] : " << fMaxDistanceStationToExternalCore/
km <<
" km"
258 << (fMaxDistanceStationToExternalCore == 0 ?
" (check disabled)" :
"");
269 msg <<
"Event " <<
event.GetHeader().GetId();
275 return eContinueLoop;
277 return eContinueLoop;
279 SEvent& sEvent =
event.GetSEvent();
289 size_t nCandidates = 0;
291 if (!UpdateBarycenter(nCandidates, sEvent))
293 ERROR(
"Could not find barycenter!");
294 return eContinueLoop;
297 if (nCandidates < fMinStationsForEnergyFit) {
299 msg <<
"Event has less than " << fMinStationsForEnergyFit
300 <<
" stations. Dropping it...";
302 return eContinueLoop;
305 if (fExternalGeometry ==
eNone) {
307 if (!event.
HasRecShower() && !
event.GetRecShower().HasSRecShower())
308 return eContinueLoop;
309 const ShowerSRecData& sRecSh =
event.GetRecShower().GetSRecShower();
323 axisData.
fChi2 =
event.GetRecShower().GetSRecShower().GetAngleChi2();
327 if (!GetExternalGeometry(extGeomData, event))
328 return eContinueLoop;
345 if (!CleanEvent(nCandidates, sEvent, axisData, sizeData))
346 return eContinueLoop;
352 msg <<
" theta = " << axisData.
fPar[
eTheta]/
degree <<
" deg outside range ["
353 << fMinTheta/
degree <<
", " << fMaxTheta/
degree <<
"] deg, skipping...";
355 return eContinueLoop;
359 GetShowerAxis(core, origin, sizeData, axisData);
360 PrepareStationData(list, slist, core, origin, sEvent);
364 <<
" Theta " << axisData.
fPar[
eTheta]/
deg <<
" deg (bary)" <<
'\n'
365 <<
" # candidate stations = " << nCandidates <<
'\n'
366 <<
" # included non-triggering stations = " << slist.size();
370 const bool fixAxis = (fExternalGeometry ==
eMC || fExternalGeometry ==
eFixHybrid);
373 INFO(
"Fit shower front with fixed production distance");
377 if (nCandidates >= fMinStationsForProductionDistanceFit)
380 INFO(
"Fit shower front with free production distance");
381 if (FitShowerFront(core, update, extGeomData, list, fixAxis ? eFixAxis : 0))
388 INFO(
"Fit N19 with core fixed to barycenter, fixed axis, approximate chi2 method");
392 ERROR(
"N19 estimate failed, this should never happen! Skipping event...");
393 return eContinueLoop;
396 if (fExternalGeometry ==
eMC || fExternalGeometry ==
eFixHybrid)
398 INFO(
"Fit N19 with fixed external geometry (core, axis)");
400 if (FitShowerSize(update, axisData, extGeomData, list, slist,
eFixCore |
eFixAxis))
403 ShowerSRecData::kLDFSilentsAndCurvature : ShowerSRecData::kLDFSilents;
409 INFO(
"Fit N19 with free core, fixed axis, approximate chi2 method");
412 ERROR(
"N19 estimate failed, this should never happen! Skipping event...");
413 return eContinueLoop;
417 INFO(
"Fit N19 with free core, fixed axis");
418 if (FitShowerSize(update, axisData, extGeomData, list, slist,
eFixAxis))
421 ShowerSRecData::kLDFSilentsAndCurvature : ShowerSRecData::kLDFSilents;
424 if (fPropagateAxisUncertainty)
426 INFO(
"Fit N19 with free core, free axis");
427 if (FitShowerSize(update, axisData, extGeomData, list, slist))
429 update.
fRecStage = ShowerSRecData::kLDFGlobalFit;
437 const double correctionFactor =
438 1.0 + fN19Correction[0] + fN19Correction[1]*log10(sizeData.
fPar[
eN19]);
439 sizeData.
fPar[
eN19] *= correctionFactor;
440 for (
size_t i = 0; i < SizeData::size; ++i)
441 sizeData.
fCov(
eN19,i) *= correctionFactor;
444 SetReconstructedValues(event, sizeData, axisData, list, slist, extGeomData);
457 SdHorizontalReconstruction::UpdateBarycenter(
size_t& nCandidates,
460 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
462 det::Detector::GetInstance().GetSiteCoordinateSystem();
463 const Point siteOrigin(0,0,0, siteCS);
465 Vector barySum(0,0,0, siteCS);
467 double weightSum = 0;
479 if (!(fDropStationsBelowThreshold && (sRec.
GetTotalSignal() < fSilentSignalThreshold)))
484 FATAL(
"sum of weights = 0!");
488 fBary = siteOrigin + barySum/weightSum;
489 fBaryTime = eventTime + timeSum/weightSum;
500 const double r2 = (sIt->GetPosition() - fBary).GetMag2();
504 bestPos = sIt->GetPosition();
509 fBary +=
Vector(0, 0, bestPos.
GetZ(prelimCS), prelimCS);
511 fBaryCS = LocalCoordinateSystem::Create(fBary);
516 msg <<
"\n # candidate stations = " << nCandidates <<
"\n"
517 <<
" barycenter = ( " << fBary.GetX(siteCS)/
km
518 <<
", " << fBary.GetY(siteCS)/
km <<
", " << fBary.GetZ(siteCS)/
km
520 <<
" bary time = " << (timeSum/weightSum)/
nanosecond
521 <<
" [ns] (to event time)";
533 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
535 switch (fExternalGeometry)
540 ERROR(
"Event contains no simulation data.");
559 const double r2 = (sIt->GetPosition() - core).GetMag2();
563 bestZ = sIt->GetPosition().GetZ(prelimCS);
567 core += axis * bestZ/axis.
GetZ(prelimCS);
569 fBaryCS = LocalCoordinateSystem::Create(fBary);
582 ERROR(
"Event contains no data from a hybrid reconstruction.");
588 Point core(0, 0, 0, fBaryCS);
589 Vector axis(0, 0, 0, fBaryCS);
594 eEnd =
event.GetFEvent().EyesEnd(ComponentSelector::eHasData);
600 const fdet::Eye& detEye = det::Detector::GetInstance().GetFDetector().GetEye(*eIt);
602 const Point eyePos(0, 0, 0, eyeCS);
608 eyeCS, Vector::kSpherical);
610 const Vector vertical(0, 0, 1, eyeCS);
615 core += (eyePos-fBary) + core_eye_vec;
619 axis += rot * horizontalInSDP;
624 ERROR(
"Event contains no data from a hybrid reconstruction.");
634 const SEvent& sEvent =
event.GetSEvent();
635 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
636 Point bestPos = fEarthCenter;
643 if ((pos - core).GetMag2() < (bestPos - core).GetMag2())
647 core += axis * bestPos.
GetZ(prelimCS)/axis.
GetZ(prelimCS);
648 if (fMaxDistanceStationToExternalCore > 0 &&
649 (bestPos - core).GetMag() > fMaxDistanceStationToExternalCore)
652 msg <<
"Event rejected: station with signal " << (bestPos-core).GetMag()/
km
653 <<
" km away from hybrid core [limit: " << fMaxDistanceStationToExternalCore/
km <<
" km]";
659 fBaryCS = LocalCoordinateSystem::Create(fBary);
663 eEnd =
event.GetFEvent().EyesEnd(ComponentSelector::eHasData);
668 const fdet::Eye& detEye = det::Detector::GetInstance().GetFDetector().GetEye(*eIt);
672 vector<double> iPar(4), oPar(4);
678 iPar[eRp] = r.
GetRp();
687 propagate(oPar, oCov, iPar, iCov);
689 for (
size_t i = 0; i < 4; ++i)
691 extGeomData.
fPar[i] += oPar[i];
692 for (
size_t j = 0; j < 4; ++j)
693 extGeomData.
fInvCov[i][j] += oCov(i,j);
697 for (
size_t i = 0; i < 4; ++i)
699 extGeomData.
fPar[i] /= nEyes;
700 for (
size_t j = 0; j < 4; ++j)
701 extGeomData.
fInvCov[i][j] /= nEyes;
722 SdHorizontalReconstruction::CleanEvent(std::size_t& nCandidates,
729 GetShowerAxis(core, origin, sizeData, axisData);
733 det::Detector::GetInstance().GetSDetector();
736 double bestWeight = 0;
738 double bestSigmaCT = 0;
744 const int sId = sIt->GetId();
745 const double s = sIt->GetRecData().GetTotalSignal();
747 const double weight = s/rho;
748 if (bestWeight < weight)
760 msg <<
"Station " << bestId <<
" serves as time reference to clean event";
770 frontFcn.
Predict(meanCT, bestSigmaCT, sd, origin, 0);
771 originCT = sd.
fCTime-meanCT;
775 ERROR(
"No reference station found");
794 double meanCT, sigmaCT;
795 frontFcn.
Predict(meanCT, sigmaCT, sd, origin, originCT);
796 sigmaCT =
sqrt(
Sqr(sigmaCT) +
Sqr(bestSigmaCT));
798 if (
abs(sd.
fCTime - meanCT) > fMaxTimeSigma*sigmaCT)
801 msg <<
"Station " << sIt->GetId() <<
" rejected:"
802 " time residual to external geometry = "
803 << fixed << setprecision(2)
804 << (sd.
fCTime - meanCT)/sigmaCT <<
" sigma [limit: " << fMaxTimeSigma <<
"]";
807 if (!(fDropStationsBelowThreshold && (sd.
fSignal < fSilentSignalThreshold)))
812 return nCandidates > 0;
817 SdHorizontalReconstruction::FitShowerFront(
const Point& core,
824 using namespace ROOT::Minuit2;
826 MnUserParameters pars;
831 pars.Add(
"phi", ad.
fPar[
ePhi], 0.01);
835 pars.SetLimits(
"theta", 0, 89*
degree);
836 pars.SetLowerLimit(
"distance", 0);
848 pars.Fix(
"distance");
854 MnMinimize
m(fcn, pars, 1);
856 FunctionMinimum fmin =
m(10000);
858 if (fmin.IsAboveMaxEdm() || fmin.HasReachedCallLimit() || !fmin.IsValid())
860 ERROR(
"Fit failed: no convergence");
865 hesse(fcn, fmin, 10000);
869 ERROR(
"Fit failed: error in computation of covariance matrix");
876 ad.
fPar[
eTheta] = fmin.UserParameters().Value(0);
877 ad.
fPar[
ePhi] = fmin.UserParameters().Value(1);
881 const size_t nVar = pars.VariableParameters();
885 for (
size_t i = 0; i < nVar; ++i)
886 for (
size_t j = 0; j < nVar; ++j)
888 if (std::isnan(fmin.UserCovariance()(i, j)))
891 const size_t k = m.ExtOfInt(i);
892 const size_t l = m.ExtOfInt(j);
893 ad.
fCov(k, l) = fmin.UserCovariance()(i, j);
902 msg << fixed << setprecision(2)
903 <<
"Found minimum after " << fmin.NFcn() <<
" evaluations\n"
915 if (fMaxThetaDifference > 0 && (
abs(oldTheta - ad.
fPar[
eTheta]) > fMaxThetaDifference))
918 msg << fixed << setprecision(2)
919 <<
"Fit rejected: theta changed by " <<
abs(oldTheta - ad.
fPar[
eTheta])/
degree <<
" deg, [limit: "
920 << fMaxThetaDifference/
degree <<
" deg]";
925 const double newChi2 = fmin.Fval();
931 msg << fixed << setprecision(2)
932 <<
"Fit rejected: new chi^2 = " << newChi2 <<
", old chi^2 = " << ad.
fChi2;
944 SdHorizontalReconstruction::FitShowerSize(
SizeData& sd,
952 using namespace ROOT::Minuit2;
954 MnUserParameters pars;
956 pars.Add(
"n19", sd.
fPar[
eN19], 1.0);
960 pars.Add(
"phi", ad.
fPar[
ePhi], 0.01);
963 pars.SetLowerLimit(
"n19", 0);
964 pars.SetLimits(
"theta", 0, 89*
degree);
965 pars.SetLowerLimit(
"distance", 0);
982 pars.Fix(
"distance");
986 fcn.
SetType(ShowerSizeFunction::eApprox);
988 MnMinimize
m(fcn, pars, 1);
990 FunctionMinimum fmin =
m(10000);
992 if (fmin.IsAboveMaxEdm() || fmin.HasReachedCallLimit() || !fmin.IsValid())
994 ERROR(
"Fit failed: no convergence");
999 hesse(fcn, fmin, 10000);
1001 if (!fmin.IsValid())
1003 ERROR(
"Fit failed: error in computation of covariance matrix");
1010 sd.
fPar[
eN19] = fmin.UserParameters().Value(0);
1014 const size_t nVar = pars.VariableParameters();
1018 for (
size_t i=0;i<nVar;++i)
1019 for (
size_t j=0;j<nVar;++j)
1021 if (std::isnan(fmin.UserCovariance()(i, j)))
1024 const size_t k = m.ExtOfInt(i);
1025 const size_t l = m.ExtOfInt(j);
1028 sd.
fCov(k, l) = fmin.UserCovariance()(i, j);
1038 msg << fixed << setprecision(2)
1039 <<
"Found minimum after " << fmin.NFcn() <<
" evaluations\n"
1041 " +/- " << sd.
fCov.Std(
eN19) <<
"\n"
1049 if (fMaxDistanceCoreToBarycenter > 0)
1052 GetShowerAxis(core, origin, sd, ad);
1053 Point bary(0, 0, 0, fBaryCS);
1056 const double d = (core - bary).GetMag();
1057 if (d > fMaxDistanceCoreToBarycenter) {
1059 err <<
"Fit rejected: Distance between core and barycenter " << d/
kilometer
1060 <<
" km too large [limit: " << fMaxDistanceCoreToBarycenter/
km <<
" km]";
1074 const Point& origin,
1079 det::Detector::GetInstance().GetSDetector();
1090 sd.
fId = sIt->GetId();
1110 if (
GetRho(pos, core, origin) > fMaxSilentRadius)
1113 for (StationList::const_iterator it = list.begin();
1114 it != list.end(); ++it)
1116 if ((pos - it->fPos).GetMag() < fMaxSilentRelDistance)
1120 sd.
fId = sIt->GetId();
1131 SdHorizontalReconstruction::SetReconstructedValues(
Event& event,
1140 const double energy =
1141 fEnergyConstant *
pow(sizeData.
fPar[
eN19],fGamma);
1142 const double energyErr =
1149 << fixed << setprecision(2)
1150 <<
" N19 (corrected) : "
1152 <<
" Energy / EeV : "
1153 << energy/
EeV <<
" +/- " << energyErr/
EeV;
1156 const double energyMC =
event.GetSimShower().GetEnergy();
1157 const double diffToMC = energy/energyMC-1.;
1158 const double diffToMCSigma =
1159 (energy-energyMC)/energyErr;
1160 msg <<
"\n Energy (MC-input) / EeV : "
1162 <<
" ( " << diffToMC*100.
1163 <<
" % | " << diffToMCSigma <<
" std.dev. )";
1172 GetShowerAxis(core, origin, sizeData, axisData);
1173 Vector axis = origin - core;
1176 vector<double> oPar;
1178 const size_t nAxis = 4;
1182 vector<double> iPar(6);
1193 for (
size_t i = 0; i < AxisData::size; ++i)
1194 for (
size_t j = i; j < AxisData::size; ++j)
1195 iCov(2+i, 2+j) = axisData.
fCov(i, j);
1197 vector<Point> posList;
1198 for (StationList::const_iterator
1202 posList.push_back(sIt->fPos);
1204 oPar.resize(nAxis + posList.size());
1208 prop(oPar, oCov, iPar, iCov);
1212 for (
size_t i = 0; i < 4; ++i)
1213 for (
size_t j = i; j < 4; ++j)
1214 if (iCov(2+i,2+j) == 0) oCov(i,j) = 0;
1217 const double n19 = sizeData.
fPar[
eN19];
1220 LocalCoordinateSystem::Create(core);
1222 const double theta = axis.
GetTheta(coreCS);
1223 const double phi = axis.
GetPhi(coreCS);
1229 double energyChi2 = 0;
1230 double axisChi2 = 0;
1235 for (
size_t i = 0; i < list.size(); ++i)
1243 double signalPred = 0, signalSigma = 0;
1246 if (signalSigma == 0)
1249 msg << fixed << setprecision(2)
1250 <<
"Station " << sd.
fId <<
":"
1251 <<
"signal = " << sd.
fSignal <<
" "
1252 <<
"pred = " << signalPred <<
" "
1253 <<
"sigma = " << signalSigma;
1258 const double residual = (sd.
fSignal - signalPred)/signalSigma;
1263 energyChi2 +=
Sqr(residual);
1266 if (axisData.
fNFree > 0) {
1267 double meanCT, sigmaCT;
1269 const double timeResidual = (sd.
fCTime - meanCT)/sigmaCT;
1273 axisChi2 +=
Sqr(timeResidual);
1274 timeSum += timeResidual;
1282 ShowerSRecData& recShower =
event.GetRecShower().GetSRecShower();
1290 tabulatedLDF.
Clear();
1292 const double x0 = log(1);
1293 const double x1 = log(10000);
1295 const size_t nLDFPoints = 20;
1296 for (
size_t i = 0; i < nLDFPoints; ++i)
1298 const double z = float(i)/(nLDFPoints-1);
1299 double mean = 0, smin = 0, smax = 0;
1300 const size_t nPsi = 4;
1301 const double rho0 = exp((1.0-z)*x0 + z*x1);
1302 for (
size_t j = 0; j < nPsi; ++j) {
1303 const double psi = 2*
kPi*double(j)/(nPsi-1);
1304 Point pos(rho0, psi, 0, showerPlaneCS, Point::kCylindrical);
1305 pos -= pos.
GetZ(coreCS)/axis.
GetZ(coreCS)*axis;
1307 double signalPred = 0, signalSigma = 0;
1308 sizeFcn.
Predict(signalPred, signalSigma, pos, origin, n19, core);
1310 mean += signalPred/nPsi;
1311 if (signalPred < smin || smin == 0) smin = signalPred;
1312 if (signalPred > smax || smax == 0) smax = signalPred;
1314 tabulatedLDF.
PushBack(rho0, 0, mean, 0.5*(smax-smin));
1324 recShower.
SetCoreTime(finalCoreTime, finalCoreTimeErr);
1326 const double timeMean = timeSum / nUsed;
1327 const double timeSpread =
sqrt(axisChi2/(nUsed - 1));
1338 const double rcErr = oCov.Std(
eDistance);
1363 recShower.
SetEnergy (energy, energyErr);
1374 SdHorizontalReconstruction::GetShowerAxis(
Point& core,
1380 const double distance)
1383 core =
Point(coreX, coreY, 0, fBaryCS);
1384 origin =
Point(distance, theta, phi, fBaryCS, Point::kSpherical);
1389 SdHorizontalReconstruction::GetShowerAxis(
Point& core,
1401 SdHorizontalReconstruction::LocalCoordinates(
double& xProjected,
1403 double& rho,
double& theta,
1409 using namespace utl;
1411 const Vector posToOrigin = origin - pos;
1412 const double d = pos.
GetZ(fBaryCS)/posToOrigin.GetZ(fBaryCS);
1413 const Vector corePlanePos = pos - core - d*posToOrigin;
1415 xProjected = corePlanePos.
GetX(fBaryCS);
1416 yProjected = corePlanePos.GetY(fBaryCS);
1417 rho =
GetRho(pos, core, origin);
1418 theta =
Angle(posToOrigin, (pos - fEarthCenter));
1423 SdHorizontalReconstruction::ExpectedCurvatureRadius(
const double theta)
1428 return exp(fCurvModelPars[0] + fCurvModelPars[1] *
pow(theta, fCurvModelPars[2]))*
utl::km;
AxialVector cross(const Vector &l, const Vector &r)
vector cross product
const SdHorizontalReconstruction & fParent
Class to access station level reconstructed data.
Facade for any instance of EMComponent.
void SetCurvature(const double curvature, const double error)
gaussian curvature = 1 / Rc
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)
SilentStationIterator SilentStationsEnd()
double GetRpError() const
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
void SetPhiError(const double err)
Interface class to access to the SD Reconstruction of a Shower.
StationIterator AllStationsEnd() const
End of the collection of pointers to all stations in the history of the array.
boost::filter_iterator< ComponentSelector, ConstAllEyeIterator > ConstEyeIterator
Class to handle average muon profiles.
bool HasRecShower() const
const utl::TabulatedFunctionErrors & GetLDF() const
Interface class to access to the SD part of an event.
void SetAzimuthShowerPlane(const double azimuth)
Azimuth in shower plane coordinates.
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
void SetType(const Type type)
double GetChiZero() const
ShowerRecData & GetRecShower()
bool HasSimShower() const
const SdHorizontalReconstruction & fParent
EventTrigger & GetTrigger()
Get the object with central trigger data, throw if n.a.
unsigned int GetTimeFitNDof() const
sevt::StationRecData & GetRecData()
Get station level reconstructed data.
utl::CovarianceMatrix fCov
#define INFO(message)
Macro for logging informational messages.
double GetRho(const utl::Point &pos, const utl::Point &core, const utl::Point &origin)
void SetAngleChi2(const double chi2, const double ndof)
void Predict(double &meanCT, double &sigmaCT, const StationData &sd, const utl::Point &originPos, const double originCT) const
#define FATAL(message)
Macro for logging fatal messages.
boost::filter_iterator< CandidateStationFilter, StationIterator > CandidateStationIterator
Iterator over candidate stations.
void Init()
Initialise the registry.
Detector description interface for Eye-related data.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
CoordinateSystemPtr GetShowerCoordinateSystem(const double theta, const double phi, const Point &core)
boost::filter_iterator< SilentStationFilter, ConstStationIterator > ConstSilentStationIterator
double pow(const double x, const unsigned int i)
double GetSDPPhiError() const
void SortStations(const OrderingCriterion ord) const
Sort the list of stations by the criterion specified in an OrderingCriterion object.
void SetLDFChi2(const double chi2, const double ndof)
void SetExtent(const unsigned int n)
double GetChiZeroError() const
void Predict(double &meanSignal, double &sigmaSignal, const utl::Point &station, const utl::Point &origin, const double n19, const utl::Point &core, const double recoveryErr=0) const
A TimeStamp holds GPS second and nanosecond for some event.
utl::Point GetPosition() const
Tank position.
StationIterator AllStationsBegin() const
Beginning of the collection of pointers to all stations in the history of the array.
void SetCorrelationThetaPhi(const double corr)
void SetTimeResidualMean(const double mean)
Interface class to access Shower Simulated parameters.
CandidateStationIterator CandidateStationsBegin()
Criterion to sort stations by decreasing signal.
void SetCoreError(const utl::Vector &coreerr)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
double GetRecoveredSignalError() const
double GetRecoveredSignal() const
Total recovered signal in VEM unit, averaged over pmts.
void SetResidual(const double residual)
Residual of geometry fit.
void SetLDFResidual(const double LDFresidual)
Residual of lateral fit.
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
utl::TimeStamp GetSignalStartTime() const
Start time of the signal.
void InvertMatrix(const size_t n, AMatrix &a)
Invert A in place with Gauss-Jordan elimination and full pivoting.
SilentStationIterator SilentStationsBegin()
double GetX(const CoordinateSystemPtr &coordinateSystem) const
double fInvCov[size][size]
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.
bool HasTrigger() const
check whether the central trigger object exists
EyeIterator EyesBegin(const ComponentSelector::Status status)
void SetThetaError(const double err)
double GetSDPCorrThetaPhi() const
double GetThetaError() const
const utl::Vector & GetAxis() const
double GetPhiError() const
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.
std::string GetName() const
function to get the Branch name
std::vector< StationData > StationList
const CoordinateSystemPtr & fEyeCS
Eye-specific shower reconstruction data.
Base class for inconsistency/illogicality exceptions.
void SetCoreTime(const utl::TimeStamp &coreTime, const utl::TimeInterval &coreTimeErr)
Station & GetStation(const int stationId)
retrieve station by id throw utl::NonExistentComponentException if n.a.
FinalPropagator(const SdHorizontalReconstruction &parent, const vector< Point > &posList)
const utl::AxialVector & GetSDP() const
double GetTimeFitChiSquare() const
fevt::FEvent & GetFEvent()
double GetRpChi0Correlation() const
double GetY(const CoordinateSystemPtr &coordinateSystem) const
const utl::TimeInterval & GetCoreTimeError() const
constexpr double kSpeedOfLight
A TimeInterval is used to represent time elapsed between two events.
utl::TimeStamp GetTime() const
Get time of the trigger.
ResultFlag
Flag returned by module methods to the RunController.
void SetTimeResidualSpread(const double spread)
double GetCorrelationThetaPhi() const
FdGeometryPropagator(const SdHorizontalReconstruction &parent, const CoordinateSystemPtr &eyeCS)
constexpr double kilometer
std::vector< SilentStationData > SilentStationList
Detector description interface for SDetector-related data.
const utl::Point & GetCorePosition() const
void SetCorePosition(const utl::Point &core)
sevt::Header & GetHeader()
Main configuration utility.
void SetLDFLikelihood(const double likelihood)
CandidateStationIterator CandidateStationsEnd()
void SetShowerSizeType(const ShowerSizeType type)
void SetEnergy(const double energy, const double error)
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.
void SetSPDistance(const double distance, const double error)
Distance from core in shower plane coordinates.
#define ERROR(message)
Macro for logging error messages.
bool HasSRecShower() const
sevt::SEvent & GetSEvent()
const vector< Point > & fPosList
const double kEarthRadius
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
boost::filter_iterator< CandidateStationFilter, ConstStationIterator > ConstCandidateStationIterator
utl::CovarianceMatrix fCov
double GetSDPThetaError() const