CorsikaShowerFileParticleIterator.cc
Go to the documentation of this file.
1 
8 #include <io/CorsikaShowerFileParticleIterator.h>
9 
10 #include <io/RawCorsikaFile.h>
11 #include <io/CorsikaBlock.h>
12 #include <io/CorsikaIOException.h>
13 #include <io/CorsikaUtilities.h>
14 
15 #include <evt/ShowerSimData.h>
16 
17 #include <utl/AugerUnits.h>
18 #include <utl/CoordinateSystem.h>
19 #include <utl/ErrorLogger.h>
20 #include <utl/Particle.h>
21 #include <utl/PhysicalConstants.h>
22 #include <utl/Point.h>
23 #include <utl/Vector.h>
24 #include <utl/GeometryUtilities.h>
25 #include <utl/ReferenceEllipsoid.h>
26 #include <utl/UTMPoint.h>
27 #include <utl/Math.h>
28 
29 #include <utl/RandomEngine.h>
30 #include <fwk/LocalCoordinateSystem.h>
31 #include <fwk/RandomEngineRegistry.h>
32 
33 #include <CLHEP/Random/Randomize.h>
34 
35 #include <det/Detector.h> // to retrieve references-CS
36 
37 #include <sstream>
38 #include <cmath>
39 
40 using namespace evt;
41 using namespace utl;
42 using namespace std;
43 
44 using namespace io;
47 
48 using CLHEP::RandFlat;
49 
50 
51 CorsikaShowerFileParticleIterator::
52 CorsikaShowerFileParticleIterator(Corsika::RawFile& rawFile,
53  const io::Corsika::EventHeader& header,
54  const Corsika::AtmosphereParameters& params,
55  const double timeOffset,
56  const PositionType& startPosition,
57  const unsigned int observationLevel,
58  const bool isThinned,
59  const double wmaxEM,
60  const bool CERFIL,
61  const double CERwlMin,
62  const double CERwlMax) :
63  fRawFile(rawFile),
64  fAtmPars(params),
65  fTimeOffset(timeOffset),
66  fStartPosition(startPosition),
67  fVersion(header.fVersion),
68  fObservationLevel(observationLevel),
69  fCurrentPosition(startPosition),
70  fCurrentParticle(utl::Particle::eUndefined,
71  utl::Particle::eShower,
72  utl::Point(0, 0, 0, CoordinateSystem::GetRootCoordinateSystem()),
73  utl::Vector(0, 0, 0, CoordinateSystem::GetRootCoordinateSystem()),
74  utl::TimeInterval(0),
75  0.),
76  fIsThinned(isThinned),
77  fWMaxEM(wmaxEM),
78  fCERFIL(CERFIL),
79  fMCERFI(header.fCerenkovOutputFlag),
80  fWlLowerLimit(CERwlMin),
81  fWlUpperLimit(CERwlMax),
82  fCurvedObsLevel(header.fCurvedObsLevel),
83  fCurved(header.fFlagCurved),
84  fObsLevelHeight(header.fObservationHeight[observationLevel-1]*cm),
85  fParent(utl::Particle(utl::Particle::eUndefined,
86  utl::Particle::eShower,
87  utl::Point(0, 0, 0, CoordinateSystem::GetRootCoordinateSystem()),
88  utl::Vector(0, 0, 0, CoordinateSystem::GetRootCoordinateSystem()),
89  utl::TimeInterval(0),
90  0.)),
91  fGrandParent(utl::Particle(utl::Particle::eUndefined,
92  utl::Particle::eShower,
93  utl::Point(0, 0, 0, CoordinateSystem::GetRootCoordinateSystem()),
94  utl::Vector(0, 0, 0, CoordinateSystem::GetRootCoordinateSystem()),
95  utl::TimeInterval(0),
96  0.))
97 {
98  fGrandParent.SetValid(false);
99  fParent.SetValid(false);
100 }
101 
102 
103 void
105 {
107  fParticleInBlock = 0;
108  fBlockBufferValid = false;
109  fIteratorValid = true;
110 }
111 
112 
114 CorsikaShowerFileParticleIterator::GetEMParticleSource(const float wt, const short int gen)
115  const
116 {
117  if (fVersion < 6.71)
118  return Particle::eShower;
119  else if (gen > 50)
120  return Particle::eShowerFromMuonDecay;
121  else if (fIsThinned) {
122  // A rectangular cut
123  const double wlimits[2] = { 0, 2000.*fWMaxEM/10000 };
124  const double glimits[2] = { 5, 11 };
125  const double w = double(wlimits[1] - wlimits[0]) / (glimits[1] - glimits[0]) * (gen - glimits[0]) + wlimits[0];
126  if (wt < w)
127  return Particle::eShowerFromLocalHadron;
128  return Particle::eShower;
129  }
130  return Particle::eShower;
131 }
132 
133 
134 Particle*
136 {
137  for (;;) {
138 
139  if (fIsThinned) {
140 
141  const Corsika::ParticleData* const corsikaParticle = GetOneParticleRecord();
142 
143  // end of particle list
144  if (!corsikaParticle)
145  return 0;
146 
147  if (fCERFIL) {
148 
149  const Corsika::CherenkovData* const cherenkovPhoton = (const Corsika::CherenkovData*)corsikaParticle;
150 
151  const double weight = cherenkovPhoton->fPhotonsInBunch *
152  (fMCERFI == 1 ? cherenkovPhoton->fWavelength : 1); // "Wavelength" is still "thinning weight"
153 
154  if (weight == 0 || (cherenkovPhoton->fX == 0 && cherenkovPhoton->fY == 0)) // empty block is all zeros
155  return 0;
156 
157  const double x = cherenkovPhoton->fX*cm;
158  const double y = cherenkovPhoton->fY*cm;
159  const double z = 0;
160  /*
161  Note: Cherenkov photon output is NEVER on curved observation level !!!!
162  RU, Do 15. Dez 15:49:12 CET 2016
163  */
164  const double sintheta_cosphi = cherenkovPhoton->fU;
165  const double sintheta_sinphi = cherenkovPhoton->fV;
166  const double costheta = -sqrt(1 - Sqr(sintheta_sinphi) - Sqr(sintheta_cosphi)); // downwards
167 
168  const Point posOnGround(x, y, z, groundCS);
169  const Vector direction(sintheta_cosphi, sintheta_sinphi, costheta, groundCS);
170 
171  double lambda = (fMCERFI > 1) ? cherenkovPhoton->fWavelength * nanometer : 0; // for MCERFI==1 no wavelength is stored!
172  if (!lambda) {
173  // zero also means that CORSIKA did not generate wavelength already
174  utl::RandomEngine* const randomEngine = &fwk::RandomEngineRegistry::GetInstance().Get(fwk::RandomEngineRegistry::eDetector);
175  lambda = 1 / (1/fWlLowerLimit - RandFlat::shoot(&randomEngine->GetEngine(), 0, 1) * (1/fWlLowerLimit - 1/fWlUpperLimit));
176  }
177 
178  // for MCERFI<=2, fDistance is PRODUCTION HEIGHT, for MCERFI>2 it is DISTANCE
179  const double distance = cherenkovPhoton->fDistance * (fMCERFI > 2 ? 1. : -1/costheta) * cm;
180  const Point posAtProduction = posOnGround - distance*direction;
181 
182  const double energy = utl::kPlanck / lambda;
183 
186  Particle::eShower,
187  posAtProduction, direction,
188  TimeInterval(cherenkovPhoton->fT*ns - fTimeOffset - distance/utl::kSpeedOfLight),
189  weight, energy);
190 
191  fProductionPoint.SetValid(false);
192  fGrandParent.SetValid(false);
193  fParent.SetValid(false);
194 
195  return &fCurrentParticle;
196  }
197 
198  const int info = corsikaParticle->fDescription / 1000;
199  const int particleId = Corsika::CorsikaToPDG(abs(info));
200 
201  // muon additional info (75,76: regular muons. 85,86: decaying muons at production point)
202  if (info == 75 || info == 76 || info == 85 || info == 86) {
203  if (!fCurved) {
204  fProductionPoint = Point(corsikaParticle->fX*cm,
205  corsikaParticle->fY*cm,
206  corsikaParticle->fTorZ*cm - fObsLevelHeight,
207  groundCS);
208  continue;
209  }
210  }
211 
212  // negative particle description denotes mother and grandmother particles
213  if (corsikaParticle->fDescription < 0) {
214 
215  if (particleId == Particle::eUndefined) {
216  ostringstream warn;
217  warn << "Unknown corsika particle code " << abs(int(corsikaParticle->fDescription/1000));
218  WARNING(warn);
219  }
220 
221  if (!fParent.IsValid()) {
222  if (!fCurved) {
223  fParent = Particle(particleId,
224  Particle::eShower,
225  Point(corsikaParticle->fX*cm,
226  corsikaParticle->fY*cm,
227  corsikaParticle->fTorZ*cm - fObsLevelHeight,
228  groundCS),
229  Vector(corsikaParticle->fPx*GeV,
230  corsikaParticle->fPy*GeV,
231  -corsikaParticle->fPz*GeV,
232  groundCS),
233  TimeInterval(),
234  corsikaParticle->fWeight);
235  }
236  } else if (!fGrandParent.IsValid()) {
237  if (!fCurved) {
238  const Vector direction(corsikaParticle->fPx*GeV,
239  corsikaParticle->fPy*GeV,
240  -corsikaParticle->fPz*GeV,
241  groundCS);
242  const double cosTheta = direction.GetCosTheta(groundCS);
243  const double parent_h = corsikaParticle->fTorZ*cm;
244  // Subtract traversed depth along the momentum direction
245  const double grand_parent_depth = GetDepthAtHeight(parent_h) - corsikaParticle->fY*g/cm2*cosTheta;
246  const double d = (GetHeightAtDepth(grand_parent_depth) - parent_h)/cosTheta;
247  const Point position = fParent.Get().GetPosition() - d*direction/direction.GetMag();
248  fGrandParent = Particle(particleId,
249  Particle::eShower,
250  position,
251  direction,
252  TimeInterval(),
253  corsikaParticle->fWeight);
254  }
255  }
256  continue;
257  }
258 
259  // skip unknown particles...
260  if (particleId == Particle::eUndefined) {
261  fProductionPoint.SetValid(false);
262  fGrandParent.SetValid(false);
263  fParent.SetValid(false);
264  continue;
265  }
266 
267  // these are not defined in ehistory particles
268  const short int hadGen = fmod(corsikaParticle->fDescription, 1000) / 10;
269  short unsigned int obsLevel = fmod(corsikaParticle->fDescription, 10);
270  //short unsigned int fateIndex = 0;
271 
272  // 95,96: decaying muons at point of decay. observation level is replaced by fate index
273  if (info == 95 || info == 96) {
274  obsLevel = fObservationLevel;
275  //fateIndex = fmod(corsikaParticle->fDescription, 10);
276  }
277 
278  if (obsLevel != fObservationLevel) {
279  fProductionPoint.SetValid(false);
280  fGrandParent.SetValid(false);
281  fParent.SetValid(false);
282  continue;
283  }
284 
285  const float weight = corsikaParticle->fWeight;
286 
287  const Particle::Source source =
288  (particleId == Particle::eElectron ||
289  particleId == Particle::ePositron ||
290  particleId == Particle::ePhoton) ?
291  GetEMParticleSource(weight, hadGen) : Particle::eShower;
292 
293  double x = corsikaParticle->fX*cm;
294  double y = corsikaParticle->fY*cm;
295  double z = 0;
296  if ((fVersion == 6.98) ||
297  (fVersion >= 6.981 && fVersion < 6.990 && fCurvedObsLevel)) {
298  const double theta = sqrt(x*x + y*y) / Corsika::kEarthRadius;
299  const double phi = atan2(y, x);
300  const double r = Corsika::kEarthRadius + fObsLevelHeight;
301  const double d = r * sin(theta);
302  x = d * cos(phi);
303  y = d * sin(phi);
304  z = r * (cos(theta) - 1);
305  } else if (fVersion >= 6.990 && fCurvedObsLevel) {
306  const double r = Corsika::kEarthRadius + fObsLevelHeight;
307  const double theta = sqrt(x*x + y*y) / r;
308  const double phi = atan2(y, x);
309  const double d = r * sin(theta);
310  x = d * cos(phi);
311  y = d * sin(phi);
312  z = r * (cos(theta) - 1);
313  }
314 
316  Particle(particleId,
317  source,
318  Point(x,
319  y,
320  z,
321  groundCS),
322  Vector(corsikaParticle->fPx*GeV,
323  corsikaParticle->fPy*GeV,
324  -corsikaParticle->fPz*GeV,
325  groundCS),
326  TimeInterval(corsikaParticle->fTorZ*ns - fTimeOffset),
327  weight);
328 
331  if (fParent.IsValid())
333  if (fGrandParent.IsValid())
335 
336  fProductionPoint.SetValid(false);
337  fGrandParent.SetValid(false);
338  fParent.SetValid(false);
339 
340  return &fCurrentParticle;
341 
342  } else { // NOT THINNED
343 
344  const Corsika::ParticleDataUnthinned* const corsikaParticle = GetOneParticleRecordUnthinned();
345 
346  // end of particle list
347  if (!corsikaParticle)
348  return 0;
349 
350  if (fCERFIL) {
351 
352  const Corsika::CherenkovDataUnthinned* const cherenkovPhoton = (const Corsika::CherenkovDataUnthinned*)corsikaParticle;
353 
354  const double weight = cherenkovPhoton->fPhotonsInBunch;
355  if (weight == 0 || (cherenkovPhoton->fX == 0 && cherenkovPhoton->fY == 0)) // empty block is all zeros
356  return 0;
357 
358  const double x = cherenkovPhoton->fX*cm;
359  const double y = cherenkovPhoton->fY*cm;
360  const double z = 0;
361  /*
362  Note: Cherenkov photon output is NEVER on curved observation level !!!!
363  RU, Do 15. Dez 15:49:12 CET 2016
364  */
365  const double sintheta_cosphi = cherenkovPhoton->fU; // corsika x-direction
366  const double sintheta_sinphi = cherenkovPhoton->fV; // corsika y-direction
367  const double costheta = -sqrt(1 - Sqr(sintheta_sinphi) - Sqr(sintheta_cosphi)); // downwards
368 
369  const Point posOnGround(x, y, z, groundCS);
370  const Vector direction(sintheta_cosphi, sintheta_sinphi, costheta, groundCS);
371 
372  // for MCERFI<=2, fDistance is PRODUCTION HEIGHT, for MCERFI>2 it is DISTANCE
373  const double distance = cherenkovPhoton->fDistance * (fMCERFI > 2 ? 1. : 1/costheta) * cm;
374  const Point posAtProduction = posOnGround - distance*direction;
375 
376  utl::RandomEngine* const randomEngine = &fwk::RandomEngineRegistry::GetInstance().Get(fwk::RandomEngineRegistry::eDetector);
377 
378  // if (since) wavelength is not stored, sample one:
379  const double lambda = 1 / (1/fWlLowerLimit - RandFlat::shoot(&randomEngine->GetEngine(), 0, 1) * (1/fWlLowerLimit - 1/fWlUpperLimit));
380  const double energy = utl::kPlanck / (lambda );
381 
384  Particle::eShower,
385  posAtProduction, direction,
386  TimeInterval(cherenkovPhoton->fT*ns - fTimeOffset - distance/utl::kSpeedOfLight),
387  weight, energy);
388 
389  fProductionPoint.SetValid(false);
390  fGrandParent.SetValid(false);
391  fParent.SetValid(false);
392 
393  return &fCurrentParticle;
394  }
395 
396  const int info = corsikaParticle->fDescription / 1000;
397  const int particleId = Corsika::CorsikaToPDG(abs(info));
398 
399  // muon additional info (75,76: regular muons. 85,86: decaying muons at production point)
400  if (info == 75 || info == 76 || info == 85 || info == 86) {
401  if (!fCurved) {
402  fProductionPoint = Point(corsikaParticle->fX*cm,
403  corsikaParticle->fY*cm,
404  corsikaParticle->fTorZ*cm - fObsLevelHeight,
405  groundCS);
406  continue;
407  }
408  }
409 
410  // negative particle description denotes mother and grandmother particles
411  if (corsikaParticle->fDescription < 0) {
412 
413  if (particleId == Particle::eUndefined) {
414  ostringstream what;
415  what << "Unknown corsika particle code " << abs(int(corsikaParticle->fDescription/1000));
416  WARNING(what);
417  }
418 
419  if (!fParent.IsValid()) {
420  if (!fCurved) {
421  fParent = Particle(particleId,
422  Particle::eShower,
423  Point(corsikaParticle->fX*cm,
424  corsikaParticle->fY*cm,
425  corsikaParticle->fTorZ*cm - fObsLevelHeight,
426  groundCS),
427  Vector(corsikaParticle->fPx*GeV,
428  corsikaParticle->fPy*GeV,
429  -corsikaParticle->fPz*GeV,
430  groundCS),
431  TimeInterval(),
432  1);
433  }
434  } else if (!fGrandParent.IsValid()) {
435  if (!fCurved) {
436  const Vector direction(corsikaParticle->fPx*GeV,
437  corsikaParticle->fPy*GeV,
438  -corsikaParticle->fPz*GeV,
439  groundCS);
440  const double cosTheta = direction.GetCosTheta(groundCS);
441  const double parent_h = corsikaParticle->fTorZ*cm;
442  // Subtract traversed depth along the momentum direction
443  const double grand_parent_depth = GetDepthAtHeight(parent_h) - corsikaParticle->fY*g/cm2 * cosTheta;
444  const double d = (GetHeightAtDepth(grand_parent_depth) - parent_h) / cosTheta;
445  const Point position = fParent.Get().GetPosition() - d*direction/direction.GetMag();
446  fGrandParent = Particle(particleId,
447  Particle::eShower,
448  position,
449  direction,
450  TimeInterval(),
451  1);
452  }
453  }
454  continue;
455  }
456 
457  // skip unknown particles...
458  if (particleId == Particle::eUndefined) {
459  fProductionPoint.SetValid(false);
460  fGrandParent.SetValid(false);
461  fParent.SetValid(false);
462  continue;
463  }
464 
465  // these are not defined in ehistory particles
466  const short int hadGen = fmod(corsikaParticle->fDescription, 1000) / 10;
467  short unsigned int obsLevel = fmod(corsikaParticle->fDescription, 10);
468  //short unsigned int fateIndex = 0;
469 
470  // 95,96: decaying muons at point of decay. observation level is replaced by fate index
471  if (info == 95 || info == 96) {
472  obsLevel = fObservationLevel;
473  //fateIndex = fmod(corsikaParticle->fDescription, 10);
474  }
475 
476  if (obsLevel != fObservationLevel) {
477  fProductionPoint.SetValid(false);
478  fGrandParent.SetValid(false);
479  fParent.SetValid(false);
480  continue;
481  }
482 
483  const float weight = 1;
484 
485  const Particle::Source source =
486  (fVersion >= 6.71 &&
487  (particleId == Particle::eElectron ||
488  particleId == Particle::ePositron ||
489  particleId == Particle::ePhoton) &&
490  hadGen > 50) ?
491  Particle::eShowerFromMuonDecay : Particle::eShower;
492 
493  double x = corsikaParticle->fX*cm;
494  double y = corsikaParticle->fY*cm;
495  double z = 0;
496  if ((fVersion == 6.98) ||
497  (fVersion >= 6.981 && fVersion < 6.990 && fCurvedObsLevel)) {
498  const double theta = sqrt(x*x + y*y) / Corsika::kEarthRadius;
499  const double phi = atan2(y, x);
500  const double r = Corsika::kEarthRadius + fObsLevelHeight;
501  const double d = r * sin(theta);
502  x = d * cos(phi);
503  y = d * sin(phi);
504  z = r * (cos(theta) - 1);
505  } else if (fVersion >= 6.990 && fCurvedObsLevel) {
506  const double r = Corsika::kEarthRadius + fObsLevelHeight;
507  const double theta = sqrt(x*x + y*y) / r;
508  const double phi = atan2(y, x);
509  const double d = r * sin(theta);
510  x = d * cos(phi);
511  y = d * sin(phi);
512  z = r * (cos(theta) - 1);
513  }
514 
516  Particle(particleId,
517  source,
518  Point(x,
519  y,
520  z,
521  groundCS),
522  Vector(corsikaParticle->fPx*GeV,
523  corsikaParticle->fPy*GeV,
524  -corsikaParticle->fPz*GeV,
525  groundCS),
526  TimeInterval(corsikaParticle->fTorZ*ns - fTimeOffset),
527  weight);
530  if (fParent.IsValid())
532  if (fGrandParent.IsValid())
534 
535  fProductionPoint.SetValid(false);
536  fGrandParent.SetValid(false);
537  fParent.SetValid(false);
538 
539  return &fCurrentParticle;
540 
541  }
542  }
543 }
544 
545 
564 {
565  using std::ostringstream;
566 
567  if (!fIteratorValid)
568  throw CorsikaIOException("CorsikaShowerFileParticleIterator not valid.");
569 
570  if (!fBlockBufferValid) {
573  ostringstream err;
574  err << "Error reading block " << fCurrentPosition << " in CORSIKA file.";
575  ERROR(err);
576  throw CorsikaIOException(err.str());
577  }
578 
579  if (fCurrentBlock.IsControl()) { // end of particle records
580  // cout << " ------------------- CONTROL BLOCK ----------" << endl;
581  fIteratorValid = false;
582  return 0;
583  }
584  }
585 
586  const Corsika::ParticleData* const currentRecord =
589 
592  fParticleInBlock = 0;
593  fBlockBufferValid = false;
594  }
595 
596  return currentRecord;
597 }
598 
599 
602 {
603  using std::ostringstream;
604 
605  if (!fIteratorValid)
606  throw CorsikaIOException("CorsikaShowerFileParticleIterator not valid.");
607 
608  if (!fBlockBufferValid) {
611  ostringstream err;
612  err << "Error reading block " << fCurrentPosition << " in CORSIKA file.";
613  ERROR(err);
614  throw CorsikaIOException(err.str());
615  }
616 
617  if (fCurrentBlockUnthinned.IsControl()) { // end of particle records
618  fIteratorValid = false;
619  return 0;
620  }
621  }
622 
623  const Corsika::ParticleDataUnthinned* const currentRecord =
626 
629  fParticleInBlock = 0;
630  fBlockBufferValid = false;
631  }
632 
633  return currentRecord;
634 }
635 
636 
637 double
639  const
640 {
641  const double d = (depth < 0) ? 0 : depth;
642 
643  // depth values in ZLAY[] are in descending order
644  for (int i = 0; i < 4; ++i)
645  if (fAtmPars.fZLAY[i+1] < d && d <= fAtmPars.fZLAY[i])
646  return -fAtmPars.fCATM[i] * log((d - fAtmPars.fAATM[i]) / fAtmPars.fBATM[i]);
647 
648  if (d <= fAtmPars.fZLAY[4])
649  return fAtmPars.fCATM[4] * (fAtmPars.fAATM[4] - d) / fAtmPars.fBATM[4];
650 
651  return 0;
652 }
653 
654 
655 double
657  const
658 {
659  // height values in HLAY[] are in ascending order
660 
661 //#warning why use fabs(height)?
662  const double h = fabs(height);
663 
664  // figure out in what layer of the atmosphere model the first interaction happened
665  int section = 0;
666  if (h > fAtmPars.fHLAY[4])
667  section = 4;
668  else if (h > fAtmPars.fHLAY[3])
669  section = 3;
670  else if (h > fAtmPars.fHLAY[2])
671  section = 2;
672  else if (h > fAtmPars.fHLAY[1])
673  section = 1;
674 
675  // Calculate X1 (slant depth in g/cm^2) from height (in cm) of first interaction
676  if (section < 4)
677  return fAtmPars.fAATM[section] +
678  fAtmPars.fBATM[section] * exp(-h / fAtmPars.fCATM[section]);
679  return fAtmPars.fAATM[section] -
680  fAtmPars.fBATM[section] * (h / fAtmPars.fCATM[section]);
681 }
static const unsigned int kParticlesInBlock
Definition: CorsikaBlock.h:104
double GetHeightAtDepth(const double depth) const
Return height at the vertical atmospheric depth, according to the parameters stored in the file...
constexpr T Sqr(const T &x)
Point object.
Definition: Point.h:32
constexpr double kPlanck
RandomEngineType & GetEngine()
Definition: RandomEngine.h:32
virtual utl::Particle * GetOneParticle(const utl::CoordinateSystemPtr &cs)
Member function to fetch the next particle.
struct with particle data
Definition: CorsikaBlock.h:369
Describes a particle for Simulation.
Definition: Particle.h:26
event header struct for Corsika files
Definition: CorsikaBlock.h:182
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
Definition: BasicVector.h:251
Constructors for Transformer classes.
Raw disk file.
Particle & GetParent()
Definition: Particle.h:148
void SetProductionPoint(const utl::Point &point)
Definition: Particle.h:154
double GetMag() const
Definition: Vector.h:58
bool GetNextBlock(Block &block)
Read one block and advance.
constexpr double nanometer
Definition: AugerUnits.h:102
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
virtual void Rewind()
Rewind the particle list in the shower file to the beginning.
struct with Cherenkov data
Definition: CorsikaBlock.h:388
const double ns
Wraps the random number engine used to generate distributions.
Definition: RandomEngine.h:27
Base for exceptions in the CORSIKA reader.
double abs(const SVector< n, T > &v)
const io::Corsika::ParticleData * GetOneParticleRecord()
Low level reader of individual Corsika particles.
bool IsValid() const
Definition: Validated.h:64
constexpr double g
Definition: AugerUnits.h:200
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
bool GetNextBlockUnthinned(BlockUnthinned &block)
Read one block and advance.
BasicBlock< ParticleData, CherenkovData, kParticlesInBlock, 39 > Block
Definition: CorsikaBlock.h:443
void SeekTo(const PositionType position, const bool reset=false)
Seek to a given block, the next block will be thePosition.
const io::Corsika::ParticleDataUnthinned * GetOneParticleRecordUnthinned()
if(dataRoot)
Definition: XXMLManager.h:1003
constexpr double kSpeedOfLight
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
constexpr double GeV
Definition: AugerUnits.h:187
bool IsControl() const
Definition: CorsikaBlock.h:425
BasicBlock< ParticleDataUnthinned, CherenkovDataUnthinned, kParticlesInBlock, 0 > BlockUnthinned
Definition: CorsikaBlock.h:445
int CorsikaToPDG(const int corsikaCode)
converters from CORSIKA to PDG particle codes
const ParticleBlock & AsParticleBlock() const
Definition: CorsikaBlock.h:432
constexpr double cm
Definition: AugerUnits.h:117
double GetDepthAtHeight(const double h) const
Return vertical atmospheric depth at the height, according to the parameters stored in the file...
Vector object.
Definition: Vector.h:30
const Point & GetPosition() const
Position of the particle.
Definition: Particle.h:110
void SetValid(const bool valid=true)
Definition: Validated.h:66
utl::Particle::Source GetEMParticleSource(const float wt, const short int gen) const
void SetParent(Particle &parent)
Definition: Particle.h:150
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
const double kEarthRadius
constexpr double cm2
Definition: AugerUnits.h:118

, generated on Tue Sep 26 2023.