MagneticFieldModel.cc
Go to the documentation of this file.
1 #include "MagneticFieldModel.h"
2 
3 #include <utl/Vector.h>
4 #include <utl/Point.h>
5 #include <utl/CoordinateSystemPtr.h>
6 #include <utl/AugerUnits.h>
7 #include <utl/UTCDate.h>
8 
9 #include <utl/AugerException.h>
10 #include <utl/Reader.h>
11 
12 #include <fwk/CentralConfig.h>
13 #include <fwk/CoordinateSystemRegistry.h>
14 
15 #include <string>
16 
18 {
19  Init();
20 }
21 
23 {
24  static MagneticFieldModel f;
25  return f;
26 }
27 
28 void
30 {
31  using namespace utl;
32  using namespace std;
33  using namespace fwk;
34  Branch top =
35  CentralConfig::GetInstance()->GetTopBranch("MagneticFieldModel");
36 
37  Branch models = top.GetChild("BaseModelList");
38 
39  for (Branch model = models.GetFirstChild(); model; model = model.GetNextSibling())
40  {
41  double year;
42  model.GetChild("BaseYear").GetData(year);
43  size_t order;
44  model.GetChild("Order").GetData(order);
45  vector<double> g;
46  vector<double> h;
47  model.GetChild("G").GetData(g);
48  model.GetChild("H").GetData(h);
49 
50  fModels.push_back(ParametricGeoMagneticField(year,order,&g[0],&h[0]));
51  }
52 
53  Branch changeModel = top.GetChild("ChangeModel");
54  {
55  size_t order;
56  changeModel.GetChild("Order").GetData(order);
57  vector<double> g;
58  vector<double> h;
59  changeModel.GetChild("G").GetData(g);
60  changeModel.GetChild("H").GetData(h);
61 
62  fChangeModel = new ParametricGeoMagChange(order,&g[0],&h[0]);
63  }
64 }
65 
66 
68  const utl::TimeStamp &time)
69 {
71 
72  return (90*utl::degree - GetMagneticFieldVector(position, time).GetPhi(cs));
73 }
74 
76  const utl::TimeStamp &time)
77 {
79 
80  return (GetMagneticFieldVector(position, time).GetTheta(cs) - 90*utl::degree);
81 }
82 
83 
85  const utl::TimeStamp &time)
86 {
87  return instance().ModelForTime(time).Get(position);
88 }
89 
90 
91 double
93 {
94  int days[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
95 
96  int leap_year = (((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0)));
97 
98  double day_in_year = (days[month - 1] + day + (month > 2 ? leap_year : 0));
99 
100  //did you know a day in a leap year is a little shorter ...
101  return ((double) year + (day_in_year / (365.0 + leap_year)));
102 }
103 
104 
107 {
108  int year = date.GetYear();
109  int month = date.GetMonth();
110  int day = date.GetDay();
111 
112  return ModelForYear(decimalYear(year, month, day));
113 }
114 
117 {
118  double firstYear = fModels.front().GetBaseYear();
119  if (year < firstYear)
120  {
121  std::ostringstream msg;
122  msg << "No magnet field information before year " << year << "\n";
123  ERROR(msg.str());
124  abort();
125  // There may be some sense in returning models.front(), but rather let user provide
126  // older magnet field data or let her explicitely ask for the first year.
127  }
128 
129  double lastYear = fModels.back().GetBaseYear();
130  if (year > lastYear)
131  {
132  return fChangeModel -> Extrapolate (year - lastYear, fModels.back());
133  }
134 
135  std::vector<ParametricGeoMagneticField>::iterator modelit = fModels.begin();
136  do
137  {
138  ParametricGeoMagneticField &model = *modelit;
139  ParametricGeoMagneticField &nextModel = *(++modelit);
140 
141  if (nextModel.GetBaseYear() >= year)
142  {
143  return model.Interpolate (year, nextModel);
144  }
145  }
146  while (modelit != fModels.end());
147 
148  ERROR("This point should never be reached."); abort();
149 }
double Extrapolate(const TH2D &h, double rmax, double r, double zeta)
static double GetInclination(const utl::Point &position, const utl::TimeStamp &time)
returns inclination in radians
Point object.
Definition: Point.h:32
Rate-of-change model for spherical harmonics parametrisation of geomagnetic field.
ParametricGeoMagneticField Interpolate(const double year, const ParametricGeoMagneticField &later) const
Interpolate between two models Given a time as decimal year, interpolate coefficients between this an...
static double GetDeclination(const utl::Point &position, const utl::TimeStamp &time)
returns declination in radians
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
int GetYear() const
Definition: UTCDate.h:44
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
Branch GetNextSibling() const
Get next sibling of this branch.
Definition: Branch.cc:284
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Definition: Branch.h:107
static MagneticFieldModel & instance()
static utl::Vector GetMagneticFieldVector(const utl::Point &position, const utl::TimeStamp &time)
returns the magnetic field at a specific place at a specific time
constexpr double degree
constexpr double g
Definition: AugerUnits.h:200
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
ParametricGeoMagneticField ModelForTime(const utl::UTCDate &date)
ParametricGeoMagneticField ModelForYear(double year)
int GetMonth() const
Definition: UTCDate.h:46
Spherical harmonics parametrisation of geomagnetic field.
int GetDay() const
Definition: UTCDate.h:48
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
Vector object.
Definition: Vector.h:30
Get the magnetic field of the earth dependent on location and time.
double decimalYear(int year, int month, int day)
Branch GetFirstChild() const
Get first child of this Branch.
Definition: Branch.cc:98
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double day
Definition: AugerUnits.h:151
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
const double year
Definition: GalacticUnits.h:22

, generated on Tue Sep 26 2023.