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

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