RdStationPositionCorrection.cc
Go to the documentation of this file.
2 
3 #include <fwk/LocalCoordinateSystem.h>
4 #include <fwk/CentralConfig.h>
5 
6 #include <det/VManager.h>
7 #include <rdet/RDetector.h>
8 
9 #include <utl/ReadStream.h>
10 #include <utl/UTMPoint.h>
11 #include <utl/Point.h>
12 #include <utl/Vector.h>
13 #include <utl/PhysicalConstants.h>
14 #include <utl/UTCDateTime.h>
15 
16 #include <evt/Event.h>
17 #include <revt/REvent.h>
18 #include <revt/Header.h>
19 #include <revt/StationRecData.h>
20 
21 #include <vector>
22 
23 
24 using namespace evt;
25 using namespace revt;
26 using namespace std;
27 using namespace utl;
28 using namespace fwk;
29 
30 
31 namespace RdStationPositionCorrectionOG {
32 
33  struct UTM {
34  double fNorthing;
35  double fEasting;
36  double fHeight;
37  };
38 
39 
40  inline
41  istream&
42  operator>>(istream& is, UTM& utm)
43  {
44  return is >> utm.fNorthing >> ws >> utm.fEasting >> ws >> utm.fHeight;
45  }
46 
47 
48  struct KnownPositions {
49  unsigned int fStationId;
53  };
54 
55 
56  inline
57  istream&
58  operator>>(istream& is, KnownPositions& pos)
59  {
60  return is >> pos.fStationId >> ws >> pos.fUsedPosition >> ws >> pos.fTruePosition >> ws
61  >> pos.fCorrectionValidUntil;
62  }
63 
64 
67  {
68  Branch topB = CentralConfig::GetInstance()->GetTopBranch("RdStationPositionCorrection");
69 
70  fDistanceTolerance = topB.GetChild("DistanceTolerance").Get<double>();
71  const double effectiveVerticalDelay = topB.GetChild("EffectiveVerticalDelay").Get<double>();
72  const string rdStationGPSPositionsFile = topB.GetChild("RdStationGPSPositionsFile").Get<string>();
73 
74  // trigger detector update to read standard station positions
75  det::Detector& det = det::Detector::GetInstance();
76  det.Update(GetCurrentSystemTime());
77  const rdet::RDetector& rDet = det.GetRDetector();
78 
79  ifstream posFile(rdStationGPSPositionsFile.c_str());
80  if (!posFile.is_open()) {
81  ostringstream err;
82  err << "Cannot open GPS positions file '" << rdStationGPSPositionsFile << "'!";
83  ERROR(err);
84  return eFailure;
85  }
86 
87  vector<KnownPositions> positions;
88  ReadStream(posFile).GetLines(positions);
89 
90  fOffsets.clear();
91  fValidityTimes.clear();
92 
93  const int zone = 19;
94  const char band = 'H';
95  const ReferenceEllipsoid& ellipsoid = ReferenceEllipsoid::GetWGS84();
96  const CoordinateSystemPtr siteCS = det.GetSiteCoordinateSystem();
97 
98  for (const auto& pos : positions) {
99  // get position used in GPS unit
100  const unsigned int sId = pos.fStationId;
101  const UTM& usedpos = pos.fUsedPosition;
102  const UTMPoint usedposUTM(usedpos.fNorthing, usedpos.fEasting, usedpos.fHeight, zone, band, ellipsoid);
103  const Point usedPosition = usedposUTM.GetPoint(siteCS);
104 
105  try {
106  // get true position which should have been used in GPS unit
107  const UTM& truepos = pos.fTruePosition;
108  const UTMPoint trueposUTM(truepos.fNorthing, truepos.fEasting, truepos.fHeight, zone, band, ellipsoid);
109  const Point truePosition = trueposUTM.GetPoint(siteCS);
110  const CoordinateSystemPtr localCS = LocalCoordinateSystem::Create(truePosition);
111 
112  const double dt = (truePosition - usedPosition).GetZ(localCS) * effectiveVerticalDelay;
113 
114  // check for double entries in GPS positions correction file
115  if (fOffsets.find(sId) != fOffsets.end()) {
116  ostringstream err;
117  err << "Duplicate entry for station id " << sId << " found in the positions file!";
118  ERROR(err);
119  return eFailure;
120  }
121 
122  // store offset and validity time of correction
123  fOffsets.emplace(sId, dt);
124  fValidityTimes.emplace(sId, pos.fCorrectionValidUntil.GetTimeStamp());
125 
126  // cross-check that position listed in GPS correction file is consistent with position in RDetector
127  const rdet::Station& dStation = rDet.GetStation(sId);
128  const Point detPosition = dStation.GetPosition();
129  const double posDistance = (truePosition - detPosition).GetMag();
130 
131  if (posDistance > fDistanceTolerance) {
132  ostringstream err;
133  err << "Distance of " << posDistance / meter << " m between current station position in RDetector"
134  " and GPS corrections file for station id " << sId << " is too large!";
135  ERROR(err);
136  return eFailure;
137  }
138 
139  } catch (NonExistentComponentException&) {
140  ostringstream warn;
141  warn << "Station id " << sId << " has a GPS position in the corrections file but is not found in the RDetector!";
142  WARNING(warn);
143  }
144  }
145 
146  return eSuccess;
147  }
148 
149 
151  RdStationPositionCorrection::Run(Event& event)
152  {
153  if (!event.HasREvent())
154  return eSuccess;
155 
156  REvent& rEvent = event.GetREvent();
157 
158  for (auto& station : rEvent.StationsRange()) {
159  if (!station.HasRecData())
160  continue;
161 
162  StationRecData& recData = station.GetRecData();
163 
164  if (!recData.HasParameter(eTraceStartTime)) {
165  ostringstream err;
166  err << "Trying to correct trace start time for station id " << station.GetId()
167  << ", but no trace start time available in ParameterStorage!";
168  ERROR(err);
169  return eFailure;
170  }
171 
172  const TimeInterval oldTime = recData.GetParameter(eTraceStartTime);
173  const auto offsetIt = fOffsets.find(station.GetId());
174 
175  if (offsetIt == fOffsets.end()) // no correction value found for this station
176  continue;
177 
178  // check validity time to see if correction needs to be applied, it is ensured that the entry is present in the map
179  if (rEvent.GetHeader().GetTime() > fValidityTimes[station.GetId()])
180  continue;
181 
182  const TimeInterval& offset = offsetIt->second;
183  recData.SetParameter(eTraceStartTime, oldTime - offset, false); // set corrected start time
184  recData.SetParameter(eTraceStartTimeCorrectionByGPSPosition, -offset); // store value that has been added to the trace start time
185 
186  // also change relative position of signal search window accordingly
187  recData.SetParameter(eSignalSearchWindowStart, recData.GetParameter(eSignalSearchWindowStart) + offset, false);
188  recData.SetParameter(eSignalSearchWindowStop, recData.GetParameter(eSignalSearchWindowStop) + offset, false);
189  }
190 
191  return eSuccess;
192  }
193 
194 
196  RdStationPositionCorrection::Finish()
197  {
198  return eSuccess;
199  }
200 
201 }
void operator>>(const Event &theEvent, IoSdEvent &rawSEvent)
Branch GetTopBranch() const
Definition: Branch.cc:63
Class to access station level reconstructed data.
Point object.
Definition: Point.h:32
Detector description interface for Station-related data.
Interface class to access to the Radio part of an event.
Definition: REvent.h:42
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
utl::TimeStamp GetTime() const
Definition: REvent/Header.h:17
bool is(const double a, const double b)
Definition: testlib.cc:113
const double meter
Definition: GalacticUnits.h:29
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
bool HasREvent() const
Detector description interface for RDetector-related data.
Definition: RDetector.h:46
T Get() const
Definition: Branch.h:271
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Definition: Branch.h:107
Reference ellipsoids for UTM transformations.
Header & GetHeader()
access to REvent Header
Definition: REvent.h:239
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
double GetParameter(const Parameter i) const
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
bool HasParameter(const Parameter i) const
void SetParameter(Parameter i, double value, bool lock=true)
TimeStamp GetCurrentSystemTime()
get current time as reported by system
Definition: TimeStamp.cc:46
void GetLines(std::vector< T > &v, const bool filterComments=true, const bool trim=false)
Definition: ReadStream.h:101
utl::Point GetPosition() const
Tank position in Site Cartesian Coordinates.
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
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: RDetector.cc:141

, generated on Tue Sep 26 2023.