8 #include <boost/io/ios_state.hpp>
10 #include <utl/Vector.h>
11 #include <utl/UTMPoint.h>
12 #include <utl/AugerUnits.h>
13 #include <utl/AugerException.h>
14 #include <utl/MathConstants.h>
15 #include <utl/PhysicalConstants.h>
16 #include <utl/PhysicalFunctions.h>
17 #include <utl/TabulatedFunctionErrors.h>
19 #include <det/Detector.h>
21 #include <atm/ProfileResult.h>
22 #include <atm/Atmosphere.h>
23 #include <atm/ScatteringResult.h>
24 #include <atm/AttenuationResult.h>
26 #include <det/Detector.h>
27 #include <fdet/FDetector.h>
29 #include <fwk/CentralConfig.h>
30 #include <fwk/CoordinateSystemRegistry.h>
31 #include <fwk/RandomEngineRegistry.h>
32 #include <utl/UTMPoint.h>
33 #include <utl/ReferenceEllipsoid.h>
34 #include <CLHEP/Random/RandFlat.h>
35 #include <utl/RandomEngine.h>
37 using CLHEP::RandFlat;
46 using namespace oBLAS;
49 using namespace FdProfileReconstructorKG;
57 CherenkovFluorescenceMatrix::CherenkovFluorescenceMatrix(
58 const double xMax,
const utl::Point& eyePosition,
59 const std::deque<std::vector<utl::Point>>& showerGeometry,
61 const std::deque<double>& depth,
62 const double eCut,
const double zeta,
const double cFac,
const double fFac,
67 const bool cherenkovCone,
72 fEyePosition(eyePosition),
73 fShowerGeometry(showerGeometry),
83 fCherenkovCone(cherenkovCone),
84 fOpticalHalo(spotHalo)
87 cout <<
" -->CherenkovFluorescenceMatrix()" << endl;
92 for (
unsigned int i = 0; i < nDepth; ++i)
132 cout <<
" -->~CherenkovFluorescenceMatrix()" << endl;
146 cout <<
" -->CalculateFluorescenceMatrix()" << endl;
152 const auto& atmo = det::Detector::GetInstance().GetAtmosphere();
154 const double dEdX0 = atmo.GetdEdX0();
161 for (
unsigned int i = 0, n =
fShowerPoints.size(); i < n; ++i) {
166 const double disteye = (meanPos -
fEyePosition).GetMag();
175 cout << d.GetExceptionName() << endl;
176 const ProfileResult& densityProfile = atmo.EvaluateDensityVsHeight();
177 height = densityProfile.
MaxX();
180 const auto& fluoyield_tab = atmo.EvaluateFluorescenceYield(height);
183 for (
unsigned int j = 0, n = lambdaVec.size(); j < n; ++j) {
184 const double y_j = fluoyield_tab.Y(lambdaVec[j]) *
fFfac;
193 flMat(i, i) = msFactor * spotFraction * zetaFraction * epsYTsum *
fGfac[i] / dEdX0 * deltaL;
204 cout <<
" -->GetWaveLengths()" << endl;
208 const auto& atmo = det::Detector::GetInstance().GetAtmosphere();
210 fCWaveLength = atmo.GetWavelengths(Atmosphere::eCerenkov);
211 fFWaveLength = atmo.GetWavelengths(Atmosphere::eFluorescence);
214 const double effMinLam =
fRelEff[0].X();
218 const auto& lam = *it;
219 if (effMinLam <= lam && lam <= effMaxLam &&
fRelEff.
Y(lam) > 0)
226 const auto& lam = *it;
227 if (effMinLam <= lam && lam <= effMaxLam)
240 cout <<
" -->CalculateDirectCherenkovMatrix()" << endl;
246 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
258 const double disteye = (meanPos -
fEyePosition).GetMag();
259 const double spotFraction =
267 for (
unsigned int j = 0; j < lambdaVec.size(); ++j) {
268 const double y_j = directCherenkov.
GetY(j) *
fCfac;
272 const double msFactor =
276 cDirMat(i, i) = msFactor * spotFraction * zetaFraction * epsYTsum /
fMeandEdX[i];
285 cout <<
" -->CalculateMieAndRayScattCherenkovMatrix()" << endl;
291 cerr <<
" CalculateMieAndRayScattCherenkovMatrix() "
292 <<
" Error - no multiple scattering factors " << endl;
298 const unsigned int nLambda = lambdaVec.size();
310 const double disteye = (meanPos -
fEyePosition).GetMag();
311 const double spotFraction =
316 for (
unsigned int k = 0; k < nLambda; ++k)
319 for (
int j = i; j >= 0; --j) {
320 double epsYTsumMie = 0;
321 double epsYTsumRay = 0;
322 for (
unsigned int k = 0; k < nLambda; ++k) {
326 const double detEff =
fRelEff.
Y(lambdaVec[k]);
332 const double zetaPerAlpha = zetaFraction /
fMeandEdX[j];
333 cMieMat(i, j) = msFactor * spotFraction * zetaPerAlpha * epsYTsumMie;
334 cRayMat(i, j) = msFactor * spotFraction * zetaPerAlpha * epsYTsumRay;
346 cout <<
" -->CalculateAttenuationToEye()" << endl;
353 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
357 const unsigned int nCLambda = lambdaCVec.size();
358 std::vector<double> tC(nCLambda);
360 const unsigned int nFLambda = lambdaFVec.size();
361 std::vector<double> tF(nFLambda);
378 for (
unsigned int j = 0; j < nCLambda; ++j) {
379 tC[j] = mieCAtt.
GetY(j) * rayCAtt.
GetY(j);
394 for (
unsigned int j = 0; j < nFLambda; ++j) {
395 tF[j] = mieFAtt.
GetY(j) * rayFAtt.
GetY(j);
409 cout <<
" -->CalculateAttenuationAlongTrack()" << endl;
415 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
419 const unsigned int nLambda = lambdaVec.size();
420 std::vector<double> transmission(nLambda);
438 for (
unsigned int k = 0; k < nLambda; ++k) {
439 transmission[k] = mieAtt.
GetY(k) * rayAtt.
GetY(k);
453 cout <<
" -->CalculateScatteringToEye()" << endl;
460 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
464 const unsigned int nLambda = lambdaVec.size();
465 std::vector<double> tR(nLambda);
466 std::vector<double> tM(nLambda);
476 const double disteye = meanVec.
GetMag();
479 const double angle =
Angle(-shwDir,meanVec);
483 fShowerGeometry[i][1],
484 angle, disteye, lambdaVec);
487 fShowerGeometry[i][1],
488 angle, disteye, lambdaVec);
493 for (
unsigned int j = 0; j < nLambda; ++j) {
494 tR[j] = rayleighScattTrackEye.
GetY(j);
495 tM[j] = mieScattTrackEye.
GetY(j);
510 cout <<
" -->CalculateCherenkovAtTrack()" << endl;
514 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
520 const unsigned int nLambda = lambdaVec.size();
521 std::vector<double> t(nLambda);
527 for (
unsigned int j = 0; j < nLambda; ++j) {
541 cout <<
" -->CalculateGeometricalFactor()" << endl;
548 const double rSquared = r.
GetMag2();
549 fGfac.push_back(1/(fourPi*rSquared));
574 cout <<
" -->GetCherenkovFluorescenceMatrix()" << endl;
590 for (
unsigned int i = 0, n =
fShowerPoints.size(); i < n; ++i) {
591 tot(i, i) = fl(i, i) + dc(i, i) + rc(i, i) + mc(i, i);
592 for (
unsigned int j = 0; j < i; ++j)
593 tot(i, j) = rc(i, j) + mc(i, j);
607 cout <<
" -->updateXmax()" << endl;
688 const double maxEmissionAngle = atan2(zetaDistance, pathLength);
690 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
699 cout << d.GetExceptionName() << endl;
700 height = depthProfile.
MaxX();
703 const double xVert = depthProfile.
Y(height);
704 const double xSlant =
fDepth[jOrigin];
707 const double minValidCherenkovAngle = 5*
utl::degree;
722 const double xVert,
const double showerAge)
726 const int nMC = 1000;
728 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
732 const double cosThetaCher = 1/nRefrac;
733 const double sinThetaCher =
sqrt(1 - cosThetaCher*cosThetaCher);
740 std::vector<double> cdf;
743 double thisAngle = 0;
745 while (thisAngle <= maxIntegrationAngle) {
747 cdf.push_back(cumulative);
748 thisAngle += angularBinning;
752 RandomEngineRegistry::GetInstance().Get(RandomEngineRegistry::ePhysics);
754 std::vector<double> randomNumbers1(nMC);
755 std::vector<double> randomNumbers2(nMC);
757 RandFlat::shootArray(&theRandom.
GetEngine(), nMC, &randomNumbers1.front());
758 RandFlat::shootArray(&theRandom.
GetEngine(), nMC, &randomNumbers2.front());
762 const double cosThetaEmission = cos(maxEmissionAngle);
766 for (
int i = 0; i < nMC; ++i) {
767 const double x = randomNumbers1[i];
768 double alpha = maxIntegrationAngle;
769 for (
unsigned int k = 0, n = cdf.size()-1; k < n; ++k) {
770 if (x > cdf[k] && x < cdf[k+1]) {
771 alpha = k*angularBinning + angularBinning/(cdf[k] - cdf[k+1]) * (cdf[k] - x);
777 const double cosTheta = sinThetaCher*cos(phi)*sin(alpha) + cos(alpha)*cosThetaCher;
779 if (cosTheta > cosThetaEmission)
783 const double fractionWithinEmissionAngle = double(nInsideZeta) / nMC;
790 return fractionWithinEmissionAngle;
799 const std::vector<double>& waveLengths,
803 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
834 double yieldEffSum = 0;
835 double yieldEffAttEyeSum = 0;
836 double yieldEffAttBinSum = 0;
838 for (
unsigned int j = 0, n = waveLengths.size(); j < n; ++j) {
839 const double y_j = yield.
Y(waveLengths[j]);
840 const double eff =
fRelEff.
Y(waveLengths[j]);
841 const double attEye = rayAttShowerToEye.
GetY(j) * mieAttShowerToEye.
GetY(j);
842 const double attBin = rayAttInBin.
GetY(j) * mieAttInBin.
GetY(j);
844 const double yEff = y_j * eff;
846 yieldEffAttEyeSum += yEff * attEye;
847 yieldEffAttBinSum += yEff * attBin;
854 const double attenuationToEye = yieldEffAttEyeSum / yieldEffSum;
855 const double attenuationInBin = yieldEffAttBinSum / yieldEffSum;
857 const double opticalDepth = attenuationToEye > 0 ?
858 -log(attenuationToEye) :
860 const double alphaTot = attenuationInBin > 0 ?
861 -log(attenuationInBin)/binLength :
865 const double argument = opticalDepth * alphaTot/
utl::m *
868 const double fraction = 0.774 *
pow(argument, 0.68);
879 const std::vector<double>& waveLengths,
883 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
900 double yieldEffSum = 0;
901 double yieldEffAttEyeSum = 0;
903 for (
unsigned int j = 0, n = waveLengths.size(); j < n; ++j) {
904 const double y_j = yield.
Y(waveLengths[j]);
905 const double eff =
fRelEff.
Y(waveLengths[j]);
906 const double attEye = rayAttShowerToEye.
GetY(j) * mieAttShowerToEye.
GetY(j);
908 const double yEff = y_j * eff;
910 yieldEffAttEyeSum += yEff * attEye;
913 const double attenuationToEye = yieldEffAttEyeSum / yieldEffSum;
915 const double opticalDepth = attenuationToEye > 0 ?
916 -log(attenuationToEye) :
924 cout << d.GetExceptionName() << endl;
931 const double f = 4.2947e-2;
934 const double fraction1 = f * opticalDepth * (
fZeta/
utl::degree) * exp(-height/g);
937 const double fraction2 = fraction1 / (fraction1 + 1);
952 const double alpha = 1.65;
953 const double beta = 325.*
utl::m;
954 const double fraction = 1 - exp(-
pow(r/beta, alpha));
967 const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
985 cout << d.GetExceptionName() << endl;
986 height = depthProfile.
MaxX();
989 const double xSlant =
fDepth[iPosition];
990 const double pressure = pressureProfile.
Y(height);
991 const double temperature = tempProfile.
Y(height);
1016 const std::vector<double>& waveLengths,
1051 const double chkovFac)
1059 const double fluoRescale = fluoFac /
fFfac;
1060 const double chkovRescale = chkovFac /
fCfac;
1062 for (
unsigned int i = 0, n =
fShowerPoints.size(); i < n; ++i) {
1063 fl(i, i) *= fluoRescale;
1064 dc(i, i) *= chkovRescale;
1065 rc(i, i) *= chkovRescale;
1066 mc(i, i) *= chkovRescale;
1067 tot(i, i) = fl(i, i) + dc(i, i) + rc(i, i) + mc(i, i);
1068 for (
unsigned int j = 0; j < i; ++j) {
1069 rc(i, j) *= chkovRescale;
1070 mc(i, j) *= chkovRescale;
1071 tot(i, j) = rc(i, j) + mc(i, j);
1088 boost::io::ios_all_saver save(cout);
1089 cout.flags(std::ios::scientific);
1094 const unsigned int nLambda = lambdaVec.size();
1097 cout <<
"\n wave lengths:\n";
1098 for (
unsigned int j = 0; j < nLambda; ++j)
1099 cout << std::setw(9) << lambdaVec[j];
1102 cout <<
"\n transmission to eye:\n";
1104 for (
unsigned int j = 0; j < nLambda; ++j)
1105 cout << std::setw(9) <<
fCT2eye[i][j];
1108 }
else if (iwhat == 1) {
1111 cout << std::setw(9) << i
1112 << std::setw(9) << lambdaVec[kLam]
1114 << std::setw(9) <<
fCT2eye[i][kLam]
double AngularCherenkovCDFWithCone(const double maxEmissionAngle, const double xVert, const double showerAge) const
std::vector< double > fCWaveLength
unsigned int GetNPoints() const
Top of the interface to Atmosphere information.
std::vector< std::vector< double > > fMieScat2eye
double GoraCDF(const double rStar, const double age)
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
oBLAS::lowerTriangularMatrix * fRayleighScatteredCherenkovMatrix
std::vector< double > fFWaveLength
atm::AttenuationResult EvaluateMieAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
void CalculateWaveLengths()
eMultipleScatteringLDF fMultScatLDF
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
std::vector< double > fCherenkovMultipleScattering
RandomEngineType & GetEngine()
std::vector< double > fMeandEdX
Class to hold and convert a point in geodetic coordinates.
Class to hold collection (x,y) points and provide interpolation between them.
const atm::ProfileResult & EvaluatePressureVsHeight() const
Tabulated function giving Y=air pressure as a function of X=height.
double RobertsFraction(const int, const std::vector< double > &, const utl::TabulatedFunction &) const
const utl::Point & fEyePosition
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
const atm::ProfileResult & EvaluateDensityVsHeight() const
Tabulated function giving Y=density as a function of X=height.
double ScatteredCherenkovLDFFraction(const int, const int) const
void CalculateMeanEnergyDeposit()
void SetZeta(const double z)
set zeta
double pow(const double x, const unsigned int i)
Report attempts to use invalid UTM zone.
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
std::vector< double > fGfac
std::vector< std::vector< double > > fFT2eye
Exception for reporting variable out of valid range.
Class holding the output of the ScatteringResult function.
~CherenkovFluorescenceMatrix()
void CalculateAttenuationAlongTrack()
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
double AngularCherenkovCDF(const double theta, const double verticalDepth, const double showerAge) const
cumulative of angular Cherenkov distribution from 0 to theta
std::vector< std::vector< double > > fCT2eye
oBLAS::lowerTriangularMatrix * fCherenkovFluorescenceMatrix
void CalculateMieAndRayScattCherenkovMatrix()
double GetHeight() const
Get the height.
double GetHaloFraction(const double zeta, const double age, const double dist) const
double MoliereRadius(double temperature, double pressure, const double cosTheta)
The Moliere Radius (2 radiation length above obs-level, GAP-1998-002)
Wraps the random number engine used to generate distributions.
Class describing the Atmospheric profile.
const utl::TabulatedFunction & EvaluateCherenkovDirect(const utl::Point &xA, const utl::Point &xB, const utl::Point &xEye, const double showerAge) const
void UpdateXmax(const double)
update matrices for new xmax value
const std::deque< std::vector< utl::Point > > & fShowerGeometry
constexpr double fraction
atm::AttenuationResult EvaluateRayleighAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
Compute Rayleigh attenuation between points.
std::vector< std::vector< double > > fRayScat2eye
double GetZetaDistance(const int) const
get distance to shower axis corresponding to zeta
const std::deque< double > & fDepth
const atm::ProfileResult & EvaluateDepthVsHeight() const
Tabulated function giving Y=depth as a function of X=height.
static const ReferenceEllipsoid & GetWGS84()
Get the auger standard ellipsoid: wgs84.
atm::ScatteringResult EvaluateRayleighScattering(const utl::Point &xA, const utl::Point &xB, const double angle, const double distance, const std::vector< double > &xLength) const
double ExponentialFraction(const int) const
void CalculateDirectCherenkovMatrix()
std::vector< std::vector< double > > fTShower
void CalculateCherenkovAtTrack()
const oBLAS::lowerTriangularMatrix * GetCherenkovFluorescenceMatrix() const
returns total light matrix (not const as we eventually want to invert it ...)
void CalculateFluorescenceMatrix()
double GoraFraction(const int) const
const double & GetY(const unsigned int idx) const
double LorentzLorentz(const double verticalDepth)
Calculate the refraction index for a given depth.
void SetYieldFactors(const double fluoFac, const double chkovFac)
set yield factors
std::vector< double > fFluorescenceMultipleScattering
const utl::TabulatedFunctionErrors & GetScatteringFactor() const
Scattering factor.
oBLAS::diagonalMatrix * fDirectCherenkovMatrix
oBLAS::diagonalMatrix * fFluorescenceMatrix
eFluorescenceLDF fFluoLDF
double ShowerAge(const double slantDepth, const double showerMax)
General definition of shower age.
eDirectCherenkovLDF fDirCherLDF
void CalculateGeometricalFactor()
const utl::TabulatedFunction & EvaluateCherenkovPhotons(const utl::Point &xA, const utl::Point &xB, const double showerAge) const
double EnergyDeposit(const double age, const double enCut)
Parametrization for the average energy deposit per particle.
double MultipleScatteringFraction(const int, const std::vector< double > &, const utl::TabulatedFunction &) const
void Print(const int iwhat) const
const utl::TabulatedFunction & fRelEff
double DirectCherenkovLDFFraction(const int) const
double GillerFraction(const int, const int) const
double FluorescenceLDFFraction(const int) const
eScatteredCherenkovLDF fScatCherLDF
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
std::vector< std::vector< double > > fCherAtTrack
std::vector< utl::Point > fShowerPoints
void CalculateAttenuationToEye()
double PekalaFraction(const int, const std::vector< double > &, const utl::TabulatedFunction &) const
const atm::ProfileResult & EvaluateTemperatureVsHeight() const
Tabulated function giving Y=temperature as a function of X=height.
Class describing the Atmospheric attenuation.
oBLAS::lowerTriangularMatrix * fMieScatteredCherenkovMatrix
double MaxX() const
Return the maximum value for X (ordinate) stored in the profile.
void CalculateScatteringToEye()
atm::ScatteringResult EvaluateMieScattering(const utl::Point &xA, const utl::Point &xB, const double angle, const double distance, const std::vector< double > &xLength) const