12 #include <utl/Reader.h>
13 #include <utl/ErrorLogger.h>
14 #include <utl/AugerUnits.h>
15 #include <utl/MathConstants.h>
16 #include <utl/PhysicalConstants.h>
17 #include <utl/PhysicalFunctions.h>
18 #include <utl/Vector.h>
19 #include <utl/Point.h>
20 #include <utl/TabulatedFunction.h>
21 #include <utl/TabulatedFunctionErrors.h>
22 #include <utl/MultiTabulatedFunction.h>
23 #include <utl/UTMPoint.h>
24 #include <utl/Particle.h>
25 #include <utl/GeometryUtilities.h>
27 #include <evt/Event.h>
28 #include <evt/ShowerSimData.h>
30 #include <fwk/CentralConfig.h>
31 #include <fwk/CoordinateSystemRegistry.h>
33 #include <det/Detector.h>
34 #include <fdet/FDetector.h>
37 #include <atm/AttenuationResult.h>
38 #include <atm/ProfileResult.h>
39 #include <atm/Atmosphere.h>
40 #include <atm/InclinedAtmosphericProfile.h>
42 #include <CLHEP/Random/Randomize.h>
46 #include <boost/tuple/tuple.hpp>
47 #include <boost/tuple/tuple_io.hpp>
49 using namespace ShowerLightSimulatorKG;
62 const Branch topB = CentralConfig::GetInstance()->
GetTopBranch(
"ShowerLightSimulatorKG");
64 fPrimaryCherenkov =
false;
74 << GetVersionInfo(VModule::eRevisionNumber) <<
"\n"
76 " fluorescence: " << (fFluorescence ?
"ON" :
"OFF") <<
"\n"
77 " cherenkov: " << (fCherenkov ?
"ON" :
"OFF") <<
"\n"
78 " cherenkov mode: " << (fUseCherenkovProfile ?
"CORSIKA" :
"model") <<
"\n"
79 " atmosphere geometry: " << (fFlatEarth ?
"FLAT" :
"CURVED") <<
'\n';
91 ERROR(
"Event has no simulated shower.");
96 Detector& theDetector = Detector::GetInstance();
101 Point showerCore(0, 0, 0, showerCS);
102 Vector showerDir(0, 0, -1, showerCS);
106 const double zenith = (-simShower.
GetDirection()).GetTheta(localCS);
107 const double cosTheta = cos (zenith);
108 const double absCosTheta = std::fabs(cosTheta);
117 double atmDepthMin = 0;
118 double atmDepthMax = 0;
119 double atmDistanceMin = 0;
120 double atmDistanceMax = 0;
123 bool skimming =
false;
137 atmDepthMin = distanceVsSlantDepth->
MinX();
138 atmDepthMax = distanceVsSlantDepth->
MaxX();
139 atmDistanceMin = distanceVsSlantDepth->
Y(atmDepthMin);
140 atmDistanceMax = distanceVsSlantDepth->
Y(atmDepthMax);
144 upward = (heightVsDistance.
Y(atmDistanceMin) < heightVsDistance.
Y(atmDistanceMax) - 1.*
m);
145 skimming = ((upward ? heightVsDistance.
Y(atmDistanceMin) : heightVsDistance.
Y(atmDistanceMax)) >
146 heightVsDistance.
Y((atmDistanceMax+atmDistanceMin)/2));
147 double atmHeightMax = (upward ? heightVsDistance.
Y(atmDistanceMax) : heightVsDistance.
Y(atmDistanceMin));
148 double atmHeightMin = (skimming ? heightVsDistance.
Y((atmDistanceMax+atmDistanceMin)/2) :
149 (upward ? heightVsDistance.
Y(atmDistanceMin) : heightVsDistance.
Y(atmDistanceMax)));
155 if (atmHeightMax>temperaturProfile.
MaxX() ||
156 atmHeightMax>densityProfile.
MaxX()) {
158 atmHeightMax = std::min(temperaturProfile.
MaxX(), densityProfile.
MaxX()) - 1.*
mm;
159 const vector<Point> intersections =
161 Line(showerCore, -showerDir));
162 if (intersections.size() != 2) {
165 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
166 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
167 "Number of intersections point of air shower axis with ellipsoid of height="
168 << atmHeightMax/
km <<
" km is: " << intersections.size()
169 <<
" ---> skip event\n"
170 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
171 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
173 return eContinueLoop;
178 atmDistanceMax = (intersections[0] - showerCore).GetMag();
179 atmDepthMax = slantDepthVsDistance.
Y(atmDistanceMax);
183 atmDistanceMin = (intersections[1] - showerCore).GetMag();
184 atmDepthMin = slantDepthVsDistance.
Y(atmDistanceMin);
187 atmDistanceMax = std::min(atmDistanceMax, (intersections[0] - showerCore).GetMag());
188 atmDepthMax = slantDepthVsDistance.
Y(atmDistanceMax);
189 atmHeightMin = heightVsDistance.
Y((atmDistanceMax + atmDistanceMin)/2);
194 if (atmHeightMin<temperaturProfile.
MinX() ||
195 atmHeightMin<densityProfile.
MinX()) {
198 const vector<Point> intersections =
200 Line(showerCore, -showerDir));
202 if (intersections.size() != 2) {
205 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
206 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
207 "Number of intersections point of air shower axis with ellipsoid of height="
208 << atmHeightMin/
km <<
" km is: " << intersections.size()
209 <<
" ---> skip event\n"
210 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
211 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
213 return eContinueLoop;
218 atmDistanceMin = (intersections[0] - showerCore).GetMag();
219 atmDepthMin = slantDepthVsDistance.
Y(atmDistanceMin);
223 atmDistanceMax = (intersections[1] - showerCore).GetMag();
224 atmDepthMax = slantDepthVsDistance.
Y(atmDistanceMax);
227 atmDistanceMin =
std::max(atmDistanceMin, (intersections[0] - showerCore).GetMag());
228 atmDepthMin = slantDepthVsDistance.
Y(atmDistanceMin);
229 atmHeightMax = heightVsDistance.
Y((atmDistanceMax + atmDistanceMin)/2);
235 ERROR(
string(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
236 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
237 "InclinedAtmosphericProfile EXCEPTION:\n") + e.
GetMessage() +
239 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
240 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
242 return eContinueLoop;
248 upward = (cosTheta < 0);
257 atmDistanceMin = (coreZ - depthVsHeight.
MinX()) / absCosTheta;
258 atmDistanceMin =
std::max(atmDistanceMin, (coreZ - densityProfile.
MinX()) / absCosTheta);
259 atmDistanceMin =
std::max(atmDistanceMin, (coreZ - temperaturProfile.
MinX()) / absCosTheta);
261 atmDistanceMax = (coreZ - depthVsHeight.
MaxX()) / absCosTheta;
262 atmDistanceMax = std::min(atmDistanceMax, (coreZ - densityProfile.
MaxX()) / absCosTheta);
263 atmDistanceMax = std::min(atmDistanceMax, (coreZ - temperaturProfile.
MaxX()) / absCosTheta);
265 atmDepthMin = depthVsHeight.
Y(coreZ - atmDistanceMax*absCosTheta);
266 atmDepthMax = depthVsHeight.
Y(coreZ - atmDistanceMin*absCosTheta);
268 atmDepthMin /= absCosTheta;
269 atmDepthMax /= absCosTheta;
272 info <<
"Flat geometry with Theta=" << zenith/
deg;
278 info <<
"Atmosphere starts at " << atmDepthMin/
g*
cm*
cm <<
"g/cm2, "
279 "d=" << atmDistanceMin/
m <<
"m, "
280 "and ends at " << atmDepthMax/
g*
cm*
cm <<
"g/cm2, "
281 "d=" << atmDistanceMax/
m <<
"m";
285 bool truncated =
false;
288 ERROR(
"The shower has no energy deposit profile.");
293 ERROR(
"The shower has an empty energy deposit profile.");
296 int iFirstValidBin_dEdX = 0;
297 int iLastValidBin_dEdX = energyDep.
GetNPoints() - 1;
300 ERROR(
"The shower has no charge profile.");
305 ERROR(
"The shower has an empty charge profile.");
308 int iFirstValidBin_Ne = 0;
309 int iLastValidBin_Ne = chargeProfile.
GetNPoints() - 1;
311 const double profDepthMin =
312 std::max(energyDep[iFirstValidBin_dEdX].X(), chargeProfile[iFirstValidBin_Ne].X());
313 const double profDepthMax =
314 std::min(energyDep[iLastValidBin_dEdX].X(), chargeProfile[iLastValidBin_Ne].X());
317 info <<
"Shower profile starts at " << profDepthMin/
g*
cm*
cm <<
" g/cm2, "
318 "and ends at " << profDepthMax/
g*
cm*
cm <<
" g/cm2";
322 while (energyDep[iFirstValidBin_dEdX].X() < atmDepthMin &&
323 iFirstValidBin_dEdX<iLastValidBin_dEdX) {
324 ++iFirstValidBin_dEdX;
328 while (energyDep[iLastValidBin_dEdX].X() > atmDepthMax &&
329 iLastValidBin_dEdX>iFirstValidBin_dEdX) {
330 --iLastValidBin_dEdX;
335 while (chargeProfile[iFirstValidBin_Ne].X() < atmDepthMin &&
336 iFirstValidBin_Ne<iLastValidBin_Ne) {
341 while (chargeProfile[iLastValidBin_Ne].X() > atmDepthMax &&
342 iLastValidBin_Ne>iFirstValidBin_Ne) {
347 const double truncDepthMin =
348 std::max(energyDep[iFirstValidBin_dEdX].X(), chargeProfile[iFirstValidBin_Ne].X());
350 const double truncDepthMax =
351 std::min(energyDep[iLastValidBin_dEdX].X(), chargeProfile[iLastValidBin_Ne].X());
354 double truncHeightMax;
355 double truncHeightMin;
357 truncHeightMax = heightVsDepth.
Y(truncDepthMin*absCosTheta);
358 truncHeightMin = heightVsDepth.
Y(truncDepthMax*absCosTheta);
362 truncHeightMax = heightVsSlantDepth.
Y(truncDepthMin);
363 truncHeightMin = heightVsSlantDepth.
Y(truncDepthMax);
369 double distFinalCore;
371 distInitCore = (coreZ-truncHeightMax) / cosTheta;
372 distFinalCore = (coreZ-truncHeightMin) / cosTheta;
374 distInitCore = distanceVsSlantDepth->
Y(truncDepthMin);
375 distFinalCore = distanceVsSlantDepth->
Y(truncDepthMax);
404 info <<
"Profile was truncated to fit the Atmosphere:\n"
406 "X=" << truncDepthMin/
g*
cm2 <<
"g/cm2, "
407 "h=" << truncHeightMax/
m <<
"m, "
408 "d=" << distInitCore/
m <<
"m\n"
410 "X=" << truncDepthMax/
g*
cm2 <<
"g/cm2, "
411 "h=" << truncHeightMin/
m <<
"m, "
412 "d=" << distFinalCore/
m <<
"m";
416 info <<
"Profile fits into the Atmosphere definition:\n"
418 "h=" << truncHeightMax/
m <<
"m, "
419 "d=" << distInitCore/
m <<
"m\n"
421 "h=" << truncHeightMin/
m <<
"m, "
422 "d=" << distFinalCore/
m <<
"m";
427 INFO (
"shower is UPWARD going");
432 FluorescenceLight(event, distInitCore, distFinalCore, upward);
438 ERROR(
"Shower without GH-fit: Cannot compute Cherenkov light ! SKIPPING !");
440 return eContinueLoop;
444 CherenkovLight(event, distInitCore, distFinalCore, upward, fUseCherenkovProfile);
447 if (fPrimaryCherenkov) {
449 PrimaryCherenkovLight(event);
474 double distFinalCore,
477 INFO (
"Calculating fluorescence light");
479 Detector& theDetector = Detector::GetInstance();
484 Point core(0, 0, 0, showerCS);
485 Vector axis(0, 0, -1, showerCS);
489 const double cosTheta = (-simShower.
GetDirection()).GetCosTheta(localCS);
490 const double absCosTheta = std::fabs(cosTheta);
498 const double distInitFinal = std::fabs(distFinalCore - distInitCore);
500 const int nPoints = int(distInitFinal / delta);
507 const vector<double>& wavelengths =
509 unsigned int nWaves = wavelengths.size();
511 for (
unsigned int iwl = 0; iwl < nWaves; ++iwl) {
516 ERROR(
"Flourescence light produced twice !!!!!");
521 const double distanceStart = distInitCore;
523 for (
int i = 0; i < nPoints; ++i) {
525 const double distance = distanceStart + delta * (0.5 + i);
533 heightBin = coreZ - distance * cosTheta;
534 depthBin = depthVsHeight.
Y(heightBin) / absCosTheta;
536 Point p (core + axis * distance);
538 depthBin = slantDepthVsDistance.
Y(distance);
546 for (
unsigned int iwl = 0; iwl < nWaves; ++iwl) {
549 ERROR (
"Data structure SimShowerData not initialized properly!");
553 const double photons = spectrum[iwl].
Y()*energyDep.
Y(depthBin)/dEdX0;
556 fluoPhotons.
Insert(distance, photons);
575 double distFinalCore,
577 bool useCherenkovProfile)
579 INFO(
"Calculating Cherenkov light and beam");
581 Detector& theDetector = Detector::GetInstance();
586 Point core(0, 0, 0, showerCS);
587 Vector axis(0, 0, -1, showerCS);
591 const double cosTheta = (-simShower.
GetDirection()).GetCosTheta(localCS);
592 const double absCosTheta = std::fabs(cosTheta);
600 const double distInitFinal = std::fabs(distFinalCore - distInitCore);
602 const int nPoints = int(distInitFinal / delta);
609 double wl_spect_norm_prod = 0;
611 if (!useCherenkovProfile) {
620 wl_spect_norm_prod = 1./lambdaMin - 1./lambdaMax;
624 const vector<double>& wavelengths =
626 const unsigned int nWaves = wavelengths.size();
629 for (
unsigned int iwl = 0; iwl < nWaves; ++iwl) {
635 ERROR(
"Cherenkov light produced twice !!!!!");
642 ERROR(
"Cherenkov beam produced twice !!!!!");
649 ERROR(
"Cherenkov beam produced twice !!!!!");
654 const double distanceStart = distInitCore;
656 vector<double> beam(nWaves, 0);
657 for (
int i = 0; i < nPoints; ++i) {
659 const double distance = distanceStart + delta * (0.5 + i);
660 const double distanceStart = distance - 0.5*delta;
661 const double distanceEnd = distance + 0.5*delta;
662 const Point xStepStart(core + axis * distanceStart);
663 const Point xStepEnd(core + axis * distanceEnd);
665 double heightBin = 0;
668 heightBin = coreZ - distance * cosTheta;
669 depthBin = depthVsHeight.
Y(heightBin) / absCosTheta;
671 const Point p(core + axis * distance);
673 depthBin = slantDepthVsDistance.
Y(distance);
681 double showerAge = 0;
683 double cherenkovProduction = 0;
684 if (!useCherenkovProfile) {
688 cherenkovProduction = cherenkovProfile->
Y(depthBin) / wl_spect_norm_prod;
719 double minWaveBin = 0;
720 double maxWaveBin = 0;
721 for (
unsigned int iwl = 0; iwl < nWaves; ++iwl) {
725 const double attenuation = mieAttenuation * rayleightAttenuation;
731 minWaveBin = (iwl == 0 ?
732 wavelengths[iwl] - 0.5*(wavelengths[iwl+1] - wavelengths[iwl]) :
734 maxWaveBin = (iwl == nWaves-1 ?
735 wavelengths[iwl] + 0.5*(wavelengths[iwl] - wavelengths[iwl-1]) :
736 0.5*(wavelengths[iwl] + wavelengths[iwl+1]));
742 double generatedPhotons = 0;
743 if (!useCherenkovProfile) {
744 const double Nch = chargeProfile->
Y(depthBin);
745 generatedPhotons = cherPh->
Y(wavelengths[iwl]) * Nch;
746 beam[iwl] += generatedPhotons;
751 const double deltaDepth = fFlatEarth ?
752 (depthVsHeight.
Y(coreZ - distanceEnd*cosTheta) - depthVsHeight.
Y(coreZ - distanceStart*cosTheta)) / absCosTheta :
753 slantDepthVsDistance.
Y(distanceEnd) - slantDepthVsDistance.
Y(distanceStart);
754 generatedPhotons = cherenkovProduction * deltaDepth * (1./minWaveBin - 1./maxWaveBin);
755 beam[iwl] += generatedPhotons;
758 beam[iwl] *= attenuation;
764 ckovPhotons.
Insert(distance, generatedPhotons/delta);
765 ckovBeam.
Insert(distance, beam[iwl]);
766 ckovBeamProduction.
Insert(distance, generatedPhotons/delta);
768 for (
unsigned int jTrace = 0; jTrace < ckovBeamProduction.
GetNPoints(); ++jTrace) {
769 ckovBeamProduction.
GetY(jTrace) *= attenuation;
770 if (ckovBeamProduction.
GetY(jTrace) < 0) {
771 WARNING(
"Cherenkov beam production negative. Forcing it to zero.");
772 ckovBeamProduction.
GetY(jTrace) = 0.;
785 INFO(
"Calculating primary Cherenkov light and beam");
787 Detector& theDetector = Detector::GetInstance();
792 Point core(0, 0, 0, showerCS);
793 Vector axis(0, 0, -1, showerCS);
809 double atmDepthMin = heightVsSlantDepth.
MinX();
810 double atmDepthMax = heightVsSlantDepth.
MaxX();
811 double atmHeightMin = heightVsSlantDepth.
Y (atmDepthMax);
814 if (fOverRidePrimaryCharge >= 0) {
815 Z = fOverRidePrimaryCharge;
816 cout <<
" Override primary charge ----------> Z=" << Z << endl;
819 switch (particleID) {
834 err <<
"Unkown primary particle type " << particleID;
845 const double Xfirst = simShower.
GetXFirst();
847 if (Xfirst < atmDepthMin) {
849 info <<
"Xfirst is out of the bounds of the atmosphere. X1=" << Xfirst/
g*
cm2
850 <<
", Xmin=" << atmDepthMin/
g*
cm2 ;
855 double height1 = heightVsSlantDepth.
Y(atmDepthMin);
856 double height2 = heightVsSlantDepth.
Y(Xfirst);
857 double dist1 = distanceVsSlantDepth.
Y(atmDepthMin);
858 double dist2 = distanceVsSlantDepth.
Y(Xfirst);
859 double distInitFinal =
std::abs(dist2 - dist1);
861 int nPoints = std::min(10000,
int(distInitFinal / delta));
862 dist1 = dist2 - nPoints*delta;
865 info <<
"track primary from depth="
866 << atmDepthMin/
g*
cm2 <<
" g/cm2, dist=" << dist1/
m <<
" m, height=" << height1/
m <<
" m; "
867 "point of first interaction at "
868 << Xfirst/(
g/
cm2) <<
" " << dist2/
m <<
" " << height2/
m;
873 const unsigned int nWaves = wavelength.size();
876 const double minHeight = refractiveIndex.
MinX();
877 const double maxHeight = refractiveIndex.
MaxX();
878 const double minRI = refractiveIndex.
Y(maxHeight);
881 const double minRIdepth = depthVsHeight.
Y(maxHeight);
883 double maxWaveBin = wavelength[0] - (wavelength[1] - wavelength[0])/2;
884 for (
unsigned int wl = 0; wl < nWaves; ++wl) {
887 double minWaveBin = maxWaveBin;
890 maxWaveBin = wavelength[wl] + (wavelength[wl] - wavelength[wl-1])/2.;
892 maxWaveBin = (wavelength[wl] + wavelength[wl+1])/2.;
894 double lambda1 = minWaveBin;
895 double lambda2 = maxWaveBin;
897 vector<double> vPhotons;
898 vector<double> vPhotonsBeam;
899 vector<double> vDist;
902 for (
int i = 0; i < nPoints*1.5; ++i) {
904 double distBin1 = dist1 + delta * i;
905 double distBin2 = dist1 + delta * (i + 1);
906 double dist = (distBin2 + distBin1)/2.;
908 Point p1 = core + distBin1*axis;
909 Point p2 = core + distBin2*axis;
910 Point p = core + dist*axis;
913 if (height < atmHeightMin)
916 vDist.push_back(dist);
919 vPhotons.push_back(0);
920 vPhotonsBeam.push_back(0);
931 double attenuation = mie * rayleight;
934 double vertDepth = depthVsHeight.
Y(height);
935 double n_height = (minRI - 0.000283) + 0.000283 * (vertDepth/minRIdepth);
936 if (height > minHeight && height < maxHeight) {
937 n_height = refractiveIndex.
Y(height);
940 double lambda = (lambda1 + lambda2)/2 / (1e-10*
m);
941 double n = n_height + 1e-7 * (2726.42 + 12.288/(lambda*lambda*1e-8) + 0.3555/(lambda*lambda*lambda*lambda+1.e-16) );
945 double dNdl = Z*Z * 2.*
kPi * 1./137. * (1.-1./(
pow(n*beta, 2))) * (-1) * (1./lambda2 - 1./lambda1);
947 if (i >= nPoints-1) {
957 beam += dNdl * delta;
960 vPhotons.push_back(dNdl);
961 vPhotonsBeam.push_back(beam);
969 simShower.AddPrimaryCherenkovPhotons(cher, wl);
970 simShower.AddPrimaryCherenkovBeamPhotons(cherBeam, wl);
972 ERROR(
"You cannot us primary particle cherenkov light, without compiling with -DPRIM_CHER !!! ");
Branch GetTopBranch() const
double GetEnergyCutoff(const ProfileType type=eElectron) const
Get the energy cutoff for which the profile of charged particles was calculated.
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Get the Auger coordinate system associated to the shower core position.
int GetPrimaryParticle() const
Get the type of the shower primary particle.
unsigned int GetNPoints() const
const utl::TabulatedFunction & EvaluateFluorescenceYield(const double heightAboveSeaLevel) const
Evaluated Fluorescence Yield for a specific model.
const utl::TabulatedFunction & GetdEdX() const
Get the energy deposit of the shower.
atm::AttenuationResult EvaluateMieAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
double GetMinCherenkovWavelength() const
Get the minimal Cherenkov wavelength for photons in longitudinal profile.
Base class for all exceptions used in the auger offline code.
const std::vector< double > & GetWavelengths(const EmissionMode mode=eFluorescence) const
const utl::TabulatedFunction & GetCherenkovBeamProductionPhotons(const int wavelength) const
Get the cherenkov beam production along the shower axis.
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
const atm::ProfileResult & EvaluateHeightVsSlantDepth() const
Table of height as a function of slant depth.
bool HasCherenkovBeamProductionPhotons(const int wavelength) const
const evt::VGaisserHillasParameter & GetGHParameters() const
Get the Gaisser-Hillas parameters of the shower.
void AddCherenkovBeamPhotons(const utl::TabulatedFunction &cp, const int wavelength)
Class to hold collection (x,y) points and provide interpolation between them.
bool HasCherenkovPhotons(const int wavelength) const
void CherenkovLight(evt::Event &event, double distInit, double distFinal, bool upwardGoing, bool useCherenkovProfile)
Simulate the Cherenkov light beam along the shower axis.
const atm::ProfileResult & EvaluateDensityVsHeight() const
Tabulated function giving Y=density as a function of X=height.
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
bool HasSimShower() const
const utl::TabulatedFunction & GetFluorescencePhotons(const int wavelength) const
Get the fluorescence photons generated along the shower axis.
bool HasFluorescencePhotons(const int wavelength) const
const atm::ProfileResult & EvaluateDistanceVsSlantDepth() const
Table of distance as a function of slant depth.
const utl::TabulatedFunction & GetCherenkovBeamPhotons(const int wavelength) const
Get the beam of Cherenkov beam photons along the shower axis.
#define INFO(message)
Macro for logging informational messages.
bool HasCherenkovBeamPhotons(const int wavelength) const
double GetMaxCherenkovWavelength() const
Get the maximal Cherenkov wavelength for photons in longitudinal profile.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
double pow(const double x, const unsigned int i)
fwk::VModule::ResultFlag Run(evt::Event &event)
Run: invoked once per event.
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
Line Intersection(const Plane &p1, const Plane &p2)
Interface class to access Shower Simulated parameters.
const atm::Atmosphere & GetAtmosphere() const
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
const utl::TabulatedFunction & GetCherenkovPhotons(const int wavelength) const
Get the Cherenkov photon production along the shower axis.
double GetXFirst() const
Get depth of first interaction.
Class representing a document branch.
Reference ellipsoids for UTM transformations.
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
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.
double abs(const SVector< n, T > &v)
atm::AttenuationResult EvaluateRayleighAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
Compute Rayleigh attenuation between points.
Top of the hierarchy of the detector description interface.
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
const atm::ProfileResult & EvaluateDepthVsHeight() const
Tabulated function giving Y=depth as a function of X=height.
Iterator Insert(const double x, const double y)
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
void AddCherenkovBeamProductionPhotons(const utl::TabulatedFunction &fp, const int wavelength)
const double & GetY(const unsigned int idx) const
bool HasdEdX() const
Check initialization of the energy deposit.
void PrimaryCherenkovLight(evt::Event &event)
Generate Cherenkov emission from primary particle.
void AddCherenkovPhotons(const utl::TabulatedFunction &cp, const int wavelength)
constexpr double kSpeedOfLight
double MinX() const
Return the minimum value for X (ordinate) stored in the profile.
ResultFlag
Flag returned by module methods to the RunController.
double ShowerAge(const double slantDepth, const double showerMax)
General definition of shower age.
electron/positron profile
bool HasGHParameters() const
Check initialization of the Gaisser-Hillas parameters.
const utl::TabulatedFunction & EvaluateCherenkovPhotons(const utl::Point &xA, const utl::Point &xB, const double showerAge) const
execption handling for calculation/access for inclined atmosphere model
void AddFluorescencePhotons(const utl::TabulatedFunction &fp, const int wavelength)
double GetdEdX0() const
get reference energy deposit for fluorescence yield model
void FluorescenceLight(evt::Event &event, double distInit, double distFinal, bool upwardGoing)
Simulate the Fluorescence photons generated isotropically along the shower axis.
void SetCherenkovEnergyCutoff(const double eCut) const
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
const atm::ProfileResult & EvaluateHeightVsDepth() const
Tabulated function giving Y=height as a function of X=depth.
const atm::ProfileResult & EvaluateRefractionIndexVsHeight() const
Tabulated function giving Y=refraction index as a function of X=height.
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
const atm::ProfileResult & EvaluateSlantDepthVsDistance() const
#define ERROR(message)
Macro for logging error messages.
const std::string & GetMessage() const
Retrieve the message from the exception.
bool HasLongitudinalProfile(const ProfileType type=eCharged) const
Check initialization of the longitudinal profile.
utl::CoordinateSystemPtr GetShowerCoordinateSystem() const
Class describing the Atmospheric attenuation.
const atm::ProfileResult & EvaluateTemperatureVsHeight() const
Tabulated function giving Y=temperature as a function of X=height.
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
const utl::TabulatedFunction & GetLongitudinalProfile(const ProfileType type=eCharged) const
Get the longitudinal charge profile of the shower.
const atm::ProfileResult & EvaluateHeightVsDistance() const
Table of height as a function of distance.