source: trunk/MagicSoft/Mars/mjobs/MSequence.cc@ 8977

Last change on this file since 8977 was 8969, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 34.0 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, 8/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2004-2008
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MSequence
28//
29// This class describes a sequence. For sequences see:
30// http://db.astro.uni-wuerzburg.de
31//
32// A sequence is a collection of runs which should be used together.
33// Any run can be contained only once.
34//
35// Here is an example how a file describing a sequence could look like.
36//
37// Reading the file is based on TEnv. For more details see also
38// the class reference of TEnv.
39//
40// ===========================================================================
41//
42// sequence.txt
43// ------------
44//
45// # Sequence number (identifier) - necessary if the path
46// # contains the sequence number, e.g. image files
47// Sequence: 31015
48//
49// # Observation Period (not needed)
50// Period: 18
51//
52// # Date of sunrise of the observation night - necessary if the path
53// # contains the date, e.g. raw data
54// Night: 2004-06-24
55//
56// # Start time of the sequence (first data run, not needed)
57// Start: 2004-06-24 03:12:42
58//
59// # Run number of last data run in sequence (not needed)
60// LastRun: 31032
61//
62// # Project name of data-runs of sequence (not needed)
63// Project: 3EG2033+41
64//
65// # Source name of all runs of sequence (not needed)
66// Source: 3EG2033+41
67//
68// # Trigger table of data-runs of sequence (not needed)
69// TriggerTable: L1_4NN:L2_DEFAULT
70//
71// # HV Setting table of data-runs of sequence (not needed)
72// HvSettings: HVSettings_FF36q
73//
74// # Total number of data-events in sequence (not needed)
75// NumEvents: 250914
76//
77// # Whether this is MC data or not (necessary in case of MCs if
78// # default paths should be used)
79// MonteCarlo: Yes
80//
81// # List of all runs of this sequence (not needed)
82// Runs: 31015:31017 31018 31019.0 31019.3 31019.5:7 31020+ 31021::3
83//
84// # List of all calibration runs of this sequence (necessary if accessed)
85// CalRuns: 31015 31016 31017
86// # List of pedestal runs belonging to the calibration runs of this sequence (necessary if accessed)
87// PedRuns: 31018
88// # List of all data runs belonging to this sequence (necessary)
89// DatRuns: 31019.0 31019.3 31019:5:7 31020+ 31021::3
90//
91// Run00031020: :3 7:9 15
92//
93// # Just for fun ;-) (not needed, but helpful)
94// Comment: This is a template for a sequence file
95//
96// ===========================================================================
97//
98// Runs are devided into file since run 1000000. These Run-/Filenumbers
99// are given by a dot. X.Y means Run X, File Y.
100//
101// In the Runs, CalRuns, PedRuns and DatRuns tag you can use
102// several abbreviationa:
103//
104// 31015:31017 means 31015.0 31016.0 31017.0
105// 31018 means 31018.0
106// 31019.3 means 31019.3
107// 31019.5:7 means 31019.5 31019.6 31019.7
108// 31020+ means file list for run 21020 given below
109// 31021::3 means 31021.0 31021.1 31021.2 31021.3
110//
111// For the run-list defined above (note the number must have 8 digits,
112// for example 'Run00031020') you can also use abbreviations:
113//
114// :3 means 0 1 2 3
115// 7:9 means 7 8 9
116//
117// ===========================================================================
118//
119// For special cases you can also setup a sequence directly from a macro,
120// for example:
121//
122// MDirIter pediter, datiter, caliter;
123//
124// MSequence seq;
125// seq.SetNight("2004-07-06");
126// seq.AddRun(31751, 'P');
127// seq.AddRun(31752, 'C');
128// seq.AddRuns(31753, 31764, 'D');
129// seq.SetupPedRuns(pediter);
130// seq.SetupCalRuns(caliter);
131// seq.SetupDatRuns(datiter);
132//
133// or
134//
135// MDirIter iter;
136//
137// MSequence seq;
138// seq.SetNight("2004-07-06");
139// seq.AddFiles(31753, 0, 120);
140// seq.SetupRuns(iter);
141// seq.SetupPedRuns(iter, "/mypath", "[DPC]");
142//
143// ===========================================================================
144//
145// Class Version 2:
146// + fMonteCarlo
147//
148// Class Version 3:
149// + fComment
150//
151// Class Version 4:
152// + fExclRuns
153//
154// Class Version 5:
155// + fRunsSub
156// + fDatRunsSub
157// + fPedRunsSub
158// + fCalRunsSub
159// + fExclRunsSub
160//
161/////////////////////////////////////////////////////////////////////////////
162#include "MSequence.h"
163
164#include <stdlib.h>
165
166#include <TEnv.h>
167#include <TPRegexp.h>
168#include <TSystem.h> // TSystem::ExpandPath
169
170#include "MLog.h"
171#include "MLogManip.h"
172
173#include "MEnv.h"
174#include "MJob.h"
175#include "MAstro.h"
176#include "MString.h"
177#include "MDirIter.h"
178
179ClassImp(MSequence);
180
181using namespace std;
182
183// --------------------------------------------------------------------------
184//
185// This adds an run/file entry to the data/sub arrays. If it is already
186// contained a waring is printed.
187//
188void MSequence::AddEntry(Int_t run, Int_t file, TArrayI &data, TArrayI &sub) const
189{
190 const Int_t n = data.GetSize();
191
192 // skip already existing entries
193 if (IsContained(data, sub, run, file))
194 {
195 *fLog << warn << "WARNING - File " << run << "." << file << " already in list... skipped." << endl;
196 return;
197 }
198
199 if (run<1000000 && file>0)
200 *fLog << warn << "WARNING - Run number " << run << "<" << "1,000,000 but file " << file << ">0..." << endl;
201
202 // set new entry
203 data.Set(n+1);
204 sub.Set(n+1);
205
206 data[n] = run;
207 sub[n] = file;
208}
209
210// --------------------------------------------------------------------------
211//
212// Evaluate a token in thr Run string. Add the coresponding run/files
213// with AddEntry
214//
215void MSequence::EvalEntry(const TEnv *env, const TString &prefix, const TString &num, TArrayI &data, TArrayI &sub) const
216{
217 // Split entry into run and file
218 const Int_t run = num.Atoi();
219
220 // Syntax error forbidden by construction
221 const Ssiz_t p1 = num.First('.');
222 const Ssiz_t p2 = num.Last(':');
223
224 // ---------------------------------------------------------------
225
226 const Int_t n1 = atoi(num.Data()+p1+1);
227 const Int_t n2 = atoi(num.Data()+p2+1);
228
229 // ---------------------------------------------------------------
230 // p1>=0 && p2<0 (. but no :) run.n1 run.file1
231 if (p1>=0 && p2<0)
232 {
233 AddEntry(run, n1, data, sub);
234 return;
235 }
236
237 // ---------------------------------------------------------------
238 // p1>=0 && p2>=0 (. and :) run:n1:n2 run.file1-run.file2
239 if (p1>=0 && p2>=0)
240 {
241 if (n2<n1)
242 {
243 *fLog << warn << "WARNING - Invalid range '" << num << "'... ignored." << endl;
244 return;
245 }
246
247 for (int i=n1; i<=n2; i++)
248 AddEntry(run, i, data, sub);
249 return;
250 }
251
252 // ---------------------------------------------------------------
253 // p1<0 && p2>=0 (no . but :) n1:n2 run1-run2
254 if (p1<0 && p2>=0)
255 {
256 if (n2<run)
257 {
258 *fLog << warn << "WARNING - Invalid range in '" << num << "'... ignored." << endl;
259 return;
260 }
261
262 for (int i=run; i<=n2; i++)
263 AddEntry(i, 0, data, sub);
264 return;
265 }
266
267 // ---------------------------------------------------------------
268 // p0<0 and p1<0 (no . and no :) run run
269
270 if (!num.EndsWith("+"))
271 {
272 AddEntry(run, 0, data, sub);
273 return;
274 }
275
276 if (!env)
277 return;
278
279 TPRegexp regexp("([0-9]*:[0-9]+|[0-9]+(:[0-9]*)?)( +|$)");
280
281 TString files = GetEnvValue2(*env, prefix, Form("Run%08d", run), "");
282 if (files.IsNull())
283 {
284 AddEntry(run, 0, data, sub);
285 return;
286 }
287
288 while (!files.IsNull())
289 {
290 const TString num = files(regexp);
291 if (num.IsNull())
292 {
293 *fLog << warn << "WARNING - File in run " << run << " is NaN (not a number): '" << files << "'" << endl;
294 break;
295 }
296
297 const Ssiz_t p1 = num.First(':');
298 if (p1>=0)
299 {
300 const Int_t n1 = atoi(num.Data());
301 const Int_t n2 = atoi(num.Data()+p1+1);
302
303 if (n2<n1)
304 {
305 *fLog << warn << "WARNING - Invalid range in '" << num << "'... ignored." << endl;
306 return;
307 }
308
309 // FIXME: n2==0 || n2<n1
310 for (int i=n1; i<=n2; i++)
311 AddEntry(run, i, data, sub);
312 }
313 else
314 {
315 const Int_t file = atoi(num.Data());
316 AddEntry(run, file, data, sub);
317 }
318
319 files.Remove(0, files.First(num)+num.Length());
320 }
321}
322
323// --------------------------------------------------------------------------
324//
325// Interprete the TString and add the run/files to the arrays.
326// Run/files which are twice in the list are only added once. In this case
327// a warning is emitted.
328//
329void MSequence::Split(TString &runs, TArrayI &data, TArrayI &sub, const TEnv *env, const TString prefix) const
330{
331 TPRegexp regexp("^[0-9]+([+]|(:|[.]([0-9]*:)?)[0-9]+)?( +|$)");
332
333 data.Set(0);
334 sub.Set(0);
335
336 runs.ReplaceAll("\t", " ");
337 runs = runs.Strip(TString::kBoth);
338
339 while (!runs.IsNull())
340 {
341 const TString num = runs(regexp);
342 if (num.IsNull())
343 {
344 *fLog << warn << "WARNING - Run syntax error: '" << runs << "'" << endl;
345 break;
346 }
347
348 EvalEntry(env, prefix, num.Strip(TString::kTrailing), data, sub);
349
350 runs.Remove(0, runs.First(num)+num.Length());
351 }
352
353 SortArrays(data, sub);
354}
355
356// --------------------------------------------------------------------------
357//
358// Get the String from the TEnv file prefixed by prefix-name.
359// Intepret the string using Split which adds the run/files to the arrays.
360//
361void MSequence::Split(const TEnv &env, const TString &prefix, const char *name, TArrayI &data, TArrayI &sub) const
362{
363 TString str = GetEnvValue2(env, prefix, name, "");
364 Split(str, data, sub, &env, prefix);
365}
366
367// --------------------------------------------------------------------------
368//
369// Compile path from the given path name and expand it. If it IsNull()
370// the path is compiled as standard path from tha datacenter). The
371// returned path will end with a "/".
372//
373TString MSequence::GetPathName(TString d, FileType_t type) const
374{
375 // Setup path
376 if (d.IsNull())
377 {
378 d = GetStandardPath();
379 switch (type)
380 {
381 case kRawDat: // rawdata
382 case kRawPed:
383 case kRawCal:
384 case kRawAll:
385 case kRootDat: // mcdata
386 case kRootPed:
387 case kRootCal:
388 case kRootAll:
389 d += "rawfiles/";
390 d += fNight.GetStringFmt("%Y/%m/%d");
391 break;
392 case kCalibrated:
393 d += Form("callisto/%04d/%08d", fSequence/10000, fSequence);
394 break;
395 case kImages:
396 d += Form("star/%04d/%08d", fSequence/10000, fSequence);
397 break;
398 }
399 }
400 else
401 gSystem->ExpandPathName(d);
402
403 if (!d.EndsWith("/"))
404 d += '/';
405
406 return d;
407}
408
409// --------------------------------------------------------------------------
410//
411// Return the expression describing the file-name for the file defined
412// by i-th entry of the the given arrays. The file type identifier is
413// defined by type. The source name is replaced by a wildcard and
414// the extension is defined by the type as well.
415//
416TString MSequence::GetFileName(UInt_t i, const TArrayI &arr, const TArrayI &sub, FileType_t type) const
417{
418 const char *id="_";
419 switch (type)
420 {
421 case kRawDat:
422 case kRootDat:
423 id = "D";
424 break;
425 case kRawPed:
426 case kRootPed:
427 id = "P";
428 break;
429 case kRawCal:
430 case kRootCal:
431 id = "C";
432 break;
433 case kRawAll:
434 case kRootAll:
435 id = "[PCD]";
436 break;
437 case kCalibrated:
438 id = "Y";
439 break;
440 case kImages:
441 id = "I";
442 break;
443 }
444
445 // ------------- Create file name --------------
446 TString n = fNight.GetStringFmt("%Y%m%d_");
447
448 if (arr[i]>999999)
449 n += "M1_";
450
451 // R. DeLosReyes and T. Bretz
452 // Changes to read the DAQ numbering format. Changes takes place
453 // between runs 35487 and 00035488 (2004_08_30)
454 n += Form(arr[i]>35487 || fMonteCarlo ? "%08d" : "%05d", arr[i]);
455
456 if (arr[i]>999999 && sub.GetSize()>0)
457 n += Form(".%05d", sub[i]);
458
459 n += "_";
460 n += id;
461 n += "_*";
462
463 if (arr[i]<1000000)
464 n += "_E";
465
466 switch (type)
467 {
468 case kRawDat:
469 case kRawPed:
470 case kRawCal:
471 case kRawAll:
472 n += ".raw.?g?z?";
473 break;
474 default:
475 n += ".root";
476 }
477
478 return n;
479}
480
481// --------------------------------------------------------------------------
482//
483// Add the entries from the arrays to the MDirIter
484//
485UInt_t MSequence::SetupRuns(MDirIter &iter, const TArrayI &arr, const TArrayI &sub, FileType_t type, const char *path) const
486{
487 TString d(path);
488 if (d.IsNull())
489 d = fDataPath;
490
491 const Bool_t def = d.IsNull();
492
493 d = GetPathName(d, type);
494
495 // For this particular case we assume that the files are added one by
496 // one without wildcards.
497 const Int_t n0 = iter.GetNumEntries();
498
499 Int_t excluded = 0;
500 for (int i=0; i<arr.GetSize(); i++)
501 {
502 if (IsExcluded(arr[i], sub[i]))
503 {
504 excluded++;
505 continue;
506 }
507
508 const TString n = GetFileName(i, arr, sub, type);
509
510 // Check existance and accessibility of file
511 MDirIter file(d, n, 0);
512 TString name = file();
513 gSystem->ExpandPathName(name);
514 if (gSystem->AccessPathName(name, kFileExists))
515 {
516 *fLog << err;
517 *fLog << "ERROR - File " << d << n << " not accessible!" << endl;
518 return 0;
519 }
520 if (!file().IsNull())
521 {
522 *fLog << err;
523 *fLog << "ERROR - Searching for file " << d << n << " gave more than one result!" << endl;
524 return 0;
525 }
526
527 // Add Path/File to TIter
528 iter.AddDirectory(d, n, 0);
529 }
530
531 // n0: The previous contents of the iter
532 // n1: The number of files which have been added to the iter
533 // n2: The number of files which should have been added from the array
534 const Int_t n1 = iter.GetNumEntries()-n0;
535 const Int_t n2 = arr.GetSize()-excluded;
536 if (n1==0)
537 {
538 *fLog << err;
539 *fLog << "ERROR - No input files for sequence #" << GetSequence() << endl;
540 *fLog << " read from " << GetName() << endl;
541 *fLog << " found in" << (def?" default-path ":" ") << d << endl;
542 return 0;
543 }
544
545 if (n1==n2)
546 return n1;
547
548 *fLog << err;
549 *fLog << "ERROR - " << n1 << " input files for sequence #" << GetSequence() << " found in" << endl;
550 *fLog << " " << (def?" default-path ":" ") << d << endl;
551 *fLog << " but " << n2 << " files were defined in sequence file" << endl;
552 *fLog << " " << GetName() << endl;
553 if (fLog->GetDebugLevel()<=4)
554 return 0;
555
556 *fLog << inf << "Files which are searched for this sequence:" << endl;
557 iter.Print();
558 return 0;
559}
560
561// --------------------------------------------------------------------------
562//
563// Get LightCondition from resource file and convert it to LIghtCondition_t
564//
565MSequence::LightCondition_t MSequence::ReadLightCondition(TEnv &env, const char *prefix) const
566{
567 TString str = GetEnvValue2(env, prefix, "LightConditions", "n/a");
568 if (!str.CompareTo("n/a", TString::kIgnoreCase))
569 return kNA;
570 if (!str.CompareTo("No_Moon", TString::kIgnoreCase))
571 return kNoMoon;
572 if (!str.CompareTo("NoMoon", TString::kIgnoreCase))
573 return kNoMoon;
574 if (!str.CompareTo("Twilight", TString::kIgnoreCase))
575 return kTwilight;
576 if (!str.CompareTo("Moon", TString::kIgnoreCase))
577 return kMoon;
578 if (!str.CompareTo("Day", TString::kIgnoreCase))
579 return kDay;
580
581 gLog << warn;
582 gLog << "WARNING - in " << fFileName << ":" << endl;
583 gLog << " LightCondition-tag is '" << str << "' but must be n/a, no_moon, twilight, moon or day." << endl;
584 return kNA;
585}
586
587// --------------------------------------------------------------------------
588//
589// Read the file fname as setup file for the sequence.
590//
591MSequence::MSequence(const char *fname, const char *path, UInt_t seq)
592{
593 fName = fname;
594 fTitle = path;
595
596 fFileName = fname;
597 fDataPath = path;
598
599 gSystem->ExpandPathName(fName);
600 gSystem->ExpandPathName(fTitle);
601
602 const Bool_t rc1 = gSystem->AccessPathName(fName, kFileExists);
603 const Bool_t rc2 = !fTitle.IsNull() && gSystem->AccessPathName(fTitle, kFileExists);
604
605 if (rc1)
606 gLog << err << "ERROR - Sequence file '" << fName << "' doesn't exist." << endl;
607 if (rc2)
608 gLog << err << "ERROR - Directory '" << fTitle << "' doesn't exist." << endl;
609
610 MEnv env(fName);
611
612 fSequence = (UInt_t)env.GetValue("Sequence", (Int_t)seq);
613 if (rc1 || rc2)
614 fSequence = (UInt_t)-1;
615
616 const TString prefix = Form("Sequence%08d", fSequence);
617
618 fLastRun = GetEnvValue2(env, prefix, "LastRun", -1);
619 fNumEvents = GetEnvValue2(env, prefix, "NumEvents", -1);
620 fPeriod = GetEnvValue2(env, prefix, "Period", -1);
621
622 fLightCondition = ReadLightCondition(env, prefix);
623
624 TString str;
625 str = GetEnvValue2(env, prefix, "Start", "");
626 fStart.SetSqlDateTime(str);
627 str = GetEnvValue2(env, prefix, "Night", "");
628 str += " 00:00:00";
629 fNight.SetSqlDateTime(str);
630
631 fProject = GetEnvValue2(env, prefix, "Project", "");
632 fSource = GetEnvValue2(env, prefix, "Source", "");
633 fTriggerTable = GetEnvValue2(env, prefix, "TriggerTable", "");
634 fHvSettings = GetEnvValue2(env, prefix, "HvSettings", "");
635 fMonteCarlo = GetEnvValue2(env, prefix, "MonteCarlo", kFALSE);
636 fComment = GetEnvValue2(env, prefix, "Comment", "");
637
638 Split(env, prefix, "Runs", fRuns, fRunsSub);
639 Split(env, prefix, "CalRuns", fCalRuns, fCalRunsSub);
640 Split(env, prefix, "PedRuns", fPedRuns, fPedRunsSub);
641 Split(env, prefix, "DatRuns", fDatRuns, fDatRunsSub);
642 Split(env, prefix, "Exclude", fExclRuns, fExclRunsSub);
643
644 // Dummies:
645 env.Touch("ZdMin");
646 env.Touch("ZdMax");
647 env.Touch("L1TriggerTable");
648 env.Touch("L2TriggerTable");
649
650 if (seq<0 && env.GetNumUntouched()>0)
651 {
652 gLog << warn << "WARNING - At least one resource in the sequence-file has not been touched!" << endl;
653 env.PrintUntouched();
654 }
655}
656
657//---------------------------------------------------------------------------
658//
659// Make sure that the name used for writing doesn't contain a full path
660//
661const char *MSequence::GetName() const
662{
663 const char *pos = strrchr(GetRcName(), '/');
664 return pos>0 ? pos+1 : GetRcName();
665}
666
667// --------------------------------------------------------------------------
668//
669// Find a sequence of continous numbers in f starting at pos (looking
670// only at n entries). The output is converted into sequences
671// of X (single r) and X:Y (a sequence between x and r). The function
672// returnes when position pos+n is reached
673//
674TString MSequence::GetNumSequence(Int_t pos, Int_t n, const TArrayI &f) const
675{
676 TString str;
677
678 Int_t p=pos;
679 while (p<pos+n)
680 {
681 str += Form(" %d", f[p]);
682
683 if (p==pos+n-1)
684 break;
685
686 int i=0;
687 while (++i<n)
688 if (f[p+i]-f[p]!=i)
689 break;
690
691 if (i>1)
692 str += Form(":%d", f[p+i-1]);
693
694 p += i;
695 }
696
697 return str;
698}
699
700// --------------------------------------------------------------------------
701//
702// Search for a sequence of continous numbers in r with f==0 starting at p.
703// A new starting p is returned. The output is converted into sequences
704// of X (single r) and X:Y (a sequence between x and r). The function
705// returnes with the next f!=0.
706//
707TString MSequence::GetNumSequence(Int_t &p, const TArrayI &r, const TArrayI &f) const
708{
709 TString str;
710
711 while (p<r.GetSize() && f[p]==0)
712 {
713 // serach for the first entry which doesn't fit
714 // or has a file number which is != 0
715 int i=0;
716 while (p+ ++i<r.GetSize())
717 if (r[p+i]-r[p]!=i || f[p+i]!=0)
718 break;
719
720 // None found (i-1==0)
721 if (i-1==0)
722 return str;
723
724 // The last run found in the sequence (e.g. 5.0) is followed
725 // by an identical run number but file != 0 (e.g. 5.1)
726 if (p+i<f.GetSize() && r[p+i]==r[p] && f[p+i]!=0)
727 i--;
728
729 // Now we have to check again whether found no valid entry
730 if (i-1==0)
731 return str;
732
733 str += Form(" %d", r[p]);
734 // p now points to the last entry which fits and
735 // has a file number == 0
736 p += i-1;
737 // Only one found (i-1==1)
738 // More tahn one found (i-1>1)
739 str += i-1==1 ? " " : ":";
740 str += Form("%d", r[p]);
741
742 // One step forward
743 p++;
744 }
745
746 return str;
747}
748
749// --------------------------------------------------------------------------
750//
751// Print the runs in a compressed wa. Returns the RunXXXXXXX string
752// simplyfing the file setup
753//
754TString MSequence::PrintRuns(const char *pre, const char *name, const TArrayI &r, const TArrayI &f) const
755{
756 if (r.GetSize()==0)
757 return "";
758
759 gLog << pre << name;
760 if (f.GetSize()==0)
761 const_cast<TArrayI&>(f).Set(r.GetSize());
762
763#ifdef DEBUG
764 for (int i=0; i<r.GetSize(); i++)
765 gLog << " " << r[i] << "." << f[i];
766 gLog << endl;
767 return "";
768#endif
769
770 TString str;
771
772 Int_t pos = 0;
773 while (pos<r.GetSize())
774 {
775 TString rc = GetNumSequence(pos, r, f);
776 if (!rc.IsNull())
777 {
778 gLog << rc;
779 continue;
780 }
781
782 Int_t n = GetSubArray(pos, r.GetSize(), (Int_t*)r.GetArray());
783 // end reached
784 if (n<0)
785 break;
786
787 // This can happen if it is the last entry
788 if (n==1)
789 {
790 gLog << " " << r[pos];
791 if (f[pos]>0)
792 gLog << "." << f[pos];
793 }
794 else
795 {
796 // Check for sequence
797 Bool_t isseq = kTRUE;
798 for (int i=1; i<n; i++)
799 if (f[pos+i]-f[pos]!=i)
800 isseq=kFALSE;
801
802 if (isseq)
803 {
804 gLog << " " << r[pos] << ".";
805 if (f[pos]!=0)
806 gLog << f[pos];
807 gLog << ":" << f[pos+n-1];
808 }
809 else
810 {
811 gLog << " " << r[pos] << "+";
812
813 str += '\n';
814 str += pre;
815 str += Form("Run%08d:", r[pos]);
816 str += GetNumSequence(pos, n, f);
817 }
818 }
819
820 pos += n;
821 }
822
823 gLog << endl;
824
825 return str;
826}
827
828// --------------------------------------------------------------------------
829//
830// Print the numbers in the classical way (one run after the other)
831//
832void MSequence::PrintRunsClassic(const char *pre, const char *name, const TArrayI &r) const
833{
834 gLog << pre << name;
835 for (int i=0; i<r.GetSize(); i++)
836 gLog << " " << r[i];
837 gLog << endl;
838}
839
840// --------------------------------------------------------------------------
841//
842// Print the contents of the sequence
843//
844void MSequence::Print(Option_t *o) const
845{
846 const TString opt(o);
847
848 const TString pre = opt.Contains("prefixed") ? Form("Sequence%08d.", fSequence) : "";
849
850 gLog << all;
851 if (!IsValid())
852 {
853 gLog << pre << "Sequence: " << fFileName << " <invalid>" << endl;
854 return;
855 }
856 gLog << "# Path: " << GetRcName() << endl;
857 gLog << "# Name: " << GetName() << endl;
858 gLog << endl;
859 if (pre.IsNull())
860 gLog << "Sequence: " << fSequence << endl;
861 if (fMonteCarlo)
862 gLog << pre << "MonteCarlo: Yes" << endl;
863 gLog << pre <<"Period: " << fPeriod << endl;
864 gLog << pre << "Night: " << fNight << endl << endl;
865 gLog << pre << "LightCondition: ";
866 switch (fLightCondition)
867 {
868 case kNA: gLog << "n/a" << endl; break;
869 case kNoMoon: gLog << "NoMoon" << endl; break;
870 case kTwilight: gLog << "Twilight" << endl; break;
871 case kMoon: gLog << "Moon" << endl; break;
872 case kDay: gLog << "Day" << endl; break;
873 }
874 gLog << pre << "Start: " << fStart << endl;
875 gLog << pre << "LastRun: " << fLastRun << endl;
876 gLog << pre << "NumEvents: " << fNumEvents << endl;
877 gLog << pre << "Project: " << fProject << endl;
878 gLog << pre << "Source: " << fSource << endl;
879 gLog << pre << "TriggerTable: " << fTriggerTable << endl;
880 gLog << pre << "HvSettings: " << fHvSettings << endl << endl;
881
882 TString str;
883 if (!HasSubRuns() && opt.Contains("classic"))
884 {
885 PrintRunsClassic(pre, "Runs: ", fRuns);
886 PrintRunsClassic(pre, "CalRuns: ", fCalRuns);
887 PrintRunsClassic(pre, "PedRuns: ", fPedRuns);
888 PrintRunsClassic(pre, "DataRuns: ", fDatRuns);
889 PrintRunsClassic(pre, "Exclude: ", fExclRuns);
890 }
891 else
892 {
893 str += PrintRuns(pre, "Runs: ", fRuns, fRunsSub);
894 str += PrintRuns(pre, "CalRuns: ", fCalRuns, fCalRunsSub);
895 str += PrintRuns(pre, "PedRuns: ", fPedRuns, fPedRunsSub);
896 str += PrintRuns(pre, "DataRuns: ", fDatRuns, fDatRunsSub);
897 str += PrintRuns(pre, "Exclude: ", fExclRuns, fExclRunsSub);
898 }
899
900 if (!fDataPath.IsNull())
901 gLog << endl << pre << "DataPath: " << fDataPath << endl;
902
903 if (!str.IsNull())
904 gLog << str << endl;
905
906 gLog << endl << pre << "Comment: " << fComment << endl;
907}
908
909// --------------------------------------------------------------------------
910//
911// Add all ped runs from the sequence to MDirIter.
912// If path==0 fDataPath is used instead. If it is also empty
913// the standard path of the data-center is assumed.
914// If you have the runs locally use path="."
915// Using raw=kTRUE you get correspodning raw-files setup.
916// Return the number of files added.
917//
918// Runs which are in fExlRuns are ignored.
919//
920UInt_t MSequence::SetupPedRuns(MDirIter &iter, const char *path, Bool_t raw) const
921{
922 return SetupRuns(iter, fPedRuns, fPedRunsSub, raw?kRawPed:kRootPed, path);
923}
924
925// --------------------------------------------------------------------------
926//
927// Add all data runs from the sequence to MDirIter.
928// If path==0 fDataPath is used instead. If it is also empty
929// the standard path of the data-center is assumed.
930// If you have the runs locally use path="."
931// Using raw=kTRUE you get correspodning raw-files setup.
932// Return the number of files added.
933//
934// Runs which are in fExlRuns are ignored.
935//
936UInt_t MSequence::SetupDatRuns(MDirIter &iter, const char *path, Bool_t raw) const
937{
938 return SetupRuns(iter, fDatRuns, fDatRunsSub, raw?kRawDat:kRootDat, path);
939}
940
941// --------------------------------------------------------------------------
942//
943// Add all runs from the sequence to MDirIter.
944// If path==0 fDataPath is used instead. If it is also empty
945// the standard path of the data-center is assumed.
946// If you have the runs locally use path="."
947// Using raw=kTRUE you get correspodning raw-files setup.
948// Return the number of files added.
949//
950// Runs which are in fExlRuns are ignored.
951//
952UInt_t MSequence::SetupAllRuns(MDirIter &iter, const char *path, Bool_t raw) const
953{
954 return SetupRuns(iter, fRuns, fRunsSub, raw?kRawAll:kRootAll, path);
955}
956
957// --------------------------------------------------------------------------
958//
959// Add all calibration runs from the sequence to MDirIter.
960// If path==0 fDataPath is used instead. If it is also empty
961// the standard path of the data-center is assumed.
962// If you have the runs locally use path="."
963// Using raw=kTRUE you get correspodning raw-files setup.
964// Return the number of files added.
965//
966// Runs which are in fExlRuns are ignored.
967//
968UInt_t MSequence::SetupCalRuns(MDirIter &iter, const char *path, Bool_t raw) const
969{
970 return SetupRuns(iter, fCalRuns, fCalRunsSub, raw?kRawCal:kRootCal, path);
971}
972
973// --------------------------------------------------------------------------
974//
975// Add all data runs from the sequence to MDirIter.
976// If path==0 fDataPath is used instead. If it is also empty
977// the standard path of the data-center is assumed.
978// If you have the runs locally use path="."
979// Using raw=kTRUE you get correspodning raw-files setup.
980// Return the number of files added.
981//
982// Runs which are in fExlRuns are ignored.
983//
984UInt_t MSequence::SetupDatRuns(MDirIter &iter, FileType_t type, const char *path) const
985{
986 return SetupRuns(iter, fDatRuns, fDatRunsSub, type, path);
987}
988
989// --------------------------------------------------------------------------
990//
991// check if the run/file is contained in the arrays.
992//
993Bool_t MSequence::IsContained(const TArrayI &arr, const TArrayI &sub, UInt_t run, UInt_t file) const
994{
995 // Backward compatibilty
996 if (sub.GetSize()==0)
997 {
998 for (int i=0; i<arr.GetSize(); i++)
999 if (run==(UInt_t)arr[i])
1000 return kTRUE;
1001 }
1002 else
1003 {
1004 for (int i=0; i<arr.GetSize(); i++)
1005 if (run==(UInt_t)arr[i] && file==(UInt_t)sub[i])
1006 return kTRUE;
1007 }
1008 return kFALSE;
1009}
1010
1011// --------------------------------------------------------------------------
1012//
1013// Add a file (run/file) to the arrays defined by type (P, C, D, X)
1014//
1015void MSequence::AddFile(UInt_t run, UInt_t file, char type)
1016{
1017 TArrayI *r=0, *f=0;
1018 switch (type)
1019 {
1020 case 'P':
1021 r = &fPedRuns;
1022 f = &fPedRunsSub;
1023 break;
1024 case 'D':
1025 r = &fDatRuns;
1026 f = &fDatRunsSub;
1027 break;
1028 case 'C':
1029 r = &fCalRuns;
1030 f = &fCalRunsSub;
1031 break;
1032 default:
1033 r = &fRuns;
1034 f = &fRunsSub;
1035 break;
1036 }
1037
1038 AddEntry(run, file, *r, *f);
1039
1040 MJob::SortArray(fExclRuns);
1041}
1042
1043// --------------------------------------------------------------------------
1044//
1045// Exclude this run (i.e. add it to fExclRuns)
1046//
1047void MSequence::ExcludeFile(UInt_t run, UInt_t file/*, Bool_t force*/)
1048{
1049// if (force && IsExcluded(run, file))
1050// return;
1051
1052 AddEntry(run, file, fExclRuns, fExclRunsSub);
1053
1054 MJob::SortArray(fExclRuns);
1055}
1056
1057// --------------------------------------------------------------------------
1058//
1059// Exclude all runs which are found in the list, e.g. "100 102 105"
1060//
1061void MSequence::ExcludeRuns(TString runs)
1062{
1063 // FIXME: Decode stream!!!
1064
1065 TArrayI data, sub;
1066 Split(runs, data, sub);
1067 for (int i=0; i<data.GetSize(); i++)
1068 ExcludeFile(data[i], sub[i]);
1069}
1070
1071// --------------------------------------------------------------------------
1072//
1073// Return the excluded runs (to be more precise:the excluded files)
1074// in a string
1075//
1076const TString MSequence::GetExcludedRuns() const
1077{
1078 TString rc;
1079 for (int i=0; i<fExclRuns.GetSize(); i++)
1080 {
1081 rc += fExclRuns[i];
1082 if (fExclRunsSub.GetSize()>0)
1083 {
1084 rc += ".";
1085 rc += fExclRunsSub[i];
1086 }
1087 rc += " ";
1088 }
1089 return rc(0, rc.Length()-1);
1090}
1091
1092// --------------------------------------------------------------------------
1093//
1094// If you want to change or set the night manually.
1095// The Format is
1096// SetNight("yyyy-mm-dd");
1097//
1098void MSequence::SetNight(const char *txt)
1099{
1100 TString night(txt);
1101 night += " 00:00:00";
1102 fNight.SetSqlDateTime(night);
1103
1104 fPeriod = MAstro::GetMagicPeriod(fNight.GetMjd());
1105}
1106
1107// --------------------------------------------------------------------------
1108//
1109// If the sequence name seq is just a digit it is inflated to a full
1110// path following the datacenter standard.
1111//
1112// Returns if file accessible or not.
1113//
1114Bool_t MSequence::InflatePath(TString &seq, Bool_t ismc)
1115{
1116 if (seq.IsDigit())
1117 {
1118 const Int_t numseq = seq.Atoi();
1119 seq = "/magic/";
1120 if (ismc)
1121 seq += "montecarlo/";
1122 seq += Form("sequences/%04d/sequence%08d.txt", numseq/10000, numseq);
1123 gLog << inf << "Inflated sequence file: " << seq << endl;
1124 }
1125
1126 if (!gSystem->AccessPathName(seq, kFileExists))
1127 return kTRUE;
1128
1129 gLog << err << "Sorry, sequence file '" << seq << "' doesn't exist." << endl;
1130 return kFALSE;
1131}
1132
1133// --------------------------------------------------------------------------
1134//
1135// Search starting at position p in array arr and return the number
1136// of elemets which are identical to the starting entry (the starting entry
1137// is also counted)
1138//
1139Int_t MSequence::GetSubArray(Int_t p, Int_t n, Int_t *arr)
1140{
1141 Int_t *ptr0 = arr+p;
1142
1143 Int_t *ptr = ptr0;
1144 Int_t *end = arr+n;
1145
1146 while (ptr<end && *ptr==*ptr0)
1147 ptr++;
1148
1149 return ptr-ptr0;
1150}
1151
1152// --------------------------------------------------------------------------
1153//
1154// Sort the array arr2 starting at position p for following entries
1155// for which arr1 is equal. If not at least two entries are found which
1156// can be sorted return -1.
1157//
1158// The absolute index of the next entry in arr1 is returned.
1159//
1160Int_t MSequence::SortArraySub(Int_t p, Int_t n, Int_t *arr1, Int_t *arr2)
1161{
1162 Int_t *ptr2 = arr2+p;
1163
1164 Int_t cnt = GetSubArray(p, n, arr1);
1165 if (cnt==0)
1166 return -1;
1167
1168 TArrayI srt(cnt, ptr2);
1169 MJob::SortArray(srt);
1170
1171 memcpy(ptr2, srt.GetArray(), srt.GetSize()*sizeof(Int_t));
1172
1173 return p+srt.GetSize();
1174}
1175
1176void MSequence::SortArrays(TArrayI &arr1, TArrayI &arr2)
1177{
1178 if (arr1.GetSize()!=arr2.GetSize())
1179 return;
1180
1181 TArrayI idx(arr1.GetSize());
1182
1183 TArrayI srt1(arr1);
1184 TArrayI srt2(arr2);
1185
1186 TMath::Sort(arr1.GetSize(), srt1.GetArray(), idx.GetArray(), kFALSE);
1187
1188 for (int i=0; i<arr1.GetSize(); i++)
1189 {
1190 arr1[i] = srt1[idx[i]];
1191 arr2[i] = srt2[idx[i]];
1192 }
1193
1194 Int_t p = 0;
1195 while (p>=0)
1196 p = SortArraySub(p, arr1.GetSize(), arr1.GetArray(), arr2.GetArray());
1197}
Note: See TracBrowser for help on using the repository browser.