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

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