RSimulationStationListManager.cc
Go to the documentation of this file.
1 #include <io/REASIOException.h>
2 
3 #include <rdet/RSimulationStationListManager.h>
4 #include <rdet/RManagerRegister.h>
5 
6 #include <det/Detector.h>
7 
8 #include <evt/Event.h>
9 #include <evt/ShowerSimData.h>
10 #include <evt/RadioSimulation.h>
11 
12 #include <utl/UTCDateTime.h>
13 #include <utl/TimeStamp.h>
14 #include <utl/UTMPoint.h>
15 #include <utl/Point.h>
16 #include <utl/ReferenceEllipsoid.h>
17 #include <utl/ErrorLogger.h>
18 
19 #include <fwk/CentralConfig.h>
20 #include <fwk/RunController.h>
21 #include <fwk/LocalCoordinateSystem.h>
22 
23 #include <boost/algorithm/string/predicate.hpp>
24 #include <boost/lexical_cast.hpp>
25 
26 #include <iostream>
27 #include <string>
28 #include <map>
29 
30 
31 using namespace std;
32 using namespace rdet;
33 using namespace det;
34 using namespace evt;
35 using namespace utl;
36 using namespace boost;
37 using namespace fwk;
38 
39 
40 REGISTER_R_MANAGER("RSimulationStationListManager", RSimulationStationListManager);
41 
42 
43 namespace rdet {
44 
46  const
47  {
48  ostringstream res;
49 
50  for (string::const_iterator it = str.begin(); it != str.end(); ++it) {
51  const int i = (unsigned char) (*it);
52  switch (i) {
53  // ntilde; appears in two ways: 0xf1 and 0xc3b1
54  case 195:
55  ++it;
56  if (it != str.end() && int((unsigned char) (*it)) == 177)
57  res << "~n";
58  break;
59  case 241:
60  res << "~n";
61  break;
62  default:
63  // drop unprintable chars
64  if (32 <= i && i < 127)
65  res << *it;
66  break;
67  }
68  }
69 
70  return res.str();
71  }
72 
73 
74  void RSimulationStationListManager::Init(const string& configLink)
75  {
76  // first call shadowed VManager::Init()
77  VSQLManager::Init(configLink);
78 
79  Branch topBranch = CentralConfig::GetInstance()->GetTopBranch("RSimulationStationListManager");
80 
81  topBranch.GetChild("ReadInAdditionalStationViaXML").GetData(fReadInAdditionalStationViaXML);
82  topBranch.GetChild("ReadInAdditionalStationViaSQL").GetData(fReadInAdditionalStationViaSQL);
83 
84  ostringstream out;
85 
86  // Add stations from a XML station list
87  if (fReadInAdditionalStationViaXML) {
88  Branch stationList = fBranch.GetChild("stationList");
89 
90  int number_of_xml_stations = 0;
91  for (Branch cB = stationList.GetFirstChild(); cB; cB = cB.GetNextSibling()) {
92 
93  if (cB.GetName() == "station") {
94 
96  station.fSource = "XML";
97 
98  station.fId = FindComponent<int>("id", cB.GetAttributes());
99  cB.GetChild("northing").GetData(station.fNorthing);
100  cB.GetChild("easting").GetData(station.fEasting);
101  cB.GetChild("altitude").GetData(station.fAltitude);
102  station.fName = cB.GetChild("name").GetDataString();
103  cB.GetChild("commission").GetData(station.fCommissionTime);
104  cB.GetChild("decommission").GetData(station.fDecommissionTime);
105  cB.GetChild("inGrid").GetData(station.fInGrid);
106  cB.GetChild("ellipsoid").GetData(station.fEllipsoid);
107  cB.GetChild("zone").GetData(station.fZone);
108  cB.GetChild("band").GetData(station.fBand);
109  cB.GetChild("nChannels").GetData(station.fNChannels);
110  cB.GetChild("firstChannelId").GetData(station.fFirstChannelId);
111  cB.GetChild("lastChannelId").GetData(station.fLastChannelId);
112 
113  const bool ok =
114  fStationManager.ConditionalAddStationData(station);
115 
116  if (!ok) {
117  ostringstream error;
118  error << "multiple instances of station id " << station.fId
119  << " found in XML / SQL configuration";
120  ERROR(error);
121  throw utl::XMLParseException(error.str());
122  }
123 
124  number_of_xml_stations++;
125  }
126  }
127 
128  out << "\n\tInitialized " << number_of_xml_stations << " radio stations via XML list.";
129  }
130 
131  out << "\n\tInitialize stations from SQL DB: " << fReadInAdditionalStationViaSQL << "\n";
132  INFO(out);
133  }
134 
135 
136  void
137  RSimulationStationListManager::AddVirtualStation(RStationListManager::StationData& station)
138  {
139  fStationManager.AddOrReplaceStationData(station);
140  }
141 
142  bool
143  RSimulationStationListManager::HasStationData(const int id)
144  const
145  {
146  return fStationManager.HasStationData(id);
147  }
148 
149 
151  RSimulationStationListManager::GetListOfChannelIds(std::vector<int>& resultData,
152  const string& /*componentProperty*/,
153  const det::VManager::IndexMap& componentIndex)
154  const
155  {
156  std::vector<int> result;
157  int firstChannelId = 0;
158  int lastChannelId = 0;
159  if (fStationManager.GetData(firstChannelId, "firstChannelId", componentIndex) == eFound &&
160  fStationManager.GetData(lastChannelId, "lastChannelId", componentIndex) == eFound) {
161  for (int i = firstChannelId; i <= lastChannelId; ++i)
162  result.push_back(i);
163  resultData = result;
164  return eFound;
165  }
166  return eNotFound;
167  }
168 
169 
170 }
171 
173 {
174  const TimeStamp& curTime = Detector::GetInstance().GetTime();
175  if (Commissioned.IsInRange(curTime))
176  return;
177 
178  // Remove only station from SQL source
179  fStationManager.ClearStations("SQL");
180 
181  TimeStamp minValidTime(0, 0);
182  TimeStamp maxValidTime(2147483647U, 999999999.9999999);
183  TimeStamp tmpTime;
184  ostringstream query;
185  query << "SELECT "
186  "RStationId, "
187  "ellipsoid, zone, band, "
188  "northing, easting, altitude, "
189  "name, "
190  "inGrid, "
191  "nChannels, firstChannelId, lastChannelId, "
192  "max(Commission), min(Decommission) "
193  "FROM RStation left join RHardWareAssociation using (RStationId) "
194  "left join utm_data using (utm_data_id) "
195  "where Commission<\""
196  << UTCDateTime(curTime).GetInMySQLFormat() << "\" "
197  "and Decommission>\""
198  << UTCDateTime(curTime).GetInMySQLFormat() << "\" "
199  "GROUP BY RStationId ORDER BY RStationId ASC";
200  //jr this selects the comission/decomission of the station
201  // with latest Commision before and the earliest decommission after
202  // the actual detector(event) time of the attached Channel
203  if (Query(query.str(), QueryInfoMessage("all station_list", "station_list")) == eNotFound) {
204  const string err = "No station_list SQL data found! Query: " + query.str();
205  throw DataNotFoundInDBException(err);
206  }
207 
208  // this query cannot be parsed low-level since this breaks mysql/sqlite compatibility
209  // boost::tuple supports only up to 10 types in template parameters
210  // therefore use vector<string> and cast where necessairy
211  // this mysql-double->string->double conversion might cause rounding effects!
212  // (but not for the actual RStationList)
213 
214  vector<string> IdElZoBaNoEaAlNaIGNCFCLCCTDT;
215  while (FetchRow(IdElZoBaNoEaAlNaIGNCFCLCCTDT, false) == eFound) {
216 
218  station.fSource = "SQL";
219 
220  station.fId = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[0]);
221  station.fEllipsoid = IdElZoBaNoEaAlNaIGNCFCLCCTDT[1];
222  station.fZone = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[2]);
223  station.fBand = IdElZoBaNoEaAlNaIGNCFCLCCTDT[3];
224  station.fNorthing = lexical_cast<double>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[4]);
225  station.fEasting = lexical_cast<double>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[5]);
226  station.fAltitude = lexical_cast<double>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[6]);
227  station.fName = Utf8To7Bit(IdElZoBaNoEaAlNaIGNCFCLCCTDT[7]);
228  station.fInGrid = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[8]);
229  station.fNChannels = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[9]);
230  station.fFirstChannelId = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[10]);
231  station.fLastChannelId = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[11]);
232 
233  //jr check for empty Times and crude conversion from human readbale UTC as of mysql to AugerTimeFormat e.g. used in SStationList.xml
234  // ComissionTime is defined in DB as 'NOT NULL'
235  // if NULL is returned (here size()==0 ), then the join found no RHardWareAssociation,
236  // thus we do not add this station to the full list!
237  if (IdElZoBaNoEaAlNaIGNCFCLCCTDT[12].size() == 0) {
238  ostringstream err;
239  err << "No configuration for station-id " << station.fId << " found -> station ignored";
240  ERROR(err);
241  } else {
242 
243  if (IdElZoBaNoEaAlNaIGNCFCLCCTDT[12].size() < 19) {
244  station.fCommissionTime = "2029-12-31T00:00:00Z";
245  ostringstream warn;
246  warn << "Empty Comissioning-Time for station " << station.fId << " now set to "
247  << station.fCommissionTime;
248  INFO(warn);
249  } else {
250  station.fCommissionTime = IdElZoBaNoEaAlNaIGNCFCLCCTDT[12];
251  station.fCommissionTime[10] = 'T';
252  station.fCommissionTime[19] = 'Z';
253  }
254 
255  if (IdElZoBaNoEaAlNaIGNCFCLCCTDT[13].size() < 19) {
256  station.fDecommissionTime = "2030-01-01T00:00:00Z";
257  ostringstream warn;
258  warn << "Empty Decomissioning-Time for station " << station.fId << " now set to "
259  << station.fDecommissionTime;
260  INFO(warn);
261  } else {
262  station.fDecommissionTime = IdElZoBaNoEaAlNaIGNCFCLCCTDT[13];
263  station.fDecommissionTime[10] = 'T';
264  station.fDecommissionTime[19] = 'Z';
265  }
266 
267  fStationManager.AddOrReplaceStationData(station);
268 
269  // const bool ok = fStationManager.ConditionalAddStationData(station);
270  // if (!ok) {
271  // ostringstream err;
272  // err << "problem adding station to list for station-id " << station.fId
273  // << "found in SQL / XML configuration";
274  // ERROR(err);
275  // }
276  }
277 
278  tmpTime = boost::lexical_cast<UTCDateTime>(station.fCommissionTime).GetTimeStamp();
279  if (tmpTime > minValidTime) {
280  minValidTime = tmpTime;
281  }
282  tmpTime = boost::lexical_cast<UTCDateTime>(station.fDecommissionTime).GetTimeStamp();
283  if (tmpTime < maxValidTime) {
284  maxValidTime = tmpTime;
285  }
286  }
287 
288  TimeStamp maxDecommission(0, 0);
289  // Check if there are additional stations commissioned within the minValidTime..maxValidTime timerange
290  query.str("");
291  query << "SELECT max(Decommission) "
292  "FROM RStation "
293  "left join RHardWareAssociation using (RStationId) left join utm_data using (utm_data_id)"
294  "where Decommission<\""
295  << UTCDateTime(curTime).GetInMySQLFormat() << "\"";
296 
297  if (Query(query.str(), QueryInfoMessage("all station_list", "station_list")) == eNotFound) {
298  const string err = "No decommissioned stations found before current time! Query: " + query.str();
299  throw DataNotFoundInDBException(err);
300  } else {
301  vector<string> sql_result;
302  if (FetchRow(sql_result, false) == eFound) {
303  if (sql_result[0].size() >= 19) {
304  std::string temp = sql_result[0];
305  temp[10] = 'T';
306  temp[19] = 'Z';
307  maxDecommission = boost::lexical_cast<UTCDateTime>(temp).GetTimeStamp();
308  }
309  }
310  }
311 
312  minValidTime = max(maxDecommission, minValidTime);
313  TimeStamp minCommission = TimeStamp::Max();
314 
315  // Check if there are additional stations commissioned within the minValidTime..maxValidTime timerange
316  query.str("");
317  query << "SELECT min(Commission) "
318  "FROM RStation "
319  "left join RHardWareAssociation using (RStationId) left join utm_data using (utm_data_id)"
320  "where Commission>\""
321  << UTCDateTime(curTime).GetInMySQLFormat() << "\"";
322  if (Query(query.str(), QueryInfoMessage("all station_list", "station_list")) == eNotFound) {
323  const string err = "No now commissioned stations found after current time! Query: " + query.str();
324  throw DataNotFoundInDBException(err);
325  } else {
326  vector<string> sql_result2;
327  if (FetchRow(sql_result2, false) == eFound) {
328  if (sql_result2[0].size() >= 19) {
329  std::string temp = sql_result2[0];
330  temp[10] = 'T';
331  temp[19] = 'Z';
332  minCommission = boost::lexical_cast<UTCDateTime>(temp).GetTimeStamp();
333  }
334  }
335  }
336 
337  maxValidTime = min(minCommission, maxValidTime);
338  Commissioned.SetTimeRange(minValidTime, maxValidTime);
339  FreeResult();
340 
341  // close SQL to save one connection, but this leads to IsInitialized=0
342  // Close();
343 }
344 
Branch GetTopBranch() const
Definition: Branch.cc:63
void Update(std::vector< double > &init, const std::vector< double > &res)
Definition: Util.h:100
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
std::string GetInMySQLFormat() const
Definition: UTCDateTime.cc:107
void Init()
Initialise the registry.
vector< t2list > out
output of the algorithm: a list of clusters
Definition: XbAlgo.cc:32
bool ok(bool okay)
Definition: testlib.cc:89
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
string Utf8To7Bit(const string &str)
Exception for errors encountered when parsing XML.
#define U
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
#define REGISTER_R_MANAGER(_name_, _Type_)
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
Exception to use in case requested data not found in the database with detailed printout.
const Data result[]
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
Manager for RD description in SQL or XML station lists.
std::map< std::string, std::string > IndexMap
Definition: VManager.h:133
Branch GetFirstChild() const
Get first child of this Branch.
Definition: Branch.cc:98
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
Status
Specifies success or (eventually) various possible failure modes.
Definition: VManager.h:127

, generated on Tue Sep 26 2023.