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

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