source: trunk/Mars/mjobs/MSequenceSQL.cc@ 9844

Last change on this file since 9844 was 9195, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 11.2 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 <stdlib.h> // atof (Ubuntu 8.10)
70
71#include <TSQLRow.h>
72#include <TSQLResult.h>
73
74#include "MLogManip.h"
75
76#include "MSQLMagic.h"
77
78ClassImp(MSequenceSQL);
79
80using namespace std;
81
82// --------------------------------------------------------------------------
83//
84// get the list of runs according to the query. Add the runs to run-list
85// according to the type. Stop adding runs if the given number of events
86// is exceeded.
87//
88// return kFALSE in case of error or if no events are in the files.
89//
90Bool_t MSequenceSQL::GetRuns(MSQLMagic &serv, TString query, RunType_t type, UInt_t nevts)
91{
92 TSQLResult *res = serv.Query(query);
93 if (!res)
94 return kFALSE;
95
96 UInt_t cnt=0;
97 UInt_t evts=0;
98
99 TSQLRow *row=0;
100 while ((row = res->Next()) && evts<nevts)
101 {
102 AddFile(atoi((*row)[0]), atoi((*row)[1]), type);
103 evts += atoi((*row)[2]);
104 cnt++;
105 }
106
107 delete res;
108
109 if (cnt==0)
110 {
111 *fLog << err << "ERROR - No " << type << " belonging to this sequence found." << endl;
112 return kFALSE;
113 }
114
115 return kTRUE;
116}
117
118// --------------------------------------------------------------------------
119//
120// Get start and stop time as requested and return stop time if start
121// time is invalid. Return a null string in case of an error or no valid time.
122//
123TString MSequenceSQL::GetTimeFromDatabase(MSQLMagic &serv, const TString &query)
124{
125 TSQLResult *res = serv.Query(query);
126 if (!res)
127 return "";
128
129 // FIXME: Check for the right number of results?
130
131 TSQLRow *row=res->Next();
132
133 const TString start = (*row)[0] ? (*row)[0] : "";
134 const TString stop = (*row)[1] ? (*row)[1] : "";
135
136 delete res;
137
138 if (!start.IsNull())
139 return start;
140
141 *fLog << warn << "WARNING - Requesting start time of first calibration run failed." << endl;
142
143 if (!stop.IsNull())
144 return stop;
145
146 *fLog << err << "ERROR - Neither start nor stop time of first calibration could be requested." << endl;
147 return "";
148}
149
150// --------------------------------------------------------------------------
151//
152// Convert the result into the MSequence data members
153//
154Bool_t MSequenceSQL::GetFromDatabase(MSQLMagic &serv, TSQLRow &data)
155{
156 // Convert the keys from the sequence table to strings
157 TString str[6];
158 str[0] = serv.QueryNameOfKey("Project", data[1]);
159 str[1] = serv.QueryNameOfKey("Source", data[2]);
160 str[2] = serv.QueryNameOfKey("L1TriggerTable", data[3]);
161 str[3] = serv.QueryNameOfKey("L2TriggerTable", data[4]);
162 str[4] = serv.QueryNameOfKey("HvSettings", data[5]);
163 str[5] = serv.QueryNameOfKey("LightConditions", data[6]);
164
165 // check that all strings are valid
166 if (str[0].IsNull() || str[1].IsNull() || str[2].IsNull() || str[3].IsNull() || str[4].IsNull() || str[5].IsNull())
167 return kFALSE;
168
169 // Setup the time and night
170 MTime time;
171 time.SetSqlDateTime(data[7]);
172 MTime night = time.GetDateOfSunrise();
173
174 SetNight(night.GetStringFmt("%Y-%m-%d"));
175
176 // set the other values
177 fStart = time;
178 fLastRun = atoi(data[0]);
179 fNumEvents = atoi(data[8]);
180 fTelescope = atoi(data[11]);
181 fProject = str[0];
182 fSource = str[1];
183 fTriggerTable = str[2]+":"+str[3];
184 fHvSettings = str[4];
185 fLightCondition = GetLightCondition(str[5]);
186
187 // FIXME: ZdMin (str[9]) ZdMax(str[10]) --> Comment
188 // FIXME: fMonteCarlo
189 // FIXME: fComment?
190
191 // Now prepare queries to request the runs from the database
192 const TString where(Form(" FROM RunData WHERE"
193 " fTelescopeNumber=%d AND fSequenceFirst=%d AND"
194 " fExcludedFDAKEY=1 AND fRunTypeKEY%%s",
195 fTelescope, fSequence));
196
197 const TString query1(Form("SELECT fRunNumber, fFileNumber, fNumEvents %s", where.Data()));
198 const TString query2(Form("SELECT fRunStart, fRunStop %s", where.Data()));
199
200 const TString queryA(Form(query1.Data(), " BETWEEN 2 AND 4 ORDER BY fRunNumber*1000+fFileNumber"));
201 const TString queryC(Form(query1.Data(), "=4 ORDER BY fRunNumber*1000+fFileNumber"));
202 const TString queryD(Form(query1.Data(), "=2 ORDER BY fRunNumber*1000+fFileNumber"));
203 const TString queryT(Form(query2.Data(), "=4 ORDER BY fRunNumber*1000+fFileNumber LIMIT 1"));
204
205 // Try to get a valid time for the first calibration run
206 const TString timec = GetTimeFromDatabase(serv, queryT);
207 if (timec.IsNull())
208 return kFALSE;
209
210 // Query to get pedestal runs sorted in the order by distance to the cal run
211 const TString query4(Form("=3 ORDER BY ABS(TIME_TO_SEC(TIMEDIFF(fRunStop,'%s'))) ASC", timec.Data()));
212 const TString queryP(Form(query1.Data(), query4.Data()));
213
214 // get and setup runs
215 if (!GetRuns(serv, queryA, kAll))
216 return kFALSE;
217 if (!GetRuns(serv, queryC, kCal))
218 return kFALSE;
219 if (!GetRuns(serv, queryP, kPed, 1000))
220 return kFALSE;
221 if (!GetRuns(serv, queryD, kDat))
222 return kFALSE;
223
224 return kTRUE;
225}
226
227// --------------------------------------------------------------------------
228//
229// This is a wrapper to get rid of the deletion of res in case of error.
230// It also checks that exactly one sequence has been found and all
231// requested column were returned.
232//
233Bool_t MSequenceSQL::GetFromDatabase(MSQLMagic &serv, TSQLResult &res)
234{
235 if (res.GetRowCount()==0)
236 {
237 *fLog << err << "ERROR - Requested Sequence not found in database." << endl;
238 return kFALSE;
239 }
240
241 if (res.GetRowCount()>1)
242 {
243 *fLog << err << "ERROR - Database request returned morethan one sequence." << endl;
244 return kFALSE;
245 }
246
247 if (res.GetFieldCount()!=12)
248 {
249 *fLog << err << "ERROR - Database request returned unexpected number of rows." << endl;
250 return kFALSE;
251 }
252
253 TSQLRow *row = res.Next();
254
255 return row ? GetFromDatabase(serv, *row) : kFALSE;
256}
257
258// --------------------------------------------------------------------------
259//
260// Set the contents of a sequence from the database.
261// The sequence number is given as argument.
262//
263// Example 1:
264// // Define the database url
265// MSQLMagic serv("mysql://user:password@url/Database");
266// MSequenceSQL s;
267// s.GetFromDatabase(serv, 100002);
268// if (s.IsValid())
269// s.Print();
270//
271// Example 2:
272// // Define the database in the resource file
273// MSQLMagic serv("sql.rc");
274// MSequenceSQL s;
275// s.GetFromDatabase(serv, 100002);
276// if (s.IsValid())
277// s.Print();
278//
279// In case of error the Sequence is set invalid and kFALSE is returned,
280// kTrue in case of success.
281//
282Bool_t MSequenceSQL::GetFromDatabase(MSQLMagic &serv, UInt_t sequno, Int_t tel)
283{
284 // Check if we are connected to the sql server
285 if (!serv.IsConnected())
286 {
287 *fLog << err << "ERROR - No connection to database in GetSeqFromDatabase." << endl;
288 return kFALSE;
289 }
290
291 /*
292 // check if any telescope number is valid
293 if (tel<0 && fTelescope==0)
294 {
295 *fLog << err << "ERROR - No telescope number given in GetSeqFromDatabase." << endl;
296 return kFALSE;
297 }
298 */
299
300 // check if any sequence number is valid
301 if (sequno==(UInt_t)-1 && fSequence==(UInt_t)-1)
302 {
303 *fLog << err << "ERROR - No sequence number given in GetSeqFromDatabase." << endl;
304 return kFALSE;
305 }
306
307 // set "filename" and sequence number
308 fFileName = serv.GetName();
309 if (tel>=0)
310 fTelescope = tel;
311 if (sequno!=(UInt_t)-1)
312 fSequence = sequno;
313
314 // get sequence information from database
315 TString query("SELECT fSequenceLast, fProjectKEY, fSourceKEY,"
316 " fL1TriggerTableKEY, fL2TriggerTableKEY, fHvSettingsKEY, "
317 " fLightConditionsKEY, fRunStart, fNumEvents, "
318 " fZenithDistanceMin, fZenithDistanceMax, fTelescopeNumber "
319 " FROM Sequences WHERE ");
320 query += Form("fSequenceFirst=%d", fSequence);
321
322 if (tel>0)
323 query += Form(" AND fTelescopeNumber=%d", fTelescope);
324
325 // Request information from database
326 TSQLResult *res = serv.Query(query);
327 if (!res)
328 return kFALSE;
329
330 const Bool_t rc = GetFromDatabase(serv, *res);
331 delete res;
332
333 // invalidate sequence if retrieval failed
334 if (!rc)
335 {
336 fTelescope = 0;
337 fSequence = (UInt_t)-1;
338 }
339
340 // return result
341 return rc;
342}
343
344// --------------------------------------------------------------------------
345//
346// Set the contents of a sequence from the database.
347// The sequence number is given as argument.
348//
349// Example 1:
350// // Define the database url
351// MSequenceSQL s;
352// s.GetFromDatabase("mysql://user:password@url/Database", 100002);
353// if (s.IsValid())
354// s.Print();
355//
356// Example 2:
357// // Define the database in the resource file
358// MSequenceSQL s;
359// s.GetFromDatabase("sql.rc", 100002);
360// if (s.IsValid())
361// s.Print();
362//
363// In case of error the Sequence is set invalid and kFALSE is returned,
364// kTrue in case of success.
365//
366Bool_t MSequenceSQL::GetFromDatabase(const char *rc, UInt_t sequno, Int_t tel)
367{
368 MSQLMagic serv(rc);
369 return GetFromDatabase(serv, sequno, tel);
370}
Note: See TracBrowser for help on using the repository browser.