MdLDFFinder.cc
Go to the documentation of this file.
1 #include "MdLDFFinder.h"
2 #include "KascadeGrandeLDF.h"
3 #include "Likelihood.h"
4 #include "Likelihood2.h"
5 #include "Likelihood3.h"
6 //
7 #include <evt/Event.h>
8 #include <evt/ShowerRecData.h>
9 #include <evt/ShowerSRecData.h>
10 #include <evt/ShowerMRecData.h>
11 //
12 #include <mevt/MEvent.h>
13 #include <mevt/Counter.h>
14 #include <mevt/Module.h>
15 #include <mevt/ModuleRecData.h>
16 //
17 #include <fwk/CentralConfig.h>
18 #include <utl/ConsecutiveEnumFactory.h>
19 #include <utl/AugerUnits.h>
20 #include <utl/Branch.h>
21 #include <utl/ConfigUtils.h>
22 #include <fwk/RunController.h>
23 //
24 #include <fwk/LocalCoordinateSystem.h>
25 #include <utl/ErrorLogger.h>
26 #include <utl/CoordinateSystem.h>
27 #include <utl/PhysicalConstants.h>
28 #include <utl/PhysicalFunctions.h>
29 #include <utl/AxialVector.h>
30 #include <utl/Math.h>
31 #include <utl/UTMPoint.h>
32 #include <utl/ReferenceEllipsoid.h>
33 #include <utl/TabulatedFunctionErrors.h>
34 #include <utl/Line.h>
35 //
36 #include <Minuit2/FunctionMinimum.h>
37 #include <Minuit2/MnUserParameterState.h>
38 #include <Minuit2/MnUserCovariance.h>
39 #include <boost/iterator/transform_iterator.hpp>
40 #include <string>
41 #include <iostream>
42 #include <vector>
43 #include <sstream>
44 
45 using namespace fwk;
46 using namespace evt;
47 using std::cout;
48 using std::endl;
49 
50 
51 namespace MdLDFFinderAG {
52 
53 const char* const MdLDFFinder::kLDFTags[] = { "KascadeGrande", "ToBeDef_I", "ToBeDef_II" };
54 
55 const char* const MdLDFFinder::kMinMethodTags[] = { "Likelihood", "Likelihood2", "Likelihood3" };
56 
57 
58 MdLDFFinder::MdLDFFinder()
59 { }
60 
61 
62 MdLDFFinder::~MdLDFFinder()
63 { }
64 
65 
68 {
69  // Configuration reading.
70  utl::Branch config = fwk::CentralConfig::GetInstance()->GetTopBranch("MdLDFFinder");
71  std::string tag;
72 
73  LoadConfig(config, "ldfType", tag, kLDFTags[0]);//default LDF
74  //Creates enumeration from tags
76 
77  //LDF Parameter
78  LoadConfig(config, "referenceDistance", fReferenceDistance, 450*utl::m );
79 
80  LoadConfig(config, "a0", fA0, 3.00 );
81  LoadConfig(config, "a1", fA1, -1.00 );
82  LoadConfig(config, "a2", fA2, 0.00 );
83 
84  //Fitting and minimization methods
85  LoadConfig(config, "minMethodType", tag, kMinMethodTags[0]);//default MinMethod
86  //Creates enumeration from tags
88 
89  LoadConfig(config, "useSilentCounters",fUseSilent, true);
90  LoadConfig(config, "silentLimit", fSilentLimit, 2 );
91 
92  LoadConfig(config, "useSaturatedCounters",fUseSaturated, false);
93  LoadConfig(config, "saturationLimit", fSaturationLimit, 64);
94 
95  //Minimum Number of good stations to fix beta in the MLDF fit
96  LoadConfig(config, "fixBeta", fFixBeta, false );
97  LoadConfig(config, "countersToFixBeta", fCountersToFixBeta, 5);
98 
99  //Criteria to fix or relax beta
100  //(half those corresponding to regular array)
101  //Range where counters are considered
102  LoadConfig(config, "LowLimToRelaxBeta", fLowLimToRelaxBeta, 500*utl::m/2);
103  LoadConfig(config, "UppLimToRelaxBeta", fUppLimToRelaxBeta, 1500*utl::m/2);
104  //Distances between counters (depending on the number of counters)
105  LoadConfig(config, "CounterSpacings1", fCounterSpacings1, 500*utl::m/2 );
106  LoadConfig(config, "CounterSpacings2", fCounterSpacings2, 400*utl::m/2 );
107  LoadConfig(config, "CounterSpacings3", fCounterSpacings3, 300*utl::m/2 );
108 
109  LoadConfig(config, "fixCoreFromSd", fFixCoreFromSd, 0 );
110 
111  // Init according to selected LDF.
112  switch (fLDFType) {
113  case eKascadeGrande:
114  fLDF.reset( new KascadeGrandeLDF(fReferenceDistance) );
115  break;
116  default:
117  ERROR("LDF UNDEFINED");
118  return eFailure;
119  //fLDF.reset( new Undefined_I() );
120  break;
121  }
122 
123  // Init according to selected MinMethod.
124  switch (fMinMethodType) {
125  case eLikelihood:
126  INFO("Original likelihood will be used");
127  fMinimizer.reset( new Likelihood( fLDF.get(), fUseSilent, fSilentLimit, fUseSaturated, fSaturationLimit) );
128  break;
129  case eLikelihood2:
130  INFO("Profile likelihood will be used");
131  fMinimizer.reset( new Likelihood2(fLDF.get(), fUseSilent, fSilentLimit) );
132  break;
133  case eLikelihood3:
134  INFO("Infinite window likelihood will be used");
135  fMinimizer.reset( new Likelihood3(fLDF.get(), fUseSilent, fSilentLimit, fUseSaturated) );
136  break;
137  }
138 
139  mDetector = &(det::Detector::GetInstance().GetMDetector());
140  siteCS = det::Detector::GetInstance().GetSiteCoordinateSystem();
141 
142  return eSuccess;
143 }
144 
145 
147 MdLDFFinder::Run(evt::Event& event)
148 {
149  std::ostringstream info("");
150 
151  INFO("Starting the muon LDF reconstruction");
152 
153  // nothing to do if there is no RecShower
154  if (!(event.HasRecShower() &&
155  event.GetRecShower().HasSRecShower()) ) {
156  ERROR("Current event does not have a recontructed shower.");
157  return eContinueLoop;
158  }
159 
160  if (!event.HasMEvent()) {
161  ERROR("Current event does not have an MD event.");
162  return eContinueLoop;
163  }
164 
165  // Pass core position and shower axis from SD reconstruction to minimizer
166  const ShowerSRecData& sRecShower = event.GetRecShower().GetSRecShower() ;
167  const utl::Point& sdCore = sRecShower.GetCorePosition();
168  const utl::Vector& sdAxis = sRecShower.GetAxis();
169 
170  info.str("");
171  info << "Core = (" << sdCore.GetX(siteCS) << ", " << sdCore.GetY(siteCS) << ", " << sdCore.GetZ(siteCS) << ")";
172  DEBUGLOG(info.str());
173 
174  // Select counters with data
175  mevt::MEvent& me = event.GetMEvent();
176  const mdet::MDetector& mDetector = det::Detector::GetInstance().GetMDetector();
177 
178  // Filling modules SP distances
179  FillModulesShowerPlaneDistances(sRecShower, mDetector, me);
180 
181  CounterList fCandidateCounters = SelectCandidateCounters(me);
182 
183  info.str("");
184  info << "candidate counters = " << fCandidateCounters.size();
185  DEBUGLOG(info.str());
186 
187  info.str("");
188  info << "Candidate counters: " << fCandidateCounters;
189  DEBUGLOG(info.str());
190 
191  // Select silent counters
192  CounterList fSilentCounters = SelectSilentCounters(me);
193 
194  // Estimate initial values of rho0 and beta
195  double rho0Seed = CalculateRho0Seed( fCandidateCounters, sdCore, sdAxis );
196  double rho0SeedError = .5*rho0Seed; // using some gross estimate...
197 
198  // Define a coordinate system centered in the core reconstructed by the SD
200 
201  info.str("");
202  info << "Core = (" << sdCore.GetX(sdCoreCS) << ", " << sdCore.GetY(sdCoreCS) << ", " << sdCore.GetZ(sdCoreCS) << ")" << std::endl;
203  info << " theta = " << sdAxis.GetTheta(sdCoreCS)/utl::deg << " [deg]\n";
204  DEBUGLOG(info.str());
205 
206  size_t numberOfFitParameters = 4; // rho0, beta, xcore, ycore
207 
208  std::vector<double> fPars(numberOfFitParameters); // Estimators
209  std::vector<double> fErrPars(numberOfFitParameters); // Errors
210  std::vector<bool> fFlagPars(numberOfFitParameters); // Fix/free parameter flags
211 
212  fPars.at(VMinMethodFunctor::eShowerSize) = rho0Seed;
213  fErrPars.at(VMinMethodFunctor::eShowerSize) = rho0SeedError;
214  fFlagPars.at(VMinMethodFunctor::eShowerSize) = false;
215 
216  double betaSeed = CalculateBeta( sdAxis.GetTheta(sdCoreCS) );
217  //Criteria to fix beta in this event
218  bool fFixBetaEvent = FixBetaFlag( fCandidateCounters, sdCore, sdAxis );
219 
220  fPars.at(VMinMethodFunctor::eBeta) = betaSeed;
221  fErrPars.at(VMinMethodFunctor::eBeta) = 0; //TO-DO: add error in axis (by means of cos(theta)) recontruction
222  fFlagPars.at(VMinMethodFunctor::eBeta) = fFixBetaEvent;
223 
224  // Set the initical core as the SD core
225  double xcore = sdCore.GetX(siteCS); // referred to the siteCS as the counters
226  double ycore = sdCore.GetY(siteCS);
227  double zcore = sdCore.GetZ(siteCS);
228 
229  fPars.at(VMinMethodFunctor::eCoreX) = xcore;
230  fErrPars.at(VMinMethodFunctor::eCoreX) = 100;
231  fFlagPars.at(VMinMethodFunctor::eCoreX) = fFixCoreFromSd;
232 
233  ycore = sdCore.GetY(siteCS);
234  fPars.at(VMinMethodFunctor::eCoreY) = ycore;
235  fErrPars.at(VMinMethodFunctor::eCoreY) = 100;
236  fFlagPars.at(VMinMethodFunctor::eCoreY) = fFixCoreFromSd;
237 
238  // Configure the minimizer
239  fMinimizer->SetZcore(zcore);
240  fMinimizer->SetAxis(sdAxis);
241  fMinimizer->SetCandidateCounterList(fCandidateCounters);
242  fMinimizer->SetSilentCounterList(fSilentCounters);
243 
244  // Run the minimization
245  ROOT::Minuit2::FunctionMinimum functionMinimum = fMinimizer->Minimize(fPars, fErrPars, fFlagPars);
246 
247  if (!functionMinimum.IsValid()) {
248  ERROR("MD reconstruction failed");
249  std::cerr << functionMinimum << endl;
250  ++RunController::GetInstance().GetRunData().GetNamedCounters()["MdLDFFinder/Failed"];
251  return eContinueLoop;
252  }
253 
254  if (!functionMinimum.HasValidCovariance()) {
255  ERROR("MD reconstruction: invalid covariance matrix");
256  std::cerr << functionMinimum << endl;
257  ++RunController::GetInstance().GetRunData().GetNamedCounters()["MdLDFFinder/Failed"];
258  return eContinueLoop;
259  }
260 
261  ++RunController::GetInstance().GetRunData().GetNamedCounters()["MdLDFFinder/Reconstructed"];
262 
263  // Fill the event with reconstructed data
264  if (!(event.GetRecShower().HasMRecShower()) )
265  event.GetRecShower().MakeMRecShower();
266 
267  ShowerMRecData& mRecShower = event.GetRecShower().GetMRecShower();
268 
269  if (!mRecShower.HasMLDF())
270  mRecShower.MakeMLDF();
271 
272  FillReconstructedParameters(mRecShower, functionMinimum.UserState(), zcore);
273 
274  mRecShower.SetLdfReconstructed(true);
275  mRecShower.SetReferenceDistance( fReferenceDistance );
276  //mRecShower.SetAxis(sdAxis);
277  mRecShower.SetReferenceAxis(sdAxis);
278  mRecShower.SetReferenceCorePosition(sdCore);
279 
280 
281  // Set the residuals and calculate the chi2
282  SetLdfResiduals(fCandidateCounters, fPars, sdCore, sdAxis);
283  double chi2 = CalculateChi2(fCandidateCounters, fPars, sdCore, sdAxis);
284  size_t ndof = CalculateDegreesOfFreedom(fCandidateCounters, fFlagPars);
285  mRecShower.SetMLDFChi2(chi2, ndof);
286 
287  // Set the likelihood (using the -log likelihood!)
288  const double nlnLikelihood = fMinimizer->operator()(fPars);
289  mRecShower.SetMLDFLikelihood(nlnLikelihood);
290 
291  FillTabulatedFunction( mRecShower, fPars, fErrPars );
292 
293  return eSuccess;
294 }
295 
296 
298  MdLDFFinder::Finish()
299 {
300  return eSuccess;
301 }
302 
303 
304 // Private methods
305 
306 bool
307 MdLDFFinder::FixBetaFlag( const CounterList counters, const utl::Point& rCore, const utl::Vector& rAxis )
308  const
309 {
310  std::ostringstream info;
311 
312  if (fFixBeta || counters.size() < fCountersToFixBeta) { // if fix beta specified in the input
313  info.str("");
314  info << "Fixing Beta (" << counters.size() << " counters when at least "
315  << fCountersToFixBeta << " are required)";
316  INFO(info);
317  return true;
318  }
319 
320  typedef CounterList::const_iterator CIt;
321 
322  int nCountersInRange = 0;
323  double maxDistance = 0;
324 
325  info.str("");
326  info << "Core = (" << rCore.GetX(siteCS) << ", " << rCore.GetY(siteCS) << ", " << rCore.GetZ(siteCS) << ')';
327  DEBUGLOG(info);
328 
329  for (CIt ci = counters.begin(), cend = counters.end(); ci != cend; ++ci) {
330 
331  const unsigned int counterId_i = (*ci)->GetId();
332  const utl::Point& position_i = mDetector->GetCounter(counterId_i).GetPosition();
333 
334  const double rho_i = utl::Cross(rAxis, position_i - rCore).GetMag();
335 
336  info.str("");
337  info << "counter " << (*ci)->GetId() << ", position = ("
338  << position_i.GetX(siteCS) / utl::m << ", "
339  << position_i.GetY(siteCS) / utl::m << ", "
340  << position_i.GetZ(siteCS) / utl::m << ") m"
341  << ", distance to core = " << rho_i;
342  DEBUGLOG(info);
343 
344  if (fLowLimToRelaxBeta < rho_i && rho_i < fUppLimToRelaxBeta) {
345  ++nCountersInRange;
346  for (CIt cj = ci+1; cj != cend; ++cj) {
347 
348  const unsigned int counterId_j = (*cj)->GetId();
349  const utl::Point& position_j = mDetector->GetCounter(counterId_j).GetPosition();
350 
351  const double rho_j = utl::Cross(rAxis, position_j - rCore).GetMag();
352 
353  if (fLowLimToRelaxBeta < rho_j && rho_j < fUppLimToRelaxBeta) {
354  const double distance = std::abs(rho_i - rho_j);
355  if (distance > maxDistance)
356  maxDistance = distance;
357  }
358  } // end loop cj
359  } // end if
360 
361  } // end loop ci
362 
363  const bool rvalue = !(
364  (nCountersInRange > 1 && maxDistance > fCounterSpacings1) ||
365  (nCountersInRange > 2 && maxDistance > fCounterSpacings2) ||
366  (nCountersInRange > 3 && maxDistance > fCounterSpacings3)
367  );
368 
369  info.str("");
370  info << "Using " << (rvalue?"fixed":"free") << " beta in the LDF fit "
371  << "nCountersInRange " << nCountersInRange << " (out of " << counters.size() << ")\n"
372  << "maxDistance " << maxDistance/utl::m << " m";
373  INFO(info);
374 
375  return rvalue;
376 }
377 
378 
379 void
380 MdLDFFinder::FillTabulatedFunction(evt::ShowerMRecData& mRecShower,
381  const std::vector<double>& fPars,
382  const std::vector<double>& /*fErrPars*/)
383 {
384  std::ostringstream info("");
385 /*
386  info << "Pars -- Errors\n";
387  std::vector<double>::const_iterator it1, it2;
388  for ( it1=fPars.begin(), it2=fErrPars.begin(); it1!=fPars.end() && it2!=fErrPars.end(); ++it1, ++it2 ) {
389  info << *it1 << " +/- " << *it2 << std::endl;
390  }
391  DEBUGLOG(info.str());
392 */
393  utl::TabulatedFunctionErrors& tabulatedMLDF = mRecShower.GetMLDF();
394  tabulatedMLDF.Clear();
395 
396  const double minRho = 50*utl::m;
397  const double maxRho = 3500*utl::m;
398 
399  const int nMLDFPoints = 250;
400  const double dRho = (maxRho - minRho) / (nMLDFPoints - 1);
401 
402  for (int i = 0; i < nMLDFPoints; ++i) {
403  const double rho = minRho + i*dRho;
404  const double Nmu_r =(*fLDF)(rho, &fPars[0]);
405  const double sigma = sqrt(Nmu_r);
406  tabulatedMLDF.PushBack(rho, 0, Nmu_r, sigma);
407  }
408 }
409 
410 
411 void
412 MdLDFFinder::FillReconstructedParameters(evt::ShowerMRecData& mRecShower,
413  const ROOT::Minuit2::MnUserParameterState& MnParState,
414  double zcore)
415 {
416  //DEBUGLOG("");
417  //std::cout << MnParState << std::endl;
418 
419  // Retrieve parameter and errors from Minuit
420  const std::vector<ROOT::Minuit2::MinuitParameter> minuitParameters(MnParState.MinuitParameters());
421  //std::vector<double> fPars(MnParState.Params());
422  //std::vector<double> fErrPars(MnParState.Errors());
423 
424  // Muon density
425  double muonDensity0 = minuitParameters[VMinMethodFunctor::eShowerSize].Value();
426  double muonDensity0Error = minuitParameters[VMinMethodFunctor::eShowerSize].Error();
427  mRecShower.SetNMuRef(muonDensity0, muonDensity0Error);
428 
429  // LDF slope
430  const double beta = minuitParameters[VMinMethodFunctor::eBeta].Value();
431  if (minuitParameters[VMinMethodFunctor::eBeta].IsFixed()) {
432  mRecShower.SetBetaFixed(true);
433  mRecShower.SetBeta(beta);
434  } else {
435  mRecShower.SetBetaFixed(false);
436  const double betaError = minuitParameters[VMinMethodFunctor::eBeta].Error();
437  mRecShower.SetBeta(beta,betaError);
438  }
439 
440  // Core position
441  const double xcore = minuitParameters[VMinMethodFunctor::eCoreX].Value();
442  const double ycore = minuitParameters[VMinMethodFunctor::eCoreY].Value();
443  const utl::Point core = utl::Point(xcore, ycore, zcore, siteCS);
444  // mRecShower.SetCorePosition(core);
445 
446  // Filling the core position from the MLDF minimizer only if it was left as free paramerter (ie if a geometry reconstruction was done with UMD)
447  // To acces the sd core position use fReferenceCore
448  if (mRecShower.IsGeometryReconstructed()) {
449  mRecShower.SetCorePosition(core);
450  }
451 
452  if (minuitParameters[VMinMethodFunctor::eCoreX].IsFixed()) {
453 
454  mRecShower.SetCoreFixedLdf(true);
455 
456  } else {
457 
458  mRecShower.SetCoreFixedLdf(false);
459 
460  // Core errors
461  const double xcoreError = minuitParameters[VMinMethodFunctor::eCoreX].Error();
462  const double ycoreError = minuitParameters[VMinMethodFunctor::eCoreY].Error();
463  const double zcoreError = 0; // approximate core altitude by barycenter
464  const utl::Vector coreError = utl::Vector(xcoreError, ycoreError, zcoreError, siteCS);
465  mRecShower.SetCoreError(coreError);
466 
467  // Core xy correlation
468  const ROOT::Minuit2::MnUserCovariance covarianceMatrix = MnParState.Covariance();
469  unsigned int xcoreIndex = GetFreeParIndex(minuitParameters, VMinMethodFunctor::eCoreX);
470  unsigned int ycoreIndex = GetFreeParIndex(minuitParameters, VMinMethodFunctor::eCoreY);
471  const double covaxx = covarianceMatrix(xcoreIndex,xcoreIndex);
472  const double covayy = covarianceMatrix(ycoreIndex,ycoreIndex);
473  const double covaxy = covarianceMatrix(xcoreIndex,ycoreIndex);
474  const double correlationXY = covaxy / sqrt(covaxx*covayy);
475  mRecShower.SetCorrelationXY(correlationXY);
476 
477  } // end if
478 
479 }
480 
481 
482 unsigned int
483 MdLDFFinder::GetFreeParIndex(const std::vector<ROOT::Minuit2::MinuitParameter> minuitParameters,
484  unsigned int globalIndex)
485  const
486 {
487  // check boundaries
488  assert(globalIndex<minuitParameters.size());
489 
490  int freeParIndex = -1;
491  for (unsigned int i=0; i<=globalIndex; ++i) {
492  if(!minuitParameters[i].IsFixed()) {
493  freeParIndex++;
494  }
495  }
496 
497  assert(freeParIndex>=0);
498 
499  return freeParIndex;
500 }
501 
502 
503 double
504 MdLDFFinder::CalculateBeta(double theta)
505  const
506 {
507  return fA0 + fA1/cos(theta) + fA2/pow(cos(theta),2);
508 }
509 
510 
511 double
512 MdLDFFinder::CalculateRho0Seed(const CounterList counters, const utl::Point rCore,
513  const utl::Vector rAxis )
514  const
515 {
516 
517  double minDist = std::numeric_limits<double>::max();
518 
519  mevt::Counter* nearestCounter = 0;
520 
521  // find the counter closest to the reference distance
522  for (CounterList::const_iterator ic = counters.begin(); ic != counters.end(); ++ic) {
523 
524  mevt::Counter* co = *ic;
525 
526  unsigned int counterId = co->GetId();
527  utl::Point counterPosition = mDetector->GetCounter(counterId).GetPosition();
528 
529  double distanceToCore = cross(rAxis, counterPosition - rCore).GetMag();
530 
531  double distanceToR0 = fabs(fReferenceDistance - distanceToCore);
532 
533  if (distanceToR0<minDist) {
534  nearestCounter = co;
535  }
536 
537  }
538 
539  double density = nearestCounter->GetMuonDensity();
540 
541  // minimal density to be used as a seed - avoids reconstruction issues with seed density=0
542  const double minSeedDensity = 0.05;
543 
544  density = ( density>minSeedDensity? density : minSeedDensity);
545 
546 
547  return density;
548 }
549 
550 
552 MdLDFFinder::SelectSilentCounters(mevt::MEvent& me)
553 {
554  CounterList fSilentCounters;
555 
556  // Populate the list of candidate modules and silent counters
557  for (mevt::MEvent::CounterIterator ic = me.CountersBegin(), ec = me.CountersEnd();
558  ic != ec; ++ic) {
559 
560  if (ic->IsSilent()) {
561  fSilentCounters.push_back(&(*ic));
562  }
563 
564  } // end counter loop
565 
566  return fSilentCounters;
567 }
568 
569 
571 MdLDFFinder::SelectCandidateCounters(mevt::MEvent& me)
572 {
573  CounterList fCandidateCounters;
574 
575  // Populate the list of candidate modules and silent counters
576  for (mevt::MEvent::CounterIterator ic = me.CountersBegin(), ec = me.CountersEnd();
577  ic != ec; ++ic) {
578 
579  if (ic->IsCandidate()) {
580  if (fMinMethodType == eLikelihood ){//This check is not necessary in ProfileLikelihood case
581  // Loop over the modules to check user defined saturation limit (different from hardaware imposed limit by segmentation)
582  for (mevt::Counter::ModuleIterator im = ic->ModulesBegin(); im != ic->ModulesEnd(); ++im) {
583  if(!im->IsCandidate()) {// skip non candidate modules
584  continue;
585  }
586  size_t maxWindowsOn = im->GetRecData().GetMaxChannelsOn();
587  im->GetRecData().SetSaturationFlag( ((im->GetRecData().IsSaturated()||maxWindowsOn>=fSaturationLimit) ? true : false) );
588  }//end if on modules
589  }//end if likelihood
590  fCandidateCounters.push_back(&(*ic));
591  }
592 
593  } // end counter loop
594 
595  return fCandidateCounters;
596 }
597 
598 
599 void
600 MdLDFFinder::SetLdfResiduals(CounterList counters, const std::vector<double> parameters,
601  const utl::Point rCore, const utl::Vector rAxis)
602  const
603 {
604  // Get the cosine of the zenith angle in the core coordinate system
606  const double cosTheta = rAxis.GetCosTheta(coreCS);
607 
608  for (CounterList::const_iterator ic = counters.begin(); ic != counters.end(); ++ic) {
609 
610  mevt::Counter* co = *ic;
611 
612  unsigned int counterId = co->GetId();
613  const mdet::Counter& mdetCounter = mDetector->GetCounter(counterId);
614 
615  // Loop over the modules
616  for (mevt::Counter::ModuleIterator im = co->ModulesBegin(); im != co->ModulesEnd(); ++im) {
617  if(im->IsCandidate() && !im->GetRecData().IsSaturated()) {
618 
619  unsigned int moduleId = im->GetId();
620  const mdet::Module& mdetModule = mdetCounter.GetModule(moduleId);
621 
622  const utl::Point r_i = mdetModule.GetPosition();
623  double distanceToCore = cross( rAxis, r_i - rCore ).GetMag();
624 
625  //density of muons from the ldf
626  double ldfDensity = (*fLDF)( distanceToCore, &parameters[0] );
627 
628  // density of muons from the module data corrected by zenith angle
629  double dataDensity = im->GetRecData().GetMuonDensity() / cosTheta;
630 
631  // simple chi2 like residual
632  double residual = (dataDensity - ldfDensity);
633 
634  im->GetRecData().SetLDFResidual(residual);
635  }
636  } // end module loop
637 
638  } // end counter loop
639 }
640 
641 
642 double
643 MdLDFFinder::CalculateChi2(const CounterList counters, const std::vector<double> parameters,
644  const utl::Point rCore, const utl::Vector rAxis)
645  const
646 {
647  double chi2(0);
648 
649  // Get the cosine of the zenith angle in the core coordinate system
651  const double cosTheta = rAxis.GetCosTheta(coreCS);
652 
653  for (CounterList::const_iterator ic = counters.begin(); ic != counters.end(); ++ic) {
654 
655  const mevt::Counter* co = *ic;
656 
657  unsigned int counterId = co->GetId();
658  const mdet::Counter& mdetCounter = mDetector->GetCounter(counterId);
659 
660  // Loop over the modules
661  for (mevt::Counter::ModuleConstIterator im = co->ModulesBegin(); im != co->ModulesEnd(); ++im) {
662  if(im->IsCandidate() && !im->GetRecData().IsSaturated()) {
663 
664  unsigned int moduleId = im->GetId();
665  const mdet::Module& mdetModule = mdetCounter.GetModule(moduleId);
666 
667  const utl::Point r_i = mdetModule.GetPosition();
668  double distanceToCore = cross( rAxis, r_i - rCore ).GetMag();
669 
670  //number of muons from the ldf
671  double ldfDensity = (*fLDF)( distanceToCore, &parameters[0] );
672  double moduleArea = im->GetRecData().GetActiveArea();
673  double ldfMuons = ldfDensity*moduleArea*cosTheta;
674 
675  //number of muons from the module data
676  double measuredMuons = im->GetRecData().GetNumberOfEstimatedMuons();
677 
678  double dMuons = measuredMuons-ldfMuons;
679  chi2 += dMuons*dMuons/ldfMuons;
680 
681 // Debug
682 // DEBUGLOG("");
683 // cout << "Module " << co->GetId() << "-" << im->GetId() << ", measured = " << measuredMuons;
684 // cout << ", expected = " << ldfMuons << ", chi2 = " << dMuons*dMuons/ldfMuons << endl;
685 
686  }
687  } // end module loop
688 
689  } // end counter loop
690 
691  return chi2;
692 }
693 
694 
695 size_t
696 MdLDFFinder::CalculateDegreesOfFreedom(const CounterList counters, const std::vector<bool> parameterFlags)
697  const
698 {
699  size_t ndof(0);
700 
701  for (CounterList::const_iterator ic = counters.begin(); ic != counters.end(); ++ic) {
702 
703  const mevt::Counter* co = *ic;
704 
705  // Loop over the modules
706  for (mevt::Counter::ModuleConstIterator im = co->ModulesBegin(); im != co->ModulesEnd(); ++im)
707  if (im->IsCandidate() && !im->GetRecData().IsSaturated()) {
708  ++ndof;
709  } // end module loop
710  } // end counter loop
711 
712  // count the number of free parameters
713  const size_t nFitParameters = std::count(parameterFlags.begin(),parameterFlags.end(), false);
714 
715  // substract the number of fit parameters to the number of degree of freedom
716  ndof -= nFitParameters;
717 
718  return ndof;
719 }
720 
721 void
722 MdLDFFinder::FillModulesShowerPlaneDistances(const ShowerSRecData& sRecShower, const mdet::MDetector& mdet, mevt::MEvent& me)
723 {
724  const utl::CoordinateSystemPtr sdShowerCS = sRecShower.GetShowerCoordinateSystem();
725 
726  for (mevt::MEvent::CounterIterator cIt = me.CountersBegin(); cIt != me.CountersEnd(); ++cIt) {
727  int cId = cIt->GetId();
728  const mdet::Counter& cDet = mdet.GetCounter(cId);
729  for (mevt::Counter::ModuleIterator mIt = cIt->ModulesBegin(); mIt != cIt->ModulesEnd(); ++mIt) {
730  if (!mIt->HasRecData())
731  continue;
732  int mId = mIt->GetId();
733  const mdet::Module& mDet = cDet.GetModule(mId);
734  const utl::Point& mPosition = mDet.GetPosition();
735  const double r = mPosition.GetRho(sdShowerCS);
736  mevt::ModuleRecData& mRecData = mIt->GetRecData();
737  mRecData.SetSPDistance(r);
738 
739  }
740  }
741 
742 }
743 
744 
745 } // end namespace MdLDFFinderAG
746 
AxialVector cross(const Vector &l, const Vector &r)
vector cross product
Definition: OperationsAV.h:32
Module level reconstruction data. This class contains all data required by the muon reconstruction...
Definition: ModuleRecData.h:29
AxialVector Cross(const Vector &l, const Vector &r)
Definition: OperationsAV.h:25
void SetReferenceCorePosition(const utl::Point &core)
void SetLdfReconstructed(bool flag=true)
void SetReferenceDistance(double rd)
const Module & GetModule(const int mId) const
Retrieve by id a constant module.
CounterConstIterator CountersBegin() const
Definition: MEvent.h:49
Point object.
Definition: Point.h:32
bool HasMEvent() const
static EnumType Create(const int k)
int version of the overloaded creation method.
Interface class to access to the SD Reconstruction of a Shower.
Counter level event data.
bool HasRecShower() const
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
void SetReferenceAxis(const utl::Vector &axis)
void SetCoreFixedLdf(bool flag)
ShowerRecData & GetRecShower()
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
Definition: BasicVector.h:251
void SetCoreError(const utl::Vector &coreerr)
double GetMag() const
Definition: AxialVector.h:56
Functor implementing LDF. Corner-clipping correction and noise included in the likelihood.
Definition: Likelihood3.h:26
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
utl::Point GetPosition() const
void Init()
Initialise the registry.
double Likelihood(double *pars)
double pow(const double x, const unsigned int i)
Detector associated to muon detector hierarchy.
Definition: MDetector.h:32
const utl::CoordinateSystemPtr & GetShowerCoordinateSystem() const
origin = GetCore(), z-axis = GetAxis(), x-axis = upstream
constexpr double deg
Definition: AugerUnits.h:140
void SetBetaFixed(bool flag=true)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define max(a, b)
double GetMuonDensity() const
The density measured by a counter is the calculated as the number of estimated muons over the active ...
Class representing a document branch.
Definition: Branch.h:107
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
const utl::TabulatedFunctionErrors & GetMLDF() const
double abs(const SVector< n, T > &v)
#define DEBUGLOG(message)
Macro for logging debugging messages.
Definition: ErrorLogger.h:157
Array of Scintillator.
void SetCorePosition(const utl::Point &core)
const utl::Vector & GetAxis() const
void SetSPDistance(const double r)
void PushBack(const double x, const double xErr, const double y, const double yErr)
bool HasMRecShower() const
InternalModuleCollection::ComponentIterator ModuleIterator
ModuleConstIterator ModulesBegin() const
Root detector of the muon detector hierarchy.
double GetRho(const CoordinateSystemPtr &coordinateSystem) const
radius r in cylindrical coordinates (distance to z axis)
Definition: BasicVector.h:263
Functor implementing LDF.
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
int GetId() const
The id of the counter.
ModuleConstIterator ModulesEnd() const
InternalCounterCollection::ComponentIterator CounterIterator
Definition: MEvent.h:31
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
void LoadConfig(const utl::Branch &b, const std::string &tag, T1 &var, const T2 &defaultValue)
Helper method to load a particular configuration parameter.
Definition: ConfigUtils.h:35
Vector object.
Definition: Vector.h:30
bool HasMLDF() const
CounterConstIterator CountersEnd() const
Definition: MEvent.h:52
InternalModuleCollection::ComponentConstIterator ModuleConstIterator
const utl::Point & GetCorePosition() const
void SetNMuRef(const double NMuRef, const double error)
int GetId() const
The id of this component.
Interface class to access to the Muon Reconstruction of a Shower.
void SetBeta(const double beta, const double error=0)
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
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.
void SetCorrelationXY(double corr)
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
Root of the Muon event hierarchy.
Definition: MEvent.h:25
void SetMLDFLikelihood(const double likelihood)
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
void SetMLDFChi2(const double chi2, const double ndof)
bool IsGeometryReconstructed() const

, generated on Tue Sep 26 2023.