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

, generated on Tue Sep 26 2023.