SdStationPositionCorrection.cc
Go to the documentation of this file.
2 #include <evt/Event.h>
3 #include <sevt/SEvent.h>
4 #include <sdet/SDetector.h>
5 #include <fwk/LocalCoordinateSystem.h>
6 #include <fwk/CentralConfig.h>
7 #include <utl/ReadStream.h>
8 #include <utl/UTMPoint.h>
9 #include <utl/LeapSeconds.h>
10 #include <utl/Math.h>
11 #include <utl/zfstream.h>
12 #include <utl/String.h>
13 
14 using namespace evt;
15 using namespace sevt;
16 using namespace std;
17 using namespace utl;
18 using namespace fwk;
19 
20 
21 namespace SdStationPositionCorrectionOG {
22 
24  public:
25  void
26  SetPosition(const Point& pos,
27  const CoordinateSystemPtr& referenceSystem = CoordinateSystemPtr())
28  {
29  fPosition = pos;
30  fReferenceSystem = referenceSystem;
31  }
32  };
33 
34 
35  struct UTM {
36 
37  double fNorthing;
38  double fEasting;
39  double fHeight;
40 
41  friend istream& operator>>(istream& is, UTM& u)
42  { return is >> u.fNorthing >> ws >> u.fEasting >> ws >> u.fHeight; }
43 
44  };
45 
46 
47  struct KnownPositions {
48 
49  unsigned int fStationId;
53 
54  friend istream& operator>>(istream& is, KnownPositions& p)
55  { return is >> p.fStationId >> ws >> p.fPMS >> ws >> p.fGPSAverage >> ws >> p.fGPSAverageWithDOPWeights; }
56 
57  };
58 
59 
60  struct FixedPosition {
61 
62  unsigned short int fStationId;
63  time_t fUnixSecond;
64  int fNRepeats;
66 
67  friend istream& operator>>(istream& is, FixedPosition& p)
68  { return is >> p.fStationId >> ws >> p.fUnixSecond >> ws >> p.fNRepeats >> ws >> p.fPosition; }
69 
70  };
71 
72 
75  {
76  // trigger detector update to read standard station positions
77  auto& det = det::Detector::GetInstance();
78  det.Update(GetCurrentSystemTime());
79  const auto& sDet = det.GetSDetector();
80 
81  auto topB = CentralConfig::GetInstance()->GetTopBranch("SdStationPositionCorrection");
82 
83  fEffectiveVerticalDelay = topB.GetChild("EffectiveVerticalDelay").Get<double>();
84 
85  const auto var = topB.GetChild("EffectiveVarianceCoefficients").Get<vector<double>>();
86  fEffectiveVarianceCoefficients = Triple(var.at(0), var.at(1), var.at(2));
87 
88  const auto sdStationGPSPositionsFile = topB.GetChild("SdStationGPSPositionsFile").Get<string>();
89 
90  const auto sdStationFixPositionsFile = topB.GetChild("SdStationFixPositionsFile").Get<string>();
91 
92  const int zone = 19;
93  const char band = 'H';
94  const auto& ellipsoid = ReferenceEllipsoid::GetWGS84();
95  const auto& siteCS = det.GetSiteCoordinateSystem();
96 
97  typedef std::map<unsigned int, utl::Point> PositionMap;
98  PositionMap gpsPositions;
99 
100  {
101  zifstream posFile(sdStationGPSPositionsFile.c_str());
102 
103  if (!posFile.is_open()) {
104  ostringstream err;
105  err << "Cannot open GPS positions file '" << sdStationGPSPositionsFile << "'!";
106  ERROR(err);
107  return eFailure;
108  }
109 
110  vector<KnownPositions> positions;
111  ReadStream(posFile).GetLines(positions, /*skip comments*/true, /*trim*/true);
112 
113  ostringstream info;
114  info << "Got " << positions.size() << " GPS positions from file \"" << sdStationGPSPositionsFile << "\"";
115  INFO(info);
116 
117  for (const auto& kpos : positions) {
118  const unsigned int sId = kpos.fStationId;
119  try {
120  const auto& dStation = sDet.GetAllStation(sId);
121  const auto& detPosition = dStation.GetPosition();
122  const auto& gps = kpos.fGPSAverage;
123  // skip entries with only PMS positions
124  if (gps.fNorthing && gps.fEasting && gps.fHeight) {
125  const auto position = UTMPoint(gps.fNorthing, gps.fEasting, gps.fHeight, zone, band, ellipsoid).GetPoint(siteCS);
126  gpsPositions.insert(make_pair(sId, position));
127  const auto& localCS = LocalCoordinateSystem::Create(position);
128  static_cast<UnrestrictedSDetStation&>(const_cast<sdet::Station&>(dStation)).SetPosition(position, localCS);
129  }
130  } catch (NonExistentComponentException&) {
131  ostringstream warn;
132  warn << "Station id=" << sId << " has a GPS position but is not found in the SDetector!";
133  WARNING(warn);
134  }
135  }
136  }
137 
138  fStationSpatialOffset.clear();
139 
140  {
141  zifstream fixFile(sdStationFixPositionsFile.c_str());
142 
143  if (!fixFile.is_open()) {
144  ostringstream err;
145  err << "Cannot open fix-positions file '" << sdStationFixPositionsFile << "'!";
146  ERROR(err);
147  return eFailure;
148  }
149 
150  vector<FixedPosition> fixPositions;
151  ReadStream(fixFile).GetLines(fixPositions, /*strip comments*/true, /*trim*/true);
152 
153  ostringstream info;
154  info << "Got " << fixPositions.size() << " fixed positions from file \"" << sdStationFixPositionsFile << "\"";
155  INFO(info);
156 
157  set<int> missingStations;
158  for (const auto& fpos : fixPositions) {
159  const unsigned int sId = fpos.fStationId;
160  auto& st = fStationSpatialOffset[sId];
161  unsigned long gpsSec = 0;
162  LeapSeconds::GetInstance().ConvertUnixToGPS(fpos.fUnixSecond, gpsSec);
163  auto& dx = st[gpsSec];
164  dx = Triple(0, 0, 0);
165  // gps measurement campaings will have negative NRepeats
166  if (fpos.fNRepeats > 0) { // for gps measurement campaigns assume correlated changes in time
167  const auto gpsIt = gpsPositions.find(sId);
168  if (gpsIt == gpsPositions.end())
169  missingStations.insert(sId);
170  else {
171  const auto& fix = fpos.fPosition;
172  const auto pos = UTMPoint(fix.fNorthing, fix.fEasting, fix.fHeight, zone, band, ellipsoid).GetPoint(siteCS);
173  const auto& gpsPos = gpsIt->second;
174  const auto diff = gpsPos - pos;
175  const auto& localCS = LocalCoordinateSystem::Create(gpsPos);
176  dx = diff.GetCoordinates(localCS);
177  }
178  }
179  }
180 
181  if (!missingStations.empty()) {
182  ostringstream warn;
183  warn << "Stations without GPS positions will have delay set to zero: " << String::OfSortedIds(missingStations);
184  WARNING(warn);
185  }
186  }
187 
188  return eSuccess;
189  }
190 
191 
193  SdStationPositionCorrection::Run(Event& event)
194  {
195  if (!event.HasSEvent())
196  return eSuccess;
197 
198  auto& sEvent = event.GetSEvent();
199 
200  vector<pair<unsigned int, pair<double, double>>> stationDtSigma;
201  for (auto& station : sEvent.StationsRange()) {
202  if (!station.HasRecData() || station.IsUUB())
203  continue;
204  auto& recData = station.GetRecData();
205  const auto& oldTime = recData.GetSignalStartTime();
206  if (!oldTime)
207  continue;
208  const unsigned int sId = station.GetId();
209  const auto tdxIt = fStationSpatialOffset.find(sId);
210  if (tdxIt == fStationSpatialOffset.end())
211  continue;
212  const auto& tdx = tdxIt->second;
213  if (tdx.empty())
214  continue;
215  auto dxIt = tdx.lower_bound(oldTime.GetGPSSecond());
216  if (dxIt == tdx.begin())
217  continue;
218  --dxIt;
219  const auto& dx = dxIt->second;
220  const TimeInterval dt = dx.get<2>() * fEffectiveVerticalDelay; // Z
221  recData.SetStartTimeGPSCorrection(dt);
222  recData.SetSignalStartTime(oldTime - dt);
223  const double sigma2 =
224  Sqr(fEffectiveVarianceCoefficients.get<0>() * dx.get<0>()) + // X
225  Sqr(fEffectiveVarianceCoefficients.get<1>() * dx.get<1>()) + // Y
226  Sqr(fEffectiveVarianceCoefficients.get<2>() * dx.get<2>()); // Z
227  recData.SetGPSTimeVariance(sigma2);
228  stationDtSigma.push_back(make_pair(sId, make_pair(dt, sqrt(sigma2))));
229  }
230 
231  if (stationDtSigma.empty())
232  INFO("no stations were corrected.");
233  else {
234  ostringstream info;
235  info << "station time offset and sigma [ns]:";
236  for (const auto& ids : stationDtSigma)
237  info << " (" << ids.first << ": "
238  << ids.second.first/nanosecond << " +- " << ids.second.second/nanosecond << ')';
239  INFO(info);
240  }
241 
242  return eSuccess;
243  }
244 
245 }
constexpr T Sqr(const T &x)
Point object.
Definition: Point.h:32
Detector description interface for Station-related data.
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
bool is(const double a, const double b)
Definition: testlib.cc:113
#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.
friend istream & operator>>(istream &is, KnownPositions &p)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
boost::tuple< double, double, double > Triple
Coordinate triple for easy getting or setting of coordinates.
Definition: Triple.h:15
constexpr double nanosecond
Definition: AugerUnits.h:143
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void SetPosition(const Point &pos, const CoordinateSystemPtr &referenceSystem=CoordinateSystemPtr())
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
friend istream & operator>>(istream &is, UTM &u)
TimeStamp GetCurrentSystemTime()
get current time as reported by system
Definition: TimeStamp.cc:46
friend istream & operator>>(istream &is, FixedPosition &p)
string OfSortedIds(vector< int > ids)
Definition: String.cc:65
void GetLines(std::vector< T > &v, const bool filterComments=true, const bool trim=false)
Definition: ReadStream.h:101
Point GetPoint(const CoordinateSystemPtr &theCS=CoordinateSystemPtr()) const
Get a cartesian point from an UTMPoint.
Definition: UTMPoint.cc:45
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
bool HasSEvent() const

, generated on Tue Sep 26 2023.