RStationListSQLManager.cc
Go to the documentation of this file.
1 #include <map>
2 #include <boost/lexical_cast.hpp>
3 #include <det/Detector.h>
4 #include <rdet/RStationListSQLManager.h>
5 #include <rdet/RManagerRegister.h>
6 #include <utl/UTCDateTime.h>
7 #include <utl/TimeStamp.h>
8 
9 using namespace std;
10 using namespace rdet;
11 using namespace det;
12 using namespace utl;
13 using namespace boost;
14 
15 REGISTER_R_MANAGER("RStationListSQLManager", RStationListSQLManager)
16 ;
17 
18 namespace rdet {
19 
20 string Utf8To7Bit(const string& str)
21 {
22  ostringstream res;
23 
24  for (string::const_iterator it = str.begin(); it != str.end(); ++it) {
25  const int i = (unsigned char) (*it);
26  switch (i) {
27  // ntilde; appears in two ways: 0xf1 and 0xc3b1
28  case 195:
29  ++it;
30  if (it != str.end() && int((unsigned char) (*it)) == 177)
31  res << "~n";
32  break;
33  case 241:
34  res << "~n";
35  break;
36  default:
37  // drop unprintable chars
38  if (32 <= i && i < 127)
39  res << *it;
40  break;
41  }
42  }
43 
44  return res.str();
45 }
46 
47 }
48 
49 void RStationListSQLManager::Init(const string& configLink)
50 {
51  // first call shadowed VManager::Init()
52  VSQLManager::Init(configLink);
53 }
54 
56 {
57  const TimeStamp& curTime = Detector::GetInstance().GetTime();
58  if (Commissioned.IsInRange(curTime))
59  return;
60 
61  ostringstream info;
62  info << "Request station_list SQL Data for time: " << curTime;
63  INFO(info);
64 
65  // clear station list
66  fStationManager.ClearStationList();
67 
68  TimeStamp minValidTime(0, 0);
69  TimeStamp maxValidTime(2147483647U, 999999999.9999999);
70  TimeStamp tmpTime;
71  ostringstream query;
72  query << "SELECT "
73  "RStationId, "
74  "ellipsoid, zone, band, "
75  "northing, easting, altitude, "
76  "name, "
77  "inGrid, "
78  "nChannels, firstChannelId, lastChannelId, "
79  "max(Commission), min(Decommission) "
80  "FROM RStation left join RHardWareAssociation using (RStationId) "
81  "left join utm_data using (utm_data_id) "
82  "where Commission<\""
83  << UTCDateTime(curTime).GetInMySQLFormat() << "\" "
84  "and Decommission>\""
85  << UTCDateTime(curTime).GetInMySQLFormat() << "\" "
86  "GROUP BY RStationId ORDER BY RStationId ASC";
87  //jr this selects the comission/decomission of the station
88  // with latest Commision before and the earliest decommission after
89  // the actual detector(event) time of the attached Channel
90 
91  if (Query(query.str(), QueryInfoMessage("all station_list", "station_list")) == eNotFound) {
92  const string err = "No station_list SQL data found! Query: " + query.str();
93  throw DataNotFoundInDBException(err);
94  }
95 
96  // this query cannot be parsed low-level since this breaks mysql/sqlite compatibility
97  // boost::tuple supports only up to 10 types in template parameters
98  // therefore use vector<string> and cast where necessairy
99  // this mysql-double->string->double conversion might cause rounding effects!
100  // (but not for the actual RStationList)
101 
102  vector<string> IdElZoBaNoEaAlNaIGNCFCLCCTDT;
103  while (FetchRow(IdElZoBaNoEaAlNaIGNCFCLCCTDT, false) == eFound) {
104 
106  station.fSource = "SQL"; // to identify that the describtion of this station should come from an SQL manager
107 
108  station.fId = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[0]);
109  if (!fStationManager.HasStationData(station.fId)) {
110  station.fEllipsoid = IdElZoBaNoEaAlNaIGNCFCLCCTDT[1];
111  station.fZone = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[2]);
112  station.fBand = IdElZoBaNoEaAlNaIGNCFCLCCTDT[3];
113  station.fNorthing = lexical_cast<double>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[4]);
114  station.fEasting = lexical_cast<double>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[5]);
115  station.fAltitude = lexical_cast<double>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[6]);
116  station.fName = Utf8To7Bit(IdElZoBaNoEaAlNaIGNCFCLCCTDT[7]);
117  station.fInGrid = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[8]);
118  station.fNChannels = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[9]);
119  station.fFirstChannelId = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[10]);
120  station.fLastChannelId = lexical_cast<int>(IdElZoBaNoEaAlNaIGNCFCLCCTDT[11]);
121  //jr check for empty Times and crude conversion from human readbale UTC as of mysql to AugerTimeFormat e.g. used in SStationList.xml
122  // ComissionTime is defined in DB as 'NOT NULL'
123  // if NULL is returned (here size()==0 ), then the join found no RHardWareAssociation,
124  // thus we do not add this station to the full list!
125  if (IdElZoBaNoEaAlNaIGNCFCLCCTDT[12].size() == 0) {
126  ostringstream err;
127  err << "No configuration for station-id " << station.fId << " found -> station ignored";
128  ERROR(err);
129  } else {
130  if (IdElZoBaNoEaAlNaIGNCFCLCCTDT[12].size() < 19) {
131  station.fCommissionTime = "2029-12-31T00:00:00Z";
132  ostringstream warn;
133  warn << "Empty Comissioning-Time for station " << station.fId << " now set to "
134  << station.fCommissionTime;
135  INFO(warn);
136  } else {
137  station.fCommissionTime = IdElZoBaNoEaAlNaIGNCFCLCCTDT[12];
138  station.fCommissionTime[10] = 'T';
139  station.fCommissionTime[19] = 'Z';
140  }
141  if (IdElZoBaNoEaAlNaIGNCFCLCCTDT[13].size() < 19) {
142  station.fDecommissionTime = "2030-01-01T00:00:00Z";
143  ostringstream warn;
144  warn << "Empty Decomissioning-Time for station " << station.fId << " now set to "
145  << station.fDecommissionTime;
146  INFO(warn);
147  } else {
148  station.fDecommissionTime = IdElZoBaNoEaAlNaIGNCFCLCCTDT[13];
149  station.fDecommissionTime[10] = 'T';
150  station.fDecommissionTime[19] = 'Z';
151  }
152  const bool ok = fStationManager.ConditionalAddStationData(station);
153  if (!ok) {
154  ostringstream err;
155  err << "problem adding station to list for station-id " << station.fId
156  << "found in SQL configuration";
157  ERROR(err);
158  }
159  }
160  tmpTime = boost::lexical_cast<UTCDateTime>(station.fCommissionTime).GetTimeStamp();
161  if (tmpTime > minValidTime) {
162  minValidTime = tmpTime;
163  }
164  tmpTime = boost::lexical_cast<UTCDateTime>(station.fDecommissionTime).GetTimeStamp();
165  if (tmpTime < maxValidTime) {
166  maxValidTime = tmpTime;
167  }
168  }
169  }
170 
171  TimeStamp maxDecommission(0, 0);
172  // Check if there are additional stations commissioned within the minValidTime..maxValidTime timerange
173  query.str("");
174  query << "SELECT max(Decommission) "
175  "FROM RStation "
176  "left join RHardWareAssociation using (RStationId) left join utm_data using (utm_data_id)"
177  "where Decommission<\""
178  << UTCDateTime(curTime).GetInMySQLFormat() << "\"";
179  if (Query(query.str(), QueryInfoMessage("all station_list", "station_list")) == eNotFound) {
180  const string err = "No decommissioned stations found before current time! Query: "
181  + query.str();
182  throw DataNotFoundInDBException(err);
183  } else {
184  vector<string> sql_result;
185  if (FetchRow(sql_result, false) == eFound) {
186  if (sql_result[0].size() >= 19) {
187  std::string temp = sql_result[0];
188  temp[10] = 'T';
189  temp[19] = 'Z';
190  maxDecommission = boost::lexical_cast<UTCDateTime>(temp).GetTimeStamp();
191  }
192  }
193  }
194  minValidTime = max(maxDecommission, minValidTime);
195 
196  TimeStamp minCommission = TimeStamp::Max();
197  // Check if there are additional stations commissioned within the minValidTime..maxValidTime timerange
198  query.str("");
199  query << "SELECT min(Commission) "
200  "FROM RStation "
201  "left join RHardWareAssociation using (RStationId) left join utm_data using (utm_data_id)"
202  "where Commission>\""
203  << UTCDateTime(curTime).GetInMySQLFormat() << "\"";
204  if (Query(query.str(), QueryInfoMessage("all station_list", "station_list")) == eNotFound) {
205  const string err = "No now commissioned stations found after current time! Query: "
206  + query.str();
207  throw DataNotFoundInDBException(err);
208  } else {
209  vector<string> sql_result2;
210  if (FetchRow(sql_result2, false) == eFound) {
211  if (sql_result2[0].size() >= 19) {
212  std::string temp = sql_result2[0];
213  temp[10] = 'T';
214  temp[19] = 'Z';
215  minCommission = boost::lexical_cast<UTCDateTime>(temp).GetTimeStamp();
216  }
217  }
218  }
219  maxValidTime = min(minCommission, maxValidTime);
220 
221  Commissioned.SetTimeRange(minValidTime, maxValidTime);
222  FreeResult();
223  // close SQL to save one connection, but this leads to IsInitialized=0
224  // Close();
225 }
226 
227 // Configure (x)emacs for this file ...
228 // Local Variables:
229 // mode: c++
230 // End:
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.
bool ok(bool okay)
Definition: testlib.cc:89
string Utf8To7Bit(const string &str)
#define U
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
#define REGISTER_R_MANAGER(_name_, _Type_)
#define max(a, b)
Exception to use in case requested data not found in the database with detailed printout.
Manager for SD description in SQL station lists.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165

, generated on Tue Sep 26 2023.