ConexShowerGenerator.cc
Go to the documentation of this file.
1 #include "ConexShowerGenerator.h"
2 #include "ConexInterface.h"
3 
4 #include <conexHEModels.h>
5 
6 #include <io/CONEXStructures.h>
7 
8 #include <atm/Atmosphere.h>
9 #include <atm/InclinedAtmosphericProfile.h>
10 #include <atm/ProfileResult.h>
11 
12 #include <det/Detector.h>
13 
14 #include <tls/Atmosphere.h>
15 
16 #include <utl/AugerException.h>
17 #include <utl/ErrorLogger.h>
18 #include <utl/Particle.h>
19 #include <utl/RandomEngine.h>
20 #include <utl/Reader.h>
21 #include <utl/NucleusProperties.h>
22 #include <utl/ReferenceEllipsoid.h>
23 #include <fwk/RandomEngineRegistry.h>
24 #include <fwk/CentralConfig.h>
25 
26 #include <evt/ShowerSimData.h>
27 #include <evt/Event.h>
28 
29 #include <sstream>
30 #include <string>
31 #include <iostream>
32 
33 #include <CLHEP/Random/RandFlat.h>
34 
35 using CLHEP::RandFlat;
36 using namespace ConexShowerGeneratorKG;
37 using namespace std;
38 using namespace utl;
39 using namespace fwk;
40 using namespace evt;
41 using namespace atm;
42 
43 
44 inline
45 int
46 ConexParticleNumber(const int type)
47 {
48  if (NucleusProperties::IsNucleus(type))
49  return NucleusProperties(type).GetAtomicNumber() * 100;
50  else if (type == Particle::eProton)
51  return 100;
52  else if (type == Particle::ePhoton)
53  return 0;
54  else {
55  ostringstream errMsg;
56  errMsg << " can not convert particle type " << type << " to CONEX ID";
57  ERROR(errMsg);
58  throw utl::NonExistentComponentException(errMsg.str());
59  }
60 }
61 
62 
65 {
66  CentralConfig& cc = *CentralConfig::GetInstance();
67  const Branch topB = cc.GetTopBranch("ConexShowerGenerator");
68 
69  const string parameterPathName =
70  topB.GetChild("parameterDirectoryPath") ?
71  topB.GetChild("parameterDirectoryPath").Get<string>() : string(_CONEX_PREFIX) + "/cfg";
72 
73  const string interactionModelName = topB.GetChild("interactionModel").Get<string>();
74 
75  EHEModel interactionModel;
76  if (interactionModelName == "QGSJet01")
77  interactionModel = eQGSJet01;
78  else if (interactionModelName == "EPOS")
79 #if _CONEX2R_VERSION >= 436
80  interactionModel = eEposLHC;
81 #else
82  interactionModel = eEpos199;
83 #endif
84  else if (interactionModelName == "Sibyll")
85 #if _CONEX2R_VERSION >= 530
86  interactionModel = eSibyll23;
87 #else
88  interactionModel = eSibyll21;
89 #endif
90  else if (interactionModelName == "QGSJetII")
91  interactionModel = eQGSJetII;
92  else {
93  ostringstream errMsg;
94  errMsg << " unknown interaction model " << interactionModelName;
95  ERROR(errMsg);
96  return eFailure;
97  }
98 
99  const Branch randomXmaxB = topB.GetChild("randomXmax");
100  if (randomXmaxB) {
101  fRandomXmax = true;
102  randomXmaxB.GetChild("minXmax").GetData(fMinXmax);
103  randomXmaxB.GetChild("maxXmax").GetData(fMaxXmax);
104  if (fMinXmax < 0 || fMaxXmax < fMinXmax) {
105  ostringstream errMsg;
106  errMsg << " inconsistent xMax range: minXmax = "
107  << fMinXmax / g * cm2 << ", maxXmax = "
108  << fMaxXmax / g * cm2 ;
109  ERROR(errMsg);
110  return eFailure;
111  }
112  }
113 
114  const Branch randomDistanceB = topB.GetChild("randomDistance");
115  if (randomDistanceB) {
116  fRandomDistance = true;
117  randomDistanceB.GetChild("maxHeight").GetData(fMaxHeight);
118  if (fMaxHeight < 0) {
119  ostringstream errMsg;
120  errMsg << " maximum height must be positve: maxHeight= "
121  << fMaxHeight / m ;
122  ERROR(errMsg);
123  return eFailure;
124  }
125  }
126 
127  topB.GetChild("recycle").GetData(fRecycle);
128  if (fRecycle < 1)
129  fRecycle = 1;
130 
131  fPropagateAltitude = false;
132  if (topB.GetChild("propagateAltitude"))
133  topB.GetChild("propagateAltitude").GetData(fPropagateAltitude);
134 
135  // Set number of stored generations of leading interactions
136  topB.GetChild("storedGenerations").GetData(fStoredGenerations);
137  if (fStoredGenerations < 0)
138  fStoredGenerations = 0;
139  if (fStoredGenerations > 100) // hard limit from CONEX
140  fStoredGenerations = 100;
141 
142  // Set number of stored most energetic particles in an interaction
143  // Check on the upper limit is done for each interaction, when the multiplicity is known
144  topB.GetChild("storedParticles").GetData(fStoredParticles);
145  if (fStoredParticles < 0)
146  fStoredParticles = 0;
147 
148  // set CONEX random seed
149  utl::RandomEngine& randomEngine =
150  RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::ePhysics);
151  const long physicsSeed = randomEngine.GetEngine().getSeed();
152 
153  // info output
154  ostringstream info;
155  info << " Version: " << GetVersionInfo(VModule::eRevisionNumber) << "\n"
156  << " Parameters:\n";
157  info << " he-model: " << interactionModelName << "\n"
158  " he-model-code: " << interactionModel << "\n"
159  " conex-config-path: " << parameterPathName << "\n"
160  " stored generations: " << fStoredGenerations << "\n"
161  " seed: " << physicsSeed << "\n";
162  INFO(info);
163 
164  fConexInterface =
165  new ConexInterface(interactionModel, parameterPathName, fStoredGenerations, physicsSeed);
166 
167  return eSuccess;
168 }
169 
170 
173 {
174  if (!event.HasSimShower()) {
175  INFO("event without sim shower --> skip ");
176  return eSuccess;
177  }
178 
179  evt::ShowerSimData& simEvent= event.GetSimShower();
180 
181  // simulate one shower
182  const int particleType = ConexParticleNumber(simEvent.GetPrimaryParticle());
183  const double energyInGeV = simEvent.GetEnergy() / GeV;
184 
185  const CoordinateSystemPtr localCS = simEvent.GetLocalCoordinateSystem();
186  const double zenith = (-simEvent.GetDirection()).GetTheta(localCS) / degree;
187  double azimuth = (-simEvent.GetDirection()).GetPhi(localCS) / degree;
188 
189  double altitude = 0;
190  if (fPropagateAltitude) {
191  const ReferenceEllipsoid& e = ReferenceEllipsoid::GetWGS84();
192  altitude = e.PointToLatitudeLongitudeHeight(simEvent.GetPosition()).get<2>();
193  }
194 
195  ostringstream info;
196  info << "simulating shower, lg(E/eV)=" << log10(energyInGeV)+9 << ", "
197  "zenith =" << zenith << " "
198  "azimuth=" << azimuth << " "
199  "altitude=" << altitude << " "
200  "Offline pid=" << simEvent.GetPrimaryParticle() << " "
201  "CONEX pid=" << particleType;
202  INFO(info);
203 
204  // Conex upgoing requires azimuth = 0, does not affect result in Offline
205  if (zenith > 90)
206  azimuth = 0;
207 
208  if (!(fShowerCounter % fRecycle))
209  fConexInterface->SimulateShower(particleType, energyInGeV, zenith, azimuth, altitude, fStoredParticles);
210 
211  const io::CONEXHeader& conexHeader = fConexInterface->GetHeader();
212  const io::CONEXShower& conexShower = fConexInterface->GetShower();
213  const std::vector<io::CONEXLeadingParticles>& fLeadingParticles = fConexInterface->GetLPvector();
214 
215  double xShift = 0;
216 
217  if (fRandomXmax) {
218  RandomEngine& randEngine =
219  RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::ePhysics);
220  const double xMax = RandFlat::shoot(&randEngine.GetEngine(), fMinXmax, fMaxXmax);
221  xShift = xMax - conexShower.fXmax * g/cm2;
222  }
223 
224  if (fRandomDistance) {
225  if (zenith <= 90) {
226  ERROR("RandomDistance only for up-going showers. Skipping shower.");
227  return eContinueLoop;
228  }
229 
230  const double maxDistance = -fMaxHeight / cos(zenith * deg);
231  RandomEngine& randEngine =
232  RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::ePhysics);
233  const double distanceShift = RandFlat::shoot(&randEngine.GetEngine(), maxDistance);
234  info.str("");
235  info << "Moving the point of first interaction along the axis to "
236  << distanceShift/meter << " meters from the shower core.";
237  INFO(info);
238 
239  const double depthStepSize = 5 * g/cm2;
240  const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
241  atmo.InitSlantProfileModel(simEvent.GetPosition(), -simEvent.GetDirection(), depthStepSize);
242  const atm::ProfileResult slantDepthProfile = atmo.EvaluateSlantDepthVsDistance();
243  xShift = slantDepthProfile.Y(distanceShift);
244  xShift -= conexShower.fXfirst * g/cm2; // Randomization of point of first interaction
245  }
246 
247  io::FillShowerProfileDataFromConex(conexHeader, conexShower, fLeadingParticles,
248  conexHeader.fROOTVersion, simEvent, xShift);
249 
250  simEvent.SetShowerNumber(fShowerCounter);
251  stringstream runIdentifier;
252  runIdentifier << "cx_" << conexHeader.fVersion
253  << '_' << conexHeader.fHighEnergyModel
254  << '_' << conexHeader.fSeed;
255  simEvent.SetShowerRunId(runIdentifier.str());
256 
257  bool skip = !simEvent.HasLongitudinalProfile(ShowerSimData::eCharged);
258 
259  if (simEvent.GetLongitudinalProfile(ShowerSimData::eCharged).GetNPoints() < 2)
260  skip = true;
261 
262  info.str("");
263  info << "\n"
264  "\t ----------- CONEX -------------\n";
265  if (simEvent.HasGHParameters()) {
266  info << "\t xmax/g*cm2: "
267  << simEvent.GetGHParameters().GetXMax() / (g/cm2);
268  if (fRandomXmax)
269  info << " [random Xmax] ";
270  if (fRandomDistance)
271  info << " [random Distance] ";
272  } else {
273  skip = true;
274  info << "\t no GH paramaters!! ";
275  }
276  info << "\n"
277  "\t energy/eV: " << simEvent.GetEnergy()/eV << "\n"
278  "\t zenith/deg: " << zenith << "\n"
279  "\t ----------- CONEX ------------- ";
280 
281  INFO(info);
282 
283  ++fShowerCounter;
284 
285  if (skip) {
286  ERROR("Skipping shower.");
287  return eContinueLoop;
288  }
289 
290  return eSuccess;
291 }
292 
293 
296 {
297  delete fConexInterface;
298  fConexInterface = nullptr;
299 
300  return eSuccess;
301 }
302 
303 
305 {
306  delete fConexInterface;
307 }
308 
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger coordinate system associated to the shower core position.
const double eV
Definition: GalacticUnits.h:35
int GetPrimaryParticle() const
Get the type of the shower primary particle.
Definition: ShowerSimData.h:84
unsigned int GetNPoints() const
Top of the interface to Atmosphere information.
Wrapper for CONEX header information.
const double degree
virtual double GetAtomicNumber() const
Get atomic mass number A of particle.
Wrapper for CONEX header shower profile data.
void InitSlantProfileModel(const utl::Point &core, const utl::Vector &dir, const double deltaX) const
RandomEngineType & GetEngine()
Definition: RandomEngine.h:32
const evt::VGaisserHillasParameter & GetGHParameters() const
Get the Gaisser-Hillas parameters of the shower.
bool HasSimShower() const
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
Class to hold properties of nuclei.
const double meter
Definition: GalacticUnits.h:29
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
Base class for exceptions trying to access non-existing components.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
int ConexParticleNumber(const int type)
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
constexpr double deg
Definition: AugerUnits.h:140
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
T Get() const
Definition: Branch.h:271
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Definition: Branch.h:107
Reference ellipsoids for UTM transformations.
const utl::Vector & GetDirection() const
Get the direction of the shower axis. This is the true direction of shower movement.
Wraps the random number engine used to generate distributions.
Definition: RandomEngine.h:27
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
const utl::Point & GetPosition() const
Get the position of the shower core.
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
constexpr double g
Definition: AugerUnits.h:200
double GetEnergy() const
Get the energy of the shower primary particle.
Definition: ShowerSimData.h:89
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
constexpr double GeV
Definition: AugerUnits.h:187
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
void SetShowerNumber(const int sid)
Definition: ShowerSimData.h:75
bool HasGHParameters() const
Check initialization of the Gaisser-Hillas parameters.
void FillShowerProfileDataFromConex(const CONEXHeader &conexHeader, const CONEXShower &conexShower, const std::vector< io::CONEXLeadingParticles > conexLPvector, const float conexFileVersion, evt::ShowerSimData &, const double xShift=0)
Main configuration utility.
Definition: CentralConfig.h:51
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
void SetShowerRunId(const std::string srid)
Definition: ShowerSimData.h:81
const atm::ProfileResult & EvaluateSlantDepthVsDistance() const
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
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)
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.