00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4FitData.h"
00015
00016 #include "Riostream.h"
00017
00018 #include "TMath.h"
00019 #include "TObjArray.h"
00020 #include "TArrayC.h"
00021 #include "TH1.h"
00022 #include "TH2.h"
00023 #include "TH3.h"
00024 #include "TGraph.h"
00025 #include "TClass.h"
00026
00027 #include "TGo4FitSlot.h"
00028 #include "TGo4FitAxisTrans.h"
00029
00030
00031 TGo4FitData::TGo4FitData() : TGo4FitComponent(),
00032 fiDataType(0), fbUseBinScale(kFALSE), fiTakeSigmasFrom(1), fdSigmaValue(1.), fdExcludeLessThen(0.),
00033 fxAxisTrans() {
00034 ResetAllPoinetrs();
00035 }
00036
00037 TGo4FitData::TGo4FitData(const char* iName, const char* iTitle, Int_t iDataType, Bool_t AddAmpl) :
00038 TGo4FitComponent(iName,iTitle), fiDataType(iDataType),
00039 fbUseBinScale(kFALSE), fiTakeSigmasFrom(1), fdSigmaValue(1.), fdExcludeLessThen(0.),
00040 fxAxisTrans() {
00041
00042 ResetAllPoinetrs();
00043
00044 if(AddAmpl) NewAmplitude("Ampl",1.0,kTRUE);
00045
00046 fxAxisTrans.SetOwner(kTRUE);
00047 }
00048
00049 TGo4FitData::~TGo4FitData() {
00050 ReleaseAllPointers();
00051 }
00052
00053
00054 Bool_t TGo4FitData::SetNumberOfTransSlots(Int_t nslots) {
00055 Int_t oldnum = GetNumberOfTransSlots();
00056 if ( (nslots<0) || (nslots == oldnum) ) return kFALSE;
00057
00058 if (oldnum<nslots)
00059 for(Int_t n=oldnum;n<nslots;n++) {
00060 TString name("Trans");
00061 name+=n;
00062 fxAxisTrans.Add(new TGo4FitSlot(name.Data(),"Axis transformation", this, TGo4FitAxisTrans::Class(), kFALSE));
00063 }
00064 else
00065 for (Int_t n=oldnum;n>nslots;n--) {
00066 TObject* slot = fxAxisTrans.Last();
00067 fxAxisTrans.Remove(slot);
00068 fxAxisTrans.Compress();
00069 delete slot;
00070 }
00071 SetUpdateSlotList();
00072 return kTRUE;
00073 }
00074
00075 TGo4FitSlot* TGo4FitData::GetAxisTransSlot(Int_t nslot)
00076 {
00077 return (nslot>=0) && (nslot<=fxAxisTrans.GetLast()) ? dynamic_cast<TGo4FitSlot*> (fxAxisTrans[nslot]) : 0;
00078 }
00079
00080 TGo4FitAxisTrans* TGo4FitData::GetAxisTrans(Int_t nslot)
00081 {
00082 TGo4FitSlot* slot = GetAxisTransSlot(nslot);
00083 return (slot==0) ? 0 : dynamic_cast<TGo4FitAxisTrans*> (slot->GetObject());
00084 }
00085
00086 void TGo4FitData::SetAxisTrans(Int_t nslot, TGo4FitAxisTrans *Trans, Bool_t TransOwned)
00087 {
00088 if (nslot<0) return;
00089 if(nslot>=GetNumberOfTransSlots())
00090 SetNumberOfTransSlots(nslot+1);
00091 ((TGo4FitSlot*) (fxAxisTrans[nslot]))->SetObject(Trans,TransOwned);
00092 }
00093
00094 void TGo4FitData::AddAxisTrans(TGo4FitAxisTrans* Trans, Bool_t TransOwned) {
00095 Int_t nslot = GetNumberOfTransSlots();
00096 SetNumberOfTransSlots(nslot+1);
00097 ((TGo4FitSlot*) (fxAxisTrans[nslot]))->SetObject(Trans,TransOwned);
00098 }
00099
00100 void TGo4FitData::SetAxisTransNeeded(Int_t nslot, Bool_t iNeeded) {
00101 if( iNeeded && (nslot>=GetNumberOfTransSlots()))
00102 SetNumberOfTransSlots(nslot+1);
00103 if ((nslot>=0) && (nslot<GetNumberOfTransSlots()))
00104 ((TGo4FitSlot*) (fxAxisTrans[nslot]))->SetNeeded(iNeeded);
00105 }
00106
00107 Bool_t TGo4FitData::IsAnyDataTransform() {
00108 if (GetUseBinScale() || (GetExcludeLessThen()>0)) return kTRUE;
00109 for (Int_t n=0;n<GetNumberOfTransSlots();n++)
00110 if (GetAxisTrans(n)) return kTRUE;
00111 return kFALSE;
00112 }
00113
00114 TObject* TGo4FitData::CreateDrawObject(const char* ObjName) {
00115 TGo4FitDataIter* iter = MakeIter();
00116 if (iter==0) return 0;
00117 TObject* obj = iter->CreateDrawObject(ObjName);
00118 delete iter;
00119 return obj;
00120 }
00121
00122 Bool_t TGo4FitData::Initialize(Int_t UseBuffers) {
00123
00124 TGo4FitDataIter* iter = MakeIter();
00125 if (iter==0) return kFALSE;
00126
00127 fiBinsSize = iter->CountPoints(kTRUE);
00128
00129 fiIndexesSize = iter->IndexesSize();
00130 fiScalesSize = iter->ScalesSize();
00131
00132 Bool_t use = ((UseBuffers<0) && GetUseBuffers()) || (UseBuffers>0);
00133
00134 if (use)
00135 for(Int_t n=0; n<GetNumberOfTransSlots();n++) {
00136 TGo4FitAxisTrans* trans = GetAxisTrans(n);
00137 if (trans && !trans->IsAllParsFixed()) {
00138 use = kFALSE;
00139 break;
00140 }
00141 }
00142
00143 if (use) {
00144
00145 fxValues = new Double_t[fiBinsSize];
00146 fxStandDev = new Double_t[fiBinsSize];
00147 fxBinsResult = new Double_t[fiBinsSize];
00148
00149 if (iter->HasIndexes()) fxFullIndex = new Int_t[fiBinsSize*fiIndexesSize];
00150 fxFullScale = new Double_t[fiBinsSize*fiScalesSize];
00151 if (iter->HasWidths()) fxFullWidth = new Double_t [fiBinsSize*fiScalesSize];
00152
00153 Int_t nbin = 0;
00154 if (iter->Reset()) do {
00155
00156 fxValues[nbin] = iter->Value();
00157 fxStandDev[nbin] = iter->StandardDeviation();
00158
00159 if(fxFullIndex)
00160 for(Int_t n=0;n<fiIndexesSize;n++)
00161 fxFullIndex[nbin*fiIndexesSize+n] = iter->Indexes()[n];
00162
00163 if(fxFullScale)
00164 for(Int_t naxis = 0;naxis<fiScalesSize;naxis++)
00165 fxFullScale[nbin*fiScalesSize+naxis] = iter->Scales()[naxis];
00166
00167 if(fxFullWidth && iter->HasWidths())
00168 for(Int_t naxis = 0;naxis<fiScalesSize;naxis++)
00169 fxFullWidth[nbin*fiScalesSize+naxis] = iter->Widths()[naxis];
00170
00171 nbin++;
00172 } while (iter->Next());
00173 }
00174
00175 delete iter;
00176
00177 return kTRUE;
00178 }
00179
00180 void TGo4FitData::Finalize() {
00181 ReleaseAllPointers();
00182 }
00183
00184 void TGo4FitData::ResetAllPoinetrs() {
00185 fiBinsSize = 0;
00186 fiIndexesSize = 0;
00187 fiScalesSize = 0;
00188
00189 fxValues = 0;
00190 fxStandDev = 0;
00191 fxBinsResult = 0;
00192
00193 fxFullScale = 0;
00194 fxFullWidth = 0;
00195
00196 fxFullIndex = 0;
00197 }
00198
00199 void TGo4FitData::ReleaseAllPointers() {
00200 if (fxValues) delete[] fxValues;
00201
00202 if (fxStandDev) delete[] fxStandDev;
00203
00204 if (fxBinsResult) delete[] fxBinsResult;
00205
00206 if (fxFullIndex) delete[] fxFullIndex;
00207
00208 if (fxFullScale) delete[] fxFullScale;
00209
00210 if (fxFullWidth) delete[] fxFullWidth;
00211
00212 ResetAllPoinetrs();
00213 }
00214
00215 Bool_t TGo4FitData::DefineScaleMinMax(Int_t naxis, Double_t& min, Double_t& max) {
00216 TGo4FitDataIter* iter = MakeIter();
00217 if (iter==0) return kFALSE;
00218 Bool_t res = kFALSE;
00219 if (iter->Reset(kFALSE) && (iter->ScalesSize()<=naxis)) {
00220 min = iter->Scales()[naxis]; max = min;
00221 do {
00222 Double_t value = iter->Scales()[naxis];
00223 if (value<min) min = value; else
00224 if (value>max) max = value;
00225 } while (iter->Next(kFALSE));
00226 res = kTRUE;
00227 }
00228
00229 delete iter;
00230 return res;
00231 }
00232
00233 Int_t TGo4FitData::DefineDimensions() {
00234 TGo4FitDataIter* iter = MakeIter();
00235 if (iter==0) return 0;
00236 Int_t res = 0;
00237 if (iter->Reset(kFALSE)) res = iter->IndexesSize();
00238 delete iter;
00239 return res;
00240 }
00241
00242 Int_t TGo4FitData::DefineBinsSize()
00243 {
00244 TGo4FitDataIter* iter = MakeIter();
00245 if (iter==0) return 0;
00246
00247 Int_t res = iter->CountPoints(kTRUE);
00248 delete iter;
00249
00250 return res;
00251 }
00252
00253 const Double_t* TGo4FitData::GetScaleValues(const Int_t nbin)
00254 {
00255 if(fxFullScale) return &(fxFullScale[nbin*GetScalesSize()]);
00256 else return 0;
00257 }
00258
00259 const Double_t* TGo4FitData::GetWidthValues(const Int_t nbin)
00260 {
00261 if(fxFullWidth) return &(fxFullWidth[nbin*GetScalesSize()]);
00262 else return 0;
00263 }
00264
00265 const Int_t* TGo4FitData::GetFullIndex(Int_t nbin)
00266 {
00267 if (fxFullIndex) return &(fxFullIndex[nbin*GetIndexesSize()]);
00268 else return 0;
00269 }
00270
00271 Bool_t TGo4FitData::IsCompatibleData(TGo4FitData* data)
00272 {
00273 if (data==0) return kFALSE;
00274 TGo4FitDataIter* iter = data->MakeIter();
00275 if (iter==0) return kFALSE;
00276
00277 Bool_t res = kFALSE;
00278 if (iter->Reset(kFALSE)) res = (iter->IndexesSize()==GetIndexesSize()) && (GetIndexesSize()>0);
00279 delete iter;
00280
00281 return res;
00282 }
00283
00284 void TGo4FitData::ApplyRangesForModelMask(TGo4FitComponent* model, Char_t* ModelMask)
00285 {
00286
00287 if (ModelMask==0) return;
00288
00289 if (BuffersAllocated())
00290 for(Int_t nbin=0;nbin<GetBinsSize();nbin++) {
00291 const Double_t* values = GetScaleValues(nbin);
00292
00293 Bool_t res = model->CheckRangeConditions(values, GetScalesSize());
00294
00295 ModelMask[nbin] = res ? 1 : 0;
00296 }
00297 else {
00298 TGo4FitDataIter* iter = MakeIter();
00299 Int_t nbin = 0;
00300 if (iter->Reset()) do {
00301 Bool_t res = model->CheckRangeConditions(iter->Scales(), iter->ScalesSize());
00302 ModelMask[nbin] = res ? 1 : 0;
00303 nbin++;
00304 } while (iter->Next());
00305 }
00306 }
00307
00308 void TGo4FitData::FillSlotList(TSeqCollection* list)
00309 {
00310 TGo4FitComponent::FillSlotList(list);
00311 for(Int_t n=0;n<=fxAxisTrans.GetLast();n++)
00312 list->Add(fxAxisTrans[n]);
00313 }
00314
00315 void TGo4FitData::Print(Option_t* option) const
00316 {
00317 TGo4FitComponent::Print(option);
00318 cout << " Data type: ";
00319 switch(fiDataType) {
00320 case 1: cout << "histogram" << endl; break;
00321 case 2: cout << "graph" << endl; break;
00322 default: cout << fiDataType << endl;
00323 }
00324 cout << " Use bin scale: " << fbUseBinScale << endl;
00325 cout << " Take sigmas from: " ;
00326 switch(GetSigmaSource()) {
00327 case 0: cout << "none" << endl; break;
00328 case 1: cout << "data" << endl; break;
00329 case 2: cout << "const value " << GetSigmaValue() << endl; break;
00330 }
00331 cout << " Exclude bins less then: " << GetExcludeLessThen() << endl;
00332 cout << " Axis transformation data: " << endl;
00333 fxAxisTrans.Print(option);
00334 }
00335
00336 void TGo4FitData::Streamer(TBuffer& b)
00337 {
00338 if (b.IsReading()) {
00339
00340 TGo4FitData::Class()->ReadBuffer(b, this);
00341
00342 for(Int_t n=0;n<=fxAxisTrans.GetLast();n++) {
00343 TGo4FitSlot* dc = (TGo4FitSlot*) fxAxisTrans[n];
00344 dc->SetDefaults(this, TGo4FitAxisTrans::Class());
00345 }
00346
00347 } else {
00348 TGo4FitData::Class()->WriteBuffer(b, this);
00349 }
00350 }
00351
00352
00353
00354
00355 TGo4FitDataIter::TGo4FitDataIter() : TObject(),
00356 fxIndexes(), fxScales(), fxWidths(), fdValue(0.), fdStandardDeviation(1.), fiNumPoint(0), fbReachEnd(kTRUE) {
00357 }
00358
00359 TGo4FitDataIter::~TGo4FitDataIter() {
00360 }
00361
00362 Bool_t TGo4FitDataIter::ReserveArrays(Int_t NumDimen, Int_t NumOwnAxis, Bool_t HasWidth) {
00363 TGo4FitData* data = GetData();
00364 if (data==0) return kFALSE;
00365
00366 fxIndexes.Set(NumDimen); fxIndexes.Reset(0);
00367
00368 Int_t size = 0;
00369 if (data->GetUseBinScale()) size = NumDimen;
00370 else size = NumOwnAxis;
00371
00372 if (size<=0) return kFALSE;
00373
00374 fxScales.Set(size); fxScales.Reset(0.);
00375 if (HasWidth) { fxWidths.Set(size); fxWidths.Reset(1.); }
00376 else fxWidths.Set(0);
00377
00378 return kTRUE;
00379 }
00380
00381 void TGo4FitDataIter::TransformScales(Double_t* scales)
00382 {
00383 TGo4FitData* data = GetData();
00384 for(Int_t nslot=0;nslot<data->GetNumberOfTransSlots();nslot++) {
00385 TGo4FitAxisTrans* trans = data->GetAxisTrans(nslot);
00386 if (trans) trans->Transformation(scales, ScalesSize());
00387 }
00388 }
00389
00390 Bool_t TGo4FitDataIter::ProduceScales(const Int_t* index, const Double_t* ownscales, const Double_t* ownwidths)
00391 {
00392 TGo4FitData* data = GetData();
00393 if (data==0) return kFALSE;
00394
00395 if ( (data->GetUseBinScale()) || (ownscales==0) ) {
00396 if (index==0) return kFALSE;
00397 Double_t add = (data->GetDataType() == TGo4FitData::dtHistogram) ? .5 : 0.;
00398 for(Int_t n=0;n<fxScales.GetSize();n++)
00399 fxScales[n] = index[n] + add;
00400 fxWidths.Reset(1.);
00401 } else {
00402 for(Int_t n=0; n<fxScales.GetSize();n++)
00403 fxScales[n] = ownscales[n];
00404 if (ownwidths!=0)
00405 for(Int_t n=0; n<fxWidths.GetSize();n++)
00406 fxWidths[n] = ownwidths[n];
00407 }
00408
00409 if (data->GetNumberOfTransSlots()>0) {
00410 if (fxWidths.GetSize()==ScalesSize()) {
00411 TArrayD arr1(ScalesSize()), arr2(ScalesSize());
00412 for(Int_t n=0;n<ScalesSize();n++) {
00413 arr1[n] = fxScales[n]-fxWidths[n]/2.;
00414 arr2[n] = fxScales[n]+fxWidths[n]/2.;
00415 }
00416 TransformScales(arr1.GetArray());
00417 TransformScales(arr2.GetArray());
00418 for(Int_t n=0;n<ScalesSize();n++)
00419 fxWidths[n] = TMath::Abs(arr2[n]-arr1[n]);
00420 }
00421
00422 TransformScales(fxScales.GetArray());
00423 }
00424
00425 return kTRUE;
00426 }
00427
00428 Bool_t TGo4FitDataIter::NextIndex(TArrayI& Index, TArrayI& Limits) {
00429 Int_t n=0;
00430 while (n<Index.GetSize()) {
00431 Index[n]++;
00432 if (Index[n]<Limits[n]) return kTRUE;
00433 Index[n] = 0; n++;
00434 }
00435 return kFALSE;
00436 }
00437
00438 Bool_t TGo4FitDataIter::GetDeviation() {
00439 TGo4FitData* data = GetData();
00440 if (data==0) return kFALSE;
00441 if (data->GetSigmaSource()==2) {
00442 fdStandardDeviation = data->GetSigmaValue()*data->GetSigmaValue();
00443 return kTRUE;
00444 } else return kFALSE;
00445 }
00446
00447 Bool_t TGo4FitDataIter::CheckPointForRange() {
00448 TGo4FitData* data = GetData();
00449 if (data==0) return kFALSE;
00450 if (Value()<data->GetExcludeLessThen()) return kFALSE;
00451 return data->CheckRangeConditions(Scales(),ScalesSize());
00452 }
00453
00454 Bool_t TGo4FitDataIter::Reset(Bool_t UseRanges) {
00455 fbReachEnd = kTRUE;
00456
00457 if (!StartReset()) return kFALSE;
00458
00459 fiNumPoint = 0;
00460
00461 if (!ReadCurrentPoint()) return kFALSE;
00462 if (!UseRanges) { fbReachEnd = kFALSE; return kTRUE; }
00463
00464 while (!CheckPointForRange()) {
00465 if (!ShiftToNextPoint()) return kFALSE;
00466 if (!ReadCurrentPoint()) return kFALSE;
00467 }
00468
00469 fbReachEnd = kFALSE;
00470 return kTRUE;
00471 }
00472
00473 Bool_t TGo4FitDataIter::Next(Bool_t UseRanges) {
00474 fiNumPoint++;
00475
00476 if (fbReachEnd || (GetData()==0)) { fbReachEnd = kTRUE; return kFALSE; }
00477
00478 do {
00479 if (!ShiftToNextPoint()) { fbReachEnd = kTRUE; return kFALSE; }
00480
00481 if (!ReadCurrentPoint()) { fbReachEnd = kTRUE; return kFALSE; }
00482
00483 if (!UseRanges) return kTRUE;
00484
00485 } while (!CheckPointForRange());
00486
00487 return kTRUE;
00488 }
00489
00490 Double_t TGo4FitDataIter::xWidths() const
00491 {
00492 double res = 1.;
00493 if(HasWidths())
00494 for(int n=0;n<fxWidths.GetSize();n++)
00495 res=res*fxWidths[n];
00496 return res;
00497 }
00498
00499 Int_t TGo4FitDataIter::CountPoints(Bool_t UseRanges) {
00500 if (!Reset(UseRanges)) return 0;
00501 Int_t cnt=0;
00502 do {
00503 cnt+=1;
00504 } while (Next(UseRanges)) ;
00505 return cnt;
00506 }
00507
00508 Bool_t TGo4FitDataIter::DefineIndexesLimits(TArrayI& Limits) {
00509 if (!Reset(kFALSE)) return kFALSE;
00510 if (IndexesSize()<=0) return kFALSE;
00511 Limits.Set(IndexesSize()); Limits.Reset(0);
00512 do {
00513 for(Int_t n=0;n<IndexesSize();n++)
00514 if (Indexes()[n]>Limits[n]) Limits[n] = Indexes()[n];
00515 } while(Next(kFALSE));
00516 return kTRUE;
00517 }
00518
00519 TH1* TGo4FitDataIter::CreateHistogram(const char* HistoName, Bool_t UseRanges, Bool_t SetBins) {
00520 TArrayI Limits;
00521 if (!DefineIndexesLimits(Limits)) return 0;
00522 if (!HasIndexes() || (IndexesSize()!=ScalesSize()) || !HasWidths()) return 0;
00523
00524 Int_t NumDim = IndexesSize();
00525 if (NumDim>3) NumDim=3;
00526
00527 Double_t* dummy = 0;
00528 TH1* histo = 0;
00529 switch(NumDim) {
00530 case 1: histo = new TH1D(HistoName, "result", Limits[0]+1, dummy); break;
00531 case 2: histo = new TH2D(HistoName, "result", Limits[0]+1, dummy, Limits[1]+1, dummy); break;
00532 case 3: histo = new TH3D(HistoName, "result", Limits[0]+1, dummy, Limits[1]+1, dummy, Limits[2]+1, dummy); break;
00533 default: return 0;
00534 }
00535
00536 histo->SetDirectory(0);
00537
00538 Double_t* Axises[3];
00539 for (Int_t n=0;n<NumDim;n++)
00540 Axises[n] = new Double_t[Limits[n]+2];
00541
00542 Double_t ampl = GetData()->GetAmplValue();
00543
00544 if (Reset(UseRanges)) do {
00545 if (SetBins)
00546 switch (NumDim) {
00547 case 1: histo->SetBinContent(Indexes()[0]+1, ampl*Value()); break;
00548 case 2: histo->SetBinContent(Indexes()[0]+1, Indexes()[1]+1, ampl*Value()); break;
00549 case 3: histo->SetBinContent(Indexes()[0]+1, Indexes()[1]+1, Indexes()[2]+1, ampl*Value()); break;
00550 }
00551 for(Int_t n=0;n<NumDim;n++) {
00552 Int_t indx = Indexes()[n];
00553 Axises[n][indx] = Scales()[n]-Widths()[n]/2.;
00554 Axises[n][indx+1] = Scales()[n]+Widths()[n]/2.;
00555 }
00556 } while(Next(UseRanges));
00557
00558 histo->GetXaxis()->Set(Limits[0]+1,Axises[0]);
00559 if (NumDim>1) histo->GetYaxis()->Set(Limits[1]+1,Axises[1]);
00560 if (NumDim>2) histo->GetZaxis()->Set(Limits[2]+1,Axises[2]);
00561
00562 for (Int_t n=0;n<NumDim;n++)
00563 delete[] Axises[n];
00564
00565 return histo;
00566 }
00567
00568 TGraph* TGo4FitDataIter::CreateGraph(const char* GraphName, Bool_t UseRanges, Bool_t SetBins) {
00569 Int_t NumPoints = CountPoints(UseRanges);
00570 if ((NumPoints<=0) || (ScalesSize()<1)) return 0;
00571
00572 TGraph* gr = new TGraph(NumPoints);
00573 gr->SetName(GraphName);
00574 if (Reset(UseRanges)) do {
00575 (gr->GetX())[Point()] = x();
00576 if (SetBins)
00577 (gr->GetY())[Point()] = GetData()->GetAmplValue() * Value();
00578 } while(Next(UseRanges));
00579
00580 return gr;
00581 }
00582
00583 TObject* TGo4FitDataIter::CreateDrawObject(const char* ObjName) {
00584 if (!Reset(kFALSE)) return 0;
00585 if (HasIndexes() && (IndexesSize()==ScalesSize()) && HasWidths()) return CreateHistogram(ObjName, kFALSE, kTRUE);
00586 else return CreateGraph(ObjName, kFALSE, kTRUE);
00587 }