8 #include <io/CorsikaShowerFileParticleIterator.h>
10 #include <io/RawCorsikaFile.h>
11 #include <io/CorsikaBlock.h>
12 #include <io/CorsikaIOException.h>
13 #include <io/CorsikaUtilities.h>
15 #include <evt/ShowerSimData.h>
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>
29 #include <utl/RandomEngine.h>
30 #include <fwk/LocalCoordinateSystem.h>
31 #include <fwk/RandomEngineRegistry.h>
33 #include <CLHEP/Random/Randomize.h>
35 #include <det/Detector.h>
48 using CLHEP::RandFlat;
51 CorsikaShowerFileParticleIterator::
55 const double timeOffset,
57 const unsigned int observationLevel,
61 const double CERwlMin,
62 const double CERwlMax) :
65 fTimeOffset(timeOffset),
66 fStartPosition(startPosition),
67 fVersion(header.fVersion),
68 fObservationLevel(observationLevel),
69 fCurrentPosition(startPosition),
76 fIsThinned(isThinned),
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),
118 return Particle::eShower;
120 return Particle::eShowerFromMuonDecay;
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];
127 return Particle::eShowerFromLocalHadron;
128 return Particle::eShower;
130 return Particle::eShower;
144 if (!corsikaParticle)
154 if (weight == 0 || (cherenkovPhoton->
fX == 0 && cherenkovPhoton->
fY == 0))
157 const double x = cherenkovPhoton->
fX*
cm;
158 const double y = cherenkovPhoton->
fY*
cm;
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));
168 const Point posOnGround(x, y, z, groundCS);
169 const Vector direction(sintheta_cosphi, sintheta_sinphi, costheta, groundCS);
179 const double distance = cherenkovPhoton->
fDistance * (
fMCERFI > 2 ? 1. : -1/costheta) *
cm;
180 const Point posAtProduction = posOnGround - distance*direction;
187 posAtProduction, direction,
202 if (info == 75 || info == 76 || info == 85 || info == 86) {
205 corsikaParticle->
fY*
cm,
217 warn <<
"Unknown corsika particle code " <<
abs(
int(corsikaParticle->
fDescription/1000));
226 corsikaParticle->
fY*
cm,
231 -corsikaParticle->
fPz*
GeV,
240 -corsikaParticle->
fPz*
GeV,
242 const double cosTheta = direction.
GetCosTheta(groundCS);
243 const double parent_h = corsikaParticle->
fTorZ*
cm;
246 const double d = (
GetHeightAtDepth(grand_parent_depth) - parent_h)/cosTheta;
268 const short int hadGen = fmod(corsikaParticle->
fDescription, 1000) / 10;
269 short unsigned int obsLevel = fmod(corsikaParticle->
fDescription, 10);
273 if (info == 95 || info == 96) {
285 const float weight = corsikaParticle->
fWeight;
289 particleId == Particle::ePositron ||
293 double x = corsikaParticle->
fX*
cm;
294 double y = corsikaParticle->
fY*
cm;
299 const double phi = atan2(y, x);
301 const double d = r * sin(theta);
304 z = r * (cos(theta) - 1);
307 const double theta =
sqrt(x*x + y*y) / r;
308 const double phi = atan2(y, x);
309 const double d = r * sin(theta);
312 z = r * (cos(theta) - 1);
324 -corsikaParticle->
fPz*
GeV,
347 if (!corsikaParticle)
355 if (weight == 0 || (cherenkovPhoton->
fX == 0 && cherenkovPhoton->
fY == 0))
358 const double x = cherenkovPhoton->
fX*
cm;
359 const double y = cherenkovPhoton->
fY*
cm;
365 const double sintheta_cosphi = cherenkovPhoton->
fU;
366 const double sintheta_sinphi = cherenkovPhoton->
fV;
367 const double costheta = -
sqrt(1 -
Sqr(sintheta_sinphi) -
Sqr(sintheta_cosphi));
369 const Point posOnGround(x, y, z, groundCS);
370 const Vector direction(sintheta_cosphi, sintheta_sinphi, costheta, groundCS);
373 const double distance = cherenkovPhoton->
fDistance * (
fMCERFI > 2 ? 1. : 1/costheta) *
cm;
374 const Point posAtProduction = posOnGround - distance*direction;
385 posAtProduction, direction,
400 if (info == 75 || info == 76 || info == 85 || info == 86) {
403 corsikaParticle->
fY*
cm,
415 what <<
"Unknown corsika particle code " <<
abs(
int(corsikaParticle->
fDescription/1000));
424 corsikaParticle->
fY*
cm,
429 -corsikaParticle->
fPz*
GeV,
438 -corsikaParticle->
fPz*
GeV,
440 const double cosTheta = direction.
GetCosTheta(groundCS);
441 const double parent_h = corsikaParticle->
fTorZ*
cm;
444 const double d = (
GetHeightAtDepth(grand_parent_depth) - parent_h) / cosTheta;
466 const short int hadGen = fmod(corsikaParticle->
fDescription, 1000) / 10;
467 short unsigned int obsLevel = fmod(corsikaParticle->
fDescription, 10);
471 if (info == 95 || info == 96) {
483 const float weight = 1;
488 particleId == Particle::ePositron ||
491 Particle::eShowerFromMuonDecay : Particle::eShower;
493 double x = corsikaParticle->
fX*
cm;
494 double y = corsikaParticle->
fY*
cm;
499 const double phi = atan2(y, x);
501 const double d = r * sin(theta);
504 z = r * (cos(theta) - 1);
507 const double theta =
sqrt(x*x + y*y) / r;
508 const double phi = atan2(y, x);
509 const double d = r * sin(theta);
512 z = r * (cos(theta) - 1);
524 -corsikaParticle->
fPz*
GeV,
565 using std::ostringstream;
596 return currentRecord;
603 using std::ostringstream;
633 return currentRecord;
641 const double d = (depth < 0) ? 0 : depth;
644 for (
int i = 0; i < 4; ++i)
662 const double h = fabs(height);
static const unsigned int kParticlesInBlock
double GetHeightAtDepth(const double depth) const
Return height at the vertical atmospheric depth, according to the parameters stored in the file...
const Corsika::AtmosphereParameters fAtmPars
constexpr T Sqr(const T &x)
RandomEngineType & GetEngine()
virtual utl::Particle * GetOneParticle(const utl::CoordinateSystemPtr &cs)
Member function to fetch the next particle.
struct with particle data
Describes a particle for Simulation.
utl::Validated< utl::Particle > fParent
const PositionType fStartPosition
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
PositionType fCurrentPosition
const unsigned int fObservationLevel
utl::Validated< utl::Point > fProductionPoint
void SetProductionPoint(const utl::Point &point)
unsigned int fParticleInBlock
bool GetNextBlock(Block &block)
Read one block and advance.
constexpr double nanometer
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
io::Corsika::RawFile::PositionType PositionType
Wraps the random number engine used to generate distributions.
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.
utl::Particle fCurrentParticle
io::Corsika::BlockUnthinned fCurrentBlockUnthinned
#define WARNING(message)
Macro for logging warning messages.
bool GetNextBlockUnthinned(BlockUnthinned &block)
Read one block and advance.
BasicBlock< ParticleData, CherenkovData, kParticlesInBlock, 39 > Block
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()
io::Corsika::Block fCurrentBlock
Corsika::RawFile & fRawFile
constexpr double kSpeedOfLight
A TimeInterval is used to represent time elapsed between two events.
BasicBlock< ParticleDataUnthinned, CherenkovDataUnthinned, kParticlesInBlock, 0 > BlockUnthinned
int CorsikaToPDG(const int corsikaCode)
converters from CORSIKA to PDG particle codes
const double fWlLowerLimit
const ParticleBlock & AsParticleBlock() const
double GetDepthAtHeight(const double h) const
Return vertical atmospheric depth at the height, according to the parameters stored in the file...
utl::Validated< utl::Particle > fGrandParent
const Point & GetPosition() const
Position of the particle.
void SetValid(const bool valid=true)
utl::Particle::Source GetEMParticleSource(const float wt, const short int gen) const
void SetParent(Particle &parent)
const bool fCurvedObsLevel
#define ERROR(message)
Macro for logging error messages.
const double kEarthRadius
const double fWlUpperLimit
const double fObsLevelHeight