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

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