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

Last change on this file since 890 was 890, checked in by tbretz, 23 years ago
*** empty log message ***
File size: 16.7 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 (tbretz@uni-sw.gwdg.de)
19!
20! Copyright: MAGIC Software Development, 2000-2001
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 <TNamed.h>
44#include <TClass.h>
45#include <TObjArray.h>
46
47#include "MLog.h"
48#include "MLogManip.h"
49
50ClassImp(MParList);
51
52// --------------------------------------------------------------------------
53//
54// default constructor
55// creates an empty list
56//
57MParList::MParList(const char *name, const char *title)
58{
59 *fName = name ? name : "MParList";
60 *fTitle = title ? title : "A list of Parameter Containers";
61
62 //
63 // This sets a flag that the list is the owner, which means
64 // that the destructor of the list deletes all it's objects
65 //
66 fAutodelete.SetOwner();
67}
68
69// --------------------------------------------------------------------------
70//
71// copy constructor
72//
73MParList::MParList(MParList &ts)
74{
75 fContainer.AddAll(&ts.fContainer);
76}
77
78// --------------------------------------------------------------------------
79//
80// create the Iterator over the tasklist
81//
82void MParList::SetLogStream(MLog *log)
83{
84 TIter Next(&fContainer);
85
86 MParContainer *cont=NULL;
87
88 //
89 // loop over all tasks for preproccesing
90 //
91 while ( (cont=(MParContainer*)Next()) )
92 cont->SetLogStream(log);
93
94 MParContainer::SetLogStream(log);
95}
96
97// --------------------------------------------------------------------------
98//
99// Add an Container to the list.
100//
101// If 'where' is given, the object will be added after this.
102//
103Bool_t MParList::AddToList(MParContainer *cont, MParContainer *where)
104{
105 //
106 // check if the object (you want to add) exists
107 //
108
109 if (!cont)
110 return kFALSE;
111
112 //
113 // Get Name of new container
114 //
115 const char *name = cont->GetName();
116
117 //
118 // Check if the new container is already existing in the list
119 //
120 const TObject *objn = fContainer.FindObject(name);
121 const TObject *objt = fContainer.FindObject(cont);
122
123 if (objn || objt)
124 {
125 //
126 // If the container is already in the list ignore it.
127 //
128 if (objt || objn==cont)
129 {
130 *fLog << dbginf << "Warning: Container '" << cont->GetName() << ", 0x" << (void*)cont;
131 *fLog << "' already existing in '" << GetName() << "'... ignoring." << endl;
132 return kTRUE;
133 }
134
135 //
136 // Otherwise add it to the list, but print a warning message
137 //
138 *fLog << dbginf << "Warning: Container with the same name '" << cont->GetName();
139 *fLog << "' already existing in '" << GetName() << "'." << endl;
140 *fLog << "You may not be able to get a pointer to container task by name." << endl;
141 }
142
143 //
144 // check if you want to add the new parameter container somewhere
145 // special (in that case you specify "where")
146 //
147 if (where)
148 {
149 if (!fContainer.FindObject(where))
150 {
151 *fLog << dbginf << "Error: Cannot find parameter container after which the new one should be added!" << endl;
152 return kFALSE;
153 }
154 }
155
156 *fLog << "Adding " << name << " to " << GetName() << "... " << flush;
157
158 fContainer.Add(cont);
159 *fLog << "Done." << endl;
160
161 return kTRUE;
162}
163
164// --------------------------------------------------------------------------
165//
166// Add all entries of the TObjArray to the list.
167//
168void MParList::AddToList(TObjArray *list)
169{
170 //
171 // check if the object (you want to add) exists
172 //
173 if (!list)
174 return;
175
176 TObjArrayIter Next(list);
177
178 MParContainer *cont = NULL;
179 while ((cont=(MParContainer*)Next()))
180 {
181 //
182 // Get Name of new container
183 //
184 const char *name = cont->GetName();
185
186 //
187 // Check if the new container is already existing in the list
188 //
189 const TObject *objn = fContainer.FindObject(name);
190 const TObject *objt = fContainer.FindObject(cont);
191
192 if (objn || objt)
193 {
194 //
195 // If the container is already in the list ignore it.
196 //
197 if (objt || objn==cont)
198 {
199 *fLog << dbginf << "Warning: Container '" << cont->GetName() << ", 0x" << (void*)cont;
200 *fLog << "' already existing in '" << GetName() << "'... ignoring." << endl;
201 continue;
202 }
203
204 //
205 // Otherwise add it to the list, but print a warning message
206 //
207 *fLog << dbginf << "Warning: Container with the same name '" << cont->GetName();
208 *fLog << "' already existing in '" << GetName() << "'." << endl;
209 *fLog << "You may not be able to get a pointer to container task by name." << endl;
210 }
211
212 *fLog << "Adding " << name << " to " << GetName() << "... " << flush;
213
214 fContainer.Add(cont);
215
216 *fLog << "Done." << endl;
217 }
218}
219
220// --------------------------------------------------------------------------
221//
222// Find an object in the list.
223// 'name' is the name of the object you are searching for.
224//
225TObject *MParList::FindObject(const char *name) const
226{
227 return fContainer.FindObject(name);
228}
229
230// --------------------------------------------------------------------------
231//
232// check if the object is in the list or not
233//
234TObject *MParList::FindObject(TObject *obj) const
235{
236 return fContainer.FindObject(obj);
237}
238
239// --------------------------------------------------------------------------
240//
241// returns the ClassName without anything which is behind that last ';' in
242// string.
243//
244TString MParList::GetClassName(const char *classname)
245{
246 TString cname(classname);
247 const char *semicolon = strrchr(cname, ';');
248
249 if (semicolon)
250 cname.Remove(semicolon-cname);
251
252 return cname;
253}
254
255// --------------------------------------------------------------------------
256//
257// returns the ObjectName. It is created from a class and object name.
258// If no object name is given the objectname is the same than the
259// class name. Leading dots are removed from the object name
260//
261TString MParList::GetObjectName(const char *classname, const char *objname)
262{
263 TString cname(classname);
264 const char *semicolon = strrchr(cname, ';');
265
266 TString oname(objname ? objname : classname);
267
268 if (semicolon)
269 {
270 //
271 // Remove leading dots from objectname (eg. "MMcTrig;5.")
272 //
273 Int_t sz = oname.Sizeof()-2;
274
275 while (sz>=0 && oname[sz]=='.')
276 oname.Remove(sz--);
277 }
278 return oname;
279}
280
281// --------------------------------------------------------------------------
282//
283// Find an object in the list.
284// 'name' is the name of the object you are searching for.
285// If the object doesn't exist we try to create one from the
286// dictionary. If this isn't possible NULL is returned.
287//
288// An object which was created automatically is deleted automatically in
289// the destructor of the parameter list, too. This means, that if an
290// object should survive (eg. Histograms) you MUST create it by yourself
291// and add it to the parameter list.
292//
293// By default (you don't specify an object name) the object name is
294// the same as the classname
295//
296// If the classname (default classname) is of the structure
297// "Name;something" - containing a semicolon - evarything which is
298// after the last appearance of a semicolon is stripped to get the
299// Name of the Class. Normally this is used to number your objects.
300// "Name;1", "Name;2", ... If a semicolon is detected leading dots
301// are stripped from the object-name (eg. "name;5.")
302//
303MParContainer *MParList::FindCreateObj(const char *classname, const char *objname)
304{
305 //
306 // If now object name (name of the object to identify it in the
307 // List) is given use it's classname as the objectname
308 //
309
310 //
311 // Check if the classname is a 'numbered' name (like: "MTime;2")
312 // if so strip the number from the classname.
313 //
314 // Becareful: We check for the last occurance of a ';' only and we
315 // also don't check if a number follows or something else.
316 //
317 // Rem: I use a TString to make the code more readyble and to get
318 // the new object deleted automatically
319 //
320 TString cname = GetClassName(classname);
321 TString oname = GetObjectName(classname, objname);
322
323 //
324 // Try to find a object with this object name which is already
325 // in the List. If we can find one we are done.
326 //
327 MParContainer *pcont = (MParContainer*)FindObject(oname);
328
329 if (pcont)
330 return pcont;
331
332 //
333 // if object is not existing in the list try to create one
334 //
335 *fLog << dbginf << "Object '" << oname << "' of type '" << cname << "' not found... creating." << endl;
336
337 //
338 // try to get class from root environment
339 //
340 TClass *cls = gROOT->GetClass(cname);
341
342 if (!cls)
343 {
344 //
345 // if class is not existing in the root environment
346 //
347 *fLog << dbginf << "Class '" << cname << "' not existing in dictionary." << endl;
348 return NULL;
349 }
350
351 //
352 // create the parameter container of the the given class type
353 //
354 pcont = (MParContainer*)cls->New();
355
356 //
357 // Set the name of the container
358 //
359 pcont->SetName(oname);
360
361 //
362 // Now add the object to the parameter list
363 //
364 AddToList(pcont);
365
366 //
367 // The object was automatically created. This makes sure, that such an
368 // object is deleted together with the list
369 //
370 fAutodelete.Add(pcont);
371
372 //
373 // Find an object in the list.
374 // 'name' is the name of the object you are searching for.
375 //
376 return pcont;
377}
378
379// --------------------------------------------------------------------------
380//
381// print some information about the current status of MParList
382//
383void MParList::Print(Option_t *t)
384{
385 *fLog << dbginf << "ParList: " << this->GetName() << " <" << this->GetTitle() << ">" << endl;
386 *fLog << endl;
387}
388
389// --------------------------------------------------------------------------
390//
391// Sets the flags off all containers in the list (and the list
392// itself) to unchanged
393//
394void MParList::SetReadyToSave(Bool_t flag)
395{
396 TIter Next(&fContainer);
397
398 MParContainer *cont=NULL;
399
400 //
401 // loop over all tasks for preproccesing
402 //
403 while ( (cont=(MParContainer*)Next()) )
404 cont->SetReadyToSave(flag);
405
406 MParContainer::SetReadyToSave(flag);
407}
408
409// --------------------------------------------------------------------------
410//
411// Reset all containers in the list
412//
413void MParList::Reset()
414{
415 TIter Next(&fContainer);
416
417 MParContainer *cont=NULL;
418
419 //
420 // loop over all tasks for preproccesing
421 //
422 while ((cont=(MParContainer*)Next()))
423 cont->Reset();
424}
425
426// --------------------------------------------------------------------------
427//
428// This finds numbered objects. The objects are returned in a copy of a
429// TObjArray.
430//
431// If from only is given (or to=0) object are assumed numbered
432// from 1 to from.
433//
434TObjArray MParList::FindObjectList(const char *name, const UInt_t from, const UInt_t to) const
435{
436 TObjArray list;
437
438 if (to>0 && to<=from)
439 {
440 *fLog << dbginf << "Cannot create entries backwards (to<from)...skipped." << endl;
441 return list;
442 }
443
444 const UInt_t len = strlen(name);
445
446 char *auxname = new char[len+7];
447 strcpy(auxname, name);
448
449 //
450 // If only 'from' is specified the number of entries are ment
451 //
452 const Bool_t exc = from>0 && to==0;
453
454 const UInt_t first = exc ? 0 : from;
455 const UInt_t last = exc ? from : to;
456
457 for (UInt_t num=first; num<last; num++)
458 {
459 if (from!=0 || to!=0)
460 sprintf(auxname+len, ";%d", num+1);
461
462 TObject *obj = FindObject(auxname);
463 if (!obj)
464 continue;
465
466 list.AddLast(obj);
467 }
468 delete auxname;
469
470 return list;
471}
472
473// --------------------------------------------------------------------------
474//
475// This finds numbered objects. The objects are returned in a copy of a
476// TObjArray. If one of the objects doesn't exist it is created from the
477// meaning of cname and oname (s. FindCreateObj)
478//
479// If from only is given (or to=0) object are assumed numbered
480// from 1 to from.
481//
482TObjArray MParList::FindCreateObjList(const char *cname, const UInt_t from, const UInt_t to, const char *oname)
483{
484 TObjArray list;
485
486 if (to>0 && to<=from)
487 {
488 *fLog << dbginf << "Cannot create entries backwards (to<from)...skipped." << endl;
489 return list;
490 }
491
492 const UInt_t len = strlen(cname);
493
494 char *auxname = new char[len+7];
495 strcpy(auxname, cname);
496
497 //
498 // If only 'from' is specified the number of entries are ment
499 //
500 const Bool_t exc = from>0 && to==0;
501
502 const UInt_t first = exc ? 0 : from;
503 const UInt_t last = exc ? from : to;
504
505 for (UInt_t num=first; num<last; num++)
506 {
507 if (from!=0 || to!=0)
508 sprintf(auxname+len, ";%d", num+1);
509
510 TObject *obj = FindCreateObj(auxname, oname);
511 if (!obj)
512 break;
513
514 list.AddLast(obj);
515 }
516 delete auxname;
517
518 return list;
519}
520
521// --------------------------------------------------------------------------
522//
523// This finds numbered objects. The objects are returned in a copy of a
524// TObjArray. If one of the objects doesn't exist it is created from the
525// meaning of cname and oname (s. FindCreateObj)
526//
527// If from only is given (or to=0) object are assumed numbered
528// from 1 to from.
529//
530// Remark: Because it is static the object are only created and not added to
531// the parameter list. You must also take care of deleting these objects!
532// This function is mainly made for use in root macros. Don't use it in
533// compiled programs if you are not 100% sure what you are doing.
534//
535TObjArray MParList::CreateObjList(const char *cname, const UInt_t from, const UInt_t to=0, const char *oname=NULL)
536{
537 TObjArray list;
538
539 //
540 // try to get class from root environment
541 //
542 TClass *cls = gROOT->GetClass(cname);
543
544 if (!cls)
545 {
546 //
547 // if class is not existing in the root environment
548 //
549 gLog << dbginf << "Class '" << cname << "' not existing in dictionary." << endl;
550 return list;
551 }
552
553 const UInt_t len = strlen(cname);
554
555 char *auxname = new char[len+7];
556 strcpy(auxname, cname);
557
558 //
559 // If only 'from' is specified the number of entries are ment
560 //
561 const Bool_t exc = from>0 && to==0;
562
563 const UInt_t first = exc ? 0 : from;
564 const UInt_t last = exc ? from : to;
565
566 for (UInt_t num=first; num<last; num++)
567 {
568 if (from!=0 || to!=0)
569 sprintf(auxname+len, ";%d", num+1);
570
571 //
572 // create the parameter container of the the given class type
573 //
574 MParContainer *pcont = (MParContainer*)cls->New();
575
576 //
577 // Set the name of the container
578 //
579 pcont->SetName(auxname);
580
581 //
582 // Add new object to the return list
583 //
584 list.AddLast(pcont);
585 }
586 delete auxname;
587
588 return list;
589}
Note: See TracBrowser for help on using the repository browser.