source: trunk/MagicSoft/Mars/mjobs/MSequenceSQL.cc@ 9061

Last change on this file since 9061 was 9019, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 11.1 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 7/2008 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2004-2008
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MSequenceSQL
28//
29// This is an extension to retrieve a sequence from a database instead
30// of readin it from a file
31//
32// Example 1:
33// MSQLMagic serv("sql.rc");
34// MSequenceSQL s(serv, 100002))
35// if (s.IsValid())
36// s.Print();
37//
38// Example 2:
39// MSequenceSQL s("sql.rc", 100002);
40// if (s.IsValid())
41// s.Print();
42//
43// Example 2:
44// MSequence s = MSequenceSQL("sql.rc", 100002);
45// if (s.IsValid())
46// s.Print();
47//
48// Instead of initializing the constructor directly you can
49// also use the function GetFromDatabase.
50//
51// Instead of a resource file sql.rc you can also give the qualified
52// path to the database:
53//
54// mysql://user:password@url/database
55//
56//
57// A telscope number of -1 means: Take fTelescope as telescope number
58// to request. A telescope number of 0 tries to get the sequence from
59// the db including the telescope number. This will fail if more than
60// one sequence with the same number exist in the db for several
61// telescopes.
62//
63//
64// This tool will work from Period017 (2004_05_17) on...
65//
66/////////////////////////////////////////////////////////////////////////////
67#include "MSequenceSQL.h"
68
69#include <TSQLRow.h>
70#include <TSQLResult.h>
71
72#include "MLogManip.h"
73
74#include "MSQLMagic.h"
75
76ClassImp(MSequenceSQL);
77
78using namespace std;
79
80// --------------------------------------------------------------------------
81//
82// get the list of runs according to the query. Add the runs to run-list
83// according to the type. Stop adding runs if the given number of events
84// is exceeded.
85//
86// return kFALSE in case of error or if no events are in the files.
87//
88Bool_t MSequenceSQL::GetRuns(MSQLMagic &serv, TString query, RunType_t type, UInt_t nevts)
89{
90 TSQLResult *res = serv.Query(query);
91 if (!res)
92 return kFALSE;
93
94 UInt_t cnt=0;
95 UInt_t evts=0;
96
97 TSQLRow *row=0;
98 while ((row = res->Next()) && evts<nevts)
99 {
100 AddFile(atoi((*row)[0]), atoi((*row)[1]), type);
101 evts += atoi((*row)[2]);
102 cnt++;
103 }
104
105 delete res;
106
107 if (cnt==0)
108 {
109 *fLog << err << "ERROR - No " << type << " belonging to this sequence found." << endl;
110 return kFALSE;
111 }
112
113 return kTRUE;
114}
115
116// --------------------------------------------------------------------------
117//
118// Get start and stop time as requested and return stop time if start
119// time is invalid. Return a null string in case of an error or no valid time.
120//
121TString MSequenceSQL::GetTimeFromDatabase(MSQLMagic &serv, const TString &query)
122{
123 TSQLResult *res = serv.Query(query);
124 if (!res)
125 return "";
126
127 // FIXME: Check for the right number of results?
128
129 TSQLRow *row=res->Next();
130
131 const TString start = (*row)[0] ? (*row)[0] : "";
132 const TString stop = (*row)[1] ? (*row)[1] : "";
133
134 delete res;
135
136 if (!start.IsNull())
137 return start;
138
139 *fLog << warn << "WARNING - Requesting start time of first calibration run failed." << endl;
140
141 if (!stop.IsNull())
142 return stop;
143
144 *fLog << err << "ERROR - Neither start nor stop time of first calibration could be requested." << endl;
145 return "";
146}
147
148// --------------------------------------------------------------------------
149//
150// Convert the result into the MSequence data members
151//
152Bool_t MSequenceSQL::GetFromDatabase(MSQLMagic &serv, TSQLRow &data)
153{
154 // Convert the keys from the sequence table to strings
155 TString str[6];
156 str[0] = serv.QueryNameOfKey("Project", data[1]);
157 str[1] = serv.QueryNameOfKey("Source", data[2]);
158 str[2] = serv.QueryNameOfKey("L1TriggerTable", data[3]);
159 str[3] = serv.QueryNameOfKey("L2TriggerTable", data[4]);
160 str[4] = serv.QueryNameOfKey("HvSettings", data[5]);
161 str[5] = serv.QueryNameOfKey("LightConditions", data[6]);
162
163 // check that all strings are valid
164 if (str[0].IsNull() || str[1].IsNull() || str[2].IsNull() || str[3].IsNull() || str[4].IsNull() || str[5].IsNull())
165 return kFALSE;
166
167 // Setup the time and night
168 MTime time;
169 time.SetSqlDateTime(data[7]);
170 MTime night = time.GetDateOfSunrise();
171
172 SetNight(night.GetStringFmt("%Y-%m-%d"));
173
174 // set the other values
175 fStart = time;
176 fLastRun = atoi(data[0]);
177 fNumEvents = atoi(data[8]);
178 fTelescope = atoi(data[11]);
179 fProject = str[0];
180 fSource = str[1];
181 fTriggerTable = str[2]+":"+str[3];
182 fHvSettings = str[4];
183 fLightCondition = GetLightCondition(str[5]);
184
185 // FIXME: ZdMin (str[9]) ZdMax(str[10]) --> Comment
186 // FIXME: fMonteCarlo
187 // FIXME: fComment?
188
189 // Now prepare queries to request the runs from the database
190 const TString where(Form(" FROM RunData WHERE"
191 " fTelescopeNumber=%d AND fSequenceFirst=%d AND"
192 " fExcludedFDAKEY=1 AND fRunTypeKEY%%s",
193 fTelescope, fSequence));
194
195 const TString query1(Form("SELECT fRunNumber, fFileNumber, fNumEvents %s", where.Data()));
196 const TString query2(Form("SELECT fRunStart, fRunStop %s", where.Data()));
197
198 const TString queryA(Form(query1.Data(), " BETWEEN 2 AND 4 ORDER BY fRunNumber*1000+fFileNumber"));
199 const TString queryC(Form(query1.Data(), "=4 ORDER BY fRunNumber*1000+fFileNumber"));
200 const TString queryD(Form(query1.Data(), "=2 ORDER BY fRunNumber*1000+fFileNumber"));
201 const TString queryT(Form(query2.Data(), "=4 ORDER BY fRunNumber*1000+fFileNumber LIMIT 1"));
202
203 // Try to get a valid time for the first calibration run
204 const TString timec = GetTimeFromDatabase(serv, queryT);
205 if (timec.IsNull())
206 return kFALSE;
207
208 // Query to get pedestal runs sorted in the order by distance to the cal run
209 const TString query4(Form("=3 ORDER BY ABS(TIME_TO_SEC(TIMEDIFF(fRunStop,'%s'))) ASC", timec.Data()));
210 const TString queryP(Form(query1.Data(), query4.Data()));
211
212 // get and setup runs
213 if (!GetRuns(serv, queryA, kAll))
214 return kFALSE;
215 if (!GetRuns(serv, queryC, kCal))
216 return kFALSE;
217 if (!GetRuns(serv, queryP, kPed, 1000))
218 return kFALSE;
219 if (!GetRuns(serv, queryD, kDat))
220 return kFALSE;
221
222 return kTRUE;
223}
224
225// --------------------------------------------------------------------------
226//
227// This is a wrapper to get rid of the deletion of res in case of error.
228// It also checks that exactly one sequence has been found and all
229// requested column were returned.
230//
231Bool_t MSequenceSQL::GetFromDatabase(MSQLMagic &serv, TSQLResult &res)
232{
233 if (res.GetRowCount()==0)
234 {
235 *fLog << err << "ERROR - Requested Sequence not found in database." << endl;
236 return kFALSE;
237 }
238
239 if (res.GetRowCount()>1)
240 {
241 *fLog << err << "ERROR - Database request returned morethan one sequence." << endl;
242 return kFALSE;
243 }
244
245 if (res.GetFieldCount()!=12)
246 {
247 *fLog << err << "ERROR - Database request returned unexpected number of rows." << endl;
248 return kFALSE;
249 }
250
251 TSQLRow *row = res.Next();
252
253 return row ? GetFromDatabase(serv, *row) : kFALSE;
254}
255
256// --------------------------------------------------------------------------
257//
258// Set the contents of a sequence from the database.
259// The sequence number is given as argument.
260//
261// Example 1:
262// // Define the database url
263// MSQLMagic serv("mysql://user:password@url/Database");
264// MSequenceSQL s;
265// s.GetFromDatabase(serv, 100002);
266// if (s.IsValid())
267// s.Print();
268//
269// Example 2:
270// // Define the database in the resource file
271// MSQLMagic serv("sql.rc");
272// MSequenceSQL s;
273// s.GetFromDatabase(serv, 100002);
274// if (s.IsValid())
275// s.Print();
276//
277// In case of error the Sequence is set invalid and kFALSE is returned,
278// kTrue in case of success.
279//
280Bool_t MSequenceSQL::GetFromDatabase(MSQLMagic &serv, UInt_t sequno, Int_t tel)
281{
282 // Check if we are connected to the sql server
283 if (!serv.IsConnected())
284 {
285 *fLog << err << "ERROR - No connection to database in GetSeqFromDatabase." << endl;
286 return kFALSE;
287 }
288
289 /*
290 // check if any telescope number is valid
291 if (tel<0 && fTelescope==0)
292 {
293 *fLog << err << "ERROR - No telescope number given in GetSeqFromDatabase." << endl;
294 return kFALSE;
295 }
296 */
297
298 // check if any sequence number is valid
299 if (sequno==(UInt_t)-1 && fSequence==(UInt_t)-1)
300 {
301 *fLog << err << "ERROR - No sequence number given in GetSeqFromDatabase." << endl;
302 return kFALSE;
303 }
304
305 // set "filename" and sequence number
306 fFileName = serv.GetName();
307 if (tel>=0)
308 fTelescope = tel;
309 if (sequno!=(UInt_t)-1)
310 fSequence = sequno;
311
312 // get sequence information from database
313 TString query("SELECT fSequenceLast, fProjectKEY, fSourceKEY,"
314 " fL1TriggerTableKEY, fL2TriggerTableKEY, fHvSettingsKEY, "
315 " fLightConditionsKEY, fRunStart, fNumEvents, "
316 " fZenithDistanceMin, fZenithDistanceMax, fTelescopeNumber "
317 " FROM Sequences WHERE ");
318 query += Form("fSequenceFirst=%d", fSequence);
319
320 if (tel>0)
321 query += Form(" AND fTelescopeNumber=%d", fTelescope);
322
323 // Request information from database
324 TSQLResult *res = serv.Query(query);
325 if (!res)
326 return kFALSE;
327
328 const Bool_t rc = GetFromDatabase(serv, *res);
329 delete res;
330
331 // invalidate sequence if retrieval failed
332 if (!rc)
333 {
334 fTelescope = 0;
335 fSequence = (UInt_t)-1;
336 }
337
338 // return result
339 return rc;
340}
341
342// --------------------------------------------------------------------------
343//
344// Set the contents of a sequence from the database.
345// The sequence number is given as argument.
346//
347// Example 1:
348// // Define the database url
349// MSequenceSQL s;
350// s.GetFromDatabase("mysql://user:password@url/Database", 100002);
351// if (s.IsValid())
352// s.Print();
353//
354// Example 2:
355// // Define the database in the resource file
356// MSequenceSQL s;
357// s.GetFromDatabase("sql.rc", 100002);
358// if (s.IsValid())
359// s.Print();
360//
361// In case of error the Sequence is set invalid and kFALSE is returned,
362// kTrue in case of success.
363//
364Bool_t MSequenceSQL::GetFromDatabase(const char *rc, UInt_t sequno, Int_t tel)
365{
366 MSQLMagic serv(rc);
367 return GetFromDatabase(serv, sequno, tel);
368}
Note: See TracBrowser for help on using the repository browser.