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

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