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

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