27 using namespace RooFit;
31 ClassImp(RooStats::ToyMCImportanceSampler);
37 ToyMCImportanceSampler::~ToyMCImportanceSampler() {
38 for(
unsigned int i=0; i < fImportanceSnapshots.size(); i++ )
if(fImportanceSnapshots[i])
delete fImportanceSnapshots[i];
39 for(
unsigned int i=0; i < fNullSnapshots.size(); i++ )
if(fNullSnapshots[i])
delete fNullSnapshots[i];
44 void ToyMCImportanceSampler::ClearCache(
void) {
45 ToyMCSampler::ClearCache();
47 for(
unsigned int i=0; i < fImpNLLs.size(); i++ )
if(fImpNLLs[i]) {
delete fImpNLLs[i]; fImpNLLs[i] = NULL; }
48 for(
unsigned int i=0; i < fNullNLLs.size(); i++ )
if(fNullNLLs[i]) {
delete fNullNLLs[i]; fNullNLLs[i] = NULL; }
53 RooDataSet* ToyMCImportanceSampler::GetSamplingDistributionsSingleWorker(RooArgSet& paramPoint) {
54 if( fNToys == 0 )
return NULL;
57 Int_t allToys = fNToys;
60 RooCategory densityLabel(
"densityLabel",
"densityLabel" );
61 densityLabel.defineType(
"null", -1 );
62 for(
unsigned int i=0; i < fImportanceDensities.size(); i++ )
63 densityLabel.defineType( TString::Format(
"impDens_%d", i ), i );
66 RooDataSet* fullResult = NULL;
69 for(
int i = -1; i < (int)fImportanceDensities.size(); i++ ) {
72 oocoutP((TObject*)0,Generation) << endl << endl <<
" GENERATING FROM NULL DENSITY " << endl << endl;
73 SetDensityToGenerateFromByIndex( 0,
true );
75 oocoutP((TObject*)0,Generation) << endl << endl <<
" GENERATING IMP DENS/SNAP "<<i+1<<
" OUT OF "<<fImportanceDensities.size()<<endl<<endl;
76 SetDensityToGenerateFromByIndex( i,
false );
79 RooRealVar reweight(
"reweight",
"reweight", 1.0 );
81 if( fToysStrategy == EQUALTOYSPERDENSITY ) {
83 fNToys = TMath::CeilNint(
double(allToys)/(fImportanceDensities.size()+1) );
84 }
else if(fToysStrategy == EXPONENTIALTOYDISTRIBUTION ) {
87 fNToys = TMath::CeilNint(
double(allToys) * pow(
double(2) , i+1 ) / (pow(
double(2),
int(fImportanceDensities.size()+1) )-1) );
89 int largestNToys = TMath::CeilNint( allToys * pow(
double(2),
int(fImportanceDensities.size()) ) / (pow(
double(2),
int(fImportanceDensities.size()+1) )-1) );
90 reweight.setVal( ((
double)largestNToys) / fNToys );
93 ooccoutI((TObject*)NULL,InputArguments) <<
"Generating " << fNToys <<
" toys for this density." << endl;
94 ooccoutI((TObject*)NULL,InputArguments) <<
"Reweight is " << reweight.getVal() << endl;
97 RooDataSet* result = ToyMCSampler::GetSamplingDistributionsSingleWorker( paramPoint );
99 if (result->get()->getSize() > Int_t(fTestStatistics.size())) {
101 densityLabel.setIndex( i );
102 result->addColumn( densityLabel );
103 result->addColumn( reweight );
107 RooArgSet columns( *result->get() );
108 RooRealVar weightVar (
"weight",
"weight", 1.0 );
109 columns.add( weightVar );
113 fullResult =
new RooDataSet( result->GetName(), result->GetTitle(), columns,
"weight" );
116 for(
int j=0; j < result->numEntries(); j++ ) {
121 const RooArgSet* row = result->get(j);
122 fullResult->add( *row, result->weight()*reweight.getVal() );
135 RooAbsData* ToyMCImportanceSampler::GenerateToyData(
136 RooArgSet& paramPoint,
139 if( fNullDensities.size() > 1 ) {
140 ooccoutI((TObject*)NULL,InputArguments) <<
"Null Densities:" << endl;
141 for(
unsigned int i=0; i < fNullDensities.size(); i++) {
142 ooccoutI((TObject*)NULL,InputArguments) <<
" null density["<<i<<
"]: " << fNullDensities[i] <<
" \t null snapshot["<<i<<
"]: " << fNullSnapshots[i] << endl;
144 ooccoutE((TObject*)NULL,InputArguments) <<
"Cannot use multiple null densities and only ask for one weight." << endl;
148 if( fNullDensities.size() == 0 && fPdf ) {
149 ooccoutI((TObject*)NULL,InputArguments) <<
"No explicit null densities specified. Going to add one based on the given paramPoint and the global fPdf. ... but cannot do that inside const function." << endl;
155 if( fNullSnapshots[0] != ¶mPoint ) {
156 ooccoutD((TObject*)NULL,InputArguments) <<
"Using given parameter point. Replaces snapshot for the only null currently defined." << endl;
157 if(fNullSnapshots[0])
delete fNullSnapshots[0];
158 fNullSnapshots.clear();
159 fNullSnapshots.push_back( (RooArgSet*)paramPoint.snapshot() );
162 vector<double> weights;
163 weights.push_back( weight );
165 vector<double> impNLLs;
166 for(
unsigned int i=0; i < fImportanceDensities.size(); i++ ) impNLLs.push_back( 0.0 );
167 vector<double> nullNLLs;
168 for(
unsigned int i=0; i < fNullDensities.size(); i++ ) nullNLLs.push_back( 0.0 );
170 RooAbsData *d = GenerateToyData( weights, impNLLs, nullNLLs );
177 RooAbsData* ToyMCImportanceSampler::GenerateToyData(
178 RooArgSet& paramPoint,
180 vector<double>& impNLLs,
183 if( fNullDensities.size() > 1 ) {
184 ooccoutI((TObject*)NULL,InputArguments) <<
"Null Densities:" << endl;
185 for(
unsigned int i=0; i < fNullDensities.size(); i++) {
186 ooccoutI((TObject*)NULL,InputArguments) <<
" null density["<<i<<
"]: " << fNullDensities[i] <<
" \t null snapshot["<<i<<
"]: " << fNullSnapshots[i] << endl;
188 ooccoutE((TObject*)NULL,InputArguments) <<
"Cannot use multiple null densities and only ask for one weight and NLL." << endl;
192 if( fNullDensities.size() == 0 && fPdf ) {
193 ooccoutI((TObject*)NULL,InputArguments) <<
"No explicit null densities specified. Going to add one based on the given paramPoint and the global fPdf. ... but cannot do that inside const function." << endl;
197 ooccoutI((TObject*)NULL,InputArguments) <<
"Using given parameter point. Overwrites snapshot for the only null currently defined." << endl;
198 if(fNullSnapshots[0])
delete fNullSnapshots[0];
199 fNullSnapshots.clear();
200 fNullSnapshots.push_back( (
const RooArgSet*)paramPoint.snapshot() );
202 vector<double> weights;
203 weights.push_back( weight );
205 vector<double> nullNLLs;
206 nullNLLs.push_back( nullNLL );
208 RooAbsData *d = GenerateToyData( weights, impNLLs, nullNLLs );
210 nullNLL = nullNLLs[0];
216 RooAbsData* ToyMCImportanceSampler::GenerateToyData(
217 vector<double>& weights
219 if( fNullDensities.size() != weights.size() ) {
220 ooccoutI((TObject*)NULL,InputArguments) <<
"weights.size() != nullDesnities.size(). You need to provide a vector with the correct size." << endl;
224 vector<double> impNLLs;
225 for(
unsigned int i=0; i < fImportanceDensities.size(); i++ ) impNLLs.push_back( 0.0 );
226 vector<double> nullNLLs;
227 for(
unsigned int i=0; i < fNullDensities.size(); i++ ) nullNLLs.push_back( 0.0 );
229 RooAbsData *d = GenerateToyData( weights, impNLLs, nullNLLs );
240 RooAbsData* ToyMCImportanceSampler::GenerateToyData(
241 vector<double>& weights,
242 vector<double>& impNLLVals,
243 vector<double>& nullNLLVals
247 ooccoutD((TObject*)0,InputArguments) << endl;
248 ooccoutD((TObject*)0,InputArguments) <<
"GenerateToyDataImportanceSampling" << endl;
251 ooccoutE((TObject*)NULL,InputArguments) <<
"Observables not set." << endl;
255 if( fNullDensities.size() == 0 ) {
256 oocoutE((TObject*)NULL,InputArguments) <<
"ToyMCImportanceSampler: Need to specify the null density explicitly." << endl;
261 if( fNullNLLs.size() == 0 && fNullDensities.size() > 0 ) {
262 for(
unsigned int i = 0; i < fNullDensities.size(); i++ ) fNullNLLs.push_back( NULL );
264 if( fImpNLLs.size() == 0 && fImportanceDensities.size() > 0 ) {
265 for(
unsigned int i = 0; i < fImportanceDensities.size(); i++ ) fImpNLLs.push_back( NULL );
268 if( fNullDensities.size() != fNullNLLs.size() ) {
269 oocoutE((TObject*)NULL,InputArguments) <<
"ToyMCImportanceSampler: Something wrong. NullNLLs must be of same size as null densities." << endl;
273 if( (!fGenerateFromNull && fIndexGenDensity >= fImportanceDensities.size()) ||
274 (fGenerateFromNull && fIndexGenDensity >= fNullDensities.size())
276 oocoutE((TObject*)NULL,InputArguments) <<
"ToyMCImportanceSampler: no importance density given or index out of range." << endl;
284 RooArgSet paramPoint( *fNullSnapshots[0] );
290 RooArgSet* allVars = fPdf->getVariables();
291 *allVars = paramPoint;
295 if(!fNuisanceParametersSampler && fPriorNuisance && fNuisancePars)
296 fNuisanceParametersSampler =
new NuisanceParametersSampler(fPriorNuisance, fNuisancePars, fNToys, fExpectedNuisancePar);
299 RooArgSet observables(*fObservables);
300 if(fGlobalObservables && fGlobalObservables->getSize()) {
301 observables.remove(*fGlobalObservables);
303 GenerateGlobalObservables(*fNullDensities[0]);
308 if( !fGenerateFromNull ) {
309 RooArgSet* allVarsImpDens = fImportanceDensities[fIndexGenDensity]->getVariables();
310 allVars->add(*allVarsImpDens);
311 delete allVarsImpDens;
313 const RooArgSet* saveVars = (
const RooArgSet*)allVars->snapshot();
315 double globalWeight = 1.0;
316 if(fNuisanceParametersSampler) {
325 RooArgSet allVarsMinusParamPoint(*allVars);
326 allVarsMinusParamPoint.remove(paramPoint, kFALSE, kTRUE);
329 fNuisanceParametersSampler->NextPoint(allVarsMinusParamPoint, globalWeight);
332 for(
unsigned int i=0; i < weights.size(); i++ ) weights[i] = globalWeight;
334 RooAbsData* data = NULL;
335 if( fGenerateFromNull ) {
337 *allVars = *fNullSnapshots[fIndexGenDensity];
338 data = Generate(*fNullDensities[fIndexGenDensity], observables);
343 if(fImportanceSnapshots[fIndexGenDensity]) *allVars = *fImportanceSnapshots[fIndexGenDensity];
344 data = Generate(*fImportanceDensities[fIndexGenDensity], observables);
349 oocoutE((TObject*)0,InputArguments) <<
"ToyMCImportanceSampler: error generating data" << endl;
358 ooccoutD((TObject*)0,InputArguments) <<
"About to create/calculate all nullNLLs." << endl;
359 for(
unsigned int i=0; i < fNullDensities.size(); i++ ) {
363 *allVars = *fNullSnapshots[i];
364 if( !fNullNLLs[i] ) {
365 RooArgSet* allParams = fNullDensities[i]->getParameters(*data);
366 fNullNLLs[i] = fNullDensities[i]->createNLL(*data, RooFit::CloneData(kFALSE), RooFit::Constrain(*allParams),
367 RooFit::ConditionalObservables(fConditionalObs));
370 fNullNLLs[i]->setData( *data, kFALSE );
372 nullNLLVals[i] = fNullNLLs[i]->getVal();
374 if( !fReuseNLL ) {
delete fNullNLLs[i]; fNullNLLs[i] = NULL; }
379 ooccoutD((TObject*)0,InputArguments) <<
"About to find the minimum NLLs." << endl;
380 vector<double> minNLLVals;
381 for(
unsigned int i=0; i < nullNLLVals.size(); i++ ) minNLLVals.push_back( nullNLLVals[i] );
383 for(
unsigned int i=0; i < fImportanceDensities.size(); i++ ) {
387 if( fImportanceSnapshots[i] ) *allVars = *fImportanceSnapshots[i];
389 RooArgSet* allParams = fImportanceDensities[i]->getParameters(*data);
390 fImpNLLs[i] = fImportanceDensities[i]->createNLL(*data, RooFit::CloneData(kFALSE), RooFit::Constrain(*allParams),
391 RooFit::ConditionalObservables(fConditionalObs));
394 fImpNLLs[i]->setData( *data, kFALSE );
396 impNLLVals[i] = fImpNLLs[i]->getVal();
398 if( !fReuseNLL ) {
delete fImpNLLs[i]; fImpNLLs[i] = NULL; }
400 for(
unsigned int j=0; j < nullNLLVals.size(); j++ ) {
401 if( impNLLVals[i] < minNLLVals[j] ) minNLLVals[j] = impNLLVals[i];
402 ooccoutD((TObject*)0,InputArguments) <<
"minNLLVals["<<j<<
"]: " << minNLLVals[j] <<
" nullNLLVals["<<j<<
"]: " << nullNLLVals[j] <<
" impNLLVals["<<i<<
"]: " << impNLLVals[i] << endl;
408 ooccoutD((TObject*)0,InputArguments) <<
"About to apply vetos and calculate weights." << endl;
409 for(
unsigned int j=0; j < nullNLLVals.size(); j++ ) {
410 if ( fApplyVeto && fGenerateFromNull && minNLLVals[j] != nullNLLVals[j] ) weights[j] = 0.0;
411 else if( fApplyVeto && !fGenerateFromNull && minNLLVals[j] != impNLLVals[fIndexGenDensity] ) weights[j] = 0.0;
412 else if( !fGenerateFromNull ) {
416 weights[j] *= exp(minNLLVals[j] - nullNLLVals[j]);
419 ooccoutD((TObject*)0,InputArguments) <<
"weights["<<j<<
"]: " << weights[j] << endl;
424 *allVars = *saveVars;
434 int ToyMCImportanceSampler::CreateImpDensitiesForOnePOIAdaptively( RooAbsPdf& pdf,
const RooArgSet& allPOI, RooRealVar& poi,
double nStdDevOverlap,
double poiValueForBackground ) {
436 double impMaxMu = poi.getVal();
442 if( poi.getError() > 0.01 && poi.getError() < 5.0 ) {
443 n = TMath::CeilNint( poi.getVal() / (2.*nStdDevOverlap*poi.getError()) );
444 oocoutI((TObject*)0,InputArguments) <<
"Using fitFavoredMu and error to set the number of imp points" << endl;
445 oocoutI((TObject*)0,InputArguments) <<
"muhat: " << poi.getVal() <<
" optimize for distance: " << 2.*nStdDevOverlap*poi.getError() << endl;
446 oocoutI((TObject*)0,InputArguments) <<
"n = " << n << endl;
447 oocoutI((TObject*)0,InputArguments) <<
"This results in a distance of: " << impMaxMu / n << endl;
451 return CreateNImpDensitiesForOnePOI( pdf, allPOI, poi, n-1, poiValueForBackground);
457 int ToyMCImportanceSampler::CreateNImpDensitiesForOnePOI( RooAbsPdf& pdf,
const RooArgSet& allPOI, RooRealVar& poi,
int n,
double poiValueForBackground ) {
460 double impMaxMu = poi.getVal();
463 if( impMaxMu > poiValueForBackground && n > 0 ) {
464 for(
int i=1; i <= n; i++ ) {
465 poi.setVal( poiValueForBackground + (
double)i/(n)*(impMaxMu - poiValueForBackground) );
466 oocoutI((TObject*)0,InputArguments) << endl <<
"create point with poi: " << endl;
471 AddImportanceDensity( &pdf, &allPOI );