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

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