AtmosphereUtilities.cc
Go to the documentation of this file.
2 #include <atm/Atmosphere.h>
3 #include <atm/ProfileResult.h>
4 #include <det/Detector.h>
5 #include <utl/Point.h>
6 #include <utl/Vector.h>
7 #include <utl/AugerUnits.h>
8 #include <utl/UTCDateTime.h>
9 #include <utl/Branch.h>
10 #include <fwk/CentralConfig.h>
11 #include <src/PowerConfig.h>
12 #include <src/Functions.h>
13 
14 using namespace std;
15 using namespace utl;
16 
17 
18 namespace un2 {
19 
20  /*void
21  Print(const atm::ProfileResult& p,
22  const string& label,
23  const double xUnit, const double yUnit,
24  const string& xLabel, const string& yLabel)
25  {
26  const auto& x = p.GetXValues();
27  const auto& y = p.GetYValues();
28  cout << label << '\n'
29  << xLabel << '\t' << yLabel << '\n';
30  for (unsigned int i = 0, n = x.size(); i < n; ++i)
31  cout << x[i]/xUnit << '\t' << y[i]/yUnit << '\n';
32  }
33 
34  // testing
35  atm.InitSlantProfileModel(core, axis, 50*gpcm2);
36  Print(atm.EvaluateSlantDepthVsDistance(), "\nEvaluateSlantDepthVsDistance:", meter, gpcm2, "Distance/m", "SlantDepth/(g/cm2)");
37  Print(atm.EvaluateDistanceVsSlantDepth(), "\nEvaluateDistanceVsSlantDepth:", gpcm2, meter, "SlantDepth/(g/cm2)", "Distance/m");
38  Print(atm.EvaluateHeightVsSlantDepth(), "\nEvaluateHeightVsSlantDepth:", gpcm2, meter, "SlantDepth/(g/cm2)", "Height/m");
39  Print(atm.EvaluateHeightVsDistance(), "\nEvaluateHeightVsDistance:", meter, meter, "Distance/m", "Height/m");
40  return 0;*/
41 
42 
43  inline
44  double
45  Interpolate(const double dx, const double dy,
46  const double x)
47  {
48  return dy * x / dx;
49  }
50 
51 
52  inline
53  double
54  Interpolate(const double x1, const double y1,
55  const double x2, const double y2,
56  const double x)
57  {
58  return y1 + Interpolate(x2 - x1, y2 - y1, x - x1);
59  }
60 
61 
62  inline
63  double
64  ExpInterpolate(const double x1, const double y1,
65  const double x2, const double y2,
66  const double x)
67  {
68  // assume log(y) is linear, ie y is exponential
69  return exp(Interpolate(x1, log(y1), x2, log(y2), x));
70  }
71 
72 
73  /* Calculate the shower age
74  *
75  * differences to old method:
76  * - non-abelean behaviour of calculations was taken into account
77  * - using observation height gauged to what was actually used in simulations
78  * - real atmospheric data can be used
79  * - debug output
80  * - units are now meters and radians */
81 
82  inline
83  double
84  CalcDXRealAtm(const bool useDL,
85  const double spRadius, const double spPsi, const double groundHeight,
86  const double xMax, const double theta, const int month)
87  {
88  // use the atmosphere configured in the bootstrap (preferably from FdRealDetConfig) to
89  // do the full DX calculation. this is also used to create the atmosphere_parameters.xml
90  // for faster analtic calculation.
91  if (month<0)
92  return 0;
93 
94  auto& detector = det::Detector::GetInstance();
95 
96  // make sure the atmosphere switches to the right month
97  //detector.Update(UTCDateTime(2018, month, 15).GetTimeStamp());
98 
99  const auto& cs = detector.GetReferenceCoordinateSystem(); // ePampaAmarilla
100 
101  // referenceHeight is new effective "zero" height
102  constexpr double paReferenceHeight = 1400; // the UTM height of ePampaAmarilla origin
103  const double paHeight = groundHeight - paReferenceHeight; // universality height
104 
105  const Point core(0, 0, paHeight, cs);
106  const Vector axis(1, theta, 0, cs, Vector::kSpherical); // tilted towards x-axis
107 
108  const double gpcm2 = g/cm2;
109 
110  const auto& atm = detector.GetAtmosphere();
111 
112  atm.InitSlantProfileModel(core, axis, 0.5*gpcm2);
113 
114  // note: positive distance is downwards in direction of -axis
115  const double projectedStationDistance = -spRadius * tan(theta) * cos(spPsi);
116 
117  if (useDL) {
118  const auto& dVsX = atm.EvaluateDistanceVsSlantDepth();
119  const double distanceToXMax = dVsX.Y(xMax * gpcm2) / meter;
120  return projectedStationDistance - distanceToXMax;
121  } else {
122  const auto& xVsD = atm.EvaluateSlantDepthVsDistance();
123  const double d = projectedStationDistance * meter;
124  if (d < xVsD.MinX())
125  // assume zero X
126  return -xMax;
127  else if (d < xVsD.MaxX()) {
128  const double depthOfProjectedStation = xVsD.Y(d) / gpcm2;
129  return depthOfProjectedStation - xMax;
130  } else {
131  // extrapolate below sea level
132  const auto& dists = xVsD.GetXValues();
133  const auto& depths = xVsD.GetYValues();
134  const unsigned int n = dists.size();
135  const double d1 = dists[n-2];
136  const double d2 = dists[n-1];
137  const double depth1 = depths[n-2];
138  const double depth2 = depths[n-1];
139  const double extrapolatedDepth = ExpInterpolate(d1, depth1, d2, depth2, d);
140  return extrapolatedDepth / gpcm2 - xMax;
141  }
142  }
143  }
144 
145 
146  inline
147  double
148  CalcDXCorsikaAtm(const bool useDL,
149  const double spRadius, const double spPsi, const double groundHeight,
150  const double xMax, const double theta, const int month)
151  {
152  // use the maximum vertical depths from corsika profiles with the parametrised atmospheric
153  // profiles from MonthlyAvgDB. results match the corsika atmosphere with ~1% precision and
154  // better
155 
156  const UniversalityConfig& config = PowerConfig::GetInstance();
157  fwk::CentralConfig& cc = *fwk::CentralConfig::GetInstance(/*config.GetBootstrap()*/);
158 
159  const auto& monthsDict = config.GetMonthsMapReverse();
160  const auto m = monthsDict.at(month);
161  auto mB = cc.GetTopBranch("AtmosphereParameters").GetChild("un2").GetChild(m);
162  const auto hs = mB.GetChild("hs").Get<double>();
163  const auto hs2 = mB.GetChild("hs2").Get<double>();
164  // these are taken directly from the CORSIKA documentation
165  const double xVert = config.GetGroundLevelDepths()[month-1];
166 
167  if (useDL) {
168 
169  const double hXmax = AnalyticHeightFromDepth(xMax, theta, xVert, hs, hs2);
170  const double hProj = spRadius * cos(spPsi) * sin(theta);
171  return (hXmax - hProj - 1400.) / cos(theta);
172 
173  } else {
174 
175  return AnalyticDX(spRadius, spPsi, theta, xMax, xVert, hs, hs2, groundHeight);
176 
177  }
178  }
179 
180 
181  double
182  CalcDX(const bool realAtmosphere, const bool useDL,
183  const double spRadius, const double spPsi, const double groundHeight,
184  const double xMax, const double theta, const int month, const bool silent)
185  {
186  if (silent) {
187  utl::ErrorLogger::GetInstance().SetStream(cerr); // redirect offline logging
188  cerr.rdbuf(nullptr); // turn off offline output, which was directed to cerr
189  }
190 
191  return (realAtmosphere) ?
192  CalcDXRealAtm(useDL, spRadius, spPsi, groundHeight, xMax, theta, month) :
193  CalcDXCorsikaAtm(useDL, spRadius, spPsi, groundHeight, xMax, theta, month);
194  }
195 
196 }
double CalcDX(const bool realAtmosphere, const bool useDL, const double spRadius, const double spPsi, const double groundHeight, const double xMax, const double theta, const int month, const bool silent)
Point object.
Definition: Point.h:32
double Interpolate(const double dx, const double dy, const double x)
const double meter
Definition: GalacticUnits.h:29
void SetStream(std::ostream &stream)
Definition: ErrorLogger.h:85
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double ExpInterpolate(const double x1, const double y1, const double x2, const double y2, const double x)
T Get() const
Definition: Branch.h:271
virtual const std::vector< double > & GetGroundLevelDepths() const =0
constexpr double g
Definition: AugerUnits.h:200
double AnalyticDX(const double r, const double psi, const double theta, const double Xmax, const double Xvert, const double hs, const double hs2, const double height)
Definition: Functions.cc:355
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
double AnalyticHeightFromDepth(const double depth, const double theta, const double xVertGround, const double hs, const double hs2)
Definition: Functions.cc:374
Vector object.
Definition: Vector.h:30
double CalcDXRealAtm(const bool useDL, const double spRadius, const double spPsi, const double groundHeight, const double xMax, const double theta, const int month)
static ErrorLogger & GetInstance()
Definition: Singleton.h:128
Main configuration utility.
Definition: CentralConfig.h:51
double CalcDXCorsikaAtm(const bool useDL, const double spRadius, const double spPsi, const double groundHeight, const double xMax, const double theta, const int month)
constexpr double m
Definition: AugerUnits.h:121
virtual const std::map< unsigned int, std::string > & GetMonthsMapReverse() const =0
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
constexpr double cm2
Definition: AugerUnits.h:118

, generated on Tue Sep 26 2023.