95 for (
int i = 0; i < nOther; ++i)
131 for (
int i=0; i < nOther; ++i) {
211 bool resultIsAsymptotic(
false);
215 if ( !
r->GetNullDistribution() && !
r->GetAltDistribution() ) {
216 resultIsAsymptotic =
true;
220 int nPointsRemoved(0);
222 double CLsobsprev(1.0);
225 const double x = *itr;
235 coutE(
Eval) <<
"HypoTestInverterResult::ExclusionCleanup - invalid size of sampling distribution" << std::endl;
242 if (resultIsAsymptotic) {
244 double dsig = 2.*maxSigma / (values.size() -1) ;
257 double * z =
const_cast<double *
>(&values[0] );
263 const double CLsobs =
CLs(i);
267 bool removeThisPoint(
false);
270 if (resultIsAsymptotic && i>=1 && CLsobs>CLsobsprev) {
271 removeThisPoint =
true;
272 }
else if (CLsobs >= 0.) {
277 removeThisPoint |= i>=1 && CLsobs >= 0.9999;
283 removeThisPoint |= CLsobs < 0.;
286 if (removeThisPoint) {
302 return nPointsRemoved;
320 if (nOther == 0)
return true;
322 if (nThis !=
fYObjects.GetSize() )
return false;
328 coutI(
Eval) <<
"HypoTestInverterResult::Add - merging result from " << otherResult.
GetName()
329 <<
" in " <<
GetName() << std::endl;
334 if (addExpPValues || mergeExpPValues)
335 coutI(
Eval) <<
"HypoTestInverterResult::Add - merging also the expected p-values from pseudo-data" << std::endl;
342 for (
int i = 0; i < nOther; ++i)
349 for (
int i = 0; i < nOther; ++i) {
350 double otherVal = otherResult.
fXValues[i];
352 if (otherHTR ==
nullptr)
continue;
353 bool sameXFound =
false;
354 for (
int j = 0; j < nThis; ++j) {
361 thisHTR->
Append(otherHTR);
363 if (mergeExpPValues) {
368 if (thisNToys != otherNToys )
369 coutW(
Eval) <<
"HypoTestInverterResult::Add expected p values have been generated with different toys " << thisNToys <<
" , " << otherNToys << std::endl;
388 coutI(
Eval) <<
"HypoTestInverterResult::Add - new number of points is " <<
fXValues.size()
391 coutI(
Eval) <<
"HypoTestInverterResult::Add - new toys/point is "
413 if (!
r)
return false;
448 return result->CLs();
450 return result->CLsplusb();
465 return result->CLsError();
467 return result->CLsplusbError();
480 return result->CLb();
492 return result->CLsplusb();
504 return result->CLs();
516 return result->CLbError();
528 return result->CLsplusbError();
540 return result->CLsError();
563 const double tol = 1.E-12;
582 ccoutD(
Eval) <<
"using graph for search " << lowSearch <<
" min " << axmin <<
" max " << axmax << std::endl;
587 const double *
y = graph.
GetY();
588 int n = graph.
GetN();
590 ooccoutE(
this,
Eval) <<
"HypoTestInverterResult::GetGraphX - need at least 2 points for interpolation (n=" <<
n <<
")\n";
591 return (
n>0) ?
y[0] : 0;
608 return (lowSearch) ? varmax : varmin;
611 return (lowSearch) ? varmin : varmax;
618 if (axmin >= axmax ) {
621 ccoutD(
Eval) <<
"No range given - check if extrapolation is needed " << std::endl;
627 double yfirst = graph.
GetY()[0];
628 double ylast = graph.
GetY()[
n-1];
634 if ( (
ymax < y0 && !lowSearch) || ( yfirst > y0 && lowSearch) ) {
638 if ( (
ymax < y0 && lowSearch) || ( ylast > y0 && !lowSearch) ) {
643 auto func = [&](
double x) {
653 <<
" , " << graph.
Eval(
xmax) <<
" target " << y0 << std::endl;
656 bool ret = brf.
Solve(100, 1.E-16, 1.E-6);
658 ooccoutE(
this,
Eval) <<
"HypoTestInverterResult - interpolation failed for interval [" <<
xmin <<
"," <<
xmax
660 <<
" target=" << y0 <<
" return inf" << std::endl
661 <<
"One may try to clean up invalid points using HypoTestInverterResult::ExclusionCleanup()." << std::endl;
664 double limit = brf.
Root();
667 if (lowSearch)
ccoutD(
Eval) <<
"lower limit search : ";
670 <<
"\n Found limit using RootFinder is " << limit << std::endl;
672 TString fname =
"graph_upper.root";
673 if (lowSearch) fname =
"graph_lower.root";
675 std::unique_ptr<TFile> file{
TFile::Open(fname,
"RECREATE")};
676 graph.
Write(
"graph");
682 if (axmin >= axmax) {
685 ccoutD(
Eval) <<
"do new interpolation dividing from " << index <<
" and " <<
y[index] << std::endl;
688 if (lowSearch && index >= 1 && (
y[0] - y0) * (
y[index]- y0) < 0) {
692 else if (!lowSearch && index <
n-2 && (
y[
n-1] - y0) * (
y[index+1]- y0) < 0) {
721 double val = (lowSearch) ?
xmin :
xmax;
722 coutW(
Eval) <<
"HypoTestInverterResult::FindInterpolatedLimit"
723 <<
" - not enough points to get the inverted interval - return "
732 std::vector<unsigned int> index(
n );
736 for (
int i = 0; i <
n; ++i)
748 double * itrmax = std::max_element(graph.
GetY() , graph.
GetY() +
n);
749 double ymax = *itrmax;
750 int iymax = itrmax - graph.
GetY();
751 double xwithymax = graph.
GetX()[iymax];
754 ccoutD(
Eval) <<
" max of y " << iymax <<
" " << xwithymax <<
" " <<
ymax <<
" target is " << target << std::endl;
761 xmin = ( graph.
GetY()[0] <= target ) ? graph.
GetX()[0] : varmin;
774 xmax = ( graph.
GetY()[
n-1] <= target ) ? graph.
GetX()[
n-1] : varmax;
786 if (iymax <= (
n-1)/2 ) {
797 ccoutD(
Eval) <<
" found xmin, xmax = " <<
xmin <<
" " <<
xmax <<
" for search " << lowSearch << std::endl;
808 if (upI < 1)
return xmin;
814 if (lowI >=
n-1)
return xmax;
822 ccoutD(
Eval) <<
"finding " << lowSearch <<
" limit between " <<
xmin <<
" " <<
xmax << std::endl;
832 TString limitType = (lowSearch) ?
"lower" :
"upper";
833 ooccoutD(
this,
Eval) <<
"HypoTestInverterResult::FindInterpolateLimit "
834 <<
"the computed " << limitType <<
" limit is " << limit <<
" +/- " << error << std::endl;
837 ccoutD(
Eval) <<
"Found limit is " << limit <<
" +/- " << error << std::endl;
885 int closestIndex = -1;
887 double smallestError = 2;
888 double bestValue = 2;
890 double dist = std::abs(
GetYValue(i)-target);
897 if ( dist < bestValue) {
902 if (bestIndex >=0)
return bestIndex;
910 std::vector<unsigned int> indx(
n);
912 std::vector<double> xsorted(
n);
913 for (
int i = 0; i <
n; ++i) xsorted[i] =
fXValues[indx[i] ];
917 ccoutD(
Eval) <<
"finding closest point to " << xtarget <<
" is " << index1 <<
" " << indx[index1] << std::endl;
921 if (index1 < 0)
return indx[0];
922 if (index1 >=
n-1)
return indx[
n-1];
923 int index2 = index1 +1;
925 if (mode == 2)
return (
GetXValue(indx[index1]) <
GetXValue(indx[index2])) ? indx[index1] : indx[index2];
926 if (mode == 3)
return (
GetXValue(indx[index1]) >
GetXValue(indx[index2])) ? indx[index1] : indx[index2];
928 if (std::abs(
GetYValue(indx[index1])-target) <= std::abs(
GetYValue(indx[index2])-target) )
974 coutW(
Eval) <<
"HypoTestInverterResult::CalculateEstimateError"
975 <<
"Empty result \n";
980 coutW(
Eval) <<
"HypoTestInverterResult::CalculateEstimateError"
981 <<
" only points - return its error\n";
988 TString type = (!lower) ?
"upper" :
"lower";
991 ccoutD(
Eval) <<
"calculate estimate error " << type <<
" between " <<
xmin <<
" and " <<
xmax << std::endl;
996 std::vector<unsigned int> indx(
fXValues.size());
1013 if (graph.
GetN() < 2) {
1014 if (np >= 2)
coutW(
Eval) <<
"HypoTestInverterResult::CalculateEstimatedError - no valid points - cannot estimate the " << type <<
" limit error " << std::endl;
1025 TF1 fct(
"fct",
"exp([0] * (x - [2] ) + [1] * (x-[2])**2)", minX, maxX);
1026 double scale = maxX-minX;
1045 ccoutD(
Eval) <<
"fitting for limit " << type <<
"between " << minX <<
" , " << maxX <<
" points considered " << graph.
GetN() << std::endl;
1046 int fitstat = graph.
Fit(&fct,
" EX0");
1053 int fitstat = graph.
Fit(&fct,
"Q EX0");
1057 double theError = 0;
1062 theError = std::min(std::abs(
GetYError(index) /
m), maxX-minX);
1066 coutW(
Eval) <<
"HypoTestInverterResult::CalculateEstimatedError - cannot estimate the " << type <<
" limit error " << std::endl;
1076 ccoutD(
Eval) <<
"closes point to the limit is " << index <<
" " <<
GetXValue(index) <<
" and has error " <<
GetYError(index) << std::endl;
1109 if (!firstResult)
return nullptr;
1118 if (!result)
return nullptr;
1127 if (index < 0 || index >=
ArraySize() )
return nullptr;
1133 static bool useFirstB =
false;
1135 int bIndex = (useFirstB) ? 0 : index;
1142 if (bDistribution && sbDistribution) {
1152 std::vector<double> values(bDistribution->
GetSize());
1153 for (
int i = 0; i < bDistribution->
GetSize(); ++i) {
1165 const double dsig = 2* smax/ (npoints-1) ;
1166 std::vector<double> values(npoints);
1167 for (
int i = 0; i < npoints; ++i) {
1168 double nsig = -smax + dsig*i;
1170 if (pval < 0) {
return nullptr;}
1173 return new SamplingDistribution(
"Asymptotic expected values",
"Asymptotic expected values",values);
1183 coutE(
Eval) <<
"HypoTestInverterResult::GetLimitDistribution"
1184 <<
" not enough points - return 0 " << std::endl;
1188 ooccoutD(
this,
Eval) <<
"HypoTestInverterResult - computing limit distribution...." << std::endl;
1193 std::vector<SamplingDistribution*> distVec( npoints );
1195 for (
unsigned int i = 0; i < distVec.size(); ++i) {
1200 distVec[i]->InverseCDF(0);
1201 sum += distVec[i]->GetSize();
1207 ooccoutW(
this,
InputArguments) <<
"HypoTestInverterResult - set a minimum size of 10 for limit distribution" << std::endl;
1215 std::vector< std::vector<double> > quantVec(npoints );
1216 for (
int i = 0; i < npoints; ++i) {
1218 if (!distVec[i])
continue;
1221 std::vector<double> pvalues = distVec[i]->GetSamplingDistribution();
1222 delete distVec[i]; distVec[i] =
nullptr;
1223 std::sort(pvalues.begin(), pvalues.end());
1228 quantVec[i] = std::vector<double>(
size);
1229 for (
int ibin = 0; ibin <
size; ++ibin) {
1231 p[0] = std::min( (ibin+1) * 1./
double(
size), 1.0);
1234 (quantVec[i])[ibin] =
q[0];
1240 std::vector<unsigned int> index( npoints );
1247 std::vector<double> limits(
size);
1249 for (
int j = 0; j <
size; ++j ) {
1252 for (
int k = 0; k < npoints ; ++k) {
1253 if (!quantVec[index[k]].empty() )
1254 g.SetPoint(
g.GetN(),
GetXValue(index[k]), (quantVec[index[k]])[j] );
1314 if (nEntries <= 0)
return (lower) ? 1 : 0;
1317 assert(
r !=
nullptr);
1318 if (!
r->GetNullDistribution() && !
r->GetAltDistribution() ) {
1322 if (!limitDist)
return 0;
1324 if (values.size() <= 1)
return 0;
1346 std::vector<unsigned int> index(nEntries);
1349 for (
int j=0; j<nEntries; ++j) {
1353 ooccoutI(
this,
Eval) <<
"HypoTestInverterResult - cannot compute expected p value distribution for point, x = "
1354 <<
GetXValue(i) <<
" skip it " << std::endl;
1358 double *
x =
const_cast<double *
>(&values[0]);
1364 ooccoutE(
this,
Eval) <<
"HypoTestInverterResult - cannot compute limits , not enough points, n = " <<
g.GetN() << std::endl;
1375 if (!limitDist)
return 0;
1377 double *
x =
const_cast<double *
>(&values[0]);
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Class for finding the root of a one dimensional function using the Brent algorithm.
bool SetFunction(const ROOT::Math::IGenFunction &f, double xlow, double xup) override
Sets the function for the rest of the algorithms.
bool Solve(int maxIter=100, double absTol=1E-8, double relTol=1E-10) override
Returns the X value corresponding to the function value fy for (xmin<x<xmax).
double Root() const override
Returns root value.
void SetNpx(int npx)
Set the number of point used to bracket root using a grid.
Functor1D class for one-dimensional functions.
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
virtual double getMin(const char *name=nullptr) const
Get minimum of currently defined range.
Variable that can be changed from the outside.
TObject * clone(const char *newname=nullptr) const override
static double GetExpectedPValues(double pnull, double palt, double nsigma, bool usecls, bool oneSided=true)
function given the null and the alt p value - return the expected one given the N - sigma value
HypoTestInverterResult class holds the array of hypothesis test results and compute a confidence inte...
bool fInterpolateUpperLimit
double GetYValue(int index) const
function to return the value of the confidence level for the i^th entry in the results
double LowerLimitEstimatedError()
rough estimation of the error on the computed bound of the confidence interval Estimate of lower limi...
double FindInterpolatedLimit(double target, bool lowSearch=false, double xmin=1, double xmax=0.0)
interpolate to find a limit value Use a linear or a spline interpolation depending on the interpolati...
double UpperLimitEstimatedError()
Estimate of lower limit error function evaluates only a rough error on the lower limit.
SamplingDistribution * GetSignalAndBackgroundTestStatDist(int index) const
get the signal and background test statistic distribution
double fCLsCleanupThreshold
HypoTestResult * GetResult(int index) const
return a pointer to the i^th result object
HypoTestInverterResult & operator=(const HypoTestInverterResult &other)
operator =
InterpolOption_t fInterpolOption
interpolation option (linear or spline)
int ArraySize() const
number of entries in the results array
bool fInterpolateLowerLimit
std::vector< double > fXValues
double CLsplusbError(int index) const
return the observed CLsplusb value for the i-th entry
double CLsError(int index) const
return the observed CLb value for the i-th entry
double GetGraphX(const TGraph &g, double y0, bool lowSearch, double &xmin, double &xmax) const
return the X value of the given graph for the target value y0 the graph is evaluated using linear int...
double CLbError(int index) const
return the observed CLb value for the i-th entry
double GetExpectedUpperLimit(double nsig=0, const char *opt="") const
get Limit value corresponding at the desired nsigma level (0) is median -1 sigma is 1 sigma
HypoTestInverterResult(const char *name=nullptr)
default constructor
double GetXValue(int index) const
function to return the value of the parameter of interest for the i^th entry in the results
double UpperLimit() override
return the interval upper limit
bool Add(const HypoTestInverterResult &otherResult)
merge with the content of another HypoTestInverterResult object
int FindClosestPointIndex(double target, int mode=0, double xtarget=0)
TList fExpPValues
list of expected sampling distribution for each point
double GetExpectedLowerLimit(double nsig=0, const char *opt="") const
get Limit value corresponding at the desired nsigma level (0) is median -1 sigma is 1 sigma
bool fIsTwoSided
two sided scan (look for lower/upper limit)
double CalculateEstimatedError(double target, bool lower=true, double xmin=1, double xmax=0.0)
Return an error estimate on the upper(lower) limit.
static int fgAsymptoticNumPoints
number of points used to build expected p-values
static double fgAsymptoticMaxSigma
max sigma value used to scan asymptotic expected p values
int ExclusionCleanup()
remove points that appear to have failed.
double LowerLimit() override
lower and upper bound of the confidence interval (to get upper/lower limits, multiply the size( = 1-c...
double CLs(int index) const
return the observed CLb value for the i-th entry
int FindIndex(double xvalue) const
find the index corresponding at the poi value xvalue If no points is found return -1 Note that a tole...
double GetYError(int index) const
function to return the estimated error on the value of the confidence level for the i^th entry in the...
double CLb(int index) const
return the observed CLb value for the i-th entry
TList fYObjects
list of HypoTestResult for each point
double GetExpectedLimit(double nsig, bool lower, const char *opt="") const
get expected limit (lower/upper) depending on the flag for asymptotic is a special case (the distribu...
SamplingDistribution * GetExpectedPValueDist(int index) const
return expected distribution of p-values (Cls or Clsplusb)
double CLsplusb(int index) const
return the observed CLsplusb value for the i-th entry
SamplingDistribution * GetLimitDistribution(bool lower) const
get the limit distribution (lower/upper depending on the flag) by interpolating the expected p values...
SamplingDistribution * GetNullTestStatDist(int index) const
same in terms of alt and null
SamplingDistribution * GetBackgroundTestStatDist(int index) const
get the background test statistic distribution
~HypoTestInverterResult() override
destructor
HypoTestResult is a base class for results from hypothesis tests.
virtual double CLsplusb() const
Convert AlternatePValue into a "confidence level".
TObject * Clone(const char *newname=nullptr) const override
clone method, required since some data members cannot rely on the streamers to copy them
virtual void Append(const HypoTestResult *other)
add values from another HypoTestResult
void SetBackgroundAsAlt(bool l=true)
bool GetPValueIsRightTail(void) const
virtual double AlternatePValue() const
Return p-value for alternate hypothesis.
void SetNullDistribution(SamplingDistribution *null)
bool GetBackGroundIsAlt(void) const
virtual double NullPValue() const
Return p-value for null hypothesis.
void SetTestStatisticData(const double tsd)
void SetAltDistribution(SamplingDistribution *alt)
void SetPValueIsRightTail(bool pr)
SamplingDistribution * GetNullDistribution(void) const
virtual double CLs() const
is simply (not a method, but a quantity)
SamplingDistribution * GetAltDistribution(void) const
This class simply holds a sampling distribution of some test statistic.
Int_t GetSize() const
size of samples
const std::vector< double > & GetSamplingDistribution() const
Get test statistics values.
double fUpperLimit
upper interval limit
SimpleInterval(const char *name=nullptr)
default constructor
RooArgSet fParameters
set containing the parameter of interest
double ConfidenceLevel() const override
return the confidence interval
double fLowerLimit
lower interval limit
double fConfidenceLevel
confidence level
SimpleInterval & operator=(const SimpleInterval &other)
default constructor
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
virtual Double_t Derivative(Double_t x, Double_t *params=nullptr, Double_t epsilon=0.001) const
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
virtual void SetParameters(const Double_t *params)
virtual void FixParameter(Int_t ipar, Double_t value)
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
void Print(Option_t *chopt="") const override
This method must be overridden when a class wants to print itself.
virtual void SetPointError(Double_t ex, Double_t ey)
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
virtual Double_t Eval(Double_t x, TSpline *spline=nullptr, Option_t *option="") const
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Axis_t xmin=0, Axis_t xmax=0)
void Draw(Option_t *chopt="") override
Default Draw method for all objects.
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
const char * GetName() const override
Returns name of object.
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
const char * Data() const
void ToUpper()
Change string to upper case.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
double normal_cdf(double x, double sigma=1, double x0=0)
Cumulative distribution function of the normal (Gaussian) distribution (lower tail).
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Namespace for the RooStats classes.
void SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down=kTRUE)
Sort the n1 elements of the Short_t array defined by its iterators.
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
T MinElement(Long64_t n, const T *a)
Returns minimum of array a of length n.
void Quantiles(Int_t n, Int_t nprob, Double_t *x, Double_t *quantiles, Double_t *prob, Bool_t isSorted=kTRUE, Int_t *index=nullptr, Int_t type=7)
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Comparing floating points.
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Comparing floating points.
T MaxElement(Long64_t n, const T *a)
Returns maximum of array a of length n.
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
static uint64_t sum(uint64_t i)