Loading [MathJax]/jax/output/HTML-CSS/config.js
Logo ROOT   6.16/01
Reference Guide
•All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
HistoToWorkspaceFactoryFast.cxx
Go to the documentation of this file.
1// @(#)root/roostats:$Id: cranmer $
2// Author: Kyle Cranmer, Akira Shibata
3/*************************************************************************
4 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11////////////////////////////////////////////////////////////////////////////////
12
13/** \class RooStats::HistFactory::HistoToWorkspaceFactoryFast
14 * \ingroup HistFactory
15 */
16
17
18#ifndef __CINT__
19#include "RooGlobalFunc.h"
20#endif
21
22#include "RooDataSet.h"
23#include "RooRealVar.h"
24#include "RooConstVar.h"
25#include "RooAddition.h"
26#include "RooProduct.h"
27#include "RooProdPdf.h"
28#include "RooAddPdf.h"
29#include "RooGaussian.h"
30#include "RooPoisson.h"
31#include "RooExponential.h"
32#include "RooRandom.h"
33#include "RooCategory.h"
34#include "RooSimultaneous.h"
35#include "RooMultiVarGaussian.h"
36#include "RooNumIntConfig.h"
37#include "RooMinuit.h"
38#include "RooNLLVar.h"
39#include "RooProfileLL.h"
40#include "RooFitResult.h"
41#include "RooDataHist.h"
42#include "RooHistFunc.h"
43#include "RooHistPdf.h"
44#include "RooRealSumPdf.h"
45#include "RooProduct.h"
46#include "RooWorkspace.h"
47#include "RooCustomizer.h"
48#include "RooPlot.h"
49#include "RooMsgService.h"
55
56#include "TH2F.h"
57#include "TH3F.h"
58#include "TFile.h"
59#include "TCanvas.h"
60#include "TH1.h"
61#include "TLine.h"
62#include "TTree.h"
63#include "TMarker.h"
64#include "TStopwatch.h"
65#include "TROOT.h"
66#include "TStyle.h"
67#include "TVectorD.h"
68#include "TMatrixDSym.h"
69
70// specific to this package
75#include "Helper.h"
76
77#include <algorithm>
78
79#define VERBOSE
80
81#define alpha_Low "-5"
82#define alpha_High "5"
83#define NoHistConst_Low "0"
84#define NoHistConst_High "2000"
85
86// use this order for safety on library loading
87using namespace RooFit ;
88using namespace RooStats ;
89using namespace std ;
90
92
93namespace RooStats{
94namespace HistFactory{
95
97 fNomLumi(1.0), fLumiError(0),
98 fLowBin(0), fHighBin(0)
99 {}
100
102 }
103
105 fSystToFix( measurement.GetConstantParams() ),
106 fParamValues( measurement.GetParamValues() ),
107 fNomLumi( measurement.GetLumi() ),
108 fLumiError( measurement.GetLumi()*measurement.GetLumiRelErr() ),
109 fLowBin( measurement.GetBinLow() ),
110 fHighBin( measurement.GetBinHigh() ) {
111
112 // Set Preprocess functions
114
115 }
116
117 void HistoToWorkspaceFactoryFast::ConfigureWorkspaceForMeasurement( const std::string& ModelName, RooWorkspace* ws_single, Measurement& measurement ) {
118
119 // Configure a workspace by doing any
120 // necessary post-processing and by
121 // creating a ModelConfig
122
123 // Make a ModelConfig and configure it
124 ModelConfig * proto_config = (ModelConfig *) ws_single->obj("ModelConfig");
125 if( proto_config == NULL ) {
126 std::cout << "Error: Did not find 'ModelConfig' object in file: " << ws_single->GetName()
127 << std::endl;
128 throw hf_exc();
129 }
130
131 std::vector<std::string> poi_list = measurement.GetPOIList();
132 if( poi_list.size()==0 ) {
133 std::cout << "Warining: No Parametetrs of interest are set" << std::endl;
134 }
135
136 cout << "Setting Parameter(s) of Interest as: ";
137 for(unsigned int i = 0; i < poi_list.size(); ++i) {
138 cout << poi_list.at(i) << " ";
139 }
140 cout << endl;
141
142 RooArgSet params;
143 for( unsigned int i = 0; i < poi_list.size(); ++i ) {
144 std::string poi_name = poi_list.at(i);
145 RooRealVar* poi = (RooRealVar*) ws_single->var( poi_name.c_str() );
146 if(poi){
147 params.add(*poi);
148 }
149 else {
150 std::cout << "WARNING: Can't find parameter of interest: " << poi_name
151 << " in Workspace. Not setting in ModelConfig." << std::endl;
152 //throw hf_exc();
153 }
154 }
155 proto_config->SetParametersOfInterest(params);
156
157 // Name of an 'edited' model, if necessary
158 std::string NewModelName = "newSimPdf"; // <- This name is hard-coded in HistoToWorkspaceFactoryFast::EditSyt. Probably should be changed to : std::string("new") + ModelName;
159
160#ifdef DO_EDIT_WS
161 // Activate Additional Constraint Terms
162 if( measurement.GetGammaSyst().size() > 0
163 || measurement.GetUniformSyst().size() > 0
164 || measurement.GetLogNormSyst().size() > 0
165 || measurement.GetNoSyst().size() > 0) {
166 HistoToWorkspaceFactoryFast::EditSyst( ws_single, (ModelName).c_str(),
167 measurement.GetGammaSyst(),
168 measurement.GetUniformSyst(),
169 measurement.GetLogNormSyst(),
170 measurement.GetNoSyst());
171
172 proto_config->SetPdf( *ws_single->pdf( "newSimPdf" ) );
173 }
174#endif
175
176 // Set the ModelConfig's Params of Interest
177 RooAbsData* expData = ws_single->data("asimovData");
178 if( !expData ) {
179 std::cout << "Error: Failed to find dataset: " << expData
180 << " in workspace" << std::endl;
181 throw hf_exc();
182 }
183 if(poi_list.size()!=0){
184 proto_config->GuessObsAndNuisance(*expData);
185 }
186
187 // Now, let's loop over any additional asimov datasets
188 // that we need to make
189
190 // Get the pdf
191 // Notice that we get the "new" pdf, this is the one that is
192 // used in the creation of these asimov datasets since they
193 // are fitted (or may be, at least).
194 RooAbsPdf* pdf = ws_single->pdf(NewModelName.c_str());
195 if( !pdf ) pdf = ws_single->pdf( ModelName.c_str() );
196 const RooArgSet* observables = ws_single->set("observables");
197
198 // Create a SnapShot of the nominal values
199 std::string SnapShotName = "NominalParamValues";
200 ws_single->saveSnapshot(SnapShotName.c_str(), ws_single->allVars());
201
202 for( unsigned int i=0; i<measurement.GetAsimovDatasets().size(); ++i) {
203
204 // Set the variable values and "const" ness with the workspace
205 RooStats::HistFactory::Asimov& asimov = measurement.GetAsimovDatasets().at(i);
206 std::string AsimovName = asimov.GetName();
207
208 std::cout << "Generating additional Asimov Dataset: " << AsimovName << std::endl;
209 asimov.ConfigureWorkspace(ws_single);
210 RooDataSet* asimov_dataset =
212
213 std::cout << "Importing Asimov dataset" << std::endl;
214 bool failure = ws_single->import(*asimov_dataset, Rename(AsimovName.c_str()));
215 if( failure ) {
216 std::cout << "Error: Failed to import Asimov dataset: " << AsimovName
217 << std::endl;
218 delete asimov_dataset;
219 throw hf_exc();
220 }
221
222 // Load the snapshot at the end of every loop iteration
223 // so we start each loop with a "clean" snapshot
224 ws_single->loadSnapshot(SnapShotName.c_str());
225
226 // we can now deleted the data set after having imported it
227 delete asimov_dataset;
228
229 }
230
231 // Cool, we're done
232 return; // ws_single;
233 }
234
235
236 // We want to eliminate this interface and use the measurment directly
238
239 // This is a pretty light-weight wrapper function
240 //
241 // Take a fully configured measurement as well as
242 // one of its channels
243 //
244 // Return a workspace representing that channel
245 // Do this by first creating a vector of EstimateSummary's
246 // and this by configuring the workspace with any post-processing
247
248 // Get the channel's name
249 string ch_name = channel.GetName();
250
251 // Create a workspace for a SingleChannel from the Measurement Object
252 RooWorkspace* ws_single = this->MakeSingleChannelWorkspace(measurement, channel);
253 if( ws_single == NULL ) {
254 std::cout << "Error: Failed to make Single-Channel workspace for channel: " << ch_name
255 << " and measurement: " << measurement.GetName() << std::endl;
256 throw hf_exc();
257 }
258
259 // Finally, configure that workspace based on
260 // properties of the measurement
261 HistoToWorkspaceFactoryFast::ConfigureWorkspaceForMeasurement( "model_"+ch_name, ws_single, measurement );
262
263 return ws_single;
264
265 }
266
268
269 // This function takes a fully configured measurement
270 // which may contain several channels and returns
271 // a workspace holding the combined model
272 //
273 // This can be used, for example, within a script to produce
274 // a combined workspace on-the-fly
275 //
276 // This is a static function (for now) to make
277 // it a one-liner
278
279 // First, we create an instance of a HistFactory
281
282 // Loop over the channels and create the individual workspaces
283 vector<RooWorkspace*> channel_workspaces;
284 vector<string> channel_names;
285
286 for( unsigned int chanItr = 0; chanItr < measurement.GetChannels().size(); ++chanItr ) {
287
288 HistFactory::Channel& channel = measurement.GetChannels().at( chanItr );
289
290 if( ! channel.CheckHistograms() ) {
291 std::cout << "MakeModelAndMeasurementsFast: Channel: " << channel.GetName()
292 << " has uninitialized histogram pointers" << std::endl;
293 throw hf_exc();
294 }
295
296 string ch_name = channel.GetName();
297 channel_names.push_back(ch_name);
298
299 // GHL: Renaming to 'MakeSingleChannelWorkspace'
300 RooWorkspace* ws_single = factory.MakeSingleChannelModel( measurement, channel );
301
302 channel_workspaces.push_back(ws_single);
303
304 }
305
306
307 // Now, combine the individual channel workspaces to
308 // form the combined workspace
309 RooWorkspace* ws = factory.MakeCombinedModel( channel_names, channel_workspaces );
310
311
312 // Configure the workspace
314
315 // Delete channel workspaces
316 for (vector<RooWorkspace*>::iterator iter = channel_workspaces.begin() ; iter != channel_workspaces.end() ; ++iter) {
317 delete *iter ;
318 }
319
320 // Done. Return the pointer
321 return ws;
322
323 }
324
326 string prefix, string productPrefix,
327 string systTerm ) {
328 if(hist) {
329 cout << "processing hist " << hist->GetName() << endl;
330 } else {
331 cout << "hist is empty" << endl;
332 R__ASSERT(hist != 0);
333 return;
334 }
335
336 /// require dimension >=1 or <=3
337 if (fObsNameVec.empty() && !fObsName.empty()) { fObsNameVec.push_back(fObsName); }
338 R__ASSERT( fObsNameVec.size()>=1 && fObsNameVec.size()<=3 );
339
340 /// determine histogram dimensionality
341 unsigned int histndim(1);
342 std::string classname = hist->ClassName();
343 if (classname.find("TH1")==0) { histndim=1; }
344 else if (classname.find("TH2")==0) { histndim=2; }
345 else if (classname.find("TH3")==0) { histndim=3; }
346 R__ASSERT( histndim==fObsNameVec.size() );
347
348 /// create roorealvar observables
349 RooArgList observables;
350 std::vector<std::string>::iterator itr = fObsNameVec.begin();
351 for (int idx=0; itr!=fObsNameVec.end(); ++itr, ++idx ) {
352 if ( !proto->var(itr->c_str()) ) {
353 TAxis* axis(0);
354 if (idx==0) { axis = hist->GetXaxis(); }
355 if (idx==1) { axis = hist->GetYaxis(); }
356 if (idx==2) { axis = hist->GetZaxis(); }
357 Int_t nbins = axis->GetNbins();
358 Double_t xmin = axis->GetXmin();
359 Double_t xmax = axis->GetXmax();
360 // create observable
361 proto->factory(Form("%s[%f,%f]",itr->c_str(),xmin,xmax));
362 proto->var(itr->c_str())->setBins(nbins);
363 }
364 observables.add( *proto->var(itr->c_str()) );
365 }
366
367 RooDataHist* histDHist = new RooDataHist((prefix+"nominalDHist").c_str(),"",observables,hist);
368 RooHistFunc* histFunc = new RooHistFunc((prefix+"_nominal").c_str(),"",observables,*histDHist,0) ;
369
370 proto->import(*histFunc);
371
372 /// now create the product of the overall efficiency times the sigma(params) for this estimate
373 proto->factory(("prod:"+productPrefix+"("+prefix+"_nominal,"+systTerm+")").c_str() );
374
375 delete histDHist;
376 delete histFunc;
377
378 }
379
380 void HistoToWorkspaceFactoryFast::AddMultiVarGaussConstraint(RooWorkspace* proto, string prefix,int lowBin, int highBin, vector<string>& constraintTermNames){
381 // these are the nominal predictions: eg. the mean of some space of variations
382 // later fill these in a loop over histogram bins
383
384 TVectorD mean(highBin); //-lowBin); // MB: fix range
385 cout << "a" << endl;
386 for(Int_t i=lowBin; i<highBin; ++i){
387 std::stringstream str;
388 str<<"_"<<i;
389 RooRealVar* temp = proto->var((prefix+str.str()).c_str());
390 mean(i) = temp->getVal();
391 }
392
393 TMatrixDSym Cov(highBin-lowBin);
394 for(int i=lowBin; i<highBin; ++i){
395 for(int j=0; j<highBin-lowBin; ++j){
396 if(i==j) { Cov(i,j) = sqrt(mean(i)); } // MB : this doesn't make sense to me if lowBin!=0 (?)
397 else { Cov(i,j) = 0; }
398 }
399 }
400
401 // can't make MultiVarGaussian with factory yet, do it by hand
402 RooArgList floating( *(proto->set(prefix.c_str() ) ) );
403 RooMultiVarGaussian constraint((prefix+"Constraint").c_str(),"",
404 floating, mean, Cov);
405
406 proto->import(constraint);
407
408 constraintTermNames.push_back(constraint.GetName());
409 }
410
412 std::vector<HistoSys> histoSysList,
413 string prefix, string productPrefix,
414 string systTerm,
415 vector<string>& constraintTermNames){
416
417 // these are the nominal predictions: eg. the mean of some space of variations
418 // later fill these in a loop over histogram bins
419
420 // require dimension >=1 or <=3
421 if (fObsNameVec.empty() && !fObsName.empty()) { fObsNameVec.push_back(fObsName); }
422 R__ASSERT( fObsNameVec.size()>=1 && fObsNameVec.size()<=3 );
423
424 // determine histogram dimensionality
425 unsigned int histndim(1);
426 std::string classname = nominal->ClassName();
427 if (classname.find("TH1")==0) { histndim=1; }
428 else if (classname.find("TH2")==0) { histndim=2; }
429 else if (classname.find("TH3")==0) { histndim=3; }
430 R__ASSERT( histndim==fObsNameVec.size() );
431 // cout <<"In LinInterpWithConstriants and histndim = " << histndim <<endl;
432
433 // create roorealvar observables
434 RooArgList observables;
435 std::vector<std::string>::iterator itr = fObsNameVec.begin();
436 for (int idx=0; itr!=fObsNameVec.end(); ++itr, ++idx ) {
437 if ( !proto->var(itr->c_str()) ) {
438 TAxis* axis(NULL);
439 if (idx==0) { axis = nominal->GetXaxis(); }
440 else if (idx==1) { axis = nominal->GetYaxis(); }
441 else if (idx==2) { axis = nominal->GetZaxis(); }
442 else {
443 std::cout << "Error: Too many observables. "
444 << "HistFactory only accepts up to 3 observables (3d) "
445 << std::endl;
446 throw hf_exc();
447 }
448 Int_t nbins = axis->GetNbins();
449 Double_t xmin = axis->GetXmin();
450 Double_t xmax = axis->GetXmax();
451 // create observable
452 proto->factory(Form("%s[%f,%f]",itr->c_str(),xmin,xmax));
453 proto->var(itr->c_str())->setBins(nbins);
454 }
455 observables.add( *proto->var(itr->c_str()) );
456 }
457
458 RooDataHist* nominalDHist = new RooDataHist((prefix+"nominalDHist").c_str(),"",observables,nominal);
459 RooHistFunc* nominalFunc = new RooHistFunc((prefix+"nominal").c_str(),"",observables,*nominalDHist,0) ;
460
461 // make list of abstract parameters that interpolate in space of variations
462 RooArgList params( ("alpha_Hist") );
463 // range is set using defined macro (see top of the page)
464 string range=string("[")+alpha_Low+","+alpha_High+"]";
465
466 // Loop over the HistoSys list
467 for(unsigned int j=0; j<histoSysList.size(); ++j){
468 std::stringstream str;
469 str<<"_"<<j;
470
471 HistoSys& histoSys = histoSysList.at(j);
472 string histoSysName = histoSys.GetName();
473
474 RooRealVar* temp = (RooRealVar*) proto->var(("alpha_" + histoSysName).c_str());
475 if(!temp){
476
477 temp = (RooRealVar*) proto->factory(("alpha_" + histoSysName + range).c_str());
478
479 // now add a constraint term for these parameters
480 string command=("Gaussian::alpha_"+histoSysName+"Constraint(alpha_"+histoSysName+",nom_alpha_"+histoSysName+"[0.,-10,10],1.)");
481 cout << command << endl;
482 constraintTermNames.push_back( proto->factory( command.c_str() )->GetName() );
483 proto->var(("nom_alpha_"+histoSysName).c_str())->setConstant();
484 const_cast<RooArgSet*>(proto->set("globalObservables"))->add(*proto->var(("nom_alpha_"+histoSysName).c_str()));
485 }
486 params.add(* temp );
487 }
488
489 // now make function that linearly interpolates expectation between variations
490 // get low/high variations to interpolate between
491 vector<double> low, high;
492 RooArgSet lowSet, highSet;
493 //ES// for(unsigned int j=0; j<lowHist.size(); ++j){
494 for(unsigned int j=0; j<histoSysList.size(); ++j){
495 std::stringstream str;
496 str<<"_"<<j;
497
498 HistoSys& histoSys = histoSysList.at(j);
499 RooDataHist* lowDHist = new RooDataHist((prefix+str.str()+"lowDHist").c_str(),"",observables, histoSys.GetHistoLow());
500 RooDataHist* highDHist = new RooDataHist((prefix+str.str()+"highDHist").c_str(),"",observables, histoSys.GetHistoHigh());
501 RooHistFunc* lowFunc = new RooHistFunc((prefix+str.str()+"low").c_str(),"",observables,*lowDHist,0) ;
502 RooHistFunc* highFunc = new RooHistFunc((prefix+str.str()+"high").c_str(),"",observables,*highDHist,0) ;
503 lowSet.add(*lowFunc);
504 highSet.add(*highFunc);
505 }
506
507 // this is sigma(params), a piece-wise linear interpolation
508 PiecewiseInterpolation interp(prefix.c_str(),"",*nominalFunc,lowSet,highSet,params);
509 interp.setPositiveDefinite();
510 interp.setAllInterpCodes(4); // LM: change to 4 (piece-wise linear to 6th order polynomial interpolation + linear extrapolation )
511 // KC: interpo codes 1 etc. don't have proper analytic integral.
512 RooArgSet observableSet(observables);
513 interp.setBinIntegrator(observableSet);
514 interp.forceNumInt();
515
516 proto->import(interp); // individual params have already been imported in first loop of this function
517
518 // now create the product of the overall efficiency times the sigma(params) for this estimate
519 proto->factory(("prod:"+productPrefix+"("+prefix+","+systTerm+")").c_str() );
520
521 }
522
523 // GHL: Consider passing the NormFactor list instead of the entire sample
524 string HistoToWorkspaceFactoryFast::AddNormFactor(RooWorkspace* proto, string& channel, string& sigmaEpsilon, Sample& sample, bool doRatio){
525 string overallNorm_times_sigmaEpsilon ;
526 string prodNames;
527
528 vector<NormFactor> normList = sample.GetNormFactorList();
529 vector<string> normFactorNames, rangeNames;
530
531 if(normList.size() > 0){
532
533 for(vector<NormFactor>::iterator itr = normList.begin(); itr != normList.end(); ++itr){
534
535 NormFactor& norm = *itr;
536
537 string varname;
538 if(!prodNames.empty()) prodNames += ",";
539 if(doRatio) {
540 varname = norm.GetName() + "_" + channel;
541 }
542 else {
543 varname=norm.GetName();
544 }
545
546 // GHL: Check that the NormFactor doesn't already exist
547 // (it may have been created as a function expression
548 // during preprocessing)
549 std::stringstream range;
550 range << "[" << norm.GetVal() << "," << norm.GetLow() << "," << norm.GetHigh() << "]";
551
552 if( proto->obj(varname.c_str()) == NULL) {
553 cout << "making normFactor: " << norm.GetName() << endl;
554 // remove "doRatio" and name can be changed when ws gets imported to the combined model.
555 proto->factory((varname + range.str()).c_str());
556 }
557
558 if(norm.GetConst()) {
559 // proto->var(varname.c_str())->setConstant();
560 // cout <<"setting " << varname << " constant"<<endl;
561 cout << "WARNING: Const attribute to <NormFactor> tag is deprecated, will ignore." <<
562 " Instead, add \n\t<ParamSetting Const=\"True\">" << varname << "</ParamSetting>\n" <<
563 " to your top-level XML's <Measurment> entry" << endl;
564 }
565 prodNames+=varname;
566 rangeNames.push_back(range.str());
567 normFactorNames.push_back(varname);
568 }
569
570 overallNorm_times_sigmaEpsilon = sample.GetName() + "_" + channel + "_overallNorm_x_sigma_epsilon";
571 proto->factory(("prod::" + overallNorm_times_sigmaEpsilon + "(" + prodNames + "," + sigmaEpsilon + ")").c_str());
572 }
573
574 unsigned int rangeIndex=0;
575 for( vector<string>::iterator nit = normFactorNames.begin(); nit!=normFactorNames.end(); ++nit){
576 if( count (normFactorNames.begin(), normFactorNames.end(), *nit) > 1 ){
577 cout <<"WARNING: <NormFactor Name =\""<<*nit<<"\"> is duplicated for <Sample Name=\""
578 << sample.GetName() << "\">, but only one factor will be included. \n Instead, define something like"
579 << "\n\t<Function Name=\""<<*nit<<"Squared\" Expresion=\""<<*nit<<"*"<<*nit<<"\" Var=\""<<*nit<<rangeNames.at(rangeIndex)
580 << "\"> \nin your top-level XML's <Measurment> entry and use <NormFactor Name=\""<<*nit<<"Squared\" in your channel XML file."<< endl;
581 }
582 ++rangeIndex;
583 }
584
585 if(!overallNorm_times_sigmaEpsilon.empty())
586 return overallNorm_times_sigmaEpsilon;
587 else
588 return sigmaEpsilon;
589 }
590
592 string interpName,
593 std::vector<OverallSys>& systList,
594 vector<string>& constraintTermNames,
595 vector<string>& totSystTermNames) {
596
597 // add variables for all the relative overall uncertainties we expect
598 // range is set using defined macro (see top of the page)
599
600 string range=string("[0,")+alpha_Low+","+alpha_High+"]";
601 totSystTermNames.push_back(prefix);
602
603 RooArgSet params(prefix.c_str());
604 vector<double> lowVec, highVec;
605
606 std::map<std::string, double>::iterator itconstr;
607 for(unsigned int i = 0; i < systList.size(); ++i) {
608
609 OverallSys& sys = systList.at(i);
610 std::string strname = sys.GetName();
611 const char * name = strname.c_str();
612
613 // case of no systematic (is it possible)
614 if (meas.GetNoSyst().count(sys.GetName()) > 0 ) {
615 std::cout << "HistoToWorkspaceFast::AddConstraintTerm - skip systematic " << sys.GetName() << std::endl;
616 continue;
617 }
618 // case systematic is a gamma constraint
619 if (meas.GetGammaSyst().count(sys.GetName()) > 0 ) {
620 double relerr = meas.GetGammaSyst().find(sys.GetName() )->second;
621 if (relerr <= 0) {
622 std::cout << "HistoToWorkspaceFast::AddConstraintTerm - zero uncertainty assigned - skip systematic " << sys.GetName() << std::endl;
623 continue;
624 }
625 double tauVal = 1./(relerr*relerr);
626 double sqtau = 1./relerr;
627 RooAbsArg * beta = proto->factory(TString::Format("beta_%s[1,0,10]",name) );
628 // the global observable (y_s)
629 RooAbsArg * yvar = proto->factory(TString::Format("nom_%s[%f,0,10]",beta->GetName(),tauVal)) ;
630 // the rate of the gamma distribution (theta)
631 RooAbsArg * theta = proto->factory(TString::Format("theta_%s[%f]",name,1./tauVal));
632 // find alpha as function of beta
633 RooAbsArg* alphaOfBeta = proto->factory(TString::Format("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",name,name,-sqtau,sqtau));
634
635 // add now the constraint itself Gamma_beta_constraint(beta, y+1, tau, 0 )
636 // build the gamma parameter k = as y_s + 1
637 RooAbsArg * kappa = proto->factory(TString::Format("sum::k_%s(%s,1.)",name,yvar->GetName()) );
638 RooAbsArg * gamma = proto->factory(TString::Format("Gamma::%sConstraint(%s, %s, %s, 0.0)",beta->GetName(),beta->GetName(), kappa->GetName(), theta->GetName() ) );
639 alphaOfBeta->Print("t");
640 gamma->Print("t");
641 constraintTermNames.push_back(gamma->GetName());
642 // set global observables
643 RooRealVar * gobs = dynamic_cast<RooRealVar*>(yvar); assert(gobs);
644 gobs->setConstant(true);
645 const_cast<RooArgSet*>(proto->set("globalObservables"))->add(*yvar);
646
647 // add alphaOfBeta in the list of params to interpolate
648 params.add(*alphaOfBeta);
649 std::cout << "Added a gamma constraint for " << name << std::endl;
650
651 }
652 else {
653
654 // add the Gaussian constraint part
655
656 // case systematic is uniform (asssume they are like a gauaaian bbut with a large width
657 // (100 instead of 1)
658 double gaussSigma = 1;
659 if (meas.GetUniformSyst().count(sys.GetName()) > 0 ) {
660 gaussSigma = 100;
661 std::cout << "Added a uniform constraint for " << name << " as a gaussian constraint with a very large sigma " << std::endl;
662 }
663
664 // add Gaussian constraint terms (normal + log-normal case)
665 RooRealVar* alpha = (RooRealVar*) proto->var((prefix + sys.GetName()).c_str());
666 if(!alpha) {
667
668 alpha = (RooRealVar*) proto->factory((prefix + sys.GetName() + range).c_str());
669 RooAbsArg * nomAlpha = proto->factory(TString::Format("nom_%s[0.,-10,10]",alpha->GetName() ) );
670 RooAbsArg * gausConstraint = proto->factory(TString::Format("Gaussian::%sConstraint(%s,%s,%f)",alpha->GetName(),alpha->GetName(), nomAlpha->GetName(), gaussSigma) );
671 //cout << command << endl;
672 constraintTermNames.push_back( gausConstraint->GetName() );
673 proto->var(("nom_" + prefix + sys.GetName()).c_str())->setConstant();
674 const_cast<RooArgSet*>(proto->set("globalObservables"))->add(*nomAlpha);
675 }
676
677
678 // add constraint in terms of bifrucated gauss with low/high as sigmas
679 //std::stringstream lowhigh;
680
681 // check if exists a log-normal constraint
682 if (meas.GetLogNormSyst().count(sys.GetName()) == 0 && meas.GetGammaSyst().count(sys.GetName()) == 0 ) {
683 // just add the alpha for the parameters of the FlexibleInterpVar function
684 params.add(*alpha);
685 }
686 // case systematic is a log-normal constraint
687 if (meas.GetLogNormSyst().count(sys.GetName()) > 0 ) {
688 // log normal constraint for parameter
689 double relerr = meas.GetLogNormSyst().find(sys.GetName() )->second;
690 double tauVal = 1./relerr;
691 std::string tauName = "tau_" + sys.GetName();
692 proto->factory(TString::Format("%s[%f]",tauName.c_str(),tauVal ) );
693 double kappaVal = 1. + relerr;
694 std::string kappaName = "kappa_" + sys.GetName();
695 proto->factory(TString::Format("%s[%f]",kappaName.c_str(),kappaVal ) );
696 const char * alphaName = alpha->GetName();
697
698 std::string alphaOfBetaName = "alphaOfBeta_" + sys.GetName();
699 RooAbsArg * alphaOfBeta = proto->factory(TString::Format("expr::%s('%s*(pow(%s,%s)-1.)',%s,%s,%s)",alphaOfBetaName.c_str(),
700 tauName.c_str(),kappaName.c_str(),alphaName,
701 tauName.c_str(),kappaName.c_str(),alphaName ) );
702
703 std::cout << "Added a log-normal constraint for " << name << std::endl;
704 alphaOfBeta->Print("t");
705 params.add(*alphaOfBeta);
706 }
707
708 }
709 // add low/high vectors
710 double low = sys.GetLow();
711 double high = sys.GetHigh();
712 lowVec.push_back(low);
713 highVec.push_back(high);
714
715 } // end sys loop
716
717 if(systList.size() > 0){
718 // this is epsilon(alpha_j), a piece-wise linear interpolation
719 // LinInterpVar interp( (interpName).c_str(), "", params, 1., lowVec, highVec);
720
721 assert( params.getSize() > 0);
722 assert(int(lowVec.size()) == params.getSize() );
723
724 FlexibleInterpVar interp( (interpName).c_str(), "", params, 1., lowVec, highVec);
725 interp.setAllInterpCodes(4); // LM: change to 4 (piece-wise linear to 6th order polynomial interpolation + linear extrapolation )
726 //interp.setAllInterpCodes(0); // simple linear interpolation
727 proto->import(interp); // params have already been imported in first loop of this function
728 } else{
729 // some strange behavior if params,lowVec,highVec are empty.
730 //cout << "WARNING: No OverallSyst terms" << endl;
731 RooConstVar interp( (interpName).c_str(), "", 1.);
732 proto->import(interp); // params have already been imported in first loop of this function
733 }
734
735 // std::cout << "after creating FlexibleInterpVar " << std::endl;
736 // proto->Print();
737
738 }
739
740
742 vector<string>& syst_x_expectedPrefixNames,
743 vector<string>& normByNames){
744
745 // for ith bin calculate totN_i = lumi * sum_j expected_j * syst_j
746 string command;
747 string coeffList="";
748 string shapeList="";
749 string prepend="";
750
751 if (fObsNameVec.empty() && !fObsName.empty()) { fObsNameVec.push_back(fObsName); }
752
753 double binWidth(1.0);
754 std::string obsNameVecStr;
755 std::vector<std::string>::iterator itr = fObsNameVec.begin();
756 for (; itr!=fObsNameVec.end(); ++itr) {
757 std::string obsName = *itr;
758 binWidth *= proto->var(obsName.c_str())->numBins()/(proto->var(obsName.c_str())->getMax() - proto->var(obsName.c_str())->getMin()) ; // MB: Note: requires fixed bin sizes
759 if (obsNameVecStr.size()>0) { obsNameVecStr += "_"; }
760 obsNameVecStr += obsName;
761 }
762
763 //vector<string>::iterator it=syst_x_expectedPrefixNames.begin();
764 for(unsigned int j=0; j<syst_x_expectedPrefixNames.size();++j){
765 std::stringstream str;
766 str<<"_"<<j;
767 // repatative, but we need one coeff for each term in the sum
768 // maybe can be avoided if we don't use bin width as coefficient
769 command=string(Form("binWidth_%s_%d[%e]",obsNameVecStr.c_str(),j,binWidth));
770 proto->factory(command.c_str());
771 proto->var(Form("binWidth_%s_%d",obsNameVecStr.c_str(),j))->setConstant();
772 coeffList+=prepend+"binWidth_"+obsNameVecStr+str.str();
773
774 command="prod::L_x_"+syst_x_expectedPrefixNames.at(j)+"("+normByNames.at(j)+","+syst_x_expectedPrefixNames.at(j)+")";
775 /*RooAbsReal* tempFunc =(RooAbsReal*) */
776 proto->factory(command.c_str());
777 shapeList+=prepend+"L_x_"+syst_x_expectedPrefixNames.at(j);
778 prepend=",";
779
780 // add to num int to product
781 // tempFunc->specialIntegratorConfig(kTRUE)->method1D().setLabel("RooBinIntegrator") ;
782 // tempFunc->forceNumInt();
783
784 }
785
786 proto->defineSet("coefList",coeffList.c_str());
787 proto->defineSet("shapeList",shapeList.c_str());
788 // proto->factory(command.c_str());
789 RooRealSumPdf tot(totName.c_str(),totName.c_str(),*proto->set("shapeList"),*proto->set("coefList"),kTRUE);
790 tot.specialIntegratorConfig(kTRUE)->method1D().setLabel("RooBinIntegrator") ;
791 tot.specialIntegratorConfig(kTRUE)->method2D().setLabel("RooBinIntegrator") ;
792 tot.specialIntegratorConfig(kTRUE)->methodND().setLabel("RooBinIntegrator") ;
793 tot.forceNumInt();
794
795 // for mixed generation in RooSimultaneous
796 tot.setAttribute("GenerateBinned"); // for use with RooSimultaneous::generate in mixed mode
797 // tot.setAttribute("GenerateUnbinned"); // we don't want that
798
799 /*
800 // Use binned numeric integration
801 int nbins = 0;
802 if( fObsNameVec.size() == 1 ) {
803 nbins = proto->var(fObsNameVec.at(0).c_str())->numBins();
804
805 cout <<"num bis for RooRealSumPdf = "<<nbins <<endl;
806 //int nbins = ((RooRealVar*) allVars.first())->numBins();
807 tot.specialIntegratorConfig(kTRUE)->getConfigSection("RooBinIntegrator").setRealValue("numBins",nbins);
808 tot.forceNumInt();
809
810 } else {
811 cout << "Bin Integrator only supports 1-d. Will be slow." << std::endl;
812 }
813 */
814
815
816 proto->import(tot);
817
818 }
819
820 void HistoToWorkspaceFactoryFast::AddPoissonTerms(RooWorkspace* proto, string prefix, string obsPrefix, string expPrefix, int lowBin, int highBin,
821 vector<string>& likelihoodTermNames){
822 /////////////////////////////////
823 // Relate observables to expected for each bin
824 // later modify variable named expPrefix_i to be product of terms
825 RooArgSet Pois(prefix.c_str());
826 for(Int_t i=lowBin; i<highBin; ++i){
827 std::stringstream str;
828 str<<"_"<<i;
829 //string command("Poisson::"+prefix+str.str()+"("+obsPrefix+str.str()+","+expPrefix+str.str()+")");
830 string command("Poisson::"+prefix+str.str()+"("+obsPrefix+str.str()+","+expPrefix+str.str()+",1)");//for no rounding
831 RooAbsArg* temp = (proto->factory( command.c_str() ) );
832
833 // output
834 cout << "Poisson Term " << command << endl;
835 ((RooAbsPdf*) temp)->setEvalErrorLoggingMode(RooAbsReal::PrintErrors);
836 //cout << temp << endl;
837
838 likelihoodTermNames.push_back( temp->GetName() );
839 Pois.add(* temp );
840 }
841 proto->defineSet(prefix.c_str(),Pois); // add argset to workspace
842 }
843
844 void HistoToWorkspaceFactoryFast::SetObsToExpected(RooWorkspace* proto, string obsPrefix, string expPrefix, int lowBin, int highBin){
845 /////////////////////////////////
846 // set observed to expected
847 TTree* tree = new TTree();
848 Double_t* obsForTree = new Double_t[highBin-lowBin];
849 RooArgList obsList("obsList");
850
851 for(Int_t i=lowBin; i<highBin; ++i){
852 std::stringstream str;
853 str<<"_"<<i;
854 RooRealVar* obs = (RooRealVar*) proto->var((obsPrefix+str.str()).c_str());
855 cout << "expected number of events called: " << expPrefix << endl;
856 RooAbsReal* exp = proto->function((expPrefix+str.str()).c_str());
857 if(obs && exp){
858
859 //proto->Print();
860 obs->setVal( exp->getVal() );
861 cout << "setting obs"+str.str()+" to expected = " << exp->getVal() << " check: " << obs->getVal() << endl;
862
863 // add entry to array and attach to tree
864 obsForTree[i] = exp->getVal();
865 tree->Branch((obsPrefix+str.str()).c_str(), obsForTree+i ,(obsPrefix+str.str()+"/D").c_str());
866 obsList.add(*obs);
867 }else{
868 cout << "problem retrieving obs or exp " << obsPrefix+str.str() << obs << " " << expPrefix+str.str() << exp << endl;
869 }
870 }
871 tree->Fill();
872 RooDataSet* data = new RooDataSet("expData","", tree, obsList); // one experiment
873
874 delete tree;
875 delete [] obsForTree;
876
877 proto->import(*data);
878
879 delete data;
880
881 }
882
883 //////////////////////////////////////////////////////////////////////////////
884
886 map<string,double> gammaSyst,
887 map<string,double> uniformSyst,
888 map<string,double> logNormSyst,
889 map<string,double> noSyst) {
890 string pdfName(pdfNameChar);
891
892 ModelConfig * combined_config = (ModelConfig *) proto->obj("ModelConfig");
893 if( combined_config==NULL ) {
894 std::cout << "Error: Failed to find object 'ModelConfig' in workspace: "
895 << proto->GetName() << std::endl;
896 throw hf_exc();
897 }
898 // const RooArgSet * constrainedParams=combined_config->GetNuisanceParameters();
899 // RooArgSet temp(*constrainedParams);
900 string edit="EDIT::newSimPdf("+pdfName+",";
901 string editList;
902 string lastPdf=pdfName;
903 string precede="";
904 unsigned int numReplacements = 0;
905 unsigned int nskipped = 0;
906 map<string,double>::iterator it;
907
908
909 // add gamma terms and their constraints
910 for(it=gammaSyst.begin(); it!=gammaSyst.end(); ++it) {
911 //cout << "edit for " << it->first << "with rel uncert = " << it->second << endl;
912 if(! proto->var(("alpha_"+it->first).c_str())){
913 //cout << "systematic not there" << endl;
914 nskipped++;
915 continue;
916 }
917 numReplacements++;
918
919 double relativeUncertainty = it->second;
920 double scale = 1/sqrt((1+1/pow(relativeUncertainty,2)));
921
922 // this is the Gamma PDF and in a form that doesn't have roundoff problems like the Poisson does
923 proto->factory(Form("beta_%s[1,0,10]",it->first.c_str()));
924 proto->factory(Form("y_%s[%f]",it->first.c_str(),1./pow(relativeUncertainty,2))) ;
925 proto->factory(Form("theta_%s[%f]",it->first.c_str(),pow(relativeUncertainty,2))) ;
926 proto->factory(Form("Gamma::beta_%sConstraint(beta_%s,sum::k_%s(y_%s,one[1]),theta_%s,zero[0])",
927 it->first.c_str(),
928 it->first.c_str(),
929 it->first.c_str(),
930 it->first.c_str(),
931 it->first.c_str())) ;
932
933 /*
934 // this has some problems because N in poisson is rounded to nearest integer
935 proto->factory(Form("Poisson::beta_%sConstraint(y_%s[%f],prod::taub_%s(taus_%s[%f],beta_%s[1,0,5]))",
936 it->first.c_str(),
937 it->first.c_str(),
938 1./pow(relativeUncertainty,2),
939 it->first.c_str(),
940 it->first.c_str(),
941 1./pow(relativeUncertainty,2),
942 it->first.c_str()
943 ) ) ;
944 */
945 // combined->factory(Form("expr::alphaOfBeta('(beta-1)/%f',beta)",scale));
946 // combined->factory(Form("expr::alphaOfBeta_%s('(beta_%s-1)/%f',beta_%s)",it->first.c_str(),it->first.c_str(),scale,it->first.c_str()));
947 proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",it->first.c_str(),it->first.c_str(),-1./scale,1./scale));
948
949 // set beta const status to be same as alpha
950 if(proto->var(Form("alpha_%s",it->first.c_str()))->isConstant()) {
951 proto->var(Form("beta_%s",it->first.c_str()))->setConstant(true);
952 }
953 else {
954 proto->var(Form("beta_%s",it->first.c_str()))->setConstant(false);
955 }
956 // set alpha const status to true
957 // proto->var(Form("alpha_%s",it->first.c_str()))->setConstant(true);
958
959 // replace alphas with alphaOfBeta and replace constraints
960 editList+=precede + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint";
961 precede=",";
962 editList+=precede + "alpha_"+it->first+"=alphaOfBeta_"+ it->first;
963
964 /*
965 if( proto->pdf(("alpha_"+it->first+"Constraint").c_str()) && proto->var(("alpha_"+it->first).c_str()) )
966 cout << " checked they are there" << proto->pdf(("alpha_"+it->first+"Constraint").c_str()) << " " << proto->var(("alpha_"+it->first).c_str()) << endl;
967 else
968 cout << "NOT THERE" << endl;
969 */
970
971 // EDIT seems to die if the list of edits is too long. So chunck them up.
972 if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
973 edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
974 lastPdf+="_"; // append an underscore for the edit
975 editList=""; // reset edit list
976 precede="";
977 cout << "Going to issue this edit command\n" << edit<< endl;
978 proto->factory( edit.c_str() );
979 RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
980 if(!newOne)
981 cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
982
983 }
984 }
985
986 // add uniform terms and their constraints
987 for(it=uniformSyst.begin(); it!=uniformSyst.end(); ++it) {
988 cout << "edit for " << it->first << "with rel uncert = " << it->second << endl;
989 if(! proto->var(("alpha_"+it->first).c_str())){
990 cout << "systematic not there" << endl;
991 nskipped++;
992 continue;
993 }
994 numReplacements++;
995
996 // this is the Uniform PDF
997 proto->factory(Form("beta_%s[1,0,10]",it->first.c_str()));
998 proto->factory(Form("Uniform::beta_%sConstraint(beta_%s)",it->first.c_str(),it->first.c_str()));
999 proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{-1,1})",it->first.c_str(),it->first.c_str()));
1000
1001 // set beta const status to be same as alpha
1002 if(proto->var(Form("alpha_%s",it->first.c_str()))->isConstant())
1003 proto->var(Form("beta_%s",it->first.c_str()))->setConstant(true);
1004 else
1005 proto->var(Form("beta_%s",it->first.c_str()))->setConstant(false);
1006 // set alpha const status to true
1007 // proto->var(Form("alpha_%s",it->first.c_str()))->setConstant(true);
1008
1009 // replace alphas with alphaOfBeta and replace constraints
1010 cout << "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl;
1011 editList+=precede + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint";
1012 precede=",";
1013 cout << "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl;
1014 editList+=precede + "alpha_"+it->first+"=alphaOfBeta_"+ it->first;
1015
1016 if( proto->pdf(("alpha_"+it->first+"Constraint").c_str()) && proto->var(("alpha_"+it->first).c_str()) )
1017 cout << " checked they are there" << proto->pdf(("alpha_"+it->first+"Constraint").c_str()) << " " << proto->var(("alpha_"+it->first).c_str()) << endl;
1018 else
1019 cout << "NOT THERE" << endl;
1020
1021 // EDIT seems to die if the list of edits is too long. So chunck them up.
1022 if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
1023 edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
1024 lastPdf+="_"; // append an underscore for the edit
1025 editList=""; // reset edit list
1026 precede="";
1027 cout << edit<< endl;
1028 proto->factory( edit.c_str() );
1029 RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
1030 if(!newOne)
1031 cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
1032
1033 }
1034 }
1035
1036 /////////////////////////////////////////
1037 ////////////////////////////////////
1038
1039
1040 // add lognormal terms and their constraints
1041 for(it=logNormSyst.begin(); it!=logNormSyst.end(); ++it) {
1042 cout << "edit for " << it->first << "with rel uncert = " << it->second << endl;
1043 if(! proto->var(("alpha_"+it->first).c_str())){
1044 cout << "systematic not there" << endl;
1045 nskipped++;
1046 continue;
1047 }
1048 numReplacements++;
1049
1050 double relativeUncertainty = it->second;
1051 double kappa = 1+relativeUncertainty;
1052 // when transforming beta -> alpha, need alpha=1 to be +1sigma value.
1053 // the P(beta>kappa*\hat(beta)) = 16%
1054 // and \hat(beta) is 1, thus
1055 double scale = relativeUncertainty;
1056 //double scale = kappa;
1057
1058 const char * cname = it->first.c_str();
1059
1060 // this is the LogNormal
1061 proto->factory(TString::Format("beta_%s[1,0,10]",cname));
1062 proto->factory(TString::Format("nom_beta_%s[1]",cname));
1063 proto->factory(TString::Format("kappa_%s[%f]",cname,kappa));
1064 proto->factory(TString::Format("Lognormal::beta_%sConstraint(beta_%s,nom_beta_%s,kappa_%s)",
1065 cname, cname, cname, cname)) ;
1066 proto->factory(TString::Format("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",cname,cname,-1./scale,1./scale));
1067
1068
1069 // set beta const status to be same as alpha
1070 if(proto->var(TString::Format("alpha_%s",cname))->isConstant())
1071 proto->var(TString::Format("beta_%s",cname))->setConstant(true);
1072 else
1073 proto->var(TString::Format("beta_%s",cname))->setConstant(false);
1074 // set alpha const status to true
1075 // proto->var(TString::Format("alpha_%s",cname))->setConstant(true);
1076
1077 // replace alphas with alphaOfBeta and replace constraints
1078 cout << "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl;
1079 editList+=precede + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint";
1080 precede=",";
1081 cout << "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl;
1082 editList+=precede + "alpha_"+it->first+"=alphaOfBeta_"+ it->first;
1083
1084 if( proto->pdf(("alpha_"+it->first+"Constraint").c_str()) && proto->var(("alpha_"+it->first).c_str()) )
1085 cout << " checked they are there" << proto->pdf(("alpha_"+it->first+"Constraint").c_str()) << " " << proto->var(("alpha_"+it->first).c_str()) << endl;
1086 else
1087 cout << "NOT THERE" << endl;
1088
1089 // EDIT seems to die if the list of edits is too long. So chunck them up.
1090 if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
1091 edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
1092 lastPdf+="_"; // append an underscore for the edit
1093 editList=""; // reset edit list
1094 precede="";
1095 cout << edit<< endl;
1096 proto->factory( edit.c_str() );
1097 RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
1098 if(!newOne)
1099 cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
1100
1101 }
1102 // add global observables
1103 const RooArgSet * gobs = proto->set("globalObservables");
1104 RooArgSet gobsNew(*gobs);
1105 gobsNew.add(*proto->var(TString::Format("nom_beta_%s",cname)) );
1106 proto->removeSet("globalObservables");
1107 proto->defineSet("globalObservables",gobsNew);
1108 gobsNew.Print();
1109
1110 }
1111
1112 /////////////////////////////////////////
1113
1114 // MB: remove a systematic constraint
1115 for(it=noSyst.begin(); it!=noSyst.end(); ++it) {
1116
1117 cout << "remove constraint for parameter" << it->first << endl;
1118 if(! proto->var(("alpha_"+it->first).c_str()) || ! proto->pdf(("alpha_"+it->first+"Constraint").c_str()) ) {
1119 cout << "systematic not there" << endl;
1120 nskipped++;
1121 continue;
1122 }
1123 numReplacements++;
1124
1125 // dummy replacement pdf
1126 if ( !proto->var("one") ) { proto->factory("one[1.0]"); }
1127 proto->var("one")->setConstant();
1128
1129 // replace constraints
1130 cout << "alpha_"+it->first+"Constraint=one" << endl;
1131 editList+=precede + "alpha_"+it->first+"Constraint=one";
1132 precede=",";
1133
1134 // EDIT seems to die if the list of edits is too long. So chunck them up.
1135 if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
1136 edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
1137 lastPdf+="_"; // append an underscore for the edit
1138 editList=""; // reset edit list
1139 precede="";
1140 cout << edit << endl;
1141 proto->factory( edit.c_str() );
1142 RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
1143 if(!newOne) { cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl; }
1144 }
1145 }
1146
1147 /////////////////////////////////////////
1148
1149 // commit last bunch of edits
1150 edit="EDIT::newSimPdf("+lastPdf+","+editList+")";
1151 cout << edit<< endl;
1152 proto->factory( edit.c_str() );
1153 // proto->writeToFile(("results/model_"+fRowTitle+"_edited.root").c_str());
1154 RooAbsPdf* newOne = proto->pdf("newSimPdf");
1155 if(newOne){
1156 // newOne->graphVizTree(("results/"+pdfName+"_"+fRowTitle+"newSimPdf.dot").c_str());
1157 combined_config->SetPdf(*newOne);
1158 }
1159 else{
1160 cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
1161 }
1162 }
1163
1165 // Change-> Now a static utility
1166
1167 FILE* covFile = fopen ((filename).c_str(),"w");
1168
1169 TIter iti = params->createIterator();
1170 TIter itj = params->createIterator();
1171 RooRealVar *myargi, *myargj;
1172 fprintf(covFile," ") ;
1173 while ((myargi = (RooRealVar *)iti.Next())) {
1174 if(myargi->isConstant()) continue;
1175 fprintf(covFile," & %s", myargi->GetName());
1176 }
1177 fprintf(covFile,"\\\\ \\hline \n" );
1178 iti.Reset();
1179 while ((myargi = (RooRealVar *)iti.Next())) {
1180 if(myargi->isConstant()) continue;
1181 fprintf(covFile,"%s", myargi->GetName());
1182 itj.Reset();
1183 while ((myargj = (RooRealVar *)itj.Next())) {
1184 if(myargj->isConstant()) continue;
1185 cout << myargi->GetName() << "," << myargj->GetName();
1186 fprintf(covFile, " & %.2f", result->correlation(*myargi, *myargj));
1187 }
1188 cout << endl;
1189 fprintf(covFile, " \\\\\n");
1190 }
1191 fclose(covFile);
1192
1193 }
1194
1195
1196 ///////////////////////////////////////////////
1198
1199 // check inputs (see JIRA-6890 )
1200
1201 if (channel.GetSamples().empty()) {
1202 Error("MakeSingleChannelWorkspace","The input Channel does not contain any sample - return a nullptr");
1203 return 0;
1204 }
1205
1206 // Set these by hand inside the function
1207 vector<string> systToFix = measurement.GetConstantParams();
1208 bool doRatio=false;
1209
1210 // to time the macro
1211 TStopwatch t;
1212 t.Start();
1213 //ES// string channel_name=summary[0].channel;
1214 string channel_name = channel.GetName();
1215
1216 /// MB: reset observable names for each new channel.
1217 fObsNameVec.clear();
1218
1219 /// MB: label observables x,y,z, depending on histogram dimensionality
1220 /// GHL: Give it the first sample's nominal histogram as a template
1221 /// since the data histogram may not be present
1222 TH1* channel_hist_template = channel.GetSamples().at(0).GetHisto();
1223 if (fObsNameVec.empty()) { GuessObsNameVec(channel_hist_template); }
1224
1225 for ( unsigned int idx=0; idx<fObsNameVec.size(); ++idx ) {
1226 fObsNameVec[idx] = "obs_" + fObsNameVec[idx] + "_" + channel_name ;
1227 }
1228
1229 if (fObsNameVec.empty()) {
1230 fObsName= "obs_" + channel_name; // set name ov observable
1231 fObsNameVec.push_back( fObsName );
1232 }
1233
1234 R__ASSERT( fObsNameVec.size()>=1 && fObsNameVec.size()<=3 );
1235
1236 cout << "\n\n-------------------\nStarting to process " << channel_name << " channel with " << fObsNameVec.size() << " observables" << endl;
1237
1238 //
1239 // our main workspace that we are using to construct the model
1240 //
1241 RooWorkspace* proto = new RooWorkspace(channel_name.c_str(), (channel_name+" workspace").c_str());
1242 auto proto_config = make_unique<ModelConfig>("ModelConfig", proto);
1243 proto_config->SetWorkspace(*proto);
1244
1245 // preprocess functions
1246 vector<string>::iterator funcIter = fPreprocessFunctions.begin();
1247 for(;funcIter!= fPreprocessFunctions.end(); ++funcIter){
1248 cout <<"will preprocess this line: " << *funcIter <<endl;
1249 proto->factory(funcIter->c_str());
1250 proto->Print();
1251 }
1252
1253 RooArgSet likelihoodTerms("likelihoodTerms"), constraintTerms("constraintTerms");
1254 vector<string> likelihoodTermNames, constraintTermNames, totSystTermNames, syst_x_expectedPrefixNames, normalizationNames;
1255
1256 vector< pair<string,string> > statNamePairs;
1257 vector< pair<TH1*,TH1*> > statHistPairs; // <nominal, error>
1258 std::string statFuncName; // the name of the ParamHistFunc
1259 std::string statNodeName; // the name of the McStat Node
1260 // Constraint::Type statConstraintType=Constraint::Gaussian;
1261 // Double_t statRelErrorThreshold=0.0;
1262
1263 string prefix, range;
1264
1265 /////////////////////////////
1266 // shared parameters
1267 // this is ratio of lumi to nominal lumi. We will include relative uncertainty in model
1268 std::stringstream lumiStr;
1269 // lumi range
1270 lumiStr<<"["<<fNomLumi<<",0,"<<10.*fNomLumi<<"]";
1271 proto->factory(("Lumi"+lumiStr.str()).c_str());
1272 cout << "lumi str = " << lumiStr.str() << endl;
1273
1274 std::stringstream lumiErrorStr;
1275 lumiErrorStr << "nominalLumi["<<fNomLumi << ",0,"<<fNomLumi+10*fLumiError<<"]," << fLumiError ;
1276 proto->factory(("Gaussian::lumiConstraint(Lumi,"+lumiErrorStr.str()+")").c_str());
1277 proto->var("nominalLumi")->setConstant();
1278 proto->defineSet("globalObservables","nominalLumi");
1279 //likelihoodTermNames.push_back("lumiConstraint");
1280 constraintTermNames.push_back("lumiConstraint");
1281 cout << "lumi Error str = " << lumiErrorStr.str() << endl;
1282
1283 //proto->factory((string("SigXsecOverSM[1.,0.5,1..8]").c_str()));
1284 ///////////////////////////////////
1285 // loop through estimates, add expectation, floating bin predictions,
1286 // and terms that constrain floating to expectation via uncertainties
1287 // GHL: Loop over samples instead, which doesn't contain the data
1288 vector<Sample>::iterator it = channel.GetSamples().begin();
1289 for(; it!=channel.GetSamples().end(); ++it) {
1290
1291 //ES// string overallSystName = it->name+"_"+it->channel+"_epsilon";
1292 Sample& sample = (*it);
1293 string overallSystName = sample.GetName() + "_" + channel_name + "_epsilon";
1294
1295 string systSourcePrefix = "alpha_";
1296
1297 // constraintTermNames and totSystTermNames are vectors that are passed
1298 // by reference and filled by this method
1299 AddConstraintTerms(proto,measurement, systSourcePrefix, overallSystName,
1300 sample.GetOverallSysList(), constraintTermNames , totSystTermNames);
1301
1302 // GHL: Consider passing the NormFactor list instead of the entire sample
1303 overallSystName = AddNormFactor(proto, channel_name, overallSystName, sample, doRatio);
1304
1305 // Create the string for the object
1306 // that is added to the RooRealSumPdf
1307 // for this channel
1308 string syst_x_expectedPrefix = "";
1309
1310 // get histogram
1311 //ES// TH1* nominal = it->nominal;
1312 TH1* nominal = sample.GetHisto();
1313
1314 // MB : HACK no option to have both non-hist variations and hist variations ?
1315 // get histogram
1316 // GHL: Okay, this is going to be non-trivial.
1317 // We will loop over histosys's, which contain both
1318 // the low hist and the high hist together.
1319
1320 // Logic:
1321 // - If we have no HistoSys's, do part A
1322 // - else, if the histo syst's don't match, return (we ignore this case)
1323 // - finally, we take the syst's and apply the linear interpolation w/ constraint
1324
1325 if(sample.GetHistoSysList().size() == 0) {
1326
1327 // If no HistoSys
1328 cout << sample.GetName() + "_" + channel_name + " has no variation histograms " << endl;
1329 string expPrefix = sample.GetName() + "_" + channel_name; //+"_expN";
1330 syst_x_expectedPrefix = sample.GetName() + "_" + channel_name + "_overallSyst_x_Exp";
1331
1332 ProcessExpectedHisto(sample.GetHisto(), proto, expPrefix, syst_x_expectedPrefix,
1333 overallSystName);
1334 }
1335 else {
1336 // If there ARE HistoSys(s)
1337 // name of source for variation
1338 string constraintPrefix = sample.GetName() + "_" + channel_name + "_Hist_alpha";
1339 syst_x_expectedPrefix = sample.GetName() + "_" + channel_name + "_overallSyst_x_HistSyst";
1340 // constraintTermNames are passed by reference and appended to,
1341 // overallSystName is a std::string for this sample
1342
1344 constraintPrefix, syst_x_expectedPrefix, overallSystName,
1345 constraintTermNames);
1346 }
1347
1348 ////////////////////////////////////
1349 // Add StatErrors to this Channel //
1350 ////////////////////////////////////
1351
1352 if( sample.GetStatError().GetActivate() ) {
1353
1354 if( fObsNameVec.size() > 3 ) {
1355 std::cout << "Cannot include Stat Error for histograms of more than 3 dimensions."
1356 << std::endl;
1357 throw hf_exc();
1358 } else {
1359
1360 // If we are using StatUncertainties, we multiply this object
1361 // by the ParamHistFunc and then pass that to the
1362 // RooRealSumPdf by appending it's name to the list
1363
1364 std::cout << "Sample: " << sample.GetName() << " to be included in Stat Error "
1365 << "for channel " << channel_name
1366 << std::endl;
1367
1368 /*
1369 Constraint::Type type = channel.GetStatErrorConfig().GetConstraintType();
1370 statConstraintType = Constraint::Gaussian;
1371 if( type == Constraint::Gaussian) {
1372 std::cout << "Using Gaussian StatErrors" << std::endl;
1373 statConstraintType = Constraint::Gaussian;
1374 }
1375 if( type == Constraint::Poisson ) {
1376 std::cout << "Using Poisson StatErrors" << std::endl;
1377 statConstraintType = Constraint::Poisson;
1378 }
1379 */
1380
1381 //statRelErrorThreshold = channel.GetStatErrorConfig().GetRelErrorThreshold();
1382
1383 // First, get the uncertainty histogram
1384 // and push it back to our vectors
1385
1386 //if( sample.GetStatError().GetErrorHist() ) {
1387 //statErrorHist = (TH1*) sample.GetStatError().GetErrorHist()->Clone();
1388 //}
1389 //if( statErrorHist == NULL ) {
1390
1391 // We need to get the *ABSOLUTE* uncertainty for use in Stat Uncertainties
1392 // This can be done in one of two ways:
1393 // - Use the built-in Errors in the TH1 itself (they are aboslute)
1394 // - Take the supplied *RELATIVE* error and multiply by the nominal
1395 string UncertName = syst_x_expectedPrefix + "_StatAbsolUncert";
1396 TH1* statErrorHist = NULL;
1397
1398 if( sample.GetStatError().GetErrorHist() == NULL ) {
1399 // Make the absolute stat error
1400 std::cout << "Making Statistical Uncertainty Hist for "
1401 << " Channel: " << channel_name
1402 << " Sample: " << sample.GetName()
1403 << std::endl;
1404 statErrorHist = MakeAbsolUncertaintyHist( UncertName, nominal );
1405 } else {
1406 // clone the error histograms because in case the sample has not error hist
1407 // it is created in MakeAbsolUncertainty
1408 // we need later to clean statErrorHist
1409 statErrorHist = (TH1*) sample.GetStatError().GetErrorHist()->Clone();
1410 // We assume the (relative) error is provided.
1411 // We must turn it into an absolute error
1412 // using the nominal histogram
1413 std::cout << "Using external histogram for Stat Errors for "
1414 << " Channel: " << channel_name
1415 << " Sample: " << sample.GetName()
1416 << std::endl;
1417 std::cout << "Error Histogram: " << statErrorHist->GetName() << std::endl;
1418 // Multiply the relative stat uncertainty by the
1419 // nominal to get the overall stat uncertainty
1420 statErrorHist->Multiply( nominal );
1421 statErrorHist->SetName( UncertName.c_str() );
1422 }
1423
1424 // Save the nominal and error hists
1425 // for the building of constraint terms
1426 statHistPairs.push_back( pair<TH1*,TH1*>(nominal, statErrorHist) );
1427
1428 // To do the 'conservative' version, we would need to do some
1429 // intervention here. We would probably need to create a different
1430 // ParamHistFunc for each sample in the channel. The would nominally
1431 // use the same gamma's, so we haven't increased the number of parameters
1432 // However, if a bin in the 'nominal' histogram is 0, we simply need to
1433 // change the parameter in that bin in the ParamHistFunc for this sample.
1434 // We also need to add a constraint term.
1435 // Actually, we'd probably not use the ParamHistFunc...?
1436 // we could remove the dependence in this ParamHistFunc on the ith gamma
1437 // and then create the poisson term: Pois(tau | n_exp)Pois(data | n_exp)
1438
1439
1440 // Next, try to get the ParamHistFunc (it may have been
1441 // created by another sample in this channel)
1442 // or create it if it doesn't yet exist:
1443 statFuncName = "mc_stat_" + channel_name;
1444 ParamHistFunc* paramHist = (ParamHistFunc*) proto->function( statFuncName.c_str() );
1445 if( paramHist == NULL ) {
1446
1447 // Get a RooArgSet of the observables:
1448 // Names in the list fObsNameVec:
1449 RooArgList observables;
1450 std::vector<std::string>::iterator itr = fObsNameVec.begin();
1451 for (int idx=0; itr!=fObsNameVec.end(); ++itr, ++idx ) {
1452 observables.add( *proto->var(itr->c_str()) );
1453 }
1454
1455 // Create the list of terms to
1456 // control the bin heights:
1457 std::string ParamSetPrefix = "gamma_stat_" + channel_name;
1458 Double_t gammaMin = 0.0;
1459 Double_t gammaMax = 10.0;
1460 RooArgList statFactorParams = ParamHistFunc::createParamSet(*proto,
1461 ParamSetPrefix.c_str(),
1462 observables,
1463 gammaMin, gammaMax);
1464
1465 ParamHistFunc statUncertFunc(statFuncName.c_str(), statFuncName.c_str(),
1466 observables, statFactorParams );
1467
1468 proto->import( statUncertFunc, RecycleConflictNodes() );
1469
1470 paramHist = (ParamHistFunc*) proto->function( statFuncName.c_str() );
1471
1472 } // END: If Statement: Create ParamHistFunc
1473
1474 // Create the node as a product
1475 // of this function and the
1476 // expected value from MC
1477 statNodeName = sample.GetName() + "_" + channel_name + "_overallSyst_x_StatUncert";
1478
1479 RooAbsReal* expFunc = (RooAbsReal*) proto->function( syst_x_expectedPrefix.c_str() );
1480 RooProduct nodeWithMcStat(statNodeName.c_str(), statNodeName.c_str(),
1481 RooArgSet(*paramHist, *expFunc) );
1482
1483 proto->import( nodeWithMcStat, RecycleConflictNodes() );
1484
1485 // Push back the final name of the node
1486 // to be used in the RooRealSumPdf
1487 // (node to be created later)
1488 syst_x_expectedPrefix = nodeWithMcStat.GetName();
1489
1490 }
1491 } // END: if DoMcStat
1492
1493
1494 ///////////////////////////////////////////
1495 // Create a ShapeFactor for this channel //
1496 ///////////////////////////////////////////
1497
1498 if( sample.GetShapeFactorList().size() > 0 ) {
1499
1500 if( fObsNameVec.size() > 3 ) {
1501 std::cout << "Cannot include Stat Error for histograms of more than 3 dimensions."
1502 << std::endl;
1503 throw hf_exc();
1504 } else {
1505
1506 std::cout << "Sample: " << sample.GetName() << " in channel: " << channel_name
1507 << " to be include a ShapeFactor."
1508 << std::endl;
1509
1510 std::vector<ParamHistFunc*> paramHistFuncList;
1511 std::vector<std::string> shapeFactorNameList;
1512
1513 for(unsigned int i=0; i < sample.GetShapeFactorList().size(); ++i) {
1514
1515 ShapeFactor& shapeFactor = sample.GetShapeFactorList().at(i);
1516
1517 std::string funcName = channel_name + "_" + shapeFactor.GetName() + "_shapeFactor";
1518 ParamHistFunc* paramHist = (ParamHistFunc*) proto->function( funcName.c_str() );
1519 if( paramHist == NULL ) {
1520
1521 RooArgList observables;
1522 std::vector<std::string>::iterator itr = fObsNameVec.begin();
1523 for (int idx=0; itr!=fObsNameVec.end(); ++itr, ++idx ) {
1524 observables.add( *proto->var(itr->c_str()) );
1525 }
1526
1527 // Create the Parameters
1528 std::string funcParams = "gamma_" + shapeFactor.GetName();
1529
1530 // GHL: Again, we are putting hard ranges on the gamma's
1531 // We should change this to range from 0 to /inf
1532 RooArgList shapeFactorParams = ParamHistFunc::createParamSet(*proto,
1533 funcParams.c_str(),
1534 observables, 0, 1000);
1535
1536 // Create the Function
1537 ParamHistFunc shapeFactorFunc( funcName.c_str(), funcName.c_str(),
1538 observables, shapeFactorParams );
1539
1540 // Set an initial shape, if requested
1541 if( shapeFactor.GetInitialShape() != NULL ) {
1542 TH1* initialShape = shapeFactor.GetInitialShape();
1543 std::cout << "Setting Shape Factor: " << shapeFactor.GetName()
1544 << " to have initial shape from hist: "
1545 << initialShape->GetName()
1546 << std::endl;
1547 shapeFactorFunc.setShape( initialShape );
1548 }
1549
1550 // Set the variables constant, if requested
1551 if( shapeFactor.IsConstant() ) {
1552 std::cout << "Setting Shape Factor: " << shapeFactor.GetName()
1553 << " to be constant" << std::endl;
1554 shapeFactorFunc.setConstant(true);
1555 }
1556
1557 proto->import( shapeFactorFunc, RecycleConflictNodes() );
1558 paramHist = (ParamHistFunc*) proto->function( funcName.c_str() );
1559
1560 } // End: Create ShapeFactor ParamHistFunc
1561
1562 paramHistFuncList.push_back(paramHist);
1563 shapeFactorNameList.push_back(funcName);
1564
1565 } // End loop over ShapeFactor Systematics
1566
1567 // Now that we have the right ShapeFactor,
1568 // we multiply the expected function
1569
1570 //std::string shapeFactorNodeName = syst_x_expectedPrefix + "_x_" + funcName;
1571 // Dynamically build the name as a long product
1572 std::string shapeFactorNodeName = syst_x_expectedPrefix;
1573 for( unsigned int i=0; i < shapeFactorNameList.size(); ++i) {
1574 shapeFactorNodeName += "_x_" + shapeFactorNameList.at(i);
1575 }
1576
1577 RooAbsReal* expFunc = (RooAbsReal*) proto->function( syst_x_expectedPrefix.c_str() );
1578 RooArgSet nodesForProduct(*expFunc);
1579 for( unsigned int i=0; i < paramHistFuncList.size(); ++i) {
1580 nodesForProduct.add( *paramHistFuncList.at(i) );
1581 }
1582 //RooProduct nodeWithShapeFactor(shapeFactorNodeName.c_str(),
1583 // shapeFactorNodeName.c_str(),
1584 //RooArgSet(*paramHist, *expFunc) );
1585 RooProduct nodeWithShapeFactor(shapeFactorNodeName.c_str(),
1586 shapeFactorNodeName.c_str(),
1587 nodesForProduct );
1588
1589 proto->import( nodeWithShapeFactor, RecycleConflictNodes() );
1590
1591 // Push back the final name of the node
1592 // to be used in the RooRealSumPdf
1593 // (node to be created later)
1594 syst_x_expectedPrefix = nodeWithShapeFactor.GetName();
1595
1596 }
1597 } // End: if ShapeFactorName!=""
1598
1599
1600 ////////////////////////////////////////
1601 // Create a ShapeSys for this channel //
1602 ////////////////////////////////////////
1603
1604 if( sample.GetShapeSysList().size() != 0 ) {
1605
1606 if( fObsNameVec.size() > 3 ) {
1607 std::cout << "Cannot include Stat Error for histograms of more than 3 dimensions."
1608 << std::endl;
1609 throw hf_exc();
1610 } else {
1611
1612 // List of ShapeSys ParamHistFuncs
1613 std::vector<string> ShapeSysNames;
1614
1615 for( unsigned int i = 0; i < sample.GetShapeSysList().size(); ++i) {
1616
1617 // Create the ParamHistFunc's
1618 // Create their constraint terms and add them
1619 // to the list of constraint terms
1620
1621 // Create a single RooProduct over all of these
1622 // paramHistFunc's
1623
1624 // Send the name of that product to the RooRealSumPdf
1625
1626 RooStats::HistFactory::ShapeSys& shapeSys = sample.GetShapeSysList().at(i);
1627
1628 std::cout << "Sample: " << sample.GetName() << " in channel: " << channel_name
1629 << " to include a ShapeSys." << std::endl;
1630
1631 std::string funcName = channel_name + "_" + shapeSys.GetName() + "_ShapeSys";
1632 ShapeSysNames.push_back( funcName );
1633 ParamHistFunc* paramHist = (ParamHistFunc*) proto->function( funcName.c_str() );
1634 if( paramHist == NULL ) {
1635
1636 //std::string funcParams = "gamma_" + it->shapeFactorName;
1637 //paramHist = CreateParamHistFunc( proto, fObsNameVec, funcParams, funcName );
1638
1639 RooArgList observables;
1640 std::vector<std::string>::iterator itr = fObsNameVec.begin();
1641 for(; itr!=fObsNameVec.end(); ++itr ) {
1642 observables.add( *proto->var(itr->c_str()) );
1643 }
1644
1645 // Create the Parameters
1646 std::string funcParams = "gamma_" + shapeSys.GetName();
1647 RooArgList shapeFactorParams = ParamHistFunc::createParamSet(*proto,
1648 funcParams.c_str(),
1649 observables, 0, 10);
1650
1651 // Create the Function
1652 ParamHistFunc shapeFactorFunc( funcName.c_str(), funcName.c_str(),
1653 observables, shapeFactorParams );
1654
1655 proto->import( shapeFactorFunc, RecycleConflictNodes() );
1656 paramHist = (ParamHistFunc*) proto->function( funcName.c_str() );
1657
1658 } // End: Create ShapeFactor ParamHistFunc
1659
1660 // Create the constraint terms and add
1661 // them to the workspace (proto)
1662 // as well as the list of constraint terms (constraintTermNames)
1663
1664 // The syst should be a fractional error
1665 TH1* shapeErrorHist = shapeSys.GetErrorHist();
1666
1667 // Constraint::Type shapeConstraintType = Constraint::Gaussian;
1668 Constraint::Type systype = shapeSys.GetConstraintType();
1669 if( systype == Constraint::Gaussian) {
1670 systype = Constraint::Gaussian;
1671 }
1672 if( systype == Constraint::Poisson ) {
1673 systype = Constraint::Poisson;
1674 }
1675
1676 Double_t minShapeUncertainty = 0.0;
1677 RooArgList shapeConstraints = createStatConstraintTerms(proto, constraintTermNames,
1678 *paramHist, shapeErrorHist,
1679 systype,
1680 minShapeUncertainty);
1681
1682 } // End: Loop over ShapeSys vector in this EstimateSummary
1683
1684 // Now that we have the list of ShapeSys ParamHistFunc names,
1685 // we create the total RooProduct
1686 // we multiply the expected functio
1687
1688 std::string NodeName = syst_x_expectedPrefix;
1689 RooArgList ShapeSysForNode;
1690 RooAbsReal* expFunc = (RooAbsReal*) proto->function( syst_x_expectedPrefix.c_str() );
1691 ShapeSysForNode.add( *expFunc );
1692 for( unsigned int i = 0; i < ShapeSysNames.size(); ++i ) {
1693 std::string ShapeSysName = ShapeSysNames.at(i);
1694 ShapeSysForNode.add( *proto->function(ShapeSysName.c_str()) );
1695 NodeName = NodeName + "_x_" + ShapeSysName;
1696 }
1697
1698 // Create the name for this NEW Node
1699 RooProduct nodeWithShapeFactor(NodeName.c_str(), NodeName.c_str(), ShapeSysForNode );
1700 proto->import( nodeWithShapeFactor, RecycleConflictNodes() );
1701
1702 // Push back the final name of the node
1703 // to be used in the RooRealSumPdf
1704 // (node to be created later)
1705 syst_x_expectedPrefix = nodeWithShapeFactor.GetName();
1706
1707 } // End: NumObsVar == 1
1708
1709 } // End: GetShapeSysList.size() != 0
1710
1711 // Append the name of the "node"
1712 // that is to be summed with the
1713 // RooRealSumPdf
1714 syst_x_expectedPrefixNames.push_back(syst_x_expectedPrefix);
1715
1716 // GHL: This was pretty confusing before,
1717 // hopefully using the measurement directly
1718 // will improve it
1719 if( sample.GetNormalizeByTheory() ) {
1720 normalizationNames.push_back( "Lumi" );
1721 }
1722 else {
1723 TString lumiParamString;
1724 lumiParamString += measurement.GetLumi();
1725 lumiParamString.ReplaceAll(' ', TString());
1726 normalizationNames.push_back(lumiParamString.Data());
1727 }
1728
1729 } // END: Loop over EstimateSummaries
1730 // proto->Print();
1731
1732 // If a non-zero number of samples call for
1733 // Stat Uncertainties, create the statFactor functions
1734 if( statHistPairs.size() > 0 ) {
1735
1736 // Create the histogram of (binwise)
1737 // stat uncertainties:
1738 TH1* fracStatError = MakeScaledUncertaintyHist( statNodeName + "_RelErr", statHistPairs );
1739 if( fracStatError == NULL ) {
1740 std::cout << "Error: Failed to make ScaledUncertaintyHist for: "
1741 << statNodeName << std::endl;
1742 throw hf_exc();
1743 }
1744
1745 // Using this TH1* of fractinal stat errors,
1746 // create a set of constraint terms:
1747 ParamHistFunc* chanStatUncertFunc = (ParamHistFunc*) proto->function( statFuncName.c_str() );
1748 std::cout << "About to create Constraint Terms from: "
1749 << chanStatUncertFunc->GetName()
1750 << " params: " << chanStatUncertFunc->paramList()
1751 << std::endl;
1752
1753 // Get the constraint type and the
1754 // rel error threshold from the (last)
1755 // EstimateSummary looped over (but all
1756 // should be the same)
1757
1758 // Get the type of StatError constraint from the channel
1759 Constraint::Type statConstraintType = channel.GetStatErrorConfig().GetConstraintType();
1760 if( statConstraintType == Constraint::Gaussian) {
1761 std::cout << "Using Gaussian StatErrors in channel: " << channel.GetName() << std::endl;
1762 }
1763 if( statConstraintType == Constraint::Poisson ) {
1764 std::cout << "Using Poisson StatErrors in channel: " << channel.GetName() << std::endl;
1765 }
1766
1767 double statRelErrorThreshold = channel.GetStatErrorConfig().GetRelErrorThreshold();
1768 RooArgList statConstraints = createStatConstraintTerms(proto, constraintTermNames,
1769 *chanStatUncertFunc, fracStatError,
1770 statConstraintType,
1771 statRelErrorThreshold);
1772
1773
1774 // clean stat hist pair (need to delete second histogram)
1775 for (unsigned int i = 0; i < statHistPairs.size() ; ++i )
1776 delete statHistPairs[i].second;
1777
1778 statHistPairs.clear();
1779 //delete also histogram of stat uncertainties created in MakeScaledUncertaintyHist
1780 delete fracStatError;
1781
1782 } // END: Loop over stat Hist Pairs
1783
1784
1785 ///////////////////////////////////
1786 // for ith bin calculate totN_i = lumi * sum_j expected_j * syst_j
1787 //MakeTotalExpected(proto,channel_name+"_model",channel_name,"Lumi",fLowBin,fHighBin,
1788 // syst_x_expectedPrefixNames, normalizationNames);
1789 MakeTotalExpected(proto, channel_name+"_model", //channel_name,"Lumi",fLowBin,fHighBin,
1790 syst_x_expectedPrefixNames, normalizationNames);
1791 likelihoodTermNames.push_back(channel_name+"_model");
1792
1793 //////////////////////////////////////
1794 // fix specified parameters
1795 for(unsigned int i=0; i<systToFix.size(); ++i){
1796 RooRealVar* temp = proto->var((systToFix.at(i)).c_str());
1797 if(temp) {
1798 // set the parameter constant
1799 temp->setConstant();
1800
1801 // remove the corresponding auxiliary observable from the global observables
1802 RooRealVar* auxMeas = NULL;
1803 if(systToFix.at(i)=="Lumi"){
1804 auxMeas = proto->var("nominalLumi");
1805 } else {
1806 auxMeas = proto->var(TString::Format("nom_%s",temp->GetName()));
1807 }
1808
1809 if(auxMeas){
1810 const_cast<RooArgSet*>(proto->set("globalObservables"))->remove(*auxMeas);
1811 } else{
1812 cout << "could not corresponding auxiliary measurement "
1813 << TString::Format("nom_%s",temp->GetName()) << endl;
1814 }
1815 } else {
1816 cout << "could not find variable " << systToFix.at(i)
1817 << " could not set it to constant" << endl;
1818 }
1819 }
1820
1821 //////////////////////////////////////
1822 // final proto model
1823 for(unsigned int i=0; i<constraintTermNames.size(); ++i){
1824 RooAbsArg* proto_arg = (proto->arg(constraintTermNames[i].c_str()));
1825 if( proto_arg==NULL ) {
1826 std::cout << "Error: Cannot find arg set: " << constraintTermNames.at(i)
1827 << " in workspace: " << proto->GetName() << std::endl;
1828 throw hf_exc();
1829 }
1830 constraintTerms.add( *proto_arg );
1831 // constraintTerms.add(* proto_arg(proto->arg(constraintTermNames[i].c_str())) );
1832 }
1833 for(unsigned int i=0; i<likelihoodTermNames.size(); ++i){
1834 RooAbsArg* proto_arg = (proto->arg(likelihoodTermNames[i].c_str()));
1835 if( proto_arg==NULL ) {
1836 std::cout << "Error: Cannot find arg set: " << likelihoodTermNames.at(i)
1837 << " in workspace: " << proto->GetName() << std::endl;
1838 throw hf_exc();
1839 }
1840 likelihoodTerms.add( *proto_arg );
1841 }
1842 proto->defineSet("constraintTerms",constraintTerms);
1843 proto->defineSet("likelihoodTerms",likelihoodTerms);
1844 // proto->Print();
1845
1846 // list of observables
1847 RooArgList observables;
1848 std::string observablesStr;
1849
1850 std::vector<std::string>::iterator itr = fObsNameVec.begin();
1851 for(; itr!=fObsNameVec.end(); ++itr ) {
1852 observables.add( *proto->var(itr->c_str()) );
1853 if (!observablesStr.empty()) { observablesStr += ","; }
1854 observablesStr += *itr;
1855 }
1856
1857 // We create two sets, one for backwards compatability
1858 // The other to make a consistent naming convention
1859 // between individual channels and the combined workspace
1860 proto->defineSet("observables", TString::Format("%s",observablesStr.c_str()));
1861 proto->defineSet("observablesSet", TString::Format("%s",observablesStr.c_str()));
1862
1863 // Create the ParamHistFunc
1864 // after observables have been made
1865 cout <<"-----------------------------------------"<<endl;
1866 cout <<"import model into workspace" << endl;
1867
1868 auto model = make_unique<RooProdPdf>(
1869 ("model_"+channel_name).c_str(), // MB : have changed this into conditional pdf. Much faster for toys!
1870 "product of Poissons accross bins for a single channel",
1871 constraintTerms, Conditional(likelihoodTerms,observables));
1872 proto->import(*model,RecycleConflictNodes());
1873
1874 proto_config->SetPdf(*model);
1875 proto_config->SetObservables(observables);
1876 proto_config->SetGlobalObservables(*proto->set("globalObservables"));
1877 // proto->writeToFile(("results/model_"+channel+".root").c_str());
1878 // fill out nuisance parameters in model config
1879 // proto_config->GuessObsAndNuisance(*proto->data("asimovData"));
1880 proto->import(*proto_config,proto_config->GetName());
1881 proto->importClassCode();
1882
1883 ///////////////////////////
1884 // make data sets
1885 // THis works and is natural, but the memory size of the simultaneous dataset grows exponentially with channels
1886 const char* weightName="weightVar";
1887 proto->factory(TString::Format("%s[0,-1e10,1e10]",weightName));
1888 proto->defineSet("obsAndWeight",TString::Format("%s,%s",weightName,observablesStr.c_str()));
1889
1890 /* Old code for generating the asimov
1891 Asimov generation is now done later...
1892
1893 RooAbsData* asimov_data = model->generateBinned(observables,ExpectedData());
1894
1895 /// Asimov dataset
1896 RooDataSet* asimovDataUnbinned = new RooDataSet("asimovData","",*proto->set("obsAndWeight"),weightName);
1897 for(int i=0; i<asimov_data->numEntries(); ++i){
1898 asimov_data->get(i)->Print("v");
1899 //cout << "GREPME : " << i << " " << data->weight() <<endl;
1900 asimovDataUnbinned->add( *asimov_data->get(i), asimov_data->weight() );
1901 }
1902 proto->import(*asimovDataUnbinned);
1903 */
1904
1905 // New Asimov Generation: Use the code in the Asymptotic calculator
1906 // Need to get the ModelConfig...
1907 unique_ptr<RooAbsData> asimov_dataset(AsymptoticCalculator::GenerateAsimovData(*model, observables));
1908 proto->import(dynamic_cast<RooDataSet&>(*asimov_dataset), Rename("asimovData"));
1909
1910 // GHL: Determine to use data if the hist isn't 'NULL'
1911 if(channel.GetData().GetHisto() != NULL) {
1912
1913 Data& data = channel.GetData();
1914 TH1* mnominal = data.GetHisto();
1915 if( !mnominal ) {
1916 std::cout << "Error: Data histogram for channel: " << channel.GetName()
1917 << " is NULL" << std::endl;
1918 throw hf_exc();
1919 }
1920
1921 // THis works and is natural, but the memory size of the simultaneous dataset grows exponentially with channels
1922 auto obsDataUnbinned = make_unique<RooDataSet>("obsData","",*proto->set("obsAndWeight"),weightName);
1923
1924
1925 ConfigureHistFactoryDataset( obsDataUnbinned.get(), mnominal,
1926 proto, fObsNameVec );
1927
1928 /*
1929 //ES// TH1* mnominal = summary.at(0).nominal;
1930 TH1* mnominal = data.GetHisto();
1931 TAxis* ax = mnominal->GetXaxis();
1932 TAxis* ay = mnominal->GetYaxis();
1933 TAxis* az = mnominal->GetZaxis();
1934
1935 for (int i=1; i<=ax->GetNbins(); ++i) { // 1 or more dimension
1936 Double_t xval = ax->GetBinCenter(i);
1937 proto->var( fObsNameVec[0].c_str() )->setVal( xval );
1938 if (fObsNameVec.size()==1) {
1939 Double_t fval = mnominal->GetBinContent(i);
1940 obsDataUnbinned->add( *proto->set("obsAndWeight"), fval );
1941 } else { // 2 or more dimensions
1942 for (int j=1; j<=ay->GetNbins(); ++j) {
1943 Double_t yval = ay->GetBinCenter(j);
1944 proto->var( fObsNameVec[1].c_str() )->setVal( yval );
1945 if (fObsNameVec.size()==2) {
1946 Double_t fval = mnominal->GetBinContent(i,j);
1947 obsDataUnbinned->add( *proto->set("obsAndWeight"), fval );
1948 } else { // 3 dimensions
1949 for (int k=1; k<=az->GetNbins(); ++k) {
1950 Double_t zval = az->GetBinCenter(k);
1951 proto->var( fObsNameVec[2].c_str() )->setVal( zval );
1952 Double_t fval = mnominal->GetBinContent(i,j,k);
1953 obsDataUnbinned->add( *proto->set("obsAndWeight"), fval );
1954 }
1955 }
1956 }
1957 }
1958 }
1959 */
1960
1961 proto->import(*obsDataUnbinned);
1962 } // End: Has non-null 'data' entry
1963
1964
1965 for(unsigned int i=0; i < channel.GetAdditionalData().size(); ++i) {
1966
1967 Data& data = channel.GetAdditionalData().at(i);
1968 std::string dataName = data.GetName();
1969 TH1* mnominal = data.GetHisto();
1970 if( !mnominal ) {
1971 std::cout << "Error: Additional Data histogram for channel: " << channel.GetName()
1972 << " with name: " << dataName << " is NULL" << std::endl;
1973 throw hf_exc();
1974 }
1975
1976 // THis works and is natural, but the memory size of the simultaneous dataset grows exponentially with channels
1977 auto obsDataUnbinned = make_unique<RooDataSet>(dataName.c_str(), dataName.c_str(),
1978 *proto->set("obsAndWeight"), weightName);
1979
1980 ConfigureHistFactoryDataset( obsDataUnbinned.get(), mnominal,
1981 proto, fObsNameVec );
1982
1983 /*
1984 //ES// TH1* mnominal = summary.at(0).nominal;
1985 TH1* mnominal = data.GetHisto();
1986 TAxis* ax = mnominal->GetXaxis();
1987 TAxis* ay = mnominal->GetYaxis();
1988 TAxis* az = mnominal->GetZaxis();
1989
1990 for (int i=1; i<=ax->GetNbins(); ++i) { // 1 or more dimension
1991 Double_t xval = ax->GetBinCenter(i);
1992 proto->var( fObsNameVec[0].c_str() )->setVal( xval );
1993 if (fObsNameVec.size()==1) {
1994 Double_t fval = mnominal->GetBinContent(i);
1995 obsDataUnbinned->add( *proto->set("obsAndWeight"), fval );
1996 } else { // 2 or more dimensions
1997 for (int j=1; j<=ay->GetNbins(); ++j) {
1998 Double_t yval = ay->GetBinCenter(j);
1999 proto->var( fObsNameVec[1].c_str() )->setVal( yval );
2000 if (fObsNameVec.size()==2) {
2001 Double_t fval = mnominal->GetBinContent(i,j);
2002 obsDataUnbinned->add( *proto->set("obsAndWeight"), fval );
2003 } else { // 3 dimensions
2004 for (int k=1; k<=az->GetNbins(); ++k) {
2005 Double_t zval = az->GetBinCenter(k);
2006 proto->var( fObsNameVec[2].c_str() )->setVal( zval );
2007 Double_t fval = mnominal->GetBinContent(i,j,k);
2008 obsDataUnbinned->add( *proto->set("obsAndWeight"), fval );
2009 }
2010 }
2011 }
2012 }
2013 }
2014 */
2015
2016 proto->import(*obsDataUnbinned);
2017
2018 } // End: Has non-null 'data' entry
2019
2020 proto->Print();
2021 return proto;
2022 }
2023
2024
2026 TH1* mnominal,
2028 std::vector<std::string> ObsNameVec) {
2029
2030 // Take a RooDataSet and fill it with the entries
2031 // from a TH1*, using the observable names to
2032 // determine the columns
2033
2034 if (ObsNameVec.empty() ) {
2035 Error("ConfigureHistFactoryDataset","Invalid input - return");
2036 return;
2037 }
2038
2039 //ES// TH1* mnominal = summary.at(0).nominal;
2040 // TH1* mnominal = data.GetHisto();
2041 TAxis* ax = mnominal->GetXaxis();
2042 TAxis* ay = mnominal->GetYaxis();
2043 TAxis* az = mnominal->GetZaxis();
2044
2045 for (int i=1; i<=ax->GetNbins(); ++i) { // 1 or more dimension
2046
2047 Double_t xval = ax->GetBinCenter(i);
2048 proto->var( ObsNameVec[0].c_str() )->setVal( xval );
2049
2050 if(ObsNameVec.size()==1) {
2051 Double_t fval = mnominal->GetBinContent(i);
2052 obsDataUnbinned->add( *proto->set("obsAndWeight"), fval );
2053 } else { // 2 or more dimensions
2054
2055 for(int j=1; j<=ay->GetNbins(); ++j) {
2056 Double_t yval = ay->GetBinCenter(j);
2057 proto->var( ObsNameVec[1].c_str() )->setVal( yval );
2058
2059 if(ObsNameVec.size()==2) {
2060 Double_t fval = mnominal->GetBinContent(i,j);
2061 obsDataUnbinned->add( *proto->set("obsAndWeight"), fval );
2062 } else { // 3 dimensions
2063
2064 for(int k=1; k<=az->GetNbins(); ++k) {
2065 Double_t zval = az->GetBinCenter(k);
2066 proto->var( ObsNameVec[2].c_str() )->setVal( zval );
2067 Double_t fval = mnominal->GetBinContent(i,j,k);
2068 obsDataUnbinned->add( *proto->set("obsAndWeight"), fval );
2069 }
2070 }
2071 }
2072 }
2073 }
2074 }
2075
2077 {
2078 fObsNameVec.clear();
2079
2080 // determine histogram dimensionality
2081 unsigned int histndim(1);
2082 std::string classname = hist->ClassName();
2083 if (classname.find("TH1")==0) { histndim=1; }
2084 else if (classname.find("TH2")==0) { histndim=2; }
2085 else if (classname.find("TH3")==0) { histndim=3; }
2086
2087 for ( unsigned int idx=0; idx<histndim; ++idx ) {
2088 if (idx==0) { fObsNameVec.push_back("x"); }
2089 if (idx==1) { fObsNameVec.push_back("y"); }
2090 if (idx==2) { fObsNameVec.push_back("z"); }
2091 }
2092 }
2093
2094
2095 RooWorkspace* HistoToWorkspaceFactoryFast::MakeCombinedModel(vector<string> ch_names, vector<RooWorkspace*> chs)
2096 {
2097
2098
2099 // check first the inputs (see JIRA-6890)
2100 if (ch_names.empty() || chs.empty() ) {
2101 Error("MakeCombinedModel","Input vectors are empty - return a nullptr");
2102 return 0;
2103 }
2104 if (chs.size() < ch_names.size() ) {
2105 Error("MakeCombinedModel","Input vector of workspace has an invalid size - return a nullptr");
2106 return 0;
2107 }
2108
2109 //
2110 /// These things were used for debugging. Maybe useful in the future
2111 //
2112
2113 map<string, RooAbsPdf*> pdfMap;
2114 vector<RooAbsPdf*> models;
2115 stringstream ss;
2116
2117 RooArgList obsList;
2118 for(unsigned int i = 0; i< ch_names.size(); ++i){
2119 ModelConfig * config = (ModelConfig *) chs[i]->obj("ModelConfig");
2120 obsList.add(*config->GetObservables());
2121 }
2122 cout <<"full list of observables:"<<endl;
2123 obsList.Print();
2124
2125 RooArgSet globalObs;
2126 for(unsigned int i = 0; i< ch_names.size(); ++i){
2127 string channel_name=ch_names[i];
2128
2129 if (ss.str().empty()) ss << channel_name ;
2130 else ss << ',' << channel_name ;
2131 RooWorkspace * ch=chs[i];
2132
2133 RooAbsPdf* model = ch->pdf(("model_"+channel_name).c_str());
2134 if(!model) cout <<"failed to find model for channel"<<endl;
2135 // cout << "int = " << model->createIntegral(*obsN)->getVal() << endl;;
2136 models.push_back(model);
2137 globalObs.add(*ch->set("globalObservables"));
2138
2139 // constrainedParams->add( * ch->set("constrainedParams") );
2140 pdfMap[channel_name]=model;
2141 }
2142 //constrainedParams->Print();
2143
2144 cout << "\n\n------------------\n Entering combination" << endl;
2145 RooWorkspace* combined = new RooWorkspace("combined");
2146 // RooWorkspace* combined = chs[0];
2147
2148
2149 RooCategory* channelCat = (RooCategory*) combined->factory(("channelCat["+ss.str()+"]").c_str());
2150 RooSimultaneous * simPdf= new RooSimultaneous("simPdf","",pdfMap, *channelCat);
2151 ModelConfig * combined_config = new ModelConfig("ModelConfig", combined);
2152 combined_config->SetWorkspace(*combined);
2153 // combined_config->SetNuisanceParameters(*constrainedParams);
2154
2155 combined->import(globalObs);
2156 combined->defineSet("globalObservables",globalObs);
2157 combined_config->SetGlobalObservables(*combined->set("globalObservables"));
2158
2159
2160 ////////////////////////////////////////////
2161 // Make toy simultaneous dataset
2162 cout <<"-----------------------------------------"<<endl;
2163 cout << "create toy data for " << ss.str() << endl;
2164
2165
2166 // now with weighted datasets
2167 // First Asimov
2168 //RooDataSet * simData=NULL;
2169 combined->factory("weightVar[0,-1e10,1e10]");
2170 obsList.add(*combined->var("weightVar"));
2171
2172 // Loop over channels and create the asimov
2173 /*
2174 for(unsigned int i = 0; i< ch_names.size(); ++i){
2175 cout << "merging data for channel " << ch_names[i].c_str() << endl;
2176 RooDataSet * tempData=new RooDataSet(ch_names[i].c_str(),"", obsList, Index(*channelCat),
2177 WeightVar("weightVar"),
2178 Import(ch_names[i].c_str(),*(RooDataSet*)chs[i]->data("asimovData")));
2179 if(simData){
2180 simData->append(*tempData);
2181 delete tempData;
2182 }else{
2183 simData = tempData;
2184 }
2185 }
2186
2187 if (simData) combined->import(*simData,Rename("asimovData"));
2188 */
2189 RooDataSet* asimov_combined = (RooDataSet*) AsymptoticCalculator::GenerateAsimovData(*simPdf,
2190 obsList);
2191 if( asimov_combined ) {
2192 combined->import( *asimov_combined, Rename("asimovData"));
2193 }
2194 else {
2195 std::cout << "Error: Failed to create combined asimov dataset" << std::endl;
2196 throw hf_exc();
2197 }
2198 delete asimov_combined;
2199
2200 // Now merge the observable datasets across the channels
2201 if(chs[0]->data("obsData") != NULL) {
2202 MergeDataSets(combined, chs, ch_names, "obsData", obsList, channelCat);
2203 }
2204
2205 /*
2206 if(chs[0]->data("obsData") != NULL){
2207 RooDataSet * simData=NULL;
2208 //simData=NULL;
2209
2210 // Loop through channels, get their individual datasets,
2211 // and add them to the combined dataset
2212 for(unsigned int i = 0; i< ch_names.size(); ++i){
2213 cout << "merging data for channel " << ch_names[i].c_str() << endl;
2214
2215 RooDataSet* obsDataInChannel = (RooDataSet*) chs[i]->data("obsData");
2216 RooDataSet * tempData = new RooDataSet(ch_names[i].c_str(),"", obsList, Index(*channelCat),
2217 WeightVar("weightVar"),
2218 Import(ch_names[i].c_str(),*obsDataInChannel));
2219 // *(RooDataSet*) chs[i]->data("obsData")));
2220 if(simData) {
2221 simData->append(*tempData);
2222 delete tempData;
2223 }
2224 else {
2225 simData = tempData;
2226 }
2227 } // End Loop Over Channels
2228
2229 // Check that we successfully created the dataset
2230 // and import it into the workspace
2231 if(simData) {
2232 combined->import(*simData, Rename("obsData"));
2233 }
2234 else {
2235 std::cout << "Error: Unable to merge observable datasets" << std::endl;
2236 throw hf_exc();
2237 }
2238
2239 } // End 'if' on data != NULL
2240 */
2241
2242 // Now, create any additional Asimov datasets that
2243 // are configured in the measurement
2244
2245
2246 // obsList.Print();
2247 // combined->import(obsList);
2248 // combined->Print();
2249
2250 obsList.add(*channelCat);
2251 combined->defineSet("observables",obsList);
2252 combined_config->SetObservables(*combined->set("observables"));
2253
2254 combined->Print();
2255
2256 cout << "\n\n----------------\n Importing combined model" << endl;
2257 combined->import(*simPdf,RecycleConflictNodes());
2258 //combined->import(*simPdf, RenameVariable("SigXsecOverSM","SigXsecOverSM_comb"));
2259 // cout << "check pointer " << simPdf << endl;
2260 // cout << "check val " << simPdf->getVal() << endl;
2261
2262 std::map< std::string, double>::iterator param_itr = fParamValues.begin();
2263 for( ; param_itr != fParamValues.end(); ++param_itr ){
2264 // make sure they are fixed
2265 std::string paramName = param_itr->first;
2266 double paramVal = param_itr->second;
2267
2268 RooRealVar* temp = combined->var( paramName.c_str() );
2269 if(temp) {
2270 temp->setVal( paramVal );
2271 cout <<"setting " << paramName << " to the value: " << paramVal << endl;
2272 } else
2273 cout << "could not find variable " << paramName << " could not set its value" << endl;
2274 }
2275
2276
2277 for(unsigned int i=0; i<fSystToFix.size(); ++i){
2278 // make sure they are fixed
2279 RooRealVar* temp = combined->var((fSystToFix.at(i)).c_str());
2280 if(temp) {
2281 temp->setConstant();
2282 cout <<"setting " << fSystToFix.at(i) << " constant" << endl;
2283 } else
2284 cout << "could not find variable " << fSystToFix.at(i) << " could not set it to constant" << endl;
2285 }
2286
2287 ///
2288 /// writing out the model in graphViz
2289 ///
2290 // RooAbsPdf* customized=combined->pdf("simPdf");
2291 //combined_config->SetPdf(*customized);
2292 combined_config->SetPdf(*simPdf);
2293 // combined_config->GuessObsAndNuisance(*simData);
2294 // customized->graphVizTree(("results/"+fResultsPrefixStr.str()+"_simul.dot").c_str());
2295 combined->import(*combined_config,combined_config->GetName());
2296 combined->importClassCode();
2297 // combined->writeToFile("results/model_combined.root");
2298
2299 //clean up
2300 delete combined_config;
2301 delete simPdf;
2302
2303 return combined;
2304 }
2305
2306
2308 std::vector<RooWorkspace*> wspace_vec,
2309 std::vector<std::string> channel_names,
2310 std::string dataSetName,
2311 RooArgList obsList,
2312 RooCategory* channelCat) {
2313
2314 // Create the total dataset
2315 RooDataSet* simData=NULL;
2316
2317 // Loop through channels, get their individual datasets,
2318 // and add them to the combined dataset
2319 for(unsigned int i = 0; i< channel_names.size(); ++i){
2320
2321 // Grab the dataset for the existing channel
2322 std::cout << "Merging data for channel " << channel_names[i].c_str() << std::endl;
2323 RooDataSet* obsDataInChannel = (RooDataSet*) wspace_vec[i]->data(dataSetName.c_str());
2324 if( !obsDataInChannel ) {
2325 std::cout << "Error: Can't find DataSet: " << dataSetName
2326 << " in channel: " << channel_names.at(i)
2327 << std::endl;
2328 throw hf_exc();
2329 }
2330
2331 // Create the new Dataset
2332 RooDataSet * tempData = new RooDataSet(channel_names[i].c_str(),"",
2333 obsList, Index(*channelCat),
2334 WeightVar("weightVar"),
2335 Import(channel_names[i].c_str(),*obsDataInChannel));
2336 if(simData) {
2337 simData->append(*tempData);
2338 delete tempData;
2339 }
2340 else {
2341 simData = tempData;
2342 }
2343 } // End Loop Over Channels
2344
2345 // Check that we successfully created the dataset
2346 // and import it into the workspace
2347 if(simData) {
2348 combined->import(*simData, Rename(dataSetName.c_str()));
2349 delete simData;
2350 simData = (RooDataSet*) combined->data(dataSetName.c_str() );
2351 }
2352 else {
2353 std::cout << "Error: Unable to merge observable datasets" << std::endl;
2354 throw hf_exc();
2355 }
2356
2357 return simData;
2358
2359 }
2360
2361
2363
2364 // Take a nominal TH1* and create
2365 // a TH1 representing the binwise
2366 // errors (taken from the nominal TH1)
2367
2368 TH1* ErrorHist = (TH1*) Nominal->Clone( Name.c_str() );
2369 ErrorHist->Reset();
2370
2371 Int_t numBins = Nominal->GetNbinsX()*Nominal->GetNbinsY()*Nominal->GetNbinsZ();
2372 Int_t binNumber = 0;
2373
2374 // Loop over bins
2375 for( Int_t i_bin = 0; i_bin < numBins; ++i_bin) {
2376
2377 binNumber++;
2378 // Ignore underflow / overflow
2379 while( Nominal->IsBinUnderflow(binNumber) || Nominal->IsBinOverflow(binNumber) ){
2380 binNumber++;
2381 }
2382
2383 Double_t histError = Nominal->GetBinError( binNumber );
2384
2385 // Check that histError != NAN
2386 if( histError != histError ) {
2387 std::cout << "Warning: In histogram " << Nominal->GetName()
2388 << " bin error for bin " << i_bin
2389 << " is NAN. Not using Error!!!"
2390 << std::endl;
2391 throw hf_exc();
2392 //histError = sqrt( histContent );
2393 //histError = 0;
2394 }
2395
2396 // Check that histError ! < 0
2397 if( histError < 0 ) {
2398 std::cout << "Warning: In histogram " << Nominal->GetName()
2399 << " bin error for bin " << binNumber
2400 << " is < 0. Setting Error to 0"
2401 << std::endl;
2402 //histError = sqrt( histContent );
2403 histError = 0;
2404 }
2405
2406 ErrorHist->SetBinContent( binNumber, histError );
2407
2408 }
2409
2410 return ErrorHist;
2411
2412 }
2413
2414 TH1* HistoToWorkspaceFactoryFast::MakeScaledUncertaintyHist( const std::string& Name, std::vector< std::pair<TH1*, TH1*> > HistVec ) {
2415
2416 // Take a list of < nominal, absolError > TH1* pairs
2417 // and construct a single histogram representing the
2418 // total fractional error as:
2419
2420 // UncertInQuad(bin i) = Sum: absolUncert*absolUncert
2421 // Total(bin i) = Sum: Value
2422 //
2423 // TotalFracError(bin i) = Sqrt( UncertInQuad(i) ) / TotalBin(i)
2424
2425
2426 unsigned int numHists = HistVec.size();
2427
2428 if( numHists == 0 ) {
2429 std::cout << "Warning: Empty Hist Vector, cannot create total uncertainty" << std::endl;
2430 return NULL;
2431 }
2432
2433 TH1* HistTemplate = HistVec.at(0).first;
2434 Int_t numBins = HistTemplate->GetNbinsX()*HistTemplate->GetNbinsY()*HistTemplate->GetNbinsZ();
2435
2436 // Check that all histograms
2437 // have the same bins
2438 for( unsigned int i = 0; i < HistVec.size(); ++i ) {
2439
2440 TH1* nominal = HistVec.at(i).first;
2441 TH1* error = HistVec.at(i).second;
2442
2443 if( nominal->GetNbinsX()*nominal->GetNbinsY()*nominal->GetNbinsZ() != numBins ) {
2444 std::cout << "Error: Provided hists have unequal bins" << std::endl;
2445 return NULL;
2446 }
2447 if( error->GetNbinsX()*error->GetNbinsY()*error->GetNbinsZ() != numBins ) {
2448 std::cout << "Error: Provided hists have unequal bins" << std::endl;
2449 return NULL;
2450 }
2451 }
2452
2453 std::vector<double> TotalBinContent( numBins, 0.0);
2454 std::vector<double> HistErrorsSqr( numBins, 0.0);
2455
2456 Int_t binNumber = 0;
2457
2458 // Loop over bins
2459 for( Int_t i_bins = 0; i_bins < numBins; ++i_bins) {
2460
2461 binNumber++;
2462 while( HistTemplate->IsBinUnderflow(binNumber) || HistTemplate->IsBinOverflow(binNumber) ){
2463 binNumber++;
2464 }
2465
2466 for( unsigned int i_hist = 0; i_hist < numHists; ++i_hist ) {
2467
2468 TH1* nominal = HistVec.at(i_hist).first;
2469 TH1* error = HistVec.at(i_hist).second;
2470
2471 //Int_t binNumber = i_bins + 1;
2472
2473 Double_t histValue = nominal->GetBinContent( binNumber );
2474 Double_t histError = error->GetBinContent( binNumber );
2475 /*
2476 std::cout << " Getting Bin content for Stat Uncertainty"
2477 << " Nom name: " << nominal->GetName()
2478 << " Err name: " << error->GetName()
2479 << " HistNumber: " << i_hist << " bin: " << binNumber
2480 << " Value: " << histValue << " Error: " << histError
2481 << std::endl;
2482 */
2483
2484 if( histError != histError ) {
2485 std::cout << "Warning: In histogram " << error->GetName()
2486 << " bin error for bin " << binNumber
2487 << " is NAN. Not using error!!"
2488 << std::endl;
2489 throw hf_exc();
2490 //histError = 0;
2491 }
2492
2493 TotalBinContent.at(i_bins) += histValue;
2494 HistErrorsSqr.at(i_bins) += histError*histError; // Add in quadrature
2495
2496 }
2497 }
2498
2499 binNumber = 0;
2500
2501 // Creat the output histogram
2502 TH1* ErrorHist = (TH1*) HistTemplate->Clone( Name.c_str() );
2503 ErrorHist->Reset();
2504
2505 // Fill the output histogram
2506 for( Int_t i = 0; i < numBins; ++i) {
2507
2508 // Int_t binNumber = i + 1;
2509 binNumber++;
2510 while( ErrorHist->IsBinUnderflow(binNumber) || ErrorHist->IsBinOverflow(binNumber) ){
2511 binNumber++;
2512 }
2513
2514 Double_t ErrorsSqr = HistErrorsSqr.at(i);
2515 Double_t TotalVal = TotalBinContent.at(i);
2516
2517 if( TotalVal <= 0 ) {
2518 std::cout << "Warning: Sum of histograms for bin: " << binNumber
2519 << " is <= 0. Setting error to 0"
2520 << std::endl;
2521
2522 ErrorHist->SetBinContent( binNumber, 0.0 );
2523 continue;
2524 }
2525
2526 Double_t RelativeError = sqrt(ErrorsSqr) / TotalVal;
2527
2528 // If we otherwise get a NAN
2529 // it's an error
2530 if( RelativeError != RelativeError ) {
2531 std::cout << "Error: bin " << i << " error is NAN" << std::endl;
2532 std::cout << " HistErrorsSqr: " << ErrorsSqr
2533 << " TotalVal: " << TotalVal
2534 << std::endl;
2535 throw hf_exc();
2536 }
2537
2538 // 0th entry in vector is
2539 // the 1st bin in TH1
2540 // (we ignore underflow)
2541
2542 ErrorHist->SetBinContent( binNumber, RelativeError );
2543
2544 std::cout << "Making Total Uncertainty for bin " << binNumber
2545 << " Error = " << sqrt(ErrorsSqr)
2546 << " Val = " << TotalVal
2547 << " RelativeError = " << RelativeError
2548 << std::endl;
2549
2550 }
2551
2552 return ErrorHist;
2553
2554}
2555
2556
2557
2559 createStatConstraintTerms( RooWorkspace* proto, vector<string>& constraintTermNames,
2560 ParamHistFunc& paramHist, TH1* uncertHist,
2561 Constraint::Type type, Double_t minSigma ) {
2562
2563
2564 // Take a RooArgList of RooAbsReal's and
2565 // create N constraint terms (one for
2566 // each gamma) whose relative uncertainty
2567 // is the value of the ith RooAbsReal
2568 //
2569 // The integer "type" controls the type
2570 // of constraint term:
2571 //
2572 // type == 0 : NONE
2573 // type == 1 : Gaussian
2574 // type == 2 : Poisson
2575 // type == 3 : LogNormal
2576
2577 RooArgList ConstraintTerms;
2578
2579 RooArgList paramSet = paramHist.paramList();
2580
2581 // Must get the full size of the TH1
2582 // (No direct method to do this...)
2583 Int_t numBins = uncertHist->GetNbinsX()*uncertHist->GetNbinsY()*uncertHist->GetNbinsZ();
2584 Int_t numParams = paramSet.getSize();
2585 // Int_t numBins = uncertHist->GetNbinsX()*uncertHist->GetNbinsY()*uncertHist->GetNbinsZ();
2586
2587 // Check that there are N elements
2588 // in the RooArgList
2589 if( numBins != numParams ) {
2590 std::cout << "Error: In createStatConstraintTerms, encountered bad number of bins" << std::endl;
2591 std::cout << "Given histogram with " << numBins << " bins,"
2592 << " but require exactly " << numParams << std::endl;
2593 throw hf_exc();
2594 }
2595
2596 Int_t TH1BinNumber = 0;
2597 for( Int_t i = 0; i < paramSet.getSize(); ++i) {
2598
2599 TH1BinNumber++;
2600
2601 while( uncertHist->IsBinUnderflow(TH1BinNumber) || uncertHist->IsBinOverflow(TH1BinNumber) ){
2602 TH1BinNumber++;
2603 }
2604
2605 RooRealVar& gamma = (RooRealVar&) (paramSet[i]);
2606
2607 std::cout << "Creating constraint for: " << gamma.GetName()
2608 << ". Type of constraint: " << type << std::endl;
2609
2610 // Get the sigma from the hist
2611 // (the relative uncertainty)
2612 Double_t sigma = uncertHist->GetBinContent( TH1BinNumber );
2613
2614 // If the sigma is <= 0,
2615 // do cont create the term
2616 if( sigma <= 0 ){
2617 std::cout << "Not creating constraint term for "
2618 << gamma.GetName()
2619 << " because sigma = " << sigma
2620 << " (sigma<=0)"
2621 << " (TH1 bin number = " << TH1BinNumber << ")"
2622 << std::endl;
2623 gamma.setConstant(kTRUE);
2624 continue;
2625 }
2626
2627 // set reasonable ranges for gamma parameters
2628 gamma.setMax( 1 + 5*sigma );
2629 // gamma.setMin( TMath::Max(1. - 5*sigma, 0.) );
2630 gamma.setMin( 0. );
2631
2632 // Make Constraint Term
2633 std::string constrName = string(gamma.GetName()) + "_constraint";
2634 std::string nomName = string("nom_") + gamma.GetName();
2635 std::string sigmaName = string(gamma.GetName()) + "_sigma";
2636 std::string poisMeanName = string(gamma.GetName()) + "_poisMean";
2637
2638 if( type == Constraint::Gaussian ) {
2639
2640 // Type 1 : RooGaussian
2641
2642 // Make sigma
2643
2644 RooConstVar constrSigma( sigmaName.c_str(), sigmaName.c_str(), sigma );
2645 //proto->import( constrSigma, RecycleConflictNodes() );
2646 //proto->import( constrSigma );
2647
2648 // Make "observed" value
2649 RooRealVar constrNom(nomName.c_str(), nomName.c_str(), 1.0,0,10);
2650 constrNom.setConstant( true );
2651
2652 // Make the constraint:
2653 RooGaussian gauss( constrName.c_str(), constrName.c_str(),
2654 constrNom, gamma, constrSigma );
2655
2656 proto->import( gauss, RecycleConflictNodes() );
2657 //proto->import( gauss );
2658
2659 } else if( type == Constraint::Poisson ) {
2660
2661 Double_t tau = 1/sigma/sigma; // this is correct Poisson equivalent to a Gaussian with mean 1 and stdev sigma
2662
2663 // Make nominal "observed" value
2664 RooRealVar constrNom(nomName.c_str(), nomName.c_str(), tau);
2665 constrNom.setMin(0);
2666 constrNom.setConstant( true );
2667
2668 // Make the scaling term
2669 std::string scalingName = string(gamma.GetName()) + "_tau";
2670 RooConstVar poissonScaling( scalingName.c_str(), scalingName.c_str(), tau);
2671
2672 // Make mean for scaled Poisson
2673 RooProduct constrMean( poisMeanName.c_str(), poisMeanName.c_str(), RooArgSet(gamma, poissonScaling) );
2674 //proto->import( constrSigma, RecycleConflictNodes() );
2675 //proto->import( constrSigma );
2676
2677 // Type 2 : RooPoisson
2678 RooPoisson pois(constrName.c_str(), constrName.c_str(), constrNom, constrMean);
2679 pois.setNoRounding(true);
2680 proto->import( pois, RecycleConflictNodes() );
2681
2682 } else {
2683
2684 std::cout << "Error: Did not recognize Stat Error constraint term type: "
2685 << type << " for : " << paramHist.GetName() << std::endl;
2686 throw hf_exc();
2687 }
2688
2689 // If the sigma value is less
2690 // than a supplied threshold,
2691 // set the variable to constant
2692 if( sigma < minSigma ) {
2693 std::cout << "Warning: Bin " << i << " = " << sigma
2694 << " and is < " << minSigma
2695 << ". Setting: " << gamma.GetName() << " to constant"
2696 << std::endl;
2697 gamma.setConstant(kTRUE);
2698 }
2699
2700 constraintTermNames.push_back( constrName );
2701 ConstraintTerms.add( *proto->pdf(constrName.c_str()) );
2702
2703 // Add the "observed" value to the
2704 // list of global observables:
2705 RooArgSet* globalSet = const_cast<RooArgSet*>(proto->set("globalObservables"));
2706
2707 RooRealVar* nomVarInWorkspace = proto->var(nomName.c_str());
2708 if( ! globalSet->contains(*nomVarInWorkspace) ) {
2709 globalSet->add( *nomVarInWorkspace );
2710 }
2711
2712 } // end loop over parameters
2713
2714 return ConstraintTerms;
2715
2716}
2717
2718} // namespace RooStats
2719} // namespace HistFactory
2720
#define alpha_Low
#define alpha_High
int Int_t
Definition: RtypesCore.h:41
double Double_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
#define R__ASSERT(e)
Definition: TError.h:96
int type
Definition: TGX11.cxx:120
float xmin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
double pow(double, double)
double sqrt(double)
double exp(double)
char * Form(const char *fmt,...)
const char * proto
Definition: civetweb.c:16604
A class which maps the current values of a RooRealVar (or a set of RooRealVars) to one of a number of...
Definition: ParamHistFunc.h:28
void setConstant(bool constant)
const RooArgList & paramList() const
Definition: ParamHistFunc.h:39
static RooArgList createParamSet(RooWorkspace &w, const std::string &, const RooArgList &Vars)
Create the list of RooRealVar parameters which represent the height of the histogram bins.
void setShape(TH1 *shape)
Bool_t setBinIntegrator(RooArgSet &allVars)
void setPositiveDefinite(bool flag=true)
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
virtual void Print(Option_t *options=0) const
Print TNamed name and title.
Definition: RooAbsArg.h:227
void setAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
Definition: RooAbsArg.cxx:241
Bool_t isConstant() const
Definition: RooAbsArg.h:266
Int_t getSize() const
Bool_t contains(const RooAbsArg &var) const
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
TIterator * createIterator(Bool_t dir=kIterForward) const
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:37
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
void setConstant(Bool_t value=kTRUE)
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
Double_t getVal(const RooArgSet *set=0) const
Evaluate object. Returns either cached value or triggers a recalculation.
Definition: RooAbsReal.h:64
RooNumIntConfig * specialIntegratorConfig() const
Returns the specialized integrator configuration for this RooAbsReal.
virtual void forceNumInt(Bool_t flag=kTRUE)
Definition: RooAbsReal.h:110
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:88
RooCategory represents a fundamental (non-derived) discrete value object.
Definition: RooCategory.h:24
virtual Bool_t setLabel(const char *label, Bool_t printError=kTRUE)
Set value by specifying the name of the desired state If printError is set, a message will be printed...
RooConstVar represent a constant real-valued object.
Definition: RooConstVar.h:25
RooDataSet is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:40
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:31
virtual void add(const RooArgSet &row, Double_t weight=1.0, Double_t weightError=0)
Add a data point, with its coordinates specified in the 'data' argset, to the data set.
void append(RooDataSet &data)
Add all data points of given data set to this data set.
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
Definition: RooFitResult.h:40
Double_t correlation(const RooAbsArg &par1, const RooAbsArg &par2) const
Definition: RooFitResult.h:117
Plain Gaussian p.d.f.
Definition: RooGaussian.h:25
RooHistFunc implements a real-valued function sampled from a multidimensional histogram.
Definition: RooHistFunc.h:29
Multivariate Gaussian p.d.f.
RooCategory & method2D()
RooCategory & methodND()
RooCategory & method1D()
Poisson pdf.
Definition: RooPoisson.h:19
void setNoRounding(bool flag=kTRUE)
Definition: RooPoisson.h:33
RooProduct a RooAbsReal implementation that represent the product of a given set of other RooAbsReal ...
Definition: RooProduct.h:32
Class RooRealSumPdf implements a PDF constructed from a sum of functions:
Definition: RooRealSumPdf.h:24
RooRealVar represents a fundamental (non-derived) real valued object.
Definition: RooRealVar.h:36
void setMin(const char *name, Double_t value)
Set minimum of name range to given value.
Definition: RooRealVar.cxx:387
virtual void setVal(Double_t value)
Set value of variable to 'value'.
Definition: RooRealVar.cxx:204
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
static RooAbsData * GenerateAsimovData(const RooAbsPdf &pdf, const RooArgSet &observables)
generate the asimov data for the observables (not the global ones) need to deal with the case of a si...
TODO Here, we are missing some documentation.
Definition: Asimov.h:23
std::string GetName()
Definition: Asimov.h:32
void ConfigureWorkspace(RooWorkspace *)
Definition: Asimov.cxx:22
This class encapsulates all information for the statistical interpretation of one experiment.
Definition: Channel.h:26
std::vector< RooStats::HistFactory::Data > & GetAdditionalData()
retrieve vector of additional data objects
Definition: Channel.h:60
HistFactory::StatErrorConfig & GetStatErrorConfig()
get information about threshold for statistical uncertainties and constraint term
Definition: Channel.h:67
RooStats::HistFactory::Data & GetData()
get data object
Definition: Channel.h:55
std::string GetName()
get name of channel
Definition: Channel.h:39
std::vector< RooStats::HistFactory::Sample > & GetSamples()
get vector of samples for this channel
Definition: Channel.h:71
Configuration for a constrained, coherent shape variation of affected samples.
Definition: Systematics.h:114
void ConfigureHistFactoryDataset(RooDataSet *obsData, TH1 *nominal, RooWorkspace *proto, std::vector< std::string > obsNameVec)
static void EditSyst(RooWorkspace *proto, const char *pdfNameChar, std::map< std::string, double > gammaSyst, std::map< std::string, double > uniformSyst, std::map< std::string, double > logNormSyst, std::map< std::string, double > noSyst)
RooWorkspace * MakeSingleChannelModel(Measurement &measurement, Channel &channel)
RooWorkspace * MakeSingleChannelWorkspace(Measurement &measurement, Channel &channel)
void ProcessExpectedHisto(TH1 *hist, RooWorkspace *proto, std::string prefix, std::string productPrefix, std::string systTerm)
void SetObsToExpected(RooWorkspace *proto, std::string obsPrefix, std::string expPrefix, int lowBin, int highBin)
void LinInterpWithConstraint(RooWorkspace *proto, TH1 *nominal, std::vector< HistoSys >, std::string prefix, std::string productPrefix, std::string systTerm, std::vector< std::string > &likelihoodTermNames)
void SetFunctionsToPreprocess(std::vector< std::string > lines)
RooDataSet * MergeDataSets(RooWorkspace *combined, std::vector< RooWorkspace * > wspace_vec, std::vector< std::string > channel_names, std::string dataSetName, RooArgList obsList, RooCategory *channelCat)
TH1 * MakeAbsolUncertaintyHist(const std::string &Name, const TH1 *Hist)
static void ConfigureWorkspaceForMeasurement(const std::string &ModelName, RooWorkspace *ws_single, Measurement &measurement)
TH1 * MakeScaledUncertaintyHist(const std::string &Name, std::vector< std::pair< TH1 *, TH1 * > > HistVec)
void AddPoissonTerms(RooWorkspace *proto, std::string prefix, std::string obsPrefix, std::string expPrefix, int lowBin, int highBin, std::vector< std::string > &likelihoodTermNames)
static void PrintCovarianceMatrix(RooFitResult *result, RooArgSet *params, std::string filename)
void MakeTotalExpected(RooWorkspace *proto, std::string totName, std::vector< std::string > &syst_x_expectedPrefixNames, std::vector< std::string > &normByNames)
void AddMultiVarGaussConstraint(RooWorkspace *proto, std::string prefix, int lowBin, int highBin, std::vector< std::string > &likelihoodTermNames)
std::string AddNormFactor(RooWorkspace *proto, std::string &channel, std::string &sigmaEpsilon, Sample &sample, bool doRatio)
void AddConstraintTerms(RooWorkspace *proto, Measurement &measurement, std::string prefix, std::string interpName, std::vector< OverallSys > &systList, std::vector< std::string > &likelihoodTermNames, std::vector< std::string > &totSystTermNames)
RooWorkspace * MakeCombinedModel(std::vector< std::string >, std::vector< RooWorkspace * >)
RooArgList createStatConstraintTerms(RooWorkspace *proto, std::vector< std::string > &constraintTerms, ParamHistFunc &paramHist, TH1 *uncertHist, Constraint::Type type, Double_t minSigma)
The RooStats::HistFactory::Measurement class can be used to construct a model by combining multiple R...
Definition: Measurement.h:30
std::map< std::string, double > & GetGammaSyst()
Definition: Measurement.h:121
std::map< std::string, double > & GetLogNormSyst()
Definition: Measurement.h:123
std::map< std::string, double > & GetNoSyst()
Definition: Measurement.h:124
std::vector< std::string > & GetPOIList()
get vector of PoI names
Definition: Measurement.h:51
std::map< std::string, double > & GetUniformSyst()
Definition: Measurement.h:122
std::vector< std::string > & GetConstantParams()
get vector of all constant parameters
Definition: Measurement.h:60
std::vector< RooStats::HistFactory::Channel > & GetChannels()
Definition: Measurement.h:105
std::vector< RooStats::HistFactory::Asimov > & GetAsimovDatasets()
get vector of defined Asimov Datasets
Definition: Measurement.h:79
double GetLumi()
retrieve integrated luminosity
Definition: Measurement.h:88
std::vector< std::string > GetPreprocessFunctions()
Configuration for an un- constrained overall systematic to scale sample normalisations.
Definition: Systematics.h:77
Configuration for a constrained overall systematic to scale sample normalisations.
Definition: Systematics.h:49
std::vector< RooStats::HistFactory::OverallSys > & GetOverallSysList()
Definition: Sample.h:108
std::string GetName()
get name of sample
Definition: Sample.h:82
RooStats::HistFactory::StatError & GetStatError()
Definition: Sample.h:117
std::vector< RooStats::HistFactory::ShapeFactor > & GetShapeFactorList()
Definition: Sample.h:115
std::vector< RooStats::HistFactory::NormFactor > & GetNormFactorList()
Definition: Sample.h:109
std::vector< RooStats::HistFactory::HistoSys > & GetHistoSysList()
Definition: Sample.h:111
bool GetNormalizeByTheory()
does the normalization scale with luminosity
Definition: Sample.h:78
std::vector< RooStats::HistFactory::ShapeSys > & GetShapeSysList()
Definition: Sample.h:114
Unconstrained bin-by-bin variation of affected histogram.
Definition: Systematics.h:277
Constrained bin-by-bin variation of affected histogram.
Definition: Systematics.h:232
Constraint::Type GetConstraintType()
Definition: Systematics.h:258
ModelConfig is a simple class that holds configuration information specifying how a model should be u...
Definition: ModelConfig.h:30
virtual void SetObservables(const RooArgSet &set)
specify the observables
Definition: ModelConfig.h:140
virtual void SetWorkspace(RooWorkspace &ws)
Definition: ModelConfig.h:66
virtual void SetParametersOfInterest(const RooArgSet &set)
Definition: ModelConfig.h:99
virtual void SetGlobalObservables(const RooArgSet &set)
specify the global observables
Definition: ModelConfig.h:166
const RooArgSet * GetObservables() const
get RooArgSet for observables (return NULL if not existing)
Definition: ModelConfig.h:243
void GuessObsAndNuisance(const RooAbsData &data)
guesses Observables and ParametersOfInterest if not already set
Definition: ModelConfig.cxx:50
virtual void SetPdf(const RooAbsPdf &pdf)
Set the Pdf, add to the the workspace if not already there.
Definition: ModelConfig.h:81
The RooWorkspace is a persistable container for RooFit projects.
Definition: RooWorkspace.h:43
RooAbsData * data(const char *name) const
Retrieve dataset (binned or unbinned) with given name. A null pointer is returned if not found.
RooArgSet allVars() const
Return set with all variable objects.
Bool_t importClassCode(const char *pat="*", Bool_t doReplace=kFALSE)
Inport code of all classes in the workspace that have a class name that matches pattern 'pat' and whi...
void Print(Option_t *opts=0) const
Print contents of the workspace.
Bool_t defineSet(const char *name, const RooArgSet &aset, Bool_t importMissing=kFALSE)
Define a named RooArgSet with given constituents.
Bool_t saveSnapshot(const char *name, const char *paramNames)
Save snapshot of values and attributes (including "Constant") of parameters 'params' If importValues ...
Bool_t loadSnapshot(const char *name)
Load the values and attributes of the parameters in the snapshot saved with the given name.
RooRealVar * var(const char *name) const
Retrieve real-valued variable (RooRealVar) with given name. A null pointer is returned if not found.
Bool_t import(const RooAbsArg &arg, const RooCmdArg &arg1=RooCmdArg(), const RooCmdArg &arg2=RooCmdArg(), const RooCmdArg &arg3=RooCmdArg(), const RooCmdArg &arg4=RooCmdArg(), const RooCmdArg &arg5=RooCmdArg(), const RooCmdArg &arg6=RooCmdArg(), const RooCmdArg &arg7=RooCmdArg(), const RooCmdArg &arg8=RooCmdArg(), const RooCmdArg &arg9=RooCmdArg())
Import a RooAbsArg object, e.g.
RooFactoryWSTool & factory()
Return instance to factory tool.
const RooArgSet * set(const char *name)
Return pointer to previously defined named set with given nmame If no such set is found a null pointe...
TObject * obj(const char *name) const
Return any type of object (RooAbsArg, RooAbsData or generic object) with given name)
RooAbsPdf * pdf(const char *name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
Class to manage histogram axis.
Definition: TAxis.h:30
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
Double_t GetXmax() const
Definition: TAxis.h:134
Double_t GetXmin() const
Definition: TAxis.h:133
Int_t GetNbins() const
Definition: TAxis.h:121
The TH1 histogram class.
Definition: TH1.h:56
TAxis * GetZaxis()
Definition: TH1.h:318
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition: TH1.cxx:5542
virtual Int_t GetNbinsY() const
Definition: TH1.h:293
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8384
virtual Int_t GetNbinsZ() const
Definition: TH1.h:294
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH1.cxx:6608
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TH1.cxx:2657
virtual Int_t GetNbinsX() const
Definition: TH1.h:292
TAxis * GetYaxis()
Definition: TH1.h:317
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition: TH1.cxx:4943
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition: TH1.cxx:4911
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition: TH1.cxx:8542
virtual void SetName(const char *name)
Change the name of this histogram.
Definition: TH1.cxx:8282
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4790
TObject * Next()
Definition: TCollection.h:249
void Reset()
Definition: TCollection.h:252
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
Stopwatch class.
Definition: TStopwatch.h:28
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
Definition: TStopwatch.cxx:58
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2286
double beta(double x, double y)
Calculates the beta function.
const Double_t sigma
double gamma(double x)
RooCmdArg WeightVar(const char *name, Bool_t reinterpretAsWeight=kFALSE)
RooCmdArg RecycleConflictNodes(Bool_t flag=kTRUE)
RooCmdArg Index(RooCategory &icat)
RooCmdArg Rename(const char *suffix)
RooCmdArg Import(const char *state, TH1 &histo)
RooCmdArg Conditional(const RooArgSet &pdfSet, const RooArgSet &depSet, Bool_t depsAreCond=kFALSE)
@(#)root/roostats:$Id$ Author: George Lewis, Kyle Cranmer
Definition: Asimov.h:20
static constexpr double second
static constexpr double gauss
STL namespace.
Definition: tree.py:1
const char * Name
Definition: TXMLSetup.cxx:66
void ws()
Definition: ws.C:63