00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "RooStats/HypoTestInverterResult.h"
00022
00023 #include "RooStats/HypoTestInverterPlot.h"
00024 #include "RooStats/HybridResult.h"
00025
00026 #include "TF1.h"
00027 #include "TGraphErrors.h"
00028
00029 ClassImp(RooStats::HypoTestInverterResult)
00030
00031 using namespace RooStats;
00032
00033
00034 HypoTestInverterResult::HypoTestInverterResult(const char * name ) :
00035 SimpleInterval(name),
00036 fUseCLs(false),
00037 fInterpolateLowerLimit(true),
00038 fInterpolateUpperLimit(true)
00039 {
00040
00041 }
00042
00043
00044 HypoTestInverterResult::HypoTestInverterResult( const char* name,
00045 const RooRealVar& scannedVariable,
00046 double cl ) :
00047 SimpleInterval(name,scannedVariable,-999,999,cl),
00048 fUseCLs(false),
00049 fInterpolateLowerLimit(true),
00050 fInterpolateUpperLimit(true)
00051 {
00052
00053 fYObjects.SetOwner();
00054 }
00055
00056
00057 HypoTestInverterResult::~HypoTestInverterResult()
00058 {
00059
00060
00061 }
00062
00063
00064 bool HypoTestInverterResult::Add( const HypoTestInverterResult& )
00065 {
00066
00067
00068
00069 std::cout << "Sorry, this function is not yet implemented\n";
00070
00071 return true;
00072 }
00073
00074
00075 double HypoTestInverterResult::GetXValue( int index ) const
00076 {
00077 if ( index >= ArraySize() || index<0 ) {
00078 std::cout << "Problem: You are asking for an impossible array index value\n";
00079 return -999;
00080 }
00081
00082 return fXValues[index];
00083 }
00084
00085 double HypoTestInverterResult::GetYValue( int index ) const
00086 {
00087 if ( index >= ArraySize() || index<0 ) {
00088 std::cout << "Problem: You are asking for an impossible array index value\n";
00089 return -999;
00090 }
00091
00092 if (fUseCLs)
00093 return ((HybridResult*)fYObjects.At(index))->CLs();
00094 else
00095 return ((HybridResult*)fYObjects.At(index))->AlternatePValue();
00096 }
00097
00098 double HypoTestInverterResult::GetYError( int index ) const
00099 {
00100 if ( index >= ArraySize() || index<0 ) {
00101 std::cout << "Problem: You are asking for an impossible array index value\n";
00102 return -999;
00103 }
00104
00105 if (fUseCLs)
00106 return ((HybridResult*)fYObjects.At(index))->CLsError();
00107 else
00108 return ((HybridResult*)fYObjects.At(index))->CLsplusbError();
00109 }
00110
00111 HypoTestResult* HypoTestInverterResult::GetResult( int index ) const
00112 {
00113 if ( index >= ArraySize() || index<0 ) {
00114 std::cout << "Problem: You are asking for an impossible array index value\n";
00115 return 0;
00116 }
00117
00118 return ((HypoTestResult*) fYObjects.At(index));
00119 }
00120
00121 double HypoTestInverterResult::FindInterpolatedLimit(double target)
00122 {
00123 std::cout << "Interpolate the upper limit between the 2 results closest to the target confidence level" << endl;
00124
00125 if (ArraySize()<2) {
00126 std::cout << "Error: not enough points to get the inverted interval\n";
00127 if (target<0.5) return ((RooRealVar*)fParameters.first())->getMax();
00128 else return ((RooRealVar*)fParameters.first())->getMin();
00129 }
00130
00131 double v1 = fabs(GetYValue(0)-target);
00132 int i1 = 0;
00133 double v2 = fabs(GetYValue(1)-target);
00134 int i2 = 1;
00135
00136 if (ArraySize()>2)
00137 for (int i=2; i<ArraySize(); i++) {
00138 double vt = fabs(GetYValue(i)-target);
00139 if ( vt<v1 || vt<v2 ) {
00140 if ( v1<v2 ) {
00141 v2 = vt;
00142 i2 = i;
00143 } else {
00144 v1 = vt;
00145 i1 = i;
00146 }
00147 }
00148 }
00149
00150 return GetXValue(i1)+(target-GetYValue(i1))*(GetXValue(i2)-GetXValue(i1))/(GetYValue(i2)-GetYValue(i1));
00151 }
00152
00153 int HypoTestInverterResult::FindClosestPointIndex(double target)
00154 {
00155
00156 double bestValue = fabs(GetYValue(0)-target);
00157 int bestIndex = 0;
00158 for (int i=1; i<ArraySize(); i++) {
00159 if ( fabs(GetYValue(i)-target)<GetYError(i) ) {
00160 double value = fabs(GetYValue(i)-target);
00161 if ( value<bestValue ) {
00162 bestValue = value;
00163 bestIndex = i;
00164 }
00165 }
00166 }
00167
00168 return bestIndex;
00169 }
00170
00171 Double_t HypoTestInverterResult::LowerLimit()
00172 {
00173
00174 if ( fInterpolateLowerLimit ){
00175 fLowerLimit = FindInterpolatedLimit(1-(1-ConfidenceLevel())/2);
00176 } else {
00177 fLowerLimit = GetXValue( FindClosestPointIndex(1-(1-ConfidenceLevel())/2) );
00178 }
00179 return fLowerLimit;
00180 }
00181
00182 Double_t HypoTestInverterResult::UpperLimit()
00183 {
00184
00185 if ( fInterpolateUpperLimit ) {
00186 fUpperLimit = FindInterpolatedLimit((1-ConfidenceLevel())/2);
00187 } else {
00188 fUpperLimit = GetXValue( FindClosestPointIndex((1-ConfidenceLevel())/2) );
00189 }
00190 return fUpperLimit;
00191 }
00192
00193 Double_t HypoTestInverterResult::CalculateEstimatedError(double target)
00194 {
00195
00196
00197
00198
00199 if (ArraySize()<2) {
00200 std::cout << "not enough points to get the inverted interval\n";
00201 }
00202
00203
00204 HypoTestInverterPlot plot("plot", "", this);
00205 TGraphErrors* graph = plot.MakePlot();
00206 double* xs = graph->GetX();
00207 const double minX = xs[0];
00208 const double maxX = xs[ArraySize()-1];
00209
00210 TF1 fct("fct", "exp([0] * x + [1] * x**2)", minX, maxX);
00211 graph->Fit(&fct,"Q");
00212
00213 int index = FindClosestPointIndex(target);
00214 double m = fct.Derivative( GetXValue(index) );
00215 double theError = fabs( GetYError(index) / m);
00216
00217 delete graph;
00218
00219 return theError;
00220 }
00221
00222
00223 Double_t HypoTestInverterResult::LowerLimitEstimatedError()
00224 {
00225
00226 if (fInterpolateLowerLimit) std::cout << "The lower limit was an interpolated results... in this case the error is even less reliable (the Y-error bars are currently not used in the interpolation)\n";
00227
00228 return CalculateEstimatedError(ConfidenceLevel()/2);
00229 }
00230
00231
00232 Double_t HypoTestInverterResult::UpperLimitEstimatedError()
00233 {
00234
00235 if (fInterpolateUpperLimit) std::cout << "The upper limit was an interpolated results... in this case the error is even less reliable (the Y-error bars are currently not used in the interpolation)\n";
00236
00237 return CalculateEstimatedError((1-ConfidenceLevel())/2);
00238 }