26 #include <TVirtualFitter.h> 36 #include "TDataMember.h" 48 fLogLikelihoodFunction(
nullptr),
55 fInitialParam(
nullptr),
57 fRMSEstimator(
nullptr),
58 fMISACEstimators(
nullptr),
73 if (streamerName!=
nullptr) fStreamer=
new TTreeSRedirector(streamerName,mode);
127 fParam=
new TVectorD(formula->GetNpar());
129 fCovar=
new TMatrixD(formula->GetNpar(),formula->GetNpar());
152 fPoints =
new TMatrixD(his->GetNbinsX(), 1);
153 fValues =
new TMatrixD(his->GetNbinsX(), 2);
154 for(Int_t iBin=0; iBin < his->GetNbinsX(); iBin++) {
155 Double_t x = his->GetXaxis()->GetBinCenter(iBin+1);
156 Double_t y = his->GetBinContent(iBin+1);
157 (*fPoints)(iBin, 0) = x;
158 Double_t err=his->GetBinError(iBin+1);
159 (*fValues)(iBin,0)=y;
160 (*fValues)(iBin,1)=(err>0)? 1./err:0;
171 Int_t nPoints=gr->GetN();
172 fPoints =
new TMatrixD(nPoints, 1);
173 fValues =
new TMatrixD(nPoints, 2);
174 for(Int_t ip=0; ip < nPoints; ip++) {
175 Double_t x = gr->GetX()[ip];
176 Double_t y = gr->GetY()[ip];
177 (*fPoints)(ip, 0) = x;
178 Double_t err=gr->GetErrorY(ip);
180 (*fValues)(ip,1)=(err>0)? 1./err:0;
210 const Double_t* likeParam= (logLike!=
nullptr) ? logLike->GetParameters():
nullptr;
212 const TMatrixD & variables= (*fitter->
GetPoints());
213 const TMatrixD & values= (*fitter->
GetValues());
214 Int_t nVars = variables.GetNcols();
215 Int_t nPoints = variables.GetNrows();
216 TVectorD param(fitter->
fFormula->GetNpar(), gin);
222 for (Int_t jPoint=0; jPoint<nPoints; jPoint++){
225 for (Int_t ivar=0; ivar<nVars; ivar++){
226 x[ivar] = variables(iPoint, ivar);
228 Double_t funX = (fitter->
GetFormula())->EvalPar(x,gin);
229 Double_t value=values(iPoint,0);
230 Double_t weight=values(iPoint,1);
231 Double_t delta = (value - funX);
234 Double_t normDelta = delta*weight;
235 toAdd=logLike->EvalPar(&normDelta,likeParam);
238 delta = TMath::Abs(delta*weight);
239 if (delta <= 2.5) toAdd= delta*delta;
240 if (delta > 2.5) toAdd= 2*(2.5)*delta - (2.5*2.5);
242 Double_t lChi2 = delta*weight;
249 TVectorD vecX(nVars, x);
250 (*(fitter->
fStreamer))<<
"fcnDebugPoint"<<
276 TString sOption=(option==
nullptr)?
"":option;
277 TPRegexp regBootstrap(
"bootstrap[0-9]*");
278 TPRegexp regTwofold(
"twofold[0-9]*");
279 TPRegexp regMISAC(
"misac\\([0-9]*,[0-9]*\\)");
282 if (regBootstrap.Match(sOption)>0){
283 TString newOption=sOption;
284 regBootstrap.Substitute(newOption,
"");
285 UInt_t nPoints=
static_cast<UInt_t
>(TString(&(sOption.Data()[sOption.Index(regBootstrap) + 9])).Atoi());
286 return Bootstrap(nPoints,
nullptr,newOption.Data());
289 if (regTwofold.Match(sOption)>0){
290 TString newOption=sOption;
291 regTwofold.Substitute(newOption,
"");
292 UInt_t nPoints=
static_cast<UInt_t
>(TString(&(sOption.Data()[sOption.Index(regTwofold) + 7])).Atoi());
296 if (regMISAC.Match(sOption)>0){
297 TString newOption=sOption;
298 regMISAC.Substitute(newOption,
"");
299 Int_t index1=sOption.Index(regMISAC)+6;
300 Int_t index2=sOption.Index(
",",index1+1)+1;
301 Int_t nPoints=TString(&(sOption.Data()[index1])).Atoi();
302 UInt_t nIter=
static_cast<UInt_t
>(TString(&(sOption.Data()[index2])).Atoi());
303 return MISAC(nPoints,nIter,
nullptr,newOption.Data());
311 ::Info(
"AliTMinuitToolkit::Fit",
"Default initial parameters set");
313 for (Int_t iParam=0; iParam<nParam; iParam++) {
314 (*fInitialParam)(iParam,0)=0;
315 (*fInitialParam)(iParam,1)=1000;
316 (*fInitialParam)(iParam,2)=0;
317 (*fInitialParam)(iParam,3)=0;
328 ::Error(
"AliTMinuitToolkit::Fit()",
"Invalid fit. Values not set");
333 TVirtualFitter *minuit = TVirtualFitter::Fitter(
nullptr, nParam);
334 minuit->SetObjectFit(
this);
338 minuit->ExecuteCommand(
"SET PRINTOUT",&p1,1);
342 minuit->ExecuteCommand(
"SET PRINTOUT",&pprint,1);
346 for (Int_t iParam=0; iParam<nParam; iParam++){
347 if (sOption.Contains(
"rndmInit")){
348 Double_t initValue=(*fInitialParam)(iParam, 0)+gRandom->Gaus()*(*fInitialParam)(iParam,1);
351 minuit->SetParameter(iParam, Form(
"p[%d]",iParam), (*
fInitialParam)(iParam,0), (*
fInitialParam)(iParam,1), (*
fInitialParam)(iParam, 2), (*
fInitialParam)(iParam, 3));
373 for (Int_t ivar=0; ivar<nParam; ivar++){
374 (*fParam)(ivar) = minuit->GetParameter(ivar);
375 fFormula->SetParameter(ivar, minuit->GetParameter(ivar));
381 for (Int_t ivar=0; ivar<nParam; ivar++){
382 (*fParam)(ivar) = minuit->GetParameter(ivar);
383 fFormula->SetParameter(ivar, minuit->GetParameter(ivar));
387 if (
fCovar==
nullptr)
fCovar =
new TMatrixD(nParam, nParam);
388 if (minuit->GetCovarianceMatrix()){
389 fCovar->SetMatrixArray(minuit->GetCovarianceMatrix());
416 TString query=values;
419 if (inputTree==
nullptr){
420 ::Error(
"AliTMinuitToolkit::FillFitter",
"Input tree==NULL");
427 if (doReset == 0 &&
fPoints !=
nullptr){
428 if (
fPoints->GetNrows()!=nVars){
429 ::Error(
"AliTMinuitToolkit::FillFitter",
"Non compatible number of variables: %d instead of %d: variables: %s",nVars,
fPoints->GetNrows(), query.Data());
434 Long64_t entries = inputTree->Draw(query.Data(),selection.Data(),
"goff para",nEntries,firstEntry);
436 ::Error(
"AliTMinuitToolkit::FillFitter",
"badly formatted values or variables: %s",query.Data());
437 ::Error(
"AliTMinuitToolkit::FillFitter",
"valueDescription: %s",values.Data());
438 ::Error(
"AliTMinuitToolkit::FillFitter",
"variables: %s",variables.Data());
442 if (doReset ||
fPoints==
nullptr) {
444 fPoints=
new TMatrixD(entries,nVars);
445 fValues=
new TMatrixD(entries,nVal);
448 fPoints->ResizeTo(index0+Int_t(entries),nVars);
449 fValues->ResizeTo(index0+Int_t(entries),nVal);
451 for (Int_t iPoint=0; iPoint<entries; iPoint++){
452 for (Int_t iVar=0; iVar<nVars; iVar++){
453 (*fPoints)(index0+iPoint,iVar)=inputTree->GetVal(iVar+nVal)[iPoint];
455 for (Int_t iVal=0; iVal<nVal; iVal++){
456 (*fValues)(index0+iPoint,iVal)=inputTree->GetVal(iVal)[iPoint];
468 TString inputString(
fFormula->GetTitle());
469 TString sOption(option);
473 ::Error(
"AliTMinuitToolkit::GetFitFunctionAsAlias",
"Variable names not defined");
477 for (Int_t iDim=0; iDim<
fFormula->GetNdim(); iDim++){
479 if (sOption.Contains(
"latex") &&
tree){
481 if (meta) varName=meta->GetTitle();
483 inputString.ReplaceAll(TString::Format(
"x[%d]",iDim).Data(), varName.Data());
485 for (Int_t iPar=0; iPar<
fFormula->GetNpar(); iPar++){
486 if (sOption.Contains(
"latex")==0){
487 inputString.ReplaceAll(TString::Format(
"[%d]",iPar).Data(), TString::Format(
"(%f)",(*
fParam)[iPar]).Data());
490 inputString.ReplaceAll(TString::Format(
"[%d]", iPar).Data(),
493 inputString.ReplaceAll(TString::Format(
"[%d]", iPar).Data(),
506 return gRandom->Gaus(mean,sigma);
514 return gRandom->Landau(mean,sigma);
525 Double_t vCauchy=p[1]/(TMath::Pi()*(p[1]*p[1]+(*x)*(*x)));
526 Double_t vGaus=(TMath::Abs(*x)<20) ? TMath::Gaus(*x,0,1.,kTRUE):0.;
527 Double_t p0= p[0]*TMath::Gaus(0,0,1,kTRUE)+(1-p[0])/(TMath::Pi()*p[1]);
528 return -2.*TMath::Log((p[0]*vGaus+(1-p[0])*vCauchy)/p0);
537 Double_t absX=TMath::Abs(x[0]);
538 if (absX<p[0])
return absX*absX;
539 return p[0]*(2*absX-p[0]);
548 Double_t p2=p[0]*p[0];
549 Double_t x2=x[0]*x[0];
550 Double_t result=2.*p2*(TMath::Sqrt(1.+x2/p2)-1.);
564 static Float_t msqrt2=1./TMath::Sqrt(2.);
565 Double_t gaussPart=p[0]*TMath::Exp(-(TMath::Power(TMath::Abs(x[0]-p[1])/p[2],p[3])));
566 Double_t erfPart=(1.+TMath::Erf(p[4]*(x[0]-p[1])/p[2]*msqrt2));
567 return gaussPart*erfPart;
583 Int_t nPoints=
fPoints->GetNrows();
588 TObjString rName(
"bootstrap");
589 if (reportName!=
nullptr) rName=reportName;
590 std::vector< std::vector<double> > vecPar(static_cast<unsigned long>(nPar), std::vector<double>(nIter));
591 for (UInt_t iter=0; iter<nIter; iter++){
592 for (Int_t iPoint=0; iPoint<nPoints; iPoint++){
593 fPointIndex[iPoint]=
static_cast<Int_t
>(gRandom->Rndm() * nPoints);
600 for (Int_t iPar=0; iPar<nPar;iPar++) vecPar[iPar][iter]=(*
fParam)(iPar);
602 (*fStreamer)<<
"bootstrap"<<
605 "reportName.="<<&rName<<
606 "nPoints="<<nPoints<<
609 "fcnCounter="<<fcnCounter<<
618 for (Int_t iPar=0; iPar<nPar;iPar++) {
621 static_cast<Int_t>(TMath::Max(nIter * 0.75, 1.)));
622 par[iPar]=TMath::Median(static_cast<Long64_t>(nIter), vecPar[iPar].data());
638 Int_t nPoints =
fPoints->GetNrows();
639 TArrayI indexFold(nPoints);
640 TArrayD rndmCV(nPoints);
642 Double_t chi2_00, chi2_01, chi2_11;
646 TObjString rName(reportName);
647 std::vector<std::vector<double> > vecPar(static_cast<unsigned long>(2 * nPar + 4), std::vector<double>(nIter));
648 for (UInt_t iter = 0; iter < nIter; iter++) {
649 for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
650 rndmCV[iPoint] = gRandom->Rndm() * nPoints;
652 TMath::Sort(nPoints, rndmCV.GetArray(), indexFold.GetArray());
654 fPointIndex.Set(nPoints / 2, indexFold.GetArray());
656 for (Int_t iPar = 0; iPar < nPar; iPar++) vecPar[iPar][iter] = (*
fParam)(iPar);
661 fPointIndex.Set(nPoints - nPoints / 2, &(indexFold.GetArray()[nPoints / 2]));
664 for (Int_t iPar = 0; iPar < nPar; iPar++) vecPar[nPar + iPar][iter] = (*
fParam)(iPar);
666 vecPar[2 * nPar][iter] = chi2_00 + chi2_01 + chi2_11;
670 TMatrixD covar(covar0);
673 TMatrixD delta(nPar, 1, (param1 - param0).GetMatrixArray());
674 TMatrixD delta2(covar, TMatrixD::kMult, delta);
676 TMatrixD
chi2(delta, TMatrixD::kMult, delta2);
677 chi2 *= vecPar[2 * nPar][iter];
678 vecPar[2 * nPar + 1][iter] =
chi2(0, 0);
679 Double_t logLike = chi2_00 + chi2_01 + chi2_11;
680 Double_t normDistance = TMath::Sqrt(
chi2(0, 0));
686 (*fStreamer) <<
"crossValidation" <<
687 "reportName.=" << &rName <<
690 "nPoints=" << nPoints <<
691 "chi2_00=" << chi2_00 <<
692 "chi2_01=" << chi2_01 <<
693 "chi2_11=" << chi2_11 <<
695 "fcnCounter=" << fcnCounter <<
696 "param0.=" << ¶m0 <<
697 "covar0.=" << &covar0 <<
698 "param1.=" << ¶m1 <<
699 "covar1.=" << &covar1 <<
700 "logLike=" << logLike <<
"normDistance=" << normDistance <<
721 TObjString rName(reportName);
722 const Double_t kRelMedDistanceCut=2;
723 Int_t nPoints=
fPoints->GetNrows();
725 Int_t nSamples=nFitPoints*nIter;
726 Int_t nRepeat=(1+(nSamples/nPoints));
727 Int_t *permutationIndex=
new Int_t[nRepeat*nPoints];
728 Double_t *xrndm=
new Double_t[nPoints];
729 std::vector<TMatrixD*> paramArray(nIter);
730 std::vector<TMatrixD*> covarArray(nIter);
731 std::vector<double> logLike(nIter);
732 std::vector<double> medDistance(nIter);
733 std::vector<int> fitStatus(nIter);
738 for (Int_t iR=0; iR<nRepeat; iR++){
739 for (Int_t iPoint=0; iPoint<nPoints; iPoint++){
740 xrndm[iPoint]=gRandom->Rndm();
742 TMath::Sort(nPoints, xrndm, &(permutationIndex[iR*nPoints]));
745 for (UInt_t iter=0; iter<nIter; iter++){
746 fPointIndex.Set(nFitPoints, &(permutationIndex[iter*nFitPoints]));
751 paramArray[iter] =
new TMatrixD(nPar,1,
fParam->GetMatrixArray());
752 covarArray[iter] =
new TMatrixD(*
fCovar);
755 std::vector< std::vector<double> > logDistance(nIter, std::vector<double>(nIter));
756 for (UInt_t iter0=0; iter0<nIter; iter0++){
757 for (UInt_t iter1=0; iter1<nIter; iter1++){
758 if ( ((fitStatus[iter0]&
kCovarFailed)==0 && (fitStatus[iter1]&kCovarFailed))==0){
759 TMatrixD covar(*(covarArray[iter0]));
760 covar+=*(covarArray[iter1]);
762 TMatrixD delta(*(paramArray[iter0]));
763 delta-=*(paramArray[iter1]);
764 TMatrixD delta2(covar,TMatrixD::kMult,delta);
766 TMatrixD
chi2(delta,TMatrixD::kMult,delta2);
767 chi2*=logLike[iter0]+logLike[iter1];
769 Double_t normDistance = TMath::Sqrt(
chi2(0, 0));
770 logDistance[iter0][iter1] = normDistance;
772 logDistance[iter0][iter1]=-1.;
775 logDistance[iter0][iter1]=-1.;
780 for (UInt_t iter=0; iter<nIter; iter++){
781 medDistance[iter]=TMath::Median(nIter, logDistance[iter].data());
783 Double_t medMedDistance=TMath::Median(nIter,medDistance.data());
788 for (Int_t iPar=0;iPar<nPar; iPar++){
789 std::vector<double>workingArray(nIter);
791 for (UInt_t iter=0; iter<nIter; iter++){
792 if (medDistance[iter]<0)
continue;
793 if (medDistance[iter]/medMedDistance>kRelMedDistanceCut)
continue;
794 workingArray[nAccepted]=(*(paramArray[iter]))(iPar,0);
798 (*fMISACEstimators)(0,iPar)=TMath::Median(nAccepted,workingArray.data());
799 (*fMISACEstimators)(1,iPar)=TMath::Mean(nAccepted,workingArray.data());
800 (*fMISACEstimators)(2,iPar)=TMath::RMS(nAccepted,workingArray.data());
808 for (UInt_t iter=0; iter<nIter; iter++){
809 (*fStreamer)<<
"misac"<<
811 "reportName.="<<&rName<<
813 "nPoints="<<nPoints<<
814 "param.="<<paramArray[iter]<<
815 "covar.="<<covarArray[iter]<<
816 "medDistance="<<medDistance[iter]<<
817 "medMedDistance="<<medMedDistance<<
824 delete [] permutationIndex;
840 likeGausCachy->SetParameters(0.8,1);
841 likePseudoHuber->SetParameter(0,3);
842 likeGausCachy->GetXaxis()->SetTitle(
"#Delta");
843 likeGausCachy->GetYaxis()->SetTitle(
"-logLikelihood");
844 likeGausCachy->SetLineColor(2);
845 likePseudoHuber->GetXaxis()->SetTitle(
"#Delta");
846 likePseudoHuber->GetYaxis()->SetTitle(
"-logLikelihood");
847 likePseudoHuber->SetLineColor(4);
849 for (Int_t iPol=0; iPol<10; iPol++){
850 TMatrixD initPar(iPol+1,4);
851 for (Int_t iPar=0; iPar<iPol+1; iPar++) initPar(iPar,1)=1;
853 TF1 *fpol =
new TF1(TString::Format(
"fpol%d",iPol).Data(),TString::Format(
"pol%d",iPol).Data());
857 fitter1D->SetName(TString::Format(
"pol%d",iPol).Data());
861 fitter1DR->SetVerbose(0x1); fitter1DR->SetFitFunction(fpol,kTRUE);
862 fitter1DR->SetLogLikelihoodFunction(likeGausCachy);
863 fitter1DR->SetInitialParam(&initPar);
864 fitter1DR->SetName(TString::Format(
"pol%dR",iPol).Data());
868 fitter1DH->SetVerbose(0x1); fitter1DH->SetFitFunction(fpol,kTRUE);
869 fitter1DH->SetInitialParam(&initPar);
871 fitter1DH->SetLogLikelihoodFunction(likePseudoHuber);
872 fitter1DH->SetName(TString::Format(
"pol%dH",iPol).Data());
876 TF1 *fGaus =
new TF1(
"fgaus",
"gaus");
877 TMatrixD initPar(3,4);
878 initPar(0,0)=0; initPar(0,1)=1;
879 initPar(1,0)=0; initPar(1,1)=1;
880 initPar(2,0)=1; initPar(2,1)=1;
904 TString sFormula =
"[0]*x[0]";
905 for (Int_t iPlane=1; iPlane<nPlanes; iPlane++) sFormula+=TString::Format(
"+[%d]*x[%d]", iPlane,iPlane);
906 TFormula *formula =
new TFormula(TString::Format(
"hyp%dR",nPlanes).Data(), sFormula.Data());
909 if (logLikeType==0) {
910 TF1 *likeGaus =
new TF1(
"likeGausCachy",
"x*x*0.5", -10, 10);
912 fitter->SetName(TString::Format(
"hyp%d", nPlanes).Data());
916 likeGausCachy->SetParameters(0.8, 1);
918 fitter->SetName(TString::Format(
"hyp%dR", nPlanes).Data());
922 likePseudoHuber->SetParameter(0,3);
924 fitter->SetName(TString::Format(
"hyp%dH", nPlanes).Data());
945 if (fitter==
nullptr){
946 ::Error(
"AliTMinuitToolkit::Fit",
"Non supported fitter %s. \nfitter can be added to the list using. SetPredefinedFitter", fitterName);
950 ::Error(
"AliTMinuitToolkit::Fit",
"NULL pointer");
954 TF1 * fitFun = (TF1*)(fitter->
GetFormula()->Clone());
955 fitFun->SetParameters(fitter->
GetParameters()->GetMatrixArray());
957 his->GetListOfFunctions()->AddLast(fitFun);
959 fitFun->SetRange(xMin,xMax);
961 fitFun->SetRange(his->GetXaxis()->GetXmin(), his->GetXaxis()->GetXmax());
963 if (hisOption) his->Draw(hisOption);
983 if (fitter==
nullptr){
984 ::Error(
"AliTMinuitToolkit::Fit",
"Non supported fitter %s. \nfitter can be added to the list using. SetPredefinedFitter", fitterName);
987 if (graph==
nullptr){
988 ::Error(
"AliTMinuitToolkit::Fit",
"NULL pointer");
992 TF1 * fitFun = (TF1*)(fitter->
GetFormula()->Clone());
993 fitFun->SetParameters(fitter->
GetParameters()->GetMatrixArray());
994 fitFun->SetName(TString::Format(
"%s:%s",fitter->GetName(), fitOption).Data());
995 fitFun->SetTitle(TString::Format(
"%s:%s",fitter->GetName(), fitOption).Data());
997 graph->GetListOfFunctions()->AddLast(fitFun);
999 fitFun->SetRange(xMin,xMax);
1001 fitFun->SetRange(graph->GetXaxis()->GetXmin(), graph->GetXaxis()->GetXmax());
1003 if (graphOption) graph->Draw(graphOption);
1015 TString funOption=option;
1016 TPRegexp regFunOption(
"funOption\\(");
1018 if (regFunOption.Match(funOption)){
1019 Int_t index0=funOption.Index(regFunOption)+9;
1020 Int_t index1=funOption.Index(
")",index0+1);
1021 if (index1<index0) {
1022 ::Error(
"AliTMinuitToolkit::SetFunctionDrawOption",
"Invalid function draw option syntax %s", option);
1025 Int_t index=index0+1;
1026 Int_t color=TString(&(funOption.Data()[index])).Atoi();
1027 if (color>0) fun->SetLineColor(static_cast<Color_t>(color));
1028 index=funOption.Index(
",",index+1)+1;
1030 Int_t width=TString(&(funOption.Data()[index])).Atoi();
1031 if (width>0) fun->SetLineWidth(static_cast<Width_t>(width));
1032 index=funOption.Index(
",",index+1)+1;
1034 Int_t style=TString(&(funOption.Data()[index])).Atoi();
1035 if (style>0) fun->SetLineStyle(static_cast<Style_t>(style));
for(Int_t itree=0;itree< arrInputTreesDistortionCalib->GetEntriesFast();++itree)