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