source: trunk/MagicSoft/Mars/mbase/MParList.cc@ 4577

Last change on this file since 4577 was 4577, checked in by tbretz, 20 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-2002
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MParList //
28// //
29// This class contains a list of different parameter containers. //
30// //
31// A parameter container is an object which is derived from //
32// MParContainer. //
33// //
34// Normally a parameter container is used for data exchange between two //
35// tasks at runtime. //
36// //
37// You can add every parameter container (Named object) to the //
38// instance and access it from somewhere else via its Name. //
39// //
40/////////////////////////////////////////////////////////////////////////////
41#include "MParList.h"
42
43#include <fstream> // ofstream, SavePrimitive
44
45#include <TNamed.h>
46#include <TClass.h>
47#include <TOrdCollection.h>
48
49#include "MLog.h"
50#include "MLogManip.h"
51
52#include "MIter.h"
53
54ClassImp(MParList);
55
56using namespace std;
57
58static const TString gsDefName = "MParList";
59static const TString gsDefTitle = "A list of Parameter Containers";
60
61// --------------------------------------------------------------------------
62//
63// default constructor
64// creates an empty list
65//
66MParList::MParList(const char *name, const char *title)
67{
68 fName = name ? name : gsDefName.Data();
69 fTitle = title ? title : gsDefTitle.Data();
70
71 //
72 // This sets a flag that the list is the owner, which means
73 // that the destructor of the list deletes all it's objects
74 //
75 fContainer = new TOrdCollection;
76 fAutodelete = new TOrdCollection;
77
78 gROOT->GetListOfCleanups()->Add(fContainer);
79 gROOT->GetListOfCleanups()->Add(fAutodelete);
80 fContainer->SetBit(kMustCleanup);
81 fAutodelete->SetBit(kMustCleanup);
82}
83
84// --------------------------------------------------------------------------
85//
86// Copy constructor. It copies all entries of the parameter list, but it
87// takes care of, that the automatically created entries are only deleted
88// once. (doesn't copy the list which holds the automatically created
89// entries)
90//
91MParList::MParList(MParList &ts)
92{
93 fContainer->AddAll(ts.fContainer);
94}
95
96// --------------------------------------------------------------------------
97//
98// If the 'IsOwner' bit is set (via SetOwner()) all containers are deleted
99// by the destructor
100//
101MParList::~MParList()
102{
103 //
104 // Case:
105 // 1) MParList is owner of the containers:
106 // All container are stored in fContainer, and become deleted by
107 // 'delete fContainer'. Some of these containers, which were
108 // created automatically are stored in fAutodelete, too. To prevent
109 // double deletion this containers are not deleted by the destructor
110 // of fAutodelete.
111 // 2) MParList is not owner of the containers:
112 // The containers which were Added by AddToList are not touched.
113 // Only the containers which were created automatically are also
114 // automatically deleted.
115 //
116 IsOwner() ? fContainer->SetOwner() : fAutodelete->SetOwner();
117
118 TIter Next(fContainer);
119 TObject *o;
120 while ((o=Next()))
121 if (o->TestBit(kCanDelete))
122 delete fContainer->Remove(o);
123
124 // FIXME? If fContainer is owner do we have to remove the object
125 // from fAutodelete due to the acces when checking for a
126 // garbage collection?
127
128 delete fContainer;
129 delete fAutodelete;
130}
131
132// --------------------------------------------------------------------------
133//
134// If the 'IsOwner' bit is set (via SetOwner()) all containers are deleted
135// by the destructor
136//
137void MParList::SetOwner(Bool_t enable)
138{
139 enable ? SetBit(kIsOwner) : ResetBit(kIsOwner);
140}
141
142// --------------------------------------------------------------------------
143//
144// Set the logging streamer of the parameter list and all contained
145// parameter containers
146//
147void MParList::SetLogStream(MLog *log)
148{
149 fContainer->ForEach(MParContainer, SetLogStream)(log);
150 MParContainer::SetLogStream(log);
151}
152
153void MParList::SetDisplay(MStatusDisplay *d)
154{
155 fContainer->ForEach(MParContainer, SetDisplay)(d);
156 MParContainer::SetDisplay(d);
157}
158
159// --------------------------------------------------------------------------
160//
161// Add a single container to the list.
162//
163// If 'where' is given, the object will be added after this.
164//
165Bool_t MParList::AddToList(MParContainer *cont, MParContainer *where)
166{
167 //
168 // check if the object (you want to add) exists
169 //
170 if (!cont)
171 return kFALSE;
172
173 //
174 // Get Name of new container
175 //
176 const char *name = cont->GetName();
177
178 //
179 // Check if the new container is already existing in the list
180 //
181 const TObject *objn = fContainer->FindObject(name);
182 const TObject *objt = fContainer->FindObject(cont);
183
184 if (objn || objt)
185 {
186 //
187 // If the container is already in the list ignore it.
188 //
189 if (objt || objn==cont)
190 {
191 *fLog << warn << dbginf << "Warning: Container '" << cont->GetName() << ", 0x" << (void*)cont;
192 *fLog << "' already existing in '" << GetName() << "'... ignoring." << endl;
193 return kTRUE;
194 }
195
196 //
197 // Otherwise add it to the list, but print a warning message
198 //
199 *fLog << warn << dbginf << "Warning: Container with the same name '" << cont->GetName();
200 *fLog << "' already existing in '" << GetName() << "'." << endl;
201 *fLog << "You may not be able to get a pointer to container task by name." << endl;
202 }
203
204 //
205 // check if you want to add the new parameter container somewhere
206 // special (in that case you specify "where")
207 //
208 if (where)
209 {
210 if (!fContainer->FindObject(where))
211 {
212 *fLog << dbginf << "Error: Cannot find parameter container after which the new one should be added!" << endl;
213 return kFALSE;
214 }
215 }
216
217 *fLog << inf << "Adding " << name << " to " << GetName() << "... " << flush;
218
219 cont->SetBit(kMustCleanup);
220 fContainer->Add(cont);
221 *fLog << "Done." << endl;
222
223 return kTRUE;
224}
225
226// --------------------------------------------------------------------------
227//
228// Add all entries of the TObjArray to the list.
229//
230void MParList::AddToList(TObjArray *list)
231{
232 //
233 // check if the object (you want to add) exists
234 //
235 if (!list)
236 return;
237
238 MIter Next(list);
239
240 MParContainer *cont = NULL;
241 while ((cont=Next()))
242 {
243 cont->SetBit(kMustCleanup);
244 AddToList(cont);
245 }
246}
247
248// --------------------------------------------------------------------------
249//
250// Find an object with the same name in the list and replace it with
251// the new one. If the kIsOwner flag is set and the object was not
252// created automatically, the object is deleted.
253//
254Bool_t MParList::Replace(MParContainer *cont)
255{
256 //
257 // check if the object (you want to add) exists
258 //
259 if (!cont)
260 return kFALSE;
261
262 TObject *obj = FindObject(cont->GetName());
263 if (!obj)
264 {
265 *fLog << warn << "No object with the same name '";
266 *fLog << cont->GetName() << "' in list... adding." << endl;
267 return AddToList(cont);
268 }
269
270 fContainer->Remove(obj);
271
272 if (IsOwner() && !fAutodelete->FindObject(obj))
273 delete obj;
274
275 *fLog << inf << "MParContainer '" << cont->GetName() << "' found and replaced..." << endl;
276
277 return AddToList(cont);
278}
279
280// --------------------------------------------------------------------------
281//
282// Find an object with the same name in the list and remove it.
283// If the kIsOwner flag is set and the object was not created
284// automatically, the object is deleted.
285//
286void MParList::Remove(MParContainer *cont)
287{
288 //
289 // check if the object (you want to add) exists
290 //
291 if (!cont)
292 return;
293
294 TObject *obj = fContainer->Remove(cont);
295 if (!obj)
296 {
297 *fLog << warn << "Object not found in list..." << endl;
298 return;
299 }
300
301 *fLog << inf << "MParContainer '" << cont->GetName() << "' removed..." << endl;
302
303 if (IsOwner() && !fAutodelete->FindObject(obj))
304 delete obj;
305}
306
307// --------------------------------------------------------------------------
308//
309// Find an object in the list.
310// 'name' is the name of the object you are searching for.
311//
312TObject *MParList::FindObject(const char *name) const
313{
314 return fContainer->FindObject(name);
315}
316
317// --------------------------------------------------------------------------
318//
319// check if the object is in the list or not
320//
321TObject *MParList::FindObject(const TObject *obj) const
322{
323 return fContainer->FindObject(obj);
324}
325
326// --------------------------------------------------------------------------
327//
328// Find an object in the list and check for the correct inheritance.
329// 'name' is the name of the object you are searching for.
330//
331// In words: Find object name and check whether it inherits from classname
332//
333TObject *MParList::FindObject(const char *name, const char *classname) const
334{
335 TObject *obj = fContainer->FindObject(name);
336
337 if (!obj)
338 return NULL;
339
340 if (obj->InheritsFrom(classname))
341 return obj;
342
343 *fLog << dbginf << warn << "Found object '" << name << "' doesn't ";
344 *fLog << "inherit from " << "'" << classname << "'" << endl;
345 return NULL;
346}
347
348// --------------------------------------------------------------------------
349//
350// check if the object is in the list or not and check for the correct
351// inheritance
352//
353TObject *MParList::FindObject(const TObject *obj, const char *classname) const
354{
355 TObject *nobj = fContainer->FindObject(obj);
356
357 if (!nobj)
358 return NULL;
359
360 if (nobj->InheritsFrom(classname))
361 return nobj;
362
363 *fLog << dbginf << warn << "Found object '" << nobj->GetName() << "' ";
364 *fLog << "doesn't inherit from " << "'" << classname << "'" << endl;
365 return NULL;
366}
367
368// --------------------------------------------------------------------------
369//
370// returns the ClassName without anything which is behind that last ';' in
371// string.
372//
373TString MParList::GetClassName(const char *classname)
374{
375 TString cname(classname);
376 const char *semicolon = strrchr(cname, ';');
377
378 if (semicolon)
379 cname.Remove(semicolon-cname);
380
381 return cname;
382}
383
384// --------------------------------------------------------------------------
385//
386// returns the ObjectName. It is created from a class and object name.
387// If no object name is given the objectname is the same than the
388// class name. Leading dots are removed from the object name
389//
390TString MParList::GetObjectName(const char *classname, const char *objname)
391{
392 TString cname(classname);
393 const char *semicolon = strrchr(cname, ';');
394
395 TString oname(objname ? objname : classname);
396
397 if (semicolon)
398 {
399 //
400 // Remove leading dots from objectname (eg. "MMcTrig;5.")
401 //
402 Int_t sz = oname.Sizeof()-2;
403
404 while (sz>=0 && oname[sz]=='.')
405 oname.Remove(sz--);
406 }
407 return oname;
408}
409
410// --------------------------------------------------------------------------
411//
412// Find an object in the list.
413// 'name' is the name of the object you are searching for.
414// If the object doesn't exist we try to create one from the
415// dictionary. If this isn't possible NULL is returned.
416//
417// An object which was created automatically is deleted automatically in
418// the destructor of the parameter list, too. This means, that if an
419// object should survive (eg. Histograms) you MUST create it by yourself
420// and add it to the parameter list.
421//
422// By default (you don't specify an object name) the object name is
423// the same as the classname
424//
425// If the classname (default classname) is of the structure
426// "Name;something" - containing a semicolon - evarything which is
427// after the last appearance of a semicolon is stripped to get the
428// Name of the Class. Normally this is used to number your objects.
429// "Name;1", "Name;2", ... If a semicolon is detected leading dots
430// are stripped from the object-name (eg. "name;5.")
431//
432// In words: Create object of type classname and set its name to objname.
433// If an object with objname already exists return it.
434//
435MParContainer *MParList::FindCreateObj(const char *classname, const char *objname)
436{
437 //
438 // If now object name (name of the object to identify it in the
439 // List) is given use it's classname as the objectname
440 //
441
442 //
443 // Check if the classname is a 'numbered' name (like: "MTime;2")
444 // if so strip the number from the classname.
445 //
446 // Becareful: We check for the last occurance of a ';' only and we
447 // also don't check if a number follows or something else.
448 //
449 // Rem: I use a TString to make the code more readyble and to get
450 // the new object deleted automatically
451 //
452 TString cname = GetClassName(classname);
453 TString oname = GetObjectName(classname, objname);
454
455 //
456 // Try to find a object with this object name which is already
457 // in the List. If we can find one we are done.
458 //
459 MParContainer *pcont = (MParContainer*)FindObject(oname);
460
461 if (pcont)
462 {
463 if (pcont->InheritsFrom(cname))
464 return pcont;
465
466 *fLog << err << "Warning: Object '" << oname << "' found in list doesn't inherit from " << cname << "." << endl;
467 return NULL;
468 }
469
470 //
471 // if object is not existing in the list try to create one
472 //
473 *fLog << inf << "Object '" << oname << "' [" << cname << "] not yet in " << GetName() << "... creating." << endl;
474
475 //
476 // try to get class from root environment
477 //
478 TClass *cls = gROOT->GetClass(cname);
479 Int_t rc = 0;
480 if (!cls)
481 rc =1;
482 else
483 {
484 if (!cls->Property())
485 rc = 5;
486 if (!cls->Size())
487 rc = 4;
488 if (!cls->IsLoaded())
489 rc = 3;
490 if (!cls->HasDefaultConstructor())
491 rc = 2;
492 }
493
494 if (rc)
495 {
496 *fLog << err << dbginf << "Cannot create new instance of class '" << cname << "': ";
497 switch (rc)
498 {
499 case 1:
500 *fLog << "gROOT->GetClass() returned NULL." << endl;
501 return NULL;
502 case 2:
503 *fLog << "no default constructor." << endl;
504 return NULL;
505 case 3:
506 *fLog << "not loaded." << endl;
507 return NULL;
508 case 4:
509 *fLog << "zero size." << endl;
510 return NULL;
511 case 5:
512 *fLog << "no property." << endl;
513 return NULL;
514 }
515 }
516
517 if (!cls->InheritsFrom(MParContainer::Class()))
518 {
519 *fLog << " - Class doesn't inherit from MParContainer." << endl;
520 return NULL;
521 }
522
523 //
524 // create the parameter container of the the given class type
525 //
526 pcont = (MParContainer*)cls->New();
527 if (!pcont)
528 {
529 *fLog << " - Class has no default constructor." << endl;
530 *fLog << " - An abstract member functions of a base class is not overwritten." << endl;
531 return NULL;
532 }
533
534 //
535 // Set the name of the container
536 //
537 pcont->SetName(oname);
538
539 //
540 // Now add the object to the parameter list
541 //
542 AddToList(pcont);
543
544 //
545 // The object was automatically created. This makes sure, that such an
546 // object is deleted together with the list
547 //
548 fAutodelete->Add(pcont);
549
550 //
551 // Find an object in the list.
552 // 'name' is the name of the object you are searching for.
553 //
554 return pcont;
555}
556
557// --------------------------------------------------------------------------
558//
559// print some information about the current status of MParList
560//
561void MParList::Print(Option_t *t) const
562{
563 *fLog << all << underline << GetDescriptor() << ":" << endl;
564
565 MParContainer *obj = NULL;
566 MIter Next(fContainer);
567 while ((obj=Next()))
568 {
569 *fLog << " " << obj->GetDescriptor();
570 if (fAutodelete->FindObject(obj))
571 *fLog << " <autodel>";
572 *fLog << endl;
573 }
574 *fLog << endl;
575}
576
577// --------------------------------------------------------------------------
578//
579// Sets the flags off all containers in the list (and the list
580// itself) to unchanged
581//
582void MParList::SetReadyToSave(Bool_t flag)
583{
584 fContainer->ForEach(MParContainer, SetReadyToSave)(flag);
585 MParContainer::SetReadyToSave(flag);
586}
587
588// --------------------------------------------------------------------------
589//
590// Reset all containers in the list
591//
592void MParList::Reset()
593{
594 fContainer->ForEach(MParContainer, Reset)();
595}
596
597// --------------------------------------------------------------------------
598//
599// This finds numbered objects. The objects are returned in a copy of a
600// TObjArray.
601//
602// If from only is given (or to=0) object are assumed numbered
603// from 1 to from.
604//
605TObjArray MParList::FindObjectList(const char *name, UInt_t first, const UInt_t last) const
606{
607 TObjArray list;
608
609 if (first>0 && last<first)
610 {
611 *fLog << err << dbginf << "Cannot create entries backwards (last<first)...skipped." << endl;
612 return list;
613 }
614
615 const UInt_t len = strlen(name);
616
617 char *auxname = new char[len+7];
618 strcpy(auxname, name);
619
620 if (first==0 && last!=0)
621 first = 1;
622
623 //
624 // If only 'from' is specified the number of entries are ment
625 //
626 for (UInt_t i=first; i<=last; i++)
627 {
628 if (first!=0 || last!=0)
629 sprintf(auxname+len, ";%d", i);
630
631 TObject *obj = FindObject(auxname);
632 if (!obj)
633 continue;
634
635 list.AddLast(obj);
636 }
637 delete auxname;
638
639 return list;
640}
641
642// --------------------------------------------------------------------------
643//
644// This finds numbered objects. The objects are returned in a copy of a
645// TObjArray. If one of the objects doesn't exist it is created from the
646// meaning of cname and oname (s. FindCreateObj)
647//
648// If from only is given (or to=0) object are assumed numbered
649// from 1 to from.
650//
651TObjArray MParList::FindCreateObjList(const char *cname, UInt_t first, const UInt_t last, const char *oname)
652{
653 TObjArray list;
654
655 if (first>0 && last<first)
656 {
657 *fLog << err << dbginf << "Cannot create entries backwards (last<first)...skipped." << endl;
658 return list;
659 }
660
661 const UInt_t len = strlen(cname);
662
663 char *auxname = new char[len+7];
664 strcpy(auxname, cname);
665
666 //
667 // If only 'from' is specified the number of entries are ment
668 //
669 if (first==0 && last!=0)
670 first = 1;
671
672 for (UInt_t i=first; i<=last; i++)
673 {
674 if (first!=0 || last!=0)
675 sprintf(auxname+len, ";%d", i);
676
677 TObject *obj = FindCreateObj(auxname, oname);
678 if (!obj)
679 break;
680
681 list.AddLast(obj);
682 }
683 delete auxname;
684
685 return list;
686}
687
688// --------------------------------------------------------------------------
689//
690// This finds numbered objects. The objects are returned in a copy of a
691// TObjArray. If one of the objects doesn't exist it is created from the
692// meaning of cname and oname (s. FindCreateObj)
693//
694// If from only is given (or to=0) object are assumed numbered
695// from 1 to from.
696//
697// Remark: Because it is static the object are only created and not added to
698// the parameter list. You must also take care of deleting these objects!
699// This function is mainly made for use in root macros. Don't use it in
700// compiled programs if you are not 100% sure what you are doing.
701//
702TObjArray MParList::CreateObjList(const char *cname, UInt_t first, const UInt_t last, const char *oname)
703{
704 TObjArray list;
705
706 if (first>0 && last<first)
707 {
708 gLog << err << dbginf << "Cannot create entries backwards (last<first)...skipped." << endl;
709 return list;
710 }
711
712 //
713 // try to get class from root environment
714 //
715 TClass *cls = gROOT->GetClass(cname);
716 if (!cls)
717 {
718 //
719 // if class is not existing in the root environment
720 //
721 gLog << dbginf << "Class '" << cname << "' not existing in dictionary." << endl;
722 return list;
723 }
724
725 const UInt_t len = strlen(cname);
726
727 char *auxname = new char[len+7];
728 strcpy(auxname, cname);
729
730 //
731 // If only 'from' is specified the number of entries are ment
732 //
733 if (first==0 && last!=0)
734 first = 1;
735
736 for (UInt_t i=first; i<=last; i++)
737 {
738 if (first!=0 || last!=0)
739 sprintf(auxname+len, ";%d", i);
740
741 //
742 // create the parameter container of the the given class type
743 //
744 MParContainer *pcont = (MParContainer*)cls->New();
745 if (!pcont)
746 {
747 gLog << err << dbginf << "Cannot create new instance of class '" << cname << "' (Maybe no def. constructor)" << endl;
748 return list;
749 }
750
751 //
752 // Set the name of the container
753 //
754 pcont->SetName(auxname);
755
756 //
757 // Add new object to the return list
758 //
759 list.AddLast(pcont);
760 }
761 delete auxname;
762
763 return list;
764}
765
766void MParList::SavePrimitive(ofstream &out, Option_t *o)
767{
768 Bool_t saved = IsSavedAsPrimitive();
769
770 MParContainer::SavePrimitive(out);
771
772 MIter Next(fContainer);
773
774 MParContainer *cont = NULL;
775 while ((cont=Next()))
776 {
777 //
778 // Because it was automatically created don't store its primitive
779 // I guess it will be automatically created again
780 //
781 if (fAutodelete->FindObject(cont) || cont->IsSavedAsPrimitive())
782 continue;
783
784 cont->SavePrimitive(out, "");
785
786 out << " " << GetUniqueName() << ".";
787 out << (cont->InheritsFrom("MTaskList") && saved ? "Replace" : "AddToList");
788 out << "(&" << cont->GetUniqueName() << ");" << endl << endl;
789 }
790}
791
792// --------------------------------------------------------------------------
793//
794// Implementation of SavePrimitive. Used to write the call to a constructor
795// to a macro. In the original root implementation it is used to write
796// gui elements to a macro-file.
797//
798void MParList::StreamPrimitive(ofstream &out) const
799{
800 out << " MParList " << GetUniqueName();
801 if (fName!=gsDefName || fTitle!=gsDefTitle)
802 {
803 out << "(\"" << fName << "\"";
804 if (fTitle!=gsDefTitle)
805 out << ", \"" << fTitle << "\"";
806 out <<")";
807 }
808 out << ";" << endl << endl;
809}
810
811// --------------------------------------------------------------------------
812//
813// Adds one TNamed object per object in the list. The TNamed object must
814// be deleted by the user.
815//
816void MParList::GetNames(TObjArray &arr) const
817{
818 MParContainer::GetNames(arr);
819 fContainer->ForEach(MParContainer, GetNames)(arr);
820}
821
822// --------------------------------------------------------------------------
823//
824// Sets name and title of each object in the list from the objects in
825// the array.
826//
827void MParList::SetNames(TObjArray &arr)
828{
829 MParContainer::SetNames(arr);
830 fContainer->ForEach(MParContainer, SetNames)(arr);
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 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 MParList::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
856{
857 if (print)
858 *fLog << all << "MParList::ReadEnv: " << prefix << " (" << (int)print << ")" << endl;
859
860 MParContainer *cont = NULL;
861
862 MIter Next(fContainer);
863 while ((cont=Next()))
864 {
865 if (cont->InheritsFrom("MTaskList"))
866 {
867 if (cont->ReadEnv(env, prefix, print)==kERROR)
868 return kERROR;
869 continue;
870 }
871
872 // Check For: Job4.ContainerName.Varname
873 if (print)
874 *fLog << all << "Testing: " << prefix+cont->GetName() << endl;
875 Bool_t rc = cont->ReadEnv(env, prefix+cont->GetName(), print);
876 if (rc==kERROR)
877 return kERROR;
878 if (rc==kTRUE)
879 continue;
880
881 // Check For: Job4.MClassName.Varname
882 if (print)
883 *fLog << all << "Testing: " << prefix+cont->ClassName() << endl;
884 rc = cont->ReadEnv(env, prefix+cont->ClassName(), print);
885 if (rc==kERROR)
886 return kERROR;
887 if (rc==kTRUE)
888 continue;
889
890 // Check For: ContainerName.Varname
891 if (print)
892 *fLog << all << "Testing: " << cont->GetName() << endl;
893 rc = cont->ReadEnv(env, cont->GetName(), print);
894 if (rc==kERROR)
895 return kERROR;
896 if (rc==kTRUE)
897 continue;
898
899 // Check For: MClassName.Varname
900 if (print)
901 *fLog << all << "Testing: " << cont->ClassName() << endl;
902 rc = cont->ReadEnv(env, cont->ClassName(), print);
903 if (rc==kERROR)
904 return kERROR;
905 if (rc==kTRUE)
906 continue;
907 }
908
909 return kTRUE;
910}
911
912// --------------------------------------------------------------------------
913//
914// Write the contents/setup of a parameter container/task to a TEnv
915// instance (steering card/setup file).
916// The key to search for in the file should be of the syntax:
917// prefix.vname
918// While vname is a name which is specific for a single setup date
919// (variable) of this container and prefix is something like:
920// evtloopname.name
921// While name is the name of the containers/tasks in the parlist/tasklist
922//
923// eg. Job4.MImgCleanStd.CleaningLevel1: 3.0
924// Job4.MImgCleanStd.CleaningLevel2: 2.5
925//
926// If this cannot be found the next step is to search for
927// MImgCleanStd.CleaningLevel1: 3.0
928// And if this doesn't exist, too, we search for:
929// CleaningLevel1: 3.0
930//
931// Warning: The programmer is responsible for the names to be unique in
932// all Mars classes.
933//
934Bool_t MParList::WriteEnv(TEnv &env, TString prefix, Bool_t print) const
935{
936 MParContainer *cont = NULL;
937
938 MIter Next(fContainer);
939 while ((cont=Next()))
940 if (!cont->WriteEnv(env, prefix, print))
941 return kFALSE;
942 return kTRUE;
943}
944
945// --------------------------------------------------------------------------
946//
947// Can be used to create an iterator over all containers, eg:
948// MParList plist;
949// TIter Next(plist); // Be aware: Use a object here rather than a pointer!
950// TObject *o=0;
951// while ((o=Next()))
952// {
953// [...]
954// }
955//
956MParList::operator TIterator*() const
957{
958 return new TOrdCollectionIter(fContainer);
959}
Note: See TracBrowser for help on using the repository browser.