CONEXStructures.cc
Go to the documentation of this file.
1 
6 #include <evt/ShowerSimData.h>
7 #include <evt/GaisserHillas6Parameter.h>
8 #include <utl/Particle.h>
9 #include <utl/NucleusProperties.h>
10 #include <utl/TabulatedFunction.h>
11 #include <utl/ErrorLogger.h>
12 #include <utl/AugerUnits.h>
13 
14 #include <io/CONEXStructures.h>
15 #include <io/CONEXIOException.h>
16 
17 #include <algorithm>
18 #include <sstream>
19 #include <vector>
20 
21 using namespace evt;
22 using namespace io;
23 using namespace utl;
24 using namespace std;
25 
26 
27 CONEXShower::CONEXShower(const int nSlices) :
28  fNX(nSlices),
29  fX(new float[fNX]), // starting from OutputVersion>=2.0
30  fN(new float[fNX]),
31  fdEdX(new float[fNX]),
32  fNmu(new float[fNX]),
33  fNgam(new float[fNX]),
34  fNele(new float[fNX]),
35  fMuProd(new float[fNX])
36 { }
37 
38 
39 void
41 {
42  delete[] fX;
43  delete[] fN;
44  delete[] fdEdX;
45  delete[] fNmu;
46  delete[] fNgam;
47  delete[] fNele;
48  delete[] fMuProd;
49  fNX = n;
50  fX = new float[n];
51  fN = new float[n];
52  fdEdX = new float[n];
53  fNmu = new float[n];
54  fNgam = new float[n];
55  fNele = new float[n];
56  fMuProd = new float[n];
57 }
58 
59 
61 {
62  delete[] fX;
63  delete[] fN;
64  delete[] fdEdX;
65  delete[] fNmu;
66  delete[] fNgam;
67  delete[] fNele;
68  delete[] fMuProd;
69 }
70 
71 
72 void
74  const CONEXShower& conexShower,
75  ShowerSimData& shower)
76 {
77  switch (conexHeader.fParticleID) {
78  case 0:
80  break;
81  case 13:
83  break;
84  case 100:
86  break;
87  case 400: // helium
89  break;
90  case 1200: // carbon
92  break;
93  case 1400: // nitrogen
95  break;
96  case 1600: // oxygen
98  break;
99  case 2800: // silicon
101  break;
102  case 5600: // iron
104  break;
105  default:
106  {
107  const char* const err = "Unkown primary particle type !";
108  ERROR(err);
109  throw io::CONEXIOException(err);
110  }
111  break;
112  }
113 
114  shower.SetEnergy(pow(10, conexShower.fLogE) * eV);
117 }
118 
119 
120 void
122  const CONEXShower& conexShower,
123  const std::vector<io::CONEXLeadingParticles> conexLPvector,
124  const float conexFileVersion,
125  ShowerSimData& shower,
126  const double xShift)
127 {
128  if (conexFileVersion < 2.5) {
131  } else {
134  }
135 
136  // longitudinal profile (optionally shifted by xShift)
138  gh.SetXMax(conexShower.fXmax * g/cm2 + xShift, 0);
139  gh.SetNMax(conexShower.fNmax, 0);
140  gh.SetXZero(conexShower.fX0 * g/cm2 + xShift, 0);
141 
142  const double a = conexShower.fP1 * g/cm2;
143  const double b = conexShower.fP2;
144  const double c = conexShower.fP3 / g*cm2;
145  const double A = a + xShift*(-b + c * xShift);
146  const double B = b - 2 * c * xShift;
147  const double C = c;
148 
149  gh.SetA(A, 0);
150  gh.SetB(B, 0);
151  gh.SetC(C, 0);
152  gh.SetChiSquare(conexShower.fChi2*(conexShower.fNX - 6), (conexShower.fNX - 6));
153 
154  const bool hasValidGHfit = (conexShower.fChi2 > 0 && conexShower.fChi2 < 1e13);
155 
156  TabulatedFunction profile; // charged
157  TabulatedFunction muonProfile;
158  TabulatedFunction gammaProfile;
159  TabulatedFunction electronProfile;
160  TabulatedFunction dedx;
161  TabulatedFunction dMu;
162 
163  double energyDepositSum = 0.;
164  const int nSlice = conexShower.fNX;
165 
166  // fill profiles with zeros below shift
167  double thisX = 5 * g/cm2;
168  const double deltaX = 50 * g/cm2;
169  while (thisX < xShift) {
170  profile.PushBack(thisX, 0);
171  muonProfile.PushBack(thisX, 0);
172  gammaProfile.PushBack(thisX, 0);
173  electronProfile.PushBack(thisX, 0);
174  dedx.PushBack(thisX, 0);
175  if (conexFileVersion >= 1.1)
176  dMu.PushBack(thisX, 0);
177  thisX += deltaX;
178  }
179 
180  double binWidth = 0; // this must be outside loop, otherwise the last bin has always binWidth=0
181 
182  for (int i = 0; i < nSlice; ++i) {
183 
184  // calculation of width of grammage bin
185  double slantDepthMin = 0;
186  if (conexFileVersion >= 2.0) {
187  slantDepthMin = conexShower.fX[i] * g/cm2;
188  if (i < nSlice-1) {
189  const double slantDepthMax = conexShower.fX[i+1] * g/cm2;
190  binWidth = slantDepthMax - slantDepthMin;
191  }
192  } else { // conexFileVersion < 2.0
193  slantDepthMin = conexHeader.fFirstDepth + conexHeader.fDelX*i * g/cm2;
194  const double slantDepthMax = conexHeader.fFirstDepth + conexHeader.fDelX*(i+1) * g/cm2;
195  binWidth = slantDepthMax - slantDepthMin;
196  }
197 
198  if (slantDepthMin + xShift < 0)
199  continue;
200 
201  slantDepthMin += xShift;
202 
203  const double maxDepthProfile = conexShower.fX[nSlice-1]* g/cm2;
204  if (conexShower.fZenith > 90 && slantDepthMin > maxDepthProfile) //stop up-going profile to the top of the atmosphere
205  continue;
206 
207  float nCharged = max(0.f, conexShower.fN[i]);
208  float nMuons = max(0.f, conexShower.fNmu[i]);
209  float nElectron;
210  float nGamma = 0;
211 
212  if (conexFileVersion >= 1.1) {
213  nElectron = max(0.f, conexShower.fNele[i]);
214  nGamma = max(0.f, conexShower.fNgam[i]);
215  } else
216  nElectron = max(0.f, nCharged - nMuons);
217 
218  thisX = slantDepthMin;
219  profile.PushBack(slantDepthMin, nCharged);
220  muonProfile.PushBack(slantDepthMin, nMuons);
221  gammaProfile.PushBack(slantDepthMin, nGamma);
222  electronProfile.PushBack(slantDepthMin, nElectron);
223  dedx.PushBack(slantDepthMin + binWidth/2, max(0., conexShower.fdEdX[i] * GeV/g*cm2));
224  energyDepositSum += max(0., conexShower.fdEdX[i] * GeV/g*cm2 * binWidth);
225 
226  if (conexFileVersion >= 1.1)
227  dMu.PushBack(slantDepthMin + binWidth/2, conexShower.fMuProd[i]);
228  }
229 
230  // make sure the profile has at least a length of two bins
231  /* this was not such a great idea, needs more debugging downstream:
232  while (profile.GetNPoints()<2) {
233  // cout << " RUDEBUG CONEXStructures extend profile thisX=" << thisX/g*cm2 << endl;
234  profile.PushBack(thisX, 0);
235  muonProfile.PushBack(thisX, 0);
236  gammaProfile.PushBack(thisX, 0);
237  electronProfile.PushBack(thisX, 0);
238  dedx.PushBack(thisX, 0);
239  if (conexFileVersion >= 1.1)
240  dMu.PushBack(thisX, 0);
241  thisX += 5*g/cm2;
242  } */
243 
244  // add electromagnetic and hadronic energy at ground for total Ecal
245  const double kGround = 0.61; // hadron factor from Barbosa et al., APP22,2004
246  energyDepositSum +=
247  (conexShower.fGroundEnergy[0] +
248  kGround*conexShower.fGroundEnergy[1])* GeV;
249  shower.SetCalorimetricEnergy(energyDepositSum);
250 
251  if (!shower.HasLongitudinalProfile(ShowerSimData::eCharged))
252  shower.MakeLongitudinalProfile(profile, ShowerSimData::eCharged);
253 
255  shower.MakeLongitudinalProfile(muonProfile, ShowerSimData::eMuon);
256 
258  shower.MakeLongitudinalProfile(electronProfile, ShowerSimData::eElectron);
259 
260  if (!shower.HasLongitudinalProfile(ShowerSimData::eEnergyDeposit))
261  shower.MakeLongitudinalProfile(dedx, ShowerSimData::eEnergyDeposit);
262 
263  if (conexFileVersion >= 1.1) {
264 
266  shower.MakeLongitudinalProfile(gammaProfile, ShowerSimData::ePhoton);
267 
268  if (!shower.HasLongitudinalProfile(ShowerSimData::eMuonProduction))
269  shower.MakeLongitudinalProfile(dMu, ShowerSimData::eMuonProduction);
270  }
271 
272  // Adding GH information to simulated shower
273  if (!shower.HasGHParameters()) {
274  if (hasValidGHfit)
275  shower.MakeGHParameters(gh);
276  else {
277  ostringstream err;
278  err << "CONEX shower with invalid GH fit: Xmax=" << gh.GetXMax()/g*cm2
279  << " Nmax=" << gh.GetNMax() << " X0=" << gh.GetXZero()
280  << " chi2/ndf=" << gh.GetChiSquare();
281  ERROR(err);
282  }
283  }
284 
285  shower.SetXInject(xShift);
286  shower.SetXFirst(conexShower.fXfirst * g/cm2 + xShift);
287 
288  // Fills in information about leading particles from CONEX
289  if (!shower.HasParticleTree() && !conexLPvector.empty()) {
290  GenParticle particleTree;
291  io::FillInteractionData(particleTree, conexLPvector);
292  shower.SetParticleTree(particleTree);
293  }
294 }
295 
296 
297 void
299  const std::vector<io::CONEXLeadingParticles>& lpVector,
300  unsigned counter)
301 {
302  particleNode.SetParentId(lpVector.at(counter).GetParentId());
303  particleNode.SetParentEnergy(lpVector.at(counter).GetParentEnergy() * GeV);
304  particleNode.SetEnergyCM(lpVector.at(counter).GetEnergyCM() * GeV);
305  particleNode.SetKinel(lpVector.at(counter).GetKinel());
306  particleNode.SetMultiplicity(lpVector.at(counter).GetMultiplicity());
307  particleNode.SetTargetMass(lpVector.at(counter).GetTargetMass());
308  particleNode.SetDepth(lpVector.at(counter).GetDepth() * g/cm2);
309  particleNode.SetHeight(lpVector.at(counter).GetHeight() * m);
310 
311  ++counter;
312 
313  if (counter > lpVector.size() - 1)
314  return;
315 
316  particleNode.AddDummyParticle();
317  for (auto& nSecondary : particleNode.GetDaughterParticles()) {
318  FillInteractionData(nSecondary, lpVector, counter);
319  }
320 
321  for (unsigned i = 0; i < lpVector.at(counter - 1).GetParticleIds().size(); ++i) {
322  GenParticle dummyParticle;
323  dummyParticle.SetParentId(lpVector.at(counter - 1).GetParticleIds()[i]);
324  dummyParticle.SetParentEnergy(lpVector.at(counter - 1).GetParticleEnergies()[i] * GeV);
325  particleNode.AddDaughterParticle(dummyParticle);
326  }
327 }
const double eV
Definition: GalacticUnits.h:35
Wrapper for CONEX header information.
void SetMultiplicity(const int mult)
Definition: GenParticle.h:33
Wrapper for CONEX header shower profile data.
Class to hold collection (x,y) points and provide interpolation between them.
void SetKinel(const double kinel)
Definition: GenParticle.h:32
void SetEnergyCutoff(const double energy, const ProfileType type=eElectron)
Set the enegy cutoff for which the profile of charged particles was calculated.
void SetXMax(const double xMax, const double error)
void SetDepth(const double depth)
Definition: GenParticle.h:35
void SetGroundParticleCoordinateSystemAzimuth(const double azimuth)
Set the azimuth angle of the shower. Angle in x-y plane wrt. to the x axis (0 is from east)...
void MakeGHParameters(const evt::VGaisserHillasParameter &ghPar)
Make the Gaisser-Hillas parameters of the shower.
void PushBack(const double x, const double y)
double pow(const double x, const unsigned int i)
constexpr double deg
Definition: AugerUnits.h:140
void SetB(const double b, const double error)
Interface class to access Shower Simulated parameters.
Definition: ShowerSimData.h:49
#define max(a, b)
void MakeLongitudinalProfile(const utl::TabulatedFunction &lp, const ProfileType type=eCharged)
Make the longitudinal charge profile of the shower.
void SetXZero(const double xZero, const double error)
void AddDummyParticle()
Definition: GenParticle.h:40
void SetCalorimetricEnergy(const double energy)
Set the calorimetric energy of the shower.
void SetC(const double c, const double error)
void SetEnergy(const double theEnergy)
Set the energy of the shower primary particle.
Definition: ShowerSimData.h:91
constexpr double g
Definition: AugerUnits.h:200
void SetTargetMass(const int targetMass)
Definition: GenParticle.h:34
void SetChiSquare(const double chi, const unsigned int ndof)
std::vector< GenParticle > & GetDaughterParticles()
Definition: GenParticle.h:24
void SetXFirst(const double xFirst)
Set depth of first interaction.
void SetNMax(const double nMax, const double error, const bool isEnergyDeposit=false)
Base for exceptions in the CORSIKA reader.
void SetParentId(const int parentId)
Definition: GenParticle.h:29
void SetA(const double a, const double error)
void SetParentEnergy(const double parentEnergy)
Definition: GenParticle.h:30
static int TypeCode(const unsigned int charge, const unsigned int atomicNumber)
Calculate the particle type code from Z and A.
void FillShowerSimDataFromConex(const CONEXHeader &conexHeader, const CONEXShower &conexShower, evt::ShowerSimData &)
void AddDaughterParticle(GenParticle &parttemp)
Definition: GenParticle.h:38
void SetPrimaryParticle(const int type)
Set the type of the shower primary particle.
constexpr double GeV
Definition: AugerUnits.h:187
void SetGroundParticleCoordinateSystemZenith(const double zenith)
Set the zenith angle of the shower. Room angle between z-axis and direction from where the shower is ...
bool HasGHParameters() const
Check initialization of the Gaisser-Hillas parameters.
void FillInteractionData(evt::GenParticle &interactionTree, const std::vector< io::CONEXLeadingParticles > &lpVector, unsigned counter=0)
void SetEnergyCM(const double energyCM)
Definition: GenParticle.h:31
void FillShowerProfileDataFromConex(const CONEXHeader &conexHeader, const CONEXShower &conexShower, const std::vector< io::CONEXLeadingParticles > conexLPvector, const float conexFileVersion, evt::ShowerSimData &, const double xShift=0)
void SetParticleTree(const evt::GenParticle &partTree)
Set the tree of particles in the first few generations.
void SetVectorLength(const int n)
void SetXInject(const double xInject)
Set depth of particle injection.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
void SetHeight(const double height)
Definition: GenParticle.h:36
Gaisser-Hillas with 6 parameters (CORSIKA)
bool HasLongitudinalProfile(const ProfileType type=eCharged) const
Check initialization of the longitudinal profile.
float fGroundEnergy[3]
bool HasParticleTree() const
Check if the MC data have been filled in.
float fECutLongProfElectrons
constexpr double cm2
Definition: AugerUnits.h:118

, generated on Tue Sep 26 2023.