GSI Object Oriented Online Offline (Go4)  GO4-5.3.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4Parameter.cxx
Go to the documentation of this file.
1 // $Id: TGo4Parameter.cxx 1442 2015-05-22 10:54:34Z linev $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum für Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4Parameter.h"
15 
16 #include <string.h>
17 #include <stdlib.h>
18 
19 #include "TList.h"
20 #include "TObjArray.h"
21 #include "TClass.h"
22 #include "TROOT.h"
23 #include "TUrl.h"
24 #include "TDataMember.h"
25 #include "TDataType.h"
26 #include "TBaseClass.h"
27 #include "TDatime.h"
28 #include "TArrayI.h"
29 #include "TArrayD.h"
30 
31 #include "TGo4Log.h"
32 #include "TGo4ParameterMember.h"
33 #include "TGo4ParameterStatus.h"
34 
36  TNamed()
37 {
38 }
39 
40 TGo4Parameter::TGo4Parameter(const char* name, const char* title) :
41  TNamed(name ? name : "Parameter", title)
42 {
43  GO4TRACE((12,"TGo4Parameter ::TGo4Parameter (const char*, const char*)",__LINE__, __FILE__));
44 }
45 
46 void TGo4Parameter::Print(Option_t* dummy) const
47 {
48  // this trick is needed since root defines Print as const function...
49  TGo4Parameter* const localthis= const_cast<TGo4Parameter* const>(this);
50  localthis->PrintParameter();
51 }
52 
53 Int_t TGo4Parameter::PrintParameter(Text_t* buffer, Int_t buflen)
54 {
55  GO4TRACE((12,"TGo4Parameter ::PrintParameter()",__LINE__, __FILE__));
56  //
57  if(buflen<=0 && buffer!=0) return 0;
58 
59  TObjArray items;
60  GetMemberValues(&items);
61 
62  Int_t size = 0;
63  TString localbuf = TString::Format("Parameter name: %s class %s\n", GetName(), ClassName());
64 
65  if(buffer==0) {
66  std::cout << localbuf;
67  } else {
68  size = localbuf.Length();
69  if(size>buflen) size = buflen;
70  strncpy(buffer, localbuf.Data(), size);
71  buflen -= size;
72  buffer += size;
73  }
74 
75  TIter iter(&items);
76  TGo4ParameterMember* info = 0;
77 
78  TROOT::IncreaseDirLevel();
79 
80  while ((info = (TGo4ParameterMember*) iter()) !=0 ) {
81  Int_t size1 = info->PrintMember(buffer, buflen);
82 
83  size += size1;
84  buflen -= size1;
85  buffer += size1;
86  }
87 
88  TROOT::DecreaseDirLevel();
89 
90  return size;
91 }
92 
94 {
95  GO4TRACE((12,"TGo4Parameter ::~TGo4Parameter ()",__LINE__, __FILE__));
96 }
97 
99 {
100  if (rhs==0) return kFALSE;
101 
102  if (rhs->IsA() != IsA()) {
103  std::cout << "GO4> !!! ERROR: Wrong parameter class is used in TGo4Parameter::UpdateFrom() method!!!" << std::endl;
104  std::cout << "GO4> !!! ERROR: One cannot update " << IsA()->GetName() << " class from " << rhs->IsA()->GetName() << std::endl;
105  std::cout << "GO4> !!! ERROR: Implement your custom UpdateFrom() method" << std::endl;
106  return kFALSE;
107  }
108 
109  TObjArray items;
110 
111  rhs->GetMemberValues(&items);
112 
113  return SetMemberValues(&items);
114 }
115 
116 Bool_t TGo4Parameter::UpdateFromUrl(const char* rest_url_opt)
117 {
118  TGo4Parameter* clone = (TGo4Parameter*) Clone();
119 
120  TObjArray items;
121  clone->GetMemberValues(&items);
122 
123  TUrl url;
124  url.SetOptions(rest_url_opt);
125 
126  TIter next(&items);
127  TGo4ParameterMember* member = 0;
128 
129  while ((member = (TGo4ParameterMember*) next()) != 0) {
130  TString dummy;
131  const char* optvalue = url.GetValueFromOptions(member->GetFullName(dummy)); //member->GetName());
132  if (optvalue!=0) {
133  TGo4Log::Info("Par:%s member %s newvalue %s", GetName(), member->GetFullName(dummy), optvalue);
134  member->SetStrValue(optvalue);
135  }
136  }
137 
138  clone->SetMemberValues(&items);
139 
140  Bool_t res = UpdateFrom(clone);
141  delete clone;
142  return res;
143 }
144 
145 
146 void TGo4Parameter::Clear(Option_t* opt)
147 {
148  // dummy clear, may be implemented by user
149  std::cout << "GO4> !!! Default TGo4Parameter::Clear() method is used." << std::endl;
150  std::cout << "GO4> !!! You probably need to overwrite Clear() method for your class" << IsA()->GetName() << std::endl;
151 
152  TObjArray items;
153 
154  GetMemberValues(&items);
155 
156  TIter iter(&items);
157  TGo4ParameterMember* info = 0;
158 
159  while ((info = (TGo4ParameterMember*) iter()) !=0 ) info->SetToZero();
160 
161  SetMemberValues(&items);
162 }
163 
164 void TGo4Parameter::GetMemberValues(TObjArray* fItems)
165 {
166  GetMemberValues(fItems, IsA(), (char*) this, 0);
167 }
168 
169 Bool_t TGo4Parameter::SetMemberValues(TObjArray* items)
170 {
171  if (items==0) return kFALSE;
172 
173  Int_t indx(0);
174 
175  return SetMemberValues(items, indx, IsA(), (char*) this, 0);
176 }
177 
178 
179 void TGo4Parameter::GetMemberValues(TObjArray* fItems, TClass* cl, char* ptr, unsigned long int cloffset)
180 {
181  if ((fItems==0) || (cl==0) || (ptr==0)) return;
182 
183  TIter iter(cl->GetListOfDataMembers());
184  Int_t lastmemberid = -1;
185  if (fItems->GetLast()>=0)
186  lastmemberid = ((TGo4ParameterMember*) fItems->Last())->GetMemberId();
187 
188  TObject* obj = 0;
189  while ((obj=iter()) != 0) {
190  TDataMember* member = dynamic_cast<TDataMember*>(obj);
191  if (member==0) continue;
192  const char* memtypename = member->GetFullTypeName();
193  Int_t memtypeid = 0;
194 
195  // do not edit IsA info
196  if(strcmp(memtypename,"TClass*")==0) continue;
197  // skip for a moment all types which are not basic types
198 
199  Int_t arraydim = member->GetArrayDim();
200  if (arraydim>2) continue;
201 
202  Int_t maxindex1(1), maxindex2(1);
203 
204  switch(arraydim) {
205  case 1:
206  maxindex1 = member->GetMaxIndex(0);
207  break;
208  case 2:
209  maxindex1 = member->GetMaxIndex(0);
210  maxindex2 = member->GetMaxIndex(1);
211  break;
212  } // switch()
213 
214  TArrayI* arri(0);
215  TArrayD* arrd(0);
216 
217  if (strcmp(memtypename,"TString")==0) {
219  } else
220  if (strcmp(memtypename,"TGo4Fitter*")==0) {
222  } else
223  if (strcmp(memtypename,"TArrayI")==0) {
224  memtypeid = kInt_t;
225  memtypename = "Int_t";
226  if ((maxindex1>1) || (maxindex2>1)) continue;
227  arri = (TArrayI*) (ptr + cloffset + member->GetOffset());
228  arraydim = 1;
229  maxindex1 = arri->GetSize();
230  maxindex2 = 1;
231  } else
232  if (strcmp(memtypename,"TArrayD")==0) {
233  memtypeid = kDouble_t;
234  memtypename = "Double_t";
235  if ((maxindex1>1) || (maxindex2>1)) continue;
236  arrd = (TArrayD*) (ptr + cloffset + member->GetOffset());
237  arraydim = 1;
238  maxindex1 = arrd->GetSize();
239  maxindex2 = 1;
240  } else {
241  if (!member->IsBasic()) continue;
242  memtypeid = member->GetDataType()->GetType();
243  }
244 
245  // add extra filed with array size
246  if (arri || arrd) {
247  TGo4ParameterMember* info = new TGo4ParameterMember(member->GetName(), member->GetTitle());
248 
249  info->SetMemberId(lastmemberid++);
250 
251  info->SetType("TArray", TGo4ParameterMember::kTArray_t);
252  info->SetVisible(kFALSE);
253  //info->SetArrayIndexes(0, 0, 0);
254  info->SetIntValue(maxindex1);
255 
256  fItems->Add(info);
257  }
258 
259  lastmemberid++;
260 
261  for(Int_t ix1=0;ix1<maxindex1;ix1++)
262  for(Int_t ix2=0;ix2<maxindex2;ix2++) {
263  TGo4ParameterMember* info = new TGo4ParameterMember(member->GetName(), member->GetTitle());
264  fItems->Add(info);
265 
266  info->SetMemberId(lastmemberid);
267 
268  info->SetType(memtypename, memtypeid);
269 
270  info->SetVisible((ix1==0) && (ix2==0));
271 
272  info->SetArrayIndexes(arraydim, ix1, ix2);
273 
274  char* addr = ptr + cloffset + member->GetOffset() + (ix1*maxindex2 + ix2) * member->GetUnitSize();
275  if (arri) addr = (char*) (arri->GetArray() + ix1);
276  if (arrd) addr = (char*) (arrd->GetArray() + ix1);
277 
278  info->SetValue(addr);
279  }
280  }
281 
282  // expand base classes
283  TIter cliter(cl->GetListOfBases());
284  while((obj=cliter()) !=0) {
285  TBaseClass* baseclass = dynamic_cast<TBaseClass*>(obj);
286  if (baseclass==0) continue;
287  TClass* bclass = baseclass->GetClassPointer();
288  if(bclass==0) continue;
289  if(strcmp(bclass->GetName(), "TGo4Parameter")==0) continue;
290  if(strcmp(bclass->GetName(), "TNamed")==0) continue;
291 
292  GetMemberValues(fItems, bclass, ptr, cloffset + baseclass->GetDelta());
293  }
294 }
295 
296 Int_t TGo4Parameter::FindArrayLength(TObjArray* items, Int_t& itemsindx, TDataMember* member)
297 {
298  TGo4ParameterMember* info = dynamic_cast<TGo4ParameterMember*> (items->At(itemsindx++));
299  if (info==0) return -1;
300  if (strcmp(info->GetName(), member->GetName())!=0) return -1;
301  if (strcmp(info->GetTitle(), member->GetTitle())!=0) return -1;
302  if (info->GetTypeId() != TGo4ParameterMember::kTArray_t) return -1;
303  return info->GetIntValue();
304 }
305 
306 
307 Bool_t TGo4Parameter::SetMemberValues(TObjArray* items, Int_t& itemsindx, TClass* cl, char* ptr, unsigned long int cloffset)
308 {
309  if ((items==0) || (cl==0) || (ptr==0)) return kFALSE;
310 
311  TIter iter(cl->GetListOfDataMembers());
312 
313  TObject* obj = 0;
314  while ((obj=iter()) != 0) {
315  TDataMember* member = dynamic_cast<TDataMember*>(obj);
316  if (member==0) continue;
317  const char* memtypename = member->GetFullTypeName();
318  Int_t memtypeid = 0;
319 
320  // do not edit IsA info
321  if(strcmp(memtypename,"TClass*")==0) continue;
322  // skip for a moment all types which are not basic types
323 
324  Int_t arraydim = member->GetArrayDim();
325  if (arraydim>2) continue;
326 
327  Int_t maxindex1(1), maxindex2(1);
328 
329  switch(arraydim) {
330  case 1:
331  maxindex1 = member->GetMaxIndex(0);
332  break;
333  case 2:
334  maxindex1 = member->GetMaxIndex(0);
335  maxindex2 = member->GetMaxIndex(1);
336  break;
337  } // switch()
338 
339  TArrayI* arri(0);
340  TArrayD* arrd(0);
341 
342  if (strcmp(memtypename,"TString")==0) {
344  } else
345  if (strcmp(memtypename,"TGo4Fitter*")==0) {
347  } else
348  if (strcmp(memtypename,"TArrayI")==0) {
349  memtypeid = kInt_t;
350  memtypename = "Int_t";
351  if ((maxindex1>1) || (maxindex2>1)) continue;
352  arri = (TArrayI*) (ptr + cloffset + member->GetOffset());
353  arraydim = 1;
354  maxindex1 = FindArrayLength(items, itemsindx, member); // here we need to define index ourself
355  maxindex2 = 1;
356  if (maxindex1<0) return kFALSE;
357  if (arri->GetSize()!=maxindex1) arri->Set(maxindex1);
358  } else
359  if (strcmp(memtypename,"TArrayD")==0) {
360  memtypeid = kDouble_t;
361  memtypename = "Double_t";
362  if ((maxindex1>1) || (maxindex2>1)) continue;
363  arrd = (TArrayD*) (ptr + cloffset + member->GetOffset());
364  arraydim = 1;
365  maxindex1 = FindArrayLength(items, itemsindx, member); // here we need to define index ourself
366  maxindex2 = 1;
367  if (maxindex1<0) return kFALSE;
368  if (arrd->GetSize()!=maxindex1) arrd->Set(maxindex1);
369  } else {
370  if (!member->IsBasic()) continue;
371  memtypeid = member->GetDataType()->GetType();
372  }
373 
374  for(Int_t ix1=0;ix1<maxindex1;ix1++)
375  for(Int_t ix2=0;ix2<maxindex2;ix2++) {
376  if (itemsindx>items->GetLast()) return kFALSE;
377  TGo4ParameterMember* info =
378  dynamic_cast<TGo4ParameterMember*> (items->At(itemsindx++));
379  if (info==0) return kFALSE;
380 
381  if (strcmp(info->GetName(), member->GetName())!=0) return kFALSE;
382  if (strcmp(info->GetTitle(), member->GetTitle())!=0) return kFALSE;
383 
384  if (strcmp(info->GetTypeName(), memtypename)!=0) return kFALSE;
385  if (info->GetTypeId() != memtypeid) return kFALSE;
386 
387  if (!info->CheckArrayIndexes(arraydim, ix1, ix2)) return kFALSE;
388 
389  char* addr = ptr + cloffset + member->GetOffset() + (ix1*maxindex2 + ix2) * member->GetUnitSize();
390  if (arri) addr = (char*) (arri->GetArray() + ix1);
391  if (arrd) addr = (char*) (arrd->GetArray() + ix1);
392 
393  info->GetValue(addr);
394  }
395  }
396 
397  // expand base classes
398  TIter cliter(cl->GetListOfBases());
399  while((obj=cliter()) !=0) {
400  TBaseClass* baseclass = dynamic_cast<TBaseClass*>(obj);
401  if (baseclass==0) continue;
402  TClass* bclass = baseclass->GetClassPointer();
403  if(bclass==0) continue;
404  if(strcmp(bclass->GetName(), "TGo4Parameter")==0) continue;
405  if(strcmp(bclass->GetName(), "TNamed")==0) continue;
406 
407  if (!SetMemberValues(items, itemsindx, bclass, ptr, cloffset + baseclass->GetDelta())) return kFALSE;
408  }
409 
410  return kTRUE;
411 }
412 
413 void TGo4Parameter::SavePrimitive(std::ostream& out, Option_t* opt)
414 {
415  static int cnt = 0;
416  TString varname = TString::Format("param%d", cnt++);
417  Bool_t savemacro = (opt!=0) && (strstr(opt,"savemacro")!=0);
418 
419  if (savemacro) {
420  out << Form(" %s* %s = (%s*) go4->GetParameter(\"%s\",\"%s\");",
421  ClassName(), varname.Data(), ClassName(), GetName(), ClassName()) << std::endl << std::endl;
422  out << Form(" if (%s==0) {", varname.Data()) << std::endl;
423  out << Form(" TGo4Log::Error(\"Could not find parameter %s of class %s\");", GetName(), ClassName()) << std::endl;
424  out << Form(" return;") << std::endl;
425  out << Form(" }") << std::endl << std::endl;
426  out << Form(" TGo4Log::Info(\"Set parameter %s as saved at %s\");", GetName(), TDatime().AsString()) << std::endl << std::endl;
427  } else {
428  out << Form(" %s* %s = new %s;", ClassName(), varname.Data(), ClassName()) << std::endl;
429  out << Form(" %s->SetName(\"%s\");", varname.Data(), GetName()) << std::endl;
430  out << Form(" %s->SetTitle(\"%s\");", varname.Data(), GetTitle()) << std::endl;
431  }
432 
433  TObjArray *fitems = new TObjArray();
434  fitems->SetOwner(kTRUE);
435  GetMemberValues(fitems);
436 
437  TIter iter(fitems);
438  TGo4ParameterMember* info = 0;
439 
440  while ((info = (TGo4ParameterMember*) iter()) !=0 ) {
441  if (info->GetTypeId()==TGo4ParameterMember::kTGo4Fitter_t) continue;
442 
443  TString membername;
444  info->GetFullName(membername);
445 
446  switch (info->GetTypeId()) {
448  out << Form(" %s->%s = \"%s\";", varname.Data(), membername.Data(), info->GetStrValue()) << std::endl;
449  break;
451  out << Form(" // fitter %s->%s ignored", varname.Data(), membername.Data()) << std::endl;
452  break;
454  out << Form(" %s->%s.Set(%d);", varname.Data(), membername.Data(), info->GetIntValue()) << std::endl;
455  break;
456  case kBool_t:
457  out << Form(" %s->%s = %s;", varname.Data(), membername.Data(), (info->GetIntValue() ? "kTRUE" : "kFALSE")) << std::endl;
458  break;
459  default:
460  out << Form(" %s->%s = %s;", varname.Data(), membername.Data(), info->GetStrValue()) << std::endl;
461  break;
462  }
463  }
464 
465  delete fitems;
466 }
467 
469 {
470  return new TGo4ParameterStatus(this, kTRUE);
471 }
472 
474 {
475  return status ? status->UpdateParameterValues(this) : kFALSE;
476 }
Int_t GetIntValue() const
TGo4ParameterStatus * CreateStatus()
void SetType(const char *name, Int_t id)
virtual ~TGo4Parameter()
Int_t FindArrayLength(TObjArray *items, Int_t &itemsindx, TDataMember *member)
const char * GetFullName(TString &buf)
virtual void SavePrimitive(std::ostream &fs, Option_t *opt="")
void SetStrValue(const char *value)
virtual Int_t PrintParameter(Text_t *buffer=0, Int_t buflen=0)
Bool_t UpdateParameterValues(TGo4Parameter *par)
virtual void Clear(Option_t *opt="")
Int_t PrintMember(Text_t *buffer=0, Int_t buflen=0) const
Int_t GetTypeId() const
Bool_t CheckArrayIndexes(Int_t ndim, Int_t indx1, Int_t indx2)
virtual void Print(Option_t *dummy="") const
Bool_t UpdateFromUrl(const char *rest_url_opt)
void SetIntValue(Int_t value)
Bool_t SetMemberValues(TObjArray *fItems)
const char * GetStrValue() const
#define GO4TRACE(X)
Definition: TGo4Log.h:26
virtual Bool_t UpdateFrom(TGo4Parameter *rhs)
const char * GetTypeName() const
void SetVisible(Bool_t on=kTRUE)
void SetMemberId(Int_t id)
void SetArrayIndexes(Int_t ndim=0, Int_t indx1=-1, Int_t indx2=-1)
Bool_t SetStatus(TGo4ParameterStatus *status)
void GetMemberValues(TObjArray *fItems)
static void Info(const char *text,...)
Definition: TGo4Log.cxx:283