source: trunk/MagicSoft/Mars/mbase/MStatusArray.cc@ 8930

Last change on this file since 8930 was 8484, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 11.9 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 03/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MStatusArray
28//
29// Helper class for MStatusDisplay
30//
31// If you want to read a MStatusArray (normally with name MStatusDisplay)
32// it is recommended to do it like this:
33// TFile f("myfile.root", "read");
34// MStatusArray arr;
35// arr.Read();
36//
37// If you want to use TFile::Get or TFile::GetObject you should switch off
38// addding Histograms automatically to the current directory first:
39// TFile f("myfile.root", "read");
40// TH1::AddDirectory(kFALSE);
41// f.Get("MStatusDisplay");
42//
43//////////////////////////////////////////////////////////////////////////////
44#include "MStatusArray.h"
45
46#include <TH1.h> // TH1::AddDirectoryStatus();
47#include <TClass.h>
48#include <TCanvas.h>
49
50#include "MLog.h"
51#include "MLogManip.h"
52
53#include "MStatusDisplay.h"
54
55ClassImp(MStatusArray);
56
57using namespace std;
58
59// --------------------------------------------------------------------------
60//
61// If o==NULL a new status display is created, otherwise the one with name o
62// is searched in gROOT->GetListOfSpecials().
63// In this display the contents of the MStatusArray is displayed.
64//
65TObject *MStatusArray::DisplayIn(Option_t *o) const
66{
67 MStatusDisplay *d = 0;
68 if (TString(o).IsNull())
69 d = new MStatusDisplay;
70
71 if (!d)
72 d = (MStatusDisplay*)gROOT->GetListOfSpecials()->FindObject(o);
73
74 if (!d)
75 return 0;
76
77 if (d->Display(*this))
78 return d;
79
80 delete d;
81 return 0;
82}
83
84// --------------------------------------------------------------------------
85//
86// Display the contents of the given tab in the display given as argument.
87//
88void MStatusArray::DisplayIn(MStatusDisplay &d, const char *tab) const
89{
90 d.Display(*this, tab);
91}
92
93TObject *MStatusArray::FindObjectInPad(TVirtualPad *pad, const char *object, TClass *cls) const
94{
95 TObject *o = NULL;//pad->FindObject(object);
96// if (o && o->InheritsFrom(cls))
97// return o;
98
99 TIter Next(pad->GetListOfPrimitives());
100 while ((o=Next()))
101 {
102 if (o->GetName()==(TString)object && o->InheritsFrom(cls))
103 return o;
104
105 if (o==pad || !o->InheritsFrom(TVirtualPad::Class()))
106 continue;
107
108 if ((o = FindObjectInPad((TVirtualPad*)o, object, cls)))
109 return o;
110// if (o->InheritsFrom(cls))
111// return o;
112 }
113 return 0;
114}
115
116// FIXME: Move to a general class MMARS (TROOT) and unify with MParContainer
117TClass *MStatusArray::GetClass(const char *name) const
118{
119 TClass *cls = gROOT->GetClass(name);
120 Int_t rc = 0;
121 if (!cls)
122 rc =1;
123 else
124 {
125 if (!cls->Property())
126 rc = 5;
127 if (!cls->Size())
128 rc = 4;
129 if (!cls->IsLoaded())
130 rc = 3;
131 if (!cls->HasDefaultConstructor())
132 rc = 2;
133 }
134
135 if (rc==0)
136 return cls;
137
138 gLog << err << dbginf << "Class '" << name << "' not in dictionary: ";
139 switch (rc)
140 {
141 case 1:
142 gLog << "gROOT->GetClass() returned NULL." << endl;
143 return NULL;
144 case 2:
145 gLog << "no default constructor." << endl;
146 return NULL;
147 case 3:
148 gLog << "not loaded." << endl;
149 return NULL;
150 case 4:
151 gLog << "zero size." << endl;
152 return NULL;
153 case 5:
154 gLog << "no property." << endl;
155 return NULL;
156 }
157
158 gLog << "THIS SHOULD NEVER HAPPEN!" << endl;
159
160 return 0;
161}
162
163TCanvas *MStatusArray::FindCanvas(const char *name) const
164{
165 TObject *o = TObjArray::FindObject(name);
166 if (!o)
167 return 0;
168
169 return o->InheritsFrom(TCanvas::Class()) ? (TCanvas*)o : 0;
170}
171
172
173TObject *MStatusArray::FindObjectInCanvas(const char *object, const char *base, const char *canvas) const
174{
175 TClass *cls = GetClass(base);
176 if (!cls)
177 return 0;
178
179 TCanvas *c = canvas ? FindCanvas(canvas) : 0;
180 if (canvas)
181 {
182 if (!c)
183 {
184 gLog << warn << "Canvas '" << canvas << "' not found..." << endl;
185 return 0;
186 }
187
188 TObject *o = FindObjectInPad(c, object, cls);
189 if (!o)
190 {
191 gLog << warn << "Object '" << object << "' [" << base << "] not found in canvas '" << canvas << "'..." << endl;
192 return 0;
193 }
194
195 return o; //o->InheritsFrom(cls) ? o : 0;
196 }
197
198 TObject *o=0;
199 TIter Next(this);
200 while ((o=Next()))
201 {
202 if (!o->InheritsFrom(TVirtualPad::Class()))
203 continue;
204
205 if ((o=FindObjectInPad((TVirtualPad*)c, object, cls)))
206 return o;
207 }
208
209 gLog << warn << "Object '" << object << "' [" << base << "] not found in canvas '" << canvas << "'..." << endl;
210 return NULL;
211}
212
213TObject *MStatusArray::FindObjectInCanvas(const char *object, const char *canvas) const
214{
215 return FindObjectInCanvas(object, object, canvas);
216}
217
218TObject *MStatusArray::FindObject(const char *object, const char *base) const
219{
220 return FindObjectInCanvas(object, base, 0);
221}
222
223TObject *MStatusArray::FindObject(const char *object) const
224{
225 return FindObjectInCanvas(object, object, 0);
226}
227
228// --------------------------------------------------------------------------
229//
230// Print recursively all objects in this and sub-pads
231//
232void MStatusArray::PrintObjectsInPad(const TCollection *list, const TString &name, Int_t lvl) const
233{
234 TIter Next(list);
235 TObject *o=0;
236 while ((o=Next()))
237 {
238 const Bool_t print = name.IsNull() || name==(TString)o->GetName();
239 if (print)
240 {
241 if (lvl>0)
242 gLog << setw(lvl) << ' ';
243 gLog << " " << o->ClassName() << ": " << o->GetName() << " <" << Next.GetOption() << "> (" << o << ") " << (int)o->TestBit(kCanDelete) << endl;
244 }
245
246 if (o->InheritsFrom(TVirtualPad::Class()))
247 PrintObjectsInPad(((TVirtualPad*)o)->GetListOfPrimitives(), print?TString():name, lvl+1);
248 }
249}
250
251// --------------------------------------------------------------------------
252//
253// Print recursively all objects in this and sub-pads. If !option.IsNull()
254// only objects in the corresponding pad are printed.
255//
256void MStatusArray::Print(Option_t *option) const
257{
258 const TString opt(option);
259
260 PrintObjectsInPad(this, opt);
261}
262
263/*
264// --------------------------------------------------------------------------
265//
266// Make sure that kCanDelete is properly set for all directly contained
267// objects. Some kCanDelete bits might not be properly set or get lost when
268// the MParContainer is stored.
269//
270void MStatusArray::SetCanDelete(const TCollection *list) const
271{
272 TIter Next(list);
273 TObject *o=0;
274 while ((o=Next()))
275 {
276 if (o->InheritsFrom(TVirtualPad::Class()))
277 SetCanDelete(((TVirtualPad*)o)->GetListOfPrimitives());
278 else
279 o->SetBit(kCanDelete|kMustCleanup);
280 }
281}
282*/
283
284// --------------------------------------------------------------------------
285//
286// Set kCanDelete for all objects for which kMyCanDelete is set. This
287// is a STUPID workaruond for an ANNOYING root bug which is that
288// the streamer function of TH1 resets the KCanDelete bit after reading.
289//
290void MStatusArray::SetCanDelete(const TCollection *list) const
291{
292 TIter Next(list);
293 TObject *o=0;
294 while ((o=Next()))
295 {
296 if (o->InheritsFrom(TVirtualPad::Class()))
297 SetCanDelete(((TVirtualPad*)o)->GetListOfPrimitives());
298 else
299 {
300 if (o->TestBit(kMyCanDelete) && o->InheritsFrom("TH1"))
301 {
302 o->SetBit(kCanDelete);
303 o->ResetBit(kMyCanDelete);
304 }
305 }
306 }
307}
308
309void MStatusArray::EnableTH1Workaround(const TCollection *list) const
310{
311 TIter Next(list?list:this);
312 TObject *o=0;
313 while ((o=Next()))
314 {
315 if (o->InheritsFrom(TVirtualPad::Class()))
316 EnableTH1Workaround(((TVirtualPad*)o)->GetListOfPrimitives());
317 else
318 if (o->InheritsFrom("TH1"))
319 o->SetBit(kCanDelete);
320 }
321}
322
323// --------------------------------------------------------------------------
324//
325// Set kMyCanDelete for all objects for which kCanDelete is set. This
326// is a STUPID workaruond for an ANNOYING root bug which is that
327// the streamer function of TH1 resets the KCanDelete bit after reading.
328//
329void MStatusArray::SetMyCanDelete(const TCollection *list) const
330{
331 TIter Next(list);
332 TObject *o=0;
333 while ((o=Next()))
334 {
335 if (o->InheritsFrom(TVirtualPad::Class()))
336 SetMyCanDelete(((TVirtualPad*)o)->GetListOfPrimitives());
337 else
338 {
339 if (o->TestBit(kMyCanDelete) && o->InheritsFrom("TH1"))
340 gLog << warn << "WARNING - MStatusArray::Write - " << o->GetName() << " [" << o->ClassName() << "] has BIT(30) already set!" << endl;
341
342 if (o->TestBit(kCanDelete) && o->InheritsFrom("TH1"))
343 o->SetBit(kMyCanDelete);
344 }
345 }
346}
347
348// --------------------------------------------------------------------------
349//
350// Reset kMyCanDelete for all objects for which kMyCanDelete is set. This
351// is a STUPID workaruond for an ANNOYING root bug which is that
352// the streamer function of TH1 resets the KCanDelete bit after reading.
353//
354void MStatusArray::ResetMyCanDelete(const TCollection *list) const
355{
356 TIter Next(list);
357 TObject *o=0;
358 while ((o=Next()))
359 {
360 if (o->InheritsFrom(TVirtualPad::Class()))
361 ResetMyCanDelete(((TVirtualPad*)o)->GetListOfPrimitives());
362 else
363 {
364 if (o->TestBit(kMyCanDelete) && o->InheritsFrom("TH1"))
365 o->ResetBit(kMyCanDelete);
366 }
367 }
368}
369
370// --------------------------------------------------------------------------
371//
372// Switch off adding histograms to current directory before reading.
373// Switch back
374//
375Int_t MStatusArray::Read(const char *name)
376{
377 // It seems that the contents are not properly deleted by TObjArray::Read
378 Delete();
379
380 // Make sure newly read histograms are not added to the current directory
381 const Bool_t store = TH1::AddDirectoryStatus();
382 TH1::AddDirectory(kFALSE);
383 const Int_t rc = TObjArray::Read(name?name:"MStatusDisplay");
384 TH1::AddDirectory(store);
385
386 // All objects in the list (TNamed, TCanvas, etc) do not have
387 // the kCanDelete bit set. Make sure that it is set to make
388 // them deleted by the destructor of this list
389 TIter Next(this);
390 TObject *o=0;
391 while ((o=Next()))
392 {
393 if (o->InheritsFrom(TVirtualPad::Class()))
394 {
395 TIter Next2(((TVirtualPad*)o)->GetListOfPrimitives());
396 TObject *o2=0;
397 while ((o2=Next2()))
398 if (o2->InheritsFrom("MParContainer"))
399 o2->SetBit(kCanDelete);
400 }
401 o->SetBit(kCanDelete);
402 }
403
404 // Make sure that all kCanDelete bits are properly set
405 SetCanDelete(this);
406 SetOwner();
407
408 return rc;
409}
410
411// --------------------------------------------------------------------------
412//
413// Switch off adding histograms to current directory before reading.
414// Switch back
415//
416Int_t MStatusArray::Write(const char *name, Int_t option, Int_t bufsize) const
417{
418 SetMyCanDelete(this);
419 const Int_t rc = TObjArray::Write(name, option, bufsize);
420 ResetMyCanDelete(this);
421
422 return rc;
423}
Note: See TracBrowser for help on using the repository browser.