00001 #include <stdexcept>
00002 #include <RooStats/ModelConfig.h>
00003 #include <RooStats/HypoTestInverter.h>
00004 #include <RooStats/HypoTestInverterResult.h>
00005 #include "RooStats/AsymptoticCalculator.h"
00006 #include "../interface/AsymptoticNew.h"
00007 #include "../interface/Combine.h"
00008 #include "../interface/CloseCoutSentry.h"
00009 #include "../interface/RooFitGlobalKillSentry.h"
00010 #include "../interface/ProfiledLikelihoodRatioTestStatExt.h"
00011 #include "../interface/utils.h"
00012
00013 using namespace RooStats;
00014
00015 std::string AsymptoticNew::what_ = "both";
00016 bool AsymptoticNew::qtilde_ = true;
00017 int AsymptoticNew::nscanpoints_ = 20;
00018 double AsymptoticNew::minrscan_ = 0.;
00019 double AsymptoticNew::maxrscan_ = 20.;
00020
00021 AsymptoticNew::AsymptoticNew() :
00022 LimitAlgo("AsymptoticNew specific options"){
00023 options_.add_options()
00024 ("run", boost::program_options::value<std::string>(&what_)->default_value(what_), "What to run: both (default), observed, expected.")
00025 ("nPoints", boost::program_options::value<int>(&nscanpoints_)->default_value(nscanpoints_), "Number of points in scan for CLs")
00026 ("qtilde", boost::program_options::value<bool>(&qtilde_)->default_value(qtilde_), "Allow only non-negative signal strengths (default is true).")
00027 ("scanMin", boost::program_options::value<double>(&minrscan_)->default_value(minrscan_), "Minimum value for scan in r.")
00028 ("scanMax", boost::program_options::value<double>(&maxrscan_)->default_value(maxrscan_), "Maximum value for scan in r.")
00029 ;
00030 }
00031
00032 void AsymptoticNew::applyOptions(const boost::program_options::variables_map &vm) {
00033 if (what_ != "observed" && what_ != "expected" && what_ != "both")
00034 throw std::invalid_argument("Asymptotic: option 'run' can only be 'observed', 'expected' or 'both' (the default)");
00035
00036 }
00037
00038 void AsymptoticNew::applyDefaultOptions() {
00039 what_ = "observed";
00040 nscanpoints_ = 20;
00041 qtilde_ = true;
00042 minrscan_=0.;
00043 maxrscan_=20.;
00044 }
00045
00046 bool AsymptoticNew::run(RooWorkspace *w, RooStats::ModelConfig *mc_s, RooStats::ModelConfig *mc_b, RooAbsData &data, double &limit, double &limitErr, const double *hint) {
00047 RooFitGlobalKillSentry silence(verbose <= 1 ? RooFit::WARNING : RooFit::DEBUG);
00048 if (verbose > 0) std::cout << "Will compute " << what_ << " limit(s) " << std::endl;
00049
00050 std::vector<std::pair<float,float> > expected;
00051 expected = runLimit(w, mc_s, mc_b, data, limit, limitErr, hint);
00052
00053 if (verbose >= 0) {
00054 const char *rname = mc_s->GetParametersOfInterest()->first()->GetName();
00055 std::cout << "\n -- AsymptoticNew -- " << "\n";
00056 if (what_ != "expected") {
00057 printf("Observed Limit: %s < %6.4f\n", rname, limit);
00058 }
00059 for (std::vector<std::pair<float,float> >::const_iterator it = expected.begin(), ed = expected.end(); it != ed; ++it) {
00060 printf("Expected %4.1f%%: %s < %6.4f\n", it->first*100, rname, it->second);
00061 }
00062 std::cout << std::endl;
00063 }
00064
00065 return true;
00066 }
00067
00068 std::vector<std::pair<float,float> > AsymptoticNew::runLimit(RooWorkspace *w, RooStats::ModelConfig *mc_s, RooStats::ModelConfig *mc_b, RooAbsData &data, double &limit, double &limitErr, const double *hint) {
00069
00070 RooRealVar *poi = (RooRealVar*)mc_s->GetParametersOfInterest()->first();
00071 mc_s->SetSnapshot(*poi);
00072 double oldval = poi->getVal();
00073 poi->setVal(0); mc_b->SetSnapshot(*poi);
00074 poi->setVal(oldval);
00075
00076
00077 AsymptoticCalculator * ac = new RooStats::AsymptoticCalculator(data, *mc_b, *mc_s);
00078 AsymptoticCalculator::SetPrintLevel(verbose>2);
00079 ac->SetOneSided(true);
00080 ac->SetQTilde(qtilde_);
00081 HypoTestInverter calc(*ac);
00082 calc.SetVerbose(verbose>2);
00083 calc.UseCLs(true);
00084
00085 calc.SetFixedScan(nscanpoints_,minrscan_,maxrscan_);
00086 RooStats::HypoTestInverterResult * r = calc.GetInterval();
00087
00088
00089
00090 std::vector<std::pair<float,float> > expected;
00091 const double quantiles[5] = { 0.025, 0.16, 0.50, 0.84, 0.975 };
00092 const double zvals[5] = { -2, -1, 0, 1, 2 };
00093
00094 for (int iq = 0; iq < 5; ++iq) {
00095 limit = r->GetExpectedUpperLimit(zvals[iq]);
00096 limitErr = 0;
00097 Combine::commitPoint(true, quantiles[iq]);
00098 expected.push_back(std::pair<float,float>(quantiles[iq], limit));
00099 }
00100
00101
00102
00103 if (what_!="expected") {
00104 limit = r->UpperLimit();
00105 } else {
00106 limit = 0 ;
00107 }
00108
00109 return expected;
00110
00111 }