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

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