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

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