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