8 #include <evt/ShowerRecData.h>
9 #include <evt/ShowerSRecData.h>
10 #include <evt/ShowerMRecData.h>
12 #include <mevt/MEvent.h>
13 #include <mevt/Counter.h>
14 #include <mevt/Module.h>
15 #include <mevt/ModuleRecData.h>
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>
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>
31 #include <utl/UTMPoint.h>
32 #include <utl/ReferenceEllipsoid.h>
33 #include <utl/TabulatedFunctionErrors.h>
36 #include <Minuit2/FunctionMinimum.h>
37 #include <Minuit2/MnUserParameterState.h>
38 #include <Minuit2/MnUserCovariance.h>
39 #include <boost/iterator/transform_iterator.hpp>
51 namespace MdLDFFinderAG {
53 const char*
const MdLDFFinder::kLDFTags[] = {
"KascadeGrande",
"ToBeDef_I",
"ToBeDef_II" };
55 const char*
const MdLDFFinder::kMinMethodTags[] = {
"Likelihood",
"Likelihood2",
"Likelihood3" };
58 MdLDFFinder::MdLDFFinder()
62 MdLDFFinder::~MdLDFFinder()
73 LoadConfig(config,
"ldfType", tag, kLDFTags[0]);
85 LoadConfig(config,
"minMethodType", tag, kMinMethodTags[0]);
89 LoadConfig(config,
"useSilentCounters",fUseSilent,
true);
90 LoadConfig(config,
"silentLimit", fSilentLimit, 2 );
92 LoadConfig(config,
"useSaturatedCounters",fUseSaturated,
false);
93 LoadConfig(config,
"saturationLimit", fSaturationLimit, 64);
96 LoadConfig(config,
"fixBeta", fFixBeta,
false );
97 LoadConfig(config,
"countersToFixBeta", fCountersToFixBeta, 5);
109 LoadConfig(config,
"fixCoreFromSd", fFixCoreFromSd, 0 );
117 ERROR(
"LDF UNDEFINED");
124 switch (fMinMethodType) {
126 INFO(
"Original likelihood will be used");
127 fMinimizer.reset(
new Likelihood( fLDF.get(), fUseSilent, fSilentLimit, fUseSaturated, fSaturationLimit) );
130 INFO(
"Profile likelihood will be used");
131 fMinimizer.reset(
new Likelihood2(fLDF.get(), fUseSilent, fSilentLimit) );
134 INFO(
"Infinite window likelihood will be used");
135 fMinimizer.reset(
new Likelihood3(fLDF.get(), fUseSilent, fSilentLimit, fUseSaturated) );
139 mDetector = &(det::Detector::GetInstance().GetMDetector());
140 siteCS = det::Detector::GetInstance().GetSiteCoordinateSystem();
149 std::ostringstream info(
"");
151 INFO(
"Starting the muon LDF reconstruction");
155 event.GetRecShower().HasSRecShower()) ) {
156 ERROR(
"Current event does not have a recontructed shower.");
157 return eContinueLoop;
161 ERROR(
"Current event does not have an MD event.");
162 return eContinueLoop;
166 const ShowerSRecData& sRecShower =
event.GetRecShower().GetSRecShower() ;
171 info <<
"Core = (" << sdCore.
GetX(siteCS) <<
", " << sdCore.
GetY(siteCS) <<
", " << sdCore.
GetZ(siteCS) <<
")";
176 const mdet::MDetector& mDetector = det::Detector::GetInstance().GetMDetector();
179 FillModulesShowerPlaneDistances(sRecShower, mDetector, me);
181 CounterList fCandidateCounters = SelectCandidateCounters(me);
184 info <<
"candidate counters = " << fCandidateCounters.size();
188 info <<
"Candidate counters: " << fCandidateCounters;
192 CounterList fSilentCounters = SelectSilentCounters(me);
195 double rho0Seed = CalculateRho0Seed( fCandidateCounters, sdCore, sdAxis );
196 double rho0SeedError = .5*rho0Seed;
202 info <<
"Core = (" << sdCore.
GetX(sdCoreCS) <<
", " << sdCore.
GetY(sdCoreCS) <<
", " << sdCore.
GetZ(sdCoreCS) <<
")" << std::endl;
206 size_t numberOfFitParameters = 4;
208 std::vector<double> fPars(numberOfFitParameters);
209 std::vector<double> fErrPars(numberOfFitParameters);
210 std::vector<bool> fFlagPars(numberOfFitParameters);
216 double betaSeed = CalculateBeta( sdAxis.
GetTheta(sdCoreCS) );
218 bool fFixBetaEvent = FixBetaFlag( fCandidateCounters, sdCore, sdAxis );
225 double xcore = sdCore.
GetX(siteCS);
226 double ycore = sdCore.
GetY(siteCS);
227 double zcore = sdCore.
GetZ(siteCS);
233 ycore = sdCore.
GetY(siteCS);
239 fMinimizer->SetZcore(zcore);
240 fMinimizer->SetAxis(sdAxis);
241 fMinimizer->SetCandidateCounterList(fCandidateCounters);
242 fMinimizer->SetSilentCounterList(fSilentCounters);
245 ROOT::Minuit2::FunctionMinimum functionMinimum = fMinimizer->Minimize(fPars, fErrPars, fFlagPars);
247 if (!functionMinimum.IsValid()) {
248 ERROR(
"MD reconstruction failed");
249 std::cerr << functionMinimum << endl;
250 ++RunController::GetInstance().GetRunData().GetNamedCounters()[
"MdLDFFinder/Failed"];
251 return eContinueLoop;
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;
261 ++RunController::GetInstance().GetRunData().GetNamedCounters()[
"MdLDFFinder/Reconstructed"];
265 event.GetRecShower().MakeMRecShower();
267 ShowerMRecData& mRecShower =
event.GetRecShower().GetMRecShower();
272 FillReconstructedParameters(mRecShower, functionMinimum.UserState(), zcore);
282 SetLdfResiduals(fCandidateCounters, fPars, sdCore, sdAxis);
283 double chi2 = CalculateChi2(fCandidateCounters, fPars, sdCore, sdAxis);
284 size_t ndof = CalculateDegreesOfFreedom(fCandidateCounters, fFlagPars);
288 const double nlnLikelihood = fMinimizer->operator()(fPars);
291 FillTabulatedFunction( mRecShower, fPars, fErrPars );
298 MdLDFFinder::Finish()
310 std::ostringstream info;
312 if (fFixBeta || counters.size() < fCountersToFixBeta) {
314 info <<
"Fixing Beta (" << counters.size() <<
" counters when at least "
315 << fCountersToFixBeta <<
" are required)";
320 typedef CounterList::const_iterator CIt;
322 int nCountersInRange = 0;
323 double maxDistance = 0;
326 info <<
"Core = (" << rCore.
GetX(siteCS) <<
", " << rCore.
GetY(siteCS) <<
", " << rCore.
GetZ(siteCS) <<
')';
329 for (CIt ci = counters.begin(), cend = counters.end(); ci != cend; ++ci) {
331 const unsigned int counterId_i = (*ci)->GetId();
332 const utl::Point& position_i = mDetector->GetCounter(counterId_i).GetPosition();
337 info <<
"counter " << (*ci)->GetId() <<
", position = ("
341 <<
", distance to core = " << rho_i;
344 if (fLowLimToRelaxBeta < rho_i && rho_i < fUppLimToRelaxBeta) {
346 for (CIt cj = ci+1; cj != cend; ++cj) {
348 const unsigned int counterId_j = (*cj)->GetId();
349 const utl::Point& position_j = mDetector->GetCounter(counterId_j).GetPosition();
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;
363 const bool rvalue = !(
364 (nCountersInRange > 1 && maxDistance > fCounterSpacings1) ||
365 (nCountersInRange > 2 && maxDistance > fCounterSpacings2) ||
366 (nCountersInRange > 3 && maxDistance > fCounterSpacings3)
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";
381 const std::vector<double>& fPars,
382 const std::vector<double>& )
384 std::ostringstream info(
"");
394 tabulatedMLDF.
Clear();
396 const double minRho = 50*
utl::m;
397 const double maxRho = 3500*
utl::m;
399 const int nMLDFPoints = 250;
400 const double dRho = (maxRho - minRho) / (nMLDFPoints - 1);
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);
413 const ROOT::Minuit2::MnUserParameterState& MnParState,
420 const std::vector<ROOT::Minuit2::MinuitParameter> minuitParameters(MnParState.MinuitParameters());
427 mRecShower.
SetNMuRef(muonDensity0, muonDensity0Error);
437 mRecShower.
SetBeta(beta,betaError);
463 const double zcoreError = 0;
468 const ROOT::Minuit2::MnUserCovariance covarianceMatrix = MnParState.Covariance();
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);
483 MdLDFFinder::GetFreeParIndex(
const std::vector<ROOT::Minuit2::MinuitParameter> minuitParameters,
484 unsigned int globalIndex)
488 assert(globalIndex<minuitParameters.size());
490 int freeParIndex = -1;
491 for (
unsigned int i=0; i<=globalIndex; ++i) {
492 if(!minuitParameters[i].IsFixed()) {
497 assert(freeParIndex>=0);
504 MdLDFFinder::CalculateBeta(
double theta)
507 return fA0 + fA1/cos(theta) + fA2/
pow(cos(theta),2);
522 for (CounterList::const_iterator ic = counters.begin(); ic != counters.end(); ++ic) {
526 unsigned int counterId = co->
GetId();
527 utl::Point counterPosition = mDetector->GetCounter(counterId).GetPosition();
529 double distanceToCore =
cross(rAxis, counterPosition - rCore).
GetMag();
531 double distanceToR0 = fabs(fReferenceDistance - distanceToCore);
533 if (distanceToR0<minDist) {
542 const double minSeedDensity = 0.05;
544 density = ( density>minSeedDensity? density : minSeedDensity);
560 if (ic->IsSilent()) {
561 fSilentCounters.push_back(&(*ic));
566 return fSilentCounters;
579 if (ic->IsCandidate()) {
580 if (fMinMethodType == eLikelihood ){
583 if(!im->IsCandidate()) {
586 size_t maxWindowsOn = im->GetRecData().GetMaxChannelsOn();
587 im->GetRecData().SetSaturationFlag( ((im->GetRecData().IsSaturated()||maxWindowsOn>=fSaturationLimit) ?
true :
false) );
590 fCandidateCounters.push_back(&(*ic));
595 return fCandidateCounters;
600 MdLDFFinder::SetLdfResiduals(
CounterList counters,
const std::vector<double> parameters,
608 for (CounterList::const_iterator ic = counters.begin(); ic != counters.end(); ++ic) {
612 unsigned int counterId = co->
GetId();
613 const mdet::Counter& mdetCounter = mDetector->GetCounter(counterId);
617 if(im->IsCandidate() && !im->GetRecData().IsSaturated()) {
619 unsigned int moduleId = im->
GetId();
623 double distanceToCore =
cross( rAxis, r_i - rCore ).
GetMag();
626 double ldfDensity = (*fLDF)( distanceToCore, ¶meters[0] );
629 double dataDensity = im->GetRecData().GetMuonDensity() / cosTheta;
632 double residual = (dataDensity - ldfDensity);
634 im->GetRecData().SetLDFResidual(residual);
643 MdLDFFinder::CalculateChi2(
const CounterList counters,
const std::vector<double> parameters,
653 for (CounterList::const_iterator ic = counters.begin(); ic != counters.end(); ++ic) {
657 unsigned int counterId = co->
GetId();
658 const mdet::Counter& mdetCounter = mDetector->GetCounter(counterId);
662 if(im->IsCandidate() && !im->GetRecData().IsSaturated()) {
664 unsigned int moduleId = im->
GetId();
668 double distanceToCore =
cross( rAxis, r_i - rCore ).
GetMag();
671 double ldfDensity = (*fLDF)( distanceToCore, ¶meters[0] );
672 double moduleArea = im->GetRecData().GetActiveArea();
673 double ldfMuons = ldfDensity*moduleArea*cosTheta;
676 double measuredMuons = im->GetRecData().GetNumberOfEstimatedMuons();
678 double dMuons = measuredMuons-ldfMuons;
679 chi2 += dMuons*dMuons/ldfMuons;
696 MdLDFFinder::CalculateDegreesOfFreedom(
const CounterList counters,
const std::vector<bool> parameterFlags)
701 for (CounterList::const_iterator ic = counters.begin(); ic != counters.end(); ++ic) {
707 if (im->IsCandidate() && !im->GetRecData().IsSaturated()) {
713 const size_t nFitParameters = std::count(parameterFlags.begin(),parameterFlags.end(),
false);
716 ndof -= nFitParameters;
727 int cId = cIt->GetId();
730 if (!mIt->HasRecData())
732 int mId = mIt->
GetId();
735 const double r = mPosition.
GetRho(sdShowerCS);
AxialVector cross(const Vector &l, const Vector &r)
vector cross product
Module level reconstruction data. This class contains all data required by the muon reconstruction...
AxialVector Cross(const Vector &l, const Vector &r)
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
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
void SetReferenceAxis(const utl::Vector &axis)
void SetCoreFixedLdf(bool flag)
ShowerRecData & GetRecShower()
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
void SetCoreError(const utl::Vector &coreerr)
Functor implementing LDF. Corner-clipping correction and noise included in the likelihood.
#define INFO(message)
Macro for logging informational messages.
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.
const utl::CoordinateSystemPtr & GetShowerCoordinateSystem() const
origin = GetCore(), z-axis = GetAxis(), x-axis = upstream
void SetBetaFixed(bool flag=true)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
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.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
const utl::TabulatedFunctionErrors & GetMLDF() const
double abs(const SVector< n, T > &v)
#define DEBUGLOG(message)
Macro for logging debugging messages.
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)
Functor implementing LDF.
double GetY(const CoordinateSystemPtr &coordinateSystem) const
ResultFlag
Flag returned by module methods to the RunController.
int GetId() const
The id of the counter.
ModuleConstIterator ModulesEnd() const
InternalCounterCollection::ComponentIterator CounterIterator
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.
CounterConstIterator CountersEnd() const
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
const Counter & GetCounter(int id) const
Retrieve Counter by id.
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
void SetCorrelationXY(double corr)
#define ERROR(message)
Macro for logging error messages.
Root of the Muon event hierarchy.
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