00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4Parameter.h"
00015
00016 #include <string.h>
00017 #include <stdlib.h>
00018
00019 #include "TList.h"
00020 #include "TObjArray.h"
00021 #include "TClass.h"
00022 #include "TROOT.h"
00023 #include "TDataMember.h"
00024 #include "TDataType.h"
00025 #include "TBaseClass.h"
00026 #include "TDatime.h"
00027 #include "TArrayI.h"
00028 #include "TArrayD.h"
00029
00030 #include "TGo4Log.h"
00031 #include "TGo4ParameterMember.h"
00032
00033 TGo4Parameter::TGo4Parameter() :
00034 TNamed()
00035 {
00036 }
00037
00038 TGo4Parameter::TGo4Parameter(const char* name, const char* title) :
00039 TNamed(name ? name : "Parameter", title)
00040 {
00041 GO4TRACE((12,"TGo4Parameter ::TGo4Parameter (const char*, const char*)",__LINE__, __FILE__));
00042
00043 }
00044
00045 void TGo4Parameter::Print(Option_t* dummy) const
00046 {
00047
00048 TGo4Parameter* const localthis= const_cast<TGo4Parameter* const>(this);
00049 localthis->PrintParameter();
00050 }
00051
00052 Int_t TGo4Parameter::PrintParameter(Text_t* buffer, Int_t buflen)
00053 {
00054 GO4TRACE((12,"TGo4Parameter ::PrintParameter()",__LINE__, __FILE__));
00055
00056 if(buflen<=0 && buffer!=0) return 0;
00057
00058 TObjArray items;
00059 GetMemberValues(&items);
00060
00061 Int_t size = 0;
00062 TString localbuf = TString::Format("Parameter name: %s class %s\n", GetName(), ClassName());
00063
00064 if(buffer==0) {
00065 std::cout << localbuf;
00066 } else {
00067 size = localbuf.Length();
00068 if(size>buflen) size = buflen;
00069 strncpy(buffer, localbuf.Data(), size);
00070 buflen -= size;
00071 buffer += size;
00072 }
00073
00074 TIter iter(&items);
00075 TGo4ParameterMember* info = 0;
00076
00077 TROOT::IncreaseDirLevel();
00078
00079 while ((info = (TGo4ParameterMember*) iter()) !=0 ) {
00080 Int_t size1 = info->PrintMember(buffer, buflen);
00081
00082 size += size1;
00083 buflen -= size1;
00084 buffer += size1;
00085 }
00086
00087 TROOT::DecreaseDirLevel();
00088
00089 return size;
00090 }
00091
00092 TGo4Parameter::~TGo4Parameter()
00093 {
00094 GO4TRACE((12,"TGo4Parameter ::~TGo4Parameter ()",__LINE__, __FILE__));
00095 }
00096
00097 Bool_t TGo4Parameter::UpdateFrom(TGo4Parameter* rhs)
00098 {
00099 if (rhs==0) return kFALSE;
00100
00101 if (rhs->IsA() != IsA()) {
00102 std::cout << "GO4> !!! ERROR: Wrong parameter class is used in TGo4Parameter::UpdateFrom() method!!!" << std::endl;
00103 std::cout << "GO4> !!! ERROR: One cannot update " << IsA()->GetName() << " class from " << rhs->IsA()->GetName() << std::endl;
00104 std::cout << "GO4> !!! ERROR: Implement your custom UpdateFrom() method" << std::endl;
00105 return kFALSE;
00106 }
00107
00108 TObjArray items;
00109
00110 rhs->GetMemberValues(&items);
00111
00112 return SetMemberValues(&items);
00113 }
00114
00115 void TGo4Parameter::Clear(Option_t* opt)
00116 {
00117
00118 std::cout << "GO4> !!! Default TGo4Parameter::Clear() method is used." << std::endl;
00119 std::cout << "GO4> !!! You probably need to overwrite Clear() method for your class" << IsA()->GetName() << std::endl;
00120
00121 TObjArray items;
00122
00123 GetMemberValues(&items);
00124
00125 TIter iter(&items);
00126 TGo4ParameterMember* info = 0;
00127
00128 while ((info = (TGo4ParameterMember*) iter()) !=0 ) info->SetToZero();
00129
00130 SetMemberValues(&items);
00131 }
00132
00133 void TGo4Parameter::GetMemberValues(TObjArray* fItems)
00134 {
00135 GetMemberValues(fItems, IsA(), (char*) this, 0);
00136 }
00137
00138 Bool_t TGo4Parameter::SetMemberValues(TObjArray* items)
00139 {
00140 if (items==0) return kFALSE;
00141
00142 Int_t indx(0);
00143
00144 return SetMemberValues(items, indx, IsA(), (char*) this, 0);
00145 }
00146
00147
00148 void TGo4Parameter::GetMemberValues(TObjArray* fItems, TClass* cl, char* ptr, unsigned long int cloffset)
00149 {
00150 if ((fItems==0) || (cl==0) || (ptr==0)) return;
00151
00152 TIter iter(cl->GetListOfDataMembers());
00153 Int_t lastmemberid = -1;
00154 if (fItems->GetLast()>=0)
00155 lastmemberid = ((TGo4ParameterMember*) fItems->Last())->GetMemberId();
00156
00157 TObject* obj = 0;
00158 while ((obj=iter()) != 0) {
00159 TDataMember* member = dynamic_cast<TDataMember*>(obj);
00160 if (member==0) continue;
00161 const char* memtypename = member->GetFullTypeName();
00162 Int_t memtypeid = 0;
00163
00164
00165 if(strcmp(memtypename,"TClass*")==0) continue;
00166
00167
00168 Int_t arraydim = member->GetArrayDim();
00169 if (arraydim>2) continue;
00170
00171 Int_t maxindex1(1), maxindex2(1);
00172
00173 switch(arraydim) {
00174 case 1:
00175 maxindex1 = member->GetMaxIndex(0);
00176 break;
00177 case 2:
00178 maxindex1 = member->GetMaxIndex(0);
00179 maxindex2 = member->GetMaxIndex(1);
00180 break;
00181 }
00182
00183 TArrayI* arri(0);
00184 TArrayD* arrd(0);
00185
00186 if (strcmp(memtypename,"TString")==0) {
00187 memtypeid = TGo4ParameterMember::kTString_t;
00188 } else
00189 if (strcmp(memtypename,"TGo4Fitter*")==0) {
00190 memtypeid = TGo4ParameterMember::kTGo4Fitter_t;
00191 } else
00192 if (strcmp(memtypename,"TArrayI")==0) {
00193 memtypeid = kInt_t;
00194 memtypename = "Int_t";
00195 if ((maxindex1>1) || (maxindex2>1)) continue;
00196 arri = (TArrayI*) (ptr + cloffset + member->GetOffset());
00197 arraydim = 1;
00198 maxindex1 = arri->GetSize();
00199 maxindex2 = 1;
00200 } else
00201 if (strcmp(memtypename,"TArrayD")==0) {
00202 memtypeid = kDouble_t;
00203 memtypename = "Double_t";
00204 if ((maxindex1>1) || (maxindex2>1)) continue;
00205 arrd = (TArrayD*) (ptr + cloffset + member->GetOffset());
00206 arraydim = 1;
00207 maxindex1 = arrd->GetSize();
00208 maxindex2 = 1;
00209 } else {
00210 if (!member->IsBasic()) continue;
00211 memtypeid = member->GetDataType()->GetType();
00212 }
00213
00214
00215 if (arri || arrd) {
00216 TGo4ParameterMember* info = new TGo4ParameterMember(member->GetName(), member->GetTitle());
00217
00218 info->SetMemberId(lastmemberid++);
00219
00220 info->SetType("TArray", TGo4ParameterMember::kTArray_t);
00221 info->SetVisible(kFALSE);
00222
00223 info->SetIntValue(maxindex1);
00224
00225 fItems->Add(info);
00226 }
00227
00228 lastmemberid++;
00229
00230 for(Int_t ix1=0;ix1<maxindex1;ix1++)
00231 for(Int_t ix2=0;ix2<maxindex2;ix2++) {
00232 TGo4ParameterMember* info = new TGo4ParameterMember(member->GetName(), member->GetTitle());
00233 fItems->Add(info);
00234
00235 info->SetMemberId(lastmemberid);
00236
00237 info->SetType(memtypename, memtypeid);
00238
00239 info->SetVisible((ix1==0) && (ix2==0));
00240
00241 info->SetArrayIndexes(arraydim, ix1, ix2);
00242
00243 char* addr = ptr + cloffset + member->GetOffset() + (ix1*maxindex2 + ix2) * member->GetUnitSize();
00244 if (arri) addr = (char*) (arri->GetArray() + ix1);
00245 if (arrd) addr = (char*) (arrd->GetArray() + ix1);
00246
00247 info->SetValue(addr);
00248 }
00249 }
00250
00251
00252 TIter cliter(cl->GetListOfBases());
00253 while((obj=cliter()) !=0) {
00254 TBaseClass* baseclass = dynamic_cast<TBaseClass*>(obj);
00255 if (baseclass==0) continue;
00256 TClass* bclass = baseclass->GetClassPointer();
00257 if(bclass==0) continue;
00258 if(strcmp(bclass->GetName(), "TGo4Parameter")==0) continue;
00259 if(strcmp(bclass->GetName(), "TNamed")==0) continue;
00260
00261 GetMemberValues(fItems, bclass, ptr, cloffset + baseclass->GetDelta());
00262 }
00263 }
00264
00265 Int_t TGo4Parameter::FindArrayLength(TObjArray* items, Int_t& itemsindx, TDataMember* member)
00266 {
00267 TGo4ParameterMember* info = dynamic_cast<TGo4ParameterMember*> (items->At(itemsindx++));
00268 if (info==0) return -1;
00269 if (strcmp(info->GetName(), member->GetName())!=0) return -1;
00270 if (strcmp(info->GetTitle(), member->GetTitle())!=0) return -1;
00271 if (info->GetTypeId() != TGo4ParameterMember::kTArray_t) return -1;
00272 return info->GetIntValue();
00273 }
00274
00275
00276 Bool_t TGo4Parameter::SetMemberValues(TObjArray* items, Int_t& itemsindx, TClass* cl, char* ptr, unsigned long int cloffset)
00277 {
00278 if ((items==0) || (cl==0) || (ptr==0)) return kFALSE;
00279
00280 TIter iter(cl->GetListOfDataMembers());
00281
00282 TObject* obj = 0;
00283 while ((obj=iter()) != 0) {
00284 TDataMember* member = dynamic_cast<TDataMember*>(obj);
00285 if (member==0) continue;
00286 const char* memtypename = member->GetFullTypeName();
00287 Int_t memtypeid = 0;
00288
00289
00290 if(strcmp(memtypename,"TClass*")==0) continue;
00291
00292
00293 Int_t arraydim = member->GetArrayDim();
00294 if (arraydim>2) continue;
00295
00296 Int_t maxindex1(1), maxindex2(1);
00297
00298 switch(arraydim) {
00299 case 1:
00300 maxindex1 = member->GetMaxIndex(0);
00301 break;
00302 case 2:
00303 maxindex1 = member->GetMaxIndex(0);
00304 maxindex2 = member->GetMaxIndex(1);
00305 break;
00306 }
00307
00308 TArrayI* arri(0);
00309 TArrayD* arrd(0);
00310
00311 if (strcmp(memtypename,"TString")==0) {
00312 memtypeid = TGo4ParameterMember::kTString_t;
00313 } else
00314 if (strcmp(memtypename,"TGo4Fitter*")==0) {
00315 memtypeid = TGo4ParameterMember::kTGo4Fitter_t;
00316 } else
00317 if (strcmp(memtypename,"TArrayI")==0) {
00318 memtypeid = kInt_t;
00319 memtypename = "Int_t";
00320 if ((maxindex1>1) || (maxindex2>1)) continue;
00321 arri = (TArrayI*) (ptr + cloffset + member->GetOffset());
00322 arraydim = 1;
00323 maxindex1 = FindArrayLength(items, itemsindx, member);
00324 maxindex2 = 1;
00325 if (maxindex1<0) return kFALSE;
00326 if (arri->GetSize()!=maxindex1) arri->Set(maxindex1);
00327 } else
00328 if (strcmp(memtypename,"TArrayD")==0) {
00329 memtypeid = kDouble_t;
00330 memtypename = "Double_t";
00331 if ((maxindex1>1) || (maxindex2>1)) continue;
00332 arrd = (TArrayD*) (ptr + cloffset + member->GetOffset());
00333 arraydim = 1;
00334 maxindex1 = FindArrayLength(items, itemsindx, member);
00335 maxindex2 = 1;
00336 if (maxindex1<0) return kFALSE;
00337 if (arrd->GetSize()!=maxindex1) arrd->Set(maxindex1);
00338 } else {
00339 if (!member->IsBasic()) continue;
00340 memtypeid = member->GetDataType()->GetType();
00341 }
00342
00343 for(Int_t ix1=0;ix1<maxindex1;ix1++)
00344 for(Int_t ix2=0;ix2<maxindex2;ix2++) {
00345 if (itemsindx>items->GetLast()) return kFALSE;
00346 TGo4ParameterMember* info =
00347 dynamic_cast<TGo4ParameterMember*> (items->At(itemsindx++));
00348 if (info==0) return kFALSE;
00349
00350 if (strcmp(info->GetName(), member->GetName())!=0) return kFALSE;
00351 if (strcmp(info->GetTitle(), member->GetTitle())!=0) return kFALSE;
00352
00353 if (strcmp(info->GetTypeName(), memtypename)!=0) return kFALSE;
00354 if (info->GetTypeId() != memtypeid) return kFALSE;
00355
00356 if (!info->CheckArrayIndexes(arraydim, ix1, ix2)) return kFALSE;
00357
00358 char* addr = ptr + cloffset + member->GetOffset() + (ix1*maxindex2 + ix2) * member->GetUnitSize();
00359 if (arri) addr = (char*) (arri->GetArray() + ix1);
00360 if (arrd) addr = (char*) (arrd->GetArray() + ix1);
00361
00362 info->GetValue(addr);
00363 }
00364 }
00365
00366
00367 TIter cliter(cl->GetListOfBases());
00368 while((obj=cliter()) !=0) {
00369 TBaseClass* baseclass = dynamic_cast<TBaseClass*>(obj);
00370 if (baseclass==0) continue;
00371 TClass* bclass = baseclass->GetClassPointer();
00372 if(bclass==0) continue;
00373 if(strcmp(bclass->GetName(), "TGo4Parameter")==0) continue;
00374 if(strcmp(bclass->GetName(), "TNamed")==0) continue;
00375
00376 if (!SetMemberValues(items, itemsindx, bclass, ptr, cloffset + baseclass->GetDelta())) return kFALSE;
00377 }
00378
00379 return kTRUE;
00380 }
00381
00382 void TGo4Parameter::SavePrimitive(std::ostream& out, Option_t* opt)
00383 {
00384 static int cnt = 0;
00385 TString varname = TString::Format("param%d", cnt++);
00386 Bool_t savemacro = (opt!=0) && (strstr(opt,"savemacro")!=0);
00387
00388 if (savemacro) {
00389 out << Form(" %s* %s = (%s*) go4->GetParameter(\"%s\",\"%s\");",
00390 ClassName(), varname.Data(), ClassName(), GetName(), ClassName()) << std::endl << std::endl;
00391 out << Form(" if (%s==0) {", varname.Data()) << std::endl;
00392 out << Form(" TGo4Log::Error(\"Could not find parameter %s of class %s\");", GetName(), ClassName()) << std::endl;
00393 out << Form(" return;") << std::endl;
00394 out << Form(" }") << std::endl << std::endl;
00395 out << Form(" TGo4Log::Info(\"Set parameter %s as saved at %s\");", GetName(), TDatime().AsString()) << std::endl << std::endl;
00396 } else {
00397 out << Form(" %s* %s = new %s;", ClassName(), varname.Data(), ClassName()) << std::endl;
00398 out << Form(" %s->SetName(\"%s\");", varname.Data(), GetName()) << std::endl;
00399 out << Form(" %s->SetTitle(\"%s\");", varname.Data(), GetTitle()) << std::endl;
00400 }
00401
00402 TObjArray *fitems = new TObjArray();
00403 fitems->SetOwner(kTRUE);
00404 GetMemberValues(fitems);
00405
00406 TIter iter(fitems);
00407 TGo4ParameterMember* info = 0;
00408
00409 while ((info = (TGo4ParameterMember*) iter()) !=0 ) {
00410 if (info->GetTypeId()==TGo4ParameterMember::kTGo4Fitter_t) continue;
00411
00412 TString membername;
00413 info->GetFullName(membername);
00414
00415 switch (info->GetTypeId()) {
00416 case TGo4ParameterMember::kTString_t:
00417 out << Form(" %s->%s = \"%s\";", varname.Data(), membername.Data(), info->GetStrValue()) << std::endl;
00418 break;
00419 case TGo4ParameterMember::kTGo4Fitter_t:
00420 out << Form(" // fitter %s->%s ignored", varname.Data(), membername.Data()) << std::endl;
00421 break;
00422 case TGo4ParameterMember::kTArray_t:
00423 out << Form(" %s->%s.Set(%d);", varname.Data(), membername.Data(), info->GetIntValue()) << std::endl;
00424 break;
00425 case kBool_t:
00426 out << Form(" %s->%s = %s;", varname.Data(), membername.Data(), (info->GetIntValue() ? "kTRUE" : "kFALSE")) << std::endl;
00427 break;
00428 default:
00429 out << Form(" %s->%s = %s;", varname.Data(), membername.Data(), info->GetStrValue()) << std::endl;
00430 break;
00431 }
00432 }
00433
00434 delete fitems;
00435 }
00436