51    int GetDimension(
const TH1 * h1) { 
return h1->GetDimension(); }
 
   52    int GetDimension(
const TGraph * ) { 
return 1; }
 
   53    int GetDimension(
const TMultiGraph * ) { 
return 1; }
 
   54    int GetDimension(
const TGraph2D * ) { 
return 2; }
 
   55    int GetDimension(
const THnBase * s1) { 
return s1->GetNdimensions(); }
 
   57    int CheckFitFunction(
const TF1 * f1, 
int hdim);
 
   60    void GetFunctionRange(
const TF1 & f1, ROOT::Fit::DataRange & range);
 
   62    void FitOptionsMake(
const char *option, Foption_t &fitOption);
 
   64    void CheckGraphFitOptions(Foption_t &fitOption);
 
   67    void GetDrawingRange(TH1 * h1, ROOT::Fit::DataRange & range);
 
   68    void GetDrawingRange(TGraph * gr, ROOT::Fit::DataRange & range);
 
   69    void GetDrawingRange(TMultiGraph * mg, ROOT::Fit::DataRange & range);
 
   70    void GetDrawingRange(TGraph2D * gr, ROOT::Fit::DataRange & range);
 
   71    void GetDrawingRange(THnBase * s, ROOT::Fit::DataRange & range);
 
   74    template <
class FitObject>
 
   75    TFitResultPtr Fit(FitObject * h1, TF1 *f1 , Foption_t & option , 
const ROOT::Math::MinimizerOptions & moption, 
const char *goption,  ROOT::Fit::DataRange & range);
 
   77    template <
class FitObject>
 
   78    void StoreAndDrawFitFunction(FitObject * h1, TF1 * f1, 
const ROOT::Fit::DataRange & range, 
bool, 
bool, 
const char *goption);
 
   80    template <
class FitObject>
 
   81    double ComputeChi2(
const FitObject & h1, TF1 &f1, 
bool useRange, 
bool usePL );
 
   87 int HFit::CheckFitFunction(
const TF1 * f1, 
int dim) {
 
   90       Error(
"Fit", 
"function may not be null pointer");
 
   94       Error(
"Fit", 
"function is zombie");
 
   98    int npar = f1->GetNpar();
 
  100       Error(
"Fit", 
"function %s has illegal number of parameters = %d", f1->GetName(), npar);
 
  105    if (f1->GetNdim() > dim) {
 
  106       Error(
"Fit",
"function %s dimension, %d, is greater than fit object dimension, %d",
 
  107             f1->GetName(), f1->GetNdim(), dim);
 
  110    if (f1->GetNdim() < dim-1) {
 
  111       Error(
"Fit",
"function %s dimension, %d, is smaller than fit object dimension -1, %d",
 
  112             f1->GetName(), f1->GetNdim(), dim);
 
  121 void HFit::GetFunctionRange(
const TF1 & f1, ROOT::Fit::DataRange & range) {
 
  123    Double_t fxmin, fymin, fzmin, fxmax, fymax, fzmax;
 
  124    f1.GetRange(fxmin, fymin, fzmin, fxmax, fymax, fzmax);
 
  126    if (range.Size(0) == 0) range.AddRange(0,fxmin,fxmax);
 
  127    if (range.Size(1) == 0) range.AddRange(1,fymin,fymax);
 
  128    if (range.Size(2) == 0) range.AddRange(2,fzmin,fzmax);
 
  133 template<
class FitObject>
 
  134 TFitResultPtr HFit::Fit(FitObject * h1, TF1 *f1 , Foption_t & fitOption , 
const ROOT::Math::MinimizerOptions & minOption, 
const char *goption, ROOT::Fit::DataRange & range)
 
  140    printf(
"fit function %s\n",f1->GetName() );
 
  144    int hdim = HFit::GetDimension(h1);
 
  145    int iret = HFit::CheckFitFunction(f1, hdim);
 
  146    if (iret != 0) 
return iret;
 
  151    if (f1->GetNdim() < hdim ) {
 
  152       if (fitOption.Integral) Info(
"Fit",
"Ignore Integral option. Model function dimension is less than the data object dimension");
 
  153       if (fitOption.Like) Info(
"Fit",
"Ignore Likelihood option. Model function dimension is less than the data object dimension");
 
  154       fitOption.Integral = 0;
 
  158    Int_t special = f1->GetNumber();
 
  159    Bool_t linear = f1->IsLinear();
 
  160    Int_t npar = f1->GetNpar();
 
  161    if (special==299+npar)  linear = kTRUE; 
 
  163    if (fitOption.Bound || fitOption.Like || fitOption.Errors || fitOption.Gradient || fitOption.More || fitOption.User|| fitOption.Integral || fitOption.Minuit)
 
  167    std::shared_ptr<TFitResult> tfr(
new TFitResult() );
 
  169    std::shared_ptr<ROOT::Fit::Fitter> fitter(
new ROOT::Fit::Fitter(std::static_pointer_cast<ROOT::Fit::FitResult>(tfr) ) );
 
  170    ROOT::Fit::FitConfig & fitConfig = fitter->Config();
 
  173    ROOT::Fit::DataOptions opt;
 
  174    opt.fIntegral = fitOption.Integral;
 
  175    opt.fUseRange = fitOption.Range;
 
  176    opt.fExpErrors = fitOption.PChi2;  
 
  177    if (fitOption.Like || fitOption.PChi2) opt.fUseEmpty = 
true;  
 
  178    if (special==300) opt.fCoordErrors = 
false; 
 
  179    if (fitOption.NoErrX) opt.fCoordErrors = 
false;  
 
  180    if (fitOption.W1 ) opt.fErrors1 = 
true;
 
  181    if (fitOption.W1 > 1) opt.fUseEmpty = 
true; 
 
  183    if (fitOption.BinVolume) {
 
  184       opt.fBinVolume = 
true; 
 
  185       if (fitOption.BinVolume == 2) opt.fNormBinVolume = 
true; 
 
  190       printf(
"use range \n" );
 
  192       HFit::GetFunctionRange(*f1,range);
 
  195    printf(
"range  size %d\n", range.Size(0) );
 
  197       double x1; 
double x2; range.GetRange(0,x1,x2);
 
  198       printf(
" range in x = [%f,%f] \n",x1,x2);
 
  203    std::shared_ptr<ROOT::Fit::BinData> fitdata(
new ROOT::Fit::BinData(opt,range) );
 
  204    ROOT::Fit::FillData(*fitdata, h1, f1);
 
  205    if (fitdata->Size() == 0 ) {
 
  206       Warning(
"Fit",
"Fit data is empty ");
 
  211    printf(
"HFit:: data size is %d \n",fitdata->Size());
 
  212    for (
unsigned int i = 0; i < fitdata->Size(); ++i) {
 
  213       if (fitdata->NDim() == 1) printf(
" x[%d] = %f - value = %f \n", i,*(fitdata->Coords(i)),fitdata->Value(i) );
 
  218    if (fitdata->GetErrorType() == ROOT::Fit::BinData::kCoordError && fitdata->Opt().fCoordErrors ) linear = 
false;
 
  220    if (fitdata->GetErrorType() == ROOT::Fit::BinData::kAsymError && fitdata->Opt().fAsymErrors ) linear = 
false;
 
  223    if (special != 0 && !fitOption.Bound && !linear) {
 
  224       if      (special == 100)      ROOT::Fit::InitGaus  (*fitdata,f1); 
 
  225       else if (special == 110 || special == 112)   ROOT::Fit::Init2DGaus(*fitdata,f1); 
 
  226       else if (special == 400)      ROOT::Fit::InitGaus  (*fitdata,f1); 
 
  227       else if (special == 410)      ROOT::Fit::Init2DGaus(*fitdata,f1); 
 
  229       else if (special == 200)      ROOT::Fit::InitExpo  (*fitdata, f1); 
 
  236    if ( (linear || fitOption.Gradient) )
 
  237       fitter->SetFunction(ROOT::Math::WrappedMultiTF1(*f1));
 
  238 #ifdef R__HAS_VECCORE 
  239    else if(f1->IsVectorized())
 
  240       fitter->SetFunction(static_cast<
const ROOT::Math::IParamMultiFunctionTempl<ROOT::Double_v> &>(ROOT::Math::WrappedMultiTF1Templ<ROOT::Double_v>(*f1)));
 
  243       fitter->SetFunction(static_cast<const ROOT::Math::IParamMultiFunction &>(ROOT::Math::WrappedMultiTF1(*f1) ) );
 
  246    if (fitdata->GetErrorType() == ROOT::Fit::BinData::kNoError) fitConfig.SetNormErrors(
true);
 
  248    if (
int(fitdata->NDim())  == hdim -1 ) fitConfig.SetNormErrors(
true);
 
  256    for (
int i = 0; i < npar; ++i) {
 
  257       ROOT::Fit::ParameterSettings & parSettings = fitConfig.ParSettings(i);
 
  261       f1->GetParLimits(i,plow,pup);
 
  262       if (plow*pup != 0 && plow >= pup) { 
 
  265       else if (plow < pup ) {
 
  266          if (!TMath::Finite(pup) && TMath::Finite(plow) )
 
  267             parSettings.SetLowerLimit(plow);
 
  268          else if (!TMath::Finite(plow) && TMath::Finite(pup) )
 
  269             parSettings.SetUpperLimit(pup);
 
  271             parSettings.SetLimits(plow,pup);
 
  276       double err = f1->GetParError(i);
 
  278          parSettings.SetStepSize(err);
 
  279       else if (plow < pup && TMath::Finite(plow) && TMath::Finite(pup) ) { 
 
  280          double step = 0.1 * (pup - plow);
 
  282          if (  parSettings.Value() < pup && pup - parSettings.Value() < 2 * step  )
 
  283             step = (pup - parSettings.Value() ) / 2;
 
  284          else if ( parSettings.Value() > plow && parSettings.Value() - plow < 2 * step )
 
  285             step = (parSettings.Value() - plow ) / 2;
 
  287          parSettings.SetStepSize(step);
 
  304    fitConfig.SetMinimizerOptions(minOption);
 
  307    if (fitOption.Verbose) fitConfig.MinimizerOptions().SetPrintLevel(3);
 
  308    if (fitOption.Quiet)    fitConfig.MinimizerOptions().SetPrintLevel(0);
 
  312       if (fitOption.Robust  ) {
 
  314          std::string type = 
"Robust";
 
  316          if (fitOption.hRobust > 0 && fitOption.hRobust < 1.)
 
  317             type += 
" (h=" + ROOT::Math::Util::ToString(fitOption.hRobust) + 
")";
 
  318          fitConfig.SetMinimizer(
"Linear",type.c_str());
 
  319          fitConfig.MinimizerOptions().SetTolerance(fitOption.hRobust); 
 
  322          fitConfig.SetMinimizer(
"Linear",
"");
 
  325       if (fitOption.More) fitConfig.SetMinimizer(
"Minuit",
"MigradImproved");
 
  330    if (fitOption.Errors) {
 
  332       fitConfig.SetParabErrors(
true);
 
  333       fitConfig.SetMinosErrors(
true);
 
  340    if (fitOption.Like)   printf(
"do  likelihood fit...\n");
 
  341    if (linear)    printf(
"do linear fit...\n");
 
  342    printf(
"do now  fit...\n");
 
  350    TVirtualFitter::FCNFunc_t  userFcn = 0;
 
  351    if (fitOption.User && TVirtualFitter::GetFitter() ) {
 
  352       userFcn = (TVirtualFitter::GetFitter())->GetFCN();
 
  353       (TVirtualFitter::GetFitter())->SetUserFunc(f1);
 
  357    if (fitOption.User && userFcn) 
 
  358       fitok = fitter->FitFCN( userFcn );
 
  359    else if (fitOption.Like)  {
 
  361       bool weight = ((fitOption.Like & 2) == 2);
 
  362       fitConfig.SetWeightCorrection(weight);
 
  363       bool extended = ((fitOption.Like & 4 ) != 4 );
 
  367       fitok = fitter->LikelihoodFit(fitdata, extended, fitOption.ExecPolicy);
 
  370       fitok = fitter->Fit(fitdata, fitOption.ExecPolicy);
 
  372    if ( !fitok  && !fitOption.Quiet )
 
  373       Warning(
"Fit",
"Abnormal termination of minimization.");
 
  377    const ROOT::Fit::FitResult & fitResult = fitter->Result();
 
  379    iret = fitResult.Status();
 
  380    if (!fitResult.IsEmpty() ) {
 
  382       f1->SetChisquare(fitResult.Chi2() );
 
  383       f1->SetNDF(fitResult.Ndf() );
 
  384       f1->SetNumberFitPoints(fitdata->Size() );
 
  386       assert((Int_t)fitResult.Parameters().size() >= f1->GetNpar() );
 
  387       f1->SetParameters( const_cast<double*>(&(fitResult.Parameters().front())));
 
  388       if ( 
int( fitResult.Errors().size()) >= f1->GetNpar() )
 
  389          f1->SetParErrors( &(fitResult.Errors().front()) );
 
  395       if (!fitOption.Nostore) {
 
  396          HFit::GetDrawingRange(h1, range);
 
  397          HFit::StoreAndDrawFitFunction(h1, f1, range, !fitOption.Plus, !fitOption.Nograph, goption);
 
  403       if (!fitOption.Quiet) {
 
  404          if (fitter->GetMinimizer() && fitConfig.MinimizerType() == 
"Minuit" &&
 
  405              !fitConfig.NormalizeErrors() && fitOption.Like <= 1) {
 
  406             fitter->GetMinimizer()->PrintResults(); 
 
  410             if (fitOption.Verbose) fitResult.PrintCovMatrix(std::cout);
 
  411             fitResult.Print(std::cout);
 
  419          TVirtualFitter * lastFitter = TVirtualFitter::GetFitter();
 
  420          TBackCompFitter * bcfitter = 
new TBackCompFitter(fitter, fitdata);
 
  421          bcfitter->SetFitOption(fitOption);
 
  422          bcfitter->SetObjectFit(h1);
 
  423          bcfitter->SetUserFunc(f1);
 
  424          bcfitter->SetBit(TBackCompFitter::kCanDeleteLast);
 
  426             bcfitter->SetFCN(userFcn);
 
  428             if (lastFitter->GetMethodCall() ) bcfitter->SetMethodCall(lastFitter->GetMethodCall() );
 
  433             TBackCompFitter * lastBCFitter = 
dynamic_cast<TBackCompFitter *
> (lastFitter);
 
  434             if (lastBCFitter && lastBCFitter->TestBit(TBackCompFitter::kCanDeleteLast) )
 
  438          TVirtualFitter::SetFitter( bcfitter );
 
  445       if (fitOption.StoreResult)
 
  447          TString name = 
"TFitResult-";
 
  448          name = name + h1->GetName() + 
"-" + f1->GetName();
 
  449          TString title = 
"TFitResult-";
 
  450          title += h1->GetTitle();
 
  452          tfr->SetTitle(title);
 
  453          return TFitResultPtr(tfr);
 
  456          return TFitResultPtr(iret);
 
  460 void HFit::GetDrawingRange(TH1 * h1, ROOT::Fit::DataRange & range) {
 
  464    Int_t ndim = GetDimension(h1);
 
  466    double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
 
  467    if (range.Size(0) == 0) {
 
  468       TAxis  & xaxis = *(h1->GetXaxis());
 
  469       Int_t hxfirst = xaxis.GetFirst();
 
  470       Int_t hxlast  = xaxis.GetLast();
 
  471       Double_t binwidx = xaxis.GetBinWidth(hxlast);
 
  472       xmin    = xaxis.GetBinLowEdge(hxfirst);
 
  473       xmax    = xaxis.GetBinLowEdge(hxlast) +binwidx;
 
  474       range.AddRange(xmin,xmax);
 
  478       if (range.Size(1) == 0) {
 
  479          TAxis  & yaxis = *(h1->GetYaxis());
 
  480          Int_t hyfirst = yaxis.GetFirst();
 
  481          Int_t hylast  = yaxis.GetLast();
 
  482          Double_t binwidy = yaxis.GetBinWidth(hylast);
 
  483          ymin    = yaxis.GetBinLowEdge(hyfirst);
 
  484          ymax    = yaxis.GetBinLowEdge(hylast) +binwidy;
 
  485          range.AddRange(1,ymin,ymax);
 
  489       if (range.Size(2) == 0) {
 
  490          TAxis  & zaxis = *(h1->GetZaxis());
 
  491          Int_t hzfirst = zaxis.GetFirst();
 
  492          Int_t hzlast  = zaxis.GetLast();
 
  493          Double_t binwidz = zaxis.GetBinWidth(hzlast);
 
  494          zmin    = zaxis.GetBinLowEdge(hzfirst);
 
  495          zmax    = zaxis.GetBinLowEdge(hzlast) +binwidz;
 
  496          range.AddRange(2,zmin,zmax);
 
  500    std::cout << 
"xmin,xmax" << xmin << 
"  " << xmax << std::endl;
 
  505 void HFit::GetDrawingRange(TGraph * gr,  ROOT::Fit::DataRange & range) {
 
  508    TH1 * h1 = gr->GetHistogram();
 
  510    if (h1) HFit::GetDrawingRange(h1, range);
 
  512 void HFit::GetDrawingRange(TMultiGraph * mg,  ROOT::Fit::DataRange & range) {
 
  515    TH1 * h1 = mg->GetHistogram();
 
  517       HFit::GetDrawingRange(h1, range);
 
  519    else if (range.Size(0) == 0) {
 
  521       double xmin = std::numeric_limits<double>::infinity();
 
  522       double xmax = -std::numeric_limits<double>::infinity();
 
  523       TIter next(mg->GetListOfGraphs() );
 
  525       while (  (g = (TGraph*) next() ) ) {
 
  526          double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
 
  527          g->ComputeRange(x1,y1,x2,y2);
 
  528          if (x1 < xmin) xmin = x1;
 
  529          if (x2 > xmax) xmax = x2;
 
  531       range.AddRange(xmin,xmax);
 
  534 void HFit::GetDrawingRange(TGraph2D * gr,  ROOT::Fit::DataRange & range) {
 
  541    if (range.Size(0) == 0)  {
 
  542       double xmin = gr->GetXmin();
 
  543       double xmax = gr->GetXmax();
 
  544       range.AddRange(0,xmin,xmax);
 
  546    if (range.Size(1) == 0)  {
 
  547       double ymin = gr->GetYmin();
 
  548       double ymax = gr->GetYmax();
 
  549       range.AddRange(1,ymin,ymax);
 
  553 void HFit::GetDrawingRange(THnBase * s1, ROOT::Fit::DataRange & range) {
 
  557    Int_t ndim = GetDimension(s1);
 
  559    for ( 
int i = 0; i < ndim; ++i ) {
 
  560       if ( range.Size(i) == 0 ) {
 
  561          TAxis *axis = s1->GetAxis(i);
 
  562          range.AddRange(i, axis->GetXmin(), axis->GetXmax());
 
  567 template<
class FitObject>
 
  568 void HFit::StoreAndDrawFitFunction(FitObject * h1, TF1 * f1, 
const ROOT::Fit::DataRange & range, 
bool delOldFunction, 
bool drawFunction, 
const char *goption) {
 
  573    std::cout <<
"draw and store fit function " << f1->GetName() << std::endl;
 
  577    Int_t ndim = GetDimension(h1);
 
  578    double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
 
  579    if (range.Size(0) ) range.GetRange(0,xmin,xmax);
 
  580    if (range.Size(1) ) range.GetRange(1,ymin,ymax);
 
  581    if (range.Size(2) ) range.GetRange(2,zmin,zmax);
 
  585    std::cout <<
"draw and store fit function " << f1->GetName()
 
  586              << 
" Range in x = [ " << xmin << 
" , " << xmax << 
" ]" << std::endl;
 
  589    TList * funcList = h1->GetListOfFunctions();
 
  591       Error(
"StoreAndDrawFitFunction",
"Function list has not been created - cannot store the fitted function");
 
  599    bool reuseOldFunction = 
false;
 
  600    if (delOldFunction) {
 
  601       TIter next(funcList, kIterBackward);
 
  603       while ((obj = next())) {
 
  604          if (obj->InheritsFrom(TF1::Class())) {
 
  606                funcList->Remove(obj);
 
  610                reuseOldFunction = 
true;
 
  622       if (!reuseOldFunction) {
 
  623          fnew1 = (TF1*)f1->IsA()->New();
 
  626          funcList->Add(fnew1);
 
  631       fnew1->SetParent( h1 );
 
  632       fnew1->SetRange(xmin,xmax);
 
  633       fnew1->Save(xmin,xmax,0,0,0,0);
 
  634       if (!drawFunction) fnew1->SetBit(TF1::kNotDraw);
 
  635       fnew1->AddToGlobalList(
false);
 
  636    } 
else if (ndim < 3) {
 
  637       if (!reuseOldFunction) {
 
  638          fnew2 = (TF2*)f1->IsA()->New();
 
  641          funcList->Add(fnew2);
 
  644          fnew2 = 
dynamic_cast<TF2*
>(f1);
 
  647       fnew2->SetRange(xmin,ymin,xmax,ymax);
 
  648       fnew2->SetParent( h1 );
 
  649       fnew2->Save(xmin,xmax,ymin,ymax,0,0);
 
  650       if (!drawFunction) fnew2->SetBit(TF1::kNotDraw);
 
  651       fnew2->AddToGlobalList(
false);
 
  653       if (!reuseOldFunction) {
 
  654          fnew3 = (TF3*)f1->IsA()->New();
 
  657          funcList->Add(fnew3);
 
  660          fnew2 = 
dynamic_cast<TF3*
>(f1);
 
  663       fnew3->SetRange(xmin,ymin,zmin,xmax,ymax,zmax);
 
  664       fnew3->SetParent( h1 );
 
  665       fnew3->Save(xmin,xmax,ymin,ymax,zmin,zmax);
 
  666       if (!drawFunction) fnew3->SetBit(TF1::kNotDraw);
 
  667       fnew3->AddToGlobalList(
false);
 
  669    if (h1->TestBit(kCanDelete)) 
return;
 
  671    if (drawFunction && ndim < 3 && h1->InheritsFrom(TH1::Class() ) ) {
 
  674       if (!gPad || (gPad && gPad->GetListOfPrimitives()->FindObject(h1) == NULL ) )
 
  677    if (gPad) gPad->Modified(); 
 
  683 void ROOT::Fit::FitOptionsMake(EFitObjectType type, 
const char *option, Foption_t &fitOption) {
 
  686    if(ROOT::IsImplicitMTEnabled()) {
 
  687       fitOption.ExecPolicy = ROOT::Fit::ExecutionPolicy::kMultithread;
 
  690    if (option == 0) 
return;
 
  691    if (!option[0]) 
return;
 
  693    TString opt = option;
 
  697    if (type == kHistogram) {
 
  699       if (opt.Contains(
"WIDTH")) {
 
  700          fitOption.BinVolume = 1;  
 
  701          if (opt.Contains(
"NORMWIDTH")) {
 
  704             fitOption.BinVolume = 2;
 
  705             opt.ReplaceAll(
"NORMWIDTH",
"");
 
  708             opt.ReplaceAll(
"WIDTH",
"");
 
  716       if (opt.Contains(
"SERIAL")) {
 
  717          fitOption.ExecPolicy = ROOT::Fit::ExecutionPolicy::kSerial;
 
  718          opt.ReplaceAll(
"SERIAL",
"");
 
  721       if (opt.Contains(
"MULTITHREAD")) {
 
  722          fitOption.ExecPolicy = ROOT::Fit::ExecutionPolicy::kMultithread;
 
  723          opt.ReplaceAll(
"MULTITHREAD",
"");
 
  726       if (opt.Contains(
"I"))  fitOption.Integral= 1;   
 
  727       if (opt.Contains(
"WW")) fitOption.W1      = 2; 
 
  731    else if (type == kGraph) {
 
  732       opt.ReplaceAll(
"ROB", 
"H");
 
  733       opt.ReplaceAll(
"EX0", 
"T");
 
  738       if (opt.Contains(
"H=0.")) {
 
  739          int start = opt.Index(
"H=0.");
 
  740          int numpos = start + strlen(
"H=0.");
 
  742          int len = opt.Length();
 
  743          while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
 
  744          TString num = opt(numpos,numlen);
 
  745          opt.Remove(start+strlen(
"H"),strlen(
"=0.")+numlen);
 
  746          h = atof(num.Data());
 
  747          h*=TMath::Power(10, -numlen);
 
  750       if (opt.Contains(
"H")) { fitOption.Robust  = 1;   fitOption.hRobust = h; }
 
  751       if (opt.Contains(
"T")) fitOption.NoErrX   = 1;  
 
  755    if (opt.Contains(
"U")) fitOption.User    = 1;
 
  756    if (opt.Contains(
"Q")) fitOption.Quiet   = 1;
 
  757    if (opt.Contains(
"V")) {fitOption.Verbose = 1; fitOption.Quiet   = 0;}
 
  758    if (opt.Contains(
"L")) fitOption.Like    = 1;
 
  759    if (opt.Contains(
"X")) fitOption.Chi2    = 1;
 
  760    if (opt.Contains(
"P")) fitOption.PChi2    = 1;
 
  764    if (fitOption.Like == 1) {
 
  766       if (opt.Contains(
"W")){ fitOption.Like    = 2;  fitOption.W1=0;}
 
  767       if (opt.Contains(
"MULTI")) {
 
  768          if (fitOption.Like == 2) fitOption.Like = 6; 
 
  769          else fitOption.Like    = 4; 
 
  770          opt.ReplaceAll(
"MULTI",
"");
 
  773       if (type == kHistogram) {
 
  774          if (fitOption.Chi2 == 1 || fitOption.PChi2 == 1)
 
  775             Warning(
"Fit",
"Cannot use P or X option in combination of L. Ignore the chi2 option and perform a likelihood fit");
 
  779       if (opt.Contains(
"W")) fitOption.W1     = 1; 
 
  783    if (opt.Contains(
"E")) fitOption.Errors  = 1;
 
  784    if (opt.Contains(
"R")) fitOption.Range   = 1;
 
  785    if (opt.Contains(
"G")) fitOption.Gradient= 1;
 
  786    if (opt.Contains(
"M")) fitOption.More    = 1;
 
  787    if (opt.Contains(
"N")) fitOption.Nostore = 1;
 
  788    if (opt.Contains(
"0")) fitOption.Nograph = 1;
 
  789    if (opt.Contains(
"+")) fitOption.Plus    = 1;
 
  790    if (opt.Contains(
"B")) fitOption.Bound   = 1;
 
  791    if (opt.Contains(
"C")) fitOption.Nochisq = 1;
 
  792    if (opt.Contains(
"F")) fitOption.Minuit  = 1;
 
  793    if (opt.Contains(
"S")) fitOption.StoreResult   = 1;
 
  797 void HFit::CheckGraphFitOptions(Foption_t & foption) {
 
  799       Info(
"CheckGraphFitOptions",
"L (Log Likelihood fit) is an invalid option when fitting a graph. It is ignored");
 
  802    if (foption.Integral) {
 
  803       Info(
"CheckGraphFitOptions",
"I (use function integral) is an invalid option when fitting a graph. It is ignored");
 
  804       foption.Integral = 0;
 
  811 TFitResultPtr ROOT::Fit::UnBinFit(ROOT::Fit::UnBinData * data, TF1 * fitfunc, Foption_t & fitOption , 
const ROOT::Math::MinimizerOptions & minOption) {
 
  815    std::shared_ptr<ROOT::Fit::UnBinData> fitdata(data);
 
  818    printf(
"tree data size is %d \n",fitdata->Size());
 
  819    for (
unsigned int i = 0; i < fitdata->Size(); ++i) {
 
  820       if (fitdata->NDim() == 1) printf(
" x[%d] = %f \n", i,*(fitdata->Coords(i) ) );
 
  823    if (fitdata->Size() == 0 ) {
 
  824       Warning(
"Fit",
"Fit data is empty ");
 
  829    std::shared_ptr<TFitResult> tfr(
new TFitResult() );
 
  831    std::shared_ptr<ROOT::Fit::Fitter> fitter(
new ROOT::Fit::Fitter(tfr) );
 
  832    ROOT::Fit::FitConfig & fitConfig = fitter->Config();
 
  835    unsigned int dim = fitdata->NDim();
 
  840    if ( fitOption.Gradient ) {
 
  841       assert ( (
int) dim == fitfunc->GetNdim() );
 
  842       fitter->SetFunction(ROOT::Math::WrappedMultiTF1(*fitfunc) );
 
  845       fitter->SetFunction(static_cast<const ROOT::Math::IParamMultiFunction &>(ROOT::Math::WrappedMultiTF1(*fitfunc, dim) ) );
 
  849    int npar = fitfunc->GetNpar();
 
  850    for (
int i = 0; i < npar; ++i) {
 
  851       ROOT::Fit::ParameterSettings & parSettings = fitConfig.ParSettings(i);
 
  853       fitfunc->GetParLimits(i,plow,pup);
 
  855       if (plow*pup != 0 && plow >= pup) {
 
  858       else if (plow < pup ) {
 
  859          if (!TMath::Finite(pup) && TMath::Finite(plow) )
 
  860             parSettings.SetLowerLimit(plow);
 
  861          else if (!TMath::Finite(plow) && TMath::Finite(pup) )
 
  862             parSettings.SetUpperLimit(pup);
 
  864             parSettings.SetLimits(plow,pup);
 
  869       double err = fitfunc->GetParError(i);
 
  871          parSettings.SetStepSize(err);
 
  872       else if (plow < pup && TMath::Finite(plow) && TMath::Finite(pup) ) { 
 
  873          double step = 0.1 * (pup - plow);
 
  875          if (  parSettings.Value() < pup && pup - parSettings.Value() < 2 * step  )
 
  876             step = (pup - parSettings.Value() ) / 2;
 
  877          else if ( parSettings.Value() > plow && parSettings.Value() - plow < 2 * step )
 
  878             step = (parSettings.Value() - plow ) / 2;
 
  880          parSettings.SetStepSize(step);
 
  885    fitConfig.SetMinimizerOptions(minOption);
 
  887    if (fitOption.Verbose)   fitConfig.MinimizerOptions().SetPrintLevel(3);
 
  888    if (fitOption.Quiet)     fitConfig.MinimizerOptions().SetPrintLevel(0);
 
  891    if (fitOption.More)   fitConfig.SetMinimizer(
"Minuit",
"MigradImproved");
 
  894    if (fitOption.Errors) {
 
  896       fitConfig.SetParabErrors(
true);
 
  897       fitConfig.SetMinosErrors(
true);
 
  900    if ( (fitOption.Like & 2) == 2)
 
  901       fitConfig.SetWeightCorrection(
true);
 
  903    bool extended = (fitOption.Like & 1) == 1;
 
  906    fitok = fitter->LikelihoodFit(fitdata, extended, fitOption.ExecPolicy);
 
  907    if ( !fitok  && !fitOption.Quiet )
 
  908       Warning(
"UnBinFit",
"Abnormal termination of minimization.");
 
  910    const ROOT::Fit::FitResult & fitResult = fitter->Result();
 
  912    int iret = fitResult.Status();
 
  913    if (!fitResult.IsEmpty() ) {
 
  915       fitfunc->SetNDF(fitResult.Ndf() );
 
  916       fitfunc->SetNumberFitPoints(fitdata->Size() );
 
  918       assert(  (Int_t)fitResult.Parameters().size() >= fitfunc->GetNpar() );
 
  919       fitfunc->SetParameters( const_cast<double*>(&(fitResult.Parameters().front())));
 
  920       if ( 
int( fitResult.Errors().size()) >= fitfunc->GetNpar() )
 
  921          fitfunc->SetParErrors( &(fitResult.Errors().front()) );
 
  928       TVirtualFitter * lastFitter = TVirtualFitter::GetFitter();
 
  930       TBackCompFitter * bcfitter = 
new TBackCompFitter(fitter, fitdata);
 
  933       bcfitter->SetFitOption(fitOption);
 
  935       bcfitter->SetUserFunc(fitfunc);
 
  937       if (lastFitter) 
delete lastFitter;
 
  938       TVirtualFitter::SetFitter( bcfitter );
 
  946    if (fitOption.Verbose) fitResult.PrintCovMatrix(std::cout);
 
  947    else if (!fitOption.Quiet) fitResult.Print(std::cout);
 
  949    if (fitOption.StoreResult)
 
  951       TString name = 
"TFitResult-";
 
  952       name = name + 
"UnBinData-" + fitfunc->GetName();
 
  953       TString title = 
"TFitResult-";
 
  956       tfr->SetTitle(title);
 
  957       return TFitResultPtr(tfr);
 
  960       return TFitResultPtr(iret);
 
  966 TFitResultPtr ROOT::Fit::FitObject(TH1 * h1, TF1 *f1 , Foption_t & foption , 
const ROOT::Math::MinimizerOptions &
 
  967 moption, 
const char *goption, ROOT::Fit::DataRange & range) {
 
  970    if ( ((foption.Like & 2) == 2) && h1->GetSumw2N() == 0) {
 
  971       Warning(
"HFit::FitObject",
"A weighted likelihood fit is requested but histogram is not weighted - do a standard Likelihood fit");
 
  975    return HFit::Fit(h1,f1,foption,moption,goption,range);
 
  978 TFitResultPtr ROOT::Fit::FitObject(TGraph * gr, TF1 *f1 , Foption_t & foption , 
const ROOT::Math::MinimizerOptions & moption, 
const char *goption, ROOT::Fit::DataRange & range) {
 
  980    HFit::CheckGraphFitOptions(foption);
 
  982    return HFit::Fit(gr,f1,foption,moption,goption,range);
 
  985 TFitResultPtr ROOT::Fit::FitObject(TMultiGraph * gr, TF1 *f1 , Foption_t & foption , 
const ROOT::Math::MinimizerOptions & moption, 
const char *goption, ROOT::Fit::DataRange & range) {
 
  987    HFit::CheckGraphFitOptions(foption);
 
  989    return HFit::Fit(gr,f1,foption,moption,goption,range);
 
  992 TFitResultPtr ROOT::Fit::FitObject(TGraph2D * gr, TF1 *f1 , Foption_t & foption , 
const ROOT::Math::MinimizerOptions & moption, 
const char *goption, ROOT::Fit::DataRange & range) {
 
  994    HFit::CheckGraphFitOptions(foption);
 
  996    return HFit::Fit(gr,f1,foption,moption,goption,range);
 
  999 TFitResultPtr ROOT::Fit::FitObject(THnBase * s1, TF1 *f1 , Foption_t & foption , 
const ROOT::Math::MinimizerOptions & moption, 
const char *goption, ROOT::Fit::DataRange & range) {
 
 1001    return HFit::Fit(s1,f1,foption,moption,goption,range);
 
 1020 double ROOT::Fit::Chisquare(
const TH1 & h1,  TF1 & f1, 
bool useRange, 
bool usePL) {
 
 1021    return HFit::ComputeChi2(h1,f1,useRange, usePL);
 
 1024 double ROOT::Fit::Chisquare(
const TGraph & g, TF1 & f1, 
bool useRange) {
 
 1025    return HFit::ComputeChi2(g,f1, useRange, 
false);
 
 1028 template<
class FitObject>
 
 1029 double HFit::ComputeChi2(
const FitObject & obj,  TF1  & f1, 
bool useRange, 
bool usePL ) {
 
 1032    ROOT::Fit::DataOptions opt;
 
 1033    if (usePL) opt.fUseEmpty=
true;
 
 1034    ROOT::Fit::DataRange range;
 
 1036    if (useRange) HFit::GetFunctionRange(f1,range);
 
 1038    ROOT::Fit::BinData data(opt,range);
 
 1039    ROOT::Fit::FillData(data, &obj, &f1);
 
 1040    if (data.Size() == 0 ) {
 
 1041       Warning(
"Chisquare",
"data set is empty - return -1");
 
 1044    ROOT::Math::WrappedMultiTF1  wf1(f1);
 
 1047       ROOT::Fit::PoissonLLFunction nll(data, wf1);
 
 1048       return 2.* nll( f1.GetParameters() ) ;
 
 1050    ROOT::Fit::Chi2Function chi2(data, wf1);
 
 1051    return chi2(f1.GetParameters() );