HypoTestInverterResult.cxx

Go to the documentation of this file.
00001 // @(#)root/roostats:$Id: HypoTestInverterResult.cxx 36230 2010-10-09 20:21:02Z wouter $
00002 // Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke
00003 /*************************************************************************
00004  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
00005  * All rights reserved.                                                  *
00006  *                                                                       *
00007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00009  *************************************************************************/
00010 
00011 
00012 /**
00013    HypoTestInverterResult class: holds the array of hypothesis test results and compute a confidence interval.
00014    Based on the RatioFinder code available in the RooStatsCms package developed by Gregory Schott and Danilo Piparo
00015    Ported and adapted to RooStats by Gregory Schott
00016    Some contributions to this class have been written by Matthias Wolf (error estimation)
00017 **/
00018 
00019 
00020 // include header file of this class 
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   // default constructor
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   // constructor 
00053    fYObjects.SetOwner();
00054 }
00055 
00056 
00057 HypoTestInverterResult::~HypoTestInverterResult()
00058 {
00059    // destructor
00060    // no need to delete explictly the objects in the TList since the TList owns the objects
00061 }
00062 
00063 
00064 bool HypoTestInverterResult::Add( const HypoTestInverterResult& /* otherResult */  )
00065 {
00066   /// Merge this HypoTestInverterResult with another
00067   /// HypoTestInverterResult passed as argument
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();  // CLs+b
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   // find the object with the smallest error that is < 1 sigma from the target
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) ) { // less than 1 sigma from target CL
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    //std::cout << "finding point with cl = " << 1-(1-ConfidenceLevel())/2 << endl;
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    //std::cout << "finding point with cl = " << (1-ConfidenceLevel())/2 << endl;
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   // Return an error estimate on the upper limit.  This is the error on
00196   // either CLs or CLsplusb divided by an estimate of the slope at this
00197   // point.
00198 
00199   if (ArraySize()<2) {
00200     std::cout << "not enough points to get the inverted interval\n";
00201   }
00202  
00203   // The graph contains the points sorted by their x-value
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    //std::cout << "The HypoTestInverterResult::LowerLimitEstimatedError() function evaluates only a rought error on the upper limit. Be careful when using this estimation\n";
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    //std::cout << "The HypoTestInverterResult::UpperLimitEstimatedError() function evaluates only a rought error on the upper limit. Be careful when using this estimation\n";
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 }

Generated on Tue Jul 5 15:14:34 2011 for ROOT_528-00b_version by  doxygen 1.5.1