AirFluorescenceModel.cc
Go to the documentation of this file.
1 
9 #include <sstream>
10 #include <fstream>
11 #include <utl/TabulatedFunction.h>
12 #include <utl/Reader.h>
13 #include <utl/ErrorLogger.h>
14 #include <utl/PhysicalConstants.h>
15 #include <fwk/CentralConfig.h>
16 #include <det/Detector.h>
17 #include <atm/Atmosphere.h>
18 #include <atm/ProfileResult.h>
19 #include <atm/AirFluorescenceModel.h>
20 
21 using namespace utl;
22 using namespace atm;
23 using namespace fwk;
24 using namespace std;
25 
26 
27 void
29 {
30  Branch topB = CentralConfig::GetInstance()->GetTopBranch("AirFluorescenceModel");
31 
32  string dataSetSelection;
33  topB.GetChild("DataSetSelection").GetData(dataSetSelection);
34 
35  Branch dataSetBranch;
36 
37 //#warning Kakimoto and Keilhauer data sets are not fully implemented
38 
39  if (dataSetSelection == "eAuger")
40  dataSetBranch = topB.GetChild("AugerFluorescenceYieldDataSet");
41  else if (dataSetSelection == "eNagano")
42  dataSetBranch = topB.GetChild("NaganoFluorescenceYieldDataSet");
43  else if (dataSetSelection == "eKakimoto")
44  dataSetBranch = topB.GetChild("KakimotoFluorescenceYieldDataSet");
45  else if (dataSetSelection == "eKeilhauer")
46  dataSetBranch = topB.GetChild("KeilhauerFluorescenceYieldDataSet");
47  else if (dataSetSelection == "eUserDefined")
48  dataSetBranch = topB.GetChild("UserDefinedFluorescenceYieldDataSet");
49  else {
50  ERROR("DataSet not implemented");
52  }
53 
54  dataSetBranch.GetChild("wavelength").GetData(fWavelength);
55  dataSetBranch.GetChild("relativeIntensity").GetData(fRelativeIntensity);
56  dataSetBranch.GetChild("relativeIntensityError").GetData(fRelativeIntensityError);
57  dataSetBranch.GetChild("pPrime").GetData(fPPrime);
58  dataSetBranch.GetChild("pPrimeErrorUncorrelated").GetData(fPPrimeErrorUncorrelated);
59  dataSetBranch.GetChild("pPrimeErrorCorrelated").GetData(fPPrimeErrorCorrelated);
60 
61  const string temp = dataSetBranch.GetChild("collisionalCrossSection").Get<string>();
62  if (temp == "eAIRtemp")
63  fTempParam = eAIRtemp;
64  else if (temp == "eNONE")
65  fTempParam = eNoTempParam;
66  else {
67  ERROR("Parametrization not implemented");
69  }
70  dataSetBranch.GetChild("alpha").GetData(fAlpha);
71 
72  const string water = dataSetBranch.GetChild("collisionalCrossSectionWater").Get<string>();
73  if (water == "eAIRWatertemp")
74  fTempWaterParam = eAIRWatertemp;
75  else if (water == "eNONE")
76  fTempWaterParam = eNoWaterTempParam;
77  else {
78  ERROR("Parametrization not implemented");
80  }
81 
82  dataSetBranch.GetChild("alphaWater").GetData(fAlphaWater);
83 
84  const string hum = dataSetBranch.GetChild("humidity").Get<string>();
85  if (hum == "eAIRhum")
86  fHumParam = eAIRhum;
87  else if (hum == "eNONE")
88  fHumParam = eNoHumParam;
89  else {
90  ERROR("Parametrization not implemented");
92  }
93 
94  dataSetBranch.GetChild("pPrimeWater").GetData(fPPrimeHum);
95 
96  dataSetBranch.GetChild("temperature0").GetData(fTemperature0);
97  dataSetBranch.GetChild("pressure0").GetData(fPressure0);
98  dataSetBranch.GetChild("yield337").GetData(fYield337);
99 
100  ostringstream info;
101  info << "Version:\n"
102  "Parameters:\n"
103  " DataSet: " << dataSetSelection << "\n"
104  " yield337: " << fYield337/(1/MeV) << " [1/MeV]\n"
105  " ref temperature: " << fTemperature0/kelvin << " [kelvin]\n"
106  " ref pressure: " << fPressure0/100/pascal << " [100*pascal]\n"
107  " temp dependence: " << temp << "\n"
108  " hum dependence: " << hum << "\n"
109  " water temp dep: " << water << '\n';
110  INFO(info);
111 }
112 
113 
114 const
116 AirFluorescenceModel::EvaluateFluorescenceYield(const double heightAboveSeaLevel)
117  const
118 {
119  const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
120 
121  const ProfileResult& tempProfile = atmo.EvaluateTemperatureVsHeight();
122  const ProfileResult& densityProfile = atmo.EvaluateDensityVsHeight();
123  const ProfileResult& pressureProfile = atmo.EvaluatePressureVsHeight();
124  const ProfileResult& pvaporProfile = atmo.EvaluateVaporPressureVsHeight();
125 
126  const double temperature = tempProfile.Y(heightAboveSeaLevel);
127  const double density = densityProfile.Y(heightAboveSeaLevel);
128  const double pressure = pressureProfile.Y(heightAboveSeaLevel);
129  const double vaporPressure = pvaporProfile.Y(heightAboveSeaLevel);
130 
131  fFluorescenceSpectrum.Clear();
132  for (unsigned int iwl = 0; iwl < fWavelength.size(); ++iwl) {
133 
134  const double current_alpha = (fTempParam == eAIRtemp) ? fAlpha[iwl] : 0;
135  const double current_alpha_w = (fTempWaterParam == eAIRWatertemp) ? fAlphaWater[iwl] : 0;
136  const double current_pprime_w = (fHumParam == eAIRhum) ? fPPrimeHum[iwl] : 0;
137 
138  double pprime = fPPrime[iwl] * pow(fTemperature0/temperature, current_alpha - 0.5);
139  // P'(lambda,T) = P'(lambda,T_0)(T_0/T)^(alpha-1/2)
140 
141  const double pprime_w = current_pprime_w*pow(fTemperature0/temperature, current_alpha_w - 0.5);
142  /* In a near future, alpha values for water might be available. Presently alpha_w = 0 for all wavelengths.
143  P'_w(lambda,T) = P'_w(lambda,T_0)(T_0/T)^(alpha_w-1/2) */
144 
145  if (fHumParam == eAIRhum) {
146  if (pprime_w) {
147  pprime = (1/pprime) * (1 - vaporPressure/pressure) + vaporPressure / (pressure*pprime_w);
148  pprime = 1 / pprime;
149  }
150  }
151 
152  // Y(lambda,P,T) = Y(lambda,P_0,T_0) * (1 + P_0/(P'(lambda,T_0))) / (1+P/(P'(lambda,T)))
153  const double fluorescenceYield =
154  (fYield337 * fRelativeIntensity[iwl] * 0.01) *
155  (1 + fPressure0/fPPrime[iwl]) / (1 + pressure/pprime) *
156  density;
157 
158  fFluorescenceSpectrum.PushBack(fWavelength[iwl], fluorescenceYield);
159 
160  }
161 
162  return fFluorescenceSpectrum;
163 }
164 
165 
166 double
167 AirFluorescenceModel::GetdEdX0()
168  const
169 {
170  // Energy loss evaluated for an electron of 0.85 MeV
171  return 1; //.658*MeV/(g/cm/cm);
172 }
Branch GetTopBranch() const
Definition: Branch.cc:63
Top of the interface to Atmosphere information.
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.
const atm::ProfileResult & EvaluateDensityVsHeight() const
Tabulated function giving Y=density as a function of X=height.
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
Base class for exceptions trying to access non-existing components.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double pow(const double x, const unsigned int i)
double Y(const double x) const
Get the Y value (coordinate) for given X (ordinate)
constexpr double MeV
Definition: AugerUnits.h:184
T Get() const
Definition: Branch.h:271
Class representing a document branch.
Definition: Branch.h:107
constexpr double pascal
Definition: AugerUnits.h:212
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
constexpr double kelvin
Definition: AugerUnits.h:259
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
const atm::ProfileResult & EvaluateVaporPressureVsHeight() const
Tabulated function giving Y=H20 vapor pressure as a function of X=height.
const atm::ProfileResult & EvaluateTemperatureVsHeight() const
Tabulated function giving Y=temperature as a function of X=height.

, generated on Tue Sep 26 2023.