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>
11 #include <utl/zfstream.h>
12 #include <utl/String.h>
21 namespace SdStationPositionCorrectionOG {
30 fReferenceSystem = referenceSystem;
77 auto& det = det::Detector::GetInstance();
79 const auto& sDet = det.GetSDetector();
81 auto topB = CentralConfig::GetInstance()->GetTopBranch(
"SdStationPositionCorrection");
83 fEffectiveVerticalDelay = topB.GetChild(
"EffectiveVerticalDelay").Get<
double>();
85 const auto var = topB.GetChild(
"EffectiveVarianceCoefficients").Get<vector<double>>();
86 fEffectiveVarianceCoefficients =
Triple(var.at(0), var.at(1), var.at(2));
88 const auto sdStationGPSPositionsFile = topB.GetChild(
"SdStationGPSPositionsFile").Get<
string>();
90 const auto sdStationFixPositionsFile = topB.GetChild(
"SdStationFixPositionsFile").Get<
string>();
93 const char band =
'H';
94 const auto& ellipsoid = ReferenceEllipsoid::GetWGS84();
95 const auto& siteCS = det.GetSiteCoordinateSystem();
97 typedef std::map<unsigned int, utl::Point> PositionMap;
98 PositionMap gpsPositions;
101 zifstream posFile(sdStationGPSPositionsFile.c_str());
103 if (!posFile.is_open()) {
105 err <<
"Cannot open GPS positions file '" << sdStationGPSPositionsFile <<
"'!";
110 vector<KnownPositions> positions;
114 info <<
"Got " << positions.size() <<
" GPS positions from file \"" << sdStationGPSPositionsFile <<
"\"";
117 for (
const auto& kpos : positions) {
118 const unsigned int sId = kpos.fStationId;
120 const auto& dStation = sDet.GetAllStation(sId);
121 const auto& detPosition = dStation.GetPosition();
122 const auto& gps = kpos.fGPSAverage;
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);
132 warn <<
"Station id=" << sId <<
" has a GPS position but is not found in the SDetector!";
138 fStationSpatialOffset.clear();
141 zifstream fixFile(sdStationFixPositionsFile.c_str());
143 if (!fixFile.is_open()) {
145 err <<
"Cannot open fix-positions file '" << sdStationFixPositionsFile <<
"'!";
150 vector<FixedPosition> fixPositions;
154 info <<
"Got " << fixPositions.size() <<
" fixed positions from file \"" << sdStationFixPositionsFile <<
"\"";
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];
166 if (fpos.fNRepeats > 0) {
167 const auto gpsIt = gpsPositions.find(sId);
168 if (gpsIt == gpsPositions.end())
169 missingStations.insert(sId);
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);
181 if (!missingStations.empty()) {
183 warn <<
"Stations without GPS positions will have delay set to zero: " <<
String::OfSortedIds(missingStations);
193 SdStationPositionCorrection::Run(
Event& event)
198 auto& sEvent =
event.GetSEvent();
200 vector<pair<unsigned int, pair<double, double>>> stationDtSigma;
201 for (
auto& station : sEvent.StationsRange()) {
202 if (!station.HasRecData() || station.IsUUB())
204 auto& recData = station.GetRecData();
205 const auto& oldTime = recData.GetSignalStartTime();
208 const unsigned int sId = station.GetId();
209 const auto tdxIt = fStationSpatialOffset.find(sId);
210 if (tdxIt == fStationSpatialOffset.end())
212 const auto& tdx = tdxIt->second;
215 auto dxIt = tdx.lower_bound(oldTime.GetGPSSecond());
216 if (dxIt == tdx.begin())
219 const auto& dx = dxIt->second;
220 const TimeInterval dt = dx.get<2>() * fEffectiveVerticalDelay;
221 recData.SetStartTimeGPSCorrection(dt);
222 recData.SetSignalStartTime(oldTime - dt);
223 const double sigma2 =
224 Sqr(fEffectiveVarianceCoefficients.get<0>() * dx.get<0>()) +
225 Sqr(fEffectiveVarianceCoefficients.get<1>() * dx.get<1>()) +
226 Sqr(fEffectiveVarianceCoefficients.get<2>() * dx.get<2>());
227 recData.SetGPSTimeVariance(sigma2);
228 stationDtSigma.push_back(make_pair(sId, make_pair(dt,
sqrt(sigma2))));
231 if (stationDtSigma.empty())
232 INFO(
"no stations were corrected.");
235 info <<
"station time offset and sigma [ns]:";
236 for (
const auto& ids : stationDtSigma)
237 info <<
" (" << ids.first <<
": "
constexpr T Sqr(const T &x)
Detector description interface for Station-related data.
Class to hold and convert a point in geodetic coordinates.
bool is(const double a, const double b)
unsigned short int fStationId
#define INFO(message)
Macro for logging informational messages.
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.
constexpr double nanosecond
UTM fGPSAverageWithDOPWeights
#define WARNING(message)
Macro for logging warning messages.
void SetPosition(const Point &pos, const CoordinateSystemPtr &referenceSystem=CoordinateSystemPtr())
A TimeInterval is used to represent time elapsed between two events.
ResultFlag
Flag returned by module methods to the RunController.
friend istream & operator>>(istream &is, UTM &u)
TimeStamp GetCurrentSystemTime()
get current time as reported by system
friend istream & operator>>(istream &is, FixedPosition &p)
string OfSortedIds(vector< int > ids)
void GetLines(std::vector< T > &v, const bool filterComments=true, const bool trim=false)
Point GetPoint(const CoordinateSystemPtr &theCS=CoordinateSystemPtr()) const
Get a cartesian point from an UTMPoint.
#define ERROR(message)
Macro for logging error messages.