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

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