Ads_bDataBase.cc
Go to the documentation of this file.
1 /*
2  * AdsbDataBase.cpp
3  *
4  * Created on: Jul 23, 2015
5  * Author: leven
6  */
7 
8 #include "Ads_bDataBase.h"
9 #include "AirplaneUtil.h"
10 #include "FlightAndPositionPair.h"
11 #include "Airplane.h"
12 #include "Flight.h"
13 
14 #include "fwk/CentralConfig.h"
15 
16 #include "utl/LeapSeconds.h"
17 #include "utl/UTMPoint.h"
18 #include "utl/PhysicalConstants.h"
19 #include "utl/ErrorLogger.h"
20 #include "utl/Branch.h"
21 
22 #include "det/Detector.h"
23 
24 #include "boost/filesystem.hpp"
25 #include "boost/lexical_cast.hpp"
26 
27 #include <iostream>
28 #include <fstream>
29 #include <sstream>
30 #include <limits>
31 #include <sys/time.h>
32 
33 
34 
35 using namespace utl;
36 using namespace fwk;
37 using namespace std;
38 using namespace RdAirplane;
39 using namespace boost;
40 using namespace det;
41 namespace fs = filesystem;
42 
43 
44 Ads_bDataBase::Ads_bDataBase(const TimeInterval& pTimeShift, const AirplaneOffsetsMap& pAirplaneOffsets, const string& pRootTrajectoryFitFileName) :
45  _coordinateSystem_(Detector::GetInstance().GetReferenceCoordinateSystem()),
46  _timeShift_(pTimeShift),
47  _airplaneOffsets_(pAirplaneOffsets),
48  _rootTrajectoryFitFile_(pRootTrajectoryFitFileName.empty() ? NULL : new TFile(pRootTrajectoryFitFileName.c_str(), "RECREATE")){}
49 
51  for(AirplaneMap::iterator iter = _airplanes_.begin();
52  iter!=_airplanes_.end();
53  ++iter) {
54  delete iter->second;
55  }
57  _rootTrajectoryFitFile_->Close();
58  _rootTrajectoryFitFile_->Delete();
59  }
61 }
62 
63 Airplane* Ads_bDataBase::getAirplaneById(const std::string& pId) {
64  AirplaneMap::iterator iter = _airplanes_.find(pId);
65  if(iter==_airplanes_.end())
66  return NULL;
67  return iter->second;
68 }
69 
70 Ads_bDataBase::ReadLogFileResults Ads_bDataBase::AddAirplanesFromLogFiles(const std::vector<std::string>& pAds_bLogFileNames) {
71  ReadLogFileResults results;
72  for(vector<string>::const_iterator iter = pAds_bLogFileNames.begin();iter!=pAds_bLogFileNames.end();++iter) {
73  const string& fileName = *iter;
74  results.push_back(_addAirplanesFromLogFile(fileName));
75  }
76  for(AirplaneMap::iterator iter=_airplanes_.begin(); iter!=_airplanes_.end(); ++iter) {
77  iter->second->Init();
78  }
80  _rootTrajectoryFitFile_->Write();
81  _rootTrajectoryFitFile_->Close();
82  }
83  return results;
84 }
85 
87  timeval startTime;
88  gettimeofday(&startTime, NULL);
89  INFO("Reading File: " + pAds_bLogFileName + "...");
90  if(_logFiles_.find(pAds_bLogFileName)!=_logFiles_.end())
91  return ReadLogFileResult("Log file already loaded.", true, pAds_bLogFileName);
92  _logFiles_.insert(pAds_bLogFileName);
93  fs::path pathToFile = fs::path(pAds_bLogFileName);
94  if(!fs::exists(pathToFile)) {
95  return ReadLogFileResult("Could not open file.", false, pAds_bLogFileName);
96  }
97  ifstream file(pAds_bLogFileName.c_str());
98  bool allGood = true;
99  stringstream message;
100  try {
101  if(!file.is_open())
102  return ReadLogFileResult("Could not open file.", false, pAds_bLogFileName);
103  string line;
104  unsigned int lineNumber=0;
105 
106  while(getline(file,line)) {
107  ++lineNumber;
108  string::size_type doubleWhiteSpacePosition=-1;
109 
110  while((doubleWhiteSpacePosition=line.find(" "))!=string::npos)
111  line.replace(doubleWhiteSpacePosition, 2, " ");
112 
113  if(line.empty() || line==" ")
114  continue;
115 
116  unsigned long capturedAtUnixTime=0;
117  double latitude=0.0;
118  double longitude=0.0;
119  double altitude=0.0;
120  string id;
121  string ads_bMessageAsHex;
122  stringstream lineAsStream(line);
123  lineAsStream >> capturedAtUnixTime;
124  lineAsStream >> ads_bMessageAsHex;
125  lineAsStream.ignore(numeric_limits<streamsize>::max(),' ');
126  lineAsStream.ignore(numeric_limits<streamsize>::max(),' ');
127  lineAsStream.ignore(numeric_limits<streamsize>::max(),' ');
128  lineAsStream.ignore(numeric_limits<streamsize>::max(),' ');
129  lineAsStream.ignore(numeric_limits<streamsize>::max(),' ');
130  lineAsStream.ignore(numeric_limits<streamsize>::max(),' ');
131  lineAsStream.ignore(numeric_limits<streamsize>::max(),' ');
132  lineAsStream.ignore(numeric_limits<streamsize>::max(),' ');
133  lineAsStream.ignore(numeric_limits<streamsize>::max(),' ');
134  lineAsStream >> id;
135  lineAsStream >> latitude;
136  lineAsStream >> longitude;
137  lineAsStream >> altitude;
138 
139  ads_bMessageAsHex = ads_bMessageAsHex.substr(1, ads_bMessageAsHex.length()-2);
140  // some sanity checks
141  if( capturedAtUnixTime < 1388534400000 || // later than 1.1.14 00:00:00
142  id.length()!=6 ||
143  latitude<-40.0 || latitude>-30.0 ||
144  longitude<-75.0 || longitude>-60.0 ||
145  altitude < 4000.0 || altitude > 16000.0) {
146 
147  allGood = false;
148  message << "Skipped bad data in Line " << lineNumber << endl;
149  message << "\t time: " << Util::TimestampHumanReadAble(capturedAtUnixTime) << "(" << capturedAtUnixTime << ")" << endl;
150  message << "\t airplane id: " << id << endl;
151  message << "\t latitude: " << latitude << endl;
152  message << "\t longitude: " << longitude << endl;
153  message << "\t altitude: " << altitude << endl;
154  continue;
155  }
156  // convert unix time to gps time and do from now on everything in the auger time format
157  unsigned long unixMilliSeconds = capturedAtUnixTime%1000;
158  time_t unixSeconds = (capturedAtUnixTime-unixMilliSeconds)/1000.0;
159  unsigned long gpsSecond;
160  LeapSeconds::GetInstance().ConvertUnixToGPS(unixSeconds, gpsSecond);
161  TimeStamp capturedAtTime(gpsSecond, ((double)unixMilliSeconds)*pow(10.0,6));
162  capturedAtTime+=getTimeShift();
164  airplane->AddAds_bEvent(capturedAtTime, UTMPoint(latitude*degree, longitude*degree, altitude*m, ReferenceEllipsoid::eWGS84), ads_bMessageAsHex);
165  }
166  } catch(...) {
167  file.close();
168  throw;
169  }
170  file.close();
171  timeval endTime;
172  gettimeofday(&endTime, NULL);
173  double passedTime = endTime.tv_sec-startTime.tv_sec+(1e-6)*(endTime.tv_usec-startTime.tv_usec);
174  INFO("(Finished in " + lexical_cast<string>(round(passedTime)) + " s)");
175  return ReadLogFileResult(message.str(), allGood, pAds_bLogFileName);
176 }
177 
178 Ads_bDataBase::FlightsAndCoordinatesList Ads_bDataBase::getFlights(const TimeStamp& pTime, const Point& pReconstructedEventPosition, const double& pMaxAngleDifferenceInRadian, CoordinateSystemPtr pCoreCoordinateSystem) {
180 
181  for(AirplaneMap::iterator iter = _airplanes_.begin(); iter!=_airplanes_.end(); ++iter) {
182  Airplane* airplane = iter->second;
183  Flight* flight = airplane->getFlight(pTime);
184 
185  if(flight==NULL) // no flight during this time
186  continue;
187 
188  Point* airplanePosition = flight->getPosition(pTime);
189 
190  if(airplanePosition==NULL) // no interpolation during this time
191  continue;
192 
193  double eX=airplanePosition->GetX(pCoreCoordinateSystem);
194  double eY=airplanePosition->GetY(pCoreCoordinateSystem);
195  double eZ=airplanePosition->GetZ(pCoreCoordinateSystem);
196  double pX=pReconstructedEventPosition.GetX(pCoreCoordinateSystem);
197  double pY=pReconstructedEventPosition.GetY(pCoreCoordinateSystem);
198  double pZ=pReconstructedEventPosition.GetZ(pCoreCoordinateSystem);
199  double absE=sqrt(eX*eX+eY*eY+eZ*eZ);
200  double absP=sqrt(pX*pX+pY*pY+pZ*pZ);
201  double scalarProduct=eX*pX+eY*pY+eZ*pZ;
202  double angle=acos(scalarProduct/absE/absP);
203 
204  if(angle>pMaxAngleDifferenceInRadian) // too big difference of reconstructed event origin and airplane position
205  continue;
206 
207  // copy Point because the value pointed to changes
208  results.push_back(FlightAndPositionPair(flight, Point(*airplanePosition), pReconstructedEventPosition, pTime));
209  }
210  results.sort(FlightAndPositionPair::comparator);
211  return results;
212 }
213 
214 
216  Airplane* airplane = getAirplaneById(pId);
217  if(airplane==NULL) {
218  airplane = new Airplane(pId, this);
219  _airplanes_.insert(make_pair(pId, airplane));
220  }
221  return airplane;
222 }
223 
225  string info;
226  for(AirplaneMap::const_iterator iter=_airplanes_.begin();iter!=_airplanes_.end();++iter) {
227  info+=iter->second->getInformation()+"\n";
228  }
229  return info;
230 }
231 
232 const AirplaneOffset* Ads_bDataBase::getAirplaneOffset(const Airplane& pAirplane, const TimeStamp& pTime) const {
233  AirplaneOffsetsMap::const_iterator iterMap = _airplaneOffsets_.find(pAirplane.getId());
234  if(iterMap==_airplaneOffsets_.end())
235  return NULL;
236  const AirplaneOffsetList& offsetList = iterMap->second;
237  for(AirplaneOffsetList::const_iterator iter = offsetList.begin(); iter != offsetList.end(); ++iter) {
238  double timeDifferenceInS = std::abs((iter->getWhen()-pTime).GetSecond());
240  return &*iter;
241  }
242  }
243  return NULL;
244 }
245 
246 Ads_bDataBase::ReadLogFileResults Ads_bDataBase::InitSharedDataBase(const vector<string>& pAds_bLogFileNames, const TimeInterval& pTimeShift, const AirplaneOffsetsMap& pAirplaneOffsets, const string& pRootTrajecotryFitFileName) {
247  if(_sharedDataBase==NULL) {
248  _sharedDataBase=new Ads_bDataBase(pTimeShift, pAirplaneOffsets, pRootTrajecotryFitFileName);
249  }
250  return _sharedDataBase->AddAirplanesFromLogFiles(pAds_bLogFileNames);
251 }
252 
253 Ads_bDataBase::ReadLogFileResults Ads_bDataBase::InitSharedDataBase(const std::string& pAds_bLogFileNames, const TimeInterval& pTimeShift, const AirplaneOffsetsMap& pAirplaneOffsets, const string& pRootTrajecotryFitFileName) {
254  vector<string> fileNames;
255  istringstream fileNamesStream(pAds_bLogFileNames);
256  copy(istream_iterator<string>(fileNamesStream),
257  istream_iterator<string>(),
258  back_inserter(fileNames));
259  return InitSharedDataBase(fileNames, pTimeShift, pAirplaneOffsets, pRootTrajecotryFitFileName);
260 }
261 
263  static bool initialized = false;
264  if(initialized)
266  string ads_bLogFiles;
267  string rootTrajecotryFitFileName;
268  double timeShift;
269  Branch ads_bTopBranch = CentralConfig::GetInstance()->GetTopBranch("RdAds_bDataBase");
270  ads_bTopBranch.GetChild("Ads_bLogFiles").GetData(ads_bLogFiles);
271  ads_bTopBranch.GetChild("TimeShift").GetData(timeShift);
272  ads_bTopBranch.GetChild("RootTrajectoryFitOutputFile").GetData(rootTrajecotryFitFileName);
273  Branch offsetBranch = ads_bTopBranch.GetChild("AirplaneOffsets");
274  AirplaneOffsetsMap airplaneOffsetsMap;
275  for (Branch offsetElement = offsetBranch.GetFirstChild(); offsetElement; offsetElement = offsetElement.GetNextSibling()) {
276  string airplaneId;
277  double unixTimeStamp;
278  double altitudeOffset;
279  double timeOffset;
280  offsetElement.GetChild("AirplaneId").GetData(airplaneId);
281  offsetElement.GetChild("UnixTimeStamp").GetData(unixTimeStamp);
282  offsetElement.GetChild("AltitudeOffset").GetData(altitudeOffset);
283  offsetElement.GetChild("TimeOffset").GetData(timeOffset);
284  AirplaneOffsetsMap::iterator iter = airplaneOffsetsMap.find(airplaneId);
285  AirplaneOffsetList* airplaneOffsets = NULL;
286  if(iter == airplaneOffsetsMap.end()) {
287  airplaneOffsets = &airplaneOffsetsMap.insert(make_pair(airplaneId, AirplaneOffsetList())).first->second;
288  } else {
289  airplaneOffsets = &iter->second;
290  }
291  unsigned long gpsSecond;
292  LeapSeconds::GetInstance().ConvertUnixToGPS((time_t)unixTimeStamp/s, gpsSecond);
293  airplaneOffsets->push_back(AirplaneOffset(TimeStamp(gpsSecond), TimeInterval(timeOffset), altitudeOffset));
294  }
295  initialized = true;
296  return Ads_bDataBase::InitSharedDataBase(ads_bLogFiles, TimeInterval(timeShift), airplaneOffsetsMap, rootTrajecotryFitFileName);
297 }
298 
299 
301  if(!_sharedDataBase)
303  return _sharedDataBase;
304 }
305 
Branch GetTopBranch() const
Definition: Branch.cc:63
const double degree
Point object.
Definition: Point.h:32
std::list< FlightAndPositionPair > FlightsAndCoordinatesList
Definition: Ads_bDataBase.h:34
Airplane * _getOrCreateAndGetAirplaneById(const std::string &pId)
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
utl::Point * getPosition(const utl::TimeStamp &pTime, Ads_bEvent::AltitudeType pAltitudeType) const
Definition: Flight.cc:186
Flight * getFlight(const utl::TimeStamp &pTime) const
Definition: Airplane.cc:44
const utl::TimeInterval & getTimeShift() const
Definition: Ads_bDataBase.h:68
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double pow(const double x, const unsigned int i)
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.
char * exists
Definition: XbArray.cc:12
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
constexpr double s
Definition: AugerUnits.h:163
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
const std::string & getId() const
Definition: Airplane.h:32
double abs(const SVector< n, T > &v)
Ads_bEvent * AddAds_bEvent(const utl::TimeStamp &pCaptureTime, const utl::UTMPoint &pCoordinates, const std::string &pAds_bMessageAsHex)
Definition: Airplane.cc:30
Top of the hierarchy of the detector description interface.
Definition: Detector.h:81
static bool comparator(const FlightAndPositionPair &pLHS, const FlightAndPositionPair &pRHS)
std::set< std::string > _logFiles_
Definition: Ads_bDataBase.h:88
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
const string file
FlightsAndCoordinatesList getFlights(const utl::TimeStamp &pTime, const utl::Point &pReconstructedEventPosition, const double &pMaxAngleDifferenceInRadian, utl::CoordinateSystemPtr pCoreCoordinateSystem)
Ads_bDataBase(const utl::TimeInterval &pTimeShift=0.0, const AirplaneOffsetsMap &pAirplaneOffsets=AirplaneOffsetsMap(), const std::string &pRootTrajectoryFitFileName="")
std::map< std::string, AirplaneOffsetList > AirplaneOffsetsMap
Definition: Ads_bDataBase.h:37
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
ReadLogFileResults AddAirplanesFromLogFiles(const std::vector< std::string > &pAds_bLogFileNames)
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
ReadLogFileResult _addAirplanesFromLogFile(const std::string &pAds_bLogFileName)
std::list< ReadLogFileResult > ReadLogFileResults
Definition: Ads_bDataBase.h:45
static ReadLogFileResults InitSharedDataBase(const std::vector< std::string > &pAds_bLogFileNames, const utl::TimeInterval &pTimeShift=0.0, const AirplaneOffsetsMap &pAirplaneOffsets=AirplaneOffsetsMap(), const std::string &pRootTrajecotryFitFileName="")
AirplaneOffsetsMap _airplaneOffsets_
Definition: Ads_bDataBase.h:93
std::string getInformations() const
static Ads_bDataBase * _sharedDataBase
Definition: Ads_bDataBase.h:90
static Ads_bDataBase * getSharedDataBase()
Airplane * getAirplaneById(const std::string &pId)
const AirplaneOffset * getAirplaneOffset(const Airplane &pAirplane, const utl::TimeStamp &pTime) const
Branch GetFirstChild() const
Get first child of this Branch.
Definition: Branch.cc:98
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
constexpr double m
Definition: AugerUnits.h:121
static ReadLogFileResults InitSharedDataBaseFromCentralConfig()
std::list< AirplaneOffset > AirplaneOffsetList
Definition: Ads_bDataBase.h:36
std::string TimestampHumanReadAble(const double &pUnixTimeStampInS)
Definition: AirplaneUtil.h:17
static const long LONGEST_TIMESSPAN_BETWEEN_TWO_ADS_B_EVENTS_DURING_ONE_FLIGHT_IN_SECONDS
Definition: Airplane.h:24

, generated on Tue Sep 26 2023.