source: trunk/MagicSoft/Mars/mbase/MParContainer.cc@ 1376

Last change on this file since 1376 was 1299, checked in by tbretz, 23 years ago
*** empty log message ***
File size: 10.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 <mailto:tbretz@uni-sw.gwdg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2002
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26// //
27// MParContainer //
28// //
29// The MParContainer class is the base class for all MARS parameter //
30// containers. At the moment it is almost the same than ROOT's TNamed. //
31// A TNamed contains the essential elements (name, title) //
32// to identify a derived object in lists like our MParList or MTaskList. //
33// The main difference is that the name and title isn't stored and read //
34// to and from root files ("//!") //
35// //
36//////////////////////////////////////////////////////////////////////////////
37#include "MParContainer.h"
38
39#include <fstream.h> // ofstream, AsciiWrite
40
41#include <TClass.h> // IsA
42#include <TBaseClass.h> // GetClassPointer
43#include <TROOT.h> // TROOT::Identlevel
44#include <TMethodCall.h> // TMethodCall, AsciiWrite
45#include <TDataMember.h> // TDataMember, AsciiWrite
46#include <TVirtualPad.h> // gPad
47
48#include "MLog.h"
49#include "MLogManip.h"
50
51ClassImp(MParContainer);
52
53// --------------------------------------------------------------------------
54//
55// MParContainer copy ctor
56//
57MParContainer::MParContainer(const MParContainer &named)
58{
59 fName = named.fName;
60 fTitle = named.fTitle;
61
62 fLog = named.fLog;
63
64 fReadyToSave = named.fReadyToSave;
65}
66
67// --------------------------------------------------------------------------
68//
69// MParContainer assignment operator.
70//
71MParContainer& MParContainer::operator=(const MParContainer& rhs)
72{
73 if (this == &rhs)
74 return *this;
75
76 TObject::operator=(rhs);
77
78 fName = rhs.fName;
79 fTitle = rhs.fTitle;
80
81 fLog = rhs.fLog;
82 fReadyToSave = rhs.fReadyToSave;
83
84 return *this;
85}
86
87// --------------------------------------------------------------------------
88//
89// Make a clone of an object using the Streamer facility.
90// If newname is specified, this will be the name of the new object
91//
92TObject *MParContainer::Clone(const char *newname) const
93{
94
95 MParContainer *named = (MParContainer*)TObject::Clone();
96 if (newname && strlen(newname)) named->SetName(newname);
97 return named;
98}
99
100// --------------------------------------------------------------------------
101//
102// Compare two MParContainer objects. Returns 0 when equal, -1 when this is
103// smaller and +1 when bigger (like strcmp).
104//
105Int_t MParContainer::Compare(const TObject *obj) const
106{
107 if (this == obj) return 0;
108 return fName.CompareTo(obj->GetName());
109}
110
111// --------------------------------------------------------------------------
112//
113// Copy this to obj.
114//
115void MParContainer::Copy(TObject &obj)
116{
117 MParContainer &cont = (MParContainer&)obj;
118
119 TObject::Copy(obj);
120
121 cont.fName = fName;
122 cont.fTitle = fTitle;
123
124 cont.fLog = fLog;
125 cont.fReadyToSave = fReadyToSave;
126}
127
128// --------------------------------------------------------------------------
129//
130// Encode MParContainer into output buffer.
131//
132void MParContainer::FillBuffer(char *&buffer)
133{
134 fName.FillBuffer(buffer);
135 fTitle.FillBuffer(buffer);
136}
137
138// --------------------------------------------------------------------------
139//
140// List MParContainer name and title.
141//
142void MParContainer::ls(Option_t *) const
143{
144 TROOT::IndentLevel();
145 *fLog << all << GetDescriptor() << " " << GetTitle() << ": kCanDelete=";
146 *fLog << Int_t(TestBit(kCanDelete)) << endl;
147}
148
149// --------------------------------------------------------------------------
150//
151// Print MParContainer name and title.
152//
153void MParContainer::Print(Option_t *) const
154{
155 *fLog << all << GetDescriptor() << " " << GetTitle() << endl;
156}
157
158// --------------------------------------------------------------------------
159//
160// Change (i.e. set) the name of the MParContainer.
161// WARNING !!
162// If the object is a member of a THashTable, THashList container
163// The HashTable must be Rehashed after SetName
164// For example the list of objects in the current directory is a THashList
165//
166void MParContainer::SetName(const char *name)
167{
168 fName = name;
169 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
170}
171
172// --------------------------------------------------------------------------
173//
174// Change (i.e. set) all the MParContainer parameters (name and title).
175// See also WARNING in SetName
176//
177void MParContainer::SetObject(const char *name, const char *title)
178{
179 fName = name;
180 fTitle = title;
181 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
182}
183
184// --------------------------------------------------------------------------
185//
186// Change (i.e. set) the title of the MParContainer.
187//
188void MParContainer::SetTitle(const char *title)
189{
190 fTitle = title;
191 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
192}
193
194// --------------------------------------------------------------------------
195//
196// Return size of the MParContainer part of the TObject.
197//
198Int_t MParContainer::Sizeof() const
199{
200 Int_t nbytes = fName.Sizeof() + fTitle.Sizeof();
201 return nbytes;
202}
203
204// --------------------------------------------------------------------------
205//
206// If you want to use Ascii-Input/-Output (eg. MWriteAsciiFile) of a
207// container, overload this function.
208//
209void MParContainer::AsciiRead(ifstream &fin)
210{
211 *fLog << warn << "To use the the ascii input of " << GetName();
212 *fLog << " you have to overload " << ClassName() << "::AsciiRead." << endl;
213}
214
215// --------------------------------------------------------------------------
216//
217// Write out a data member given as a TDataMember object to an output stream.
218//
219Bool_t MParContainer::WriteDataMember(ostream &out, const TDataMember *member, Double_t scale) const
220{
221 if (!member)
222 return kFALSE;
223
224 if (!member->IsPersistent() || member->Property()&kIsStatic)
225 return kFALSE;
226
227 /*const*/ TMethodCall *call = ((TDataMember*)member)->GetterMethod(); //FIXME: Root
228 if (!call)
229 {
230 *fLog << warn << "Sorry, no getter method found for " << member->GetName() << endl;
231 return kFALSE;
232 }
233
234 // For debugging: out << member->GetName() << ":";
235
236 switch (call->ReturnType())
237 {
238 case TMethodCall::kLong:
239 Long_t l;
240 call->Execute((void*)this, l); // FIXME: const, root
241 out << l << " ";
242 return kTRUE;
243
244 case TMethodCall::kDouble:
245 Double_t d;
246 call->Execute((void*)this, d); // FIXME: const, root
247 out << (scale*d) << " ";
248 return kTRUE;
249
250 default:
251 //case TMethodCall::kString:
252 //case TMethodCall::kOther:
253 /* someone may want to enhance this? */
254 return kFALSE;
255 }
256}
257
258// --------------------------------------------------------------------------
259//
260// Write out a data member given by name to an output stream.
261//
262Bool_t MParContainer::WriteDataMember(ostream &out, const char *member, Double_t scale) const
263{
264 /*const*/ TClass *cls = IsA()->GetBaseDataMember(member);
265 if (!cls)
266 return kFALSE;
267
268 return WriteDataMember(out, cls->GetDataMember(member), scale);
269}
270
271// --------------------------------------------------------------------------
272//
273// Write out a data member from a given TList of TDataMembers.
274// returns kTRUE when at least one member was successfully written
275//
276Bool_t MParContainer::WriteDataMember(ostream &out, const TList *list) const
277{
278 Bool_t rc = kFALSE;
279
280 TDataMember *data = NULL;
281
282 TIter Next(list);
283 while ((data=(TDataMember*)Next()))
284 rc |= WriteDataMember(out, data);
285
286 return rc;
287}
288
289// --------------------------------------------------------------------------
290//
291// If you want to use Ascii-Input/-Output (eg. MWriteAsciiFile) of a
292// container, you may overload this function. If you don't overload it
293// the data member of a class are written to the file in the order of
294// appearance in the class header (be more specfic: root dictionary)
295// Only data members which are of integer (Bool_t, Int_t, ...) or
296// floating point (Float_t, Double_t, ...) type are written.
297// returns kTRUE when at least one member was successfully written
298//
299Bool_t MParContainer::AsciiWrite(ostream &out) const
300{
301 // *fLog << warn << "To use the the ascii output of " << GetName();
302 // *fLog << " you have to overload " << ClassName() << "::AsciiWrite." << endl;
303
304 Bool_t rc = WriteDataMember(out, IsA()->GetListOfDataMembers());
305
306 TIter NextBaseClass(IsA()->GetListOfBases());
307 TBaseClass *base;
308 while ((base = (TBaseClass*) NextBaseClass()))
309 {
310 /*const*/ TClass *cls = base->GetClassPointer();
311
312 if (!cls)
313 continue;
314
315 if (cls->GetClassVersion())
316 rc |= WriteDataMember(out, cls->GetListOfDataMembers());
317 }
318
319 return rc;
320}
321
322TMethodCall *MParContainer::GetterMethod(const char *name) const
323{
324 TClass *cls = IsA()->GetBaseDataMember(name);
325 if (!cls)
326 {
327 *fLog << err << "'" << name << "' is neither a member of ";
328 *fLog << GetDescriptor() << " nor one of its base classes." << endl;
329 return NULL;
330 }
331
332 TDataMember *member = cls->GetDataMember(name);
333 if (!member)
334 {
335 *fLog << err << "Datamember '" << name << "' not in " << GetDescriptor() << endl;
336 return NULL;
337 }
338
339 TMethodCall *call = member->GetterMethod();
340 if (!call)
341 {
342 *fLog << err << "Sorry, no getter method found for " << name << endl;
343 return NULL;
344 }
345
346 return call;
347}
Note: See TracBrowser for help on using the repository browser.