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

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