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