52double HypoTestInverterResult::fgAsymptoticMaxSigma = 5;
53int HypoTestInverterResult::fgAsymptoticNumPoints = 11;
58HypoTestInverterResult::HypoTestInverterResult(
const char *
name ) :
62 fInterpolateLowerLimit(true),
63 fInterpolateUpperLimit(true),
64 fFittedLowerLimit(false),
65 fFittedUpperLimit(false),
66 fInterpolOption(kLinear),
69 fCLsCleanupThreshold(0.005)
83 fUseCLs(other.fUseCLs),
84 fIsTwoSided(other.fIsTwoSided),
85 fInterpolateLowerLimit(other.fInterpolateLowerLimit),
86 fInterpolateUpperLimit(other.fInterpolateUpperLimit),
87 fFittedLowerLimit(other.fFittedLowerLimit),
88 fFittedUpperLimit(other.fFittedUpperLimit),
89 fInterpolOption(other.fInterpolOption),
90 fLowerLimitError(other.fLowerLimitError),
91 fUpperLimitError(other.fUpperLimitError),
92 fCLsCleanupThreshold(other.fCLsCleanupThreshold)
99 for (
int i = 0; i < nOther; ++i)
135 for (
int i=0; i < nOther; ++i) {
158 fInterpolateLowerLimit(true),
159 fInterpolateUpperLimit(true),
160 fFittedLowerLimit(false),
161 fFittedUpperLimit(false),
162 fInterpolOption(kLinear),
163 fLowerLimitError(-1),
164 fUpperLimitError(-1),
165 fCLsCleanupThreshold(0.005)
202 std::vector<double> qv;
211 bool resultIsAsymptotic(
false);
215 if ( !
r->GetNullDistribution() && !
r->GetAltDistribution() ) {
216 resultIsAsymptotic =
true;
220 int nPointsRemoved(0);
222 double CLsobsprev(1.0);
223 std::vector<double>::iterator itr =
fXValues.begin();
236 const std::vector<double> & values =
s->GetSamplingDistribution();
238 oocoutE(
this,
Eval) <<
"HypoTestInverterResult::ExclusionCleanup - invalid size of sampling distribution" << std::endl;
245 if (resultIsAsymptotic) {
247 double dsig = 2.*maxSigma / (values.size() -1) ;
248 int i0 = (int)
TMath::Floor ( ( -nsig2 + maxSigma )/dsig + 0.5 );
249 int i1 = (int)
TMath::Floor ( ( -nsig1 + maxSigma )/dsig + 0.5 );
250 int i2 = (int)
TMath::Floor ( ( maxSigma )/dsig + 0.5 );
251 int i3 = (int)
TMath::Floor ( ( nsig1 + maxSigma )/dsig + 0.5 );
252 int i4 = (int)
TMath::Floor ( ( nsig2 + maxSigma )/dsig + 0.5 );
260 double * z =
const_cast<double *
>( &values[0] );
268 for (
int j=0; j<5; ++j) { qv[j]=
q[j]; }
275 double CLsobs = qv[5];
279 bool removeThisPoint(
false);
282 if (!removeThisPoint && resultIsAsymptotic && i>=1 && CLsobs>CLsobsprev) {
284 removeThisPoint =
true;
285 }
else { CLsobsprev = CLsobs; }
288 if (!removeThisPoint && i>=1 && CLsobs>=0.9999) {
290 removeThisPoint =
true;
296 if (removeThisPoint) {
313 return nPointsRemoved;
331 if (nOther == 0)
return true;
339 oocoutI(
this,
Eval) <<
"HypoTestInverterResult::Add - merging result from " << otherResult.
GetName()
340 <<
" in " <<
GetName() << std::endl;
345 if (addExpPValues || mergeExpPValues)
346 oocoutI(
this,
Eval) <<
"HypoTestInverterResult::Add - merging also the expected p-values from pseudo-data" << std::endl;
353 for (
int i = 0; i < nOther; ++i)
360 for (
int i = 0; i < nOther; ++i) {
361 double otherVal = otherResult.
fXValues[i];
363 if (otherHTR == 0)
continue;
364 bool sameXFound =
false;
365 for (
int j = 0; j < nThis; ++j) {
372 thisHTR->
Append(otherHTR);
374 if (mergeExpPValues) {
379 if (thisNToys != otherNToys )
380 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::Add expected p values have been generated with different toys " << thisNToys <<
" , " << otherNToys << std::endl;
399 oocoutI(
this,
Eval) <<
"HypoTestInverterResult::Add - new number of points is " <<
fXValues.size()
402 oocoutI(
this,
Eval) <<
"HypoTestInverterResult::Add - new toys/point is "
424 if (!
r)
return false;
459 return result->CLs();
461 return result->CLsplusb();
476 return result->CLsError();
478 return result->CLsplusbError();
491 return result->CLb();
503 return result->CLsplusb();
515 return result->CLs();
527 return result->CLbError();
539 return result->CLsplusbError();
551 return result->CLsError();
574 const double tol = 1.E-12;
593 std::cout <<
"using graph for search " << lowSearch <<
" min " << axmin <<
" max " << axmax << std::endl;
598 const double *
y =
graph.GetY();
601 ooccoutE(
this,
Eval) <<
"HypoTestInverterResult::GetGraphX - need at least 2 points for interpolation (n=" <<
n <<
")\n";
602 return (
n>0) ?
y[0] : 0;
619 return (lowSearch) ? varmax : varmin;
622 return (lowSearch) ? varmin : varmax;
629 if (axmin >= axmax ) {
632 std::cout <<
"No rage given - check if extrapolation is needed " << std::endl;
638 double yfirst =
graph.GetY()[0];
639 double ylast =
graph.GetY()[
n-1];
645 if ( (
ymax < y0 && !lowSearch) || ( yfirst > y0 && lowSearch) ) {
649 if ( (
ymax < y0 && lowSearch) || ( ylast > y0 && !lowSearch) ) {
654 auto func = [&](
double x) {
664 <<
" , " <<
graph.Eval(
xmax) <<
" target " << y0 << std::endl;
667 bool ret = brf.
Solve(100, 1.E-16, 1.E-6);
669 ooccoutE(
this,
Eval) <<
"HypoTestInverterResult - interpolation failed for interval [" <<
xmin <<
"," <<
xmax
671 <<
" target=" << y0 <<
" return inf" << std::endl;
674 double limit = brf.
Root();
683 if (lowSearch) std::cout <<
"lower limit search : ";
684 else std::cout <<
"Upper limit search : ";
685 std::cout <<
"interpolation done between " <<
xmin <<
" and " <<
xmax
686 <<
"\n Found limit using RootFinder is " << limit << std::endl;
688 TString fname =
"graph_upper.root";
689 if (lowSearch) fname =
"graph_lower.root";
691 graph.Write(
"graph");
697 if (axmin >= axmax) {
700 std::cout <<
"do new interpolation dividing from " << index <<
" and " <<
y[index] << std::endl;
703 if (lowSearch && index >= 1 && (
y[0] - y0) * (
y[index]- y0) < 0) {
707 else if (!lowSearch && index <
n-2 && (
y[
n-1] - y0) * (
y[index+1]- y0) < 0) {
736 double val = (lowSearch) ?
xmin :
xmax;
737 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::FindInterpolatedLimit"
738 <<
" - not enough points to get the inverted interval - return "
747 std::vector<unsigned int> index(
n );
751 for (
int i = 0; i <
n; ++i)
763 double * itrmax = std::max_element(
graph.GetY() ,
graph.GetY() +
n);
764 double ymax = *itrmax;
765 int iymax = itrmax -
graph.GetY();
766 double xwithymax =
graph.GetX()[iymax];
769 std::cout <<
" max of y " << iymax <<
" " << xwithymax <<
" " <<
ymax <<
" target is " << target << std::endl;
801 if (iymax <= (
n-1)/2 ) {
812 std::cout <<
" found xmin, xmax = " <<
xmin <<
" " <<
xmax <<
" for search " << lowSearch << std::endl;
823 if (upI < 1)
return xmin;
829 if (lowI >=
n-1)
return xmax;
837 std::cout <<
"finding " << lowSearch <<
" limit between " <<
xmin <<
" " <<
xmax << endl;
847 TString limitType = (lowSearch) ?
"lower" :
"upper";
848 ooccoutD(
this,
Eval) <<
"HypoTestInverterResult::FindInterpolateLimit "
849 <<
"the computed " << limitType <<
" limit is " << limit <<
" +/- " << error << std::endl;
852 std::cout <<
"Found limit is " << limit <<
" +/- " << error << std::endl;
900 int closestIndex = -1;
902 double smallestError = 2;
903 double bestValue = 2;
912 if (
dist < bestValue) {
917 if (bestIndex >=0)
return bestIndex;
925 std::vector<unsigned int> indx(
n);
927 std::vector<double> xsorted(
n);
928 for (
int i = 0; i <
n; ++i) xsorted[i] =
fXValues[indx[i] ];
932 std::cout <<
"finding closest point to " << xtarget <<
" is " << index1 <<
" " << indx[index1] << std::endl;
936 if (index1 < 0)
return indx[0];
937 if (index1 >=
n-1)
return indx[
n-1];
938 int index2 = index1 +1;
940 if (mode == 2)
return (
GetXValue(indx[index1]) <
GetXValue(indx[index2])) ? indx[index1] : indx[index2];
941 if (mode == 3)
return (
GetXValue(indx[index1]) >
GetXValue(indx[index2])) ? indx[index1] : indx[index2];
989 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::CalculateEstimateError"
990 <<
"Empty result \n";
995 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::CalculateEstimateError"
996 <<
" only points - return its error\n";
1006 std::cout <<
"calculate estimate error " <<
type <<
" between " <<
xmin <<
" and " <<
xmax << std::endl;
1011 std::vector<unsigned int> indx(
fXValues.size());
1027 if (
graph.GetN() < 2) {
1028 if (np >= 2)
oocoutW(
this,
Eval) <<
"HypoTestInverterResult::CalculateEstimatedError - no valid points - cannot estimate the " <<
type <<
" limit error " << std::endl;
1039 TF1 fct(
"fct",
"exp([0] * (x - [2] ) + [1] * (x-[2])**2)", minX, maxX);
1040 double scale = maxX-minX;
1059 std::cout <<
"fitting for limit " <<
type <<
"between " << minX <<
" , " << maxX <<
" points considered " <<
graph.GetN() << std::endl;
1060 int fitstat =
graph.Fit(&fct,
" EX0");
1061 graph.SetMarkerStyle(20);
1067 int fitstat =
graph.Fit(&fct,
"Q EX0");
1071 double theError = 0;
1080 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::CalculateEstimatedError - cannot estimate the " <<
type <<
" limit error " << std::endl;
1089 std::cout <<
"closes point to the limit is " << index <<
" " <<
GetXValue(index) <<
" and has error " <<
GetYError(index) << std::endl;
1122 if (!firstResult)
return 0;
1131 if (!result)
return 0;
1140 if (index < 0 || index >=
ArraySize() )
return 0;
1146 static bool useFirstB =
false;
1148 int bIndex = (useFirstB) ? 0 : index;
1155 if (bDistribution && sbDistribution) {
1165 std::vector<double> values(bDistribution->
GetSize());
1166 for (
int i = 0; i < bDistribution->
GetSize(); ++i) {
1178 const double dsig = 2* smax/ (npoints-1) ;
1179 std::vector<double> values(npoints);
1180 for (
int i = 0; i < npoints; ++i) {
1181 double nsig = -smax + dsig*i;
1183 if (pval < 0) {
return 0;}
1186 return new SamplingDistribution(
"Asymptotic expected values",
"Asymptotic expected values",values);
1196 oocoutE(
this,
Eval) <<
"HypoTestInverterResult::GetLimitDistribution"
1197 <<
" not enough points - return 0 " << std::endl;
1201 ooccoutD(
this,
Eval) <<
"HypoTestInverterResult - computing limit distribution...." << std::endl;
1206 std::vector<SamplingDistribution*> distVec( npoints );
1208 for (
unsigned int i = 0; i < distVec.size(); ++i) {
1213 distVec[i]->InverseCDF(0);
1214 sum += distVec[i]->GetSize();
1217 int size = int(
sum/ npoints);
1220 ooccoutW(
this,
InputArguments) <<
"HypoTestInverterResult - set a minimum size of 10 for limit distribution" << std::endl;
1228 std::vector< std::vector<double> > quantVec(npoints );
1229 for (
int i = 0; i < npoints; ++i) {
1231 if (!distVec[i])
continue;
1234 std::vector<double> pvalues = distVec[i]->GetSamplingDistribution();
1235 delete distVec[i]; distVec[i] = 0;
1236 std::sort(pvalues.begin(), pvalues.end());
1241 quantVec[i] = std::vector<double>(size);
1242 for (
int ibin = 0; ibin < size; ++ibin) {
1244 p[0] = std::min( (ibin+1) * 1./
double(size), 1.0);
1247 (quantVec[i])[ibin] =
q[0];
1253 std::vector<unsigned int> index( npoints );
1260 std::vector<double> limits(size);
1262 for (
int j = 0; j < size; ++j ) {
1265 for (
int k = 0; k < npoints ; ++k) {
1266 if (quantVec[index[k]].size() > 0 )
1267 g.SetPoint(
g.GetN(),
GetXValue(index[k]), (quantVec[index[k]])[j] );
1328 if (nEntries <= 0)
return (lower) ? 1 : 0;
1332 if (!
r->GetNullDistribution() && !
r->GetAltDistribution() ) {
1336 if (!limitDist)
return 0;
1338 if (values.size() <= 1)
return 0;
1360 std::vector<unsigned int> index(nEntries);
1363 for (
int j=0; j<nEntries; ++j) {
1367 ooccoutI(
this,
Eval) <<
"HypoTestInverterResult - cannot compute expected p value distribution for point, x = "
1368 <<
GetXValue(i) <<
" skip it " << std::endl;
1371 const std::vector<double> & values =
s->GetSamplingDistribution();
1372 double *
x =
const_cast<double *
>(&values[0]);
1378 ooccoutE(
this,
Eval) <<
"HypoTestInverterResult - cannot compute limits , not enough points, n = " <<
g.GetN() << std::endl;
1389 if (!limitDist)
return 0;
1391 double *
x =
const_cast<double *
>(&values[0]);
Class for finding the root of a one dimensional function using the Brent algorithm.
double Root() const
Returns root value.
bool Solve(int maxIter=100, double absTol=1E-8, double relTol=1E-10)
Returns the X value corresponding to the function value fy for (xmin<x<xmax).
void SetNpx(int npx)
Set the number of point used to bracket root using a grid.
bool SetFunction(const ROOT::Math::IGenFunction &f, double xlow, double xup)
Sets the function for the rest of the algorithms.
Functor1D class for one-dimensional functions.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
RooAbsArg * first() const
virtual Double_t getMax(const char *name=0) const
Get maximum of currently defined range.
virtual Double_t getMin(const char *name=0) const
Get miniminum of currently defined range.
virtual Bool_t addOwned(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling addOwned() for each element in the source...
RooRealVar represents a fundamental (non-derived) real valued object.
virtual TObject * clone(const char *newname) const
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...
Double_t LowerLimit()
lower and upper bound of the confidence interval (to get upper/lower limits, multiply the size( = 1-c...
Double_t LowerLimitEstimatedError()
rough estimation of the error on the computed bound of the confidence interval Estimate of lower limi...
bool fInterpolateUpperLimit
double GetYValue(int index) const
function to return the value of the confidence level for the i^th entry in the results
SamplingDistribution * GetSignalAndBackgroundTestStatDist(int index) const
get the signal and background test statistic distribution
double fCLsCleanupThreshold
Double_t UpperLimitEstimatedError()
Estimate of lower limit error function evaluates only a rough error on the lower limit.
HypoTestResult * GetResult(int index) const
return a pointer to the i^th result object
double fLowerLimitError
interpolation option (linear or spline)
HypoTestInverterResult & operator=(const HypoTestInverterResult &other)
operator =
double CalculateEstimatedError(double target, bool lower=true, double xmin=1, double xmax=0)
Return an error estimate on the upper(lower) limit.
InterpolOption_t fInterpolOption
HypoTestInverterResult(const char *name=0)
default constructor
int ArraySize() const
number of entries in the results array
double FindInterpolatedLimit(double target, bool lowSearch=false, double xmin=1, double xmax=0)
interpolate to find a limit value Use a linear or a spline interpolation depending on the interpolati...
bool fInterpolateLowerLimit
two sided scan (look for lower/upper limit)
std::vector< double > fXValues
number of points used to build expected p-values
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
double GetXValue(int index) const
function to return the value of the parameter of interest for the i^th entry in the results
virtual ~HypoTestInverterResult()
destructor
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 HypoTestResult 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
static int fgAsymptoticNumPoints
max sigma value used to scan asymptotic expected p values
static double fgAsymptoticMaxSigma
int ExclusionCleanup()
remove points that appear to have failed.
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
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
HypoTestResult is a base class for results from hypothesis tests.
void SetBackgroundAsAlt(Bool_t l=kTRUE)
Bool_t GetPValueIsRightTail(void) const
virtual void Append(const HypoTestResult *other)
add values from another HypoTestResult
virtual Double_t CLsplusb() const
Convert AlternatePValue into a "confidence level".
void SetPValueIsRightTail(Bool_t pr)
virtual Double_t AlternatePValue() const
Return p-value for alternate hypothesis.
virtual Double_t NullPValue() const
Return p-value for null hypothesis.
void SetTestStatisticData(const Double_t tsd)
void SetNullDistribution(SamplingDistribution *null)
virtual Double_t CLs() const
is simply (not a method, but a quantity)
Bool_t GetBackGroundIsAlt(void) const
void SetAltDistribution(SamplingDistribution *alt)
SamplingDistribution * GetNullDistribution(void) const
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_t > & GetSamplingDistribution() const
Get test statistics values.
SimpleInterval is a concrete implementation of the ConfInterval interface.
virtual Double_t ConfidenceLevel() const
return confidence level
Double_t fConfidenceLevel
SimpleInterval & operator=(const SimpleInterval &other)
virtual void RemoveAll(TCollection *col)
Remove all objects in collection col from this collection.
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
virtual Double_t Derivative(Double_t x, Double_t *params=0, Double_t epsilon=0.001) const
Returns the first derivative of the function at point x, computed by Richardson's extrapolation metho...
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set limits for parameter ipar.
virtual void SetParameters(const Double_t *params)
virtual void FixParameter(Int_t ipar, Double_t value)
Fix the value of a parameter The specified value will be used in a fit operation.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseGeneralPurpose, Int_t netopt=0)
Create / open a file.
A TGraphErrors is a TGraph with error bars.
A Graph is a graphics object made of two arrays X and Y with npoints each.
virtual void Add(TObject *obj)
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
virtual const char * GetName() const
Returns name of object.
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
virtual TObject * RemoveAt(Int_t idx)
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).
double dist(Rotation3D const &r1, Rotation3D const &r2)
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
Template specialisation used in RooAbsArg:
Namespace for the RooStats classes.
static constexpr double s
Short_t Max(Short_t a, Short_t b)
void SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down=kTRUE)
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754
Double_t Floor(Double_t x)
T MinElement(Long64_t n, const T *a)
Return minimum of array a of length n.
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
T MaxElement(Long64_t n, const T *a)
Return maximum of array a of length n.
Long64_t BinarySearch(Long64_t n, const T *array, T value)
void Quantiles(Int_t n, Int_t nprob, Double_t *x, Double_t *quantiles, Double_t *prob, Bool_t isSorted=kTRUE, Int_t *index=0, Int_t type=7)
Computes sample quantiles, corresponding to the given probabilities.
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
static long int sum(long int i)