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

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