MonitoringSQLManager.cc
Go to the documentation of this file.
1 #include "MonitoringSQLManager.h"
2 
3 #include <boost/lambda/lambda.hpp>
4 
5 #include <utl/ErrorLogger.h>
6 #include <rdet/RDetector.h>
7 #include <rdet/RManagerRegister.h>
8 #include <det/VManager.h>
9 #include <utl/UTCDateTime.h>
10 #include <utl/TimeStamp.h>
11 #include <utl/LeapSeconds.h>
12 #include <utl/TabulatedFunctionComplexLgAmpPhase.h>
13 #include <utl/MathConstants.h>
14 
15 #include <utl/AugerException.h>
16 #include <utl/AugerUnits.h>
17 
18 #include <sstream>
19 
20 using namespace std;
21 
22 
23 REGISTER_R_MANAGER("MonitoringSQLManager", rdet::MonitoringSQLManager);
24 
25 
26 namespace rdet {
27 
28 void
29 MonitoringSQLManager::Init(const string& configLink)
30 {
31  VSQLManager::Init(configLink);
32 }
33 
34 
35 double
36 MonitoringSQLManager::GetTemperature(const std::string& site, const double timeToAverage,
37  const unsigned int numberOfQueriesToBuffer,
38  const double precision)
39  const
40 {
41  const utl::TimeStamp& currentTime = det::Detector::GetInstance().GetTime();
42  unsigned int currentGPSSeconds = currentTime.GetGPSSecond();
43 
44  if (fTemperatureBuffer.find(site) == fTemperatureBuffer.end()) {
45  INFO("site not found in temperature buffer, buffering database...");
46  if (!BufferTemperature(site, timeToAverage, numberOfQueriesToBuffer)) {
47  WARNING("An error occurred while buffering temperature.");
48  return std::numeric_limits<double>::quiet_NaN();;
49  }
50  } else {
51  std::cout << "Temperatures buffered between " << fTemperatureBufferInterval[site].first << " and "
52  << fTemperatureBufferInterval[site].second << "\ncurrentGPSSeconds = "
53  << currentGPSSeconds << std::endl;
54  if (((fTemperatureBufferInterval[site].first - 0.9 * precision / utl::second) > currentGPSSeconds) ||
55  ((fTemperatureBufferInterval[site].second + 0.9 * precision / utl::second) < currentGPSSeconds)) {
56  INFO("No temperature information at event-time found in buffer, rebuffering database...");
57  if (!BufferTemperature(site, timeToAverage, numberOfQueriesToBuffer)) {
58  WARNING("An error occurred while buffering temperature");
59  return std::numeric_limits<double>::quiet_NaN();;
60  }
61  }
62  }
63 
64  for (auto it = fTemperatureBuffer[site].begin(); it != fTemperatureBuffer[site].end(); ++it) {
65  if (fabs(it->first - currentGPSSeconds) < precision / utl::second) {
66  stringstream sstr;
67  sstr << "Temperature found in buffer. GPSsecond in buffer " << it->first
68  << ", currentGPSseconds " << currentGPSSeconds << ", difference "
69  << fabs(it->first - currentGPSSeconds) << ", precision " << precision / utl::second
70  << "seconds";
71  INFO(sstr.str());
72  return it->second;
73  }
74  }
75 
76  ostringstream sstr;
77  sstr << "An error occurred reading temperature from buffer. "
78  "Most likely reason: There is no temperature information in the database for the event time "
79  << utl::UTCDateTime(currentTime).GetInXMLFormat();
80  WARNING(sstr);
81 
82  //throw utl::AugerException("An error occurred reading temperature from buffer.");
83  //return false;
84  return std::numeric_limits<double>::quiet_NaN();
85 }
86 
87 
88 bool
89 MonitoringSQLManager::BufferTemperature(const std::string& site, const double timeToAverage,
90  const unsigned int numberOfQueriesToBuffer)
91  const
92 {
93  stringstream query;
94  const utl::TimeStamp& currentTime = det::Detector::GetInstance().GetTime();
95  const utl::TimeStamp startTime = currentTime - utl::TimeInterval(0.5*timeToAverage);
96  const utl::TimeStamp stopTime = currentTime + utl::TimeInterval(numberOfQueriesToBuffer * timeToAverage);
97 
98  const utl::UTCDateTime currentDateTime(currentTime);
99  const string mySQLTime = currentDateTime.GetInMySQLFormat();
100 
101  std::cout << "buffering DB for site " << site << " at time " << currentDateTime
102  << " buffer size is " << timeToAverage / utl::second << "seconds with " << numberOfQueriesToBuffer
103  << " queries" << std::endl;
104 
105  if (site == "CRS") {
106  //std::cout << "query to CRS Moni DB" << std::endl;
107  query << "select AVG(UNIX_TIMESTAMP(TimeStamp)), AVG(Temperature) from Weather where TimeStamp between \""
108  << utl::UTCDateTime(startTime).GetInMySQLFormat() << "\" and \""
109  // FLOOR is not SQLite compatible, better use ROUND(XXX - 0.5)
110  << utl::UTCDateTime(stopTime).GetInMySQLFormat() << "\" group by ROUND(UNIX_TIMESTAMP(TimeStamp)/"
111  << timeToAverage / utl::second << " -0.5) order by TimeStamp asc";
112  std::cout << query.str() << std::endl;
113  } else {
114  ostringstream error_msg;
115  error_msg << "Site " << site
116  << " is not implemented. The only current available site is \"CRS\"";
117  ERROR(error_msg);
118  throw utl::NonExistentComponentException(error_msg.str());
119  //query << "select AVG(UNIX_TIMESTAMP(Time)), AVG(Temperature) from Weather where WeatherStation == "
120  // << site << " and TimeStamp between " << utl::UTCDateTime(startTime).GetInMySQLFormat()
121  // << " and " << utl::UTCDateTime(stopTime).GetInMySQLFormat() << " group by FLOOR(TimeStamp/"
122  // << timeToAverage / utl::second << ") order by TimeStamp asc";
123  }
124 
125  if (Query(query.str(), QueryInfoMessage("monitoring", "temperature")) == eNotFound) {
126  std::cout << "error in DB Query" << std::endl;
127  return false;
128  }
129 
130  utl::LeapSeconds leapSeconds;
131 
132  vector<string> sqlResult;
133 
134  std::vector<std::pair<unsigned long, double> > temp_vector;
135  while (FetchRow(sqlResult, false) == eFound) {
136  unsigned long gpsSeconds = 0;
137  leapSeconds.ConvertUnixToGPS(long(boost::lexical_cast<double>(sqlResult[0])), gpsSeconds);
138  const double temperature = boost::lexical_cast<double>(sqlResult[1]);
139  //std::cout << "filling temperature buffer utc: " << sqlResult[0] << " gps: " << gpsSeconds << " " << temperature << std::endl;
140  std::pair<unsigned long, double> temp_pair(gpsSeconds, temperature);
141  temp_vector.push_back(temp_pair);
142  }
143  fTemperatureBuffer[site] = temp_vector;
144  fTemperatureBufferInterval[site] = std::make_pair(startTime.GetGPSSecond(), stopTime.GetGPSSecond());
145 
146  return true;
147 }
148 
149 }
constexpr double second
Definition: AugerUnits.h:145
#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.
Base class for exceptions trying to access non-existing components.
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
#define REGISTER_R_MANAGER(_name_, _Type_)
static const double precision
const double second
Definition: GalacticUnits.h:32
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
std::string GetInXMLFormat() const
Definition: UTCDateTime.cc:94
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
Manager to access monitoring data.
void ConvertUnixToGPS(const time_t unixSecond, unsigned long &gpsSecond) const
Definition: LeapSeconds.cc:25

, generated on Tue Sep 26 2023.