36 using namespace RooStats;
37 using namespace RooFit;
42 double HypoTestInverterResult::fgAsymptoticMaxSigma = 5;
45 HypoTestInverterResult::HypoTestInverterResult(const
char * name ) :
49 fInterpolateLowerLimit(true),
50 fInterpolateUpperLimit(true),
51 fFittedLowerLimit(false),
52 fFittedUpperLimit(false),
53 fInterpolOption(kLinear),
56 fCLsCleanupThreshold(0.005)
63 fExpPValues.SetOwner();
69 fUseCLs(other.fUseCLs),
70 fIsTwoSided(other.fIsTwoSided),
71 fInterpolateLowerLimit(other.fInterpolateLowerLimit),
72 fInterpolateUpperLimit(other.fInterpolateUpperLimit),
73 fFittedLowerLimit(other.fFittedLowerLimit),
74 fFittedUpperLimit(other.fFittedUpperLimit),
75 fInterpolOption(other.fInterpolOption),
76 fLowerLimitError(other.fLowerLimitError),
77 fUpperLimitError(other.fUpperLimitError),
78 fCLsCleanupThreshold(other.fCLsCleanupThreshold)
86 for (
int i = 0; i < nOther; ++i)
121 for (
int i=0; i < nOther; ++i) {
142 fInterpolateLowerLimit(true),
143 fInterpolateUpperLimit(true),
144 fFittedLowerLimit(false),
145 fFittedUpperLimit(false),
146 fInterpolOption(kLinear),
147 fLowerLimitError(-1),
148 fUpperLimitError(-1),
149 fCLsCleanupThreshold(0.005)
158 fParameters.removeAll();
159 fParameters.takeOwnership();
184 std::vector<double> qv;
193 bool resultIsAsymptotic(
false);
198 resultIsAsymptotic =
true;
202 int nPointsRemoved(0);
204 double CLsobsprev(1.0);
205 std::vector<double>::iterator itr =
fXValues.begin();
222 if (resultIsAsymptotic) {
224 double dsig = 2.*maxSigma / (values.size() -1) ;
225 int i0 = (int)
TMath::Floor ( ( -nsig2 + maxSigma )/dsig + 0.5 );
226 int i1 = (int)
TMath::Floor ( ( -nsig1 + maxSigma )/dsig + 0.5 );
227 int i2 = (int)
TMath::Floor ( ( maxSigma )/dsig + 0.5 );
228 int i3 = (int)
TMath::Floor ( ( nsig1 + maxSigma )/dsig + 0.5 );
229 int i4 = (int)
TMath::Floor ( ( nsig2 + maxSigma )/dsig + 0.5 );
237 double * z =
const_cast<double *
>( &values[0] );
245 for (
int j=0; j<5; ++j) { qv[j]=q[j]; }
252 double CLsobs = qv[5];
256 bool removeThisPoint(
false);
259 if (!removeThisPoint && resultIsAsymptotic && i>=1 && CLsobs>CLsobsprev) {
261 removeThisPoint =
true;
262 }
else { CLsobsprev = CLsobs; }
265 if (!removeThisPoint && i>=1 && CLsobs>=0.9999) {
267 removeThisPoint =
true;
270 if (!removeThisPoint && i>=1 && qv[4]<fCLsCleanupThreshold) { removeThisPoint =
true; }
273 if (removeThisPoint) {
290 return nPointsRemoved;
308 if (nOther == 0)
return true;
316 oocoutI(
this,
Eval) <<
"HypoTestInverterResult::Add - merging result from " << otherResult.
GetName()
317 <<
" in " <<
GetName() << std::endl;
322 if (addExpPValues || mergeExpPValues)
323 oocoutI(
this,
Eval) <<
"HypoTestInverterResult::Add - merging also the expected p-values from pseudo-data" << std::endl;
330 for (
int i = 0; i < nOther; ++i)
337 for (
int i = 0; i < nOther; ++i) {
338 double otherVal = otherResult.
fXValues[i];
340 if (otherHTR == 0)
continue;
341 bool sameXFound =
false;
342 for (
int j = 0; j < nThis; ++j) {
349 thisHTR->
Append(otherHTR);
351 if (mergeExpPValues) {
356 if (thisNToys != otherNToys )
357 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::Add expexted p values have been generated with different toys " << thisNToys <<
" , " << otherNToys << std::endl;
376 oocoutI(
this,
Eval) <<
"HypoTestInverterResult::Add - new number of points is " <<
fXValues.size()
379 oocoutI(
this,
Eval) <<
"HypoTestInverterResult::Add - new toys/point is "
399 if (!r)
return false;
434 return result->CLsplusb();
447 return result->CLsError();
449 return result->CLsplusbError();
470 return result->CLsplusb();
489 return result->CLbError();
499 return result->CLsplusbError();
509 return result->CLsError();
528 const double tol = 1.E-12;
539 struct InterpolatedGraph {
540 InterpolatedGraph(
const TGraph &
g,
double target,
const char * interpOpt) :
541 fGraph(g), fTarget(target), fInterpOpt(interpOpt) {}
545 return fGraph.Eval(x, (
TSpline*) 0, fInterpOpt) - fTarget;
562 InterpolatedGraph
f(graph,y0,opt);
567 const double * y = graph.
GetY();
568 int n = graph.
GetN();
570 ooccoutE(
this,
Eval) <<
"HypoTestInverterResult::GetGraphX - need at least 2 points for interpolation (n=" << n <<
")\n";
571 return (n>0) ? y[0] : 0;
585 if (axmin >= axmax ) {
586 xmin = graph.
GetX()[0];
587 xmax = graph.
GetX()[n-1];
595 if ( (ymax < y0 && !lowSearch) || ( ymin > y0 && lowSearch) ) {
599 if ( (ymax < y0 && lowSearch) || ( ymin > y0 && !lowSearch) ) {
605 #ifdef ISREALLYNEEDED //??
607 bool isCross =
false;
610 for (
int i = 0; i<
n; ++i) {
613 if (xp >= xmin && xp <= xmax) {
615 if (prod < 0 && !first) {
623 return (lowSearch) ? varmin : varmax;
632 bool ret = brf.
Solve(100, 1.
E-16, 1.
E-6);
634 ooccoutE(
this,
Eval) <<
"HypoTestInverterResult - interpolation failed - return inf" << std::endl;
637 double limit = brf.
Root();
641 if (lowSearch) std::cout <<
"lower limit search : ";
642 else std::cout <<
"Upper limit search : ";
643 std::cout <<
"do interpolation between " << xmin <<
" and " << xmax <<
" limit is " << limit << std::endl;
648 if (axmin >= axmax) {
651 std::cout <<
"do new interpolation dividing from " << index <<
" and " << y[index] << std::endl;
654 if (lowSearch && index >= 1 && (y[0] - y0) * ( y[index]- y0) < 0) {
658 else if (!lowSearch && index < n-2 && (y[n-1] - y0) * ( y[index+1]- y0) < 0) {
660 limit =
GetGraphX(graph, y0, lowSearch, graph.
GetX()[index+1], graph.
GetX()[n-1] );
676 <<
"Interpolate the upper limit between the 2 results closest to the target confidence level"
689 double val = (lowSearch) ? xmin : xmax;
690 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::FindInterpolatedLimit"
691 <<
" - not enough points to get the inverted interval - return "
700 std::vector<unsigned int> index(n );
704 for (
int i = 0; i <
n; ++i)
716 double * itrmax = std::max_element(graph.GetY() , graph.GetY() +
n);
717 double ymax = *itrmax;
718 int iymax = itrmax - graph.GetY();
719 double xwithymax = graph.GetX()[iymax];
728 xmin = ( graph.GetY()[0] <= target ) ? graph.GetX()[0] : varmin;
741 xmax = ( graph.GetY()[n-1] <= target ) ? graph.GetX()[n-1] : varmax;
755 if (iymax <= (n-1)/2 ) {
766 std::cout <<
" found xmin, xmax = " << xmin <<
" " << xmax <<
" for search " << lowSearch << std::endl;
777 if (upI < 1)
return xmin;
783 if (lowI >= n-1)
return xmax;
791 std::cout <<
"finding " << lowSearch <<
" limit betweem " << xmin <<
" " << xmax << endl;
794 double limit =
GetGraphX(graph, target, lowSearch, xmin, xmax);
800 std::cout <<
"limit is " << limit << std::endl;
814 double limit2 =
GetGraphX(graph, target, !lowSearch, xmin, xmax);
821 std::cout <<
"other limit is " << limit2 << std::endl;
840 int closestIndex = -1;
842 double smallestError = 2;
843 double bestValue = 2;
852 if ( dist < bestValue) {
857 if (bestIndex >=0)
return bestIndex;
865 std::vector<unsigned int> indx(n);
867 std::vector<double> xsorted( n);
868 for (
int i = 0; i <
n; ++i) xsorted[i] =
fXValues[indx[i] ];
872 std::cout <<
"finding closest point to " << xtarget <<
" is " << index1 <<
" " << indx[index1] << std::endl;
876 if (index1 < 0)
return indx[0];
877 if (index1 >= n-1)
return indx[n-1];
878 int index2 = index1 +1;
880 if (mode == 2)
return (
GetXValue(indx[index1]) <
GetXValue(indx[index2])) ? indx[index1] : indx[index2];
881 if (mode == 3)
return (
GetXValue(indx[index1]) >
GetXValue(indx[index2])) ? indx[index1] : indx[index2];
924 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::CalculateEstimateError"
925 <<
"Empty result \n";
930 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::CalculateEstimateError"
931 <<
" only points - return its error\n";
941 std::cout <<
"calculate estimate error " << type <<
" between " << xmin <<
" and " << xmax << std::endl;
946 std::vector<unsigned int> indx(
fXValues.size());
957 graph.SetPointError(ip, 0.,
GetYError(indx[i]) );
962 if (graph.GetN() < 2) {
963 if (np >= 2)
oocoutW(
this,
Eval) <<
"HypoTestInverterResult::CalculateEstimatedError - no valid points - cannot estimate the " << type <<
" limit error " << std::endl;
976 TF1 fct(
"fct",
"exp([0] * (x - [2] ) + [1] * (x-[2])**2)", minX, maxX);
977 double scale = maxX-minX;
996 std::cout <<
"fitting for limit " << type <<
"between " << minX <<
" , " << maxX <<
" points considered " << graph.GetN() << std::endl;
997 int fitstat = graph.Fit(&fct,
" EX0");
998 graph.SetMarkerStyle(20);
1004 int fitstat = graph.Fit(&fct,
"Q EX0");
1008 double theError = 0;
1017 oocoutW(
this,
Eval) <<
"HypoTestInverterResult::CalculateEstimatedError - cannot estimate the " << type <<
" limit error " << std::endl;
1021 fLowerLimitError = theError;
1023 fUpperLimitError = theError;
1026 std::cout <<
"closes point to the limit is " << index <<
" " <<
GetXValue(index) <<
" and has error " <<
GetYError(index) << std::endl;
1055 if (!firstResult)
return 0;
1062 if (!result)
return 0;
1069 if (index < 0 || index >=
ArraySize() )
return 0;
1075 static bool useFirstB =
false;
1077 int bIndex = (useFirstB) ? 0 : index;
1084 if (bDistribution && sbDistribution) {
1094 std::vector<double> values(bDistribution->
GetSize());
1095 for (
int i = 0; i < bDistribution->
GetSize(); ++i) {
1103 fgAsymptoticMaxSigma = 5;
1104 const int npoints = 11;
1106 const double dsig = 2* smax/ (npoints-1) ;
1107 std::vector<double> values(npoints);
1108 for (
int i = 0; i < npoints; ++i) {
1109 double nsig = -smax + dsig*i;
1111 if (pval < 0) {
return 0;}
1114 return new SamplingDistribution(
"Asymptotic expected values",
"Asymptotic expected values",values);
1126 oocoutE(
this,
Eval) <<
"HypoTestInverterResult::GetLimitDistribution"
1127 <<
" not enought points - return 0 " << std::endl;
1131 ooccoutD(
this,
Eval) <<
"HypoTestInverterResult - computing limit distribution...." << std::endl;
1136 std::vector<SamplingDistribution*> distVec( npoints );
1138 for (
unsigned int i = 0; i < distVec.size(); ++i) {
1143 distVec[i]->InverseCDF(0);
1144 sum += distVec[i]->GetSize();
1147 int size = int( sum/ npoints);
1150 ooccoutW(
this,
InputArguments) <<
"HypoTestInverterResult - set a minimum size of 10 for limit distribution" << std::endl;
1158 std::vector< std::vector<double> > quantVec(npoints );
1159 for (
int i = 0; i < npoints; ++i) {
1161 if (!distVec[i])
continue;
1164 std::vector<double> pvalues = distVec[i]->GetSamplingDistribution();
1165 delete distVec[i]; distVec[i] = 0;
1166 std::sort(pvalues.begin(), pvalues.end());
1171 quantVec[i] = std::vector<double>(size);
1172 for (
int ibin = 0; ibin < size; ++ibin) {
1174 p[0] =
std::min( (ibin+1) * 1./
double(size), 1.0);
1177 (quantVec[i])[ibin] = q[0];
1183 std::vector<unsigned int> index( npoints );
1190 std::vector<double> limits(size);
1192 for (
int j = 0; j < size; ++j ) {
1195 for (
int k = 0; k < npoints ; ++k) {
1196 if (quantVec[index[k]].size() > 0 )
1200 limits[j] =
GetGraphX(g, target, lower);
1256 if (nEntries <= 0)
return (lower) ? 1 : 0;
1264 if (!limitDist)
return 0;
1266 if (values.size() <= 1)
return 0;
1267 double dsig = 2* fgAsymptoticMaxSigma/ (values.size() -1) ;
1268 int i = (int)
TMath::Floor ( (nsig + fgAsymptoticMaxSigma)/dsig + 0.5);
1288 std::vector<unsigned int> index(nEntries);
1291 for (
int j=0; j<nEntries; ++j) {
1295 ooccoutI(
this,
Eval) <<
"HypoTestInverterResult - cannot compute expected p value distribution for point, x = "
1296 <<
GetXValue(i) <<
" skip it " << std::endl;
1300 double * x =
const_cast<double *
>(&values[0]);
1306 ooccoutE(
this,
Eval) <<
"HypoTestInverterResult - cannot compute limits , not enough points, n = " << g.
GetN() << std::endl;
1317 if (!limitDist)
return 0;
1319 double * x =
const_cast<double *
>(&values[0]);
SamplingDistribution * GetLimitDistribution(bool lower) const
void SetBackgroundAsAlt(Bool_t l=kTRUE)
double dist(Rotation3D const &r1, Rotation3D const &r2)
void SetAltDistribution(SamplingDistribution *alt)
virtual void SetParameters(const Double_t *params)
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Double_t Floor(Double_t x)
virtual Double_t ConfidenceLevel() const
return confidence level
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
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 ...
double CLbError(int index) const
return the observed CLb value for the i-th entry
HypoTestInverterResult(const char *name=0)
default constructor
int ArraySize() const
number of entries in the results array
virtual Double_t CLs() const
CLs is simply CLs+b/CLb (not a method, but a quantity)
int FindClosestPointIndex(double target, int mode=0, double xtarget=0)
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Base class for spline implementation containing the Draw/Paint methods //.
HypoTestResult is a base class for results from hypothesis tests.
void ToUpper()
Change string to upper case.
SamplingDistribution * GetSignalAndBackgroundTestStatDist(int index) const
virtual Double_t getMin(const char *name=0) const
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...
SamplingDistribution * GetAltDistribution(void) const
Int_t GetSize() const
size of samples
virtual Double_t CLsplusb() const
Convert AlternatePValue into a "confidence level".
SamplingDistribution * GetBackgroundTestStatDist(int index) const
const std::vector< Double_t > & GetSamplingDistribution() const
Get test statistics values.
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
virtual TObject * RemoveAt(Int_t idx)
Template class to wrap any C++ callable object which takes one argument i.e.
const char * Data() const
SimpleInterval & operator=(const SimpleInterval &other)
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
double FindInterpolatedLimit(double target, bool lowSearch=false, double xmin=1, double xmax=0)
double CLsError(int index) const
return the observed CLb value for the i-th entry
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 Parameters: x -the data sample n ...
double normal_cdf(double x, double sigma=1, double x0=0)
Cumulative distribution function of the normal (Gaussian) distribution (lower tail).
Double_t fConfidenceLevel
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save Pad contents in a file in one of various formats.
virtual ~HypoTestInverterResult()
destructor
static Vc_ALWAYS_INLINE Vector< T > abs(const Vector< T > &x)
virtual Double_t NullPValue() const
Return p-value for null hypothesis.
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Double_t LowerLimit()
lower and upper bound of the confidence interval (to get upper/lower limits, multiply the size( = 1-c...
bool fInterpolateLowerLimit
two sided scan (look for lower/upper limit)
int ExclusionCleanup()
remove points that appear to have failed.
double GetGraphX(const TGraph &g, double y0, bool lowSearch, double &xmin, double &xmax) const
HypoTestResult * GetResult(int index) const
return a pointer to the i^th result object
double CLsplusb(int index) const
return the observed CLsplusb value for the i-th entry
double Root() const
Returns root value.
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set limits for parameter ipar.
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
SamplingDistribution * GetExpectedPValueDist(int index) const
return expected distribution of p-values (Cls or Clsplusb)
double GetExpectedLowerLimit(double nsig=0, const char *opt="") const
get Limit value correspnding at the desired nsigma level (0) is median -1 sigma is 1 sigma ...
double fCLsCleanupThreshold
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. ...
TList fExpPValues
list of HypoTestResult for each point
virtual const char * GetName() const
Returns name of object.
Bool_t GetPValueIsRightTail(void) const
void SetTestStatisticData(const Double_t tsd)
This class simply holds a sampling distribution of some test statistic.
ClassImp(RooStats::HypoTestInverterResult) using namespace RooStats
virtual void Append(const HypoTestResult *other)
add values from another HypoTestResult
static double fgAsymptoticMaxSigma
Class for finding the root of a one dimensional function using the Brent algorithm.
void SetPValueIsRightTail(Bool_t pr)
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...
double GetXValue(int index) const
function to return the value of the parameter of interest for the i^th entry in the results ...
TRObject operator()(const T1 &t1) const
virtual Int_t GetSize() const
double CLs(int index) const
return the observed CLb value for the i-th entry
HypoTestInverterResult class: holds the array of hypothesis test results and compute a confidence int...
Double_t LowerLimitEstimatedError()
rough estimation of the error on the computed bound of the confidence interval Estimate of lower limi...
double GetYValue(int index) const
function to return the value of the confidence level for the i^th entry in the results ...
T MaxElement(Long64_t n, const T *a)
InterpolOption_t fInterpolOption
SamplingDistribution * GetNullDistribution(void) const
virtual Int_t GetPoint(Int_t i, Double_t &x, Double_t &y) const
Get x and y values for point number i.
double CLsplusbError(int index) const
return the observed CLsplusb value for the i-th entry
virtual Double_t AlternatePValue() const
Return p-value for alternate hypothesis.
virtual Double_t getMax(const char *name=0) const
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Double_t UpperLimitEstimatedError()
Estimate of lower limit error function evaluates only a rought error on the lower limit...
virtual TObject * clone(const char *newname) const
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
double GetExpectedUpperLimit(double nsig=0, const char *opt="") const
get Limit value correspnding at the desired nsigma level (0) is median -1 sigma is 1 sigma ...
HypoTestInverterResult & operator=(const HypoTestInverterResult &other)
operator =
virtual void Add(TObject *obj)
double fLowerLimitError
interpolatation option (linear or spline)
virtual void RemoveAll(TCollection *col)
Remove all objects in collection col from this collection.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
A Graph is a graphics object made of two arrays X and Y with npoints each.
A TGraphErrors is a TGraph with error bars.
double GetExpectedLimit(double nsig, bool lower, const char *opt="") const
bool Add(const HypoTestInverterResult &otherResult)
merge with the content of another HypoTestInverterResult object
int FindIndex(double xvalue) const
bool SetFunction(const ROOT::Math::IGenFunction &f, double xlow, double xup)
Sets the function for the rest of the algorithms.
void SetNpx(int npx)
Set the number of point used to bracket root using a grid.
double CalculateEstimatedError(double target, bool lower=true, double xmin=1, double xmax=0)
double CLb(int index) const
return the observed CLb value for the i-th entry
bool fInterpolateUpperLimit
Long64_t BinarySearch(Long64_t n, const T *array, T value)
void SetNullDistribution(SamplingDistribution *null)
void SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down=kTRUE)
SamplingDistribution * GetNullTestStatDist(int index) const
same in terms of alt and null
std::vector< double > fXValues
max sigma value used to scan asymptotic expected p values
T MinElement(Long64_t n, const T *a)
Bool_t GetBackGroundIsAlt(void) const