00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4FitComponent.h"
00015
00016 #include "Riostream.h"
00017
00018 #include "TCutG.h"
00019 #include "TGo4FitParameter.h"
00020
00021 const UInt_t kExcludeCut = 0x00100000;
00022
00023 TGo4FitComponent::TGo4FitComponent() : TGo4FitParsList(), TGo4FitSlotList(),
00024 fxRangeAxis(), fxRangeValue(), fxCuts(), fiAmplIndex(-1), fbUseBuffers(kFALSE) {
00025 }
00026
00027 TGo4FitComponent::TGo4FitComponent(const char* iName, const char* iTitle) :
00028 TGo4FitParsList(iName,iTitle,kTRUE), TGo4FitSlotList(),
00029 fxRangeAxis(), fxRangeValue(), fxCuts(), fiAmplIndex(-1), fbUseBuffers(kFALSE) {
00030 fxCuts.SetOwner(kTRUE);
00031 }
00032
00033 TGo4FitComponent::~TGo4FitComponent() {
00034 }
00035
00036 TGo4FitParameter* TGo4FitComponent::NewParameter(const char* Name, const char* Title, Double_t iValue, Bool_t Fixed, Int_t AtIndx) {
00037 TGo4FitParameter* par = new TGo4FitParameter(Name, Title, iValue);
00038 if (AtIndx<0) AddPar(par);
00039 else InsertPar(par,AtIndx);
00040 if(Fixed) par->SetFixed(kTRUE);
00041 return par;
00042 }
00043
00044 TGo4FitParameter* TGo4FitComponent::NewAmplitude(const char* Name, Double_t iValue, Bool_t IsFixed, Int_t AtIndx) {
00045 TGo4FitParameter* par = 0;
00046 if (Name==0) par = new TGo4FitParameter("Ampl", "Amplitude", iValue);
00047 else par = new TGo4FitParameter(Name, "Amplitude", iValue);
00048 if (AtIndx<0) { AddPar(par); AtIndx = NumPars()-1; }
00049 else InsertPar(par,AtIndx);
00050 SetAmplIndex(AtIndx);
00051 if(IsFixed) par->SetFixed(kTRUE);
00052 return par;
00053 }
00054
00055 TGo4FitParameter* TGo4FitComponent::GetAmplPar()
00056 {
00057 return fiAmplIndex<0 ? 0 : GetPar(fiAmplIndex);
00058 }
00059
00060 const char* TGo4FitComponent::GetAmplName()
00061 {
00062 return GetAmplPar() ? GetAmplPar()->GetName() : 0;
00063 }
00064
00065 const char* TGo4FitComponent::GetAmplFullName()
00066 {
00067 return GetAmplPar() ? GetAmplPar()->GetFullName() : 0;
00068 }
00069 Double_t TGo4FitComponent::GetAmplValue()
00070 {
00071 return GetAmplPar() ? GetAmplPar()->GetValue() : 1.0;
00072 }
00073
00074 void TGo4FitComponent::SetAmplValue(Double_t iAmpl)
00075 {
00076 if(GetAmplPar()) Get(fiAmplIndex)->SetValue(iAmpl);
00077 }
00078
00079 Double_t TGo4FitComponent::GetAmplError()
00080 {
00081 return GetAmplPar() ? GetAmplPar()->GetError() : 0.0;
00082 }
00083
00084 void TGo4FitComponent::SetAmplError(Double_t iError)
00085 {
00086 if(GetAmplPar()) Get(fiAmplIndex)->SetError(iError);
00087 }
00088
00089 Bool_t TGo4FitComponent::MakeAmpl(Bool_t isFixed) {
00090 if (GetAmplPar()!=0) return kFALSE;
00091 NewAmplitude();
00092 if (isFixed) GetAmplPar()->SetFixed(kTRUE);
00093 return kTRUE;
00094 }
00095
00096 Bool_t TGo4FitComponent::RemoveAmpl() {
00097 if (GetAmplPar()==0) return kFALSE;
00098 RemoveParByIndex(GetAmplIndex());
00099 SetAmplIndex(-1);
00100 return kTRUE;
00101 }
00102
00103 void TGo4FitComponent::GetRangeCondition(Int_t n, Int_t& typ, Int_t& naxis, Double_t& left, Double_t& right) const {
00104 if ((n>=0) && (n<GetNumRangeCondition())) {
00105 Int_t naxis1 = fxRangeAxis[n*2];
00106 Int_t naxis2 = fxRangeAxis[n*2+1];
00107 Double_t value1 = fxRangeValue[n*2];
00108 Double_t value2 = fxRangeValue[n*2+1];
00109
00110 if ((naxis1<0) && (naxis2>0)) {
00111 typ = 0;
00112 naxis = -naxis1 - 1;
00113 left = value1;
00114 right = value2;
00115 } else
00116 if ((naxis1>0) && (naxis2<0)) {
00117 typ = 1;
00118 naxis = naxis1 - 1;
00119 left = value1;
00120 right = value2;
00121 } else
00122 if (naxis1<0) {
00123 typ = 2;
00124 naxis = -naxis1 - 1;
00125 left = value1;
00126 right = 0.;
00127 } else
00128 if (naxis1>0) {
00129 typ = 3;
00130 naxis = naxis1 - 1;
00131 left = 0.;
00132 right = value1;
00133 }
00134 }
00135 }
00136
00137 void TGo4FitComponent::SetRangeCondition(Int_t n, Int_t typ, Int_t naxis, Double_t left, Double_t right) {
00138 if ((n>=0) && (n<GetNumRangeCondition())) {
00139 Int_t naxis1, naxis2;
00140 Double_t value1, value2;
00141
00142 switch (typ) {
00143 case 0: naxis1 = -(naxis+1); value1 = left;
00144 naxis2 = +(naxis+1); value2 = right;
00145 break;
00146 case 1: naxis1 = +(naxis+1); value1 = left;
00147 naxis2 = -(naxis+1); value2 = right;
00148 break;
00149 case 2: naxis1 = -(naxis+1); value1 = left;
00150 naxis2 = 0; value2 = 0.;
00151 break;
00152 case 3: naxis1 = +(naxis+1); value1 = right;
00153 naxis2 = 0; value2 = 0.;
00154 break;
00155 default: return;
00156 }
00157
00158 fxRangeAxis[n*2] = naxis1;
00159 fxRangeAxis[n*2+1] = naxis2;
00160 fxRangeValue[n*2] = value1;
00161 fxRangeValue[n*2+1] = value2;
00162 }
00163 }
00164
00165 void TGo4FitComponent::AddRangeCondition(Int_t typ, Int_t naxis, Double_t left, Double_t right) {
00166 Int_t sz = fxRangeValue.GetSize()+2;
00167 fxRangeAxis.Set(sz); fxRangeValue.Set(sz);
00168 SetRangeCondition(sz/2-1,typ,naxis,left,right);
00169 }
00170
00171 void TGo4FitComponent::RemoveRangeCondition(Int_t n) {
00172 if ((n<0) || (n>=GetNumRangeCondition())) return;
00173
00174 Int_t indx = n*2;
00175 while (indx<fxRangeAxis.GetSize()-2) {
00176 fxRangeAxis[indx]=fxRangeAxis[indx+2];
00177 fxRangeValue[indx]=fxRangeValue[indx+2];
00178 indx+=1;
00179 }
00180 fxRangeAxis.Set(indx);
00181 fxRangeValue.Set(indx);
00182 }
00183
00184 void TGo4FitComponent::SetRange(Int_t naxis, Double_t min, Double_t max) {
00185 AddRangeCondition(0,naxis,min,max);
00186 }
00187
00188 void TGo4FitComponent::ExcludeRange(Int_t naxis, Double_t min, Double_t max) {
00189 AddRangeCondition(1,naxis,min,max);
00190 }
00191
00192 void TGo4FitComponent::SetRangeMin(Int_t naxis, Double_t value) {
00193 AddRangeCondition(2,naxis,value,0.);
00194 }
00195
00196 void TGo4FitComponent::SetRangeMax(Int_t naxis, Double_t value) {
00197 AddRangeCondition(3,naxis,0.,value);
00198 }
00199
00200 void TGo4FitComponent::ClearRanges(Int_t naxis) {
00201 if (naxis<0) { fxRangeAxis.Set(0); fxRangeValue.Set(0); fxCuts.Delete(); } else {
00202 Int_t indx = 0, dindx = 0;
00203 while (indx<fxRangeAxis.GetSize()) {
00204 if ( TMath::Abs(fxRangeAxis[indx]) != (naxis+1) ) {
00205 fxRangeAxis[dindx]=fxRangeAxis[indx];
00206 fxRangeAxis[dindx+1]=fxRangeAxis[indx+1];
00207 fxRangeValue[dindx]=fxRangeValue[indx];
00208 fxRangeValue[dindx+1]=fxRangeValue[indx+1];
00209 dindx+=2;
00210 }
00211 indx+=2;
00212 }
00213 fxRangeAxis.Set(dindx);
00214 fxRangeValue.Set(dindx);
00215 if ((naxis==0) || (naxis==1)) fxCuts.Delete();
00216 }
00217 }
00218
00219 Bool_t TGo4FitComponent::IsAnyRangeLimits() {
00220 return (GetNumRangeCondition()>0) || (GetNumRangeCut()>0);
00221 }
00222
00223 void TGo4FitComponent::AddRangeCut(TCutG* cut, Bool_t exclude) {
00224 cut->SetBit(kExcludeCut, exclude);
00225 fxCuts.Add(cut);
00226 }
00227
00228 Int_t TGo4FitComponent::GetNumRangeCut() const {
00229 return fxCuts.GetLast()+1;
00230 }
00231
00232 TCutG* TGo4FitComponent::GetRangeCut(Int_t n) const {
00233 return (n>=0) && (n<=fxCuts.GetLast()) ? dynamic_cast<TCutG*> (fxCuts.At(n)) : 0;
00234 }
00235
00236 Bool_t TGo4FitComponent::IsRangeCutExcluding(Int_t n) {
00237 TCutG* cut = GetRangeCut(n);
00238 return cut==0 ? kFALSE : cut->TestBit(kExcludeCut);
00239 }
00240
00241 void TGo4FitComponent::SetRangeCutExcluding(Int_t n, Bool_t exclude) {
00242 TCutG* cut = GetRangeCut(n);
00243 if (cut) cut->SetBit(kExcludeCut, exclude);
00244 }
00245
00246 void TGo4FitComponent::RemoveRangeCut(Int_t n) {
00247 TCutG* cut = GetRangeCut(n);
00248 if (cut) {
00249 fxCuts.Remove(cut);
00250 delete cut;
00251 fxCuts.Compress();
00252 }
00253 }
00254
00255 Bool_t TGo4FitComponent::GetRangeMin(Int_t naxis, Double_t& value) {
00256 Bool_t isany = kFALSE;
00257 for(Int_t indx=0;indx<fxRangeAxis.GetSize();indx+=2)
00258 if ( fxRangeAxis[indx] == -(naxis+1) ) {
00259 Double_t zn = fxRangeValue[indx];
00260 if( (!isany) || (zn<value) ) value = zn;
00261 isany = kTRUE;
00262 }
00263 if(naxis<2)
00264 for(Int_t ncut=0;ncut<GetNumRangeCut();ncut++) {
00265 TCutG* cut = GetRangeCut(ncut);
00266 if(cut->TestBit(kExcludeCut)) continue;
00267 Double_t* arr = naxis == 0 ? cut->GetX() : cut->GetY();
00268 Double_t zn = arr[0];
00269 for(Int_t i=1;i<cut->GetN();i++)
00270 if(arr[i]<zn) zn = arr[i];
00271 if( (!isany) || (zn<value) ) value = zn;
00272 isany = kTRUE;
00273 }
00274
00275 return isany;
00276 }
00277
00278 Bool_t TGo4FitComponent::GetRangeMax(Int_t naxis, Double_t& value) {
00279 Bool_t isany = kFALSE;
00280 Double_t zn;
00281 for(Int_t indx=0;indx<fxRangeAxis.GetSize();indx+=2) {
00282 if ( (fxRangeAxis[indx] == -(naxis+1)) && (fxRangeAxis[indx+1] == +(naxis+1))) zn = fxRangeValue[indx+1]; else
00283 if ( (fxRangeAxis[indx] == +(naxis+1)) && (fxRangeAxis[indx+1] == 0)) zn = fxRangeValue[indx]; else continue;
00284 if( (!isany) || (zn>value) ) value = zn;
00285 isany = kTRUE;
00286 }
00287 if(naxis<2)
00288 for(Int_t ncut=0;ncut<GetNumRangeCut();ncut++) {
00289 TCutG* cut = GetRangeCut(ncut);
00290 if(cut->TestBit(kExcludeCut)) continue;
00291 Double_t* arr = naxis == 0 ? cut->GetX() : cut->GetY();
00292 zn = arr[0];
00293 for(Int_t i=1;i<cut->GetN();i++)
00294 if(arr[i]>zn) zn = arr[i];
00295 if( (!isany) || (zn>value) ) value = zn;
00296 isany = kTRUE;
00297 }
00298
00299 return isany;
00300 }
00301
00302 Bool_t TGo4FitComponent::CheckRangeConditions(const Double_t* values, Int_t numaxis) {
00303 Int_t condsize = GetNumRangeCondition();
00304
00305 if ((condsize==0) && (GetNumRangeCut()==0)) return kTRUE;
00306
00307 Bool_t res1 = kTRUE, res2 = kTRUE;
00308
00309 Bool_t isanycond = kFALSE;
00310
00311 for(Int_t naxis=0;naxis<numaxis;naxis++) {
00312 Char_t resaxis1 = kTRUE, resaxis2 = kFALSE;
00313 Bool_t isany = kFALSE;
00314 for(Int_t ncond=0;ncond<condsize;ncond++) {
00315
00316 Int_t typ, axisnumber;
00317 Double_t left, right;
00318 GetRangeCondition(ncond, typ, axisnumber, left, right);
00319
00320 if (axisnumber != naxis) continue;
00321
00322 switch(typ) {
00323 case 0:
00324 isany = kTRUE;
00325 if((values[naxis]>=left) && (values[naxis]<=right)) resaxis2 = kTRUE;
00326 break;
00327 case 1:
00328 if((values[naxis]>=left) && (values[naxis]<=right)) resaxis1 = kFALSE;
00329 break;
00330 case 2: if(values[naxis]<left) resaxis1 = kFALSE; break;
00331 case 3: if(values[naxis]>right) resaxis1 = kFALSE; break;
00332 }
00333 }
00334
00335 res1 = res1 && resaxis1;
00336 if (!isany) resaxis2 = kTRUE;
00337 res2 = res2 && resaxis2;
00338 isanycond = isanycond || isany;
00339 if (!res1) break;
00340 }
00341
00342 if ( res1 && !(isanycond && res2) && (numaxis>1) && (GetNumRangeCut()>0)) {
00343 res2 = kFALSE;
00344 for (Int_t n=0;n<GetNumRangeCut();n++) {
00345 TCutG* cut = GetRangeCut(n);
00346 if (cut->IsInside(values[0],values[1]))
00347 {
00348 if (cut->TestBit(kExcludeCut)) { res1 = kFALSE; break; }
00349 else { res2 = kTRUE; break; }
00350 }
00351 }
00352 }
00353
00354 return res1 && res2;
00355 }
00356
00357 void TGo4FitComponent::CollectParsTo(TGo4FitParsList& list) {
00358 TGo4FitParsList::CollectParsTo(list);
00359 for(Int_t n=0;n<NumSlots();n++) {
00360 TGo4FitSlot* slot = GetSlot(n);
00361 if (slot && slot->GetOwned()) {
00362 TGo4FitParsList* pars = dynamic_cast<TGo4FitParsList*> (slot->GetObject());
00363 if (pars) pars->CollectParsTo(list);
00364 }
00365 }
00366 }
00367
00368 void TGo4FitComponent::Print(Option_t* option) const {
00369 cout << "***************************************************************************" << endl;
00370 TGo4FitNamed::Print(option);
00371 TGo4FitParsList::Print(option);
00372 cout << " Amplitude index: " << fiAmplIndex << endl;
00373
00374 for (Int_t ncond=0; ncond<GetNumRangeCondition(); ncond++) {
00375 if (ncond==0) cout << " Range selection: " << endl;
00376 Int_t typ, naxis;
00377 Double_t left, right;
00378 GetRangeCondition(ncond, typ, naxis, left, right);
00379
00380 cout << " axis " << naxis << " ";
00381
00382 switch(typ) {
00383 case 0:cout << " select range from " << left << " to " << right; break;
00384 case 1: cout << " exclude range from " << left << " to " << right; break;
00385 case 2: cout << " set left bound to " << left; break;
00386 case 3: cout << " set right bound to " << right; break;
00387 }
00388
00389 cout << endl;
00390 }
00391
00392 for (Int_t n=0;n<GetNumRangeCut();n++) {
00393 TCutG* cut = GetRangeCut(n);
00394 if (cut->TestBit(kExcludeCut)) cout << " Exclude"; else cout << " Include";
00395 cout << " axises ranges, using TCutG object " << endl;
00396 cut->Print(option);
00397 }
00398 }