source: trunk/MagicSoft/Mars/mjobs/MJob.cc@ 8785

Last change on this file since 8785 was 8719, checked in by tbretz, 17 years ago
*** empty log message ***
File size: 13.1 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, 2000-2007
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MJob
28//
29// A base class for jobs
30//
31// SetDebugEnv(0) // switch off debugging
32// SetDebugEnv(1) // reserved
33// SetDebugEnv(2) // print untouched resources after evtloop resources setup
34// SetDebugEnv(3) // do 2) and debug setting env completely
35//
36// To allow overwriting the output files call SetOverwrite()
37//
38/////////////////////////////////////////////////////////////////////////////
39#include "MJob.h"
40
41#include "MEnv.h"
42#include <TFile.h>
43#include <TSystem.h>
44#include <TObjArray.h>
45
46#include "MIter.h"
47
48#include "MLog.h"
49#include "MLogManip.h"
50
51#include "MParList.h"
52#include "MEvtLoop.h"
53
54ClassImp(MJob);
55
56using namespace std;
57
58// --------------------------------------------------------------------------
59//
60// Default constructor.
61//
62// Sets fDataFlag to 0
63//
64MJob::MJob(const char *name, const char *title) : fEnv(0), fEnvDebug(0), fOverwrite(kFALSE), fMaxEvents(0)
65{
66 fName = name ? name : "MJob";
67 fTitle = title ? title : "Base class for jobs";
68}
69
70//------------------------------------------------------------------------
71//
72// If MJob is the owner of fEnv delete fEnv.
73//
74// Reset the owenership bit.
75//
76// Set fEnv to NULL.
77//
78void MJob::ClearEnv()
79{
80 if (fEnv && TestBit(kIsOwner))
81 delete fEnv;
82 ResetBit(kIsOwner);
83 fEnv=0;
84}
85
86//------------------------------------------------------------------------
87//
88// ClearEnv()
89//
90MJob::~MJob()
91{
92 ClearEnv();
93}
94
95//------------------------------------------------------------------------
96//
97// If prefix==0 the prefix is taken from fName up to the first
98// whitespace.
99//
100// A trailing dot is removed.void MJob::SetPrefix(const char *prefix)
101void MJob::SetPrefix(const char *prefix)
102{
103 fEnvPrefix = prefix;
104
105 if (!prefix)
106 fEnvPrefix = fName.First(' ')>0 ? fName(0, fName.First(' ')) : fName;
107
108 if (fEnvPrefix.EndsWith("."))
109 fEnvPrefix.Remove(fEnvPrefix.Length()-1);
110}
111
112//------------------------------------------------------------------------
113//
114// Create a new MEnv from the file env. MJob takes of course the
115// ownership of the newly created MEnv.
116//
117// SetPrefix(prefix)
118//
119// return kFALSE if MEnv is invalid
120//
121Bool_t MJob::SetEnv(const char *env, const char *prefix)
122{
123 SetEnv(new MEnv(env), prefix);
124
125 // Take the owenership of the MEnv instance
126 SetBit(kIsOwner);
127
128 return fEnv->IsValid();
129}
130
131//------------------------------------------------------------------------
132//
133// Set a new fEnv and a new general prefix.
134//
135// Calls SetPrefix(prefix)
136//
137// MJob does not take the owenership of the MEnv instance.
138//
139void MJob::SetEnv(MEnv *env, const char *prefix)
140{
141 ClearEnv();
142
143 fEnv = env;
144
145 SetPrefix(prefix);
146}
147
148//------------------------------------------------------------------------
149//
150// Removes LF's from the path (necessary if the resource file was written
151// with a different operating system than Linux.
152//
153// Removes a trailing slash if the path is not the root-path.
154//
155// Adds fname to the path if given.
156//
157void MJob::FixPath(TString &path)
158{
159 path.ReplaceAll("\015", "");
160
161 if (path==(TString)"/")
162 return;
163
164 if (path.EndsWith("/"))
165 path.Remove(path.Length()-1);
166}
167
168//------------------------------------------------------------------------
169//
170// Calls FixPath
171//
172// Adds fname to the path if given.
173//
174TString MJob::CombinePath(TString path, TString fname)
175{
176 FixPath(path);
177
178 if (fname.IsNull())
179 return path;
180
181 if (path!=(TString)"/")
182 path += "/";
183
184 path += fname;
185
186 return path;
187}
188
189//------------------------------------------------------------------------
190//
191// Sets the output path. The exact meaning (could also be a file) is
192// deined by the derived class.
193//
194void MJob::SetPathOut(const char *path)
195{
196 fPathOut = path;
197 FixPath(fPathOut);
198}
199
200//------------------------------------------------------------------------
201//
202// Sets the input path. The exact meaning (could also be a file) is
203// deined by the derived class.
204//
205void MJob::SetPathIn(const char *path)
206{
207 fPathIn = path;
208 FixPath(fPathIn);
209}
210
211//------------------------------------------------------------------------
212//
213// Returns the TEnv
214//
215const TEnv *MJob::GetEnv() const
216{
217 return static_cast<const TEnv *const>(fEnv);
218}
219
220//------------------------------------------------------------------------
221//
222// Checks GetEnvValue(*fEnv, fEnvPrefix, name, dftl)
223// For details see MParContainer
224//
225Int_t MJob::GetEnv(const char *name, Int_t dflt) const
226{
227 return GetEnvValue(*fEnv, fEnvPrefix, name, dflt); // return fEnv->GetValue(Form("%s%s", fEnvPrefix.Data(), name), dflt);
228}
229
230//------------------------------------------------------------------------
231//
232// Checks GetEnvValue(*fEnv, fEnvPrefix, name, dftl)
233// For details see MParContainer
234//
235Double_t MJob::GetEnv(const char *name, Double_t dflt) const
236{
237 return GetEnvValue(*fEnv, fEnvPrefix, name, dflt); // return fEnv->GetValue(Form("%s%s", fEnvPrefix.Data(), name), dflt);
238}
239
240//------------------------------------------------------------------------
241//
242// Checks GetEnvValue(*fEnv, fEnvPrefix, name, dftl)
243// For details see MParContainer
244//
245const char *MJob::GetEnv(const char *name, const char *dflt) const
246{
247 return GetEnvValue(*fEnv, fEnvPrefix, name, dflt); //fEnv->GetValue(Form("%s%s", fEnvPrefix.Data(), name), dflt);
248}
249
250//------------------------------------------------------------------------
251//
252// Checks IsEnvDefined(*fEnv, fEnvPrefix, name, fEnvDebug>2)
253// For details see MParContainer
254//
255Bool_t MJob::HasEnv(const char *name) const
256{
257 return IsEnvDefined(*fEnv, fEnvPrefix, name, fEnvDebug>2);//fEnv->Lookup(Form("%s%s", fEnvPrefix.Data(), name));
258}
259
260//------------------------------------------------------------------------
261//
262// Check the resource file for
263// PathOut
264// PathIn
265// MaxEvents
266// Overwrite
267// EnvDebug
268//
269// and call the virtual function CheckEnvLocal
270//
271Bool_t MJob::CheckEnv()
272{
273 if (!fEnv)
274 return kTRUE;
275
276 TString p;
277 p = GetEnv("PathOut", "");
278 if (!p.IsNull())
279 SetPathOut(p);
280
281 p = GetEnv("PathIn", "");
282 if (!p.IsNull())
283 SetPathIn(p);
284
285 SetMaxEvents(GetEnv("MaxEvents", fMaxEvents));
286 SetOverwrite(GetEnv("Overwrite", fOverwrite));
287 SetEnvDebug( GetEnv("EnvDebug", fEnvDebug));
288
289 return CheckEnvLocal();
290}
291
292//------------------------------------------------------------------------
293//
294// Returns the result of c.ReadEnv(*fEnv, fEnvPrefix, fEnvDebug>2)
295// By adding the container first to a MParList it is ensured that
296// all levels are checked.
297//
298Bool_t MJob::CheckEnv(MParContainer &c) const
299{
300 if (!fEnv)
301 return kTRUE;
302
303 // Make sure that all levels are checked
304 MParList l;
305 l.AddToList(&c);
306 return l.ReadEnv(*fEnv, fEnvPrefix+".", fEnvDebug>2);
307}
308
309//------------------------------------------------------------------------
310//
311// Call the eventsloops ReadEnv and print untouched resources afterwards
312// if fEnvDebug>1
313//
314Bool_t MJob::SetupEnv(MEvtLoop &loop) const
315{
316 if (!fEnv)
317 return kTRUE;
318
319 if (!loop.ReadEnv(*fEnv, fEnvPrefix, fEnvDebug>2))
320 return kFALSE;
321
322 if (fEnvDebug>1)
323 fEnv->PrintUntouched();
324
325 return kTRUE;
326}
327
328//------------------------------------------------------------------------
329//
330// Checks whether write permissions to fname exists including
331// the fOverwrite data member. Empty file names return kTRUE
332//
333Bool_t MJob::HasWritePermission(TString fname) const
334{
335 gSystem->ExpandPathName(fname);
336
337 const Bool_t exists = !gSystem->AccessPathName(fname, kFileExists);
338 if (!exists)
339 return kTRUE;
340
341 const Bool_t write = !gSystem->AccessPathName(fname, kWritePermission);
342 if (!write)
343 {
344 *fLog << err << "ERROR - No permission to write to " << fname << endl;
345 return kFALSE;
346 }
347
348 if (fOverwrite)
349 return kTRUE;
350
351 *fLog << err;
352 *fLog << "ERROR - File " << fname << " already exists and overwrite not allowed." << endl;
353
354 return kFALSE;
355}
356
357//------------------------------------------------------------------------
358//
359// Write containers in list to gFile. Returns kFALSE if no gFile or any
360// container couldn't be written. kTRUE otherwise.
361//
362Bool_t MJob::WriteContainer(TCollection &list) const
363{
364 if (!gFile)
365 {
366 *fLog << err << dbginf << "ERROR - No file open (gFile==0)" << endl;
367 return kFALSE;
368 }
369
370 TIter Next(&list);
371 TObject *o=0;
372 while ((o=Next()))
373 {
374 *fLog << inf << " - Writing " << MParContainer::GetDescriptor(*o) << "..." << flush;
375 if (o->Write(o->GetName())<=0)
376 {
377 *fLog << err << dbginf << "ERROR - Writing " << MParContainer::GetDescriptor(*o) << " to file " << gFile->GetName() << endl;
378 return kFALSE;
379 }
380 *fLog << "ok." << endl;
381 }
382 return kTRUE;
383}
384
385//------------------------------------------------------------------------
386//
387// Read containers in list into list from gFile
388// Returns kFALSE if no gFile or any container couldn't be read.
389//
390Bool_t MJob::ReadContainer(TCollection &list) const
391{
392 if (!gFile)
393 {
394 *fLog << err << dbginf << "ERROR - No file open (gFile==0)" << endl;
395 return kFALSE;
396 }
397
398 MIter Next(&list);
399 MParContainer *o=0;
400 while ((o=Next()))
401 {
402 *fLog << inf << " - Reading " << o->GetDescriptor() << "..." << flush;
403 if (o->Read(o->GetName())<=0)
404 {
405 *fLog << err << dbginf << "ERROR - Reading " << o->GetDescriptor() << " from file " << gFile->GetName() << endl;
406 return kFALSE;
407 }
408 *fLog << "ok." << endl;
409 }
410 return kTRUE;
411}
412
413//------------------------------------------------------------------------
414//
415// Write containers in cont to fPathOut+"/"+name, or fPathOut only
416// if name is empty.
417//
418Bool_t MJob::WriteContainer(TCollection &cont, const char *name, const char *option, const int compr) const
419{
420 if (fPathOut.IsNull())
421 {
422 *fLog << inf << "No output path specified via SetPathOut - no output written." << endl;
423 return kTRUE;
424 }
425
426 const TString oname = CombinePath(fPathOut, name);
427
428 *fLog << inf << "Writing to file: " << oname << endl;
429
430 TString title("File written by ");
431 title += fName;
432
433 TFile file(oname, option, title, compr);
434 if (!file.IsOpen())
435 {
436 *fLog << err << "ERROR - Couldn't open file " << oname << " for writing..." << endl;
437 return kFALSE;
438 }
439
440 return WriteContainer(cont);
441}
442
443//------------------------------------------------------------------------
444//
445// return kTRUE if no display is set.
446//
447// Write the display to the TFile with name name, options option and
448// compression level comp.
449//
450// If name IsNull fPathOut is assumed to contain the name, otherwise
451// name is appended to fPathOut. fPathOut might be null.
452//
453Bool_t MJob::WriteDisplay(const char *name, const char *option, const int compr) const
454{
455 if (!fDisplay)
456 return kTRUE;
457
458 TObjArray arr;
459 arr.Add((TObject*)(fDisplay));
460 return WriteContainer(arr, name, option, compr);
461}
462
463TString MJob::ExpandPath(TString fname)
464{
465 // empty
466 if (fname.IsNull())
467 return "";
468
469 // Expand path using environment
470 gSystem->ExpandPathName(fname);
471
472 // Absolute path
473 if (fname[0]=='/')
474 {
475 gLog << dbg << "MJob::ExpandPath - Path " << fname << " is absolute." << endl;
476 return fname;
477 }
478
479 // relative path to file and file could be found
480 if (!gSystem->AccessPathName(fname, kFileExists))
481 {
482 gLog << dbg << "MJob::ExpandPath - Relative path " << fname << " found..." << endl;
483 return fname;
484 }
485
486 // Now check gEnv and MARSSYS. gEnv can overwrite MARSSYS
487 TString path(gEnv ? gEnv->GetValue("Mars.Path", "$MARSSYS") : "$MARSSYS");
488
489 // Expand path using environment
490 gSystem->ExpandPathName(path);
491
492 // check if path ends with a slash
493 path = CombinePath(path, fname);
494
495 gLog << dbg << "MJob::ExpandPath - Filename expanded to " << path << endl;
496
497 // return new path
498 return path;
499}
500
501//------------------------------------------------------------------------
502//
503// Sorts the array.
504//
505void MJob::SortArray(TArrayI &arr)
506{
507 TArrayI idx(arr.GetSize());
508 TArrayI srt(arr);
509
510 TMath::Sort(arr.GetSize(), srt.GetArray(), idx.GetArray(), kFALSE);
511
512 for (int i=0; i<arr.GetSize(); i++)
513 arr[i] = srt[idx[i]];
514}
Note: See TracBrowser for help on using the repository browser.