source: trunk/MagicSoft/Mars/mbase/MEvtLoop.cc@ 2106

Last change on this file since 2106 was 2098, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 27.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 12/2000 <mailto:tbretz@uni-sw.gwdg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2001
21!
22!
23\* ======================================================================== */
24
25
26//////////////////////////////////////////////////////////////////////////////
27// //
28// MEvtLoop //
29// //
30// This class is the core of each event processing. //
31// First you must set the parameter list to use. The parameter list //
32// must contain the task list (MTaskList) to use. The name of the task //
33// list can be specified if you call Eventloop. The standard name is //
34// "MTaskList". The name you specify must match the name of the MTaskList //
35// object. //
36// //
37// If you call Eventloop first all PreProcess functions - with the //
38// parameter list as an argument - of the tasks in the task list are //
39// executed. If one of them returns kFALSE then the execution is stopped. //
40// If the preprocessing was ok. The Process funtion of the tasks are //
41// as long as one function returns kSTOP. Only the tasks which are marked //
42// marked as "All" or with a string which matches the MInputStreamID of //
43// MTaskList are executed. If one tasks returns kCONTINUE the pending //
44// tasks in the list are skipped and the execution in continued with //
45// the first one in the list. //
46// Afterwards the PostProcess functions are executed. //
47// //
48// If you want to display the progress in a gui you can use SetProgressBar //
49// and a TGProgressBar or a MProgressBar. If you set a MStatusDisplay //
50// using SetDisplay, the Progress bar from this display is used. //
51// //
52// You can create a macro from a completely setup eventloop by: //
53// evtloop.MakeMacro("mymacro.C"); //
54// //
55// You will always need to check the macro, it will not run, but it //
56// should have al important information. //
57// //
58// //
59// You can also write all this information to a root file: //
60// TFile file("myfile.root"); //
61// evtloop.Write("MyEvtloopKey"); //
62// //
63// You can afterwards read the information from an open file by: //
64// evtloop.Read("MyEvtloopKey"); //
65// //
66// To lookup the information write it to a file using MakeMacro //
67// //
68//////////////////////////////////////////////////////////////////////////////
69#include "MEvtLoop.h"
70
71#include <time.h> // time_t
72#include <fstream.h> // ofstream, SavePrimitive
73#include <iostream.h>
74
75#include <TTime.h> // TTime
76#include <TFile.h> // gFile
77#include <TSystem.h> // gSystem
78#include <TStopwatch.h>
79#include <TGProgressBar.h>
80
81#include "MLog.h"
82#include "MLogManip.h"
83
84#include "MParList.h"
85#include "MTaskList.h"
86#ifdef __MARS__
87#include "MRead.h" // for setting progress bar
88#include "MProgressBar.h" // MProgressBar::GetBar
89#include "MStatusDisplay.h" // MStatusDisplay::GetBar
90#endif
91
92ClassImp(MEvtLoop);
93
94
95//!
96//! Maybe we can add a static parameter list to MEvtLoop
97//! Also we can derive MEvtLoop from MTaskList to have a static tasklist, too
98//!
99
100TList *gListOfPrimitives; // forward declaration in MParContainer.h
101
102// --------------------------------------------------------------------------
103//
104// default constructor
105//
106MEvtLoop::MEvtLoop(const char *name) : fParList(NULL), fProgress(NULL)
107{
108 fName = name;
109
110 fLog->Underline();
111 *fLog << inf << "Instantiated MEvtLoop (" << name << "), using ROOT v" << ROOTVER << endl;
112}
113
114// --------------------------------------------------------------------------
115//
116// destructor
117//
118MEvtLoop::~MEvtLoop()
119{
120 if (TestBit(kIsOwner) && fParList)
121 delete fParList;
122}
123
124// --------------------------------------------------------------------------
125//
126// If the evntloop knows its tasklist search for the task there,
127// otherwise return NULL.
128//
129MTask *MEvtLoop::FindTask(const char *name) const
130{
131 return fTaskList ? fTaskList->FindTask(name) : NULL;
132}
133
134// --------------------------------------------------------------------------
135//
136// If the evntloop knows its tasklist search for the task there,
137// otherwise return NULL.
138//
139MTask *MEvtLoop::FindTask(const MTask *obj) const
140{
141 return fTaskList ? fTaskList->FindTask(obj) : NULL;
142}
143
144// --------------------------------------------------------------------------
145//
146// if you set the Eventloop as owner the destructor of the given parameter
147// list is calles by the destructor of MEvtLoop, otherwise not.
148//
149void MEvtLoop::SetOwner(Bool_t enable)
150{
151 enable ? SetBit(kIsOwner) : ResetBit(kIsOwner);
152}
153
154#ifdef __MARS__
155// --------------------------------------------------------------------------
156//
157// Specify an existing MProgressBar object. It will display the progress
158// graphically. This will make thing about 1-2% slower.
159//
160void MEvtLoop::SetProgressBar(MProgressBar *bar)
161{
162 fProgress = bar->GetBar();
163}
164#endif
165
166// --------------------------------------------------------------------------
167//
168// The proprocessing part of the eventloop. Be careful, this is
169// for developers or use in special jobs only!
170//
171Bool_t MEvtLoop::PreProcess(const char *tlist)
172{
173 //
174 // check if the needed parameter list is set.
175 //
176 if (!fParList)
177 {
178 *fLog << err << dbginf << "Parlist not initialized." << endl;
179 return kFALSE;
180 }
181
182 //
183 // check for the existance of the specified task list
184 // the default name is "MTaskList"
185 //
186 fTaskList = (MTaskList*)fParList->FindObject(tlist, "MTaskList");
187 if (!fTaskList)
188 {
189 *fLog << err << dbginf << "Cannot find tasklist '" << tlist << "' in parameter list." << endl;
190 return kFALSE;
191 }
192
193 if (fLog != &gLog)
194 fParList->SetLogStream(fLog);
195
196#ifdef __MARS__
197 //
198 // Check whether display is still existing
199 //
200 if (fDisplay && !gROOT->GetListOfSpecials()->FindObject(fDisplay))
201 fDisplay = NULL;
202 if (fDisplay)
203 {
204 // Lock display to prevent user from deleting it
205 fDisplay->Lock();
206 // Get pointer to update Progress bar
207 fProgress = fDisplay->GetBar();
208 // Don't display context menus
209 fDisplay->SetNoContextMenu();
210 // Set window and icon name
211 fDisplay->SetWindowName(TString("Status Display: ")+fName);
212 fDisplay->SetIconName(fName);
213 // Start automatic update
214 fDisplay->StartUpdate();
215 // Cascade display through childs
216 fParList->SetDisplay(fDisplay);
217 }
218#endif
219
220 //
221 // execute the preprocess of all tasks
222 // connect the different tasks with the right containers in
223 // the parameter list
224 //
225 if (!fTaskList->PreProcess(fParList))
226 {
227 *fLog << err << "Error detected while PreProcessing." << endl;
228 return kFALSE;
229 }
230
231 *fLog << endl;
232
233 return kTRUE;
234}
235
236Bool_t MEvtLoop::ProcessGuiEvents(Int_t num)
237{
238 if (!fProgress)
239 return kTRUE;
240
241 //
242 // Check status of display
243 //
244 Bool_t rc = kTRUE;
245
246 if (fDisplay)
247 switch (fDisplay->CheckStatus())
248 {
249 case MStatusDisplay::kLoopNone:
250 break;
251 case MStatusDisplay::kLoopStop:
252 rc = kFALSE;
253 fDisplay->ClearStatus();
254 break;
255 case MStatusDisplay::kFileExit:
256 fParList->SetDisplay(NULL);
257 delete fDisplay;
258 SetDisplay(NULL);
259 fProgress = NULL;
260 gSystem->ProcessEvents();
261 return kTRUE;
262 default:
263 *fLog << warn << "MEvtloop: fDisplay->ChecStatus() has returned unknown status #" << fDisplay->CheckStatus() << "... cleared." << endl;
264 fDisplay->ClearStatus();
265 break;
266 }
267
268 //
269 // Check System time (don't loose too much time by updates)
270 //
271
272 // FIXME: Not thread safe
273 static Int_t start = num;
274 static TTime t1 = gSystem->Now();
275 static TTime t2 = t1;
276
277 //
278 // No update < 20ms
279 //
280 const TTime t0 = gSystem->Now();
281 if (t0-t1 < (TTime)20)
282 return rc;
283 t1 = t0;
284
285 //
286 // Update current speed each second
287 //
288 if (fDisplay && t0-t2>(TTime)1000)
289 {
290 const Int_t speed = 1000*(num-start)/(long int)(t0-t2);
291 TString txt = "Processing...";
292 if (speed>0)
293 {
294 txt += " (";
295 txt += speed;
296 txt += "Evts/s)";
297 }
298 fDisplay->SetStatusLine1(txt);
299 start = num;
300 t2 = t1;
301 }
302
303 //
304 // Set new progress bar position
305 //
306 fProgress->SetPosition(num);
307
308 //
309 // Handle GUI events (display changes)
310 //
311#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
312 gSystem->ProcessEvents();
313#else
314 if (fDisplay)
315 gSystem->ProcessEvents();
316 else
317 gClient->ProcessEventsFor(fProgress);
318#endif
319
320 return rc;
321}
322
323// --------------------------------------------------------------------------
324//
325// The processing part of the eventloop. Be careful, this is
326// for developers or use in special jobs only!
327//
328Bool_t MEvtLoop::Process(Int_t maxcnt)
329{
330 //
331 // loop over all events and process all tasks for
332 // each event
333 //
334 *fLog << all <<"Eventloop running (";
335
336 if (maxcnt<0)
337 *fLog << "all";
338 else
339 *fLog << dec << maxcnt;
340
341 *fLog << " events)..." << flush;
342
343 Int_t entries = INT_MAX;
344
345 if (fProgress)
346 {
347 fProgress->Reset();
348#ifdef __MARS__
349 // limits.h
350 MRead *read = (MRead*)fTaskList->FindObject("MRead");
351 if (read && read->GetEntries()>0)
352 entries = read->GetEntries();
353#endif
354
355 if (maxcnt>0)
356 fProgress->SetRange(0, TMath::Min(maxcnt, entries));
357 else
358 if (entries!=INT_MAX)
359 fProgress->SetRange(0, entries);
360 }
361
362 if (fDisplay)
363 {
364 fDisplay->SetStatusLine1("Processing...");
365 fDisplay->SetStatusLine2("");
366 }
367
368 Int_t dummy = maxcnt<0 ? 0 : maxcnt;
369
370 //
371 // start a stopwatch
372 //
373 TStopwatch clock;
374 clock.Start();
375
376 //
377 // This is the MAIN EVENTLOOP which processes the data
378 // if maxcnt<0 the number of processed events is counted
379 // else only maxcnt events are processed
380 //
381 Int_t numcnts = 0;
382
383 Bool_t rc = kTRUE;
384 if (maxcnt<0)
385 // process first and increment if sucessfull
386 while ((rc=fTaskList->Process())==kTRUE)
387 {
388 numcnts++;
389 if (!ProcessGuiEvents(++dummy))
390 break;
391 }
392 else
393 // check for number and break if unsuccessfull
394 while (dummy-- && (rc=fTaskList->Process())==kTRUE)
395 {
396 numcnts++;
397 if (!ProcessGuiEvents(maxcnt - dummy))
398 break;
399 }
400
401 //
402 // stop stop-watch, print results
403 //
404 clock.Stop();
405
406 if (fProgress)
407 {
408 fProgress->SetPosition(maxcnt>0 ? TMath::Min(maxcnt, entries) : entries);
409#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
410 gSystem->ProcessEvents();
411#else
412 gClient->ProcessEventsFor(fDisplay ? fDisplay->GetBar() : fProgress);
413#endif
414 }
415
416 *fLog << all << "Ready!" << endl << endl;
417
418 *fLog << dec << endl << "CPU - "
419 << "Time: " << clock.CpuTime() << "s"
420 << " for " << numcnts << " Events"
421 << " --> " << numcnts/clock.CpuTime() << " Events/s"
422 << endl;
423 *fLog << "Real - "
424 << "Time: " << clock.RealTime() << "s"
425 << " for " << numcnts << " Events"
426 << " --> " << numcnts/clock.RealTime() << " Events/s"
427 << endl << endl;
428
429 return rc!=kERROR;
430}
431
432// --------------------------------------------------------------------------
433//
434// The postprocessing part of the eventloop. Be careful, this is
435// for developers or use in special jobs only!
436//
437Bool_t MEvtLoop::PostProcess() const
438{
439 //
440 // execute the post process of all tasks
441 //
442 return fTaskList->PostProcess();
443}
444
445// --------------------------------------------------------------------------
446//
447// See class description above. Returns kTRUE if PreProcessing,
448// Processing and PostProcessing was successfull, otherwise kFALSE.
449//
450Bool_t MEvtLoop::Eventloop(Int_t maxcnt, const char *tlist)
451{
452 Bool_t rc = PreProcess();
453
454 //
455 // If all Tasks were PreProcesses successfully start Processing.
456 //
457 if (rc)
458 rc = Process(maxcnt);
459
460 //
461 // Now postprocess all tasks. Only successfully preprocessed tasks
462 // are postprocessed. If the Postprocessing of one task fails
463 // return an error.
464 //
465 if (!PostProcess())
466 {
467 *fLog << err << "Error detected while PostProcessing." << endl;
468 rc = kFALSE;
469 }
470
471 if (!fDisplay)
472 return rc;
473
474 // Set status lines
475 fDisplay->SetStatusLine1(fName);
476 fDisplay->SetStatusLine2(rc ? "Done." : "Error!");
477 // Stop automatic update
478 fDisplay->StopUpdate();
479 // Reallow context menus
480 fDisplay->SetNoContextMenu(kFALSE);
481 // Reallow user to exit window by File menu
482 fDisplay->UnLock();
483
484 //
485 // If postprocessing of all preprocessed tasks was sucefully return rc.
486 // This gives an error in case the preprocessing has failed already.
487 // Otherwise the eventloop is considered: successfully.
488 //
489 return rc;
490}
491
492// --------------------------------------------------------------------------
493//
494// After you setup (or read) an Evtloop you can use this to write the
495// eventloop setup as a macro. The default name is "evtloop.C". The default
496// extension is .C If the extension is not given, .C is added.
497// I the last character in the argument is a '+' the file is not closed.
498// This is usefull if you have an eventloop which runs three times and
499// you want to write one macro. If the first character is a '+' no
500// opening is written, eg:
501//
502// MEvtLoop evtloop;
503// // some setup
504// evtloop.MakeMacro("mymacro+");
505// // replace the tasklist the first time
506// evtloop.MakeMacro("+mymacro+");
507// // replace the tasklist the second time
508// evtloop.MakeMacro("+mymacro");
509//
510void MEvtLoop::MakeMacro(const char *filename)
511{
512 TString name(filename);
513
514 name = name.Strip(TString::kBoth);
515
516 Bool_t open = kTRUE;
517 Bool_t close = kTRUE;
518 if (name[0]=='+')
519 {
520 open = kFALSE;
521 name.Remove(0, 1);
522 name = name.Strip(TString::kBoth);
523 }
524
525 if (name[name.Length()-1]=='+')
526 {
527 close = kFALSE;
528 name.Remove(name.Length()-1, 1);
529 name = name.Strip(TString::kBoth);
530 }
531
532 if (!name.EndsWith(".C"))
533 name += ".C";
534
535 ofstream fout;
536
537 if (!open)
538 {
539 fout.open(name, ios::app);
540 fout << endl;
541 fout << " // ----------------------------------------------------------------------" << endl;
542 fout << endl;
543 }
544 else
545 {
546 fout.open(name);
547
548 time_t t = time(NULL);
549 fout <<
550 "/* ======================================================================== *\\" << endl <<
551 "!" << endl <<
552 "! *" << endl <<
553 "! * This file is part of MARS, the MAGIC Analysis and Reconstruction" << endl <<
554 "! * Software. It is distributed to you in the hope that it can be a useful" << endl <<
555 "! * and timesaving tool in analysing Data of imaging Cerenkov telescopes." << endl <<
556 "! * It is distributed WITHOUT ANY WARRANTY." << endl <<
557 "! *" << endl <<
558 "! * Permission to use, copy, modify and distribute this software and its" << endl <<
559 "! * documentation for any purpose is hereby granted without fee," << endl <<
560 "! * provided that the above copyright notice appear in all copies and" << endl <<
561 "! * that both that copyright notice and this permission notice appear" << endl <<
562 "! * in supporting documentation. It is provided \"as is\" without express" << endl <<
563 "! * or implied warranty." << endl <<
564 "! *" << endl <<
565 "!" << endl <<
566 "!" << endl <<
567 "! Author(s): Thomas Bretz et al. <mailto:tbretz@astro.uni-wuerzburg.de>" << endl <<
568 "!" << endl <<
569 "! Copyright: MAGIC Software Development, 2000-2002" << endl <<
570 "!" << endl <<
571 "!" << endl <<
572 "\\* ======================================================================== */" << endl << endl <<
573 "// ------------------------------------------------------------------------" << endl <<
574 "//" << endl <<
575 "// This macro was automatically created on" << endl<<
576 "// " << ctime(&t) <<
577 "// with the MEvtLoop::MakeMacro tool." << endl <<
578 "//" << endl <<
579 "// ------------------------------------------------------------------------" << endl << endl <<
580 "void " << name(0, name.Length()-2) << "()" << endl <<
581 "{" << endl;
582 }
583
584 SavePrimitive(fout, (TString)"" + (open?"open":"") + (close?"close":""));
585
586 if (!close)
587 return;
588
589 fout << "}" << endl;
590
591 *fLog << inf << "Macro '" << name << "' written." << endl;
592}
593
594// --------------------------------------------------------------------------
595//
596// Implementation of SavePrimitive. Used to write the call to a constructor
597// to a macro. In the original root implementation it is used to write
598// gui elements to a macro-file.
599//
600void MEvtLoop::StreamPrimitive(ofstream &out) const
601{
602 out << " MEvtLoop " << GetUniqueName();
603 if (fName!="Evtloop")
604 out << "(\"" << fName << "\")";
605 out << ";" << endl;
606}
607
608// --------------------------------------------------------------------------
609//
610//
611void MEvtLoop::SavePrimitive(ofstream &out, Option_t *opt)
612{
613 TString options = opt;
614 options.ToLower();
615
616 if (HasDuplicateNames("MEvtLoop::SavePrimitive"))
617 {
618 out << " // !" << endl;
619 out << " // ! WARNING - Your eventloop (MParList, MTaskList, ...) contains more than" << endl;
620 out << " // ! one object (MParContainer, MTask, ...) with the same name. The created macro" << endl;
621 out << " // ! may need manual intervention before it can be used." << endl;
622 out << " // !" << endl;
623 out << endl;
624 }
625
626 if (!options.Contains("open"))
627 {
628 if (gListOfPrimitives)
629 {
630 *fLog << err << "MEvtLoop::SavePrimitive - Error: old file not closed." << endl;
631 gListOfPrimitives->ForEach(TObject, ResetBit)(BIT(15));
632 delete gListOfPrimitives;
633 }
634 gListOfPrimitives = new TList;
635 }
636
637 if (fParList)
638 fParList->SavePrimitive(out);
639
640 MParContainer::SavePrimitive(out);
641
642 if (fParList)
643 out << " " << GetUniqueName() << ".SetParList(&" << fParList->GetUniqueName() << ");" << endl;
644 else
645 out << " // fParList empty..." << endl;
646 out << " if (!" << GetUniqueName() << ".Eventloop())" << endl;
647 out << " return;" << endl;
648
649 if (!options.Contains("close"))
650 return;
651
652 gListOfPrimitives->ForEach(TObject, ResetBit)(BIT(15));
653 delete gListOfPrimitives;
654 gListOfPrimitives = 0;
655}
656
657// --------------------------------------------------------------------------
658//
659// Get a list of all conmtainer names which are somehow part of the
660// eventloop. Chack for duplicate members and print a warning if
661// duplicates are found. Return kTRUE if duplicates are found, otherwise
662// kFALSE;
663//
664Bool_t MEvtLoop::HasDuplicateNames(TObjArray &arr, const TString txt) const
665{
666 arr.Sort();
667
668 TIter Next(&arr);
669 TObject *obj;
670 TString name;
671 Bool_t found = kFALSE;
672 while ((obj=Next()))
673 {
674 if (name==obj->GetName())
675 {
676 if (!found)
677 {
678 *fLog << warn << endl;
679 *fLog << " ! WARNING (" << txt << ")" << endl;
680 *fLog << " ! Your eventloop (MParList, MTaskList, ...) contains more than" << endl;
681 *fLog << " ! one object (MParContainer, MTask, ...) with the same name." << endl;
682 *fLog << " ! Creating a macro from it using MEvtLoop::MakeMacro may create" << endl;
683 *fLog << " ! a macro which needs manual intervention before it can be used." << endl;
684 found = kTRUE;
685 }
686 *fLog << " ! Please rename: " << obj->GetName() << endl;
687 }
688 name = obj->GetName();
689 }
690
691 return found;
692}
693
694// --------------------------------------------------------------------------
695//
696// Get a list of all conmtainer names which are somehow part of the
697// eventloop. Chack for duplicate members and print a warning if
698// duplicates are found. Return kTRUE if duplicates are found, otherwise
699// kFALSE;
700//
701Bool_t MEvtLoop::HasDuplicateNames(const TString txt) const
702{
703 if (!fParList)
704 return kFALSE;
705
706 TObjArray list;
707 list.SetOwner();
708
709 fParList->GetNames(list);
710
711 return HasDuplicateNames(list, txt);
712}
713
714// --------------------------------------------------------------------------
715//
716// Reads a saved eventloop from a file. The default name is "Evtloop".
717// Therefor an open file must exist (See TFile for more information)
718//
719// eg:
720// TFile file("myfile.root", "READ");
721// MEvtLoop evtloop;
722// evtloop.Read();
723// evtloop.MakeMacro("mymacro");
724//
725Int_t MEvtLoop::Read(const char *name)
726{
727 if (!gFile)
728 {
729 *fLog << err << "MEvtloop::Read: No file found. Please create a TFile first." << endl;
730 return 0;
731 }
732
733 if (!gFile->IsOpen())
734 {
735 *fLog << err << "MEvtloop::Read: File not open. Please open the TFile first." << endl;
736 return 0;
737 }
738
739 Int_t n = 0;
740 TObjArray list;
741
742 n += TObject::Read(name);
743
744 if (n==0)
745 {
746 *fLog << err << "MEvtloop::Read: No objects read." << endl;
747 return 0;
748 }
749
750 n += list.Read((TString)name+"_names");
751
752 fParList->SetNames(list);
753
754 HasDuplicateNames(list, "MEvtLoop::Read");
755
756 *fLog << inf << "Eventloop '" << name << "' read from file." << endl;
757
758 return n;
759}
760
761// --------------------------------------------------------------------------
762//
763// If available print the contents of the parameter list.
764//
765void MEvtLoop::Print(Option_t *opt) const
766{
767 if (fParList)
768 fParList->Print();
769 else
770 *fLog << all << "MEvtloop: No Parameter List available." << endl;
771}
772
773// --------------------------------------------------------------------------
774//
775// Writes a eventloop to a file. The default name is "Evtloop".
776// Therefor an open file must exist (See TFile for more information)
777//
778// eg:
779// TFile file("myfile.root", "RECREATE");
780// MEvtLoop evtloop;
781// evtloop.Write();
782// file.Close();
783//
784Int_t MEvtLoop::Write(const char *name, Int_t option, Int_t bufsize)
785{
786 if (!gFile)
787 {
788 *fLog << err << "MEvtloop::Write: No file found. Please create a TFile first." << endl;
789 return 0;
790 }
791
792 if (!gFile->IsOpen())
793 {
794 *fLog << err << "MEvtloop::Write: File not open. Please open the TFile first." << endl;
795 return 0;
796 }
797
798 if (!gFile->IsWritable())
799 {
800 *fLog << err << "MEvtloop::Write: File not writable." << endl;
801 return 0;
802 }
803
804 Int_t n = 0;
805
806 TObjArray list;
807 list.SetOwner();
808
809 fParList->GetNames(list);
810
811 n += TObject::Write(name, option, bufsize);
812
813 if (n==0)
814 {
815 *fLog << err << "MEvtloop::Read: No objects written." << endl;
816 return 0;
817 }
818
819 n += list.Write((TString)name+"_names", kSingleKey);
820
821 HasDuplicateNames(list, "MEvtLoop::Write");
822
823 *fLog << inf << "Eventloop written to file as " << name << "." << endl;
824
825 return n;
826}
827
828// --------------------------------------------------------------------------
829//
830// Read the contents/setup of a parameter container/task from a TEnv
831// instance (steering card/setup file).
832// The key to search for in the file should be of the syntax:
833// prefix.vname
834// While vname is a name which is specific for a single setup date
835// (variable) of this container and prefix is something like:
836// evtloopname.name
837// While name is the name of the containers/tasks in the parlist/tasklist
838//
839// eg. Job4.MImgCleanStd.CleaningLevel1: 3.0
840// Job4.MImgCleanStd.CleaningLevel2: 2.5
841//
842// If this cannot be found the next step is to search for
843// MImgCleanStd.CleaningLevel1: 3.0
844// And if this doesn't exist, too, we should search for:
845// CleaningLevel1: 3.0
846//
847// Warning: The programmer is responsible for the names to be unique in
848// all Mars classes.
849//
850Bool_t MEvtLoop::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
851{
852 if (!prefix.IsNull())
853 *fLog << warn << "WARNING - Second argument in MEvtLoop::ReadEnv has no meaning... ignored." << endl;
854
855 prefix = fName;
856 prefix += ".";
857
858 *fLog << inf << "Reading resources for " << prefix /*TEnv::fRcName << " from " << env.GetRcName()*/ << endl;
859
860 if (fParList->ReadEnv(env, prefix, print)==kERROR)
861 {
862 *fLog << err << "ERROR - Reading Environment file." << endl;
863 return kFALSE;
864 }
865
866 return kTRUE;
867}
868
869// --------------------------------------------------------------------------
870//
871// Write the contents/setup of a parameter container/task to a TEnv
872// instance (steering card/setup file).
873// The key to search for in the file should be of the syntax:
874// prefix.vname
875// While vname is a name which is specific for a single setup date
876// (variable) of this container and prefix is something like:
877// evtloopname.name
878// While name is the name of the containers/tasks in the parlist/tasklist
879//
880// eg. Job4.MImgCleanStd.CleaningLevel1: 3.0
881// Job4.MImgCleanStd.CleaningLevel2: 2.5
882//
883// If this cannot be found the next step is to search for
884// MImgCleanStd.CleaningLevel1: 3.0
885// And if this doesn't exist, too, we should search for:
886// CleaningLevel1: 3.0
887//
888// Warning: The programmer is responsible for the names to be unique in
889// all Mars classes.
890//
891Bool_t MEvtLoop::WriteEnv(TEnv &env, TString prefix, Bool_t print) const
892{
893 if (!prefix.IsNull())
894 *fLog << warn << "WARNING - Second argument in MEvtLoop::WriteEnv has no meaning... ignored." << endl;
895
896 prefix = fName;
897 prefix += ".";
898
899 *fLog << inf << "Writing resources: " << prefix /*TEnv::fRcName << " to " << env.GetRcName()*/ << endl;
900
901 if (fParList->WriteEnv(env, prefix, print)!=kTRUE)
902 {
903 *fLog << err << "ERROR - Writing Environment file." << endl;
904 return kFALSE;
905 }
906
907 return kTRUE;
908}
Note: See TracBrowser for help on using the repository browser.