CStationListManager.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <boost/format.hpp>
3 #include <boost/lexical_cast.hpp>
4 #include <cdet/CStationListManager.h>
5 #include <det/Detector.h>
6 #include <utl/UTCDateTime.h>
7 
8 using namespace cdet;
9 using namespace det;
10 using namespace std;
11 using namespace utl;
12 using namespace ::boost::multi_index;
13 
14 
15 namespace cdet {
16 
17 // specialization for "int"
18 template<>
21  const string& componentProperty,
22  const VManager::IndexMap& componentIndex)
23  const
24 {
25  const int id = GetStationId(componentIndex);
26  const StationIdIndex& idIndex = fStations.get<ByStationId>();
27  const StationIdIndex::const_iterator sIt = idIndex.find(id);
28 
29  if (sIt == idIndex.end())
30  return VManager::eNotFound;
31 
32  if (componentProperty == "groupId")
33  returnData = sIt->fGroupId;
34  else if (componentProperty == "zone")
35  returnData = sIt->fZone;
36  else
37  return VManager::eNotFound;
38 
39  return VManager::eFound;
40 }
41 
42 
43 // specialization for "double"
44 template<>
46 CStationListManager::GetData(double& returnData,
47  const string& componentProperty,
48  const VManager::IndexMap& componentIndex)
49  const
50 {
51  const int id = GetStationId(componentIndex);
52  const StationIdIndex& idIndex = fStations.get<ByStationId>();
53  const StationIdIndex::const_iterator sIt = idIndex.find(id);
54 
55  if (sIt == idIndex.end())
56  return VManager::eNotFound;
57 
58  if (componentProperty == "northing")
59  returnData = sIt->fNorthing;
60  else if (componentProperty == "easting")
61  returnData = sIt->fEasting;
62  else if (componentProperty == "altitude")
63  returnData = sIt->fAltitude;
64  else if (componentProperty == "axis1")
65  returnData = sIt->fAxis1;
66  else if (componentProperty == "axis2")
67  returnData = sIt->fAxis2;
68  else
69  return VManager::eNotFound;
70 
71  return VManager::eFound;
72 }
73 
74 
75 // specialization for "string"
76 template<>
78 CStationListManager::GetData(string& returnData,
79  const string& componentProperty,
80  const VManager::IndexMap& componentIndex)
81  const
82 {
83  const int id = GetStationId(componentIndex);
84  const StationIdIndex& idIndex = fStations.get<ByStationId>();
85  const StationIdIndex::const_iterator sIt = idIndex.find(id);
86 
87  if (sIt == idIndex.end())
88  return VManager::eNotFound;
89 
90  if (componentProperty == "name")
91  returnData = sIt->fName;
92  else if (componentProperty == "commission")
93  returnData = sIt->fCommissionTime;
94  else if (componentProperty == "decommission")
95  returnData = sIt->fDecommissionTime;
96  else if (componentProperty == "band")
97  returnData = sIt->fBand;
98  else if (componentProperty == "ellipsoid")
99  returnData = sIt->fEllipsoid;
100  else
101  return VManager::eNotFound;
102 
103  return VManager::eFound;
104 }
105 
106 
107 // specialization for "vector<int>"
108 template<>
110 CStationListManager::GetData(vector<int>& returnData,
111  const string& componentProperty,
112  const VManager::IndexMap& componentIndex)
113  const
114 {
115  if (fStations.empty())
116  return VManager::eNotFound;
117 
118  if (componentProperty == "fullStationList")
119  GetFullStationList(returnData);
120  else if (componentProperty == "groupIds")
121  return GetGroupIds(returnData);
122  else if (componentProperty == "group")
123  return GetGroup(returnData, VManager::FindComponent<int>("groupId", componentIndex));
124  else if (componentProperty == "stationGroup")
125  return GetStationGroup(returnData, GetStationId(componentIndex));
126  else if (componentProperty == "crown")
127  return
128  GetStationCrown(returnData,
129  GetStationId(componentIndex),
130  VManager::FindComponent<int>("crown", componentIndex));
131  else
132  return VManager::eNotFound;
133 
134  return VManager::eFound;
135 }
136 
137 
138 // specialization for "vector<vector<int> >"
139 template<>
141 CStationListManager::GetData(vector<vector<int> >& returnData,
142  const string& componentProperty,
143  const VManager::IndexMap&)
144  const
145 {
146  if (fStations.empty())
147  return VManager::eNotFound;
148 
149  if (componentProperty == "fullStationGroups")
150  GetFullStationGroups(returnData);
151  else
152  return VManager::eNotFound;
153 
154  return VManager::eFound;
155 }
156 
157 
158 // specialization for "vector<bool>"
159 template<>
161 CStationListManager::GetData(vector<bool>& returnData,
162  const string& componentProperty,
163  const VManager::IndexMap& componentIndex)
164  const
165 {
166  if (fStations.empty())
167  return VManager::eNotFound;
168 
169  if (componentProperty == "inGrid")
170  {
171  const int id = GetStationId(componentIndex);
172  const StationIdIndex& idIndex = fStations.get<ByStationId>();
173  typedef StationIdIndex::const_iterator StationIterator;
174  const StationIterator sIt = idIndex.find(id);
175  if (sIt == idIndex.end())
176  return VManager::eNotFound;
177  returnData = sIt->fInGrid;
178  }
179  else
180  return VManager::eNotFound;
181 
182  return VManager::eFound;
183 }
184 
185 
186 bool
188 {
189  if (HasStationData(station.fId))
190  return false;
191 
192  const TimeStamp commission =
193  boost::lexical_cast<UTCDateTime>(station.fCommissionTime).GetTimeStamp();
194  const TimeStamp decommission =
195  boost::lexical_cast<UTCDateTime>(station.fDecommissionTime).GetTimeStamp();
196  station.fCommissionTimeRange = TimeRange(commission, decommission);
197  fStations.insert(station);
198 
199  return true;
200 }
201 
202 
203 bool
205  const
206 {
207  const StationIdIndex& idIndex = fStations.get<ByStationId>();
208  return idIndex.find(id) != idIndex.end();
209 }
210 
211 
212 void
214  const
215 {
216  returnList.clear();
217  const StationIdIndex& idIndex = fStations.get<ByStationId>();
218  for (StationIdIndex::const_iterator sIt = idIndex.begin();
219  sIt != idIndex.end(); ++sIt)
220  returnList.push_back(sIt->fId);
221 }
222 
223 
224 void
225 CStationListManager::GetFullStationGroups(vector<vector<int> >& returnData)
226  const
227 {
228  if (fStations.empty())
229  return;
230 
231  returnData.clear();
232 
233  const TimeStamp& dTime = Detector::GetInstance().GetTime();
234 
235  typedef GroupIdIndex::const_iterator GroupIterator;
236 
237  const GroupIdIndex& grIndex = fStations.get<ByGroupId>();
238 
239  int currentGroupId = 0;
240  vector<int> currentGroup;
241 
242  for (GroupIterator it = grIndex.begin(); it != grIndex.end(); ++it) {
243 
244  const int stationGroupId = it->fGroupId;
245 
246  // skip group 0 and out of time stations
247  if (!stationGroupId || it->fCommissionTimeRange != dTime)
248  continue;
249 
250  // new group?
251  if (stationGroupId != currentGroupId) {
252  if (!(currentGroup.size() > 1)) {
253  returnData.push_back(currentGroup);
254  currentGroup.clear();
255  }
256  currentGroupId = stationGroupId;
257  }
258 
259  currentGroup.push_back(it->fId);
260 
261  }
262 
263  if (!(currentGroup.size() > 1))
264  returnData.push_back(currentGroup);
265 }
266 
267 
269 CStationListManager::GetGroupIds(vector<int>& returnData)
270  const
271 {
272  const GroupIdIndex& grIndex = fStations.get<ByGroupId>();
273 
274  if (grIndex.empty())
275  return VManager::eFound;
276 
277  const TimeStamp& dTime = Detector::GetInstance().GetTime();
278 
279  typedef GroupIdIndex::const_iterator GroupIterator;
280 
281  GroupIterator sIt;
282  for (sIt = grIndex.begin(); sIt != grIndex.end(); ++sIt)
283  if (sIt->fCommissionTimeRange == dTime)
284  break;
285 
286  if (sIt != grIndex.end())
287  returnData.push_back(sIt->fGroupId);
288 
289  for (++sIt; sIt != grIndex.end(); ++sIt)
290  if (sIt->fCommissionTimeRange == dTime &&
291  returnData.back() != sIt->fGroupId)
292  returnData.push_back(sIt->fGroupId);
293 
294  return VManager::eFound;
295 }
296 
297 
299 CStationListManager::GetGroup(vector<int>& returnData, const int groupId)
300  const
301 {
302  const TimeStamp& dTime = Detector::GetInstance().GetTime();
303 
304  typedef GroupIdIndex::const_iterator GroupIterator;
305  typedef pair<GroupIterator, GroupIterator> GroupRange;
306 
307  const GroupRange group =
308  fStations.get<ByGroupId>().equal_range(groupId);
309 
310  for (GroupIterator it = group.first; it != group.second; ++it)
311  if (it->fCommissionTimeRange == dTime)
312  returnData.push_back(it->fId);
313 
314  return VManager::eFound;
315 }
316 
317 
319 CStationListManager::GetStationGroup(vector<int>& returnData, const int id)
320  const
321 {
322  const StationIdIndex& idIndex = fStations.get<ByStationId>();
323  typedef StationIdIndex::const_iterator StationIterator;
324  const StationIterator sIt = idIndex.find(id);
325  if (sIt == idIndex.end())
326  return VManager::eNotFound;
327 
328  returnData.clear();
329 
330  const TimeStamp& dTime = Detector::GetInstance().GetTime();
331 
332  if (!sIt->fGroupId)
333  return VManager::eFound;
334 
335  typedef GroupIdIndex::const_iterator GroupIterator;
336  typedef pair<GroupIterator, GroupIterator> GroupRange;
337 
338  const GroupRange group =
339  fStations.get<ByGroupId>().equal_range(sIt->fGroupId);
340 
341  for (GroupIterator it = group.first; it != group.second; ++it)
342  if (it->fCommissionTimeRange == dTime && it->fId != id)
343  returnData.push_back(it->fId);
344 
345  return VManager::eFound;
346 }
347 
348 
352  const int id,
353  const int nCrown,
355  const
356 {
357  const StationIdIndex& idIndex = fStations.get<ByStationId>();
358  typedef StationIdIndex::const_iterator StationIterator;
359  const StationIterator sIt = idIndex.find(id);
360  if (sIt == idIndex.end())
361  return VManager::eNotFound;
362 
363  crown.clear();
364 
365  if (size_t(index) >= sIt->fInGrid.size() || !sIt->fInGrid[index])
366  return VManager::eFound;
367 
368  if (nCrown <= 0) {
369  crown.push_back(id);
370  return VManager::eFound;
371  }
372 
373  double level = nCrown;
374  if (index == CDetectorConstants::eInfill750)
375  level /= 2;
376 
377  /*
378  In a = Delta axis1 and b = Delta axis2 coordinates, i.e. relative to the
379  coordinates of the central station, the crown C = 3 looks like:
380 
381  b ^
382  (-) | (+)
383  c c c c
384  |
385  c + c
386  |
387  c + c
388  |
389  --c--+--+--+--+--+--c--> a
390  |
391  c + c
392  |
393  c + c
394  |
395  c c c c
396  (+) | (-)
397 
398  where (+)/(-) denote the two diagonal quadrants. For (+) quadrants we can
399  describe crown stations with the following boolean expression,
400 
401  ( |a| == C && |b| <= C ) || ( |a| <= C && |b| == C ).
402 
403  In the (-) quadrants the crown stations are described as returning true for
404 
405  |a - b| == C.
406 
407  The quadrant is selected depending on the boolean value of
408 
409  sign(a) == sign(b) -> true for (+)
410  -> false for (-)
411 
412  According to this we can set up a MySQL query that automatically returns only
413  crown stations.
414  */
415 
416  const double axis1 = sIt->fAxis1;
417  const double axis2 = sIt->fAxis2;
418 
419  /* we narrow down the number of candidates by selecting a square region around
420  the central station and automatically satisfy condition a,b <= C */
421 
422  using boost::make_tuple;
423 
424  const AxesIndex& axesIndex = fStations.get<ByAxes>();
425  typedef AxesIndex::const_iterator AxesIterator;
426  const AxesIterator start =
427  axesIndex.lower_bound(make_tuple(axis1 - level, axis2 - level));
428  const AxesIterator stop =
429  axesIndex.upper_bound(make_tuple(axis1 + level, axis2 + level));
430 
431  const TimeStamp& detTime = det::Detector::GetInstance().GetTime();
432 
433  for (AxesIterator it = start; it != stop; ++it) {
434 
435  if (size_t(index) >= it->fInGrid.size() || !it->fInGrid[index])
436  continue;
437 
438  const double a = it->fAxis1 - axis1;
439  const double b = it->fAxis2 - axis2;
440  if (a*b >= 0) {
441  if (fabs(a) != level && fabs(b) != level)
442  continue;
443  } else if (fabs(a - b) != level)
444  continue;
445 
446  // check commission and decommission
447  if (it->fCommissionTimeRange != detTime)
448  continue;
449 
450  crown.push_back(it->fId);
451 
452  }
453 
454  return VManager::eFound;
455 }
456 
457 
458 string
459 StringToXMLString(const string& str)
460 {
461  ostringstream res;
462 
463  for (string::const_iterator it = str.begin(); it != str.end(); ++it)
464  switch (*it) {
465  // replace '&' with "&amp;"
466  case '&':
467  res << "and";
468  break;
469  default:
470  res << *it;
471  }
472 
473  return res.str();
474 }
475 
476 
477 bool
478 CStationListManager::DumpXML(ostream& output, const string& indent)
479  const
480 {
481  if (fStations.empty())
482  return false;
483 
484  boost::format stationFmt(
485  "%1%<station id=\"%2%\">\n"
486  "%1% <northing unit=\"meter\"> %|3$.2f| </northing>\n"
487  "%1% <easting unit=\"meter\"> %|4$.2f| </easting>\n"
488  "%1% <altitude unit=\"meter\"> %|5$.2f| </altitude>\n"
489  "%1% <name> %6% </name>\n"
490  "%1% <commission> %7% </commission>\n"
491  "%1% <decommission> %8% </decommission>\n"
492  "%1% <inGrid> %9% </inGrid>\n"
493  "%1% <groupId> %10% </groupId>\n"
494  "%1% <axes> %11% %12% </axes>\n"
495  "%1% <ellipsoid> %13% </ellipsoid>\n"
496  "%1% <zone> %14% </zone>\n"
497  "%1% <band> %15% </band>\n"
498  "%1%</station>\n"
499  );
500 
501  const StationIdIndex& sIndex = fStations.get<ByStationId>();
502  for (StationIdIndex::const_iterator sIt = sIndex.begin();
503  sIt != sIndex.end(); ++sIt)
504  {
505  ostringstream inGrid;
506  if (sIt->fInGrid.size()==0)
507  inGrid << "0";
508  else
509  for (size_t i = 1; i < sIt->fInGrid.size(); ++i)
510  if (sIt->fInGrid[i])
511  inGrid << i << " ";
512 
513  output
514  << stationFmt
515  % indent
516  % sIt->fId
517  % sIt->fNorthing
518  % sIt->fEasting
519  % sIt->fAltitude
520  % StringToXMLString(sIt->fName)
521  % sIt->fCommissionTime
522  % sIt->fDecommissionTime
523  % inGrid.str()
524  % sIt->fGroupId
525  % sIt->fAxis1
526  % sIt->fAxis2
527  % sIt->fEllipsoid
528  % sIt->fZone
529  % sIt->fBand
530  << '\n';
531  }
532 
533  return true;
534 }
535 
536 } // cdet
537 
538 // Configure (x)emacs for this file ...
539 // Local Variables:
540 // mode: c++
541 // End:
index< StationContainer, ByGroupId >::type GroupIdIndex
bool DumpXML(std::ostream &output, const std::string &indent="") const
det::VManager::Status GetGroupIds(std::vector< int > &returnData) const
Time interval defined by two TimeStamps.
Definition: TimeRange.h:23
bool ConditionalAddStationData(StationData &station)
adds station record only if it does not already exist
int crown(double x1, double x2, double y1, double y2)
Definition: XbArray.cc:14
bool HasStationData(const int id) const
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
det::VManager::Status GetData(T &returnData, const std::string &componentProperty, const det::VManager::IndexMap &componentIndex) const
void GetFullStationGroups(std::vector< std::vector< int > > &returnList) const
det::VManager::Status GetStationGroup(std::vector< int > &returnData, const int id) const
det::VManager::Status GetStationCrown(std::vector< int > &crown, const int id, const int nCrown, CDetectorConstants::GridIndex index=CDetectorConstants::eStandard) const
Get crown accoding to detector time and station commission time range.
index< StationContainer, ByAxes >::type AxesIndex
std::map< std::string, std::string > IndexMap
Definition: VManager.h:133
string StringToXMLString(const string &str)
void GetFullStationList(std::vector< int > &returnList) const
det::VManager::Status GetGroup(std::vector< int > &returnData, const int groupId) const
index< StationContainer, ByStationId >::type StationIdIndex
Status
Specifies success or (eventually) various possible failure modes.
Definition: VManager.h:127

, generated on Tue Sep 26 2023.