12 #include <fwk/CoordinateSystemRegistry.h>
13 #include <fwk/CentralConfig.h>
14 #include <fwk/LocalCoordinateSystem.h>
16 #include <det/Detector.h>
17 #include <sdet/SDetector.h>
18 #include <fdet/FDetector.h>
21 #include <evt/ShowerMRecData.h>
22 #include <mdet/MDetector.h>
23 #include <mdet/Counter.h>
24 #include <mevt/MEvent.h>
25 #include <mevt/Counter.h>
26 #include <mevt/Module.h>
27 #include <mevt/ModuleRecData.h>
29 #include <atm/ProfileResult.h>
31 #include <evt/Event.h>
32 #include <evt/ShowerRecData.h>
33 #include <evt/ShowerSRecData.h>
34 #include <evt/ShowerFRecData.h>
35 #include <evt/ShowerUnivRecData.h>
36 #include <evt/ShowerSimData.h>
38 #include <sevt/SEvent.h>
39 #include <sevt/Header.h>
40 #include <sevt/SortCriteria.h>
42 #include <fevt/FEvent.h>
44 #include <fevt/EyeRecData.h>
46 #include <utl/UTCDateTime.h>
47 #include <utl/TimeInterval.h>
48 #include <utl/UTMPoint.h>
49 #include <utl/GeometryUtilities.h>
50 #include <utl/TabulatedFunction.h>
52 #include <tls/Atmosphere.h>
56 #include <utl/RandomEngine.h>
57 #include <fwk/RandomEngineRegistry.h>
58 #include <CLHEP/Random/Randomize.h>
62 #include <boost/format.hpp>
77 using CLHEP::RandGauss;
78 using CLHEP::RandFlat;
89 InterpolateCDF(
const float vem1,
const float vem2,
const float t1,
const float t2,
const float vemQ)
91 return (t2 - t1) / (vem2 - vem1) * (vemQ - vem1) + t1;
96 GetTimeQuantile(
const float*
const trace,
const float sum,
const int nT,
const float timeUnit,
const float f,
float& tQ,
float& tQ_err)
98 const float sumQ = f * sum;
99 float timeQuantile[] = { 0, 0 };
102 for (
int it = 0; it <= nT; ++it) {
103 const float tmax = timeUnit * float(it);
104 const float binVal = (it == 0 ? 0 : trace[it - 1]);
107 if (accsum >= sumQ && (accsum - binVal) <= sumQ) {
108 if (!timeQuantile[0])
109 timeQuantile[0] =
InterpolateCDF(accsum - binVal, accsum, tmax - timeUnit, tmax, sumQ);
110 timeQuantile[1] =
InterpolateCDF(accsum - binVal, accsum, tmax - timeUnit, tmax, sumQ);
114 tQ = 0.5*(timeQuantile[0] + timeQuantile[1]);
115 tQ_err = 0.5*(timeQuantile[1] - timeQuantile[0]);
123 return fabs(a / b - 1) < 1e-3;
132 const double pars[2] = { 1.090029853988826319e-1, 4.353909248484404970e-1 };
133 return pars[0] + pars[1] /
sqrt(energy / 1e17);
159 topB.
GetChild(
"skipXmaxOutsideProfile").
GetData(fSkipXmaxOutsideProfile);
171 "======= Global configuration =======\n"
172 << format(
"theta cut %.1f ... %.1f deg") % (fMinTheta /
degree) % (fMaxTheta /
degree) <<
'\n'
173 << format(
"log E cut %.1f") % (log10(fMinEnergy)) <<
"\n"
174 "skipping non T5 events " << (fSkipNonT5 ?
"yes" :
"no") <<
"\n"
175 "selected FD eye " << fSelectedEye <<
"\n"
176 "SilentMaxRadius " << fSilentMaxRadius <<
"\n"
177 "use unsaturated trace (only in case of simulations) " << (fUseUnsaturatedTrace ?
"yes" :
"no") <<
"\n"
178 "active method " << fActiveMethod;
186 fFitterKG->fCalibOpt = fCalibOpt;
187 fFitterKG->fRecMixture = fRecMixture;
192 "======= Calibration settings =======\n"
193 "CalibOpt " << fCalibOpt <<
"\n"
194 "RecMixture " << fRecMixture;
201 const Branch& karlsruheBranch = topB.
GetChild(
"KarlsruheReconstruction");
202 karlsruheBranch.
GetChild(
"outputFileName").
GetData(fKarlsruheConfig.outputFileName);
203 karlsruheBranch.
GetChild(
"verbosityLevel").
GetData(fFitterKG->fVerbosityLevel);
204 karlsruheBranch.
GetChild(
"useSmearedMC").
GetData(fKarlsruheConfig.useSmearedMC);
205 karlsruheBranch.
GetChild(
"useRealisticEnergySmearing").
GetData(fKarlsruheConfig.useRealisticEnergySmearing);
207 karlsruheBranch.
GetChild(
"TimeModelVersion").
GetData(fKarlsruheConfig.TimeModelVersion);
208 karlsruheBranch.
GetChild(
"StartTimeBias").
GetData(fFitterKG->fStartTimeBias);
209 karlsruheBranch.
GetChild(
"applyXmaxBiasCorrection").
GetData(fFitterKG->fApplyXmaxBiasCorrection);
210 karlsruheBranch.
GetChild(
"useMCEnergyScale").
GetData(fFitterKG->fUseMCEnergyScale);
211 karlsruheBranch.
GetChild(
"EarlyTraceFit").
GetData(fFitterKG->fEarlyTraceFit);
212 karlsruheBranch.
GetChild(
"QuantileShapeFit").
GetData(fFitterKG->fQuantileShapeFit);
213 karlsruheBranch.
GetChild(
"IterativeFit").
GetData(fFitterKG->fIterativeFit);
216 const Branch& KGoverrides = karlsruheBranch.
GetChild(
"Overrides");
220 KGoverrides.
GetChild(
"doStartTimeFit").
GetData(fFitterKG->doStartTimeFit);
221 KGoverrides.
GetChild(
"doSaturatedStartTimeFit").
GetData(fFitterKG->doSaturatedStartTimeFit);
228 KGoverrides.
GetChild(
"TimeModelOffsetFixed").
GetData(fFitterKG->TimeModelOffsetFixed);
232 if (x0Mode ==
"Fixed")
234 else if (x0Mode ==
"Coupled")
239 KGoverrides.
GetChild(
"X0XmaxModelVersion").
GetData(fFitterKG->fX0XmaxModelVersion);
242 fFitterKG->setRecType(fKarlsruheConfig.RecType);
247 "======= Configuration of Karlsruhe reconstruction =======\n";
248 if (fWriteToTextFile)
249 msg <<
"writing reconstruction summary to " << fKarlsruheConfig.outputFileName <<
'\n';
251 "Xmax bias correction " << (fFitterKG->fApplyXmaxBiasCorrection ?
"on" :
"off") <<
"\n"
252 "rec type " << fKarlsruheConfig.RecType <<
"\n"
253 "time model version " << fKarlsruheConfig.TimeModelVersion <<
"\n"
254 "fit time model offset " << (!fFitterKG->TimeModelOffsetFixed ?
"yes" :
"no") <<
"\n"
255 "useSmearedMC " << (fKarlsruheConfig.useSmearedMC ?
"yes" :
"no");
259 if (fWriteToTextFile)
260 fitInfoKG.open(fKarlsruheConfig.outputFileName.c_str());
262 fFitterKG->initTimeModel(fKarlsruheConfig.TimeModelVersion);
267 const Branch& barilocheBranch = topB.
GetChild(
"BarilocheReconstruction");
269 barilocheBranch.
GetChild(
"outputFileName").
GetData(fBarilocheConfig.outputFileName);
271 barilocheBranch.
GetChild(
"RecDetector").
GetData(fBarilocheConfig.RecDetector);
272 barilocheBranch.
GetChild(
"RecSDEUpgrade").
GetData(fBarilocheConfig.RecSDEUpgrade);
280 "======= Configuration of Bariloche reconstruction =======\n";
281 if (fWriteToTextFile)
282 msg <<
"writing reconstruction summary to " << fBarilocheConfig.outputFileName <<
'\n';
284 "RecType " << fBarilocheConfig.RecType <<
"\n"
285 "RecDetector " << fBarilocheConfig.RecDetector <<
"\n"
286 "RecSDEUpgrade " << fBarilocheConfig.RecSDEUpgrade <<
"\n"
287 "RecSys " << fBarilocheConfig.RecSys <<
"\n"
288 "CalibOpt " << fCalibOpt <<
"\n"
289 "RecMixture " << fRecMixture <<
"\n"
290 "verbose " << fBarilocheConfig.verbose <<
"\n"
291 "debug " << fBarilocheConfig.debug;
295 if (fWriteToTextFile)
296 fitInfoBG.open(fBarilocheConfig.outputFileName.c_str());
312 fActiveMethod ==
"Karlsruhe" &&
313 fKarlsruheConfig.RecType == 1;
317 fActiveMethod ==
"Bariloche" &&
318 (fBarilocheConfig.RecType == 0 || fBarilocheConfig.RecType == 7)
320 (fActiveMethod ==
"Karlsruhe" && fKarlsruheConfig.RecType == 3);
323 if (!(event.
HasSEvent() &&
event.HasRecShower() &&
event.GetRecShower().HasSRecShower())) {
324 INFO(
"event has no reconstructed shower");
325 return eContinueLoop;
328 SEvent& sEvent =
event.GetSEvent();
330 const ShowerSRecData& showerSRec =
event.GetRecShower().GetSRecShower();
334 INFO(
"LDF reconstruction stage too small");
335 return eContinueLoop;
338 if (fSkipNonT5 && !showerSRec.
IsT5()) {
339 INFO(
"reconstruction requires T5");
340 return eContinueLoop;
343 const CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
346 if (theta < fMinTheta || theta > fMaxTheta) {
347 INFO(
"Zenith angle above range of parameterization");
348 return eContinueLoop;
352 const double energy =
event.HasSimShower() ?
event.GetSimShower().GetEnergy() : showerSRec.
GetEnergy();
353 if (energy < fMinEnergy) {
354 INFO(
"energy below cut");
355 return eContinueLoop;
359 const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
360 const string& eventId =
event.GetHeader().GetId();
366 msg << format(
"Event id %s, SD event id %i. Date %02i/%02i.") % eventId % sdEventId
372 fEventHasSaturation =
false;
379 msg <<
"Station " << sIt->GetId() <<
" is inside MC inner radius cut. Skipping event.";
381 return eContinueLoop;
384 if (!(sIt->IsCandidate() || sIt->IsSilent()))
393 if (sIt->IsSilent()) {
416 vector< vector<double> > vemTraces;
420 pmtIter != sIt->PMTsEnd(); ++pmtIter) {
422 if (!(pmtIter->HasCalibData() && pmtIter->HasRecData()))
441 vector<double> trace;
445 trace.push_back((*tIt) * calib);
447 vemTraces.push_back(trace);
450 const unsigned int npmt = vemTraces.size();
454 const unsigned int nBins = vemTraces[0].size();
456 for (
unsigned int curTrace = 0; curTrace < npmt; ++curTrace) {
457 if (vemTraces[curTrace].size() != nBins) {
458 ERROR(
"traces need to have exactly the same length");
463 vector<double> averageTrace(nBins);
465 for (
unsigned int curBin = 0; curBin < nBins; ++curBin) {
467 for (
unsigned int curTrace = 0; curTrace < npmt; ++curTrace)
468 binSum += vemTraces[curTrace][curBin];
469 averageTrace[curBin] = binSum / npmt;
472 sdata.
trace = averageTrace;
475 fStations.push_back(sdata);
478 fHottestStation = &fStations[0];
479 for (std::vector<StationFitData>::iterator sIt = fStations.begin(); sIt != fStations.end(); ++sIt) {
480 if (sIt->totalSignal > fHottestStation->totalSignal)
481 fHottestStation = &(*sIt);
484 fHottestStationHeight =
utl::UTMPoint(fHottestStation->position, ReferenceEllipsoid::GetWGS84()).
GetHeight();
486 const atm::Atmosphere& theAtm = det::Detector::GetInstance().GetAtmosphere();
489 const double temperature = tempProfile.
Y(fHottestStationHeight);
490 const double pressure = pressureProfile.
Y(fHottestStationHeight);
492 if (!pressure || !temperature)
510 const double theta = mcPars.axis.GetTheta(coreCS);
511 const double phi = mcPars.axis.GetPhi(coreCS);
513 if (fSkipXmaxBelowGround) {
516 const double DXground =
518 theta, fHottestStationHeight /
cm,
false,
true) *
gpercm2;
520 if (DXground < fMinDXground) {
522 msg << format(
"Xmax too close or below ground (DX = %.1f), skipping event.") % (DXground /
gpercm2);
524 return eContinueLoop;
528 if (fSkipXmaxOutsideProfile) {
530 ERROR(
"Can not check if Xmax is inside the longitudinal profile.");
534 for (
unsigned int i = 0; i < longProfile.
GetNPoints(); ++i) {
535 if (longProfile[i].X() < mcPars.xmax)
541 if (nlow < fMinBinsAroundMaximum || nup < fMinBinsAroundMaximum) {
542 INFO(
"Xmax is not contained in the longitudinal profile, skipping event.");
543 return eContinueLoop;
548 CoordinateSystem::RotationY(
550 CoordinateSystem::RotationZ(
560 double muonSignalSum = 0;
561 int nDenseStations = 0;
573 const double muonSignal = accumulate(trace.
Begin(), trace.
End(), 0.);
580 if (muonSignalSum > 0) {
581 const double Nmu = 1.0;
584 const double sMuRef =
586 fDensity / (
gram /
cm3), fHottestStationHeight /
cm, Nmu, 0, eventTimeUTC.
GetMonth());
587 mcPars.Nmu = (muonSignalSum / nDenseStations) / sMuRef;
588 simShower.
SetNmu(mcPars.Nmu);
590 msg <<
"True Nmu " << mcPars.Nmu;
593 INFO(
"Could not set true Nmu.");
596 if (fKarlsruheConfig.useRealisticEnergySmearing) {
598 mcParsFluct.energy = SmearValue(mcPars.energy, sigmaE * mcPars.energy);
600 mcParsFluct.energy = SmearValue(mcPars.energy, 0.1 * mcPars.energy);
602 mcParsFluct.xmax = SmearValue(mcPars.xmax, 20 *
gpercm2);
603 mcParsFluct.Nmu = SmearValue(mcPars.Nmu, 0.1);
604 mcParsFluct.x0 = SmearValue(mcPars.x0, 20 *
gpercm2);
607 const double theta = mcPars.axis.GetTheta(coreCS);
608 const double phi = mcPars.axis.GetPhi(coreCS);
611 theCR.SetMagThetaPhi(1., theta, phi);
612 TVector3 rndD = theCR.Orthogonal();
614 rndD.Rotate(RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 2 *
kPi), theCR);
618 mcParsFluct.axis =
Vector(1, theCR.Theta(), theCR.Phi(), coreCS, Vector::kSpherical);
622 mcParsFluct.core = mcPars.core +
Vector(RandGauss::shoot(&fRandomEngine->GetEngine(), 0, 50*
meter),
623 RandFlat::shoot(&fRandomEngine->GetEngine(), 0,
kPi),
624 0, coreCS, Vector::kCylindrical);
626 mcParsFluct.coretime = mcPars.coretime +
TimeInterval(RandGauss::shoot(&fRandomEngine->GetEngine(), 0, 100*
ns));
629 ERROR(
"The event has no simulated shower");
631 fdParameters.clear();
636 double bestErrorEllipse = 0;
639 eyeIt != fEvent.
EyesEnd(ComponentSelector::eHasData); ++eyeIt) {
641 if (!eyeIt->HasRecData())
644 const int eyeId = eyeIt->GetId();
645 if (fSelectedEye > 0 && eyeId != fSelectedEye)
660 const fdet::Eye& dEye = det::Detector::GetInstance().GetFDetector().GetEye(*eyeIt);
662 fdParameters[eyeId].eyeName = dEye.
GetName();
664 fdParameters[eyeId].xmaxUnc = showerFRec.
GetXmaxError();
676 const double distEyeCore = vecEyeCore.
GetMag();
681 const double sinChi0 = sin(chi0);
682 const double errorInSDP =
sqrt(
Sqr(rpErr / sinChi0) +
683 Sqr((chi0Err * distEyeCore) / (cos(chi0) * sinChi0)) +
684 rhoChi0Rp * rpErr * chi0Err);
686 const double errorPerpSDP = distEyeCore * sin(sdpPhiErr);
687 const double coreErrorEllipse = errorInSDP * errorPerpSDP *
kPi;
691 if (bestErrorEllipse && bestErrorEllipse < coreErrorEllipse)
694 bestErrorEllipse = coreErrorEllipse;
696 fdParameters[0].eyeName = dEye.
GetName();
697 fdParameters[0].axis = showerFRec.
GetAxis();
699 fdParameters[0].coretime = showerFRec.
GetCoreTime();
702 if (fdParameters.empty() && needFD) {
703 INFO(
"Event has no suitable FD data");
704 return eContinueLoop;
707 msg <<
"shower geometry (axis, core position + time) taken from " << fdParameters[0].eyeName;
711 double wghtAvEnergy = 0;
712 double wghtAvXmax = 0;
714 if (!fdParameters.empty()) {
716 double weightSum = 0;
717 for (map<int, FDParameters>::iterator
fd = fdParameters.begin();
fd != fdParameters.end(); ++
fd) {
718 if (!
fd->second.energy)
720 const double unc =
fd->second.energyUnc;
721 const double weight = 1 / (unc * unc);
723 wghtAvEnergy +=
fd->second.energy * weight;
725 wghtAvEnergy /= weightSum;
729 double weightSum = 0;
730 for (map<int, FDParameters>::iterator
fd = fdParameters.begin();
fd != fdParameters.end(); ++
fd) {
731 if (!
fd->second.xmax)
733 const double unc =
fd->second.xmaxUnc;
734 const double weight = 1 / (unc * unc);
736 wghtAvXmax +=
fd->second.xmax * weight;
738 wghtAvXmax /= weightSum;
742 msg <<
"weighted averages\n"
743 "log10 E = " << format(
"%.2f") % log10(wghtAvEnergy) <<
" "
744 "Xmax = " << format(
"%.2f") % (wghtAvXmax /
gpercm2) <<
" "
745 "nEyes = " << format(
"%d") % (fdParameters.size() - 1);
749 fdParameters[0].xmax = wghtAvXmax;
750 fdParameters[0].energy = wghtAvEnergy;
754 if (fActiveMethod ==
"Karlsruhe")
755 RunKarlsruheReconstruction(event);
756 else if (fActiveMethod ==
"Bariloche")
757 RunBarilocheReconstruction(event);
759 WriteRecParameters(event);
767 UniversalityFitter::SmearValue(
const double mean,
const double spread)
769 return RandGauss::shoot(&fRandomEngine->GetEngine(), mean, spread);
774 UniversalityFitter::SwitchMethod()
777 if (fActiveMethod ==
"Karlsruhe")
778 newMethod =
"Bariloche";
780 newMethod =
"Karlsruhe";
783 msg <<
"Switching to " << newMethod <<
" reconstruction";
785 fActiveMethod = newMethod;
790 UniversalityFitter::RunKarlsruheReconstruction(
evt::Event& event)
793 fFitterKG->isMCEvent =
event.HasSimShower();
796 MCParameters& pars = fKarlsruheConfig.useSmearedMC ? mcParsFluct : mcPars;
798 fFitterKG->mcPars.valid =
true;
800 fFitterKG->mcPars.Nmu = pars.
Nmu;
801 fFitterKG->mcPars.xmax = pars.
xmax;
802 fFitterKG->mcPars.xmaxMu = pars.
xmaxMu;
803 fFitterKG->mcPars.x0 = pars.
x0;
804 fFitterKG->mcPars.axis = pars.
axis;
805 fFitterKG->mcPars.core = pars.
core;
806 fFitterKG->mcPars.coretime = pars.
coretime;
809 const SEvent& sEvent =
event.GetSEvent();
811 fFitterKG->atmModel = eventTimeUTC.
GetMonth();
812 fFitterKG->fDensity = fDensity;
814 ShowerSRecData& showerSRec =
event.GetRecShower().GetSRecShower();
815 fFitterKG->sdPars.valid =
true;
817 fFitterKG->sdPars.energy = showerSRec.
GetEnergy();
818 fFitterKG->sdPars.axis = showerSRec.
GetAxis();
820 fFitterKG->sdPars.coretime = showerSRec.
GetCoreTime();
825 fFitterKG->sdPars.axisUncPhi = showerSRec.
GetPhiError();
827 if (!fdParameters.empty()) {
829 fFitterKG->fdPars.valid =
true;
830 fFitterKG->fdPars.energy = fdParameters[0].energy;
831 fFitterKG->fdPars.xmax = fdParameters[0].xmax;
832 fFitterKG->fdPars.axis = fdParameters[0].axis;
833 fFitterKG->fdPars.core = fdParameters[0].core;
834 fFitterKG->fdPars.coretime = fdParameters[0].coretime;
837 for (std::vector<StationFitData>::iterator sIt = fStations.begin(); sIt != fStations.end(); ++sIt) {
839 if (sIt->isSilent || sIt->stationType !=
eWCD)
848 sdata.
trace = sIt->trace;
853 sdata.
t10 = sIt->t10;
854 sdata.
t50 = sIt->t50;
855 sdata.
t90 = sIt->t90;
857 fFitterKG->addStationFitData(sdata);
860 const bool fitSuccessful = fFitterKG->run();
862 fittedPars.energy = fFitterKG->fittedPars.energy;
863 fittedPars.energyUnc = fFitterKG->fittedPars.energyUnc;
865 fittedPars.xmax = fFitterKG->fittedPars.xmax;
866 fittedPars.xmaxUnc = fFitterKG->fittedPars.xmaxUnc;
868 fittedPars.Nmu = fFitterKG->fittedPars.Nmu;
869 fittedPars.NmuUnc = fFitterKG->fittedPars.NmuUnc;
871 fittedPars.TimeModelOffset = fFitterKG->fittedPars.TimeModelOffset;
872 fittedPars.TimeModelOffsetUnc = fFitterKG->fittedPars.TimeModelOffsetUnc;
874 fittedPars.axis = fFitterKG->fittedPars.axis;
875 fittedPars.axisUncTheta = fFitterKG->fittedPars.axisUncTheta;
876 fittedPars.axisUncPhi = fFitterKG->fittedPars.axisUncPhi;
878 fittedPars.core = fFitterKG->fittedPars.core;
879 fittedPars.coreUncX = fFitterKG->fittedPars.coreUncX;
880 fittedPars.coreUncY = fFitterKG->fittedPars.coreUncY;
882 fittedPars.coretime = fFitterKG->fittedPars.coretime;
884 fittedPars.fNCandShape = fFitterKG->fNStationsShape;
885 fittedPars.fNCandStartTime = fFitterKG->fNStationsStartTime;
886 fittedPars.fNCandLDF = fFitterKG->fNStationsLDF;
888 fittedPars.isGoodRec = fitSuccessful;
890 if (!fitSuccessful) {
893 "#############################\n"
894 "### FIT DID NOT CONVERGE! ###\n"
895 "#############################";
902 UniversalityFitter::UnivRecNS_FCN(Int_t& , Double_t* , Double_t& f, Double_t* par, Int_t )
904 std::vector<double> par_v;
906 par_v.push_back(par[ipar]);
908 if (std::isnan(f) || std::isinf(f))
921 std::vector<double> par;
922 std::vector<double> epar;
923 std::vector<double>
low;
924 std::vector<double>
high;
925 std::vector<bool> hasLimits;
934 minuit->mnexcm(
"SET PRINTOUT", arglist, 1, ierflg);
935 minuit->mnexcm(
"SET NOWARNINGS", arglist, 0, ierflg);
936 minuit->SetFCN(UnivRecNS_FCN);
938 minuit->mnexcm(
"SET ERR", arglist, 1, ierflg);
943 if (hasLimits[ipar]) {
947 minuit->mnparm(ipar,
UnivRecNS::ParName[ipar].c_str(), par[ipar], epar[ipar], low, high, ierflg);
952 minuit->FixParameter(ipar);
958 if (!fBarilocheConfig.verbose) {
962 minuit->mnexcm(
"SIMPLEX", arglist , 2, ierflg);
963 if (!fBarilocheConfig.verbose) {
969 minuit->GetParameter(ipar, par[ipar], epar[ipar]);
978 UniversalityFitter::InitBarilocheReconstruction(
evt::Event& event)
980 const int gRecSys = fBarilocheConfig.RecSys;
981 const int gRecType = fBarilocheConfig.RecType;
983 const bool gRecMC = !fBarilocheConfig.IsData;
986 const SEvent& sEvent =
event.GetSEvent();
988 const ShowerSRecData& showerSRecData =
event.GetRecShower().GetSRecShower();
993 const CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
1011 recinfo.
id = sdEventId;
1012 const bool okT4 = showerSRecData.
IsT4();
1013 const bool ok6T5 = showerSRecData.
IsT5();
1020 MCinfo.
theta = mcPars.axis.GetTheta(hottestStationCS);
1021 MCinfo.
azi = mcPars.axis.GetPhi(hottestStationCS);
1023 MCinfo.
xgcore = mcPars.core.GetX(hottestStationCS) /
cm;
1024 MCinfo.
ygcore = mcPars.core.GetY(hottestStationCS) /
cm;
1025 MCinfo.
zgcore = (mcPars.core.GetZ(hottestStationCS) + fHottestStationHeight) /
cm;
1029 MCinfo.
logE = log10(mcPars.energy);
1043 const int imonth = eventTimeUTC.
GetMonth();
1045 recinfo.
iatm = imonth;
1052 MCinfo.
Nmu = mcPars.Nmu;
1058 for (
int itype = 0; itype < 3; ++itype)
1074 augerinfo.
isGoodSD = (okT4 && ok6T5);
1085 augerinfo.
logE_FD = log10(mcParsFluct.energy);
1086 augerinfo.
theta_FD = mcParsFluct.axis.GetTheta(hottestStationCS);
1087 augerinfo.
azi_FD = mcParsFluct.axis.GetPhi(hottestStationCS);
1093 if (!fdParameters.empty()) {
1094 const int EyeSel = (gRecSys == 6 || gRecSys == 7 || gRecSys == 8 || gRecSys == 9 ? gRecSys - 5 : 0);
1097 for (
int i = 0; i < 5; ++i)
1098 cout <<
" Eyes " << i <<
" " << fdParameters[i].energy <<
" " << fdParameters[EyeSel].axis.GetTheta(coreCS) << endl;
1099 augerinfo.
logE_FD = log10(fdParameters[EyeSel].energy);
1105 augerinfo.
theta_FD = fdParameters[EyeSel].axis.GetTheta(coreCS);
1106 augerinfo.
azi_FD = fdParameters[EyeSel].axis.GetPhi(coreCS);
1114 printf(
" Event is not T4/6T5 %d \n", recinfo.
id);
1118 if (!augerinfo.
isGoodFD && gRecType == 0) {
1119 printf(
" Nmu_FD reconstruction but no FD (Xmax,Energy) %d \n", recinfo.
id);
1128 for (std::vector<StationFitData>::iterator sIt = fStations.begin(); sIt != fStations.end(); ++sIt) {
1129 const int itype =
eWCD;
1134 if (sIt->stationId == 94 && recinfo.
id == 21354417)
1141 station.
type = itype;
1142 station.
id = sIt->stationId;
1144 station.
xg = sIt->position.GetX(hottestStationCS) /
cm;
1145 station.
yg = sIt->position.GetY(hottestStationCS) /
cm;
1146 station.
zg = (sIt->position.GetZ(hottestStationCS) + fHottestStationHeight) /
cm;
1148 station.
GPSnano = (sIt->startTime - fHottestStation->startTime).GetInterval();
1149 station.
GPSnano -= sIt->startBin * 25.;
1151 if (sIt->isSilent) {
1152 theRec.
fstation.push_back(station);
1156 if (sIt->trace.empty())
1167 const float timeUnit = 25.;
1168 const vector<float> vemtrace(sIt->trace.begin(), sIt->trace.end());
1171 station.
isSaturated = (sIt->isSaturated && !sIt->useUnsaturatedTrace);
1172 const int start = sIt->startBin;
1173 const int end = sIt->stopBin;
1175 station.
signalsize = accumulate(&vemtrace.front() + sIt->startBin, &vemtrace.front() + sIt->stopBin, 0.f);
1183 station.
starttime = (start + 0.5) * timeUnit;
1198 station.
tquantile[0][iq] = tq + start * timeUnit;
1220 theRec.
fstation.push_back(station);
1230 const mdet::MDetector& mDetector = det::Detector::GetInstance().GetMDetector();
1234 if (!ic->HasRecData() || !sEvent.
HasStation(ic->GetId()) || ic->IsRejected() || !ic->IsCandidate())
1239 const int itype =
eAMIGA;
1247 station.
type = itype;
1248 station.
id = ic->GetId();
1251 station.
xg = position.
GetX(hottestStationCS) /
cm;
1252 station.
yg = position.
GetY(hottestStationCS) /
cm;
1253 station.
zg = (position.
GetZ(hottestStationCS) + fHottestStationHeight) /
cm;
1260 if (ic->IsSaturated())
1267 station.
signalsize = ic->GetNumberOfEstimatedMuons();
1274 theRec.
fstation.push_back(station);
1276 printf(
"id=%d %lf %lf %lf Area=%lf Nmu=%lf \n",station.
id,station.
xg/1.e2,station.
yg/1.e2,station.
zg/1.e2,station.
DetectorArea/1.e4,station.
signalsize);
1297 printf(
"Number of stations loaded: %d (%d/%d/%d) (id=%d) | log(E_SD)=%5.2lf\n",
1301 const bool okStations = (recinfo.
nStationsWCD >= nMin);
1303 printf(
"Not processing: Number of stations loaded %d | WCD above threshold %d \n", theRec.
nRecStations, recinfo.
nStationsWCD);
1310 for (
int idet_i = 0; idet_i < theRec.
nRecStations; ++idet_i) {
1316 int idet_wcd =
UNDEF;
1317 for (
int idet_j = 0; idet_j < theRec.
nRecStations; ++idet_j)
1321 if (idet_wcd ==
UNDEF)
1330 double vemMax = -1e10;
1333 vemMax = theRec.
fstation[idet].signalsize;
1343 UniversalityFitter::RunBarilocheReconstruction(
evt::Event& event)
1345 const int verbose = fBarilocheConfig.verbose;
1346 const int debug = fBarilocheConfig.debug;
1347 fBarilocheConfig.IsData = (!
event.HasSimShower());
1350 if (!theRec.
InitRec(fBarilocheConfig.IsData, fBarilocheConfig.RecType,
1351 fCalibOpt, fBarilocheConfig.RecDetector,
1352 fBarilocheConfig.RecSys, fRecMixture))
1355 if (!InitBarilocheReconstruction(event))
1359 cerr <<
"InitEvent ok" << endl;
1361 cerr <<
"Number of stations loaded: "
1370 cerr <<
"InitRecParameters ok" << endl;
1380 cerr <<
"StationSelection ok" << endl;
1393 double lnP_max = -1e10;
1394 double Xmax_init[4] = { 650, 750, 850, 950 };
1395 double Xmax0 =
UNDEF;
1396 for (
int iscan = 0; iscan < 4; ++iscan) {
1400 cerr <<
"SetFitStage 1 Search Xmax Rec ok" << endl;
1403 Xmax0 = Xmax_init[iscan];
1438 fittedPars.axisUncTheta = 0.;
1439 fittedPars.axisUncPhi = 0.;
1447 fittedPars.isGoodRec = theRec.
IsGoodRec();
1454 if (!fittedPars.isGoodRec) {
1456 msg <<
"No reconstruction, not writing data to event.";
1471 recShower.
SetEnergy(fittedPars.energy, fittedPars.energyUnc);
1472 recShower.
SetNmu(fittedPars.Nmu, fittedPars.NmuUnc);
1473 recShower.
SetXmax(fittedPars.xmax, fittedPars.xmaxUnc);
1475 recShower.
SetTimeModelOffset(fittedPars.TimeModelOffset, fittedPars.TimeModelOffsetUnc);
1481 recShower.
SetAxis(fittedPars.axis);
1491 msg <<
"\nReconstructed shower parameters\n"
1513 const SEvent& sEvent =
event.GetSEvent();
1516 const CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
1519 const double theta = fittedPars.axis.GetTheta(coreCS);
1520 const double phi = fittedPars.axis.GetPhi(coreCS);
1522 CoordinateSystem::RotationY(
1524 CoordinateSystem::RotationZ(
1531 ofstream* textOut = 0;
1532 if (fActiveMethod ==
"Karlsruhe")
1533 textOut = &fitInfoKG;
1534 else if (fActiveMethod ==
"Bariloche")
1535 textOut = &fitInfoBG;
1537 cerr <<
"unknown method" << endl;
1542 << format(
"%i ") % (fittedPars.isGoodRec)
1543 << format(
"%i ") % (sdEventId)
1544 << format(
"%i ") % (fEventHasSaturation)
1546 << format(
"%.5f ") % (fittedPars.energy /
EeV)
1547 << format(
"%.5f ") % (fittedPars.xmax /
gpercm2)
1548 << format(
"%.5f ") % (fittedPars.Nmu)
1550 << format(
"%.5f ") % (fittedPars.core.GetX(showerPlaneCS) /
m)
1551 << format(
"%.5f ") % (fittedPars.core.GetY(showerPlaneCS) /
m)
1553 << format(
"%.5f ") % (fittedPars.coretime.GetGPSSecond())
1554 << format(
"%.5f ") % (fittedPars.coretime.GetGPSNanoSecond())
1556 << format(
"%.5f ") % (fittedPars.axis.GetTheta(siteCS) /
degree)
1563 UniversalityFitter::Finish()
1565 if (fWriteToTextFile) {
bool SetFitStage(int FitStage)
double GetVEMCharge() const
UnivParamTimeNS::UnivParamTime * ftime[nDetectorType]
Class to access station level reconstructed data.
void SetNmu(const double Nmu, const double error)
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger coordinate system associated to the shower core position.
unsigned int GetNPoints() const
Top of the interface to Atmosphere information.
bool HasUnivRecShower() const
StationIterator StationsEnd()
End of all stations.
utl::TraceD & GetVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal)
Traces calibrated in VEM Peak.
const utl::TabulatedFunction & GetdEdX() const
Get the energy deposit of the shower.
bool IsSaturated[nDetectorType]
double GetRiseTime() const
Rise time averaged over PMTs.
double NormalizeAngleMinusPiPi(const double x)
Normalize angle to lie between -pi and pi (-180 and 180 deg)
CounterConstIterator CountersBegin() const
constexpr T Sqr(const T &x)
void SetAxis(const utl::Vector &axis)
const utl::TimeStamp & GetTimeStamp() const
Get the TimeStamp of the absolute shower core-time.
double GetRpError() const
bool HasStation(const int stationId) const
Check whether station exists.
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
double GetThetaError() const
constexpr double kDryAirMolarMass
void InitRecStation(RecStation *station)
Interface class to access to the SD Reconstruction of a Shower (universality)
Interface class to access to the SD Reconstruction of a Shower.
void GetTimeQuantile(const float *const trace, const float sum, const int nT, const float timeUnit, const float f, float &tQ, float &tQ_err)
void SetXmax(const double Xmax, const double error)
boost::filter_iterator< ComponentSelector, ConstAllEyeIterator > ConstEyeIterator
float Get_DX_DL(float r, float psi, float SlantDepth, float theta, float hground, bool UseDL, bool IsDiffusive)
const evt::VGaisserHillasParameter & GetGHParameters() const
Get the Gaisser-Hillas parameters of the shower.
double GetTotalEnergy() const
retrieve total energy and its uncertainty
Interface class to access to the SD part of an event.
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
double GetChiZero() const
Class to hold and convert a point in geodetic coordinates.
Class to hold collection (x,y) points and provide interpolation between them.
const atm::ProfileResult & EvaluatePressureVsHeight() const
Tabulated function giving Y=air pressure as a function of X=height.
ShowerRecData & GetRecShower()
unsigned int GetSDPFitNDof() const
bool HasSimShower() const
std::vector< double > trace
EyeIterator EyesEnd(const ComponentSelector::Status status)
unsigned int GetTimeFitNDof() const
const double vemTimeCut[nQ]
#define INFO(message)
Macro for logging informational messages.
int InitFCNParameters(std::vector< double > &par, std::vector< double > &epar, std::vector< int > &status, std::vector< bool > &hasLimits)
void PrintRecInfo(bool PrintResiduals)
void SetNumberOfShapeCandidates(const int ncand)
const utl::Point & GetCorePosition() const
utl::Point GetPosition() const
double GetShowerSize() const
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.
void SetCoreTime(const utl::TimeStamp &coreTime, const utl::TimeInterval &coreTimeErr)
double pow(const double x, const unsigned int i)
Detector associated to muon detector hierarchy.
double GetSDPPhiError() const
double GetFallTime() const
Fall time averaged over PMTs.
void SortStations(const OrderingCriterion ord) const
Sort the list of stations by the criterion specified in an OrderingCriterion object.
double GetNmuError() const
double GetEnergyError() const
double GetSignal(double r, double XmaxEdep, double logE, double theta, double psi, double rhoGround, double hGround, double Nmu, int icomp0, int iatm)
double GetChiZeroError() const
std::vector< double >::const_iterator ConstIterator
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
A TimeStamp holds GPS second and nanosecond for some event.
utl::Point GetPosition() const
Tank position.
Interface class to access Shower Simulated parameters.
AtmosphereNS::Atmosphere * fatm
Criterion to sort stations by decreasing signal.
void SetNumberOfStartTimeCandidates(const int ncand)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
double GetXFirst() const
Get depth of first interaction.
double SdEnergyResolution(const double energy)
Class representing a document branch.
unsigned int GetnRecStations()
total FADC trace, with no saturation applied by FADC/baseline simulator
void SetGoodRec(const bool isgood)
class to hold reconstructed data at PMT level
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.
double GetHeight() const
Get the height.
const double SmearingAngle
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Class describing the Atmospheric profile.
const int nTimeStationsMin
double GetXmaxError(const EUncertaintyType type=eTotal) const
retrieve Xmax uncertainties
const utl::TimeStamp & GetCoreTime() const
time when shower front passes through the core point
float InterpolateCDF(const float vem1, const float vem2, const float t1, const float t2, const float vemQ)
double GetTotalSignal() const
Total integrated signal in VEM unit, averaged over pmts.
const utl::Point & GetPosition() const
Get the position of the shower core.
void SaveFCNParameters(std::vector< double > par, std::vector< int > status)
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)
bool IsCloseRel(const double a, const double b)
unsigned int GetSignalStartSlot() const
Start time of the signal in time slots from beginning of trace.
double GetLDFRecStage() const
double GetThetaError() const
double GetEnergy() const
Get the energy of the shower primary particle.
std::vector< RecStation_t > fstation
const utl::Vector & GetAxis() const
double GetPhiError() const
double GetTotalEnergyError(const EUncertaintyType type=eTotal) const
void GetData(bool &b) const
Overloads of the GetData member template function.
unsigned int GetSignalEndSlot() const
End time of the signal in time slots from beginning of trace.
Top of Fluorescence Detector event hierarchy.
Eye-specific shower reconstruction data.
double GetEnergyError() const
void SetThetaError(const double err)
double GetRho(const CoordinateSystemPtr &coordinateSystem) const
radius r in cylindrical coordinates (distance to z axis)
double GetRpChi0Correlation() const
bool HasGHParameters() const
void SetNmu(const double Nmu)
static const double fXmaxSys_Auger[nSys]
double GetY(const CoordinateSystemPtr &coordinateSystem) const
A TimeInterval is used to represent time elapsed between two events.
ResultFlag
Flag returned by module methods to the RunController.
double GetPhiError() const
unsigned long GetGPSSecond() const
GPS second.
InternalCounterCollection::ComponentIterator CounterIterator
constexpr double kMolarGasConstant
bool gDetectorTypeMask[nDetectorType]
static std::unique_ptr< UnivRecNS::UnivRec > gUnivRecNS
std::vector< double > trace
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
StationIterator StationsBegin()
Beginning of all stations.
void GetXmaxRange(double &Xmax0, double &Xmax1)
const int nSignalStationsMin
void SetOffsetM_Mu(double Offset)
const std::string ParName[npar]
total (shower and background)
bool IsDense() const
Tells whether the station belongs to set of hypothetical "dense" stations.
boost::filter_iterator< PMTFilter, InternalConstPMTIterator > ConstPMTIterator
Iterator over station for read.
Interface class to access to Fluorescence reconstruction of a Shower.
Detector description interface for SDetector-related data.
double GetShowerSizeError() const
const double vemSignalCut
bool InitRec(bool IsData, int RecType, int CalibOpt, int RecDetector, int RecSys, int RecMixture)
const utl::Vector & GetCoreError() const
CounterConstIterator CountersEnd() const
const utl::Point & GetCorePosition() const
sevt::Header & GetHeader()
Main configuration utility.
static std::vector< int > parStatus
void SetTimeModelOffset(const double mmu, const double mmuunc)
bool RejectTimeOutliers()
void SetCoreError(const utl::Vector &coreerr)
void SetEnergy(const double energy, const double error)
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
void SetPhiError(const double err)
const Station & GetStation(const int stationId) const
Get station by Station Id.
const Counter & GetCounter(int id) const
Retrieve Counter by id.
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
void SetCurrentAtmosphere(AtmModel theAtm)
bool HasVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal) const
boost::indirect_iterator< InternalConstStationIterator, const Station & > ConstStationIterator
#define ERROR(message)
Macro for logging error messages.
void SetCorePosition(const utl::Point &core)
const utl::Vector & GetAxis() const
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
double GetVEMPeak() const
Root of the Muon event hierarchy.
mu+ and mu- (including signal from mu decay electrons) from shower
double GetXmaxError() const
utl::Point GetPosition() const
Eye position.
bool HasLongitudinalProfile(const ProfileType type=eCharged) const
Check initialization of the longitudinal profile.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
static const double fEnergySys_Auger[nSys]
const atm::ProfileResult & EvaluateTemperatureVsHeight() const
Tabulated function giving Y=temperature as a function of X=height.
const utl::TimeStamp & GetCoreTime() const
time when shower front passes through the core point
void SetNumberOfLDFCandidates(const int ncand)
const double averageAugerDensity
const std::string & GetName() const
Eye name.
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.