source: trunk/MagicSoft/Mars/datacenter/macros/buildsequenceentries.C@ 7961

Last change on this file since 7961 was 7813, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 30.4 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, 08/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Author(s): Daniela Dorner, 08/2004 <mailto:dorner@astro.uni-wuerzburg.de>
20!
21! Copyright: MAGIC Software Development, 2000-2006
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// buildsequenceentries.C
29// ======================
30//
31// to group the runs of one night into sequences, this marco:
32// - reads the runinformation of one night from the database
33// - group the runs into sets of following runs with the same conditions
34// - groups the runs in this sets to sequences such that each run belongs
35// to the nearest (in time) calibration run
36// - check if the runs with the same runtype have the same calibration script
37// and the same trigger tables
38// if sequence is okay:
39// - check if in the range of the runnumbers of this sequence other sequences
40// exist in the database
41// if there are no sequences, insert the new sequence, else:
42// - delete overlaping sequences
43// if there's only one sequence in the same runnumber range:
44// - check if the new and the old sequence are identical
45// if they are identical, do nothing, if not, delete the old sequence and
46// insert the new one
47//
48// remark: deleting sequences includes the following steps:
49// - delete entries from the tables Sequences, SequenceProcessStatus,
50// Calibration and Star
51// - updating the sequence number (fSequenceFirst) in the table RunData
52// - remove the Sequence File, the calibrated data and the image files from
53// the disk
54//
55// the macro can be executed either for all nights or for one single night
56// .x buildsequenceentries.C+( "datapath", "sequpath", Bool_t dummy=kTRUE)
57// .x buildsequenceentries.C+( "night", "datapath", "sequpath")
58//
59// the Bool_t dummy:
60// kTRUE: dummy-mode, i.e. nothing is inserted into the database, but the
61// commands, that would be executed are returned
62// kFALSE: the information is inserted into the database and the files of
63// removed sequences is deleted
64// be careful with this option - for tests use always kTRUE
65//
66// TString datapath, TString sequpath:
67// datapath: path, where the processed data is stored in the datacenter
68// sequpath: path, where the sequence files are stored in the datacenter
69// the datapath (standard: /magic/data/) and the sequencepath (standard:
70// /magic/sequences) have to be given, that the sequence file, the
71// calibrated data and the star files can be removed, when an old sequence
72// has to be removed from the database
73//
74// If nothing failes 1 is returned. In the case of an error 2 and if
75// there's no connection to the database 0 is returned.
76// This is needed for the scripts that execute the macro.
77//
78/////////////////////////////////////////////////////////////////////////////
79#include <iostream>
80#include <iomanip>
81#include <fstream>
82
83#include <MSQLServer.h>
84#include <TSQLRow.h>
85#include <TSQLResult.h>
86
87#include <TEnv.h>
88#include <TMath.h>
89#include <TExMap.h>
90#include <TArrayI.h>
91#include <TRegexp.h>
92#include <TSystem.h>
93#include <TObjString.h>
94#include <TObjArray.h>
95
96#include <MTime.h>
97#include <MDirIter.h>
98
99using namespace std;
100
101int debug = 0;
102
103Bool_t DeleteSequence(MSQLServer &serv, TString datapath, TString sequpath, Int_t sequ, Bool_t dummy)
104{
105 //queries to delete information from the database
106 TString query1(Form("DELETE FROM Calibration WHERE fSequenceFirst=%d", sequ));
107 TString query2(Form("DELETE FROM Star WHERE fSequenceFirst=%d", sequ));
108 TString query3(Form("DELETE FROM SequenceProcessStatus WHERE fSequenceFirst=%d", sequ));
109 TString query4(Form("UPDATE RunData SET fSequenceFirst=0 WHERE fSequenceFirst=%d", sequ));
110 TString query5(Form("DELETE FROM Sequences WHERE fSequenceFirst=%d AND fManuallyChangedKEY=1", sequ));
111
112 //commands to delete files from the disk
113 TString fname(Form("%s/%04d/sequence%08d.txt", sequpath.Data(),sequ/10000, sequ));
114 TString command(Form("rm -r %s/callisto/%04d/%08d/", datapath.Data(), sequ/10000, sequ));
115 TString command2(Form("rm -r %s/star/%04d/%08d/", datapath.Data(), sequ/10000, sequ));
116
117 if (dummy)
118 {
119 cout << "not using dummy=kTRUE the following commands would be executed: " << endl;
120 cout << "queries: " << endl;
121 cout << query1 << endl;
122 cout << query2 << endl;
123 cout << query3 << endl;
124 cout << query4 << endl;
125 cout << query5 << endl;
126 cout << "removing files:" << endl;
127 cout << "unlink " << fname << endl;
128 cout << command << endl;
129 cout << command2 << endl;
130 return kTRUE;
131 }
132
133 TSQLResult *res = serv.Query(query1);
134 if (!res)
135 return kFALSE;
136 delete res;
137
138 res = serv.Query(query2);
139 if (!res)
140 return kFALSE;
141 delete res;
142
143 res = serv.Query(query3);
144 if (!res)
145 return kFALSE;
146 delete res;
147
148 res = serv.Query(query4);
149 if (!res)
150 return kFALSE;
151 delete res;
152
153 res = serv.Query(query5);
154 if (!res)
155 return kFALSE;
156 delete res;
157
158 gSystem->Unlink(fname);
159
160 gSystem->Exec(command);
161 gSystem->Exec(command2);
162
163 return kTRUE;
164}
165
166Int_t DoCheck(TSQLResult &res)
167{
168 TArrayI data(5);
169 Int_t n = 0;
170
171 TSQLRow *row=0;
172 while ((row=res.Next()))
173 {
174 n++;
175
176 if (data[0]==0)
177 {
178 for (int i=0; i<data.GetSize(); i++)
179 data[i] = atoi((*row)[i]);
180 continue;
181 }
182
183 for (int i=1; i<data.GetSize(); i++)
184 {
185 if (data[i] != atoi((*row)[i]))
186 return i+1;
187 }
188 }
189 return n==0 ? 0 : -1;
190}
191
192
193//check values, that can be different for different runtypes
194Bool_t CheckRuns(MSQLServer &serv, Int_t from, Int_t to, Int_t type)
195{
196 TString query("SELECT fRunNumber, fL1TriggerTableKEY, fL2TriggerTableKEY,"
197 " fCalibrationScriptKEY, fProjectKEY FROM RunData");
198 query += Form(" WHERE fRunTypeKEY=%d AND fExcludedFDAKEY=1 AND "
199 " (fRunNumber BETWEEN %d AND %d)"
200 " ORDER BY fRunNumber", type, from, to);
201
202 TSQLResult *res = serv.Query(query);
203 if (!res)
204 return kFALSE;
205
206 Int_t rc = DoCheck(*res);
207 delete res;
208
209 switch (rc)
210 {
211 case 0: cout << "ERROR - No runs found for check!" << endl; break;
212 case 1: cout << "ERROR - fRunNumber doesn't match!" << endl; break;
213 case 2: cout << "ERROR - fL1TriggerTableKEY doesn't match!" << endl; break;
214 case 3: cout << "ERROR - fL2TriggerTableKEY doesn't match!" << endl; break;
215 case 4: cout << "ERROR - fCalibrationScriptKEY doesn't match!" << endl; break;
216 case 5: cout << "ERROR - fProjectKEY doesn't match!" << endl; break;
217 }
218
219 return rc<0;
220}
221
222Int_t CheckSequence(MSQLServer &serv, TString datapath, TString sequpath, Int_t from, Int_t to, Bool_t dummy)
223{
224 Int_t rc=0;
225 //rc=0 means sequence not found -> insert
226 //rc=1 means deleting sequence(s) worked -> insert
227 //rc=2 means sequence is still the same -> insert not neccessary
228 //if deleting sequence doesn't work -> return -1
229
230
231 //getting # of sequence (in sequDB) between from and to
232 TString query("SELECT fSequenceFirst FROM Sequences WHERE (fSequenceFirst ");
233 query += Form("BETWEEN %d and %d OR fSequenceLast BETWEEN %d and %d) AND "
234 "fManuallyChangedKEY=1 ", from, to, from, to);
235
236 TSQLResult *res = serv.Query(query);
237 if (!res)
238 return -1;
239
240 TArrayI sequences;
241 Int_t numsequ=0;
242
243 TSQLRow *row=0;
244 while ((row=res->Next()))
245 {
246 numsequ++;
247 sequences.Set(numsequ);
248 sequences.AddAt(atoi((*row)[0]), numsequ-1);
249 }
250 delete res;
251
252 //if there's no sequence in the table Sequences -> check other tables
253 //if there's one sequence -> check if the sequence is identical
254 //if there are more sequences -> delete them
255 switch (numsequ)
256 {
257 case 0:
258 //FIXME: like this the check is of no use, but when doing it
259 // without the check for manuallychanged, all manually
260 // changed sequences would be deleted
261 cout << " + found no sequence in Sequ-DB -> check other tables" << endl;
262 cout << " deleting every sequence found in Calibration, Star or" << endl;
263 cout << " SequenceProcessStatus between " << from << " and " << to << endl;
264
265 //calibration table
266 query=Form("SELECT Calibration.fSequenceFirst FROM Calibration "
267 " LEFT JOIN Sequences ON Calibration.fSequenceFirst=Sequences.fSequenceFirst "
268 " WHERE fManuallyChangedKEY=1 AND Calibration.fSequenceFirst BETWEEN %d and %d",
269 from, to);
270 res = serv.Query(query);
271 if (!res)
272 return -1;
273 row=0;
274 while ((row=res->Next()))
275 {
276 if (!DeleteSequence(serv, datapath, sequpath, atoi((*row)[0]), dummy))
277 return -1;
278 rc=1;
279 }
280 delete res;
281
282 //Star table
283 query=Form("SELECT Star.fSequenceFirst FROM Star "
284 " LEFT JOIN Sequences ON Star.fSequenceFirst=Sequences.fSequenceFirst "
285 " WHERE fManuallyChangedKEY=1 AND Star.fSequenceFirst BETWEEN %d and %d",
286 from, to);
287 res = serv.Query(query);
288 if (!res)
289 return -1;
290 row=0;
291 while ((row=res->Next()))
292 {
293 if (!DeleteSequence(serv, datapath, sequpath, atoi((*row)[0]), dummy))
294 return -1;
295 rc=1;
296 }
297 delete res;
298
299 //SequenceProcessStatus table
300 query=Form("SELECT SequenceProcessStatus.fSequenceFirst FROM SequenceProcessStatus "
301 " LEFT JOIN Sequences ON SequenceProcessStatus.fSequenceFirst=Sequences.fSequenceFirst "
302 " WHERE fManuallyChangedKEY=1 AND SequenceProcessStatus.fSequenceFirst BETWEEN %d and %d",
303 from, to);
304 res = serv.Query(query);
305 if (!res)
306 return -1;
307 row=0;
308 while ((row=res->Next()))
309 {
310 if (!DeleteSequence(serv, datapath, sequpath, atoi((*row)[0]), dummy))
311 return -1;
312 rc=1;
313 }
314 delete res;
315 break;
316
317 case 1:
318 cout << " + found one sequence: " << sequences.At(0) << " -> check sequence." << endl;
319 if (sequences.At(0)!=from)
320 {
321 if (!DeleteSequence(serv, datapath, sequpath, sequences.At(0), dummy))
322 return -1;
323 rc=1;
324 }
325 else
326 {
327 cout << " * sequence is the same -> checking the runs." << endl;
328
329 //getting olf runs
330 query=Form("SELECT fRunNumber FROM RunData WHERE fSequenceFirst=%d ", from);
331 res = serv.Query(query);
332 if (!res)
333 return -1;
334
335 TArrayI oldruns;
336 Int_t count=0;
337 row=0;
338 while ((row=res->Next()))
339 {
340 count++;
341 oldruns.Set(count);
342 oldruns.AddAt(atoi((*row)[0]), count-1);
343 }
344 delete res;
345
346 //getting new runs
347 query=Form("SELECT fRunNumber FROM RunData WHERE fRunNumber BETWEEN %d and %d AND fExcludedFDAKEY=1", from, to);
348 res = serv.Query(query);
349 if (!res)
350 return -1;
351 TArrayI newruns;
352 count=0;
353 row=0;
354 while ((row=res->Next()))
355 {
356 count++;
357 newruns.Set(count);
358 newruns.AddAt(atoi((*row)[0]), count-1);
359 }
360 delete res;
361
362 //comparing old and new runs (first the # of runs, if it is the same, also the single runnumbers
363 if (oldruns.GetSize()!=newruns.GetSize())
364 {
365// cout << " number of runs (" << oldruns.GetSize() << " - " << newruns.GetSize()
366// << ") is not the same -> deleting sequence " << sequences.At(0) << endl;
367 if (!DeleteSequence(serv, datapath, sequpath, sequences.At(0), dummy))
368 return -1;
369 rc=1;
370 }
371 else
372 {
373 cout << " · number of runs is the same -> checking the single runnumbers." << endl;
374
375 for (Int_t i=0;i<newruns.GetSize();i++)
376 {
377// cout << "i: " << i << " - new: " << newruns.At(i) << " - old: " << oldruns.At(i) << endl;
378 if (newruns.At(i)==oldruns.At(i))
379 continue;
380
381 cout << " · " << i << ". run is not the same ( " << oldruns.At(i) << " -- " << newruns.At(i)
382 << ") -> deleting sequence " << sequences.At(0) << endl;
383 if (!DeleteSequence(serv, datapath, sequpath, sequences.At(0), dummy))
384 return -1;
385 return 1;
386 }
387 }
388 }
389 return 2;
390
391 default:
392 cout << " - found " << numsequ << " sequences -> deleting them " << endl;
393
394 for (Int_t i=0;i<sequences.GetSize();i++)
395 {
396 cout << " + deleting sequence " << sequences.At(i) << "... <" << i << ">" << endl;
397 if (!DeleteSequence(serv, datapath, sequpath, sequences.At(i), dummy))
398 return -1;
399 rc=1;
400 }
401 }
402
403 return rc;
404}
405
406Bool_t InsertSequence(MSQLServer &serv, Int_t from, Int_t to)
407{
408 cout << " · Inserting sequence " << from << " ... " << endl;
409
410 // ========== Request number of events ==========
411 TString query("SELECT SUM(fNumEvents), "
412 " SUM(if(TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)<0,"
413 " TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)+24*60*60,"
414 " TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart))), ");
415 query += " MIN(fZenithDistance), MAX(fZenithDistance), ";
416 query += " MIN(fAzimuth), MAX(fAzimuth) ";
417 query += Form(" FROM RunData WHERE fRunTypeKEY=2 AND "
418 " (fRunNumber BETWEEN %d AND %d) AND fExcludedFDAKEY=1",
419 from, to);
420
421 TSQLResult *res = serv.Query(query);
422 if (!res)
423 return kFALSE;
424
425 TSQLRow *row = res->Next();
426 if (!row || !(*row)[0])
427 {
428 cout << "ERROR - No result from query: " << query << endl;
429 return kFALSE;
430 }
431
432 TString nevts = (*row)[0];
433 TString secs = (*row)[1];
434 TString zdmin = (*row)[2];
435 TString zdmax = (*row)[3];
436 TString azmin = (*row)[4];
437 TString azmax = (*row)[5];
438
439 delete res;
440
441 // ========== Request start time of sequence ==========
442 query = Form("SELECT fRunStart FROM RunData WHERE fRunNumber=%d AND fExcludedFDAKEY=1", from);
443
444 res = serv.Query(query);
445 if (!res)
446 return kFALSE;
447
448 row = res->Next();
449 if (!row || !(*row)[0])
450 {
451 cout << "ERROR - No result from query: " << query << endl;
452 return kFALSE;
453 }
454
455 TString start((*row)[0]);
456
457 delete res;
458
459 // ========== Request data of sequence ==========
460 query = Form("SELECT fSourceKEY, fProjectKEY, "
461 " fL1TriggerTableKEY, fL2TriggerTableKEY,"
462 " fHvSettingsKEY, fDiscriminatorThresholdTableKEY,"
463 " fTriggerDelayTableKEY, fLightConditionsKEY, "
464 " fTestFlagKEY, fObservationModeKEY "
465 " FROM RunData"
466 " WHERE fRunTypeKEY=2 AND fExcludedFDAKEY=1 AND (fRunNumber BETWEEN %d AND %d)"
467 " LIMIT 1", from, to);
468
469 res = serv.Query(query);
470 if (!res)
471 return kFALSE;
472
473 row = res->Next();
474 if (!row)
475 {
476 cout << "ERROR - No result from query: " << query << endl;
477 return kFALSE;
478 }
479
480 TString query1("INSERT Sequences SET");
481 query1 += Form(" fSequenceFirst=%d, fSequenceLast=%d,", from, to);
482 query1 += Form(" fSourceKEY=%s,", (*row)[0]);
483 query1 += Form(" fProjectKEY=%s,", (*row)[1]);
484 query1 += Form(" fNumEvents=%s,", nevts.Data());
485 query1 += Form(" fRunTime=%s,", secs.Data());
486 query1 += Form(" fRunStart=\"%s\",", start.Data());
487 query1 += Form(" fZenithDistanceMin=%s,", zdmin.Data());
488 query1 += Form(" fZenithDistanceMax=%s,", zdmax.Data());
489 query1 += Form(" fAzimuthMin=%s,", azmin.Data());
490 query1 += Form(" fAzimuthMax=%s,", azmax.Data());
491 query1 += Form(" fL1TriggerTableKEY=%s,", (*row)[2]);
492 query1 += Form(" fL2TriggerTableKEY=%s,", (*row)[3]);
493 query1 += Form(" fHvSettingsKEY=%s,", (*row)[4]);
494 query1 += Form(" fDiscriminatorThresholdTableKEY=%s,", (*row)[5]);
495 query1 += Form(" fTriggerDelayTableKEY=%s,", (*row)[6]);
496 query1 += Form(" fLightConditionsKEY=%s,", (*row)[7]);
497 query1 += Form(" fTestFlagKEY=%s,", (*row)[8]);
498 query1 += Form(" fObservationModeKEY=%s, ", (*row)[9]);
499 query1+="fManuallyChangedKEY=1";
500
501
502 TString query2 = Form("UPDATE RunData SET fSequenceFirst=%d WHERE"
503 " (fRunNumber BETWEEN %d AND %d) AND"
504 " (fRunTypeKEY BETWEEN 2 AND 4) AND"
505 " fSourceKEY=%s AND fHvSettingsKEY=%s AND fExcludedFDAKEY=1",
506 from, from, to, (*row)[0], (*row)[4]);
507
508 TString query3 = Form("INSERT SequenceProcessStatus SET fSequenceFirst=%d ", from);
509
510 delete res;
511
512 /*
513 cout << "q1: " << query1 << endl;
514 cout << "q2: " << query2 << endl;
515 cout << "q3: " << query3 << endl;
516 */
517
518 res = serv.Query(query1);
519 if (!res)
520 {
521 cout << "ERROR - Could not insert Sequence into Sequences." << endl;
522 return kFALSE;
523 }
524 delete res;
525
526 res = serv.Query(query2);
527 if (!res)
528 {
529 cout << "ERROR - Could not update RunData." << endl;
530 return kFALSE;
531 }
532 delete res;
533
534 res = serv.Query(query3);
535 if (!res)
536 {
537 cout << "ERROR - Could not insert Sequence into SequenceProcessStatus." << endl;
538 return kFALSE;
539 }
540 delete res;
541
542 return kTRUE;
543}
544
545//
546// Handling new sequence (checking runs; checking for old sequence; inserting sequence, if everything is okay)
547//
548Bool_t NewSequence(MSQLServer &serv, TString datapath, TString sequpath, Int_t from, Int_t to, TList &sequlist, Bool_t dummy)
549{
550 cout << " - Found Sequence (" << from << ", " << to << ") ... checking runs..." << flush;
551
552 if (!CheckRuns(serv, from, to, 2))
553 {
554 cout << "Warning - Found inconsistency in data-runs (" << from << ", " << to << ")" << endl;
555 //sequence is not built, but kTRUE is returned, to allow
556 //the automatic processing of the other sequences of this day
557 return kTRUE;
558 }
559 if (!CheckRuns(serv, from, to, 3))
560 {
561 cout << "Warning - Found inconsistency in ped-runs (" << from << ", " << to << ")" << endl;
562 //sequence is not built, but kTRUE is returned, to allow
563 //the automatic processing of the other sequences of this day
564 return kTRUE;
565 }
566
567 cout << "ok." << endl;
568
569
570 cout << " + checking sequence..." << endl;
571
572 TObject *sequ;
573 Bool_t rc=kFALSE;
574 switch (CheckSequence(serv, datapath, sequpath, from, to, dummy))
575 {
576 case 0:
577 cout << " · sequence not found -> inserting " << from << flush;
578 if (dummy)
579 {
580 cout << " <dummy> " << endl;
581 return kTRUE;
582 }
583 cout << endl;
584 if ((sequ=sequlist.Remove(sequlist.FindObject(Form("%d", from)))))
585 delete sequ;
586 return InsertSequence(serv, from, to);
587
588 case 1:
589 cout << " · deleting successfully finished -> inserting sequence " << from << flush;
590 if (dummy)
591 {
592 cout << " <dummy> " << endl;
593 return kTRUE;
594 }
595 cout << endl;
596 if ((sequ=sequlist.Remove(sequlist.FindObject(Form("%d", from)))))
597 delete sequ;
598 return InsertSequence(serv, from, to);
599
600 case 2:
601 cout << " · sequence " << from << " is already existing -> inserting not necessary" << endl;
602 if ((sequ=sequlist.Remove(sequlist.FindObject(Form("%d", from)))))
603 delete sequ;
604 return kTRUE;
605
606 case -1:
607 cout << " · deleting went wrong " << endl;
608 return kFALSE;
609 }
610
611
612 return rc;
613}
614
615//
616// Build Sequences in range of runs
617//
618Bool_t Process(MSQLServer &serv, TString datapath, TString sequpath, Int_t from, Int_t to, TList &sequlist, Bool_t dummy)
619{
620
621 TString query(Form("SELECT fRunNumber, fRunTypeKEY, fRunStart, fRunStop"
622 " FROM RunData"
623 " WHERE fRunNumber BETWEEN %d AND %d AND "
624 " fExcludedFDAKEY=1 AND (fRunTypeKEY BETWEEN 2 AND 4)"
625 " ORDER BY fRunNumber", from, to));
626
627 TSQLResult *res = serv.Query(query);
628 if (!res)
629 return kFALSE;
630
631 TExMap map;
632
633 Int_t start=0;
634 Int_t stop=0;
635 Int_t last=0;
636 Int_t first=0;
637
638 MTime lasttime;
639
640 TSQLRow *row=0;
641
642 enum { UNKNOWN, PED=3, CAL=4, DATA=2 };
643 Char_t status = UNKNOWN;
644
645 Int_t nblocks = 0;
646
647 while ((row=res->Next()))
648 {
649 if (!(*row)[1])
650 continue;
651
652 if (start==0)
653 {
654 first = atoi((*row)[0]);
655 if (debug)
656 cout << "First Run: " << first << endl;
657 }
658
659 switch (atoi((*row)[1]))
660 {
661 case CAL: // ---------- CALIBRATION ----------
662 if (status!=CAL)
663 {
664 start = stop = atoi((*row)[0]);
665 if (!(*row)[2])
666 cout << "No time available... skipped." << endl;
667 else
668 {
669 MTime *tm = new MTime;
670 tm->SetSqlDateTime((*row)[2]);
671 map.Add((ULong_t)map.GetSize(), (Long_t)tm, (Long_t)nblocks);
672 }
673 }
674 status = CAL;
675 break;
676 default:
677 if (status==CAL)
678 {
679 MTime *tm = new MTime(lasttime);
680 map.Add((ULong_t)map.GetSize(), (Long_t)tm, (Long_t)nblocks);
681
682 stop = last;
683 nblocks++;
684 if (debug)
685 cout << "Cal Block #" << nblocks << " from " << start << " to " << last << endl;
686 }
687 status = UNKNOWN;
688 break;
689 }
690 last = atoi((*row)[0]);
691 lasttime.SetSqlDateTime((*row)[3]);
692 }
693 if (status==CAL)
694 {
695 stop = last;
696 nblocks++;
697 if (debug)
698 cout << "Cal Block #" << nblocks << " from " << start << " to " << stop << endl;
699 }
700
701 if (debug)
702 cout << "Last Run: " << last << endl;
703 delete res;
704
705 if (debug)
706 cout << "Found " << nblocks << " calibration blocks" << endl;
707
708 res = serv.Query(query);
709 if (!res)
710 return kFALSE;
711
712 Int_t n = -1;
713
714 Bool_t rc = kTRUE;
715
716 start = first;
717 while ((row=res->Next()))
718 {
719 if (!(*row)[1])
720 continue;
721
722 MTime tstart, tstop;
723 tstart.SetSqlDateTime((*row)[2]);
724 tstop.SetSqlDateTime((*row)[3]);
725
726 MTime min;
727 Int_t nmin = -1;
728 Double_t dmin = 1e35;
729
730 Long_t key, val;
731 TExMapIter nmap(&map);
732 while (nmap.Next(key, val))
733 {
734 MTime *t = (MTime*)key;
735
736 if (nmin==-1)
737 {
738 nmin = val;
739 min = *(MTime*)key;
740 dmin = fabs((Double_t)*t-(Double_t)tstart);
741 }
742
743 if (fabs((Double_t)*t-(Double_t)tstart) < dmin)
744 {
745 nmin = val;
746 dmin = fabs((Double_t)*t-(Double_t)tstart);
747 min = *t;
748 }
749 if (fabs((Double_t)*t-(Double_t)tstop) < dmin)
750 {
751 nmin = val;
752 dmin = fabs((Double_t)*t-(Double_t)tstop);
753 min = *t;
754 }
755 }
756
757 if (n!=nmin)
758 {
759 if (n!=-1)
760 {
761 if (!NewSequence(serv, datapath, sequpath, start, last, sequlist, dummy))
762 {
763 rc = kFALSE;
764 //continue;
765 }
766 }
767 n = nmin;
768 start = atoi((*row)[0]);
769 }
770 last = atoi((*row)[0]);
771 }
772
773 delete res;
774
775 if (n!=-1 && start!=last)
776 {
777 if (!NewSequence(serv, datapath, sequpath, start, last, sequlist, dummy))
778 rc = kFALSE;
779 }
780
781 if (debug)
782 cout << endl;
783
784 return rc;
785}
786
787void buildblocks(TSQLResult *res, TExMap &blocks)
788{
789 //build blocks of runs, which have the same values
790 //for each block the first and the last run are stored in a TExMap
791 //the values are checked with the help of an array of TStrings
792 TString keys[7];
793
794 Long_t runstart = -1;
795 Long_t runstop = -1;
796
797 // "Result set closed" means "Result set empty"
798
799 // Loop over runs
800 TSQLRow *row=0;
801 while ((row=res->Next()))
802 {
803 // Check whether all keys for this run fit
804 for (Int_t i=1; i<8; i++)
805 {
806 // Do not check project key for this runs
807 // (this condition is never true for the first run)
808 if (i==2 && runstart>20100 && runstop<45100)
809 continue;
810
811 // Check whether key has changed for this run
812 // (this condition is never true for the first run)
813 if (keys[i-1] == (*row)[i])
814 continue;
815
816 // Found one block with unique keys, fill values into TExMap
817 // (except if this is the first run processed)
818 if (runstart>0)
819 blocks.Add((ULong_t)blocks.GetSize(), runstart, runstop);
820
821 // This is the runnumber of the first run in the new block
822 runstart=atoi((*row)[0]);
823
824 // These are the keys corresponding to the first run in the new block
825 for (int i=1; i<8; i++)
826 keys[i-1] = (*row)[i];
827
828 break;
829 }
830
831 // This is the new runnumber of the last run in this block
832 runstop=atoi((*row)[0]);
833 }
834
835 if (runstart!=runstop)
836 {
837 //fill values into TExMap (last value)
838 blocks.Add((ULong_t)blocks.GetSize(), runstart, runstop);
839 }
840}
841
842//
843// Build Sequences for the night given by TString day
844//
845int buildsequenceentries(TString day, TString datapath, TString sequpath, Bool_t dummy=kTRUE)
846{
847 TEnv env("sql.rc");
848
849 MSQLServer serv(env);
850 if (!serv.IsConnected())
851 {
852 cout << "ERROR - Connection to database failed." << endl;
853 return 0;
854 }
855
856 cout << "buildsequences" << endl;
857 cout << "--------------" << endl;
858 cout << endl;
859 cout << "Connected to " << serv.GetName() << endl;
860 cout << "Night of sunrise at: " << day << endl;
861 cout << endl;
862
863 day += " 13:00:00";
864 const TString cond(Form("(fRunStart>ADDDATE(\"%s\", INTERVAL -1 DAY) AND fRunStart<\"%s\")",
865 day.Data(), day.Data()));
866
867 TString elts = "fSourceKEY";
868 TString eltp2 = "fProjectKEY";
869
870 //get all values from the database, that are relevant for building sequences
871 TString query("SELECT fRunNumber, ");
872 query += elts;
873 query += ", ";
874 query += eltp2;
875 query += Form(", fHvSettingsKEY, fLightConditionsKEY, fDiscriminatorThresholdTableKEY, "
876 "fTriggerDelayTableKEY, fObservationModeKEY FROM RunData "
877 "WHERE %s AND fExcludedFDAKEY=1 order by fRunNumber", cond.Data());
878
879 TSQLResult *res = serv.Query(query);
880 if (!res)
881 return 2;
882
883 TExMap blocks;
884 buildblocks(res, blocks);
885 delete res;
886
887 // ---
888 // Now the blocks containing the same observation conditions
889 // are created...
890 // ---
891
892 //get list of current sequence of this night from the database and store it in sequlist
893 TList sequlist;
894 query=Form("SELECT fSequenceFirst FROM Sequences WHERE fManuallyChangedKEY=1 AND %s order by fSequenceFirst",
895 cond.Data());
896
897 res = serv.Query(query);
898 if (!res)
899 return 2;
900
901 cout << "Old sequences: " << flush;
902 TSQLRow *row=0;
903 while ((row=res->Next()))
904 {
905 const char *str = (*row)[0];
906 cout << str << " " << flush;
907 sequlist.Add(new TObjString(str));
908 }
909 cout << endl;
910
911 delete res;
912
913 Bool_t rc = kTRUE;
914
915 //build sequences in each block of runs
916 Long_t key, val;
917 TExMapIter nblocks(&blocks);
918 while (nblocks.Next(key, val))
919 {
920 const Int_t runstart = (Int_t)key;
921 const Int_t runstop = (Int_t)val;
922
923 cout << endl << "Datablock from " << runstart << " to " << runstop << ":" << endl;
924
925 if (!Process(serv, datapath, sequpath, runstart, runstop, sequlist, dummy))
926 rc = kFALSE;
927
928 }
929
930 //newly build or remaining sequences are removed from sequlist while building sequences
931 //delete sequences that remained in the list
932 //this is necessary if e.g. all runs of one old sequence have been excluded in the meantime
933 TIter Next(&sequlist);
934 TObject *obj = 0;
935 while ((obj=Next()))
936 {
937 cout << " - Sequence " << obj->GetName() << " deleting... " << endl;
938 if (!DeleteSequence(serv, datapath, sequpath, atoi(obj->GetName()), dummy))
939 return 2;
940 }
941
942 return rc ? 1 : 2;
943}
944
945//
946// Build Sequences for all Nights
947//
948int buildsequenceentries(TString datapath, TString sequpath, Bool_t dummy=kTRUE)
949{
950 TEnv env("sql.rc");
951
952 MSQLServer serv(env);
953 if (!serv.IsConnected())
954 {
955 cout << "ERROR - Connection to database failed." << endl;
956 return 0;
957 }
958
959 //get all dates from the database
960 TString query="SELECT fDate FROM SequenceBuildStatus";
961
962 TSQLResult *res = serv.Query(query);
963 if (!res)
964 return 2;
965
966 //execute buildsequenceentries for all dates
967 TString date;
968 TSQLRow *row=0;
969 while ((row=res->Next()))
970 {
971 date=(*row)[0];
972 buildsequenceentries(date, datapath, sequpath, dummy);
973 }
974
975 delete res;
976
977 return 1;
978}
Note: See TracBrowser for help on using the repository browser.