LikelihoodIntervalPlot.cxx

Go to the documentation of this file.
00001 // @(#)root/roostats:$Id: LikelihoodIntervalPlot.cxx 34109 2010-06-24 15:00:16Z moneta $
00002 
00003 /*************************************************************************
00004  * Project: RooStats                                                     *
00005  * Package: RooFit/RooStats                                              *
00006  * Authors:                                                              *
00007  *   Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke       *
00008  *************************************************************************
00009  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
00010  * All rights reserved.                                                  *
00011  *                                                                       *
00012  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00013  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00014  *************************************************************************/
00015 
00016 //____________________________________________________________________
00017 /*
00018 LikelihoodIntervalPlot : 
00019 
00020 This class provides simple and straightforward utilities to plot a LikelihoodInterval
00021 object.
00022 */
00023 
00024 #include "RooStats/LikelihoodIntervalPlot.h"
00025 
00026 #include <algorithm>
00027 #include <iostream>
00028 
00029 #include "TROOT.h"
00030 #include "TMath.h"
00031 #include "TLine.h"
00032 #include "TObjArray.h"
00033 #include "TList.h"
00034 #include "TGraph.h"
00035 #include "TPad.h"
00036 
00037 
00038 #include "RooRealVar.h"
00039 #include "RooPlot.h"
00040 //#include "RooProfileLL.h"
00041 #include "TF1.h"
00042 
00043 /// ClassImp for building the THtml documentation of the class 
00044 ClassImp(RooStats::LikelihoodIntervalPlot);
00045 
00046 using namespace RooStats;
00047 
00048 //_______________________________________________________
00049 LikelihoodIntervalPlot::LikelihoodIntervalPlot()
00050 {
00051   // LikelihoodIntervalPlot default constructor
00052   // with default parameters
00053   fInterval = 0;
00054   fNdimPlot = 0;
00055   fParamsPlot = 0;
00056   fColor = 0;
00057   fFillStyle = 4050; // half transparent
00058   fLineColor = 0;
00059   fMaximum = 2.;
00060   fNPoints = 0;  // default depends if 1D or 2D 
00061   // default is variable range
00062   fXmin = 0;
00063   fXmax = -1;
00064   fYmin = 0;
00065   fYmax = -1;
00066   fPrecision = -1; // use default 
00067 }
00068 
00069 //_______________________________________________________
00070 LikelihoodIntervalPlot::LikelihoodIntervalPlot(LikelihoodInterval* theInterval)
00071 {
00072   // LikelihoodIntervalPlot copy constructor
00073   fInterval = theInterval;
00074   fParamsPlot = fInterval->GetParameters();
00075   fNdimPlot = fParamsPlot->getSize();
00076   fColor = kBlue;
00077   fLineColor = kGreen;
00078   fFillStyle = 4050; // half transparent
00079   fMaximum = 2.;
00080   fNPoints = 0;  // default depends if 1D or 2D 
00081   // default is variable range
00082   fXmin = 0;
00083   fXmax = -1;
00084   fYmin = 0;
00085   fYmax = -1;
00086   fPrecision = -1; // use default 
00087 }
00088 
00089 //_______________________________________________________
00090 LikelihoodIntervalPlot::~LikelihoodIntervalPlot()
00091 {
00092   // LikelihoodIntervalPlot destructor
00093 }
00094 
00095 //_____________________________________________________________________________
00096 void LikelihoodIntervalPlot::SetLikelihoodInterval(LikelihoodInterval* theInterval)
00097 {
00098   fInterval = theInterval;
00099   fParamsPlot = fInterval->GetParameters();
00100   fNdimPlot = fParamsPlot->getSize();
00101 
00102   return;
00103 }
00104 
00105 //_____________________________________________________________________________
00106 void LikelihoodIntervalPlot::SetPlotParameters(const RooArgSet *params) 
00107 {
00108   fNdimPlot = params->getSize();
00109   fParamsPlot = (RooArgSet*) params->clone((std::string(params->GetName())+"_clone").c_str());
00110 
00111   return;
00112 }
00113 
00114 
00115 //_____________________________________________________________________________
00116 void LikelihoodIntervalPlot::Draw(const Option_t *options) 
00117 {
00118    // draw the Likelihood interval or contour plot
00119    // For 1D problem draw the log profile likelihood function ratio and its interval 
00120    // The curve is draws in a RooPLot by default (i.e as a RooCurve) 
00121    // The plotting range (default is the full parameter range) and the precision of the RooCurve
00122    // can be specified by using SetRange(x1,x2) and SetPrecision(eps). 
00123    // SetNPoints(npoints) can also be used  (default is npoints=100) 
00124    // Optionally the function can be drawn as a TF1 (option="tf1") obtained by sampling the npoints
00125    // For 2D case, a contour is drawn. The number of contour points is controlled by 
00126    // SetNPoints(npoints) (default is npoints=40)
00127    // In case of problems finding the contour with Minuit, the option "nominuit" can be used. 
00128    // In this case the profile likelihood function is sampled in the npoints x npoints values and then 
00129    // an approximate contour is obtained. 
00130 
00131    if(fNdimPlot > 2){
00132       std::cout << "LikelihoodIntervalPlot::Draw(" << GetName() 
00133                 << ") ERROR: contours for more than 2 dimensions not implemented!" << std::endl;
00134       return;
00135    }
00136    
00137    TIter it = fParamsPlot->createIterator();
00138    RooRealVar *myparam = (RooRealVar*)it.Next();
00139       
00140    RooAbsReal* newProfile = fInterval->GetLikelihoodRatio(); 
00141 
00142    // analyze options 
00143    TString opt = options; 
00144    opt.ToLower(); 
00145    // use RooPLot for drawing the 1D PL
00146    // if option is TF1 use TF1 for drawing
00147    bool useRooPlot = opt.Contains("rooplot") ||  ! (opt.Contains("tf1"));
00148    opt.ReplaceAll("rooplot","");
00149    opt.ReplaceAll("tf1","");
00150    // use Minuit for drawing the contours of the PL 
00151    bool useMinuit = !opt.Contains("nominuit");
00152    opt.ReplaceAll("nominuit","");
00153 
00154    RooPlot * frame = 0; 
00155 
00156    TString title = GetTitle(); 
00157    int nPoints = fNPoints; 
00158    
00159    if(fNdimPlot == 1){
00160 
00161      //      if (title.Length() == 0) 
00162      //         title = "- log profile likelihood ratio";
00163 
00164       if (nPoints <=0) nPoints = 100; // default in 1D
00165 
00166       const Double_t xcont_min = fInterval->LowerLimit(*myparam);
00167       const Double_t xcont_max = fInterval->UpperLimit(*myparam);
00168 
00169       RooRealVar* myarg = (RooRealVar *) newProfile->getVariables()->find(myparam->GetName());
00170       double x1 = myarg->getMin(); 
00171       double x2 = myarg->getMax();
00172 
00173 
00174       // use TF1 for drawing the function
00175       if (!useRooPlot) { 
00176 
00177          // set a first estimate of range including 2 times upper and lower limit
00178          double xmin = std::max( x1, 2*xcont_min - xcont_max); 
00179          double xmax = std::min( x2, 2*xcont_max - xcont_min); 
00180          if (fXmin < fXmax) { xmin = fXmin; xmax = fXmax; }
00181          
00182          TF1 * tmp = newProfile->asTF(*myarg); 
00183          tmp->SetRange(xmin, xmax);      
00184          tmp->SetNpx(nPoints);
00185 
00186          // clone the function to avoid later to sample it
00187          TF1 * f1 = (TF1*) tmp->Clone(); 
00188          delete tmp;
00189          
00190          f1->SetTitle(title);
00191          TString name = TString(GetName()) + TString("_PLL_") + TString(myarg->GetName());
00192          f1->SetName(name);
00193          
00194          // set range for displaying x values where function <=  fMaximum
00195          // if no range is set amd 
00196          // if no reasanable value found mantain first estimate
00197          x1 = xmin; x2 = xmax;  
00198          if (fMaximum > 0 && fXmin >= fXmax ) { 
00199             double x0 = f1->GetX(0, xmin, xmax);
00200             // check that minimum is between xmin and xmax
00201             if ( x0 > x1 && x0 < x2) { 
00202                x1 = f1->GetX(fMaximum, xmin, x0); 
00203                x2 = f1->GetX(fMaximum, x0, xmax); 
00204                f1->SetMaximum(fMaximum);
00205             //std::cout << "setting range to " << x1 << " , " << x2 << " x0 = " << x0 << std::endl;
00206             }
00207          }
00208          
00209          f1->SetRange(x1,x2);
00210          
00211          
00212          f1->SetLineColor(kBlue);
00213          f1->GetXaxis()->SetTitle(myarg->GetName());
00214          f1->GetYaxis()->SetTitle(Form("- log #lambda(%s)",myparam->GetName()));
00215          f1->Draw(opt);
00216 
00217       } 
00218       else { 
00219          // use a RooPlot for drawing the PL function        
00220          double xmin = myparam->getMin(); double xmax =  myparam->getMax();
00221          if (fXmin < fXmax) { xmin = fXmin; xmax = fXmax; }  
00222 
00223          // set nbins (must be used in combination with precision )
00224          // the curve will evaluate 2 * nbins if preciaon is > 1
00225          int prevBins = myarg->getBins();
00226          myarg->setBins(fNPoints);
00227 
00228          // want to set range on frame not function
00229          frame = myarg->frame(xmin,xmax,nPoints);
00230          // for ycutoff line
00231          x1= xmin;
00232          x2=xmax;
00233          frame->SetTitle(title);
00234          frame->GetYaxis()->SetTitle(Form("- log #lambda(%s)",myparam->GetName()));
00235          //    frame->GetYaxis()->SetTitle("- log profile likelihood ratio");
00236          
00237 
00238          // plot 
00239          RooCmdArg cmd; 
00240          if (fPrecision > 0) cmd = RooFit::Precision(fPrecision); 
00241          newProfile->plotOn(frame,cmd); 
00242          
00243          frame->SetMaximum(fMaximum);
00244          frame->SetMinimum(0.);
00245 
00246          myarg->setBins(prevBins);
00247 
00248       }
00249 
00250       
00251       //myarg->setVal(xcont_max);
00252       //const Double_t Yat_Xmax = newProfile->getVal();
00253       Double_t Yat_Xmax = 0.5*TMath::ChisquareQuantile(fInterval->ConfidenceLevel(),1);
00254       
00255       TLine *Yline_cutoff = new TLine(x1,Yat_Xmax,x2,Yat_Xmax);
00256       TLine *Yline_min = new TLine(xcont_min,0.,xcont_min,Yat_Xmax);
00257       TLine *Yline_max = new TLine(xcont_max,0.,xcont_max,Yat_Xmax);
00258       
00259       Yline_cutoff->SetLineColor(fLineColor);
00260       Yline_min->SetLineColor(fLineColor);
00261       Yline_max->SetLineColor(fLineColor);
00262       
00263       if (!useRooPlot) { 
00264          // need to draw the line 
00265          Yline_cutoff->Draw();
00266          Yline_min->Draw();
00267          Yline_max->Draw();
00268       } 
00269       else { 
00270          // add line in the RooPlot
00271          frame->addObject(Yline_min);
00272          frame->addObject(Yline_max);
00273          frame->addObject(Yline_cutoff);
00274          frame->Draw(opt);
00275       }
00276       
00277 
00278       return;
00279    }
00280    else if(fNdimPlot == 2){
00281 
00282       RooRealVar *myparamY = (RooRealVar*)it.Next();
00283 
00284       Double_t cont_level = TMath::ChisquareQuantile(fInterval->ConfidenceLevel(),fNdimPlot); // level for -2log LR
00285       cont_level = cont_level/2; // since we are plotting -log LR
00286 
00287       RooArgList params(*newProfile->getVariables());
00288       // set values and error for the POI to the best fit values 
00289       for (int i = 0; i < params.getSize(); ++i) { 
00290          RooRealVar & par =  (RooRealVar &) params[i];
00291          RooRealVar * fitPar =  (RooRealVar *) (fInterval->GetBestFitParameters()->find(par.GetName() ) );
00292          if (fitPar) {
00293             par.setVal( fitPar->getVal() );
00294          }
00295       }
00296       // do a profile evaluation to start from the best fit values of parameters 
00297       newProfile->getVal(); 
00298 
00299       if (title.Length() == 0)
00300          title = TString("Contour of ") + TString(myparamY->GetName() ) + TString(" vs ") + TString(myparam->GetName() ); 
00301 
00302       if (nPoints <=0) nPoints = 40; // default in 2D
00303 
00304       if (!useMinuit) { 
00305       
00306          // draw directly the TH2 from the profile LL
00307          TH2F* hist2D = (TH2F*)newProfile->createHistogram("_hist2D",*myparam,RooFit::YVar(*myparamY),RooFit::Binning(nPoints),RooFit::Scaling(kFALSE));
00308 
00309 
00310          hist2D->SetTitle(title);
00311          hist2D->SetStats(kFALSE);
00312 
00313          hist2D->SetContour(1,&cont_level);
00314 
00315          hist2D->SetFillColor(fColor); 
00316          hist2D->SetFillStyle(fFillStyle); 
00317          hist2D->SetLineColor(fLineColor);
00318 
00319          TString tmpOpt(options);
00320 
00321          if(!tmpOpt.Contains("CONT")) tmpOpt.Append("CONT");
00322          if(!tmpOpt.Contains("LIST")) tmpOpt.Append("LIST"); // if you want the contour TGraphs
00323 
00324          hist2D->Draw(tmpOpt.Data());
00325          //    hist2D->Draw("cont2,list,same");
00326 
00327          gPad->Update();  // needed for get list of specials 
00328 
00329          // get TGraphs and add them
00330          //    gROOT->GetListOfSpecials()->Print();
00331          TObjArray *contours = (TObjArray*) gROOT->GetListOfSpecials()->FindObject("contours"); 
00332          if(contours){
00333             TList *list = (TList*)contours->At(0); 
00334             TGraph *gr1 = (TGraph*)list->First();
00335             gr1->SetLineColor(kBlack);
00336             gr1->SetLineStyle(kDashed);
00337             gr1->Draw("same");
00338          } else{
00339             std::cout << "no countours found in ListOfSpecials" << std::endl;
00340          }
00341       }
00342       else { 
00343 
00344          // find contours  using Minuit       
00345          TGraph * gr = new TGraph(nPoints+1); 
00346          
00347          int ncp = fInterval->GetContourPoints(*myparam, *myparamY, gr->GetX(), gr->GetY(),nPoints); 
00348 
00349          if (int(ncp) < nPoints) {
00350             std::cout << "Warning - Less points calculated in contours np = " << ncp << " / " << nPoints << std::endl;
00351             for (int i = ncp; i < nPoints; ++i) gr->RemovePoint(i);
00352          }
00353          // add last point to same as first one to close the contour
00354          gr->SetPoint(ncp, gr->GetX()[0], gr->GetY()[0] );
00355          opt.Append("LF");
00356          // draw first a dummy 2d histogram gfor the axis 
00357          if (!opt.Contains("same")) { 
00358 
00359             double xmin = myparam->getMin(); double xmax =  myparam->getMax();
00360             double ymin = myparamY->getMin(); double ymax =  myparamY->getMax();
00361             if (fXmin < fXmax) { xmin = fXmin; xmax = fXmax; }  
00362             if (fYmin < fYmax) { ymin = fYmin; ymax = fYmax; }  
00363 
00364             TH2F* hist2D = new TH2F("_hist2D",title, nPoints, xmin, xmax, nPoints, ymin, ymax );
00365             hist2D->GetXaxis()->SetTitle(myparam->GetName());
00366             hist2D->GetYaxis()->SetTitle(myparamY->GetName());
00367             hist2D->SetBit(TH1::kNoStats); // do not draw statistics
00368             hist2D->SetFillStyle(fFillStyle); 
00369             hist2D->SetMaximum(1);  // to avoid problem with subsequents draws
00370             hist2D->Draw("AXIS");
00371          }
00372          gr->SetFillColor(fColor); 
00373          //gr->SetFillStyle(fFillStyle); 
00374          gr->SetLineColor(kBlack); 
00375          if (opt.Contains("same"))  gr->SetFillStyle(fFillStyle); // put transparent
00376          gr->Draw(opt);
00377          TString name = TString("Graph_of_") + TString(fInterval->GetName());
00378          gr->SetName(name);
00379          
00380       }
00381 
00382    }
00383 
00384    return;
00385 }

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