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

Last change on this file since 2235 was 2221, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 28.7 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)
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)";
323 }
324 fDisplay->SetStatusLine1(txt);
325 start = num;
326 t2 = t1;
327 }
328
329 //
330 // Set new progress bar position
331 //
332 fProgress->SetPosition(num);
333
334 //
335 // Handle GUI events (display changes)
336 //
337#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
338 gSystem->ProcessEvents();
339#else
340 if (fDisplay)
341 gSystem->ProcessEvents();
342 else
343 gClient->ProcessEventsFor(fProgress);
344#endif
345
346 return rc;
347}
348
349// --------------------------------------------------------------------------
350//
351// The processing part of the eventloop. Be careful, this is
352// for developers or use in special jobs only!
353//
354Int_t MEvtLoop::Process(Int_t maxcnt)
355{
356 if (!fTaskList)
357 return kFALSE;
358
359 //
360 // loop over all events and process all tasks for
361 // each event
362 //
363 *fLog << all <<"Eventloop running (";
364
365 if (maxcnt<0)
366 *fLog << "all";
367 else
368 *fLog << dec << maxcnt;
369
370 *fLog << " events)..." << flush;
371
372 Int_t entries = INT_MAX;
373
374 if (fProgress && !gROOT->IsBatch())
375 {
376 fProgress->Reset();
377#ifdef __MARS__
378 // limits.h
379 MRead *read = (MRead*)fTaskList->FindObject("MRead");
380 if (read && read->GetEntries()>0)
381 entries = read->GetEntries();
382#endif
383
384 if (maxcnt>0)
385 fProgress->SetRange(0, TMath::Min(maxcnt, entries));
386 else
387 if (entries!=INT_MAX)
388 fProgress->SetRange(0, entries);
389 }
390
391 if (fDisplay)
392 {
393 fDisplay->SetStatusLine1("Processing...");
394 fDisplay->SetStatusLine2("");
395 }
396
397 Int_t dummy = maxcnt<0 ? 0 : maxcnt;
398
399 //
400 // start a stopwatch
401 //
402 TStopwatch clock;
403 clock.Start();
404
405 //
406 // This is the MAIN EVENTLOOP which processes the data
407 // if maxcnt<0 the number of processed events is counted
408 // else only maxcnt events are processed
409 //
410 Int_t numcnts = 0;
411
412 Bool_t rc = kTRUE;
413 if (maxcnt<0)
414 // process first and increment if sucessfull
415 while ((rc=fTaskList->Process())==kTRUE)
416 {
417 numcnts++;
418 if (!ProcessGuiEvents(++dummy))
419 break;
420 }
421 else
422 // check for number and break if unsuccessfull
423 while (dummy-- && (rc=fTaskList->Process())==kTRUE)
424 {
425 numcnts++;
426 if (!ProcessGuiEvents(maxcnt - dummy))
427 break;
428 }
429
430 //
431 // stop stop-watch, print results
432 //
433 clock.Stop();
434
435 if (fProgress && !gROOT->IsBatch())
436 {
437 fProgress->SetPosition(maxcnt>0 ? TMath::Min(maxcnt, entries) : entries);
438#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,06)
439 gSystem->ProcessEvents();
440#else
441 gClient->ProcessEventsFor(fDisplay ? fDisplay->GetBar() : fProgress);
442#endif
443 }
444
445 *fLog << all << "Ready!" << endl << endl;
446
447 *fLog << dec << endl << "CPU - "
448 << "Time: " << clock.CpuTime() << "s"
449 << " for " << numcnts << " Events"
450 << " --> " << numcnts/clock.CpuTime() << " Events/s"
451 << endl;
452 *fLog << "Real - "
453 << "Time: " << clock.RealTime() << "s"
454 << " for " << numcnts << " Events"
455 << " --> " << numcnts/clock.RealTime() << " Events/s"
456 << endl << endl;
457
458 return rc!=kERROR;
459}
460
461// --------------------------------------------------------------------------
462//
463// The postprocessing part of the eventloop. Be careful, this is
464// for developers or use in special jobs only!
465//
466Bool_t MEvtLoop::PostProcess() const
467{
468 //
469 // execute the post process of all tasks
470 //
471 return fTaskList ? fTaskList->PostProcess() : kTRUE;
472}
473
474// --------------------------------------------------------------------------
475//
476// See class description above. Returns kTRUE if PreProcessing,
477// Processing and PostProcessing was successfull, otherwise kFALSE.
478//
479Bool_t MEvtLoop::Eventloop(Int_t maxcnt, const char *tlist)
480{
481 TDatime d;
482 *fLog << inf << underline << "Eventloop: " << fName << " started at " << d.AsString() << endl;
483
484 Bool_t rc = PreProcess();
485
486 //
487 // If all Tasks were PreProcesses successfully start Processing.
488 //
489 if (rc)
490 rc = Process(maxcnt);
491
492 //
493 // Now postprocess all tasks. Only successfully preprocessed tasks
494 // are postprocessed. If the Postprocessing of one task fails
495 // return an error.
496 //
497 if (!PostProcess())
498 {
499 *fLog << err << "Error detected while PostProcessing." << endl;
500 rc = kFALSE;
501 }
502
503 if (!fDisplay)
504 return rc;
505
506 // Set status lines
507 fDisplay->SetStatusLine1(fName);
508 fDisplay->SetStatusLine2(rc ? "Done." : "Error!");
509 // Stop automatic update
510 fDisplay->StopUpdate();
511 // Reallow context menus
512 fDisplay->SetNoContextMenu(kFALSE);
513 // Reallow user to exit window by File menu
514 fDisplay->UnLock();
515
516 //
517 // If postprocessing of all preprocessed tasks was sucefully return rc.
518 // This gives an error in case the preprocessing has failed already.
519 // Otherwise the eventloop is considered: successfully.
520 //
521 return rc;
522}
523
524// --------------------------------------------------------------------------
525//
526// After you setup (or read) an Evtloop you can use MakeMacro() to write
527// the eventloop setup as a macro. The default name is "evtloop.C". The
528// default extension is .C If the extension is not given, .C is added.
529// If the last character in the argument is a '+' the file is not closed.
530// This is usefull if you have an eventloop which runs three times and
531// you want to write one macro. If the first character is a '+' no
532// opening is written, eg:
533//
534// MEvtLoop evtloop;
535// // some setup
536// evtloop.MakeMacro("mymacro+");
537// // replace the tasklist the first time
538// evtloop.MakeMacro("+mymacro+");
539// // replace the tasklist the second time
540// evtloop.MakeMacro("+mymacro");
541//
542void MEvtLoop::MakeMacro(const char *filename)
543{
544 TString name(filename);
545
546 name = name.Strip(TString::kBoth);
547
548 Bool_t open = kTRUE;
549 Bool_t close = kTRUE;
550 if (name[0]=='+')
551 {
552 open = kFALSE;
553 name.Remove(0, 1);
554 name = name.Strip(TString::kBoth);
555 }
556
557 if (name[name.Length()-1]=='+')
558 {
559 close = kFALSE;
560 name.Remove(name.Length()-1, 1);
561 name = name.Strip(TString::kBoth);
562 }
563
564 if (!name.EndsWith(".C"))
565 name += ".C";
566
567 ofstream fout;
568
569 if (!open)
570 {
571 fout.open(name, ios::app);
572 fout << endl;
573 fout << " // ----------------------------------------------------------------------" << endl;
574 fout << endl;
575 }
576 else
577 {
578 fout.open(name);
579
580 time_t t = time(NULL);
581 fout <<
582 "/* ======================================================================== *\\" << endl <<
583 "!" << endl <<
584 "! *" << endl <<
585 "! * This file is part of MARS, the MAGIC Analysis and Reconstruction" << endl <<
586 "! * Software. It is distributed to you in the hope that it can be a useful" << endl <<
587 "! * and timesaving tool in analysing Data of imaging Cerenkov telescopes." << endl <<
588 "! * It is distributed WITHOUT ANY WARRANTY." << endl <<
589 "! *" << endl <<
590 "! * Permission to use, copy, modify and distribute this software and its" << endl <<
591 "! * documentation for any purpose is hereby granted without fee," << endl <<
592 "! * provided that the above copyright notice appear in all copies and" << endl <<
593 "! * that both that copyright notice and this permission notice appear" << endl <<
594 "! * in supporting documentation. It is provided \"as is\" without express" << endl <<
595 "! * or implied warranty." << endl <<
596 "! *" << endl <<
597 "!" << endl <<
598 "!" << endl <<
599 "! Author(s): Thomas Bretz et al. <mailto:tbretz@astro.uni-wuerzburg.de>" << endl <<
600 "!" << endl <<
601 "! Copyright: MAGIC Software Development, 2000-2002" << endl <<
602 "!" << endl <<
603 "!" << endl <<
604 "\\* ======================================================================== */" << endl << endl <<
605 "// ------------------------------------------------------------------------" << endl <<
606 "//" << endl <<
607 "// This macro was automatically created on" << endl<<
608 "// " << ctime(&t) <<
609 "// with the MEvtLoop::MakeMacro tool." << endl <<
610 "//" << endl <<
611 "// ------------------------------------------------------------------------" << endl << endl <<
612 "void " << name(0, name.Length()-2) << "()" << endl <<
613 "{" << endl;
614 }
615
616 SavePrimitive(fout, (TString)"" + (open?"open":"") + (close?"close":""));
617
618 if (!close)
619 return;
620
621 fout << "}" << endl;
622
623 *fLog << inf << "Macro '" << name << "' written." << endl;
624}
625
626// --------------------------------------------------------------------------
627//
628// Implementation of SavePrimitive. Used to write the call to a constructor
629// to a macro. In the original root implementation it is used to write
630// gui elements to a macro-file.
631//
632void MEvtLoop::StreamPrimitive(ofstream &out) const
633{
634 out << " MEvtLoop " << GetUniqueName();
635 if (fName!="Evtloop")
636 out << "(\"" << fName << "\")";
637 out << ";" << endl;
638}
639
640// --------------------------------------------------------------------------
641//
642//
643void MEvtLoop::SavePrimitive(ofstream &out, Option_t *opt)
644{
645 TString options = opt;
646 options.ToLower();
647
648 if (HasDuplicateNames("MEvtLoop::SavePrimitive"))
649 {
650 out << " // !" << endl;
651 out << " // ! WARNING - Your eventloop (MParList, MTaskList, ...) contains more than" << endl;
652 out << " // ! one object (MParContainer, MTask, ...) with the same name. The created macro" << endl;
653 out << " // ! may need manual intervention before it can be used." << endl;
654 out << " // !" << endl;
655 out << endl;
656 }
657
658 if (!options.Contains("open"))
659 {
660 if (gListOfPrimitives)
661 {
662 *fLog << err << "MEvtLoop::SavePrimitive - Error: old file not closed." << endl;
663 gListOfPrimitives->ForEach(TObject, ResetBit)(BIT(15));
664 delete gListOfPrimitives;
665 }
666 gListOfPrimitives = new TList;
667 }
668
669 if (fParList)
670 fParList->SavePrimitive(out);
671
672 MParContainer::SavePrimitive(out);
673
674 if (fParList)
675 out << " " << GetUniqueName() << ".SetParList(&" << fParList->GetUniqueName() << ");" << endl;
676 else
677 out << " // fParList empty..." << endl;
678 out << " if (!" << GetUniqueName() << ".Eventloop())" << endl;
679 out << " return;" << endl;
680
681 if (!options.Contains("close"))
682 return;
683
684 gListOfPrimitives->ForEach(TObject, ResetBit)(BIT(15));
685 delete gListOfPrimitives;
686 gListOfPrimitives = 0;
687}
688
689// --------------------------------------------------------------------------
690//
691// Get a list of all conmtainer names which are somehow part of the
692// eventloop. Chack for duplicate members and print a warning if
693// duplicates are found. Return kTRUE if duplicates are found, otherwise
694// kFALSE;
695//
696Bool_t MEvtLoop::HasDuplicateNames(TObjArray &arr, const TString txt) const
697{
698 arr.Sort();
699
700 TIter Next(&arr);
701 TObject *obj;
702 TString name;
703 Bool_t found = kFALSE;
704 while ((obj=Next()))
705 {
706 if (name==obj->GetName())
707 {
708 if (!found)
709 {
710 *fLog << warn << endl;
711 *fLog << " ! WARNING (" << txt << ")" << endl;
712 *fLog << " ! Your eventloop (MParList, MTaskList, ...) contains more than" << endl;
713 *fLog << " ! one object (MParContainer, MTask, ...) with the same name." << endl;
714 *fLog << " ! Creating a macro from it using MEvtLoop::MakeMacro may create" << endl;
715 *fLog << " ! a macro which needs manual intervention before it can be used." << endl;
716 found = kTRUE;
717 }
718 *fLog << " ! Please rename: " << obj->GetName() << endl;
719 }
720 name = obj->GetName();
721 }
722
723 return found;
724}
725
726// --------------------------------------------------------------------------
727//
728// Get a list of all conmtainer names which are somehow part of the
729// eventloop. Chack for duplicate members and print a warning if
730// duplicates are found. Return kTRUE if duplicates are found, otherwise
731// kFALSE;
732//
733Bool_t MEvtLoop::HasDuplicateNames(const TString txt) const
734{
735 if (!fParList)
736 return kFALSE;
737
738 TObjArray list;
739 list.SetOwner();
740
741 fParList->GetNames(list);
742
743 return HasDuplicateNames(list, txt);
744}
745
746// --------------------------------------------------------------------------
747//
748// Reads a saved eventloop from a file. The default name is "Evtloop".
749// Therefor an open file must exist (See TFile for more information)
750//
751// eg:
752// TFile file("myfile.root", "READ");
753// MEvtLoop evtloop;
754// evtloop.Read();
755// evtloop.MakeMacro("mymacro");
756//
757Int_t MEvtLoop::Read(const char *name)
758{
759 if (!gFile)
760 {
761 *fLog << err << "MEvtloop::Read: No file found. Please create a TFile first." << endl;
762 return 0;
763 }
764
765 if (!gFile->IsOpen())
766 {
767 *fLog << err << "MEvtloop::Read: File not open. Please open the TFile first." << endl;
768 return 0;
769 }
770
771 Int_t n = 0;
772 TObjArray list;
773
774 n += TObject::Read(name);
775
776 if (n==0)
777 {
778 *fLog << err << "MEvtloop::Read: No objects read." << endl;
779 return 0;
780 }
781
782 n += list.Read((TString)name+"_names");
783
784 fParList->SetNames(list);
785
786 HasDuplicateNames(list, "MEvtLoop::Read");
787
788 *fLog << inf << "Eventloop '" << name << "' read from file." << endl;
789
790 return n;
791}
792
793// --------------------------------------------------------------------------
794//
795// If available print the contents of the parameter list.
796//
797void MEvtLoop::Print(Option_t *opt) const
798{
799 if (fParList)
800 fParList->Print();
801 else
802 *fLog << all << "MEvtloop: No Parameter List available." << endl;
803}
804
805// --------------------------------------------------------------------------
806//
807// Writes a eventloop to a file. The default name is "Evtloop".
808// Therefor an open file must exist (See TFile for more information)
809//
810// eg:
811// TFile file("myfile.root", "RECREATE");
812// MEvtLoop evtloop;
813// evtloop.Write();
814// file.Close();
815//
816Int_t MEvtLoop::Write(const char *name, Int_t option, Int_t bufsize)
817{
818 if (!gFile)
819 {
820 *fLog << err << "MEvtloop::Write: No file found. Please create a TFile first." << endl;
821 return 0;
822 }
823
824 if (!gFile->IsOpen())
825 {
826 *fLog << err << "MEvtloop::Write: File not open. Please open the TFile first." << endl;
827 return 0;
828 }
829
830 if (!gFile->IsWritable())
831 {
832 *fLog << err << "MEvtloop::Write: File not writable." << endl;
833 return 0;
834 }
835
836 Int_t n = 0;
837
838 TObjArray list;
839 list.SetOwner();
840
841 fParList->GetNames(list);
842
843 n += TObject::Write(name, option, bufsize);
844
845 if (n==0)
846 {
847 *fLog << err << "MEvtloop::Read: No objects written." << endl;
848 return 0;
849 }
850
851 n += list.Write((TString)name+"_names", kSingleKey);
852
853 HasDuplicateNames(list, "MEvtLoop::Write");
854
855 *fLog << inf << "Eventloop written to file as " << name << "." << endl;
856
857 return n;
858}
859
860// --------------------------------------------------------------------------
861//
862// Read the contents/setup of a parameter container/task from a TEnv
863// instance (steering card/setup file).
864// The key to search for in the file should be of the syntax:
865// prefix.vname
866// While vname is a name which is specific for a single setup date
867// (variable) of this container and prefix is something like:
868// evtloopname.name
869// While name is the name of the containers/tasks in the parlist/tasklist
870//
871// eg. Job4.MImgCleanStd.CleaningLevel1: 3.0
872// Job4.MImgCleanStd.CleaningLevel2: 2.5
873//
874// If this cannot be found the next step is to search for
875// MImgCleanStd.CleaningLevel1: 3.0
876// And if this doesn't exist, too, we should search for:
877// CleaningLevel1: 3.0
878//
879// Warning: The programmer is responsible for the names to be unique in
880// all Mars classes.
881//
882Bool_t MEvtLoop::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
883{
884 if (!prefix.IsNull())
885 *fLog << warn << "WARNING - Second argument in MEvtLoop::ReadEnv has no meaning... ignored." << endl;
886
887 prefix = fName;
888 prefix += ".";
889
890 *fLog << inf << "Reading resources for " << prefix /*TEnv::fRcName << " from " << env.GetRcName()*/ << endl;
891
892 if (fParList->ReadEnv(env, prefix, print)==kERROR)
893 {
894 *fLog << err << "ERROR - Reading Environment file." << endl;
895 return kFALSE;
896 }
897
898 return kTRUE;
899}
900
901// --------------------------------------------------------------------------
902//
903// Write the contents/setup of a parameter container/task to a TEnv
904// instance (steering card/setup file).
905// The key to search for in the file should be of the syntax:
906// prefix.vname
907// While vname is a name which is specific for a single setup date
908// (variable) of this container and prefix is something like:
909// evtloopname.name
910// While name is the name of the containers/tasks in the parlist/tasklist
911//
912// eg. Job4.MImgCleanStd.CleaningLevel1: 3.0
913// Job4.MImgCleanStd.CleaningLevel2: 2.5
914//
915// If this cannot be found the next step is to search for
916// MImgCleanStd.CleaningLevel1: 3.0
917// And if this doesn't exist, too, we should search for:
918// CleaningLevel1: 3.0
919//
920// Warning: The programmer is responsible for the names to be unique in
921// all Mars classes.
922//
923Bool_t MEvtLoop::WriteEnv(TEnv &env, TString prefix, Bool_t print) const
924{
925 if (!prefix.IsNull())
926 *fLog << warn << "WARNING - Second argument in MEvtLoop::WriteEnv has no meaning... ignored." << endl;
927
928 prefix = fName;
929 prefix += ".";
930
931 *fLog << inf << "Writing resources: " << prefix /*TEnv::fRcName << " to " << env.GetRcName()*/ << endl;
932
933 if (fParList->WriteEnv(env, prefix, print)!=kTRUE)
934 {
935 *fLog << err << "ERROR - Writing Environment file." << endl;
936 return kFALSE;
937 }
938
939 return kTRUE;
940}
941
942void MEvtLoop::RecursiveRemove(TObject *obj)
943{
944 if (obj==fParList)
945 {
946 fParList=NULL;
947 fTaskList=NULL;
948 }
949
950 if (obj==fProgress)
951 fProgress = NULL;
952
953 if (obj==fDisplay)
954 SetDisplay(NULL);
955
956 if (obj==fLog)
957 {
958 if (fParList)
959 fParList->SetLogStream(NULL);
960 SetLogStream(NULL);
961 }
962}
Note: See TracBrowser for help on using the repository browser.