USStdADBProfileModel.cc
Go to the documentation of this file.
1 
9 #include <utl/Reader.h>
10 #include <utl/ErrorLogger.h>
11 #include <utl/AugerException.h>
12 #include <utl/AugerUnits.h>
13 #include <utl/MathConstants.h>
14 #include <utl/TabulatedFunction.h>
15 #include <utl/PhysicalConstants.h>
16 #include <utl/PhysicalFunctions.h>
17 
18 #include <fwk/CentralConfig.h>
19 
20 #include <atm/USStdADBProfileModel.h>
21 #include <atm/MolecularDB.h>
22 #include <atm/ProfileResult.h>
23 #include <atm/MolecularLayer.h>
24 #include <atm/MolecularZone.h>
25 #include <atm/ProfileResult.h>
26 #include <det/Detector.h>
27 
28 #include <iostream>
29 #include <string>
30 #include <sstream>
31 #include <vector>
32 
33 using namespace atm;
34 using namespace fwk;
35 using namespace std;
36 using namespace utl;
37 
38 
39 // For some reason, CLHEP SystemOfUnits.h
40 // #defines pascal to hep_pascal, putting it in
41 // the global namespace and screwing up our own
42 // definition of pascal from AugerUnits.h. It appears
43 // the CLHEP units are being pulled in via the geometry
44 // package. The following line undoes the CLHEP sabotage.
45 #undef pascal
46 
47 
48 bool
50  const
51 {
52  if (fTablesFilled)
53  return true;
54  FillTables();
55  if (fTablesFilled)
56  return true;
57  return false;
58 }
59 
60 
61 const ProfileResult&
63  const
64 {
65  if (!fTablesFilled)
66  FillTables();
67  return *fTabLogPressureVsHeight;
68 }
69 
70 
71 const ProfileResult&
73  const
74 {
75  if (!fTablesFilled)
76  FillTables();
77  return *fTabTemperatureVsHeight;
78 }
79 
80 
81 const ProfileResult&
83  const
84 {
85  if (!fTablesFilled)
86  FillTables();
87  return *fTabLogVaporPressureVsHeight;
88 }
89 
90 
91 const ProfileResult&
93  const
94 {
95  if (!fTablesFilled)
96  FillTables();
97  return *fTabLogDensityVsHeight;
98 }
99 
100 
101 const ProfileResult&
103  const
104 {
105  if (!fTablesFilled)
106  FillTables();
107  return *fTabLogDepthVsHeight;
108 }
109 
110 
111 const ProfileResult&
113  const
114 {
115  if (!fTablesFilled)
116  FillTables();
117  return *fTabHeightVsLogDepth;
118 }
119 
120 
121 const ProfileResult&
123  const
124 {
125  if (!fTablesFilled)
126  FillTables();
127  return *fTabRIVsHeight;
128 }
129 
130 
131 void
133  const
134 {
135  const MolecularDB& mDB =
136  det::Detector::GetInstance().GetAtmosphere().GetMolecularDB(MolecularIds::eUSStdA);
137 
138  TabulatedFunctionErrors tabLogDensityVsHeight;
139  TabulatedFunctionErrors tabRIVsHeight;
140  TabulatedFunctionErrors tabLogPressureVsHeight;
141  TabulatedFunctionErrors tabTemperatureVsHeight;
142  TabulatedFunctionErrors tabLogVaporPressureVsHeight;
143  TabulatedFunctionErrors tabLogDepthVsHeight;
144  TabulatedFunctionErrors tabHeightVsLogDepth;
145 
146  // Fill tabulated functions.
147  // Perform conversions into Auger base units.
148  int nZonesCheck = 0;
149  const double minLog = kLn10 * numeric_limits<double>::min_exponent10;
150 
151  for (MolecularDB::ZoneIterator zIt = mDB.ZonesBegin();
152  zIt != mDB.ZonesEnd(); ++zIt) {
153 
154  for (MolecularZone::LayerIterator lIt = zIt->LayersBegin();
155  lIt != zIt->LayersEnd(); ++lIt) {
156 
157  // TEMPORARY.. in case some entries in database are not ordered
158  // by ordinate, skip the unorder entries for now. This should be
159  // fixed automatically when TabulatedFunction is redesigned + reimplemented,
160  // at which time code up to 'END TEMPORARY' should be removed.
161 
162  if (lIt != zIt->LayersBegin()) {
163  MolecularZone::LayerIterator newIt = lIt;
164  if (newIt->GetHeight() <= (--newIt)->GetHeight())
165  break;
166  }
167  // END TEMPORARY patch to compensate shitty TabulatedFunction class
168 
169  tabLogDepthVsHeight.PushBack(
170  lIt->GetHeight(), lIt->GetHeightError(),
171  log(lIt->GetDepth()), lIt->GetDepthError() / lIt->GetDepth()
172  );
173 
174  const double refracIndex =
176  tabRIVsHeight.PushBack(
177  lIt->GetHeight(), 0, // ERRORS need to be computed
178  refracIndex, 0
179  );
180 
181  tabLogPressureVsHeight.PushBack(
182  lIt->GetHeight(), lIt->GetHeightError(),
183  log(lIt->GetPressure()), lIt->GetPressureError() / lIt->GetPressure()
184  );
185 
186  // Calculate vapor pressure from relative humidity
187  const double pSat = utl::SaturationVaporPressure(lIt->GetTemperature());
188  const double pVapor = lIt->GetHumidity() * pSat;
189  const double dpVapor = lIt->GetHumidityError() * pSat; // Ignore dT...
190 
191  tabLogVaporPressureVsHeight.PushBack(
192  lIt->GetHeight(), lIt->GetHeightError(),
193  (pVapor > 0) ? log(pVapor) : minLog, (pVapor > 0 && dpVapor > 0) ? pVapor / dpVapor : minLog
194  );
195 
196  tabTemperatureVsHeight.PushBack(
197  lIt->GetHeight(), lIt->GetHeightError(),
198  lIt->GetTemperature(), lIt->GetTemperatureError()
199  );
200 
201  tabLogDensityVsHeight.PushBack(
202  lIt->GetHeight(), lIt->GetHeightError(),
203  log(lIt->GetAirDensity()),
204  lIt->GetAirDensityError() / lIt->GetAirDensity()
205  );
206 
207  }
208 
209  MolecularZone::LayerIterator lIt = zIt->LayersEnd();
210  while (lIt != zIt->LayersBegin()) {
211  --lIt;
212 
213  // TEMPORARY.. in case some entries in database are not ordered
214  // by ordinate, skip the unorder entries for now. This should be
215  // fixed automatically when TabulatedFunction is redesigned + reimplemented,
216  // at which time code up to 'END TEMPORARY' should be removed.
217  if (lIt != --(zIt->LayersEnd())) {
218  MolecularZone::LayerIterator newIt = lIt;
219  if (newIt->GetHeight() >= (++newIt)->GetHeight())
220  break;
221  }
222  // END TEMPORARY patch to compensate shitty TabulatedFunction class
223 
224  tabHeightVsLogDepth.PushBack(
225  log(lIt->GetDepth()), lIt->GetDepthError() / lIt->GetDepth(),
226  lIt->GetHeight(), lIt->GetHeightError()
227  );
228  }
229  ++nZonesCheck;
230  }
231  if (nZonesCheck != 1) {
232  ostringstream msg;
233  msg << "Expected to find one zone in DB for US Std Atmosphere, but found"
234  << nZonesCheck;
235  DEBUGLOG(msg);
236  return;
237  }
238 
239  // create profile results
240  *fTabLogPressureVsHeight =
241  ProfileResult(tabLogPressureVsHeight, ProfileResult::eLinear, ProfileResult::eLog);
242 
243  *fTabLogVaporPressureVsHeight =
244  ProfileResult(tabLogVaporPressureVsHeight, ProfileResult::eLinear, ProfileResult::eLog);
245 
246  *fTabTemperatureVsHeight =
248 
249  *fTabLogDensityVsHeight =
251 
252  *fTabLogDepthVsHeight =
254 
255  *fTabHeightVsLogDepth =
257 
258  *fTabRIVsHeight =
260 
261  // Extend all tables to a height of 100 km
262  ExtendProfilesTo100km();
263 
264  fTablesFilled = true;
265 }
boost::transform_iterator< InternalZoneFunctor, InternalZoneIterator, const MolecularZone & > ZoneIterator
ZoneIterator returns a pointer to a MolecularZone.
Definition: MolecularDB.h:52
constexpr double atmosphere
Definition: AugerUnits.h:215
constexpr double kOverburdenSeaLevel
ZoneIterator ZonesEnd() const
End of the collection of valid Zones.
Definition: MolecularDB.h:59
Detector description interface for data in the Atm_Molecular database.
Definition: MolecularDB.h:29
const atm::ProfileResult & EvaluateDepthVsHeight() const override
Table of depth as a function of height.
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
#define DEBUGLOG(message)
Macro for logging debugging messages.
Definition: ErrorLogger.h:157
const atm::ProfileResult & EvaluateTemperatureVsHeight() const override
Table of temperature as a function of height.
double SaturationVaporPressure(const double temperature)
Evaluate the saturation vapor pressure over ice or water.
void PushBack(const double x, const double xErr, const double y, const double yErr)
constexpr double kLn10
Definition: MathConstants.h:29
ZoneIterator ZonesBegin() const
Beginning of the collection of valid Zones.
Definition: MolecularDB.h:55
double LorentzLorentz(const double verticalDepth)
Calculate the refraction index for a given depth.
bool HasData() const override
True if a data source is for the given model.
const ProfileResult & EvaluateVaporPressureVsHeight() const override
Table of H2O vapor pressure as a function of height.
boost::indirect_iterator< InternalLayerIterator, const MolecularLayer & > LayerIterator
Layer iterator returns a pointer to the molecular data slice for this zone.
Definition: MolecularZone.h:43
const atm::ProfileResult & EvaluateHeightVsDepth() const override
Table of height as a function of depth.
US standard atmosphere.
Definition: MolecularIds.h:41
const atm::ProfileResult & EvaluatePressureVsHeight() const override
Table of air pressure as a function of height.
const atm::ProfileResult & EvaluateRefractionIndexVsHeight() const override
Table of refraction index as a function of height.
const atm::ProfileResult & EvaluateDensityVsHeight() const override
Table of density as a function of height.

, generated on Tue Sep 26 2023.