00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4FitModel.h"
00015
00016 #include "Riostream.h"
00017
00018 #include "TArrayD.h"
00019 #include "TArrayI.h"
00020 #include "TClass.h"
00021
00022 #include "TGo4FitData.h"
00023 #include "TGo4FitParameter.h"
00024
00025 TGo4FitAssignment::TGo4FitAssignment() :
00026 TNamed(), fxRatio(0), fxData(0), fxModelMask(0), fxModelBins(0) {
00027 }
00028
00029 TGo4FitAssignment::TGo4FitAssignment(const char* DataName) :
00030 TNamed(DataName,""),
00031 fxRatio(0), fxData(0), fxModelMask(0), fxModelBins(0) {
00032 }
00033
00034 TGo4FitAssignment::~TGo4FitAssignment() {
00035 if (fxRatio) delete fxRatio;
00036 if (fxModelMask) delete[] fxModelMask;
00037 if (fxModelBins) delete[] fxModelBins;
00038 }
00039
00040 Double_t TGo4FitAssignment::RatioValue() {
00041 return (fxRatio==0) ? 1. : fxRatio->GetValue();
00042 }
00043
00044 void TGo4FitAssignment::Print(Option_t* option) const {
00045 cout << " " << GetName();
00046 }
00047
00048
00049
00050 TGo4FitModel::TGo4FitModel() : TGo4FitComponent(),
00051 fiMinIntegrDepth(0), fiMaxIntegrDepth(0), fdIntegrEps(0.), fbAbsoluteEps(kFALSE), fbIntegrScaling(kFALSE),
00052 fxAssigments(), fiGroupIndex(-1),
00053 fxCurrentPars(), fxCurrentParsArray(0),
00054 fbNeedToRebuild(kFALSE), fxAllPars(0), fxAllParsValues(0) {
00055 }
00056
00057 TGo4FitModel::TGo4FitModel(const char* iName, const char* iTitle, Bool_t MakeAmplitude) :
00058 TGo4FitComponent(iName,iTitle),
00059 fiMinIntegrDepth(0), fiMaxIntegrDepth(0), fdIntegrEps(0.), fbAbsoluteEps(kFALSE), fbIntegrScaling(kFALSE),
00060 fxAssigments(), fiGroupIndex(-1),
00061 fxCurrentPars(), fxCurrentParsArray(0),
00062 fbNeedToRebuild(kFALSE), fxAllPars(0), fxAllParsValues(0) {
00063 fxAssigments.SetOwner(kTRUE);
00064 if (MakeAmplitude) NewAmplitude();
00065 }
00066
00067 TGo4FitModel::~TGo4FitModel() {
00068 RemoveAllPars();
00069 }
00070
00071 Int_t TGo4FitModel::NumPars() {
00072 Int_t res = TGo4FitParsList::NumPars();
00073 if (NumAssigments()>0) res += NumAssigments()-1;
00074 return res;
00075 }
00076
00077 TGo4FitParameter* TGo4FitModel::Get(Int_t n) {
00078 Int_t numpars = TGo4FitParsList::NumPars();
00079 if (n<numpars) return TGo4FitParsList::Get(n);
00080 n-=numpars-1;
00081 return (n>=0) && (n<NumAssigments()) ? GetAssigment(n)->fxRatio : 0;
00082 }
00083
00084 void TGo4FitModel::AssignToData(const char* DataName, Double_t RatioValue, Bool_t FixRatio) {
00085 if (FindAssigment(DataName)==0) {
00086 TGo4FitAssignment* ass = new TGo4FitAssignment(DataName);
00087 if (NumAssigments()>0) {
00088 ass->fxRatio = new TGo4FitParameter(GetRatioName(NumAssigments()),
00089 "Amplitude ratio to first data",
00090 RatioValue);
00091 ass->fxRatio->SetOwner(this);
00092 if (FixRatio) ass->fxRatio->SetFixed(kTRUE);
00093 }
00094 fxAssigments.Add(ass);
00095 }
00096 }
00097
00098 void TGo4FitModel::ChangeDataNameInAssignments(const char* oldname, const char* newname) {
00099 TGo4FitAssignment* ass = FindAssigment(oldname);
00100 if (ass) ass->SetName(newname);
00101 }
00102
00103 void TGo4FitModel::ClearAssignmentTo(const char* DataName) {
00104 TGo4FitAssignment* ass = FindAssigment(DataName);
00105 if (ass==0) return;
00106
00107 fxAssigments.Remove(ass);
00108 delete ass;
00109 fxAssigments.Compress();
00110
00111 for (Int_t n=0;n<NumAssigments();n++) {
00112 ass = GetAssigment(n);
00113 if (ass->fxRatio==0) continue;
00114 if (n==0) {
00115 delete ass->fxRatio;
00116 ass->fxRatio = 0;
00117 } else
00118 ass->fxRatio->SetName(GetRatioName(n+1));
00119 }
00120 }
00121
00122 void TGo4FitModel::ClearAssignments() {
00123 fxAssigments.Clear();
00124 fxAssigments.Compress();
00125 }
00126
00127 void TGo4FitModel::ConnectToDataIfAssigned(TGo4FitData* data) {
00128 if (data==0) return;
00129 TGo4FitAssignment* ass = FindAssigment(data->GetName());
00130 if ( ass != 0 ) ass->fxData = data;
00131 }
00132
00133 TGo4FitData* TGo4FitModel::GetAssignedConnection(Int_t n) {
00134 TGo4FitAssignment* ass = GetAssigment(n);
00135 if(ass) return ass->fxData;
00136 else return 0;
00137 }
00138
00139 Bool_t TGo4FitModel::GetPosition(Int_t naxis, Double_t& pos) {
00140 if(GetPosPar(naxis)) {
00141 pos = GetPosPar(naxis)->GetValue();
00142 return kTRUE;
00143 } else return kFALSE;
00144 }
00145
00146 Bool_t TGo4FitModel::SetPosition(Int_t naxis, Double_t pos) {
00147 if(GetPosPar(naxis)) {
00148 GetPosPar(naxis)->SetValue(pos);
00149 return kTRUE;
00150 } else return kFALSE;
00151 }
00152
00153 Bool_t TGo4FitModel::GetWidth(Int_t naxis, Double_t& width) {
00154 if(GetWidthPar(naxis)) {
00155 width = GetWidthPar(naxis)->GetValue();
00156 return kTRUE;
00157 } else return kFALSE;
00158 }
00159
00160 Bool_t TGo4FitModel::SetWidth(Int_t naxis, Double_t width) {
00161 if(GetWidthPar(naxis)) {
00162 GetWidthPar(naxis)->SetValue(width);
00163 return kTRUE;
00164 } else return kFALSE;
00165 }
00166
00167 void TGo4FitModel::SetIntegrationsProperty(Int_t iMinIntegrDepth, Int_t iMaxIntegrDepth, Double_t iIntegrEps, Bool_t iAbsoluteEps, Bool_t iIntegrScaling) {
00168 fiMinIntegrDepth = iMinIntegrDepth;
00169 fiMaxIntegrDepth = iMaxIntegrDepth;
00170 fdIntegrEps = iIntegrEps;
00171 fbAbsoluteEps = iAbsoluteEps;
00172 fbIntegrScaling = iIntegrScaling;
00173 if (fdIntegrEps<=0.)
00174 fiMaxIntegrDepth = fiMinIntegrDepth;
00175 }
00176
00177 void TGo4FitModel::RemoveAllPars() {
00178 if (fxAllPars) { delete fxAllPars; fxAllPars=0; }
00179 if (fxAllParsValues) { delete fxAllParsValues; fxAllParsValues=0; }
00180 }
00181
00182 Bool_t TGo4FitModel::Initialize(Int_t UseBuffers) {
00183 Bool_t use = ((UseBuffers<0) && GetUseBuffers()) || (UseBuffers>0);
00184 for(Int_t n=0;n<NumAssigments();n++) {
00185 TGo4FitAssignment* ass = GetAssigment(n);
00186 if (ass->fxData==0) {
00187 cout << "Data " << ass->GetName() << " not assigned to model " << GetName() << endl;
00188 continue;
00189 }
00190
00191 if (use && ass->fxData->BuffersAllocated()) {
00192 if (IsAnyRangeLimits()) {
00193 ass->fxModelMask = new Char_t[ass->fxData->GetBinsSize()];
00194 ass->fxData->ApplyRangesForModelMask(this,ass->fxModelMask);
00195 }
00196
00197 ass->fxModelBins = new Double_t[ass->fxData->GetBinsSize()];
00198 }
00199 }
00200
00201 SetNeedToRebuild();
00202
00203 if (use) {
00204 RemoveAllPars();
00205
00206 fxAllPars = new TGo4FitParsList(kFALSE);
00207 CollectParsTo(*fxAllPars);
00208
00209 fxAllParsValues = new TArrayD(fxAllPars->NumPars());
00210 fxAllPars->GetParsValues(fxAllParsValues->GetArray());
00211 }
00212
00213 return kTRUE;
00214 }
00215
00216 void TGo4FitModel::Finalize() {
00217 RemoveAllPars();
00218 fxCurrentPars.Set(0);
00219 for(Int_t n=0;n<NumAssigments();n++) {
00220 TGo4FitAssignment* ass = GetAssigment(n);
00221 if (ass->fxModelMask) { delete[] ass->fxModelMask; ass->fxModelMask = 0; }
00222 if (ass->fxModelBins) { delete[] ass->fxModelBins; ass->fxModelBins = 0; }
00223 }
00224 }
00225
00226 Bool_t TGo4FitModel::BuffersAllocated() const {
00227 Bool_t res = (NumAssigments()>0);
00228 for(Int_t n=0;n<NumAssigments();n++)
00229 res = res && (GetAssigment(n)->fxModelBins!=0);
00230 return res;
00231 }
00232
00233 Double_t* TGo4FitModel::GetModelBins(const char* DataName) const {
00234 TGo4FitAssignment* ass = FindAssigment(DataName);
00235 return ass != 0 ? ass->fxModelBins : 0;
00236 }
00237
00238 Double_t TGo4FitModel::EvaluateAndIntegrate(Int_t NumScales, const Double_t* Scales, const Double_t* Widths) {
00239 if ((NumScales<1) || (Scales==0)) return 0.;
00240
00241 if ( (fiMinIntegrDepth>0) && (fiMaxIntegrDepth>0) && (Widths!=0)) {
00242 TArrayI IntegrIndexes(NumScales);
00243 TArrayD ScaleValues(NumScales, Scales);
00244 TArrayD WidthValues(NumScales, Widths);
00245 TArrayD dScaleValues(NumScales);
00246
00247 Int_t* dindx = IntegrIndexes.GetArray();
00248 Double_t* vector = ScaleValues.GetArray();
00249 Double_t* width = WidthValues.GetArray();
00250 Double_t* dvector = dScaleValues.GetArray();
00251
00252 Int_t n=0;
00253
00254
00255 for(n=0;n<NumScales;n++)
00256 vector[n] -= 0.5*width[n];
00257
00258
00259 Double_t TotalSum = EvalN(vector);
00260 Int_t TotalNumPnt = 1;
00261
00262 Int_t IntegrDepth = 0;
00263 Int_t NumStep = 1;
00264 Double_t Step = 1.0;
00265 Bool_t stopcondition = kFALSE;
00266
00267
00268 do {
00269
00270 IntegrIndexes.Reset(0);
00271 Double_t Sum = 0.;
00272 Int_t NumPnt = 0;
00273
00274
00275 do {
00276 for(n=0;n<NumScales;n++)
00277 dvector[n] = vector[n]+Step*width[n]*(dindx[n]+0.5);
00278
00279 Sum+=EvalN(dvector);
00280 NumPnt++;
00281
00282 n=0;
00283 do {
00284 dindx[n]++;
00285 if (dindx[n]<NumStep) break;
00286 dindx[n]=0; n++;
00287 } while (n<NumScales);
00288 } while (n<NumScales);
00289
00290
00291 stopcondition = kFALSE;
00292 if (IntegrDepth>=fiMinIntegrDepth) {
00293 if (IntegrDepth>=fiMaxIntegrDepth) stopcondition = kTRUE; else {
00294 Double_t v1 = TotalSum/TotalNumPnt;
00295 Double_t v2 = Sum/NumPnt;
00296 Double_t v = TMath::Abs(v1-v2);
00297 if (!fbAbsoluteEps) {
00298 if ((v1!=0) || (v2!=0)) v=v/(TMath::Abs(v1)+TMath::Abs(v2));
00299 else v=0.;
00300 }
00301 if (v<=fdIntegrEps) stopcondition = kTRUE;
00302 }
00303 }
00304 TotalSum+=Sum;
00305 TotalNumPnt+=NumPnt;
00306 IntegrDepth++;
00307 NumStep*=2;
00308 Step = Step/2.;
00309 } while (!stopcondition);
00310
00311 Double_t value = 0;
00312 if (TotalNumPnt>0) value = TotalSum / TotalNumPnt;
00313 if (fbIntegrScaling)
00314 for(n=0;n<NumScales;n++) value*=width[n];
00315 return value;
00316 } else return EvalN(Scales);
00317 }
00318
00319 Double_t TGo4FitModel::EvaluateAtPoint(TGo4FitData* data, Int_t nbin, Bool_t UseRanges) {
00320 if (data==0) return 0.;
00321 const Double_t* scales = data->GetScaleValues(nbin);
00322 Int_t scalessize = data->GetScalesSize();
00323 if (UseRanges && !CheckRangeConditions(scales, scalessize)) return 0.;
00324 return EvaluateAndIntegrate(scalessize, scales, data->GetWidthValues(nbin));
00325 }
00326
00327 Double_t TGo4FitModel::EvaluateAtPoint(TGo4FitDataIter* iter, Bool_t UseRanges) {
00328 if (iter==0) return 0;
00329 const Double_t* scales = iter->Scales();
00330 Int_t scalessize = iter->ScalesSize();
00331 if (UseRanges && !CheckRangeConditions(scales, scalessize)) return 0.;
00332 return EvaluateAndIntegrate(scalessize, scales, iter->Widths());
00333 }
00334
00335 void TGo4FitModel::RebuildShape(Bool_t ForceBuild) {
00336 if ((fxAllPars==0) || (fxAllParsValues==0)) return;
00337
00338 Bool_t fill = ForceBuild || fbNeedToRebuild;
00339 if (!fill)
00340 for(Int_t n=0;n<fxAllPars->NumPars();n++) {
00341 if (n==GetAmplIndex()) continue;
00342 if ((*fxAllParsValues)[n] != fxAllPars->GetPar(n)->GetValue()) {
00343 fill = kTRUE;
00344 break;
00345 }
00346 }
00347
00348 if(fill)
00349 for(Int_t n=0;n<NumAssigments();n++) {
00350 TGo4FitAssignment* ass = GetAssigment(n);
00351
00352 if ((ass->fxData==0) || (ass->fxModelBins==0)) continue;
00353
00354 TGo4FitData* data = ass->fxData;
00355
00356 if (!BeforeEval(data->GetScalesSize())) continue;
00357
00358 Int_t size = data->GetBinsSize();
00359 Double_t* bins = ass->fxModelBins;
00360 Char_t* mask = ass->fxModelMask;
00361 Double_t ratio = ass->RatioValue();
00362
00363 for(Int_t nbin=0;nbin<size;nbin++) {
00364 if ((mask!=0) && (mask[nbin]==0)) continue;
00365 bins[nbin] = ratio * EvaluateAtPoint(data, nbin, kFALSE);
00366 }
00367
00368 AfterEval();
00369 }
00370
00371
00372 for(Int_t n=0;n<fxAllPars->NumPars();n++)
00373 (*fxAllParsValues)[n] = fxAllPars->GetPar(n)->GetValue();
00374
00375 fbNeedToRebuild = kFALSE;
00376 }
00377
00378 Bool_t TGo4FitModel::AddModelToDataResult(TGo4FitData* data) {
00379 if ((data==0) || (!data->BuffersAllocated())) return kFALSE;
00380
00381 Double_t* result = data->GetBinsResult();
00382 if (result==0) return kFALSE;
00383 Int_t size = data->GetBinsSize();
00384
00385 Double_t* modelbins = GetModelBins(data->GetName());
00386 if (modelbins) {
00387 Double_t ampl = GetAmplValue();
00388 for (Int_t nbin=0;nbin<size;nbin++)
00389 result[nbin] += ampl * modelbins[nbin];
00390 return kTRUE;
00391 }
00392
00393 if (!BeforeEval(data->GetScalesSize())) return kFALSE;
00394
00395 Double_t ampl = GetAmplValue() * GetRatioValueFor(data->GetName());
00396
00397 for(Int_t nbin=0;nbin<size;nbin++)
00398 result[nbin] += ampl * EvaluateAtPoint(data, nbin);
00399
00400 AfterEval();
00401
00402 return kTRUE;
00403 }
00404
00405 Bool_t TGo4FitModel::BeforeEval(Int_t ndim) {
00406 fxCurrentPars.Set(NumPars());
00407 GetParsValues(fxCurrentPars.GetArray());
00408 fxCurrentParsArray = fxCurrentPars.GetArray();
00409 if (GetAmplPar()!=0) fxCurrentParsArray++;
00410 return kTRUE;
00411 }
00412
00413 Double_t TGo4FitModel::EvalN(const Double_t* v) {
00414 return UserFunction((Double_t*)v, fxCurrentParsArray);
00415 }
00416
00417 Double_t TGo4FitModel::Evaluate(Double_t x) {
00418 Double_t zn = 0.;
00419 if (BeforeEval(1)) {
00420 zn = GetAmplValue() * EvalN(&x);
00421 AfterEval();
00422 }
00423 return zn;
00424 }
00425
00426 Double_t TGo4FitModel::Evaluate(Double_t x, Double_t y) {
00427 Double_t zn = 0.;
00428 if (BeforeEval(2)) {
00429 Double_t vector[2] = {x,y};
00430 zn = GetAmplValue() * EvalN(vector);
00431 AfterEval();
00432 }
00433 return zn;
00434 }
00435
00436 Double_t TGo4FitModel::Evaluate(Double_t x, Double_t y, Double_t z) {
00437 Double_t zn = 0.;
00438 if (BeforeEval(3)) {
00439 Double_t vector[3] = {x,y,z};
00440 zn = GetAmplValue() * EvalN(vector);
00441 AfterEval();
00442 }
00443 return zn;}
00444
00445 Double_t TGo4FitModel::Evaluate(Double_t* v, Int_t ndim) {
00446 Double_t zn = 0.;
00447 if (BeforeEval(ndim)) {
00448 zn = GetAmplValue() * EvalN(v);
00449 AfterEval();
00450 }
00451 return zn;
00452 }
00453
00454 Double_t TGo4FitModel::Integral() {
00455 return 0;
00456 }
00457
00458
00459 const Int_t* TGo4FitModel::GetDataFullIndex(TGo4FitData* data, Int_t nbin) {
00460 return data==0 ? 0 : data->GetFullIndex(nbin);
00461 }
00462
00463 Int_t TGo4FitModel::GetDataIndexesSize(TGo4FitData* data) {
00464 return data==0 ? 0 : data->GetIndexesSize();
00465 }
00466
00467 TGo4FitAssignment* TGo4FitModel::FindAssigment(const char* DataName) const {
00468 for (Int_t n=0;n<NumAssigments();n++)
00469 if (strcmp(DataName, GetAssigment(n)->GetName()) == 0)
00470 return GetAssigment(n);
00471 return 0;
00472 }
00473
00474 TString TGo4FitModel::GetRatioName(Int_t n)
00475 {
00476 TString res;
00477 res.Form("Ratio%d",n);
00478 return res;
00479 }
00480
00481 Double_t TGo4FitModel::GetRatioValueFor(const char* DataName) {
00482 TGo4FitAssignment* ass = FindAssigment(DataName);
00483 return (ass==0) ? 1. : ass->RatioValue();
00484 }
00485
00486 void TGo4FitModel::Print(Option_t* option) const {
00487 TGo4FitComponent::Print(option);
00488 cout << " Assigned to: ";
00489 fxAssigments.Print(option);
00490 cout << endl;
00491 if ( (fiMinIntegrDepth>0) && (fiMaxIntegrDepth>0) ) {
00492 cout << " Integration property: depths from " << fiMinIntegrDepth << " to " << fiMaxIntegrDepth;
00493 if (fbAbsoluteEps) cout << " absolute"; else cout << " relative";
00494 cout << " error " << fdIntegrEps << endl;
00495 }
00496 }
00497
00498 void TGo4FitModel::Streamer(TBuffer& b) {
00499 if (b.IsReading()) {
00500
00501 TGo4FitModel::Class()->ReadBuffer(b, this);
00502
00503 for (Int_t n=0;n<NumAssigments();n++)
00504 if (GetAssigment(n)->fxRatio)
00505 GetAssigment(n)->fxRatio->SetOwner(this);
00506
00507 } else {
00508 TGo4FitModel::Class()->WriteBuffer(b, this);
00509 }
00510 }