source: trunk/MagicSoft/Mars/mjobs/MDataSet.cc@ 7375

Last change on this file since 7375 was 7358, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 13.3 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, 1/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2004-2005
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MDataSet
28//
29// This class describes a collection of sequences.
30//
31// Such an input file looks like:
32//
33// crab.seq:
34// ---------
35// AnalysisNumber: 1
36//
37// SequencesOn: 35222
38// SequencesOff: 36817
39//
40// Sequence00035222.File: sequences/sequence035222.txt
41// Sequence00036817.File: sequences/sequence036817.txt
42//
43// Sequence00035222.Dir: /data2/wuerzburg/Crab-Analyse/images/035222
44// Sequence00036817.Dir: /data2/wuerzburg/Crab-Analyse/images/036817
45//
46// The analysis number is an artifical number used to name the output
47// files automatically if the names are not overwritten in the corresponding
48// programs.
49//
50// The sequence number are used to concatenate the filenames of the
51// sequences using the file structure used in the datacenter. Each sequence
52// can be added to the on and off data at the same time but only once.
53//
54// If you have different file names you can overwrite the default file names
55// using Sequence%08d.File (make sure you have 8 digits!)
56//
57// In standard coditions (datacenter file system) paths are concatenated
58// by using the information in the sequence files (date, etc). You can
59// overwrite the directories in which the sequence-files (eg I-files) are
60// stored using Sequence%08d.Dir (make sure you have 8 digits!)
61//
62// Resource file entries are case sensitive!
63//
64// IMPORTANT:
65// * Run filenames must begin with a string which allows correct
66// ordering in time, otherwise synchronization might fail.
67// * Sequence filenames should also have names allowing to order them
68// in time, but it is not necessary.
69//
70// MISSING (27/01/04): The default name and paths cannot be used yet, because
71// they have to be defined soon.
72//
73/////////////////////////////////////////////////////////////////////////////
74#include "MDataSet.h"
75
76#include <stdlib.h>
77#include <fstream>
78
79#include <TEnv.h>
80#include <TChain.h>
81#include <TRegexp.h>
82#include <TSystem.h> // TSystem::ExpandPath
83
84#include "MLog.h"
85#include "MLogManip.h"
86
87#include "MRead.h"
88#include "MJob.h"
89#include "MAstro.h"
90#include "MDirIter.h"
91#include "MSequence.h"
92#include "MPointingPos.h"
93
94ClassImp(MDataSet);
95
96using namespace std;
97
98// --------------------------------------------------------------------------
99//
100// Copy the sequence numbers from the TString runs into the TArrayI data
101// Sequences which are twice in the list are only added once. In this case
102// a warning is emitted.
103//
104void MDataSet::Split(TString &runs, TArrayI &data) const
105{
106 const TRegexp regexp("[0-9]+");
107
108 data.Set(0);
109 runs = runs.Strip(TString::kTrailing);
110
111 while (!runs.IsNull())
112 {
113 const TString num = runs(regexp);
114
115 if (num.IsNull())
116 {
117 *fLog << warn << "WARNING - Sequence is NaN (not a number): " << runs << endl;
118 break;
119 }
120
121 const Int_t seq = atoi(num.Data());
122 const Int_t n = data.GetSize();
123
124 // skip already existing entries
125 int i;
126 for (i=0; i<n; i++)
127 if (data[i] == seq)
128 break;
129
130 if (i<n)
131 *fLog << warn << "WARNING - Sequence #" << seq << " already in list... skipped." << endl;
132 else
133 {
134 // set new entry
135 data.Set(n+1);
136 data[n] = seq;
137 }
138
139 // remove entry from string
140 runs.Remove(0, runs.First(num)+num.Length());
141 }
142
143 MJob::SortArray(data);
144}
145
146// --------------------------------------------------------------------------
147//
148// After resolving the sequence filename and directory either from the
149// default (/magic/data/sequences/0004/sequence00004000.txt) or from
150// the corresponding entries in the dataset file.
151// The entries are sorted by filename.
152//
153void MDataSet::ResolveSequences(TEnv &env, const TArrayI &num, TList &list) const
154{
155 for (int i=0; i<num.GetSize(); i++)
156 {
157 TString name = env.GetValue(Form("Sequence%08d.File", num[i]), "");
158 TString dir = env.GetValue(Form("Sequence%08d.Dir", num[i]), "");
159
160 gSystem->ExpandPathName(name);
161 gSystem->ExpandPathName(dir);
162
163 // Set default sequence file and dir name
164 if (name.IsNull())
165 name = Form("/magic/sequences/%04d/sequence%08d.txt", num[i]/10000, num[i]);
166 if (dir.IsNull())
167 dir = Form("/magic/data/star/%04d/%08d", num[i]/10000, num[i]);
168
169 if (gSystem->AccessPathName(name, kFileExists))
170 gLog << warn << "WARNING - Sequence file '" << name << "' doesn't exist." << endl;
171
172 if (gSystem->AccessPathName(dir, kFileExists))
173 gLog << warn << "WARNING - Directory '" << dir << "' doesn't exist." << endl;
174
175 list.Add(new TNamed(name, dir));
176 }
177
178 // For the synchronization we must make sure, that all sequences are
179 // in the correct order...
180 // list.Sort();
181}
182
183// --------------------------------------------------------------------------
184//
185// Read the file fname as setup file for the sequence.
186//
187MDataSet::MDataSet(const char *fname)
188{
189 fName = fname;
190
191 const char *expname = gSystem->ExpandPathName(fname);
192
193 fTitle = Form("Sequences contained in file %s", expname);
194
195 TEnv env(expname);
196 delete [] expname;
197
198 TString str;
199
200 fNumAnalysis = env.GetValue("AnalysisNumber", -1);
201
202 str = env.GetValue("SequencesOn", "");
203 Split(str, fNumSequencesOn);
204 str = env.GetValue("SequencesOff", "");
205 Split(str, fNumSequencesOff);
206
207 ResolveSequences(env, fNumSequencesOn, fSequencesOn);
208 ResolveSequences(env, fNumSequencesOff, fSequencesOff);
209
210
211 fNameSource = env.GetValue("SourceName", "");
212 fCatalog = env.GetValue("Catalog", "~/Software/data/magic_favorites.edb");
213 fIsWobbleMode = env.GetValue("WobbleMode", kFALSE);
214
215 //Print();
216 /*
217 GetFileNames(env, fSequencesOn);
218 GetFileNames(env, fSequencesOff);
219 */
220}
221
222// --------------------------------------------------------------------------
223//
224// Return '+' if both can be accessed, '-' otherwise.
225//
226void MDataSet::PrintFile(const TObject &obj)
227{
228 const Bool_t access = !gSystem->AccessPathName(obj.GetName(), kFileExists) && !gSystem->AccessPathName(obj.GetTitle(), kFileExists) ? '+' : '-';
229 gLog << " " << (access?"+":"-") << " " << obj.GetName() << " <" << obj.GetTitle() << ">" << endl;
230}
231
232// --------------------------------------------------------------------------
233//
234// Print the contents of the sequence
235//
236void MDataSet::Print(Option_t *o) const
237{
238 gLog << all;
239 if (!IsValid())
240 {
241 gLog << "Dataset: " << fName << " <invalid>" << endl;
242 return;
243 }
244 gLog << "Analysis Number: " << fNumAnalysis << endl;
245 gLog << "Sequences On: ";
246 for (int i=0; i<fNumSequencesOn.GetSize(); i++)
247 gLog << " " << fNumSequencesOn[i];
248 gLog << endl;
249 gLog << "Sequences Off: ";
250 for (int i=0; i<fNumSequencesOff.GetSize(); i++)
251 gLog << " " << fNumSequencesOff[i];
252 gLog << endl;
253
254 gLog << "SourceName: " << fNameSource << endl;
255 gLog << "Catalog: " << fCatalog << endl;
256
257 gLog << "WobbleMode: " << (fIsWobbleMode?"On":"Off") << endl;
258
259 if (!TString(o).Contains("files", TString::kIgnoreCase))
260 return;
261
262 TObject *obj=0;
263
264 gLog << endl;
265 gLog << "On-Data Files:" << endl;
266 TIter NextOn(&fSequencesOn);
267 while ((obj=NextOn()))
268 PrintFile(*obj);
269
270 gLog << endl;
271 gLog << "Off-Data Files:" << endl;
272 TIter NextOff(&fSequencesOff);
273 while ((obj=NextOff()))
274 PrintFile(*obj);
275}
276
277// --------------------------------------------------------------------------
278//
279// Adds all sequences contained in list to the MDirIter. After adding
280// everything MDirIter::Sort is called to sort all entries by name.
281//
282Bool_t MDataSet::AddSequencesFromList(const TList &list, MDirIter &files)
283{
284 TIter Next(const_cast<TList*>(&list));
285 TObject *o=0;
286 while ((o=Next()))
287 {
288 MSequence seq(o->GetName());
289 if (!seq.IsValid())
290 {
291 gLog << warn << "WARNING - Sequence " << o->GetName() << " invalid!" << endl;
292 return kFALSE;
293 }
294
295 const TString dir(o->GetTitle());
296 seq.SetupDatRuns(files, MSequence::kImages, dir.IsNull() ? 0 : dir.Data());
297 }
298
299 // This is important in case of synchronisation, because the
300 // files in the sequences can be interleaved (eg W1, W2)
301 // Filenames MUST begin with an appropriate string which allow
302 // to order them correctly in time!
303 // files.Sort();
304
305 if (gLog.GetDebugLevel()>4)
306 {
307 gLog << dbg << "Files which are searched:" << endl;
308 files.Print();
309 }
310 return kTRUE;
311}
312
313Bool_t MDataSet::AddFilesOn(MRead &read) const
314{
315 MDirIter files;
316 if (!AddSequencesFromList(fSequencesOn, files))
317 return kFALSE;
318 return read.AddFiles(files)>0;
319}
320
321Bool_t MDataSet::AddFilesOff(MRead &read) const
322{
323 MDirIter files;
324 if (!AddSequencesFromList(fSequencesOff, files))
325 return kFALSE;
326 return read.AddFiles(files)>0;
327}
328
329Bool_t MDataSet::AddFiles(MRead &read) const
330{
331 const Bool_t rc1 = AddFilesOff(read);
332 const Bool_t rc2 = AddFilesOn(read);
333 return rc1 && rc2;
334}
335
336Int_t MDataSet::AddFilesToChain(MDirIter &files, TChain &chain)
337{
338 Int_t num=0;
339 while (1)
340 {
341 const TString fname = files.Next();
342 if (fname.IsNull())
343 break;
344
345 const Int_t n = chain.Add(fname);
346 if (n<=0)
347 return kFALSE;
348 num += n;
349 }
350 return num;
351}
352
353Bool_t MDataSet::AddFilesOn(TChain &chain) const
354{
355 MDirIter files;
356 if (!AddSequencesFromList(fSequencesOn, files))
357 return kFALSE;
358 return AddFilesToChain(files, chain)>0;
359}
360
361Bool_t MDataSet::AddFilesOff(TChain &chain) const
362{
363 MDirIter files;
364 if (!AddSequencesFromList(fSequencesOff, files))
365 return kFALSE;
366 return AddFilesToChain(files, chain)>0;
367}
368
369Bool_t MDataSet::AddFiles(TChain &read) const
370{
371 const Bool_t rc1 = AddFilesOff(read);
372 const Bool_t rc2 = AddFilesOn(read);
373 return rc1 && rc2;
374}
375
376Bool_t MDataSet::GetSourcePos(MPointingPos &pos) const
377{
378 if (!HasSource())
379 {
380 gLog << err << "ERROR - MDataSet::GetSourcePos called, but no source available." << endl;
381 return kFALSE;
382 }
383
384 TString catalog(fCatalog);
385 gSystem->ExpandPathName(catalog);
386
387 ifstream fin(catalog);
388 if (!fin)
389 {
390 gLog << err << "Cannot open file " << catalog << ": ";
391 gLog << strerror(errno) << endl;
392 return kFALSE;
393 }
394
395 TString ra, dec, epoch;
396
397 Int_t n = 0;
398 while (1)
399 {
400 TString line;
401 line.ReadLine(fin);
402 if (!fin)
403 break;
404
405 n++;
406
407 // Strip all spaces from line
408 for (int i=0; i<line.Length(); i++)
409 if (line[i]==' ')
410 line.Remove(i--, 1);
411
412 if (fNameSource!=line(0, fNameSource.Length()))
413 continue;
414
415 // CrabNebula,f|L|K0,5:34:32.0,22:0:52,-1.0,2000
416
417 for (int i=0; i<6; i++)
418 {
419 const Ssiz_t p = line.First(',');
420 if (p<0 && i<5)
421 {
422 gLog << err << "ERROR - Not enough arguments in line #" << n << " of " << catalog << endl;
423 return kFALSE;;
424 }
425
426 switch (i)
427 {
428 case 0:
429 case 1:
430 case 4:
431 break;
432 case 2:
433 ra = line(0, p);
434 break;
435 case 3:
436 dec = line(0, p);
437 break;
438 case 5:
439 epoch = line;
440 break;
441 }
442 line.Remove(0, p+1);
443 }
444
445 if (line.First(',')>=0)
446 {
447 gLog << err << "ERROR - Too much arguments in line #" << n << " of " << catalog << endl;
448 return kFALSE;
449 }
450
451 break;
452 }
453
454 if (epoch.IsNull())
455 {
456 gLog << err << "ERROR - No entry " << fNameSource << " in " << catalog << endl;
457 return kFALSE;
458 }
459
460 if (epoch!=(TString)"2000")
461 {
462 gLog << err << "ERROR - Epoch not 2000... not supported." << endl;
463 return kFALSE;
464 }
465
466 Double_t r,d;
467 if (!MAstro::Coordinate2Angle(ra, r))
468 {
469 gLog << err << "ERROR - Interpreting right ascension: " << ra << endl;
470 return kFALSE;
471 }
472 if (!MAstro::Coordinate2Angle(dec, d))
473 {
474 gLog << err << "ERROR - Interpreting declination: " << dec << endl;
475 return kFALSE;
476 }
477
478 pos.SetSkyPosition(r, d);
479 pos.SetTitle(fNameSource);
480
481 return kTRUE;
482}
Note: See TracBrowser for help on using the repository browser.