MuonProfileBuilder.cc
Go to the documentation of this file.
1 
12 #include "MuonProfileBuilder.h"
13 
14 #include <fwk/CoordinateSystemRegistry.h>
15 #include <fwk/CentralConfig.h>
16 
17 #include <det/Detector.h>
18 
19 #include <evt/Event.h>
20 #include <evt/ShowerSimData.h>
21 
22 #include <utl/ErrorLogger.h>
23 #include <utl/ShowerParticleIterator.h>
24 #include <utl/Particle.h>
25 #include <utl/UTMPoint.h>
26 
27 #include <atm/Atmosphere.h>
28 #include <atm/ProfileResult.h>
29 
30 #include <iostream>
31 
32 #include <TH1D.h>
33 #include <TF1.h>
34 #include <TFile.h>
35 #include <TFitResult.h>
36 
37 using namespace fwk;
38 using namespace evt;
39 using namespace utl;
40 
41 using namespace std;
42 
43 namespace MuonProfileBuilder {
44 
46  fMuonEnergyCut(0),
47  fWriteRootFile(false),
48  fRootFileName("dummyFile.root")
49  {
50  }
51 
52  MuonProfileBuilder::~MuonProfileBuilder()
53  {
54  }
55 
58  {
59  Branch topB =
60  CentralConfig::GetInstance()->GetTopBranch("MuonProfileBuilder");
61 
62  topB.GetChild("MuonEnergyCut").GetData(fMuonEnergyCut);
63  topB.GetChild("WriteRootFile").GetData(fWriteRootFile);
64  topB.GetChild("RootFileName").GetData(fRootFileName);
65 
66  return eSuccess;
67  }
68 
69 
71  MuonProfileBuilder::Run(evt::Event& event)
72  {
73  ShowerSimData& simShower = event.GetSimShower();
74 
75  const CoordinateSystemPtr localCS = simShower.GetLocalCoordinateSystem();
76  const double zenith = (-simShower.GetDirection()).GetTheta(localCS);
77 
78  double coreHeight = utl::UTMPoint(simShower.GetPosition(), ReferenceEllipsoid::GetWGS84()).GetHeight();
79  const CoordinateSystemPtr coreCS = simShower.GetLocalCoordinateSystem();
80 
81  // assuming flat atmosphere!
82  // for curved atmosphere, use slant profile model and remove cos(zenith) below
83  const atm::Atmosphere& theAtm = det::Detector::GetInstance().GetAtmosphere();
84  const atm::ProfileResult& DepthVsHeight = theAtm.EvaluateDepthVsHeight();
85 
86  // unit is gram/cm2 for the fit of the histogram
87  const double histLowerBound = 0.;
88  const double histUpperBound = 2000.;
89  const double binSize = 5.;
90  const int nBins = (histUpperBound-histLowerBound)/binSize;
91 
92  TFile* rootFile(0);
93  if (fWriteRootFile) {
94  rootFile = new TFile(fRootFileName.c_str(),"RECREATE");
95  }
96 
97  TH1D survivingMuons("surviving", "surviving muons", nBins, histLowerBound, histUpperBound);
98  TH1D decayedMuons("decayed", "decayed muons", nBins, histLowerBound, histUpperBound);
99  TH1D allMuons("all", "all muons", nBins, histLowerBound, histUpperBound);
100 
101  int i = 0;
102  int type = Particle::eUndefined;
103 
104  for (utl::ShowerParticleIterator particleIt = simShower.GroundParticlesBegin();
105  particleIt != simShower.GroundParticlesEnd(); ++particleIt) {
106 
107  type = particleIt->GetType();
108 
109  if (! (type == Particle::eMuon || type == Particle::eAntiMuon
110  || type == Particle::eDecayedMuon || type == Particle::eDecayedAntiMuon))
111 
112  continue;
113 
114  if (!particleIt->HasProductionPoint())
115  continue;
116 
117  if (particleIt->GetKineticEnergy() < fMuonEnergyCut)
118  continue;
119 
120  double prod_height = particleIt->GetProductionPoint().GetZ(coreCS) + coreHeight;
121  double x_prod = DepthVsHeight.Y(prod_height)/cos(zenith);
122  double weight = particleIt->GetWeight();
123 
124  if (type == Particle::eMuon || type == Particle::eAntiMuon)
125  survivingMuons.Fill(x_prod/(gram/cm2), weight);
126  else if (type == Particle::eDecayedMuon || type == Particle::eDecayedAntiMuon)
127  decayedMuons.Fill(x_prod/(gram/cm2), weight);
128 
129  allMuons.Fill(x_prod/(gram/cm2), weight);
130 
131  i++;
132  if (i % 100000 == 0) {
133  ostringstream msg;
134  msg << "read " << i << " muons";
135  INFO(msg);
136  }
137 
138  }
139 
140 
141  double histMax = allMuons.GetMaximum();
142  double maxBin = allMuons.GetMaximumBin();
143  int firstFitBin = 0;
144  int lastFitBin = 0;
145  double binContent;
146 
147  for (int i = 0; i < nBins; ++i) {
148  binContent = allMuons.GetBinContent(i);
149  if (binContent > .7*histMax && firstFitBin == 0)
150  firstFitBin = i;
151  if (binContent < .7*histMax && firstFitBin > 0 && lastFitBin == 0 && i > maxBin)
152  lastFitBin = i-1;
153  }
154 
155  double firstValue = allMuons.GetBinCenter(firstFitBin);
156  double lastValue = allMuons.GetBinCenter(lastFitBin);
157 
158  TF1 func("func", "[0] + [2] * (x - [1])**2 + [3] * (x - [1])**3", firstValue, lastValue);
159  func.SetParameters(histMax, allMuons.GetBinCenter(maxBin), -1, 0);
160  double XmaxMu = allMuons.Fit("func", "RS")->Parameter(1);
161 
162  {
163  ostringstream msg;
164  msg << "fitted muon production profile between "
165  << firstValue << " g/cm2 and "
166  << lastValue << " g/cm2. "
167  << "XmaxMu = " << XmaxMu << " g/cm2. " << endl;
168  INFO(msg);
169  }
170 
171  simShower.SetXmaxMu(XmaxMu*gram/cm2);
172 
173  {
174  ostringstream msg;
175  msg << "overwriting longitudinal profiles for muons";
176  WARNING(msg);
177  }
178 
179  if (fWriteRootFile) {
180  survivingMuons.Write();
181  decayedMuons.Write();
182  allMuons.Write();
183  if (rootFile) {
184  rootFile->Close();
185  delete rootFile;
186  }
187  }
188 
189  TabulatedFunction profileSurviving;
190  TabulatedFunction profileDecayed;
191  TabulatedFunction profileAll;
192 
193  for (int i = 0; i < nBins; ++i) {
194  profileSurviving.PushBack(survivingMuons.GetBinCenter(i)*gram/cm2, survivingMuons.GetBin(i));
195  profileDecayed.PushBack(decayedMuons.GetBinCenter(i)*gram/cm2, decayedMuons.GetBin(i));
196  profileAll.PushBack(allMuons.GetBinCenter(i)*gram/cm2, allMuons.GetBin(i));
197  }
198 
201 
202  simShower.GetLongitudinalProfile(ShowerSimData::eMuon) = profileSurviving;
203 
204  if (!simShower.HasLongitudinalProfile(ShowerSimData::eMuonProduction))
205  simShower.MakeLongitudinalProfile(ShowerSimData::eMuonProduction);
206 
207  simShower.GetLongitudinalProfile(ShowerSimData::eMuonProduction) = profileAll;
208 
209  return eSuccess;
210  }
211 
212 
214  MuonProfileBuilder::Finish()
215  {
216  return eSuccess;
217  }
218 
219 }
Branch GetTopBranch() const
Definition: Branch.cc:63
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger coordinate system associated to the shower core position.
Iterator to retrieve particles from utl::VShowerParticlList.
Top of the interface to Atmosphere information.
utl::ShowerParticleIterator GroundParticlesEnd() const
Report success to RunController.
Definition: VModule.h:62
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.
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
void PushBack(const double x, const double y)
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Definition: Branch.h:107
void MakeLongitudinalProfile(const utl::TabulatedFunction &lp, const ProfileType type=eCharged)
Make the longitudinal charge profile of the shower.
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
const utl::Point & GetPosition() const
Get the position of the shower core.
const atm::ProfileResult & EvaluateDepthVsHeight() const
Tabulated function giving Y=depth as a function of X=height.
void SetXmaxMu(const double XmaxMu)
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
constexpr double gram
Definition: AugerUnits.h:195
utl::ShowerParticleIterator GroundParticlesBegin() const
bool HasLongitudinalProfile(const ProfileType type=eCharged) const
Check initialization of the longitudinal profile.
const utl::TabulatedFunction & GetLongitudinalProfile(const ProfileType type=eCharged) const
Get the longitudinal charge profile of the shower.
constexpr double cm2
Definition: AugerUnits.h:118

, generated on Tue Sep 26 2023.