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

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