UniversalityFitter.cc
Go to the documentation of this file.
1 
10 #include "UniversalityFitter.h"
11 
12 #include <fwk/CoordinateSystemRegistry.h>
13 #include <fwk/CentralConfig.h>
14 #include <fwk/LocalCoordinateSystem.h>
15 
16 #include <det/Detector.h>
17 #include <sdet/SDetector.h>
18 #include <fdet/FDetector.h>
19 #include <fdet/Eye.h>
20 
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>
28 
29 #include <atm/ProfileResult.h>
30 
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>
37 
38 #include <sevt/SEvent.h>
39 #include <sevt/Header.h>
40 #include <sevt/SortCriteria.h>
41 
42 #include <fevt/FEvent.h>
43 #include <fevt/Eye.h>
44 #include <fevt/EyeRecData.h>
45 
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>
51 
52 #include <tls/Atmosphere.h>
53 
54 #include "FitterUtil.h"
55 
56 #include <utl/RandomEngine.h>
57 #include <fwk/RandomEngineRegistry.h>
58 #include <CLHEP/Random/Randomize.h>
59 #include <TMinuit.h>
60 #include <TVector3.h>
61 
62 #include <boost/format.hpp>
63 
64 #include <iostream>
65 #include <algorithm>
66 
67 using namespace fwk;
68 using namespace evt;
69 using namespace sevt;
70 using namespace fevt;
71 using namespace utl;
72 
73 using namespace std;
74 
75 using boost::format;
76 
77 using CLHEP::RandGauss;
78 using CLHEP::RandFlat;
79 
80 
81 namespace UniversalityFitter {
82 
83  const double gpercm2 = utl::gram / utl::cm2;
84  const double averageAugerDensity = 1.06e-3 * utl::gram / utl::cm3;
85 
86 
87  inline
88  float
89  InterpolateCDF(const float vem1, const float vem2, const float t1, const float t2, const float vemQ)
90  {
91  return (t2 - t1) / (vem2 - vem1) * (vemQ - vem1) + t1;
92  }
93 
94 
95  void
96  GetTimeQuantile(const float* const trace, const float sum, const int nT, const float timeUnit, const float f, float& tQ, float& tQ_err)
97  {
98  const float sumQ = f * sum;
99  float timeQuantile[] = { 0, 0 }; // First/Last bin crossing the signal fraction f
100 
101  float accsum = 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]);
105  accsum += binVal;
106 
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);
111  }
112  }
113 
114  tQ = 0.5*(timeQuantile[0] + timeQuantile[1]);
115  tQ_err = 0.5*(timeQuantile[1] - timeQuantile[0]);
116  }
117 
118 
119  inline
120  bool
121  IsCloseRel(const double a, const double b)
122  {
123  return fabs(a / b - 1) < 1e-3;
124  }
125 
126 
127  // 1500 m SD energy resolution model
128  // Parametrization of shower-to-shower fluctuations + sampling fluctuations
129  double
130  SdEnergyResolution(const double energy)
131  {
132  const double pars[2] = { 1.090029853988826319e-1, 4.353909248484404970e-1 };
133  return pars[0] + pars[1] / sqrt(energy / 1e17);
134  }
135 
136 
139  {
140  fFitterKG.reset(new UnivFitterKG::Fitter());
141  gUnivRecNS.reset(new UnivRecNS::UnivRec());
142 
144  const Branch topB = cc->GetTopBranch("UniversalityFitter");
145 
146  fRandomEngine = &RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::eDetector);
147 
148  //
149  // Read global configuration
150  //
151  topB.GetChild("minTheta").GetData(fMinTheta);
152  topB.GetChild("maxTheta").GetData(fMaxTheta);
153 
154  topB.GetChild("minEnergy").GetData(fMinEnergy);
155  topB.GetChild("skipNonT5").GetData(fSkipNonT5);
156  topB.GetChild("selectedEye").GetData(fSelectedEye);
157  topB.GetChild("skipXmaxBelowGround").GetData(fSkipXmaxBelowGround);
158  topB.GetChild("minDXground").GetData(fMinDXground);
159  topB.GetChild("skipXmaxOutsideProfile").GetData(fSkipXmaxOutsideProfile);
160  topB.GetChild("minBinsAroundMaximum").GetData(fMinBinsAroundMaximum);
161  topB.GetChild("SilentMaxRadius").GetData(fSilentMaxRadius);
162 
163  topB.GetChild("activeMethod").GetData(fActiveMethod);
164  topB.GetChild("writeToTextFile").GetData(fWriteToTextFile);
165 
166  topB.GetChild("useUnsaturatedTrace").GetData(fUseUnsaturatedTrace);
167 
168  {
169  ostringstream msg;
170  msg << "\n"
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;
179  INFO(msg);
180  }
181 
182  const Branch& calibBranch = topB.GetChild("Calibration");
183  calibBranch.GetChild("CalibOpt").GetData(fCalibOpt);
184  calibBranch.GetChild("RecMixture").GetData(fRecMixture);
185 
186  fFitterKG->fCalibOpt = fCalibOpt;
187  fFitterKG->fRecMixture = fRecMixture;
188 
189  {
190  ostringstream msg;
191  msg << "\n"
192  "======= Calibration settings =======\n"
193  "CalibOpt " << fCalibOpt << "\n"
194  "RecMixture " << fRecMixture;
195  INFO(msg);
196  }
197 
198  //
199  // Read configuration for Karlsruhe reconstruction
200  //
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);
206  karlsruheBranch.GetChild("RecType").GetData(fKarlsruheConfig.RecType);
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);
214 
215  // Possible overrides of standard settings
216  const Branch& KGoverrides = karlsruheBranch.GetChild("Overrides");
217 
218  KGoverrides.GetChild("doLDFFit").GetData(fFitterKG->doLDFFit);
219  KGoverrides.GetChild("doShapeFit").GetData(fFitterKG->doShapeFit);
220  KGoverrides.GetChild("doStartTimeFit").GetData(fFitterKG->doStartTimeFit);
221  KGoverrides.GetChild("doSaturatedStartTimeFit").GetData(fFitterKG->doSaturatedStartTimeFit);
222 
223  KGoverrides.GetChild("energyFixed").GetData(fFitterKG->energyFixed);
224  KGoverrides.GetChild("coreFixed").GetData(fFitterKG->coreFixed);
225  KGoverrides.GetChild("axisFixed").GetData(fFitterKG->axisFixed);
226  KGoverrides.GetChild("xmaxFixed").GetData(fFitterKG->xmaxFixed);
227  KGoverrides.GetChild("NmuFixed").GetData(fFitterKG->NmuFixed);
228  KGoverrides.GetChild("TimeModelOffsetFixed").GetData(fFitterKG->TimeModelOffsetFixed);
229 
230  string x0Mode;
231  KGoverrides.GetChild("X0Mode").GetData(x0Mode);
232  if (x0Mode == "Fixed")
233  fFitterKG->x0Mode = UnivFitterKG::eFixed;
234  else if (x0Mode == "Coupled")
235  fFitterKG->x0Mode = UnivFitterKG::eCoupled;
236  else
237  fFitterKG->x0Mode = UnivFitterKG::eFree;
238 
239  KGoverrides.GetChild("X0XmaxModelVersion").GetData(fFitterKG->fX0XmaxModelVersion);
240 
241  // Setting recType
242  fFitterKG->setRecType(fKarlsruheConfig.RecType);
243 
244  {
245  ostringstream msg;
246  msg << "\n"
247  "======= Configuration of Karlsruhe reconstruction =======\n";
248  if (fWriteToTextFile)
249  msg << "writing reconstruction summary to " << fKarlsruheConfig.outputFileName << '\n';
250  msg << "\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");
256  INFO(msg);
257  }
258 
259  if (fWriteToTextFile)
260  fitInfoKG.open(fKarlsruheConfig.outputFileName.c_str());
261 
262  fFitterKG->initTimeModel(fKarlsruheConfig.TimeModelVersion);
263 
264  //
265  // Read configuration for Bariloche reconstruction
266  //
267  const Branch& barilocheBranch = topB.GetChild("BarilocheReconstruction");
268 
269  barilocheBranch.GetChild("outputFileName").GetData(fBarilocheConfig.outputFileName);
270  barilocheBranch.GetChild("RecType").GetData(fBarilocheConfig.RecType);
271  barilocheBranch.GetChild("RecDetector").GetData(fBarilocheConfig.RecDetector);
272  barilocheBranch.GetChild("RecSDEUpgrade").GetData(fBarilocheConfig.RecSDEUpgrade);
273  barilocheBranch.GetChild("RecSys").GetData(fBarilocheConfig.RecSys);
274  barilocheBranch.GetChild("verbose").GetData(fBarilocheConfig.verbose);
275  barilocheBranch.GetChild("debug").GetData(fBarilocheConfig.debug);
276 
277  {
278  ostringstream msg;
279  msg << "\n"
280  "======= Configuration of Bariloche reconstruction =======\n";
281  if (fWriteToTextFile)
282  msg << "writing reconstruction summary to " << fBarilocheConfig.outputFileName << '\n';
283  msg << "\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;
292  INFO(msg);
293  }
294 
295  if (fWriteToTextFile)
296  fitInfoBG.open(fBarilocheConfig.outputFileName.c_str());
297 
298  return eSuccess;
299  }
300 
301 
303  UniversalityFitter::Run(evt::Event& event)
304  {
305  INFO("");
306 
307  mcPars.reset();
308  mcParsFluct.reset();
309  fittedPars.reset();
310 
311  const bool needMC =
312  fActiveMethod == "Karlsruhe" &&
313  fKarlsruheConfig.RecType == 1;
314 
315  const bool needFD =
316  (
317  fActiveMethod == "Bariloche" &&
318  (fBarilocheConfig.RecType == 0 || fBarilocheConfig.RecType == 7)
319  ) ||
320  (fActiveMethod == "Karlsruhe" && fKarlsruheConfig.RecType == 3);
321 
322  // nothing to do if there is no SEvent
323  if (!(event.HasSEvent() && event.HasRecShower() && event.GetRecShower().HasSRecShower())) {
324  INFO("event has no reconstructed shower");
325  return eContinueLoop;
326  }
327 
328  SEvent& sEvent = event.GetSEvent();
330  const ShowerSRecData& showerSRec = event.GetRecShower().GetSRecShower();
331 
332  // reconstruction requires successful LDF reconstruction
333  if (showerSRec.GetLDFRecStage() < ShowerSRecData::kLDF) {
334  INFO("LDF reconstruction stage too small");
335  return eContinueLoop;
336  }
337 
338  if (fSkipNonT5 && !showerSRec.IsT5()) {
339  INFO("reconstruction requires T5");
340  return eContinueLoop;
341  }
342 
343  const CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
344 
345  const double theta = showerSRec.GetAxis().GetTheta(siteCS);
346  if (theta < fMinTheta || theta > fMaxTheta) {
347  INFO("Zenith angle above range of parameterization");
348  return eContinueLoop;
349  }
350 
351  {
352  const double energy = event.HasSimShower() ? event.GetSimShower().GetEnergy() : showerSRec.GetEnergy();
353  if (energy < fMinEnergy) {
354  INFO("energy below cut");
355  return eContinueLoop;
356  }
357  }
358 
359  const sdet::SDetector& sDetector = det::Detector::GetInstance().GetSDetector();
360  const string& eventId = event.GetHeader().GetId();
361  const int sdEventId = sEvent.GetHeader().GetId();
362  const UTCDateTime eventTimeUTC = sEvent.GetHeader().GetTime();
363 
364  {
365  ostringstream msg;
366  msg << format("Event id %s, SD event id %i. Date %02i/%02i.") % eventId % sdEventId
367  % eventTimeUTC.GetMonth() % eventTimeUTC.GetYear();
368  INFO(msg);
369  }
370 
371  fStations.clear();
372  fEventHasSaturation = false;
373 
374  for (SEvent::ConstStationIterator sIt = sEvent.StationsBegin(), end = sEvent.StationsEnd();
375  sIt != end; ++sIt) {
376 
377  if (sIt->HasSimData() && sIt->GetRejectionStatus() == StationConstants::eMCInnerRadiusCut) {
378  ostringstream msg;
379  msg << "Station " << sIt->GetId() << " is inside MC inner radius cut. Skipping event.";
380  INFO(msg);
381  return eContinueLoop;
382  }
383 
384  if (!(sIt->IsCandidate() || sIt->IsSilent()))
385  continue;
386 
387  StationFitData sdata;
388 
389  sdata.stationId = sIt->GetId();
390  sdata.position = sDetector.GetStation(*sIt).GetPosition();
391 
392  // Values in sdata are left at the default for silent stations
393  if (sIt->IsSilent()) {
394 
395  if ((sdata.position - showerSRec.GetCorePosition()).GetMag() > fSilentMaxRadius)
396  continue;
397  sdata.isSilent = true;
398 
399  } else {
400  sdata.isSilent = false;
401 
402  const StationRecData& sRec = sIt->GetRecData();
403  sdata.totalSignal = sRec.GetTotalSignal();
404 
405  sdata.isSaturated = sIt->IsLowGainSaturation();
406  fEventHasSaturation |= sdata.isSaturated;
407 
408  sdata.startTime = sRec.GetSignalStartTime();
409  sdata.startBin = sRec.GetSignalStartSlot();
410  sdata.stopBin = sRec.GetSignalEndSlot();
411 
412  sdata.t50 = sRec.GetT50();
413  sdata.t10 = sdata.t50 - sRec.GetRiseTime();
414  sdata.t90 = sRec.GetFallTime() + sdata.t50;
415 
416  vector< vector<double> > vemTraces;
417  double aopsum = 0;
418 
419  for (sevt::Station::ConstPMTIterator pmtIter = sIt->PMTsBegin();
420  pmtIter != sIt->PMTsEnd(); ++pmtIter) {
421 
422  if (!(pmtIter->HasCalibData() && pmtIter->HasRecData()))
423  continue;
424 
425  const sevt::PMTRecData& pmtRec = pmtIter->GetRecData();
426 
427  if (!pmtRec.HasVEMTrace())
428  continue;
429 
430  const double calib = pmtRec.GetVEMPeak() / pmtRec.GetVEMCharge();
431  aopsum += 1 / calib;
432 
433  const bool useUnsat = sdata.isSaturated && fUseUnsaturatedTrace && pmtRec.HasVEMTrace(StationConstants::eTotalNoSaturation);
434 
435  if (useUnsat)
436  sdata.useUnsaturatedTrace = true;
437 
439  const TraceD& tr = pmtRec.GetVEMTrace(comp);
440 
441  vector<double> trace;
442 
443  for (TraceD::ConstIterator tIt = tr.Begin(), end = tr.End();
444  tIt != end; ++tIt)
445  trace.push_back((*tIt) * calib);
446 
447  vemTraces.push_back(trace);
448  }
449 
450  const unsigned int npmt = vemTraces.size();
451  sdata.AreaOverPeak = aopsum / npmt;
452 
453  if (npmt) {
454  const unsigned int nBins = vemTraces[0].size();
455 
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");
459  return eFailure;
460  }
461  }
462 
463  vector<double> averageTrace(nBins);
464 
465  for (unsigned int curBin = 0; curBin < nBins; ++curBin) {
466  double binSum = 0;
467  for (unsigned int curTrace = 0; curTrace < npmt; ++curTrace)
468  binSum += vemTraces[curTrace][curBin];
469  averageTrace[curBin] = binSum / npmt;
470  }
471 
472  sdata.trace = averageTrace;
473  }
474  }
475  fStations.push_back(sdata);
476  }
477 
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);
482  }
483 
484  fHottestStationHeight = utl::UTMPoint(fHottestStation->position, ReferenceEllipsoid::GetWGS84()).GetHeight();
485 
486  const atm::Atmosphere& theAtm = det::Detector::GetInstance().GetAtmosphere();
487  const atm::ProfileResult& tempProfile = theAtm.EvaluateTemperatureVsHeight();
488  const atm::ProfileResult& pressureProfile = theAtm.EvaluatePressureVsHeight();
489  const double temperature = tempProfile.Y(fHottestStationHeight);
490  const double pressure = pressureProfile.Y(fHottestStationHeight);
491 
492  if (!pressure || !temperature)
493  fDensity = averageAugerDensity;
494  else
495  fDensity = (pressure * kDryAirMolarMass) / (kMolarGasConstant * temperature);
496 
497  if (event.HasSimShower()) {
498  ShowerSimData& simShower = event.GetSimShower();
499 
500  mcPars.xmax = simShower.GetGHParameters().GetXMax();
501  mcPars.x0 = simShower.GetXFirst();
502  mcPars.xmaxMu = simShower.GetXmaxMu();
503  mcPars.Nmu = 1.0;
504  mcPars.energy = simShower.GetEnergy();
505  mcPars.axis = -simShower.GetDirection(); // GetDirection() points downwards, GetAxis() points upwards
506  mcPars.core = simShower.GetPosition();
507  mcPars.coretime = simShower.GetTimeStamp();
508 
509  const CoordinateSystemPtr coreCS = simShower.GetLocalCoordinateSystem();
510  const double theta = mcPars.axis.GetTheta(coreCS);
511  const double phi = mcPars.axis.GetPhi(coreCS);
512 
513  if (fSkipXmaxBelowGround) {
515  fatm.SetCurrentAtmosphere(eventTimeUTC.GetMonth());
516  const double DXground =
517  fatm.Get_DX_DL(0*cm, 90*degree, mcPars.xmax / gpercm2,
518  theta, fHottestStationHeight / cm, false, true) * gpercm2;
519 
520  if (DXground < fMinDXground) {
521  ostringstream msg;
522  msg << format("Xmax too close or below ground (DX = %.1f), skipping event.") % (DXground / gpercm2);
523  INFO(msg);
524  return eContinueLoop;
525  }
526  }
527 
528  if (fSkipXmaxOutsideProfile) {
529  if (!simShower.HasLongitudinalProfile())
530  ERROR("Can not check if Xmax is inside the longitudinal profile.");
531  const utl::TabulatedFunction& longProfile = simShower.GetdEdX();
532  int nlow = 0;
533  int nup = 0;
534  for (unsigned int i = 0; i < longProfile.GetNPoints(); ++i) {
535  if (longProfile[i].X() < mcPars.xmax)
536  ++nlow;
537  else
538  ++nup;
539  }
540 
541  if (nlow < fMinBinsAroundMaximum || nup < fMinBinsAroundMaximum) {
542  INFO("Xmax is not contained in the longitudinal profile, skipping event.");
543  return eContinueLoop;
544  }
545  }
546 
547  const CoordinateSystemPtr showerPlaneCS(
548  CoordinateSystem::RotationY(
549  theta,
550  CoordinateSystem::RotationZ(
551  phi,
552  coreCS
553  )
554  )
555  );
556 
557  // calculate MC Nmu
558  // this should be generalized if only dense rings at other radii are available (for example infill)
559 
560  double muonSignalSum = 0;
561  int nDenseStations = 0;
562 
563  for (SEvent::ConstStationIterator sIt = sEvent.StationsBegin(), end = sEvent.StationsEnd(); sIt != end; ++sIt) {
564  if (!sDetector.GetStation(*sIt).IsDense())
565  continue;
566  const double rhoSP = sDetector.GetStation(*sIt).GetPosition().GetRho(showerPlaneCS);
567  if (!IsCloseRel(rhoSP, 1000*meter))
568  continue;
569 
570  if (sIt->HasVEMTrace(sevt::StationConstants::eMuon)) {
571  // assuming all PMTs have the same peak/charge (true in MC)
572  const TraceD& trace = sIt->GetVEMTrace(sevt::StationConstants::eMuon);
573  const double muonSignal = accumulate(trace.Begin(), trace.End(), 0.);
574  const sevt::PMTRecData& pmtRec = sIt->GetPMT(1).GetRecData();
575  muonSignalSum += muonSignal * pmtRec.GetVEMPeak() / pmtRec.GetVEMCharge();
576  ++nDenseStations;
577  }
578  }
579 
580  if (muonSignalSum > 0) {
581  const double Nmu = 1.0; // proton QGSJet II-03
582  UnivParamNS::UnivParam fsignal(eWCD);
584  const double sMuRef =
585  fsignal.GetSignal(1000*meter / cm, mcPars.xmax / gpercm2, log10(mcPars.energy), theta, 90*degree,
586  fDensity / (gram / cm3), fHottestStationHeight / cm, Nmu, 0, eventTimeUTC.GetMonth());
587  mcPars.Nmu = (muonSignalSum / nDenseStations) / sMuRef;
588  simShower.SetNmu(mcPars.Nmu);
589  ostringstream msg;
590  msg << "True Nmu " << mcPars.Nmu;
591  INFO(msg);
592  } else {
593  INFO("Could not set true Nmu.");
594  }
595 
596  if (fKarlsruheConfig.useRealisticEnergySmearing) {
597  const double sigmaE = SdEnergyResolution(mcPars.energy);
598  mcParsFluct.energy = SmearValue(mcPars.energy, sigmaE * mcPars.energy);
599  } else
600  mcParsFluct.energy = SmearValue(mcPars.energy, 0.1 * mcPars.energy);
601 
602  mcParsFluct.xmax = SmearValue(mcPars.xmax, 20 * gpercm2);
603  mcParsFluct.Nmu = SmearValue(mcPars.Nmu, 0.1);
604  mcParsFluct.x0 = SmearValue(mcPars.x0, 20 * gpercm2);
605 
606  {
607  const double theta = mcPars.axis.GetTheta(coreCS);
608  const double phi = mcPars.axis.GetPhi(coreCS);
609 
610  TVector3 theCR;
611  theCR.SetMagThetaPhi(1., theta, phi);
612  TVector3 rndD = theCR.Orthogonal();
613  rndD.SetMag(fabs(RandGauss::shoot(&fRandomEngine->GetEngine(), 0, UnivRecNS::SmearingAngle * degree)));
614  rndD.Rotate(RandFlat::shoot(&fRandomEngine->GetEngine(), 0, 2 * kPi), theCR);
615  rndD = theCR + rndD;
616  theCR = rndD.Unit();
617 
618  mcParsFluct.axis = Vector(1, theCR.Theta(), theCR.Phi(), coreCS, Vector::kSpherical);
619  }
620 
621  // TODO check resolution of core position and time
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);
625 
626  mcParsFluct.coretime = mcPars.coretime + TimeInterval(RandGauss::shoot(&fRandomEngine->GetEngine(), 0, 100*ns));
627 
628  } else if (needMC)
629  ERROR("The event has no simulated shower");
630 
631  fdParameters.clear();
632 
633  if (event.HasFEvent()) {
634 
635  const fevt::FEvent& fEvent = event.GetFEvent();
636  double bestErrorEllipse = 0;
637 
638  for (FEvent::ConstEyeIterator eyeIt = fEvent.EyesBegin(ComponentSelector::eHasData);
639  eyeIt != fEvent.EyesEnd(ComponentSelector::eHasData); ++eyeIt) {
640 
641  if (!eyeIt->HasRecData())
642  continue;
643 
644  const int eyeId = eyeIt->GetId();
645  if (fSelectedEye > 0 && eyeId != fSelectedEye)
646  continue;
647 
648  const fevt::EyeRecData& eyeRec = eyeIt->GetRecData();
649  if (eyeRec.GetSDPFitNDof() <= 0 || eyeRec.GetTimeFitNDof() <= 0)
650  continue;
651 
652  if (!eyeRec.HasFRecShower())
653  continue;
654 
655  const evt::ShowerFRecData& showerFRec = eyeRec.GetFRecShower();
656 
657  if (!showerFRec.HasGHParameters())
658  continue;
659 
660  const fdet::Eye& dEye = det::Detector::GetInstance().GetFDetector().GetEye(*eyeIt);
661 
662  fdParameters[eyeId].eyeName = dEye.GetName();
663  fdParameters[eyeId].xmax = showerFRec.GetGHParameters().GetXMax();
664  fdParameters[eyeId].xmaxUnc = showerFRec.GetXmaxError();
665  fdParameters[eyeId].energy = showerFRec.GetTotalEnergy();
666  fdParameters[eyeId].energyUnc = showerFRec.GetTotalEnergyError();
667 
668  const Point eyePos = dEye.GetPosition();
669  const Vector vecEyeCore = eyePos - showerFRec.GetCorePosition();
670 
671  const double rpErr = eyeRec.GetRpError();
672  const double chi0 = eyeRec.GetChiZero();
673  const double chi0Err = eyeRec.GetChiZeroError();
674  const double sdpPhiErr = eyeRec.GetSDPPhiError();
675  const double rhoChi0Rp = eyeRec.GetRpChi0Correlation();
676  const double distEyeCore = vecEyeCore.GetMag();
677 
678  // calculation of core error in SDP
679  // rp error projected on ground+
680  // chi0 error+ correlation of errors in rp and chi0
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);
685 
686  const double errorPerpSDP = distEyeCore * sin(sdpPhiErr);
687  const double coreErrorEllipse = errorInSDP * errorPerpSDP * kPi;
688 
689  // if error ellipse set AND error ellipse larger than previous eye(s)
690  // don't update core with actual eye
691  if (bestErrorEllipse && bestErrorEllipse < coreErrorEllipse)
692  continue;
693 
694  bestErrorEllipse = coreErrorEllipse;
695 
696  fdParameters[0].eyeName = dEye.GetName();
697  fdParameters[0].axis = showerFRec.GetAxis();
698  fdParameters[0].core = showerFRec.GetCorePosition();
699  fdParameters[0].coretime = showerFRec.GetCoreTime();
700  }
701 
702  if (fdParameters.empty() && needFD) {
703  INFO("Event has no suitable FD data");
704  return eContinueLoop;
705  } else {
706  ostringstream msg;
707  msg << "shower geometry (axis, core position + time) taken from " << fdParameters[0].eyeName;
708  INFO(msg);
709  }
710 
711  double wghtAvEnergy = 0;
712  double wghtAvXmax = 0;
713 
714  if (!fdParameters.empty()) {
715  {
716  double weightSum = 0;
717  for (map<int, FDParameters>::iterator fd = fdParameters.begin(); fd != fdParameters.end(); ++fd) {
718  if (!fd->second.energy)
719  continue;
720  const double unc = fd->second.energyUnc;
721  const double weight = 1 / (unc * unc);
722  weightSum += weight;
723  wghtAvEnergy += fd->second.energy * weight;
724  }
725  wghtAvEnergy /= weightSum;
726  }
727 
728  {
729  double weightSum = 0;
730  for (map<int, FDParameters>::iterator fd = fdParameters.begin(); fd != fdParameters.end(); ++fd) {
731  if (!fd->second.xmax)
732  continue;
733  const double unc = fd->second.xmaxUnc;
734  const double weight = 1 / (unc * unc);
735  weightSum += weight;
736  wghtAvXmax += fd->second.xmax * weight;
737  }
738  wghtAvXmax /= weightSum;
739  }
740 
741  ostringstream msg;
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); // one "virtual" eye for weighted values
746 
747  INFO(msg);
748 
749  fdParameters[0].xmax = wghtAvXmax;
750  fdParameters[0].energy = wghtAvEnergy;
751  }
752  }
753 
754  if (fActiveMethod == "Karlsruhe")
755  RunKarlsruheReconstruction(event);
756  else if (fActiveMethod == "Bariloche")
757  RunBarilocheReconstruction(event);
758 
759  WriteRecParameters(event);
760  SetRecData(event);
761 
762  return eSuccess;
763  }
764 
765 
766  double
767  UniversalityFitter::SmearValue(const double mean, const double spread)
768  {
769  return RandGauss::shoot(&fRandomEngine->GetEngine(), mean, spread);
770  }
771 
772 
773  void
774  UniversalityFitter::SwitchMethod()
775  {
776  string newMethod;
777  if (fActiveMethod == "Karlsruhe")
778  newMethod = "Bariloche";
779  else
780  newMethod = "Karlsruhe";
781 
782  ostringstream msg;
783  msg << "Switching to " << newMethod << " reconstruction";
784  INFO(msg);
785  fActiveMethod = newMethod;
786  }
787 
788 
789  void
790  UniversalityFitter::RunKarlsruheReconstruction(evt::Event& event)
791  {
792  fFitterKG->reset();
793  fFitterKG->isMCEvent = event.HasSimShower();
794 
795  if (event.HasSimShower()) {
796  MCParameters& pars = fKarlsruheConfig.useSmearedMC ? mcParsFluct : mcPars;
797 
798  fFitterKG->mcPars.valid = true;
799  fFitterKG->mcPars.energy = pars.energy;
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;
807  }
808 
809  const SEvent& sEvent = event.GetSEvent();
810  const UTCDateTime eventTimeUTC = sEvent.GetHeader().GetTime();
811  fFitterKG->atmModel = eventTimeUTC.GetMonth();
812  fFitterKG->fDensity = fDensity;
813 
814  ShowerSRecData& showerSRec = event.GetRecShower().GetSRecShower();
815  fFitterKG->sdPars.valid = true;
816  fFitterKG->sdPars.showersize = showerSRec.GetShowerSize();
817  fFitterKG->sdPars.energy = showerSRec.GetEnergy();
818  fFitterKG->sdPars.axis = showerSRec.GetAxis();
819  fFitterKG->sdPars.core = showerSRec.GetCorePosition();
820  fFitterKG->sdPars.coretime = showerSRec.GetCoreTime();
821 
822  fFitterKG->sdPars.showersizeUnc = showerSRec.GetShowerSizeError();
823  fFitterKG->sdPars.energyUnc = showerSRec.GetEnergyError();
824  fFitterKG->sdPars.axisUncTheta = showerSRec.GetThetaError();
825  fFitterKG->sdPars.axisUncPhi = showerSRec.GetPhiError();
826 
827  if (!fdParameters.empty()) {
828  // always uses weighted average of Xmax and energy and best core / axis
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;
835  }
836 
837  for (std::vector<StationFitData>::iterator sIt = fStations.begin(); sIt != fStations.end(); ++sIt) {
838 
839  if (sIt->isSilent || sIt->stationType != eWCD)
840  continue;
841 
843 
844  sdata.stationId = sIt->stationId;
845  sdata.totalSignal = sIt->totalSignal;
846  sdata.isSaturated = sIt->isSaturated;
847  sdata.useUnsaturatedTrace = sIt->useUnsaturatedTrace;
848  sdata.trace = sIt->trace;
849  sdata.startTime = sIt->startTime;
850  sdata.startBin = sIt->startBin;
851  sdata.stopBin = sIt->stopBin;
852  sdata.position = sIt->position;
853  sdata.t10 = sIt->t10;
854  sdata.t50 = sIt->t50;
855  sdata.t90 = sIt->t90;
856 
857  fFitterKG->addStationFitData(sdata);
858  }
859 
860  const bool fitSuccessful = fFitterKG->run();
861 
862  fittedPars.energy = fFitterKG->fittedPars.energy;
863  fittedPars.energyUnc = fFitterKG->fittedPars.energyUnc;
864 
865  fittedPars.xmax = fFitterKG->fittedPars.xmax;
866  fittedPars.xmaxUnc = fFitterKG->fittedPars.xmaxUnc;
867 
868  fittedPars.Nmu = fFitterKG->fittedPars.Nmu;
869  fittedPars.NmuUnc = fFitterKG->fittedPars.NmuUnc;
870 
871  fittedPars.TimeModelOffset = fFitterKG->fittedPars.TimeModelOffset;
872  fittedPars.TimeModelOffsetUnc = fFitterKG->fittedPars.TimeModelOffsetUnc;
873 
874  fittedPars.axis = fFitterKG->fittedPars.axis;
875  fittedPars.axisUncTheta = fFitterKG->fittedPars.axisUncTheta;
876  fittedPars.axisUncPhi = fFitterKG->fittedPars.axisUncPhi;
877 
878  fittedPars.core = fFitterKG->fittedPars.core;
879  fittedPars.coreUncX = fFitterKG->fittedPars.coreUncX;
880  fittedPars.coreUncY = fFitterKG->fittedPars.coreUncY;
881 
882  fittedPars.coretime = fFitterKG->fittedPars.coretime;
883 
884  fittedPars.fNCandShape = fFitterKG->fNStationsShape;
885  fittedPars.fNCandStartTime = fFitterKG->fNStationsStartTime;
886  fittedPars.fNCandLDF = fFitterKG->fNStationsLDF;
887 
888  fittedPars.isGoodRec = fitSuccessful;
889 
890  if (!fitSuccessful) {
891  ostringstream msg;
892  msg << "\n\n"
893  "#############################\n"
894  "### FIT DID NOT CONVERGE! ###\n"
895  "#############################";
896  INFO(msg);
897  }
898  }
899 
900 
901  void
902  UniversalityFitter::UnivRecNS_FCN(Int_t& /*npar*/, Double_t* /*gin*/, Double_t& f, Double_t* par, Int_t /*iflag*/)
903  {
904  std::vector<double> par_v;
905  for (unsigned int ipar = 0; ipar < UnivRecNS::npar; ++ipar)
906  par_v.push_back(par[ipar]);
907  f = -gUnivRecNS->GetLikelihood(par_v, parStatus);
908  if (std::isnan(f) || std::isinf(f))
909  f = 100;
910  }
911 
912 
913  bool
914  UniversalityFitter::Rec(UnivRecNS::UnivRec& theRec)
915  {
916  double XmaxLow = 0;
917  double XmaxHigh = 0;
918  theRec.GetXmaxRange(XmaxLow, XmaxHigh);
919 
920  //int status=0;
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;
926  theRec.InitFCNParameters(par, epar, parStatus, hasLimits);
927 
928  // TODO switch to Minuit 2 (UnivFCN), gUnivRecNS -> local
929 
930  int ierflg = 0;
931  double arglist[10];
932  TMinuit* const minuit = new TMinuit(UnivRecNS::npar);
933  arglist[0] = -1;
934  minuit->mnexcm("SET PRINTOUT", arglist, 1, ierflg);
935  minuit->mnexcm("SET NOWARNINGS", arglist, 0, ierflg);
936  minuit->SetFCN(UnivRecNS_FCN);
937  arglist[0] = 0.5;
938  minuit->mnexcm("SET ERR", arglist, 1, ierflg);
939 
940  for (unsigned int ipar = 0; ipar < UnivRecNS::npar; ++ipar) {
941  double low = 0;
942  double high = 0;
943  if (hasLimits[ipar]) {
944  low = (ipar == 4 || ipar == 8 ? XmaxLow / UnivRecNS::unit[ipar] : UnivRecNS::low[ipar] / UnivRecNS::unit[ipar]);
945  high = (ipar == 4 || ipar == 8 ? XmaxHigh / UnivRecNS::unit[ipar] : UnivRecNS::high[ipar] / UnivRecNS::unit[ipar]);
946  }
947  minuit->mnparm(ipar, UnivRecNS::ParName[ipar].c_str(), par[ipar], epar[ipar], low, high, ierflg);
948  }
949 
950  for (unsigned int ipar = 0; ipar < UnivRecNS::npar; ++ipar)
951  if (parStatus[ipar] > 1)
952  minuit->FixParameter(ipar);
953 
954  arglist[0] = 5000;
955  arglist[1] = 0.001;
956 
957  int stdo = 0;
958  if (!fBarilocheConfig.verbose) { // removing minuit output
959  stdo = dup(1);
960  close(1);
961  }
962  minuit->mnexcm("SIMPLEX", arglist , 2, ierflg);
963  if (!fBarilocheConfig.verbose) { // removing minuit output
964  dup2(stdo, 1);
965  close(stdo);
966  }
967 
968  for (unsigned int ipar = 0; ipar < UnivRecNS::npar; ++ipar)
969  minuit->GetParameter(ipar, par[ipar], epar[ipar]);
970  theRec.SaveFCNParameters(par, parStatus);
971 
972  delete minuit;
973  return true;
974  }
975 
976 
977  bool
978  UniversalityFitter::InitBarilocheReconstruction(evt::Event& event)
979  {
980  const int gRecSys = fBarilocheConfig.RecSys;
981  const int gRecType = fBarilocheConfig.RecType;
982  //const bool gRecSDE_Upgrade = fBarilocheConfig.RecSDEUpgrade;
983  const bool gRecMC = !fBarilocheConfig.IsData;
984 
985  // SEvent
986  const SEvent& sEvent = event.GetSEvent();
987  int sdEventId = sEvent.GetHeader().GetId();
988  const ShowerSRecData& showerSRecData = event.GetRecShower().GetSRecShower();
989  const utl::Point& core = showerSRecData.GetCorePosition();
990 
991  // Coordinate system
993  const CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
994  const CoordinateSystemPtr hottestStationCS = LocalCoordinateSystem::Create(fHottestStation->position);
995 
996  // UnivRec
997  UnivRecNS::UnivRec& theRec = *gUnivRecNS;
998  UnivRecNS::MCInfo_t& MCinfo = theRec.MCinfo;
999  UnivRecNS::AugerRecInfo_t& augerinfo = theRec.augerinfo;
1000  UnivRecNS::RecInfo_t& recinfo = theRec.recinfo;
1001 
1002  theRec.ClearRecEvent();
1003 
1004  theRec.nRecStations = 0;
1005  theRec.XmaxLow = UnivRecNS::low[4];
1006  theRec.XmaxHigh = UnivRecNS::high[4];
1007 
1008  //-----------------------------------------------
1009  // Set Id, Check T4/6T5
1010  //-----------------------------------------------
1011  recinfo.id = sdEventId;
1012  const bool okT4 = showerSRecData.IsT4();
1013  const bool ok6T5 = showerSRecData.IsT5();
1014 
1015  //-----------------------------------------------
1016  // Load MC info
1017  //-----------------------------------------------
1018 
1019  if (gRecMC) {
1020  MCinfo.theta = mcPars.axis.GetTheta(hottestStationCS);
1021  MCinfo.azi = mcPars.axis.GetPhi(hottestStationCS);
1022 
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;
1026 
1027  MCinfo.T0 = 0.;// mcPars.coretime;
1028 
1029  MCinfo.logE = log10(mcPars.energy);
1030  MCinfo.Xmax = mcPars.xmax / gpercm2;
1031  }
1032 
1033  //-----------------------------------------------
1034  //Set : Atmosphere/Ground Density
1035  // Warning: 1) Ground density taken from the Offline atmosphere (not weather stations)
1036  // 2) We assume that the month in the simulations was simulated with the corresponding atmospheric monthly model
1037  //-----------------------------------------------
1038 
1039  const TimeStamp& eventTime = sEvent.GetHeader().GetTime();
1040  const UTCDateTime eventTimeUTC = eventTime;
1041  theRec.GPSsec = eventTime.GetGPSSecond();
1042 
1043  const int imonth = eventTimeUTC.GetMonth();
1044  theRec.fatm->SetCurrentAtmosphere(imonth);
1045  recinfo.iatm = imonth;
1046  recinfo.AugerDensity = fDensity / (gram / cm3);
1047 
1048  //-----------------------------------------------
1049  // Set true Nmu in MC ( using the WCD response and proton QGSJEtII-03 at r=1000 [m] and psi=90 [deg] as reference )
1050  //-----------------------------------------------
1051  if (gRecMC)
1052  MCinfo.Nmu = mcPars.Nmu;
1053 
1054  //-----------------------------------------------
1055  // Set OffsetM_Mu
1056  //-----------------------------------------------
1057  recinfo.OffsetM_Mu = 0;
1058  for (int itype = 0; itype < 3; ++itype)
1059  theRec.ftime[itype]->SetOffsetM_Mu(recinfo.OffsetM_Mu);
1060 
1061  //-----------------------------------------------
1062  //Set Auger Info
1063  //-----------------------------------------------
1064 
1065  // SD (Observer reconstruction) core position is not saved (Do it in Offline!)
1066  augerinfo.logE_SD = log10(showerSRecData.GetEnergy());
1067  augerinfo.logE_SD_err = log10(1 + showerSRecData.GetEnergyError() / showerSRecData.GetEnergy());
1068  augerinfo.theta_SD = showerSRecData.GetAxis().GetTheta(hottestStationCS);
1069  augerinfo.azi_SD = showerSRecData.GetAxis().GetPhi(hottestStationCS);
1070  augerinfo.xgcore_SD = showerSRecData.GetCorePosition().GetX(hottestStationCS) / cm;
1071  augerinfo.ygcore_SD = showerSRecData.GetCorePosition().GetY(hottestStationCS) / cm;
1072  augerinfo.zgcore_SD = (showerSRecData.GetCorePosition().GetZ(hottestStationCS) + fHottestStationHeight) / cm;
1073  augerinfo.logE_SD += log10(UnivCalibConstantsNS::fEnergySys_Auger[gRecSys]);
1074  augerinfo.isGoodSD = (okT4 && ok6T5);
1075 
1076  recinfo.RA = 0;
1077  recinfo.Dec = 0;
1078 
1079  augerinfo.Xmax_FD_err = 20;
1080  augerinfo.logE_FD_err = log10(1.1);
1081 
1082  if (gRecMC) {
1083  //--- Fluctuated values of Energy and Xmax
1084  augerinfo.Xmax_FD = mcParsFluct.xmax / gpercm2;
1085  augerinfo.logE_FD = log10(mcParsFluct.energy);
1086  augerinfo.theta_FD = mcParsFluct.axis.GetTheta(hottestStationCS);
1087  augerinfo.azi_FD = mcParsFluct.axis.GetPhi(hottestStationCS);
1088 
1089  augerinfo.isGoodFD = true;
1090 
1091  } else {
1092  augerinfo.isGoodFD = false;
1093  if (!fdParameters.empty()) {
1094  const int EyeSel = (gRecSys == 6 || gRecSys == 7 || gRecSys == 8 || gRecSys == 9 ? gRecSys - 5 : 0);
1095  augerinfo.isGoodFD = true;
1096 
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); // If Offline is using M. Tueros et al
1100  augerinfo.logE_FD += log10(UnivCalibConstantsNS::fEnergySys_Auger[gRecSys]);
1101 
1102  augerinfo.Xmax_FD = fdParameters[EyeSel].xmax / gpercm2;
1103  augerinfo.Xmax_FD += UnivCalibConstantsNS::fXmaxSys_Auger[gRecSys];
1104 
1105  augerinfo.theta_FD = fdParameters[EyeSel].axis.GetTheta(coreCS);
1106  augerinfo.azi_FD = fdParameters[EyeSel].axis.GetPhi(coreCS);
1107  }
1108  }
1109 
1110  //-----------------------------------------------
1111  // Selection
1112  //-----------------------------------------------
1113  if (!augerinfo.isGoodSD) {
1114  printf(" Event is not T4/6T5 %d \n", recinfo.id);
1115  return false;
1116  }
1117 
1118  if (!augerinfo.isGoodFD && gRecType == 0) {
1119  printf(" Nmu_FD reconstruction but no FD (Xmax,Energy) %d \n", recinfo.id);
1120  return false;
1121  }
1122 
1123  //int nSignalStations = 0;
1124 
1125  //-----------------------------------------------
1126  // Set station vector ( WCD )
1127  //-----------------------------------------------
1128  for (std::vector<StationFitData>::iterator sIt = fStations.begin(); sIt != fStations.end(); ++sIt) {
1129  const int itype = eWCD;
1130  if (theRec.gDetectorTypeMask[itype])
1131  continue;
1132 
1133  //----Stations rejected
1134  if (sIt->stationId == 94 && recinfo.id == 21354417)
1135  continue;
1136 
1137  //----Station/Event trigger and selection given by WCD
1138  UnivRecNS::RecStation_t station;
1139  theRec.InitRecStation(&station);
1140 
1141  station.type = itype;
1142  station.id = sIt->stationId;
1143 
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;
1147 
1148  station.GPSnano = (sIt->startTime - fHottestStation->startTime).GetInterval();
1149  station.GPSnano -= sIt->startBin * 25.;
1150 
1151  if (sIt->isSilent) {
1152  theRec.fstation.push_back(station);
1153  continue;
1154  }
1155 
1156  if (sIt->trace.empty())
1157  continue;
1158 
1159  //----------------
1160  // T1/T2 stations
1161  //----------------
1162 
1163  //---- Area over peak
1164  station.AreaOverPeak = sIt->AreaOverPeak;
1165 
1166  //---- Traces
1167  const float timeUnit = 25.;
1168  const vector<float> vemtrace(sIt->trace.begin(), sIt->trace.end());
1169 
1170  //---- Saturation/Signal
1171  station.isSaturated = (sIt->isSaturated && !sIt->useUnsaturatedTrace);
1172  const int start = sIt->startBin;
1173  const int end = sIt->stopBin;
1174 //#warning by offline trace convention here should be stop+1
1175  station.signalsize = accumulate(&vemtrace.front() + sIt->startBin, &vemtrace.front() + sIt->stopBin, 0.f);
1176 
1177  if (station.isSaturated)
1178  recinfo.IsSaturated[itype] = true;
1179  if (station.signalsize > UnivRecNS::vemSignalCut)
1180  station.mask_signal = false;
1181 
1182  //----Start time
1183  station.starttime = (start + 0.5) * timeUnit;
1184 
1185  //----Quantiles
1186  station.quantile[0] = 0.01 * int(100. / station.signalsize);
1187  if (station.quantile[0] < 0.01)
1188  station.quantile[0] = 0.01;
1189  station.quantile[1] = 0.100;
1190  station.quantile[2] = 0.500;
1191  station.quantile[3] = 0.900;
1192 
1193  for (int iq = 0; iq < UnivRecNS::nQ; ++iq) {
1194  float tq = 0;
1195  float tq_err = 0;
1196  const float signal = station.signalsize;
1197  GetTimeQuantile(&vemtrace[start], signal, end - start, timeUnit, station.quantile[iq], tq, tq_err);
1198  station.tquantile[0][iq] = tq + start * timeUnit;
1199  }
1200  for (int iq = 0; iq < UnivRecNS::nQ; ++iq)
1201  if (station.signalsize < UnivRecNS::vemTimeCut[iq] || station.isSaturated) {
1202  station.quantile[iq] = UNDEF;
1203  station.tquantile[0][iq] = UNDEF;
1204  station.tquantile[1][iq] = UNDEF;
1205  }
1206 
1207  station.quantile[3] = UNDEF;
1208  station.tquantile[0][3] = UNDEF; // Disable t_90 until new Time model is produced
1209 
1210  if (station.isSaturated)
1211  station.mask_starttime = false;
1212  if (station.quantile[0] != UNDEF || station.quantile[1] != UNDEF ||
1213  station.quantile[2] != UNDEF || station.quantile[3] != UNDEF)
1214  station.mask_quantiles = false;
1215 
1216  const double vemCut = !theRec.IsTimeRec ? UnivRecNS::vemSignalCut : UnivRecNS::vemTimeCut[2];
1217  if (station.signalsize > vemCut)
1218  ++recinfo.nStationsWCD;
1219 
1220  theRec.fstation.push_back(station);
1221  } // Stations
1222 
1223 
1224  //-----------------------------------------------
1225  // Set station vector ( MD )
1226  //-----------------------------------------------
1227  if (event.HasMEvent()) {
1228  // Select counters with data
1229  mevt::MEvent& me = event.GetMEvent();
1230  const mdet::MDetector& mDetector = det::Detector::GetInstance().GetMDetector();
1231 
1232  for (mevt::MEvent::CounterIterator ic = me.CountersBegin(), ec = me.CountersEnd(); ic != ec; ++ic) {
1233 
1234  if (!ic->HasRecData() || !sEvent.HasStation(ic->GetId()) || ic->IsRejected() || !ic->IsCandidate())
1235  continue;
1236  //Reject dense array stations
1237  /* if (ic->GetId() > 1080000)
1238  continue;*/
1239  const int itype = eAMIGA;
1240  if (theRec.gDetectorTypeMask[itype])
1241  continue;
1242 
1243  //----Station info
1244  UnivRecNS::RecStation_t station;
1245  theRec.InitRecStation(&station);
1246 
1247  station.type = itype;
1248  station.id = ic->GetId();
1249 
1250  utl::Point position = mDetector.GetCounter(station.id).GetPosition();
1251  station.xg = position.GetX(hottestStationCS) / cm;
1252  station.yg = position.GetY(hottestStationCS) / cm;
1253  station.zg = (position.GetZ(hottestStationCS) + fHottestStationHeight) / cm;
1254 
1255  station.GPSnano = 0;
1256  //Detector Area should be in cm^2
1257  station.DetectorArea = ic->GetActiveArea()*10000;
1258 
1259  //Saturation and signal
1260  if (ic->IsSaturated())
1261  station.isSaturated = true;
1262  else
1263  station.isSaturated = false;
1264  if (station.isSaturated)
1265  recinfo.IsSaturated[itype] = true;
1266 
1267  station.signalsize = ic->GetNumberOfEstimatedMuons(); // Info: GAP GAP2014_037.
1268  station.mask_signal = false;
1269 
1270  const double vemCut = (!theRec.IsTimeRec ? UnivRecNS::vemSignalCut : UnivRecNS::vemTimeCut[2]);
1271  if (station.signalsize > vemCut)
1272  recinfo.nStationsMD++;
1273 
1274  theRec.fstation.push_back(station);
1275 
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);
1277  } // end counter loop
1278 
1279  } // has MEvent
1280 
1281  //-----------------------------------------------
1282  // Set station vector ( ASCII )
1283  //-----------------------------------------------
1284  /*loop
1285  {
1286  itype=1;
1287  double vemCut=( !theRec.IsTimeRec ? UnivRecNS::vemSignalCut : UnivRecNS::vemTimeCut[2] );
1288  if ( station.signalsize > vemCut ) recinfo.nStationsScin++;
1289  */
1290 
1291  //-----------------------------------------------
1292  // Selection according to the number of stations
1293  //-----------------------------------------------
1294 
1295  theRec.nRecStations = theRec.fstation.size();
1296 
1297  printf("Number of stations loaded: %d (%d/%d/%d) (id=%d) | log(E_SD)=%5.2lf\n",
1298  theRec.nRecStations, recinfo.nStationsWCD, recinfo.nStationsScin, recinfo.nStationsMD, recinfo.id, augerinfo.logE_SD);
1299 
1301  const bool okStations = (recinfo.nStationsWCD >= nMin);
1302  if (!okStations) {
1303  printf("Not processing: Number of stations loaded %d | WCD above threshold %d \n", theRec.nRecStations, recinfo.nStationsWCD);
1304  return false;
1305  }
1306 
1307  //-----------------------------------------------
1308  // Set AMIGA/ASCII mask_signal according to WCD
1309  //-----------------------------------------------
1310  for (int idet_i = 0; idet_i < theRec.nRecStations; ++idet_i) {
1311  UnivRecNS::RecStation_t* st = &theRec.fstation[idet_i];
1312  if (st->type == eWCD)
1313  continue;
1314  st->mask_signal = false;
1315 
1316  int idet_wcd = UNDEF;
1317  for (int idet_j = 0; idet_j < theRec.nRecStations; ++idet_j)
1318  if (theRec.fstation[idet_j].type == eWCD && theRec.fstation[idet_j].id == st->id)
1319  idet_wcd = idet_j;
1320 
1321  if (idet_wcd == UNDEF)
1322  continue;
1323  st->mask_signal = theRec.fstation[idet_wcd].mask_signal;
1324  }
1325 
1326  //-----------------------------------------------
1327  // Hot station, Height of the core position (WCD)
1328  //-----------------------------------------------
1329 
1330  double vemMax = -1e10;
1331  for (int idet = 0; idet < theRec.nRecStations; ++idet)
1332  if (theRec.fstation[idet].type == eWCD && theRec.fstation[idet].signalsize > vemMax) {
1333  vemMax = theRec.fstation[idet].signalsize;
1334  recinfo.gDetHot = idet;
1335  }
1336  recinfo.zgcore = theRec.fstation[recinfo.gDetHot].zg;
1337 
1338  return true;
1339  }
1340 
1341 
1342  void
1343  UniversalityFitter::RunBarilocheReconstruction(evt::Event& event)
1344  {
1345  const int verbose = fBarilocheConfig.verbose;
1346  const int debug = fBarilocheConfig.debug;
1347  fBarilocheConfig.IsData = (!event.HasSimShower());
1348 
1349  UnivRecNS::UnivRec& theRec = *gUnivRecNS;
1350  if (!theRec.InitRec(fBarilocheConfig.IsData, fBarilocheConfig.RecType,
1351  fCalibOpt, fBarilocheConfig.RecDetector,
1352  fBarilocheConfig.RecSys, fRecMixture))
1353  return;
1354 
1355  if (!InitBarilocheReconstruction(event))
1356  return;
1357 
1358  if (debug)
1359  cerr << "InitEvent ok" << endl;
1360  if (verbose > 1)
1361  cerr << "Number of stations loaded: "
1362  << theRec.GetnRecStations()
1363  << " (" << theRec.GetRecInfo()->nStationsWCD
1364  << ")" << endl;
1365 
1366  if (!theRec.InitRecParameters())
1367  return;
1368 
1369  if (debug)
1370  cerr << "InitRecParameters ok" << endl;
1371 
1372  //------- Fit stage -1/0
1373  if (theRec.SetFitStage(-1))
1374  Rec(theRec);
1375 
1376  if (!theRec.StationSelection())
1377  return;
1378 
1379  if (debug)
1380  cerr << "StationSelection ok" << endl;
1381 
1382  if (theRec.SetFitStage(0)) {
1383  Rec(theRec);
1384  if (theRec.GetRecInfo()->FitStatus[0] != 3)
1385  Rec(theRec);
1386  }
1387 
1388  if (debug)
1389  theRec.PrintRecInfo(true);
1390 
1391  //--------- Fit stage 1 : Time Likelihood, Gaus PDF, (Xmax,T0) estimation
1392  if (theRec.SetFitStage(1)) {
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) {
1397  theRec.GetRecInfo()->Xmax = Xmax_init[iscan];
1398  Rec(theRec);
1399  if (debug)
1400  cerr << "SetFitStage 1 Search Xmax Rec ok" << endl;
1401  if (theRec.GetRecInfo()->lnP[0] > lnP_max) {
1402  lnP_max = theRec.GetRecInfo()->lnP[0];
1403  Xmax0 = Xmax_init[iscan];
1404  }
1405  }
1406  theRec.GetRecInfo()->Xmax = Xmax0;
1407  Rec(theRec);
1408  if (debug)
1409  theRec.PrintRecInfo(true);
1410  }
1411 
1412  //--------- Fit stage 2 ( Signal+Time+Constrains, Binomial PDF ) ,
1413  if (theRec.SetFitStage(2)) { // Set GausPDF
1414  Rec(theRec);
1415  if (!theRec.IsGoodRec())
1416  Rec(theRec);
1417  if (theRec.RejectTimeOutliers())
1418  Rec(theRec);
1419  if (!theRec.IsGoodRec())
1420  Rec(theRec);
1421  theRec.PrintRecInfo(true);
1422  }
1423 
1424  //bool WriteStations=true;
1425  //theRec.RWRecinfo(fdataOut,WriteStations,false);
1426 
1427  fittedPars.energy = pow(10., theRec.GetRecInfo()->logE);
1428  fittedPars.energyUnc = pow(10., theRec.GetRecInfo()->logE_err);
1429 
1430  fittedPars.xmax = theRec.GetRecInfo()->Xmax * gpercm2;
1431  fittedPars.xmaxUnc = theRec.GetRecInfo()->Xmax_err * gpercm2;
1432 
1433  fittedPars.Nmu = theRec.GetRecInfo()->Nmu;
1434  fittedPars.NmuUnc = theRec.GetRecInfo()->Nmu_err;
1435 
1436  CoordinateSystemPtr hottestStationCS = LocalCoordinateSystem::Create(fHottestStation->position);
1437  fittedPars.axis = Vector(1, theRec.GetRecInfo()->theta, theRec.GetRecInfo()->azi, hottestStationCS, Vector::kSpherical);
1438  fittedPars.axisUncTheta = 0.; // TODO not implemented
1439  fittedPars.axisUncPhi = 0.; // TODO not implemented
1440 
1441  fittedPars.core = Point(theRec.GetRecInfo()->xgcore * cm, theRec.GetRecInfo()->ygcore * cm, theRec.GetRecInfo()->zgcore * cm - fHottestStationHeight, hottestStationCS);
1442  fittedPars.coreUncX = theRec.GetRecInfo()->xgcore_err * cm;
1443  fittedPars.coreUncY = theRec.GetRecInfo()->ygcore_err * cm;
1444 
1445  fittedPars.coretime = fHottestStation->startTime + TimeInterval(theRec.GetRecInfo()->T0);
1446 
1447  fittedPars.isGoodRec = theRec.IsGoodRec();
1448  }
1449 
1450 
1451  void
1452  UniversalityFitter::SetRecData(evt::Event& event)
1453  {
1454  if (!fittedPars.isGoodRec) {
1455  ostringstream msg;
1456  msg << "No reconstruction, not writing data to event.";
1457  INFO(msg);
1458  return;
1459  }
1460 
1461  if (!event.GetRecShower().HasUnivRecShower())
1462  event.GetRecShower().MakeUnivRecShower();
1463 
1464  ShowerUnivRecData& recShower = event.GetRecShower().GetUnivRecShower();
1465 
1466  CoordinateSystemPtr coreCS = LocalCoordinateSystem::Create(fittedPars.core);
1467  CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
1468 
1469  recShower.SetGoodRec(fittedPars.isGoodRec);
1470 
1471  recShower.SetEnergy(fittedPars.energy, fittedPars.energyUnc);
1472  recShower.SetNmu(fittedPars.Nmu, fittedPars.NmuUnc);
1473  recShower.SetXmax(fittedPars.xmax, fittedPars.xmaxUnc);
1474 
1475  recShower.SetTimeModelOffset(fittedPars.TimeModelOffset, fittedPars.TimeModelOffsetUnc);
1476 
1477  recShower.SetCorePosition(fittedPars.core);
1478  recShower.SetCoreError(Vector(fittedPars.coreUncX, fittedPars.coreUncY, 0, coreCS));
1479  recShower.SetCoreTime(fittedPars.coretime, 0); // TODO coretime error not implemented yet
1480 
1481  recShower.SetAxis(fittedPars.axis);
1482  recShower.SetThetaError(fittedPars.axisUncTheta);
1483  recShower.SetPhiError(fittedPars.axisUncPhi);
1484 
1485  // TODO: add filling of these numbers when Bariloche reco is used
1486  recShower.SetNumberOfShapeCandidates(fittedPars.fNCandShape);
1487  recShower.SetNumberOfStartTimeCandidates(fittedPars.fNCandStartTime);
1488  recShower.SetNumberOfLDFCandidates(fittedPars.fNCandLDF);
1489 
1490  ostringstream msg;
1491  msg << "\nReconstructed shower parameters\n"
1492  "\n"
1493  " energy = " << recShower.GetEnergy() / EeV << " +/- " << recShower.GetEnergyError() / EeV << " [EeV]\n"
1494  " Nmu = " << recShower.GetNmu() << " +/- " << recShower.GetNmuError() << "\n"
1495  " Xmax = " << recShower.GetXmax() / gpercm2 << " +/- " << recShower.GetXmaxError() / gpercm2 << " [g/cm^2]\n"
1496  "\n"
1497  " core = (" << recShower.GetCorePosition().GetX(siteCS) / meter << ", "
1498  << recShower.GetCorePosition().GetY(siteCS) / meter << ", "
1499  << recShower.GetCorePosition().GetZ(siteCS) / meter << ") [m] (site) +/-\n"
1500  " (" << recShower.GetCoreError().GetX(siteCS) / meter << ", "
1501  << recShower.GetCoreError().GetY(siteCS) / meter << ", "
1502  << recShower.GetCoreError().GetZ(siteCS) / meter << ") [m]\n"
1503  "\n"
1504  " theta = " << recShower.GetAxis().GetTheta(coreCS) / degree << " +/- " << recShower.GetThetaError() / degree << " [deg] (core)\n"
1505  " phi = " << NormalizeAngleMinusPiPi(recShower.GetAxis().GetPhi(coreCS)) / degree << " +/- " << recShower.GetPhiError() / degree << " [deg] (core)\n";
1506  INFO(msg);
1507  }
1508 
1509 
1510  void
1511  UniversalityFitter::WriteRecParameters(evt::Event& event)
1512  {
1513  const SEvent& sEvent = event.GetSEvent();
1514  const int sdEventId = sEvent.GetHeader().GetId();
1515 
1516  const CoordinateSystemPtr siteCS = det::Detector::GetInstance().GetReferenceCoordinateSystem();
1517 
1518  const CoordinateSystemPtr coreCS = LocalCoordinateSystem::Create(fittedPars.core);
1519  const double theta = fittedPars.axis.GetTheta(coreCS);
1520  const double phi = fittedPars.axis.GetPhi(coreCS);
1521  const CoordinateSystemPtr showerPlaneCS(
1522  CoordinateSystem::RotationY(
1523  theta,
1524  CoordinateSystem::RotationZ(
1525  phi,
1526  coreCS
1527  )
1528  )
1529  );
1530 
1531  ofstream* textOut = 0;
1532  if (fActiveMethod == "Karlsruhe")
1533  textOut = &fitInfoKG;
1534  else if (fActiveMethod == "Bariloche")
1535  textOut = &fitInfoBG;
1536  else {
1537  cerr << "unknown method" << endl;
1538  exit(1);
1539  }
1540 
1541  *textOut
1542  << format("%i ") % (fittedPars.isGoodRec)
1543  << format("%i ") % (sdEventId)
1544  << format("%i ") % (fEventHasSaturation)
1545 
1546  << format("%.5f ") % (fittedPars.energy / EeV)
1547  << format("%.5f ") % (fittedPars.xmax / gpercm2)
1548  << format("%.5f ") % (fittedPars.Nmu)
1549 
1550  << format("%.5f ") % (fittedPars.core.GetX(showerPlaneCS) / m)
1551  << format("%.5f ") % (fittedPars.core.GetY(showerPlaneCS) / m)
1552 
1553  << format("%.5f ") % (fittedPars.coretime.GetGPSSecond())
1554  << format("%.5f ") % (fittedPars.coretime.GetGPSNanoSecond())
1555 
1556  << format("%.5f ") % (fittedPars.axis.GetTheta(siteCS) / degree)
1557  << format("%.5f ") % (NormalizeAngleMinusPiPi(fittedPars.axis.GetPhi(siteCS)) / degree)
1558  << endl;
1559  }
1560 
1561 
1563  UniversalityFitter::Finish()
1564  {
1565  if (fWriteToTextFile) {
1566  fitInfoKG.close();
1567  fitInfoBG.close();
1568  }
1569 
1570  return eSuccess;
1571  }
1572 
1573 }
bool SetFitStage(int FitStage)
Definition: UnivRec.cc:2145
double GetVEMCharge() const
Definition: PMTRecData.h:130
double GetEnergy() const
RecInfo_t * GetRecInfo()
Definition: UnivRec.h:311
UnivParamTimeNS::UnivParamTime * ftime[nDetectorType]
Definition: UnivRec.h:347
Class to access station level reconstructed data.
RecInfo_t recinfo
Definition: UnivRec.h:326
double tquantile[2][nQ]
Definition: UnivRec.h:216
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.
double quantile[nQ]
Definition: UnivRec.h:216
bool HasUnivRecShower() const
StationIterator StationsEnd()
End of all stations.
Definition: SEvent.h:59
utl::TraceD & GetVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal)
Traces calibrated in VEM Peak.
Definition: PMTRecData.h:46
const utl::TabulatedFunction & GetdEdX() const
Get the energy deposit of the shower.
bool IsSaturated[nDetectorType]
Definition: UnivRec.h:166
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
Definition: MEvent.h:49
const double degree
constexpr T Sqr(const T &x)
void SetAxis(const utl::Vector &axis)
Point object.
Definition: Point.h:32
const utl::TimeStamp & GetTimeStamp() const
Get the TimeStamp of the absolute shower core-time.
double GetRpError() const
Definition: EyeRecData.h:91
bool HasStation(const int stationId) const
Check whether station exists.
Definition: SEvent.cc:81
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
constexpr double cm3
Definition: AugerUnits.h:119
double GetThetaError() const
bool HasMEvent() const
constexpr double kDryAirMolarMass
void InitRecStation(RecStation *station)
Definition: UnivRec.cc:256
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
Definition: FEvent.h:56
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
bool HasFEvent() const
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
double GetChiZero() const
Definition: EyeRecData.h:85
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
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()
AugerRecInfo_t augerinfo
Definition: UnivRec.h:327
unsigned int GetSDPFitNDof() const
Definition: EyeRecData.h:81
bool HasSimShower() const
std::vector< double > trace
Definition: UnivFitterKG.h:52
EyeIterator EyesEnd(const ComponentSelector::Status status)
Definition: FEvent.h:66
unsigned int GetTimeFitNDof() const
Definition: EyeRecData.h:93
const double meter
Definition: GalacticUnits.h:29
const double vemTimeCut[nQ]
Definition: UnivRec.h:97
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
int InitFCNParameters(std::vector< double > &par, std::vector< double > &epar, std::vector< int > &status, std::vector< bool > &hasLimits)
Definition: UnivRec.cc:2333
int GetId() const
Definition: SEvent/Header.h:20
void PrintRecInfo(bool PrintResiduals)
Definition: UnivRec.cc:1272
void SetNumberOfShapeCandidates(const int ncand)
const utl::Point & GetCorePosition() const
utl::Point GetPosition() const
int debug
Definition: dump1090.h:276
const unsigned int npar
Definition: UnivRec.h:75
double GetShowerSize() const
void Init()
Initialise the registry.
Detector description interface for Eye-related data.
Definition: FDetector/Eye.h:45
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
void SetCoreTime(const utl::TimeStamp &coreTime, const utl::TimeInterval &coreTimeErr)
double pow(const double x, const unsigned int i)
int exit
Definition: dump1090.h:237
const double EeV
Definition: GalacticUnits.h:34
int GetYear() const
Definition: UTCDate.h:44
double GetMag() const
Definition: Vector.h:58
unsigned int GPSsec
Definition: UnivRec.h:342
Detector associated to muon detector hierarchy.
Definition: MDetector.h:32
double GetSDPPhiError() const
Definition: EyeRecData.h:78
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.
Definition: SEvent.h:172
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)
Definition: UnivParam.cc:202
double GetChiZeroError() const
Definition: EyeRecData.h:86
const double high[npar]
Definition: UnivRec.h:78
std::vector< double >::const_iterator ConstIterator
Definition: Trace.h:60
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.
Definition: TimeStamp.h:110
utl::Point GetPosition() const
Tank position.
const utl::TimeStamp & GetTime() const
Definition: SEvent/Header.h:19
Iterator Begin()
Definition: Trace.h:75
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
AtmosphereNS::Atmosphere * fatm
Definition: UnivRec.h:348
T Get() const
Definition: Branch.h:271
double ygcore_err
Definition: UnivRec.h:123
Criterion to sort stations by decreasing signal.
Definition: SortCriteria.h:41
void SetNumberOfStartTimeCandidates(const int ncand)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
void ClearRecEvent()
Definition: UnivRec.cc:307
int fd
Definition: dump1090.h:233
double GetXFirst() const
Get depth of first interaction.
double SdEnergyResolution(const double energy)
Class representing a document branch.
Definition: Branch.h:107
unsigned int GetnRecStations()
Definition: UnivRec.h:316
MCInfo_t MCinfo
Definition: UnivRec.h:328
total FADC trace, with no saturation applied by FADC/baseline simulator
void SetGoodRec(const bool isgood)
class to hold reconstructed data at PMT level
Definition: PMTRecData.h:38
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.
Definition: UTMPoint.h:212
const double SmearingAngle
Definition: UnivRec.h:58
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
const double ns
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
const int nTimeStationsMin
Definition: UnivRec.h:108
constexpr double kPi
Definition: MathConstants.h:24
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)
Definition: UnivRec.cc:2413
bool HasFRecShower() const
Check if reconstructed shower info has been allocated.
Definition: EyeRecData.h:330
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
EyeIterator EyesBegin(const ComponentSelector::Status status)
Definition: FEvent.h:58
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.
Definition: ShowerSimData.h:89
std::vector< RecStation_t > fstation
Definition: UnivRec.h:324
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.
Definition: Branch.cc:644
unsigned int GetSignalEndSlot() const
End time of the signal in time slots from beginning of trace.
Top of Fluorescence Detector event hierarchy.
Definition: FEvent.h:33
a second level trigger
Definition: XbT2.h:8
Eye-specific shower reconstruction data.
Definition: EyeRecData.h:65
if(dataRoot)
Definition: XXMLManager.h:1003
double GetEnergyError() const
double GetEnergy() const
void SetThetaError(const double err)
double GetRho(const CoordinateSystemPtr &coordinateSystem) const
radius r in cylindrical coordinates (distance to z axis)
Definition: BasicVector.h:263
int GetMonth() const
Definition: UTCDate.h:46
const double unit[npar]
Definition: UnivRec.h:76
double GetRpChi0Correlation() const
Definition: EyeRecData.h:89
bool HasGHParameters() const
void SetNmu(const double Nmu)
static const double fXmaxSys_Auger[nSys]
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
const double low[npar]
Definition: UnivRec.h:77
double GetPhiError() const
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
InternalCounterCollection::ComponentIterator CounterIterator
Definition: MEvent.h:31
constexpr double kMolarGasConstant
bool gDetectorTypeMask[nDetectorType]
Definition: UnivRec.h:335
static std::unique_ptr< UnivRecNS::UnivRec > gUnivRecNS
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
double AugerDensity
Definition: UnivRec.h:119
StationIterator StationsBegin()
Beginning of all stations.
Definition: SEvent.h:57
void GetXmaxRange(double &Xmax0, double &Xmax1)
Definition: UnivRec.h:319
const int nSignalStationsMin
Definition: UnivRec.h:109
void SetOffsetM_Mu(double Offset)
const std::string ParName[npar]
Definition: UnivRec.h:79
constexpr double cm
Definition: AugerUnits.h:117
total (shower and background)
bool IsDense() const
Tells whether the station belongs to set of hypothetical &quot;dense&quot; stations.
#define UNDEF
Definition: UnivRec.h:24
Vector object.
Definition: Vector.h:30
boost::filter_iterator< PMTFilter, InternalConstPMTIterator > ConstPMTIterator
Iterator over station for read.
Interface class to access to Fluorescence reconstruction of a Shower.
double OffsetM_Mu
Definition: UnivRec.h:140
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
double GetShowerSizeError() const
const double vemSignalCut
Definition: UnivRec.h:101
bool InitRec(bool IsData, int RecType, int CalibOpt, int RecDetector, int RecSys, int RecMixture)
Definition: UnivRec.cc:127
const utl::Vector & GetCoreError() const
CounterConstIterator CountersEnd() const
Definition: MEvent.h:52
const utl::Point & GetCorePosition() const
sevt::Header & GetHeader()
Definition: SEvent.h:155
Main configuration utility.
Definition: CentralConfig.h:51
static std::vector< int > parStatus
void SetTimeModelOffset(const double mmu, const double mmuunc)
bool RejectTimeOutliers()
Definition: UnivRec.cc:2277
int FitStatus[2]
Definition: UnivRec.h:144
void SetCoreError(const utl::Vector &coreerr)
bool InitRecParameters()
Definition: UnivRec.cc:892
double lnP[3]
Definition: UnivRec.h:147
bool IsT5() const
void SetEnergy(const double energy, const double error)
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
void SetPhiError(const double err)
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
const Counter & GetCounter(int id) const
Retrieve Counter by id.
Definition: MDetector.h:68
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
bool HasVEMTrace(const StationConstants::SignalComponent source=StationConstants::eTotal) const
Definition: PMTRecData.h:55
Iterator End()
Definition: Trace.h:76
boost::indirect_iterator< InternalConstStationIterator, const Station & > ConstStationIterator
Definition: SEvent.h:54
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
void SetCorePosition(const utl::Point &core)
bool StationSelection()
Definition: UnivRec.cc:2162
const utl::Vector & GetAxis() const
constexpr double gram
Definition: AugerUnits.h:195
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
double GetVEMPeak() const
Definition: PMTRecData.h:119
Root of the Muon event hierarchy.
Definition: MEvent.h:25
bool IsT4() const
mu+ and mu- (including signal from mu decay electrons) from shower
bool HasSEvent() const
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]
double xgcore_err
Definition: UnivRec.h:122
const double gpercm2
Definition: FitterUtil.h:9
const int nQ
Definition: UnivRec.h:70
const atm::ProfileResult & EvaluateTemperatureVsHeight() const
Tabulated function giving Y=temperature as a function of X=height.
double GetXmaxMu() const
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.
constexpr double cm2
Definition: AugerUnits.h:118
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.

, generated on Tue Sep 26 2023.