53 if (func ==
nullptr)
return false;
67 if (
option.fUseEmpty || (
option.fErrors1 && std::abs(value) > 0 ) )
71 }
else if (
option.fErrors1)
76void ExamineRange(
const TAxis * axis, std::pair<double,double> range,
int &hxfirst,
int &hxlast) {
79 double xlow = range.first;
80 double xhigh = range.second;
82 std::cout <<
"xlow " << xlow <<
" xhigh = " << xhigh << std::endl;
87 if (ilow > hxlast || ihigh < hxfirst) {
88 Warning(
"ROOT::Fit::FillData",
"fit range is outside histogram range, no fit data for %s",axis->
GetName());
91 hxfirst = std::min( std::max( ilow, hxfirst), hxlast+1) ;
92 hxlast = std::max( std::min( ihigh, hxlast), hxfirst-1) ;
94 if (hxfirst < hxlast) {
120 assert(hfit !=
nullptr);
139 if (range.
Size(0) != 0) {
141 if (range.
Size(0) > 1 ) {
142 Warning(
"ROOT::Fit::FillData",
"support only one range interval for X coordinate");
148 if (range.
Size(1) > 1 )
149 Warning(
"ROOT::Fit::FillData",
"support only one range interval for Y coordinate");
154 if (range.
Size(2) > 1 )
155 Warning(
"ROOT::Fit::FillData",
"support only one range interval for Z coordinate");
159 int n = (hxlast-hxfirst+1)*(hylast-hyfirst+1)*(hzlast-hzfirst+1);
162 std::cout <<
"THFitInterface: ifirst = " << hxfirst <<
" ilast = " << hxlast
163 <<
" total bins " <<
n
173 if (func !=
nullptr && func->
GetNdim() == hdim-1) ndim = hdim-1;
191 for ( binx = hxfirst; binx <= hxlast; ++binx) {
200 for ( biny = hyfirst; biny <= hylast; ++biny) {
208 for ( binz = hzfirst; binz <= hzlast; ++binz) {
218 if (func !=
nullptr) {
226 double error = hfit->
GetBinError(binx, biny, binz);
229 if (ndim == hdim -1) {
239 dv.
Add(
x, value, error );
247 std::cout <<
"bin " << binx <<
" add point " <<
x[0] <<
" " << hfit->
GetBinContent(binx) << std::endl;
256 std::cout <<
"THFitInterface::FillData: Hist FitData size is " << dv.
Size() << std::endl;
266 unsigned int n = data.Size();
271 double xmin = *(data.GetPoint(0,valxmin));
273 double valxmax = valxmin;
275 for (
unsigned int i = 1; i <
n; ++ i) {
277 double x = *(data.GetPoint(i,val) );
289 if (valxmin <= 0 && valxmax > 0 ) valxmin = valxmax;
290 else if (valxmax <=0 && valxmin > 0) valxmax = valxmin;
291 else if (valxmin <=0 && valxmax <= 0) { valxmin = 1; valxmax = 1; }
293 double slope = std::log( valxmax/valxmin) / (
xmax -
xmin);
294 double constant = std::log(valxmin) - slope *
xmin;
295 f1->SetParameters(constant, slope);
306 static const double sqrtpi = 2.506628;
309 unsigned int n = data.Size();
315 double rangex = data.Coords(
n-1)[0] - data.Coords(0)[0];
318 if ( rangex > 0) binwidth = rangex;
320 for (
unsigned int i = 0; i <
n; ++ i) {
322 double x = *(data.GetPoint(i,val) );
326 if (val > valmax) valmax = val;
329 if (dx < binwidth) binwidth = dx;
334 if (allcha <= 0)
return;
335 double mean = sumx/allcha;
336 double rms = sumx2/allcha - mean*mean;
340 rms = std::sqrt(rms);
355 double constant = 0.5*(valmax+ binwidth*allcha/(sqrtpi*rms));
369 f1->SetParameter(0,constant);
370 f1->SetParameter(1,mean);
371 f1->SetParameter(2,rms);
372 f1->SetParLimits(2,0,10*rms);
376 std::cout <<
"Gaussian initial par values" << constant <<
" " << mean <<
" " << rms << std::endl;
388 static const double sqrtpi = 2.506628;
391 unsigned int n = data.Size();
393 double sumx = 0, sumy = 0;
394 double sumx2 = 0, sumy2 = 0;
397 double rangex = data.Coords(
n-1)[0] - data.Coords(0)[0];
398 double rangey = data.Coords(
n-1)[1] - data.Coords(0)[1];
400 double binwidthx = 1, binwidthy = 1;
401 if ( rangex > 0) binwidthx = rangex;
402 if ( rangey > 0) binwidthy = rangey;
403 double x0 = 0, y0 = 0;
404 for (
unsigned int i = 0; i <
n; ++i) {
406 const double *coords = data.GetPoint(i,val);
407 double x = coords[0],
y = coords[1];
413 if (val > valmax) valmax = val;
416 if (dx < binwidthx) binwidthx = dx;
418 if (dy < binwidthy) binwidthy = dy;
424 if (allcha <= 0)
return;
425 double meanx = sumx/allcha, meany = sumy/allcha;
426 double rmsx = sumx2/allcha - meanx*meanx;
427 double rmsy = sumy2/allcha - meany*meany;
431 rmsx = std::sqrt(rmsx);
433 rmsx = binwidthx*
n/4;
436 rmsy = std::sqrt(rmsy);
438 rmsy = binwidthy*
n/4;
448 double constant = 0.5 * (valmax+ binwidthx*allcha/(sqrtpi*rmsx))*
449 (valmax+ binwidthy*allcha/(sqrtpi*rmsy));
451 f1->SetParameter(0,constant);
452 f1->SetParameter(1,meanx);
453 f1->SetParameter(2,rmsx);
454 f1->SetParLimits(2,0,10*rmsx);
455 f1->SetParameter(3,meany);
456 f1->SetParameter(4,rmsy);
457 f1->SetParLimits(4,0,10*rmsy);
460 std::cout <<
"2D Gaussian initial par values"
475 double *
ex =
gr->GetEX();
476 double *
ey =
gr->GetEY();
477 double * eyl =
gr->GetEYlow();
478 double * eyh =
gr->GetEYhigh();
484 if (fitOpt.
fErrors1 || (
ey ==
nullptr && ( eyl ==
nullptr || eyh ==
nullptr ) ) ) {
498 else if ( ( eyl !=
nullptr && eyh !=
nullptr) && fitOpt.
fAsymErrors) {
501 bool zeroErrorX =
true;
502 bool zeroErrorY =
true;
503 while (i < gr->GetN() && (zeroErrorX || zeroErrorY)) {
504 double e2X = (
gr->GetErrorXlow(i) +
gr->GetErrorXhigh(i) );
505 double e2Y = eyl[i] + eyh[i];
506 zeroErrorX &= (e2X <= 0);
507 zeroErrorY &= (e2Y <= 0);
510 if (zeroErrorX && zeroErrorY)
512 else if (!zeroErrorX && zeroErrorY)
514 else if (zeroErrorX && !zeroErrorY) {
526 bool zeroError =
true;
527 while (i < gr->GetN() && zeroError) {
528 if (
ey[i] > 0) zeroError =
false;
536 std::cout <<
"type is " <<
type <<
" graph type is " <<
gr->IsA()->GetName() << std::endl;
544 double *
ex =
gr->GetEX();
545 double *
ey =
gr->GetEY();
546 double *ez =
gr->GetEZ();
551 if (fitOpt.
fErrors1 || ez ==
nullptr ) {
565 std::cout <<
"type is " <<
type <<
" graph2D type is " <<
gr->IsA()->GetName() << std::endl;
580 int nPoints =
gr->GetN();
581 double *gx =
gr->GetX();
582 double *gy =
gr->GetY();
585 bool useRange = ( range.
Size(0) > 0);
593 std::cout <<
"DoFillData: graph npoints = " << nPoints <<
" type " <<
type << std::endl;
595 double a1,a2; func->
GetRange(a1,a2); std::cout <<
"func range " << a1 <<
" " << a2 << std::endl;
603 std::vector<std::pair<double, int>> indexRemap;
604 for (
int i = 0; i < nPoints; ++i) {
605 indexRemap.emplace_back(gx[i], i);
607 std::sort(indexRemap.begin(), indexRemap.end());
610 for (
int j = 0; j < nPoints; ++j) {
612 int i = indexRemap[j].second;
616 if (useRange && (
x[0] <
xmin ||
x[0] >
xmax) )
continue;
628 dv.
Add( gx[i], gy[i] );
633 double errorY =
gr->GetErrorY(i);
637 dv.
Add( gx[i], gy[i], errorY );
640 std::cout <<
"Point " << i <<
" " << gx[i] <<
" " << gy[i] <<
" " << errorY << std::endl;
651 errorX = std::max( 0.5 * (
gr->GetErrorXlow(i) +
gr->GetErrorXhigh(i) ) , 0. ) ;
655 double errorY = std::max(
gr->GetErrorY(i), 0.);
660 if ( errorX <=0 && errorY <= 0 )
continue;
665 dv.
Add( gx[i], gy[i], errorX,
gr->GetErrorYlow(i),
gr->GetErrorYhigh(i) );
669 dv.
Add( gx[i], gy[i], errorX, errorY );
676 std::cout <<
"TGraphFitInterface::FillData Graph FitData size is " << dv.
Size() << std::endl;
683 const int dim =
h1->GetDimension();
684 std::vector<double> min(
dim);
685 std::vector<double> max(
dim);
687 int ncells =
h1->GetNcells();
688 for (
int i = 0; i < ncells; ++i ) {
693 if ( !(
h1->IsBinOverflow(i) ||
h1->IsBinUnderflow(i) )
694 &&
h1->GetBinContent(i))
697 h1->GetBinXYZ(i,
x,
y, z);
708 min[0] =
h1->GetXaxis()->GetBinLowEdge(
x);
709 max[0] =
h1->GetXaxis()->GetBinUpEdge(
x);
712 min[1] =
h1->GetYaxis()->GetBinLowEdge(
y);
713 max[1] =
h1->GetYaxis()->GetBinUpEdge(
y);
716 min[2] =
h1->GetZaxis()->GetBinLowEdge(z);
717 max[2] =
h1->GetZaxis()->GetBinUpEdge(z);
720 dv.
Add(min, max,
h1->GetBinContent(i),
h1->GetBinError(i));
727 const int dim =
h1->GetNdimensions();
728 std::vector<double> min(
dim);
729 std::vector<double> max(
dim);
730 std::vector<Int_t> coord(
dim);
733 for (
ULong64_t i = 0; i < nEntries; i++ )
735 double value =
h1->GetBinContent( i, &coord[0] );
736 if ( !value )
continue;
741 bool insertBox =
true;
742 for (
int j = 0; j <
dim && insertBox; ++j )
749 min[j] =
h1->GetAxis(j)->GetBinLowEdge(coord[j]);
750 max[j] =
h1->GetAxis(j)->GetBinUpEdge(coord[j]);
764 dv.
Add(min, max, value,
h1->GetBinError(i));
771 unsigned int const ndim =
s1->GetNdimensions();
772 std::vector<double>
xmin(ndim);
773 std::vector<double>
xmax(ndim);
774 for (
unsigned int i = 0; i < ndim; ++i ) {
796 d.GetBinDataIntegral(dv);
803 assert(
gr !=
nullptr);
820 if (dv.
Size() > 0 && dv.
NDim() == 1 ) {
823 Error(
"FillData",
"Inconsistent TGraph with previous data set- skip all graph data");
835 assert(mg !=
nullptr);
838 assert(grList !=
nullptr);
844 std::cout <<
"multi-graph list of graps: " << std::endl;
845 while ((obj = itr())) {
846 std::cout << obj->
IsA()->
GetName() << std::endl;
871 std::cout <<
"Fitting MultiGraph of type " <<
type << std::endl;
881 std::cout <<
"TGraphFitInterface::FillData MultiGraph FitData size is " << dv.
Size() << std::endl;
890 assert(
gr !=
nullptr);
900 int nPoints =
gr->GetN();
901 double *gx =
gr->GetX();
902 double *gy =
gr->GetY();
903 double *gz =
gr->GetZ();
906 if (
gr->GetEZ() ==
nullptr) fitOpt.
fErrors1 =
true;
913 bool useRangeX = ( range.
Size(0) > 0);
914 bool useRangeY = ( range.
Size(1) > 0);
923 for (
int i = 0; i < nPoints; ++i) {
929 if (useRangeX && (
x[0] <
xmin ||
x[0] >
xmax) )
continue;
930 if (useRangeY && (
x[1] <
ymin ||
x[1] >
ymax) )
continue;
945 double errorZ =
gr->GetErrorZ(i);
949 dv.
Add(
x, gz[i], errorZ );
952 ex[0] = std::max(
gr->GetErrorX(i), 0.);
953 ex[1] = std::max(
gr->GetErrorY(i), 0.);
954 dv.
Add(
x, gz[i],
ex, errorZ );
960 std::cout <<
"Point " << i <<
" " << gx[i] <<
" " << gy[i] <<
" " << errorZ << std::endl;
966 std::cout <<
"THFitInterface::FillData Graph2D FitData size is " << dv.
Size() << std::endl;
974 if (
h1->GetDimension() != 1) {
975 Error(
"GetConfidenceIntervals",
"Invalid object used for storing confidence intervals");
981 gr->Set(
d.NPoints() );
982 double * ci =
gr->GetEY();
985 for (
unsigned int ipoint = 0; ipoint <
d.NPoints(); ++ipoint) {
986 const double *
x =
d.Coords(ipoint);
988 gr->SetPoint(ipoint,
x[0], (*func)(
x) );
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
const Bool_t kIterBackward
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
void AddBinUpEdge(const double *xup)
add the bin width data, a pointer to an array with the bin upper edge information.
ErrorType GetErrorType() const
retrieve the errortype
void Add(double x, double y)
add one dim data with only coordinate and values
void Initialize(unsigned int newPoints, unsigned int dim=1, ErrorType err=kValueError)
Preallocate a data set with given size, dimension and error type.
class describing the range in the coordinates it supports multiple range in a coordinate.
unsigned int Size(unsigned int icoord=0) const
return range size for coordinate icoord (starts from zero) Size == 0 indicates no range is present [-...
void GetRange(unsigned int irange, unsigned int icoord, double &xmin, double &xmax) const
get the i-th range for given coordinate.
unsigned int Size() const
return number of fit points
unsigned int NDim() const
return coordinate data dimension
const DataOptions & Opt() const
access to options
const DataRange & Range() const
access to range
class containing the result of the fit and all the related information (fitted parameter values,...
void GetConfidenceIntervals(unsigned int n, unsigned int stride1, unsigned int stride2, const double *x, double *ci, double cl=0.95, bool norm=false) const
get confidence intervals for an array of n points x.
const IModelFunction * FittedFunction() const
fitting quantities
SparseData class representing the data of a THNSparse histogram The data needs to be converted to a B...
void Add(std::vector< double > &min, std::vector< double > &max, const double content, const double error=1.0)
Adds a new bin specified by the vectors.
Class to manage histogram axis.
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Int_t GetLast() const
Return last bin on the axis i.e.
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Int_t GetFirst() const
Return first bin on the axis i.e.
static void RejectPoint(Bool_t reject=kTRUE)
static Bool_t RejectedPoint()
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
virtual Int_t GetNdim() const
TH1 is the base class of all histogram classes in ROOT.
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
virtual Int_t GetDimension() const
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Multidimensional histogram base.
TList * GetListOfGraphs() const
const char * GetName() const override
Returns name of object.
Mother of all ROOT objects.
virtual TClass * IsA() const
void ExamineRange(const TAxis *axis, std::pair< double, double > range, int &hxfirst, int &hxlast)
bool AdjustError(const DataOptions &option, double &error, double value=1)
bool IsPointOutOfRange(const TF1 *func, const double *x)
Namespace for the fitting classes.
void Init2DGaus(const ROOT::Fit::BinData &data, TF1 *f1)
compute initial parameter for 2D gaussian function given the fit data Set the sigma limits for zero t...
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.
void InitExpo(const ROOT::Fit::BinData &data, TF1 *f1)
compute initial parameter for an exponential function given the fit data Set the constant and slope a...
void InitGaus(const ROOT::Fit::BinData &data, TF1 *f1)
compute initial parameter for gaussian function given the fit data Set the sigma limits for zero top ...
void DoFillData(BinData &dv, const TGraph *gr, BinData::ErrorType type, TF1 *func)
BinData::ErrorType GetDataType(const TGraph *gr, DataOptions &fitOpt)
bool GetConfidenceIntervals(const TH1 *h1, const ROOT::Fit::FitResult &r, TGraphErrors *gr, double cl=0.95)
compute confidence intervals at level cl for a fitted histogram h1 in a TGraphErrors gr
IParametricFunctionMultiDim IParamMultiFunction
The namespace of The Lean Mean C++ Option Parser.
DataOptions : simple structure holding the options on how the data are filled.
bool fErrors1
use all errors equal to 1, i.e. fit without errors (default is false)
bool fAsymErrors
use asymmetric errors in the value when available, selecting them according to the on sign of residua...
bool fNormBinVolume
normalize data by a normalized the bin volume (bin volume divided by a reference value)
bool fIntegral
use integral of bin content instead of bin center (default is false)
bool fBinVolume
normalize data by the bin volume (it is used in the Poisson likelihood fits)
bool fCoordErrors
use errors on the x coordinates when available (default is true)