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

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