#include "RooAbsData.h"
#
#include "TMath.h"
#include "RooStats/HybridResult.h"
#include "RooStats/HypoTestInverter.h"
#include <cassert>
#include <cmath>
#include "TF1.h"
#include "TFile.h"
#include "TH1.h"
#include "TLine.h"
#include "TCanvas.h"
#include "TGraphErrors.h"
#include "RooRealVar.h"
#include "RooArgSet.h"
#include "RooAbsPdf.h"
#include "RooRandom.h"
#include "RooConstVar.h"
#include "RooMsgService.h"
#include "RooStats/ModelConfig.h"
#include "RooStats/HybridCalculator.h"
#include "RooStats/FrequentistCalculator.h"
#include "RooStats/AsymptoticCalculator.h"
#include "RooStats/SimpleLikelihoodRatioTestStat.h"
#include "RooStats/RatioOfProfiledLikelihoodsTestStat.h"
#include "RooStats/ProfileLikelihoodTestStat.h"
#include "RooStats/ToyMCSampler.h"
#include "RooStats/HypoTestPlot.h"
#include "RooStats/HypoTestInverterPlot.h"
#include "RooStats/ProofConfig.h"
ClassImp(RooStats::HypoTestInverter)
using namespace RooStats;
using namespace std;
double HypoTestInverter::fgCLAccuracy = 0.005;
unsigned int HypoTestInverter::fgNToys = 500;
double HypoTestInverter::fgAbsAccuracy = 0.05;
double HypoTestInverter::fgRelAccuracy = 0.05;
std::string HypoTestInverter::fgAlgo = "logSecant";
bool HypoTestInverter::fgCloseProof = false;
template<class HypoTestType>
struct HypoTestWrapper {
static void SetToys(HypoTestType * h, int toyNull, int toyAlt) { h->SetToys(toyNull,toyAlt); }
};
void HypoTestInverter::SetCloseProof(Bool_t flag) {
fgCloseProof = flag;
}
RooRealVar * HypoTestInverter::GetVariableToScan(const HypoTestCalculatorGeneric &hc) {
RooRealVar * varToScan = 0;
const ModelConfig * mc = hc.GetNullModel();
if (mc) {
const RooArgSet * poi = mc->GetParametersOfInterest();
if (poi) varToScan = dynamic_cast<RooRealVar*> (poi->first() );
}
if (!varToScan) {
mc = hc.GetAlternateModel();
if (mc) {
const RooArgSet * poi = mc->GetParametersOfInterest();
if (poi) varToScan = dynamic_cast<RooRealVar*> (poi->first() );
}
}
return varToScan;
}
void HypoTestInverter::CheckInputModels(const HypoTestCalculatorGeneric &hc,const RooRealVar & scanVariable) {
const ModelConfig * modelSB = hc.GetNullModel();
const ModelConfig * modelB = hc.GetAlternateModel();
if (!modelSB || ! modelB)
oocoutF((TObject*)0,InputArguments) << "HypoTestInverter - model are not existing" << std::endl;
assert(modelSB && modelB);
oocoutI((TObject*)0,InputArguments) << "HypoTestInverter ---- Input models: \n"
<< "\t\t using as S+B (null) model : "
<< modelSB->GetName() << "\n"
<< "\t\t using as B (alternate) model : "
<< modelB->GetName() << "\n" << std::endl;
RooAbsPdf * bPdf = modelB->GetPdf();
const RooArgSet * bObs = modelB->GetObservables();
if (!bPdf || !bObs) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - B model has no pdf or observables defined" << std::endl;
return;
}
RooArgSet * bParams = bPdf->getParameters(*bObs);
if (!bParams) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - pdf of B model has no parameters" << std::endl;
return;
}
if (bParams->find(scanVariable.GetName() ) ) {
const RooArgSet * poiB = modelB->GetSnapshot();
if (!poiB || !poiB->find(scanVariable.GetName()) ||
( (RooRealVar*) poiB->find(scanVariable.GetName()) )->getVal() != 0 )
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter - using a B model with POI "
<< scanVariable.GetName() << " not equal to zero "
<< " user must check input model configurations " << endl;
if (poiB) delete poiB;
}
delete bParams;
}
HypoTestInverter::HypoTestInverter( ) :
fTotalToysRun(0),
fMaxToys(0),
fCalculator0(0),
fScannedVariable(0),
fResults(0),
fUseCLs(false),
fScanLog(false),
fSize(0),
fVerbose(0),
fCalcType(kUndefined),
fNBins(0), fXmin(1), fXmax(1),
fNumErr(0)
{
}
HypoTestInverter::HypoTestInverter( HypoTestCalculatorGeneric& hc,
RooRealVar* scannedVariable, double size ) :
fTotalToysRun(0),
fMaxToys(0),
fCalculator0(0),
fScannedVariable(scannedVariable),
fResults(0),
fUseCLs(false),
fScanLog(false),
fSize(size),
fVerbose(0),
fCalcType(kUndefined),
fNBins(0), fXmin(1), fXmax(1),
fNumErr(0)
{
if (!fScannedVariable) {
fScannedVariable = HypoTestInverter::GetVariableToScan(hc);
}
if (!fScannedVariable)
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - Cannot guess the variable to scan " << std::endl;
else
CheckInputModels(hc,*fScannedVariable);
HybridCalculator * hybCalc = dynamic_cast<HybridCalculator*>(&hc);
if (hybCalc) {
fCalcType = kHybrid;
fCalculator0 = hybCalc;
return;
}
FrequentistCalculator * freqCalc = dynamic_cast<FrequentistCalculator*>(&hc);
if (freqCalc) {
fCalcType = kFrequentist;
fCalculator0 = freqCalc;
return;
}
AsymptoticCalculator * asymCalc = dynamic_cast<AsymptoticCalculator*>(&hc);
if (asymCalc) {
fCalcType = kAsymptotic;
fCalculator0 = asymCalc;
return;
}
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - Type of hypotest calculator is not supported " <<std::endl;
fCalculator0 = &hc;
}
HypoTestInverter::HypoTestInverter( HybridCalculator& hc,
RooRealVar* scannedVariable, double size ) :
fTotalToysRun(0),
fMaxToys(0),
fCalculator0(&hc),
fScannedVariable(scannedVariable),
fResults(0),
fUseCLs(false),
fScanLog(false),
fSize(size),
fVerbose(0),
fCalcType(kHybrid),
fNBins(0), fXmin(1), fXmax(1),
fNumErr(0)
{
if (!fScannedVariable) {
fScannedVariable = GetVariableToScan(hc);
}
if (!fScannedVariable)
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - Cannot guess the variable to scan " << std::endl;
else
CheckInputModels(hc,*fScannedVariable);
}
HypoTestInverter::HypoTestInverter( FrequentistCalculator& hc,
RooRealVar* scannedVariable, double size ) :
fTotalToysRun(0),
fMaxToys(0),
fCalculator0(&hc),
fScannedVariable(scannedVariable),
fResults(0),
fUseCLs(false),
fScanLog(false),
fSize(size),
fVerbose(0),
fCalcType(kFrequentist),
fNBins(0), fXmin(1), fXmax(1),
fNumErr(0)
{
if (!fScannedVariable) {
fScannedVariable = GetVariableToScan(hc);
}
if (!fScannedVariable)
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - Cannot guess the variable to scan " << std::endl;
else
CheckInputModels(hc,*fScannedVariable);
}
HypoTestInverter::HypoTestInverter( AsymptoticCalculator& hc,
RooRealVar* scannedVariable, double size ) :
fTotalToysRun(0),
fMaxToys(0),
fCalculator0(&hc),
fScannedVariable(scannedVariable),
fResults(0),
fUseCLs(false),
fScanLog(false),
fSize(size),
fVerbose(0),
fCalcType(kAsymptotic),
fNBins(0), fXmin(1), fXmax(1),
fNumErr(0)
{
if (!fScannedVariable) {
fScannedVariable = GetVariableToScan(hc);
}
if (!fScannedVariable)
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - Cannot guess the variable to scan " << std::endl;
else
CheckInputModels(hc,*fScannedVariable);
}
HypoTestInverter::HypoTestInverter( RooAbsData& data, ModelConfig &sbModel, ModelConfig &bModel,
RooRealVar * scannedVariable, ECalculatorType type, double size) :
fTotalToysRun(0),
fMaxToys(0),
fCalculator0(0),
fScannedVariable(scannedVariable),
fResults(0),
fUseCLs(false),
fScanLog(false),
fSize(size),
fVerbose(0),
fCalcType(type),
fNBins(0), fXmin(1), fXmax(1),
fNumErr(0)
{
if(fCalcType==kFrequentist) fHC.reset(new FrequentistCalculator(data, bModel, sbModel));
if(fCalcType==kHybrid) fHC.reset( new HybridCalculator(data, bModel, sbModel)) ;
if(fCalcType==kAsymptotic) fHC.reset( new AsymptoticCalculator(data, bModel, sbModel));
fCalculator0 = fHC.get();
if (!fScannedVariable) {
fScannedVariable = GetVariableToScan(*fCalculator0);
}
if (!fScannedVariable)
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - Cannot guess the variable to scan " << std::endl;
else
CheckInputModels(*fCalculator0,*fScannedVariable);
}
HypoTestInverter::HypoTestInverter(const HypoTestInverter & rhs) :
IntervalCalculator(),
fTotalToysRun(0),
fCalculator0(0), fScannedVariable(0),
fResults(0)
{
(*this) = rhs;
}
HypoTestInverter & HypoTestInverter::operator= (const HypoTestInverter & rhs) {
if (this == &rhs) return *this;
fTotalToysRun = 0;
fMaxToys = rhs.fMaxToys;
fCalculator0 = rhs.fCalculator0;
fScannedVariable = rhs.fScannedVariable;
fUseCLs = rhs.fUseCLs;
fScanLog = rhs.fScanLog;
fSize = rhs.fSize;
fVerbose = rhs.fVerbose;
fCalcType = rhs.fCalcType;
fNBins = rhs.fNBins;
fXmin = rhs.fXmin;
fXmax = rhs.fXmax;
fNumErr = rhs.fNumErr;
return *this;
}
HypoTestInverter::~HypoTestInverter()
{
if (fResults) delete fResults;
fCalculator0 = 0;
}
TestStatistic * HypoTestInverter::GetTestStatistic( ) const
{
if(fCalculator0 && fCalculator0->GetTestStatSampler()){
return fCalculator0->GetTestStatSampler()->GetTestStatistic();
}
else
return 0;
}
bool HypoTestInverter::SetTestStatistic(TestStatistic& stat)
{
if(fCalculator0 && fCalculator0->GetTestStatSampler()){
fCalculator0->GetTestStatSampler()->SetTestStatistic(&stat);
return true;
}
else return false;
}
void HypoTestInverter::Clear() {
if (fResults) delete fResults;
fResults = 0;
fLimitPlot.reset(nullptr);
}
void HypoTestInverter::CreateResults() const {
if (fResults == 0) {
TString results_name = "result_";
results_name += fScannedVariable->GetName();
fResults = new HypoTestInverterResult(results_name,*fScannedVariable,ConfidenceLevel());
TString title = "HypoTestInverter Result For ";
title += fScannedVariable->GetName();
fResults->SetTitle(title);
}
fResults->UseCLs(fUseCLs);
fResults->SetConfidenceLevel(1.-fSize);
if (fCalculator0) {
AsymptoticCalculator * ac = dynamic_cast<AsymptoticCalculator*>(fCalculator0);
if (ac)
fResults->fIsTwoSided = ac->IsTwoSided();
else {
TestStatSampler * sampler = fCalculator0->GetTestStatSampler();
if (sampler) {
ProfileLikelihoodTestStat * pl = dynamic_cast<ProfileLikelihoodTestStat*>(sampler->GetTestStatistic());
if (pl && pl->IsTwoSided() ) fResults->fIsTwoSided = true;
}
}
}
}
HypoTestInverterResult* HypoTestInverter::GetInterval() const {
if (fResults && fResults->ArraySize() >= 1) {
oocoutI((TObject*)0,Eval) << "HypoTestInverter::GetInterval - return an already existing interval " << std::endl;
return (HypoTestInverterResult*)(fResults->Clone());
}
if (fNBins > 0) {
oocoutI((TObject*)0,Eval) << "HypoTestInverter::GetInterval - run a fixed scan" << std::endl;
bool ret = RunFixedScan(fNBins, fXmin, fXmax, fScanLog);
if (!ret)
oocoutE((TObject*)0,Eval) << "HypoTestInverter::GetInterval - error running a fixed scan " << std::endl;
}
else {
oocoutI((TObject*)0,Eval) << "HypoTestInverter::GetInterval - run an automatic scan" << std::endl;
double limit(0),err(0);
bool ret = RunLimit(limit,err);
if (!ret)
oocoutE((TObject*)0,Eval) << "HypoTestInverter::GetInterval - error running an auto scan " << std::endl;
}
if (fgCloseProof) ProofConfig::CloseProof();
return (HypoTestInverterResult*) (fResults->Clone());
}
HypoTestResult * HypoTestInverter::Eval(HypoTestCalculatorGeneric &hc, bool adaptive, double clsTarget) const {
HypoTestResult * hcResult = hc.GetHypoTest();
if (hcResult == 0) {
oocoutE((TObject*)0,Eval) << "HypoTestInverter::Eval - HypoTest failed" << std::endl;
return hcResult;
}
hcResult->SetBackgroundAsAlt(true);
if (hcResult->GetPValueIsRightTail() )
hcResult->SetTestStatisticData(hcResult->GetTestStatisticData()-fNumErr);
else
hcResult->SetTestStatisticData(hcResult->GetTestStatisticData()+fNumErr);
double clsMid = (fUseCLs ? hcResult->CLs() : hcResult->CLsplusb());
double clsMidErr = (fUseCLs ? hcResult->CLsError() : hcResult->CLsplusbError());
if (adaptive) {
if (fCalcType == kHybrid) HypoTestWrapper<HybridCalculator>::SetToys((HybridCalculator*)&hc, fUseCLs ? fgNToys : 1, 4*fgNToys);
if (fCalcType == kFrequentist) HypoTestWrapper<FrequentistCalculator>::SetToys((FrequentistCalculator*)&hc, fUseCLs ? fgNToys : 1, 4*fgNToys);
while (clsMidErr >= fgCLAccuracy && (clsTarget == -1 || fabs(clsMid-clsTarget) < 3*clsMidErr) ) {
std::unique_ptr<HypoTestResult> more(hc.GetHypoTest());
hcResult->Append(more.get());
clsMid = (fUseCLs ? hcResult->CLs() : hcResult->CLsplusb());
clsMidErr = (fUseCLs ? hcResult->CLsError() : hcResult->CLsplusbError());
if (fVerbose) std::cout << (fUseCLs ? "\tCLs = " : "\tCLsplusb = ") << clsMid << " +/- " << clsMidErr << std::endl;
}
}
if (fVerbose ) {
oocoutP((TObject*)0,Eval) << "P values for " << fScannedVariable->GetName() << " = " <<
fScannedVariable->getVal() << "\n" <<
"\tCLs = " << hcResult->CLs() << " +/- " << hcResult->CLsError() << "\n" <<
"\tCLb = " << hcResult->CLb() << " +/- " << hcResult->CLbError() << "\n" <<
"\tCLsplusb = " << hcResult->CLsplusb() << " +/- " << hcResult->CLsplusbError() << "\n" <<
std::endl;
}
if (fCalcType == kFrequentist || fCalcType == kHybrid) {
fTotalToysRun += (hcResult->GetAltDistribution()->GetSize() + hcResult->GetNullDistribution()->GetSize());
TString nullDistName = TString::Format("%s_%s_%4.2f",hcResult->GetNullDistribution()->GetName(),
fScannedVariable->GetName(), fScannedVariable->getVal() );
TString altDistName = TString::Format("%s_%s_%4.2f",hcResult->GetAltDistribution()->GetName(),
fScannedVariable->GetName(), fScannedVariable->getVal() );
hcResult->GetNullDistribution()->SetName(nullDistName);
hcResult->GetAltDistribution()->SetName(altDistName);
}
return hcResult;
}
bool HypoTestInverter::RunFixedScan( int nBins, double xMin, double xMax, bool scanLog ) const
{
CreateResults();
fResults->fFittedLowerLimit = false;
fResults->fFittedUpperLimit = false;
if ( nBins<=0 ) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter::RunFixedScan - Please provide nBins>0\n";
return false;
}
if ( nBins==1 && xMin!=xMax ) {
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter::RunFixedScan - nBins==1 -> I will run for xMin (" << xMin << ")\n";
}
if ( xMin==xMax && nBins>1 ) {
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter::RunFixedScan - xMin==xMax -> I will enforce nBins==1\n";
nBins = 1;
}
if ( xMin>xMax ) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter::RunFixedScan - Please provide xMin ("
<< xMin << ") smaller that xMax (" << xMax << ")\n";
return false;
}
if (xMin < fScannedVariable->getMin()) {
xMin = fScannedVariable->getMin();
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter::RunFixedScan - xMin < lower bound, use xmin = "
<< xMin << std::endl;
}
if (xMax > fScannedVariable->getMax()) {
xMax = fScannedVariable->getMax();
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter::RunFixedScan - xMax > upper bound, use xmax = "
<< xMax << std::endl;
}
double thisX = xMin;
for (int i=0; i<nBins; i++) {
if (i > 0) {
if (scanLog)
thisX = exp( log(xMin) + i*(log(xMax)-log(xMin))/(nBins-1) );
else
thisX = xMin + i*(xMax-xMin)/(nBins-1);
}
bool status = RunOnePoint(thisX);
if ( status==false ) {
std::cout << "\t\tLoop interrupted because of failed status\n";
return false;
}
}
return true;
}
bool HypoTestInverter::RunOnePoint( double rVal, bool adaptive, double clTarget) const
{
CreateResults();
if ( rVal < fScannedVariable->getMin() ) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter::RunOnePoint - Out of range: using the lower bound "
<< fScannedVariable->getMin()
<< " on the scanned variable rather than " << rVal<< "\n";
rVal = fScannedVariable->getMin();
}
if ( rVal > fScannedVariable->getMax() ) {
if ( rVal > fScannedVariable->getMax()*(1.+1.E-12) )
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter::RunOnePoint - Out of range: using the upper bound "
<< fScannedVariable->getMax()
<< " on the scanned variable rather than " << rVal<< "\n";
rVal = fScannedVariable->getMax();
}
double oldValue = fScannedVariable->getVal();
fScannedVariable->setVal(rVal);
const ModelConfig * sbModel = fCalculator0->GetNullModel();
RooArgSet poi; poi.add(*sbModel->GetParametersOfInterest());
poi = RooArgSet(*fScannedVariable);
const_cast<ModelConfig*>(sbModel)->SetSnapshot(poi);
if (fVerbose > 0)
oocoutP((TObject*)0,Eval) << "Running for " << fScannedVariable->GetName() << " = " << fScannedVariable->getVal() << endl;
HypoTestResult* result = Eval(*fCalculator0,adaptive,clTarget);
if (!result) {
oocoutE((TObject*)0,Eval) << "HypoTestInverter - Error running point " << fScannedVariable->GetName() << " = " <<
fScannedVariable->getVal() << endl;
return false;
}
if (TMath::IsNaN(result->NullPValue() ) && TMath::IsNaN(result->AlternatePValue() ) ) {
oocoutW((TObject*)0,Eval) << "HypoTestInverter - Skip invalid result for point " << fScannedVariable->GetName() << " = " <<
fScannedVariable->getVal() << endl;
return true;
}
double lastXtested;
if ( fResults->ArraySize()!=0 ) lastXtested = fResults->GetXValue(fResults->ArraySize()-1);
else lastXtested = -999;
if ( (std::abs(rVal) < 1 && TMath::AreEqualAbs(rVal, lastXtested,1.E-12) ) ||
(std::abs(rVal) >= 1 && TMath::AreEqualRel(rVal, lastXtested,1.E-12) ) ) {
oocoutI((TObject*)0,Eval) << "HypoTestInverter::RunOnePoint - Merge with previous result for "
<< fScannedVariable->GetName() << " = " << rVal << std::endl;
HypoTestResult* prevResult = fResults->GetResult(fResults->ArraySize()-1);
if (prevResult && prevResult->GetNullDistribution() && prevResult->GetAltDistribution()) {
prevResult->Append(result);
delete result;
}
else {
oocoutI((TObject*)0,Eval) << "HypoTestInverter::RunOnePoint - replace previous empty result\n";
fResults->fYObjects.Remove( prevResult);
fResults->fYObjects.Add(result);
}
} else {
fResults->fXValues.push_back(rVal);
fResults->fYObjects.Add(result);
}
fScannedVariable->setVal(oldValue);
return true;
}
bool HypoTestInverter::RunLimit(double &limit, double &limitErr, double absAccuracy, double relAccuracy, const double*hint) const {
RooRealVar *r = fScannedVariable;
if ((hint != 0) && (*hint > r->getMin())) {
r->setMax(std::min<double>(3.0 * (*hint), r->getMax()));
r->setMin(std::max<double>(0.3 * (*hint), r->getMin()));
oocoutI((TObject*)0,InputArguments) << "HypoTestInverter::RunLimit - Use hint value " << *hint
<< " search in interval " << r->getMin() << " , " << r->getMax() << std::endl;
}
if (absAccuracy <= 0) absAccuracy = fgAbsAccuracy;
if (relAccuracy <= 0) relAccuracy = fgRelAccuracy;
typedef std::pair<double,double> CLs_t;
double clsTarget = fSize;
CLs_t clsMin(1,0), clsMax(0,0), clsMid(0,0);
double rMin = r->getMin(), rMax = r->getMax();
limit = 0.5*(rMax + rMin);
limitErr = 0.5*(rMax - rMin);
bool done = false;
TF1 expoFit("expoFit","[0]*exp([1]*(x-[2]))", rMin, rMax);
fLimitPlot.reset(new TGraphErrors());
if (fVerbose > 0) std::cout << "Search for upper limit to the limit" << std::endl;
for (int tries = 0; tries < 6; ++tries) {
if (! RunOnePoint(rMax) ) {
oocoutE((TObject*)0,Eval) << "HypoTestInverter::RunLimit - Hypotest failed" << std::endl;
return false;
}
clsMax = std::make_pair( fResults->GetLastYValue(), fResults->GetLastYError() );
if (clsMax.first == 0 || clsMax.first + 3 * fabs(clsMax.second) < clsTarget ) break;
rMax += rMax;
if (tries == 5) {
oocoutE((TObject*)0,Eval) << "HypoTestInverter::RunLimit - Cannot set higher limit: at " << r->GetName()
<< " = " << rMax << " still get "
<< (fUseCLs ? "CLs" : "CLsplusb") << " = " << clsMax.first << std::endl;
return false;
}
}
if (fVerbose > 0) {
oocoutI((TObject*)0,Eval) << "HypoTestInverter::RunLimit - Search for lower limit to the limit" << std::endl;
}
if ( fUseCLs && rMin == 0 ) {
clsMin = CLs_t(1,0);
}
else {
if (! RunOnePoint(rMin) ) return false;
clsMin = std::make_pair( fResults->GetLastYValue(), fResults->GetLastYError() );
}
if (clsMin.first != 1 && clsMin.first - 3 * fabs(clsMin.second) < clsTarget) {
if (fUseCLs) {
rMin = 0;
clsMin = CLs_t(1,0);
} else {
rMin = -rMax / 4;
for (int tries = 0; tries < 6; ++tries) {
if (! RunOnePoint(rMax) ) return false;
clsMin = std::make_pair( fResults->GetLastYValue(), fResults->GetLastYError() );
if (clsMin.first == 1 || clsMin.first - 3 * fabs(clsMin.second) > clsTarget) break;
rMin += rMin;
if (tries == 5) {
oocoutE((TObject*)0,Eval) << "HypoTestInverter::RunLimit - Cannot set lower limit: at " << r->GetName()
<< " = " << rMin << " still get " << (fUseCLs ? "CLs" : "CLsplusb")
<< " = " << clsMin.first << std::endl;
return false;
}
}
}
}
if (fVerbose > 0)
oocoutI((TObject*)0,Eval) << "HypoTestInverter::RunLimit - Now doing proper bracketing & bisection" << std::endl;
do {
if (fMaxToys > 0 && fTotalToysRun > fMaxToys ) {
oocoutW((TObject*)0,Eval) << "HypoTestInverter::RunLimit - maximum number of toys reached " << std::endl;
done = false; break;
}
limit = 0.5*(rMin+rMax); limitErr = 0.5*(rMax-rMin);
if (fgAlgo == "logSecant" && clsMax.first != 0) {
double logMin = log(clsMin.first), logMax = log(clsMax.first), logTarget = log(clsTarget);
limit = rMin + (rMax-rMin) * (logTarget - logMin)/(logMax - logMin);
if (clsMax.second != 0 && clsMin.second != 0) {
limitErr = hypot((logTarget-logMax) * (clsMin.second/clsMin.first), (logTarget-logMin) * (clsMax.second/clsMax.first));
limitErr *= (rMax-rMin)/((logMax-logMin)*(logMax-logMin));
}
}
r->setError(limitErr);
if (limitErr < std::max(absAccuracy, relAccuracy * limit)) {
if (fVerbose > 1)
oocoutI((TObject*)0,Eval) << "HypoTestInverter::RunLimit - reached accuracy " << limitErr
<< " below " << std::max(absAccuracy, relAccuracy * limit) << std::endl;
done = true; break;
}
if (! RunOnePoint(limit, true, clsTarget) ) return false;
clsMid = std::make_pair( fResults->GetLastYValue(), fResults->GetLastYError() );
if (clsMid.second == -1) {
std::cerr << "Hypotest failed" << std::endl;
return false;
}
if (fabs(clsMid.first-clsTarget) >= 2*clsMid.second) {
if ((clsMid.first>clsTarget) == (clsMax.first>clsTarget)) {
rMax = limit; clsMax = clsMid;
} else {
rMin = limit; clsMin = clsMid;
}
} else {
if (fVerbose > 0) std::cout << "Trying to move the interval edges closer" << std::endl;
double rMinBound = rMin, rMaxBound = rMax;
while (clsMin.second == 0 || fabs(rMin-limit) > std::max(absAccuracy, relAccuracy * limit)) {
rMin = 0.5*(rMin+limit);
if (!RunOnePoint(rMin,true, clsTarget) ) return false;
clsMin = std::make_pair( fResults->GetLastYValue(), fResults->GetLastYError() );
if (fabs(clsMin.first-clsTarget) <= 2*clsMin.second) break;
rMinBound = rMin;
}
while (clsMax.second == 0 || fabs(rMax-limit) > std::max(absAccuracy, relAccuracy * limit)) {
rMax = 0.5*(rMax+limit);
if (!RunOnePoint(rMax,true,clsTarget) ) return false;
clsMax = std::make_pair( fResults->GetLastYValue(), fResults->GetLastYError() );
if (fabs(clsMax.first-clsTarget) <= 2*clsMax.second) break;
rMaxBound = rMax;
}
expoFit.SetRange(rMinBound,rMaxBound);
break;
}
} while (true);
if (!done) {
if (fVerbose) {
oocoutI((TObject*)0,Eval) << "HypoTestInverter::RunLimit - Before fit --- \n";
std::cout << "Limit: " << r->GetName() << " < " << limit << " +/- " << limitErr << " [" << rMin << ", " << rMax << "]\n";
}
expoFit.FixParameter(0,clsTarget);
expoFit.SetParameter(1,log(clsMax.first/clsMin.first)/(rMax-rMin));
expoFit.SetParameter(2,limit);
double rMinBound, rMaxBound; expoFit.GetRange(rMinBound, rMaxBound);
limitErr = std::max(fabs(rMinBound-limit), fabs(rMaxBound-limit));
int npoints = 0;
HypoTestInverterPlot plot("plot","plot",fResults);
fLimitPlot.reset(plot.MakePlot() );
for (int j = 0; j < fLimitPlot->GetN(); ++j) {
if (fLimitPlot->GetX()[j] >= rMinBound && fLimitPlot->GetX()[j] <= rMaxBound) npoints++;
}
for (int i = 0, imax = 8; i <= imax; ++i, ++npoints) {
fLimitPlot->Sort();
fLimitPlot->Fit(&expoFit,(fVerbose <= 1 ? "QNR EX0" : "NR EXO"));
if (fVerbose) {
oocoutI((TObject*)0,Eval) << "Fit to " << npoints << " points: " << expoFit.GetParameter(2) << " +/- " << expoFit.GetParError(2) << std::endl;
}
if ((rMin < expoFit.GetParameter(2)) && (expoFit.GetParameter(2) < rMax) && (expoFit.GetParError(2) < 0.5*(rMaxBound-rMinBound))) {
limit = expoFit.GetParameter(2);
limitErr = expoFit.GetParError(2);
if (limitErr < std::max(absAccuracy, relAccuracy * limit)) break;
}
double rTry = RooRandom::uniform()*(rMaxBound-rMinBound)+rMinBound;
if (i != imax) {
if (!RunOnePoint(rTry,true,clsTarget) ) return false;
}
}
}
if (fLimitPlot.get() && fLimitPlot->GetN() > 0) {
fLimitPlot->Sort();
fLimitPlot->SetLineWidth(2);
double xmin = r->getMin(), xmax = r->getMax();
for (int j = 0; j < fLimitPlot->GetN(); ++j) {
if (fLimitPlot->GetY()[j] > 1.4*clsTarget || fLimitPlot->GetY()[j] < 0.6*clsTarget) continue;
xmin = std::min(fLimitPlot->GetX()[j], xmin);
xmax = std::max(fLimitPlot->GetX()[j], xmax);
}
fLimitPlot->GetXaxis()->SetRangeUser(xmin,xmax);
fLimitPlot->GetYaxis()->SetRangeUser(0.5*clsTarget, 1.5*clsTarget);
fLimitPlot->Draw("AP");
expoFit.Draw("SAME");
TLine line(fLimitPlot->GetX()[0], clsTarget, fLimitPlot->GetX()[fLimitPlot->GetN()-1], clsTarget);
line.SetLineColor(kRed); line.SetLineWidth(2); line.Draw();
line.DrawLine(limit, 0, limit, fLimitPlot->GetY()[0]);
line.SetLineWidth(1); line.SetLineStyle(2);
line.DrawLine(limit-limitErr, 0, limit-limitErr, fLimitPlot->GetY()[0]);
line.DrawLine(limit+limitErr, 0, limit+limitErr, fLimitPlot->GetY()[0]);
}
oocoutI((TObject*)0,Eval) << "HypoTestInverter::RunLimit - Result: \n"
<< "\tLimit: " << r->GetName() << " < " << limit << " +/- " << limitErr << " @ " << (1-fSize) * 100 << "% CL\n";
if (fVerbose > 1) oocoutI((TObject*)0,Eval) << "Total toys: " << fTotalToysRun << std::endl;
fResults->fUpperLimit = limit;
fResults->fUpperLimitError = limitErr;
fResults->fFittedUpperLimit = true;
fResults->fLowerLimit = fScannedVariable->getMin();
fResults->fLowerLimitError = 0;
fResults->fFittedLowerLimit = true;
return true;
}
SamplingDistribution * HypoTestInverter::GetLowerLimitDistribution(bool rebuild, int nToys) {
if (!rebuild) {
if (!fResults) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter::GetLowerLimitDistribution(false) - result not existing\n";
return 0;
}
return fResults->GetLowerLimitDistribution();
}
TList * clsDist = 0;
TList * clsbDist = 0;
if (fUseCLs) clsDist = &fResults->fExpPValues;
else clsbDist = &fResults->fExpPValues;
return RebuildDistributions(false, nToys,clsDist, clsbDist);
}
SamplingDistribution * HypoTestInverter::GetUpperLimitDistribution(bool rebuild, int nToys) {
if (!rebuild) {
if (!fResults) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter::GetUpperLimitDistribution(false) - result not existing\n";
return 0;
}
return fResults->GetUpperLimitDistribution();
}
TList * clsDist = 0;
TList * clsbDist = 0;
if (fUseCLs) clsDist = &fResults->fExpPValues;
else clsbDist = &fResults->fExpPValues;
return RebuildDistributions(true, nToys,clsDist, clsbDist);
}
void HypoTestInverter::SetData(RooAbsData & data) {
if (fCalculator0) fCalculator0->SetData(data);
}
SamplingDistribution * HypoTestInverter::RebuildDistributions(bool isUpper, int nToys, TList * clsDist, TList * clsbDist, TList * clbDist, const char *outputfile) {
if (!fScannedVariable || !fCalculator0) return 0;
const ModelConfig * bModel = fCalculator0->GetAlternateModel();
const ModelConfig * sbModel = fCalculator0->GetNullModel();
if (!bModel || ! sbModel) return 0;
RooArgSet paramPoint;
if (!sbModel->GetParametersOfInterest()) return 0;
paramPoint.add(*sbModel->GetParametersOfInterest());
const RooArgSet * poibkg = bModel->GetSnapshot();
if (!poibkg) {
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter::RebuildDistribution - bakground snapshot not existing"
<< " assume is for POI = 0" << std::endl;
fScannedVariable->setVal(0);
paramPoint = RooArgSet(*fScannedVariable);
}
else
paramPoint = *poibkg;
ToyMCSampler * toymcSampler = dynamic_cast<ToyMCSampler *>(fCalculator0->GetTestStatSampler() );
if (!toymcSampler) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter::RebuildDistribution - no toy MC sampler existing" << std::endl;
return 0;
}
if (dynamic_cast<RooStats::AsymptoticCalculator*>(fCalculator0) ) {
toymcSampler->SetObservables(*sbModel->GetObservables() );
toymcSampler->SetParametersForTestStat(*sbModel->GetParametersOfInterest());
toymcSampler->SetPdf(*sbModel->GetPdf());
toymcSampler->SetNuisanceParameters(*sbModel->GetNuisanceParameters());
if (sbModel->GetGlobalObservables() ) toymcSampler->SetGlobalObservables(*sbModel->GetGlobalObservables() );
if (!sbModel->GetPdf()->canBeExtended())
toymcSampler->SetNEventsPerToy(1);
}
int nPoints = fNBins;
bool storePValues = clsDist || clsbDist || clbDist;
if (fNBins <=0 && storePValues) {
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter::RebuildDistribution - cannot return p values distribution with the auto scan" << std::endl;
storePValues = false;
nPoints = 0;
}
if (storePValues) {
if (fResults) nPoints = fResults->ArraySize();
if (nPoints <=0) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - result is not existing and number of point to scan is not set"
<< std::endl;
return 0;
}
}
if (nToys <= 0) nToys = 100;
std::vector<std::vector<double> > CLs_values(nPoints);
std::vector<std::vector<double> > CLsb_values(nPoints);
std::vector<std::vector<double> > CLb_values(nPoints);
if (storePValues) {
for (int i = 0; i < nPoints; ++i) {
CLs_values[i].reserve(nToys);
CLb_values[i].reserve(nToys);
CLsb_values[i].reserve(nToys);
}
}
std::vector<double> limit_values; limit_values.reserve(nToys);
oocoutI((TObject*)0,InputArguments) << "HypoTestInverter - rebuilding the p value distributions by generating ntoys = "
<< nToys << std::endl;
oocoutI((TObject*)0,InputArguments) << "Rebuilding using parameter of interest point: ";
RooStats::PrintListContent(paramPoint, oocoutI((TObject*)0,InputArguments) );
if (sbModel->GetNuisanceParameters() ) {
oocoutI((TObject*)0,InputArguments) << "And using nuisance parameters: ";
RooStats::PrintListContent(*sbModel->GetNuisanceParameters(), oocoutI((TObject*)0,InputArguments) );
}
assert(bModel->GetPdf() );
assert(bModel->GetObservables() );
RooArgSet * allParams = bModel->GetPdf()->getParameters( *bModel->GetObservables() );
RooArgSet saveParams;
allParams->snapshot(saveParams);
TFile * fileOut = TFile::Open(outputfile,"RECREATE");
if (!fileOut) {
oocoutE((TObject*)0,InputArguments) << "HypoTestInverter - RebuildDistributions - Error opening file " << outputfile
<< " - the resulting limits will not be stored" << std::endl;
}
TH1D * hL = new TH1D("lowerLimitDist","Rebuilt lower limit distribution",100,1.,0.);
TH1D * hU = new TH1D("upperLimitDist","Rebuilt upper limit distribution",100,1.,0.);
TH1D * hN = new TH1D("nObs","Observed events",100,1.,0.);
hL->SetBuffer(2*nToys);
hU->SetBuffer(2*nToys);
std::vector<TH1*> hCLb;
std::vector<TH1*> hCLsb;
std::vector<TH1*> hCLs;
if (storePValues) {
for (int i = 0; i < nPoints; ++i) {
hCLb.push_back(new TH1D(TString::Format("CLbDist_bin%d",i),"CLb distribution",100,1.,0.));
hCLs.push_back(new TH1D(TString::Format("ClsDist_bin%d",i),"CLs distribution",100,1.,0.));
hCLsb.push_back(new TH1D(TString::Format("CLsbDist_bin%d",i),"CLs+b distribution",100,1.,0.));
}
}
for (int itoy = 0; itoy < nToys; ++itoy) {
oocoutP((TObject*)0,Eval) << "\nHypoTestInverter - RebuildDistributions - running toy # " << itoy << " / "
<< nToys << std::endl;
printf("\n\nshnapshot of s+b model \n");
sbModel->GetSnapshot()->Print("v");
if (itoy> 0) *allParams = saveParams;
toymcSampler->SetPdf(*bModel->GetPdf() );
RooAbsData * bkgdata = toymcSampler->GenerateToyData(paramPoint);
double nObs = bkgdata->sumEntries();
if (bkgdata->numEntries() ==1 && !bModel->GetPdf()->canBeExtended()) {
oocoutP((TObject*)0,Generation) << "Generate observables are : ";
RooArgList genObs(*bkgdata->get(0));
RooStats::PrintListContent(genObs, oocoutP((TObject*)0,Generation) );
nObs = 0;
for (int i = 0; i < genObs.getSize(); ++i) {
RooRealVar * x = dynamic_cast<RooRealVar*>(&genObs[i]);
if (x) nObs += x->getVal();
}
}
hN->Fill(nObs);
HypoTestInverter inverter = *this;
inverter.SetData(*bkgdata);
auto gobs = bModel->GetPdf()->getVariables()->selectCommon(* sbModel->GetGlobalObservables() );
gobs->Print("v");
HypoTestInverterResult * r = inverter.GetInterval();
if (r == 0) continue;
double value = (isUpper) ? r->UpperLimit() : r->LowerLimit();
limit_values.push_back( value );
hU->Fill(r->UpperLimit() );
hL->Fill(r->LowerLimit() );
std::cout << "The computed upper limit for toy #" << itoy << " is " << value << std::endl;
if (itoy%10 == 0 || itoy == nToys-1) {
hU->Write("",TObject::kOverwrite);
hL->Write("",TObject::kOverwrite);
hN->Write("",TObject::kOverwrite);
}
if (!storePValues) continue;
if (nPoints < r->ArraySize()) {
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter: skip extra points" << std::endl;
}
else if (nPoints > r->ArraySize()) {
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter: missing some points" << std::endl;
}
for (int ipoint = 0; ipoint < nPoints; ++ipoint) {
HypoTestResult * hr = r->GetResult(ipoint);
if (hr) {
CLs_values[ipoint].push_back( hr->CLs() );
CLsb_values[ipoint].push_back( hr->CLsplusb() );
CLb_values[ipoint].push_back( hr->CLb() );
hCLs[ipoint]->Fill( hr->CLs() );
hCLb[ipoint]->Fill( hr->CLb() );
hCLsb[ipoint]->Fill( hr->CLsplusb() );
}
else {
oocoutW((TObject*)0,InputArguments) << "HypoTestInverter: missing result for point: x = "
<< fResults->GetXValue(ipoint) << std::endl;
}
}
if (itoy%10 == 0 || itoy == nToys-1) {
for (int ipoint = 0; ipoint < nPoints; ++ipoint) {
hCLs[ipoint]->Write("",TObject::kOverwrite);
hCLb[ipoint]->Write("",TObject::kOverwrite);
hCLsb[ipoint]->Write("",TObject::kOverwrite);
}
}
delete r;
delete bkgdata;
}
if (storePValues) {
if (clsDist) clsDist->SetOwner(true);
if (clbDist) clbDist->SetOwner(true);
if (clsbDist) clsbDist->SetOwner(true);
oocoutI((TObject*)0,InputArguments) << "HypoTestInverter: storing rebuilt p values " << std::endl;
for (int ipoint = 0; ipoint < nPoints; ++ipoint) {
if (clsDist) {
TString name = TString::Format("CLs_distrib_%d",ipoint);
clsDist->Add( new SamplingDistribution(name,name,CLs_values[ipoint] ) );
}
if (clbDist) {
TString name = TString::Format("CLb_distrib_%d",ipoint);
clbDist->Add( new SamplingDistribution(name,name,CLb_values[ipoint] ) );
}
if (clsbDist) {
TString name = TString::Format("CLsb_distrib_%d",ipoint);
clsbDist->Add( new SamplingDistribution(name,name,CLsb_values[ipoint] ) );
}
}
}
if (fileOut) {
fileOut->Close();
}
else {
delete hL;
delete hU;
for (int i = 0; i < nPoints && storePValues; ++i) {
delete hCLs[i];
delete hCLb[i];
delete hCLsb[i];
}
}
const char * disName = (isUpper) ? "upperLimit_dist" : "lowerLimit_dist";
return new SamplingDistribution(disName, disName, limit_values);
}
HypoTestInverter.cxx:1000 HypoTestInverter.cxx:1001 HypoTestInverter.cxx:1002 HypoTestInverter.cxx:1003 HypoTestInverter.cxx:1004 HypoTestInverter.cxx:1005 HypoTestInverter.cxx:1006 HypoTestInverter.cxx:1007 HypoTestInverter.cxx:1008 HypoTestInverter.cxx:1009 HypoTestInverter.cxx:1010 HypoTestInverter.cxx:1011 HypoTestInverter.cxx:1012 HypoTestInverter.cxx:1013 HypoTestInverter.cxx:1014 HypoTestInverter.cxx:1015 HypoTestInverter.cxx:1016 HypoTestInverter.cxx:1017 HypoTestInverter.cxx:1018 HypoTestInverter.cxx:1019 HypoTestInverter.cxx:1020 HypoTestInverter.cxx:1021 HypoTestInverter.cxx:1022 HypoTestInverter.cxx:1023 HypoTestInverter.cxx:1024 HypoTestInverter.cxx:1025 HypoTestInverter.cxx:1026 HypoTestInverter.cxx:1027 HypoTestInverter.cxx:1028 HypoTestInverter.cxx:1029 HypoTestInverter.cxx:1030 HypoTestInverter.cxx:1031 HypoTestInverter.cxx:1032 HypoTestInverter.cxx:1033 HypoTestInverter.cxx:1034 HypoTestInverter.cxx:1035 HypoTestInverter.cxx:1036 HypoTestInverter.cxx:1037 HypoTestInverter.cxx:1038 HypoTestInverter.cxx:1039 HypoTestInverter.cxx:1040 HypoTestInverter.cxx:1041 HypoTestInverter.cxx:1042 HypoTestInverter.cxx:1043 HypoTestInverter.cxx:1044 HypoTestInverter.cxx:1045 HypoTestInverter.cxx:1046 HypoTestInverter.cxx:1047 HypoTestInverter.cxx:1048 HypoTestInverter.cxx:1049 HypoTestInverter.cxx:1050 HypoTestInverter.cxx:1051 HypoTestInverter.cxx:1052 HypoTestInverter.cxx:1053 HypoTestInverter.cxx:1054 HypoTestInverter.cxx:1055 HypoTestInverter.cxx:1056 HypoTestInverter.cxx:1057 HypoTestInverter.cxx:1058 HypoTestInverter.cxx:1059 HypoTestInverter.cxx:1060 HypoTestInverter.cxx:1061 HypoTestInverter.cxx:1062 HypoTestInverter.cxx:1063 HypoTestInverter.cxx:1064 HypoTestInverter.cxx:1065 HypoTestInverter.cxx:1066 HypoTestInverter.cxx:1067 HypoTestInverter.cxx:1068 HypoTestInverter.cxx:1069 HypoTestInverter.cxx:1070 HypoTestInverter.cxx:1071 HypoTestInverter.cxx:1072 HypoTestInverter.cxx:1073 HypoTestInverter.cxx:1074 HypoTestInverter.cxx:1075 HypoTestInverter.cxx:1076 HypoTestInverter.cxx:1077 HypoTestInverter.cxx:1078 HypoTestInverter.cxx:1079 HypoTestInverter.cxx:1080 HypoTestInverter.cxx:1081 HypoTestInverter.cxx:1082 HypoTestInverter.cxx:1083 HypoTestInverter.cxx:1084 HypoTestInverter.cxx:1085 HypoTestInverter.cxx:1086 HypoTestInverter.cxx:1087 HypoTestInverter.cxx:1088 HypoTestInverter.cxx:1089 HypoTestInverter.cxx:1090 HypoTestInverter.cxx:1091 HypoTestInverter.cxx:1092 HypoTestInverter.cxx:1093 HypoTestInverter.cxx:1094 HypoTestInverter.cxx:1095 HypoTestInverter.cxx:1096 HypoTestInverter.cxx:1097 HypoTestInverter.cxx:1098 HypoTestInverter.cxx:1099 HypoTestInverter.cxx:1100 HypoTestInverter.cxx:1101 HypoTestInverter.cxx:1102 HypoTestInverter.cxx:1103 HypoTestInverter.cxx:1104 HypoTestInverter.cxx:1105 HypoTestInverter.cxx:1106 HypoTestInverter.cxx:1107 HypoTestInverter.cxx:1108 HypoTestInverter.cxx:1109 HypoTestInverter.cxx:1110 HypoTestInverter.cxx:1111 HypoTestInverter.cxx:1112 HypoTestInverter.cxx:1113 HypoTestInverter.cxx:1114 HypoTestInverter.cxx:1115 HypoTestInverter.cxx:1116 HypoTestInverter.cxx:1117 HypoTestInverter.cxx:1118 HypoTestInverter.cxx:1119 HypoTestInverter.cxx:1120 HypoTestInverter.cxx:1121 HypoTestInverter.cxx:1122 HypoTestInverter.cxx:1123 HypoTestInverter.cxx:1124 HypoTestInverter.cxx:1125 HypoTestInverter.cxx:1126 HypoTestInverter.cxx:1127 HypoTestInverter.cxx:1128 HypoTestInverter.cxx:1129 HypoTestInverter.cxx:1130 HypoTestInverter.cxx:1131 HypoTestInverter.cxx:1132 HypoTestInverter.cxx:1133 HypoTestInverter.cxx:1134 HypoTestInverter.cxx:1135 HypoTestInverter.cxx:1136 HypoTestInverter.cxx:1137 HypoTestInverter.cxx:1138 HypoTestInverter.cxx:1139 HypoTestInverter.cxx:1140 HypoTestInverter.cxx:1141 HypoTestInverter.cxx:1142 HypoTestInverter.cxx:1143 HypoTestInverter.cxx:1144 HypoTestInverter.cxx:1145 HypoTestInverter.cxx:1146 HypoTestInverter.cxx:1147 HypoTestInverter.cxx:1148 HypoTestInverter.cxx:1149 HypoTestInverter.cxx:1150 HypoTestInverter.cxx:1151 HypoTestInverter.cxx:1152 HypoTestInverter.cxx:1153 HypoTestInverter.cxx:1154 HypoTestInverter.cxx:1155 HypoTestInverter.cxx:1156 HypoTestInverter.cxx:1157 HypoTestInverter.cxx:1158 HypoTestInverter.cxx:1159 HypoTestInverter.cxx:1160 HypoTestInverter.cxx:1161 HypoTestInverter.cxx:1162 HypoTestInverter.cxx:1163 HypoTestInverter.cxx:1164 HypoTestInverter.cxx:1165 HypoTestInverter.cxx:1166 HypoTestInverter.cxx:1167 HypoTestInverter.cxx:1168 HypoTestInverter.cxx:1169 HypoTestInverter.cxx:1170 HypoTestInverter.cxx:1171 HypoTestInverter.cxx:1172 HypoTestInverter.cxx:1173 HypoTestInverter.cxx:1174 HypoTestInverter.cxx:1175 HypoTestInverter.cxx:1176 HypoTestInverter.cxx:1177 HypoTestInverter.cxx:1178 HypoTestInverter.cxx:1179 HypoTestInverter.cxx:1180 HypoTestInverter.cxx:1181 HypoTestInverter.cxx:1182 HypoTestInverter.cxx:1183 HypoTestInverter.cxx:1184 HypoTestInverter.cxx:1185 HypoTestInverter.cxx:1186 HypoTestInverter.cxx:1187 HypoTestInverter.cxx:1188 HypoTestInverter.cxx:1189 HypoTestInverter.cxx:1190 HypoTestInverter.cxx:1191 HypoTestInverter.cxx:1192 HypoTestInverter.cxx:1193 HypoTestInverter.cxx:1194 HypoTestInverter.cxx:1195 HypoTestInverter.cxx:1196 HypoTestInverter.cxx:1197 HypoTestInverter.cxx:1198 HypoTestInverter.cxx:1199 HypoTestInverter.cxx:1200 HypoTestInverter.cxx:1201 HypoTestInverter.cxx:1202 HypoTestInverter.cxx:1203 HypoTestInverter.cxx:1204 HypoTestInverter.cxx:1205 HypoTestInverter.cxx:1206 HypoTestInverter.cxx:1207 HypoTestInverter.cxx:1208 HypoTestInverter.cxx:1209 HypoTestInverter.cxx:1210 HypoTestInverter.cxx:1211 HypoTestInverter.cxx:1212 HypoTestInverter.cxx:1213 HypoTestInverter.cxx:1214 HypoTestInverter.cxx:1215 HypoTestInverter.cxx:1216 HypoTestInverter.cxx:1217 HypoTestInverter.cxx:1218 HypoTestInverter.cxx:1219 HypoTestInverter.cxx:1220 HypoTestInverter.cxx:1221 HypoTestInverter.cxx:1222 HypoTestInverter.cxx:1223 HypoTestInverter.cxx:1224 HypoTestInverter.cxx:1225 HypoTestInverter.cxx:1226 HypoTestInverter.cxx:1227 HypoTestInverter.cxx:1228 HypoTestInverter.cxx:1229 HypoTestInverter.cxx:1230 HypoTestInverter.cxx:1231 HypoTestInverter.cxx:1232 HypoTestInverter.cxx:1233 HypoTestInverter.cxx:1234 HypoTestInverter.cxx:1235 HypoTestInverter.cxx:1236 HypoTestInverter.cxx:1237 HypoTestInverter.cxx:1238 HypoTestInverter.cxx:1239 HypoTestInverter.cxx:1240 HypoTestInverter.cxx:1241 HypoTestInverter.cxx:1242 HypoTestInverter.cxx:1243 HypoTestInverter.cxx:1244 HypoTestInverter.cxx:1245 HypoTestInverter.cxx:1246 HypoTestInverter.cxx:1247 HypoTestInverter.cxx:1248 HypoTestInverter.cxx:1249 HypoTestInverter.cxx:1250 HypoTestInverter.cxx:1251 HypoTestInverter.cxx:1252 HypoTestInverter.cxx:1253 HypoTestInverter.cxx:1254 HypoTestInverter.cxx:1255 HypoTestInverter.cxx:1256 HypoTestInverter.cxx:1257 HypoTestInverter.cxx:1258 HypoTestInverter.cxx:1259 HypoTestInverter.cxx:1260 HypoTestInverter.cxx:1261 HypoTestInverter.cxx:1262 HypoTestInverter.cxx:1263 HypoTestInverter.cxx:1264 HypoTestInverter.cxx:1265 HypoTestInverter.cxx:1266 HypoTestInverter.cxx:1267 HypoTestInverter.cxx:1268 HypoTestInverter.cxx:1269 HypoTestInverter.cxx:1270 HypoTestInverter.cxx:1271 HypoTestInverter.cxx:1272 HypoTestInverter.cxx:1273 HypoTestInverter.cxx:1274 HypoTestInverter.cxx:1275 HypoTestInverter.cxx:1276 HypoTestInverter.cxx:1277 HypoTestInverter.cxx:1278 HypoTestInverter.cxx:1279 HypoTestInverter.cxx:1280 HypoTestInverter.cxx:1281 HypoTestInverter.cxx:1282 HypoTestInverter.cxx:1283 HypoTestInverter.cxx:1284 HypoTestInverter.cxx:1285 HypoTestInverter.cxx:1286 HypoTestInverter.cxx:1287 HypoTestInverter.cxx:1288 HypoTestInverter.cxx:1289 HypoTestInverter.cxx:1290 HypoTestInverter.cxx:1291 HypoTestInverter.cxx:1292 HypoTestInverter.cxx:1293 HypoTestInverter.cxx:1294 HypoTestInverter.cxx:1295 HypoTestInverter.cxx:1296 HypoTestInverter.cxx:1297 HypoTestInverter.cxx:1298 HypoTestInverter.cxx:1299 HypoTestInverter.cxx:1300 HypoTestInverter.cxx:1301 HypoTestInverter.cxx:1302 HypoTestInverter.cxx:1303 HypoTestInverter.cxx:1304 HypoTestInverter.cxx:1305 HypoTestInverter.cxx:1306 HypoTestInverter.cxx:1307 HypoTestInverter.cxx:1308