77 std::vector<double> out(numBins);
79 for (
int i = 0; i < numBins; ++i) {
106 fSystToFix( measurement.GetConstantParams() ),
107 fParamValues( measurement.GetParamValues() ),
108 fNomLumi( measurement.GetLumi() ),
109 fLumiError( measurement.GetLumi()*measurement.GetLumiRelErr() ),
110 fLowBin( measurement.GetBinLow() ),
111 fHighBin( measurement.GetBinHigh() ),
127 if( proto_config ==
nullptr ) {
128 std::cout <<
"Error: Did not find 'ModelConfig' object in file: " << ws_single->
GetName()
134 cxcoutWHF <<
"No Parametetrs of interest are set" << std::endl;
138 std::stringstream sstream;
139 sstream <<
"Setting Parameter(s) of Interest as: ";
140 for(
auto const& item : measurement.
GetPOIList()) {
141 sstream << item <<
" ";
146 for(
auto const& poi_name : measurement.
GetPOIList()) {
151 std::cout <<
"WARNING: Can't find parameter of interest: " << poi_name
152 <<
" in Workspace. Not setting in ModelConfig." << std::endl;
159 std::string NewModelName =
"newSimPdf";
164 std::cout <<
"Error: Failed to find dataset: " << expData
165 <<
" in workspace" << std::endl;
180 if( !pdf ) pdf = ws_single->
pdf( ModelName );
181 const RooArgSet* observables = ws_single->
set(
"observables");
184 std::string SnapShotName =
"NominalParamValues";
191 std::string AsimovName = asimov.
GetName();
193 cxcoutPHF <<
"Generating additional Asimov Dataset: " << AsimovName << std::endl;
197 cxcoutPHF <<
"Importing Asimov dataset" << std::endl;
200 std::cout <<
"Error: Failed to import Asimov dataset: " << AsimovName
228 string ch_name = channel.
GetName();
232 if( ws_single ==
nullptr ) {
233 cxcoutF(HistFactory) <<
"Error: Failed to make Single-Channel workspace for channel: " << ch_name
234 <<
" and measurement: " << measurement.
GetName() << std::endl;
264 vector<std::unique_ptr<RooWorkspace>> channel_workspaces;
265 vector<string> channel_names;
269 if( ! channel.CheckHistograms() ) {
270 cxcoutFHF <<
"MakeModelAndMeasurementsFast: Channel: " << channel.GetName()
271 <<
" has uninitialized histogram pointers" << std::endl;
275 string ch_name = channel.GetName();
276 channel_names.push_back(ch_name);
285 std::unique_ptr<RooWorkspace> ws{factory.
MakeCombinedModel( channel_names, channel_workspaces )};
298template <
class Arg_t =
RooAbsArg,
typename... Args_t>
299Arg_t *factory(
RooWorkspace &ws,
const char *expr, Args_t &&...args)
310 for (
unsigned int idx=0; idx <
fObsNameVec.size(); ++idx) {
320 obs->setBinning(binning);
334 cxcoutI(HistFactory) <<
"processing hist " << hist->
GetName() << endl;
336 cxcoutF(HistFactory) <<
"hist is empty" << endl;
342 unsigned int histndim(1);
343 std::string classname = hist->
ClassName();
344 if (classname.find(
"TH1")==0) { histndim=1; }
345 else if (classname.find(
"TH2")==0) { histndim=2; }
346 else if (classname.find(
"TH3")==0) { histndim=3; }
349 prefix +=
"_Hist_alphanominal";
351 RooDataHist histDHist(prefix +
"DHist",
"",observables,hist);
360 std::vector<std::string> & constraintTermNames) {
361 std::string paramName = param.
GetName();
362 std::string constraintName = paramName +
"Constraint";
365 if(
proto.pdf(constraintName))
return;
369 const double gaussSigma = isUniform ? 100. : 1.0;
371 cxcoutIHF <<
"Added a uniform constraint for " << paramName <<
" as a Gaussian constraint with a very large sigma " << std::endl;
374 std::stringstream command;
375 command <<
"Gaussian::" << constraintName <<
"(" << paramName <<
",nom_" << paramName <<
"[0.,-10,10],"
376 << gaussSigma <<
")";
377 constraintTermNames.emplace_back(
proto.factory(command.str())->GetName());
378 proto.var(paramName)->setError(gaussSigma);
379 auto * normParam =
proto.var(std::string(
"nom_") + paramName);
380 normParam->setConstant();
381 const_cast<RooArgSet*
>(
proto.set(
"globalObservables"))->add(*normParam);
388 for(
auto const& histoSys : histoSysList) {
400 const string& prefix,
405 std::vector<double> low;
406 std::vector<double> high;
409 for(
unsigned int j=0; j<histoSysList.size(); ++j){
410 std::string str = prefix +
"_" + std::to_string(j);
412 const HistoSys& histoSys = histoSysList.at(j);
413 auto lowDHist = std::make_unique<RooDataHist>(str+
"lowDHist",
"",obsList, histoSys.
GetHistoLow());
414 auto highDHist = std::make_unique<RooDataHist>(str+
"highDHist",
"",obsList, histoSys.
GetHistoHigh());
415 lowSet.
addOwned(std::make_unique<RooHistFunc>((str+
"low").c_str(),
"",obsList,std::move(lowDHist),0));
416 highSet.
addOwned(std::make_unique<RooHistFunc>((str+
"high").c_str(),
"",obsList,std::move(highDHist),0));
421 interp.setPositiveDefinite();
422 interp.setAllInterpCodes(4);
425 interp.setBinIntegrator(obsSet);
426 interp.forceNumInt();
430 return proto.arg(prefix);
438 std::vector<string> prodNames;
441 vector<string> normFactorNames, rangeNames;
444 string overallNorm_times_sigmaEpsilon = sample.
GetName() +
"_" + channel +
"_scaleFactors";
445 auto sigEps =
proto.arg(sigmaEpsilon);
447 auto normFactor = std::make_unique<RooProduct>(overallNorm_times_sigmaEpsilon.c_str(), overallNorm_times_sigmaEpsilon.c_str(),
RooArgList(*sigEps));
449 if(!normList.empty()){
452 string varname = norm.GetName();
454 varname +=
"_" + channel;
460 std::stringstream range;
461 range <<
"[" << norm.GetVal() <<
"," << norm.GetLow() <<
"," << norm.GetHigh() <<
"]";
463 if(
proto.obj(varname) ==
nullptr) {
464 cxcoutI(HistFactory) <<
"making normFactor: " << norm.GetName() << endl;
466 proto.factory(varname + range.str());
469 prodNames.push_back(varname);
470 rangeNames.push_back(range.str());
471 normFactorNames.push_back(varname);
475 for (
const auto&
name : prodNames) {
478 normFactor->addTerm(arg);
483 unsigned int rangeIndex=0;
484 for( vector<string>::iterator nit = normFactorNames.begin(); nit!=normFactorNames.end(); ++nit){
485 if( count (normFactorNames.begin(), normFactorNames.end(), *nit) > 1 ){
486 cxcoutI(HistFactory) <<
"<NormFactor Name =\""<<*nit<<
"\"> is duplicated for <Sample Name=\""
487 << sample.
GetName() <<
"\">, but only one factor will be included. \n Instead, define something like"
488 <<
"\n\t<Function Name=\""<<*nit<<
"Squared\" Expression=\""<<*nit<<
"*"<<*nit<<
"\" Var=\""<<*nit<<rangeNames.at(rangeIndex)
489 <<
"\"> \nin your top-level XML's <Measurement> entry and use <NormFactor Name=\""<<*nit<<
"Squared\" in your channel XML file."<< endl;
499 std::vector<OverallSys>& systList,
500 vector<string>& constraintTermNames,
501 vector<string>& totSystTermNames) {
504 totSystTermNames.push_back(prefix);
507 vector<double> lowVec, highVec;
509 std::map<std::string, double>::iterator itconstr;
510 for(
unsigned int i = 0; i < systList.size(); ++i) {
513 std::string strname = sys.
GetName();
514 const char *
name = strname.c_str();
518 cxcoutI(HistFactory) <<
"HistoToWorkspaceFast::AddConstraintTerm - skip systematic " << sys.
GetName() << std::endl;
525 cxcoutI(HistFactory) <<
"HistoToWorkspaceFast::AddConstraintTerm - zero uncertainty assigned - skip systematic " << sys.
GetName() << std::endl;
528 double tauVal = 1./(relerr*relerr);
529 double sqtau = 1./relerr;
532 RooAbsArg * yvar = factory(
proto,
"nom_%s[%f,0,10]",beta->GetName(),tauVal);
536 RooAbsArg* alphaOfBeta = factory(
proto,
"PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",
name,
name,-sqtau,sqtau);
541 RooAbsArg * gamma = factory(
proto,
"Gamma::%sConstraint(%s, %s, %s, 0.0)",beta->GetName(),beta->GetName(), kappa->
GetName(), theta->
GetName());
543 alphaOfBeta->
Print(
"t");
546 constraintTermNames.push_back(gamma->GetName());
550 const_cast<RooArgSet*
>(
proto.set(
"globalObservables"))->add(*yvar);
553 params.
add(*alphaOfBeta);
554 cxcoutI(HistFactory) <<
"Added a gamma constraint for " <<
name << std::endl;
561 makeGaussianConstraint(*alpha,
proto, isUniform, constraintTermNames);
572 double tauVal = 1./relerr;
573 std::string tauName =
"tau_" + sys.
GetName();
574 factory(
proto,
"%s[%f]",tauName.c_str(),tauVal);
575 double kappaVal = 1. + relerr;
576 std::string kappaName =
"kappa_" + sys.
GetName();
577 factory(
proto,
"%s[%f]",kappaName.c_str(),kappaVal);
578 const char * alphaName = alpha->
GetName();
580 std::string alphaOfBetaName =
"alphaOfBeta_" + sys.
GetName();
581 RooAbsArg * alphaOfBeta = factory(
proto,
"expr::%s('%s*(pow(%s,%s)-1.)',%s,%s,%s)",alphaOfBetaName.c_str(),
582 tauName.c_str(),kappaName.c_str(),alphaName,
583 tauName.c_str(),kappaName.c_str(),alphaName);
585 cxcoutI(HistFactory) <<
"Added a log-normal constraint for " <<
name << std::endl;
587 alphaOfBeta->
Print(
"t");
588 params.
add(*alphaOfBeta);
593 double low = sys.
GetLow();
595 lowVec.push_back(low);
596 highVec.push_back(high);
600 if(!systList.empty()){
604 assert(!params.
empty());
605 assert(
int(lowVec.size()) == params.
getSize() );
607 FlexibleInterpVar interp( (interpName).c_str(),
"", params, 1., lowVec, highVec);
610 proto.import(interp);
615 proto.import(interp);
621 const vector<RooProduct*>& sampleScaleFactors, std::vector<vector<RooAbsArg*>>& sampleHistFuncs)
const {
622 assert(sampleScaleFactors.size() == sampleHistFuncs.size());
627 throw std::logic_error(
"HistFactory didn't process the observables correctly. Please file a bug report.");
629 auto firstHistFunc =
dynamic_cast<const RooHistFunc*
>(sampleHistFuncs.front().front());
630 if (!firstHistFunc) {
632 firstHistFunc =
dynamic_cast<const RooHistFunc*
>(piecewiseInt->nominalHist());
634 assert(firstHistFunc);
637 const std::string binWidthFunctionName = totName +
"_binWidth";
638 RooBinWidthFunction binWidth(binWidthFunctionName.c_str(),
"Divide by bin width to obtain probability density", *firstHistFunc,
true);
639 proto.import(binWidth);
640 auto binWidthWS =
proto.function(binWidthFunctionName);
646 for (
unsigned int i=0; i < sampleHistFuncs.size(); ++i) {
647 assert(!sampleHistFuncs[i].empty());
648 coefList.
add(*sampleScaleFactors[i]);
650 std::vector<RooAbsArg*>& thisSampleHistFuncs = sampleHistFuncs[i];
651 thisSampleHistFuncs.push_back(binWidthWS);
653 if (thisSampleHistFuncs.size() == 1) {
655 shapeList.
add(*thisSampleHistFuncs.front());
658 std::string
name = thisSampleHistFuncs.front()->GetName();
659 auto pos =
name.find(
"Hist_alpha");
660 if (pos != std::string::npos) {
661 name =
name.substr(0, pos) +
"shapes";
662 }
else if ( (pos =
name.find(
"nominal")) != std::string::npos) {
663 name =
name.substr(0, pos) +
"shapes";
666 RooProduct shapeProduct(
name.c_str(), thisSampleHistFuncs.front()->GetTitle(),
RooArgSet(thisSampleHistFuncs.begin(), thisSampleHistFuncs.end()));
673 RooRealSumPdf tot(totName.c_str(), totName.c_str(), shapeList, coefList,
true);
694 FILE* covFile = fopen ((
filename).c_str(),
"w");
695 fprintf(covFile,
" ") ;
696 for (
auto const *myargi : static_range_cast<RooRealVar *>(*params)) {
697 if(myargi->isConstant())
continue;
698 fprintf(covFile,
" & %s", myargi->GetName());
700 fprintf(covFile,
"\\\\ \\hline \n" );
701 for (
auto const *myargi : static_range_cast<RooRealVar *>(*params)) {
702 if(myargi->isConstant())
continue;
703 fprintf(covFile,
"%s", myargi->GetName());
704 for (
auto const *myargj : static_range_cast<RooRealVar *>(*params)) {
705 if(myargj->isConstant())
continue;
706 cout << myargi->GetName() <<
"," << myargj->GetName();
707 fprintf(covFile,
" & %.2f",
result->correlation(*myargi, *myargj));
710 fprintf(covFile,
" \\\\\n");
723 Error(
"MakeSingleChannelWorkspace",
724 "The input Channel does not contain any sample - return a nullptr");
728 const TH1* channel_hist_template = channel.
GetSamples().front().GetHisto();
729 if (channel_hist_template ==
nullptr) {
731 channel_hist_template = channel.
GetSamples().front().GetHisto();
733 if (channel_hist_template ==
nullptr) {
734 std::ostringstream stream;
735 stream <<
"The sample " << channel.
GetSamples().front().GetName()
736 <<
" in channel " << channel.
GetName() <<
" does not contain a histogram. This is the channel:\n";
737 channel.
Print(stream);
738 Error(
"MakeSingleChannelWorkspace",
"%s", stream.str().c_str());
743 std::cout <<
"MakeSingleChannelWorkspace: Channel: " << channel.
GetName()
744 <<
" has uninitialized histogram pointers" << std::endl;
758 string channel_name = channel.
GetName();
768 for (
unsigned int idx=0; idx<
fObsNameVec.size(); ++idx ) {
778 throw hf_exc(
"HistFactory is limited to 1- to 3-dimensional histograms.");
781 cxcoutP(HistFactory) <<
"\n-----------------------------------------\n"
782 <<
"\tStarting to process '"
783 << channel_name <<
"' channel with " <<
fObsNameVec.size() <<
" observables"
784 <<
"\n-----------------------------------------\n" << endl;
789 auto protoOwner = std::make_unique<RooWorkspace>(channel_name.c_str(), (channel_name+
" workspace").c_str());
791 auto proto_config = make_unique<ModelConfig>(
"ModelConfig", &
proto);
792 proto_config->SetWorkspace(
proto);
796 cxcoutI(HistFactory) <<
"will preprocess this line: " << func <<endl;
801 RooArgSet likelihoodTerms(
"likelihoodTerms"), constraintTerms(
"constraintTerms");
802 vector<string> likelihoodTermNames, constraintTermNames, totSystTermNames;
804 std::vector<std::vector<RooAbsArg*>> allSampleHistFuncs;
805 std::vector<RooProduct*> sampleScaleFactors;
807 std::vector< pair<string,string> > statNamePairs;
808 std::vector< pair<const TH1*, std::unique_ptr<TH1>> > statHistPairs;
809 const std::string statFuncName =
"mc_stat_" + channel_name;
811 string prefix, range;
820 std::stringstream lumiErrorStr;
822 proto.factory(
"Gaussian::lumiConstraint(Lumi,"+lumiErrorStr.str()+
")");
824 proto.var(
"nominalLumi")->setConstant();
825 proto.defineSet(
"globalObservables",
"nominalLumi");
827 constraintTermNames.push_back(
"lumiConstraint");
829 proto.var(
"Lumi")->setConstant();
838 string overallSystName = sample.GetName() +
"_" + channel_name +
"_epsilon";
840 string systSourcePrefix =
"alpha_";
845 sample.GetOverallSysList(), constraintTermNames , totSystTermNames);
847 allSampleHistFuncs.emplace_back();
848 std::vector<RooAbsArg*>& sampleHistFuncs = allSampleHistFuncs.back();
861 const TH1* nominal = sample.GetHisto();
873 string expPrefix = sample.
GetName() +
"_" + channel_name;
877 assert(nominalHistFunc);
879 if(sample.GetHistoSysList().empty()) {
881 cxcoutI(HistFactory) << sample.GetName() +
"_" + channel_name +
" has no variation histograms " << endl;
883 sampleHistFuncs.push_back(nominalHistFunc);
887 string constraintPrefix = sample.GetName() +
"_" + channel_name +
"_Hist_alpha";
890 RooArgList interpParams = makeInterpolationParameters(sample.GetHistoSysList(),
proto);
893 for(std::size_t i = 0; i < interpParams.
size(); ++i) {
894 bool isUniform = measurement.
GetUniformSyst().count(sample.GetHistoSysList()[i].GetName()) > 0;
895 makeGaussianConstraint(interpParams[i],
proto, isUniform, constraintTermNames);
899 sampleHistFuncs.push_back( makeLinInterp(interpParams, nominalHistFunc,
proto,
900 sample.GetHistoSysList(), constraintPrefix, observables) );
903 sampleHistFuncs.front()->SetTitle( (nominal && strlen(nominal->
GetTitle())>0) ? nominal->
GetTitle() : sample.GetName().c_str() );
909 if( sample.GetStatError().GetActivate() ) {
912 cxcoutF(HistFactory) <<
"Cannot include Stat Error for histograms of more than 3 dimensions."
921 cxcoutI(HistFactory) <<
"Sample: " << sample.GetName() <<
" to be included in Stat Error "
922 <<
"for channel " << channel_name
925 string UncertName = sample.GetName() +
"_" + channel_name +
"_StatAbsolUncert";
926 std::unique_ptr<TH1> statErrorHist;
928 if( sample.GetStatError().GetErrorHist() ==
nullptr ) {
930 cxcoutI(HistFactory) <<
"Making Statistical Uncertainty Hist for "
931 <<
" Channel: " << channel_name
932 <<
" Sample: " << sample.GetName()
939 statErrorHist.reset(
static_cast<TH1*
>(sample.GetStatError().GetErrorHist()->Clone()));
943 cxcoutI(HistFactory) <<
"Using external histogram for Stat Errors for "
944 <<
"\tChannel: " << channel_name
945 <<
"\tSample: " << sample.GetName()
946 <<
"\tError Histogram: " << statErrorHist->GetName() << std::endl;
949 statErrorHist->Multiply( nominal );
950 statErrorHist->SetName( UncertName.c_str() );
955 statHistPairs.emplace_back(nominal, std::move(statErrorHist));
973 if( paramHist ==
nullptr ) {
979 for (
int idx=0; itr!=
fObsNameVec.end(); ++itr, ++idx ) {
980 theObservables.
add( *
proto.var(*itr) );
985 std::string ParamSetPrefix =
"gamma_stat_" + channel_name;
991 ParamHistFunc statUncertFunc(statFuncName.c_str(), statFuncName.c_str(),
992 theObservables, statFactorParams );
996 paramHist =
proto.function( statFuncName);
1000 sampleHistFuncs.push_back(paramHist);
1009 if( !sample.GetShapeFactorList().empty() ) {
1012 cxcoutF(HistFactory) <<
"Cannot include Stat Error for histograms of more than 3 dimensions."
1017 cxcoutI(HistFactory) <<
"Sample: " << sample.GetName() <<
" in channel: " << channel_name
1018 <<
" to be include a ShapeFactor."
1021 for(
ShapeFactor& shapeFactor : sample.GetShapeFactorList()) {
1023 std::string funcName = channel_name +
"_" + shapeFactor.GetName() +
"_shapeFactor";
1025 if( paramHist ==
nullptr ) {
1029 theObservables.
add( *
proto.var(varName) );
1033 std::string funcParams =
"gamma_" + shapeFactor.GetName();
1042 ParamHistFunc shapeFactorFunc( funcName.c_str(), funcName.c_str(),
1043 theObservables, shapeFactorParams );
1046 if( shapeFactor.GetInitialShape() !=
nullptr ) {
1047 TH1* initialShape =
static_cast<TH1*
>(shapeFactor.GetInitialShape()->Clone());
1048 cxcoutI(HistFactory) <<
"Setting Shape Factor: " << shapeFactor.
GetName()
1049 <<
" to have initial shape from hist: "
1052 shapeFactorFunc.
setShape( initialShape );
1056 if( shapeFactor.IsConstant() ) {
1057 cxcoutI(HistFactory) <<
"Setting Shape Factor: " << shapeFactor.GetName()
1058 <<
" to be constant" << std::endl;
1063 paramHist =
proto.function(funcName);
1067 sampleHistFuncs.push_back(paramHist);
1077 if( !sample.GetShapeSysList().empty() ) {
1080 cxcoutF(HistFactory) <<
"Cannot include Stat Error for histograms of more than 3 dimensions."
1086 std::vector<string> ShapeSysNames;
1099 cxcoutI(HistFactory) <<
"Sample: " << sample.GetName() <<
" in channel: " << channel_name
1100 <<
" to include a ShapeSys." << std::endl;
1102 std::string funcName = channel_name +
"_" + shapeSys.GetName() +
"_ShapeSys";
1103 ShapeSysNames.push_back( funcName );
1105 if( paramHist ==
nullptr ) {
1112 theObservables.
add( *
proto.var(varName) );
1116 std::string funcParams =
"gamma_" + shapeSys.GetName();
1122 ParamHistFunc shapeFactorFunc( funcName.c_str(), funcName.c_str(),
1123 theObservables, shapeFactorParams );
1135 const TH1* shapeErrorHist = shapeSys.GetErrorHist();
1150 for (
auto const& term : shapeConstraintsInfo.constraints) {
1152 constraintTermNames.emplace_back(term->GetName());
1156 for (
RooAbsArg * glob : shapeConstraintsInfo.globalObservables) {
1157 globalSet->
add(*
proto.var(glob->GetName()));
1167 for(std::string
const&
name : ShapeSysNames) {
1168 sampleHistFuncs.push_back(
proto.function(
name));
1178 if( !sample.GetNormalizeByTheory() ) {
1180 lumi =
proto.factory(
"Lumi[" + std::to_string(measurement.
GetLumi()) +
"]");
1186 normFactors->addTerm(lumi);
1192 auto normFactorsInWS =
dynamic_cast<RooProduct*
>(
proto.arg(normFactors->GetName()));
1193 assert(normFactorsInWS);
1195 sampleScaleFactors.push_back(normFactorsInWS);
1200 if(!statHistPairs.empty()) {
1205 if( fracStatError ==
nullptr ) {
1206 cxcoutE(HistFactory) <<
"Error: Failed to make ScaledUncertaintyHist for: "
1207 << channel_name +
"_StatUncert" +
"_RelErr" << std::endl;
1213 auto chanStatUncertFunc =
static_cast<ParamHistFunc*
>(
proto.function( statFuncName ));
1214 cxcoutI(HistFactory) <<
"About to create Constraint Terms from: "
1215 << chanStatUncertFunc->
GetName()
1216 <<
" params: " << chanStatUncertFunc->paramList()
1227 cxcoutI(HistFactory) <<
"Using Gaussian StatErrors in channel: " << channel.
GetName() << std::endl;
1230 cxcoutI(HistFactory) <<
"Using Poisson StatErrors in channel: " << channel.
GetName() << std::endl;
1235 chanStatUncertFunc->paramList(),
histToVector(*fracStatError),
1236 statRelErrorThreshold,
1237 statConstraintType);
1238 for (
auto const& term : statConstraintsInfo.constraints) {
1240 constraintTermNames.emplace_back(term->GetName());
1244 for (
RooAbsArg * glob : statConstraintsInfo.globalObservables) {
1245 globalSet->
add(*
proto.var(glob->GetName()));
1254 sampleScaleFactors, allSampleHistFuncs);
1255 likelihoodTermNames.push_back(channel_name+
"_model");
1259 for(
unsigned int i=0; i<systToFix.size(); ++i){
1262 cxcoutW(HistFactory) <<
"could not find variable " << systToFix.at(i)
1263 <<
" could not set it to constant" << endl;
1272 for(
unsigned int i=0; i<constraintTermNames.size(); ++i){
1274 if( proto_arg==
nullptr ) {
1275 cxcoutF(HistFactory) <<
"Error: Cannot find arg set: " << constraintTermNames.at(i)
1279 constraintTerms.
add( *proto_arg );
1282 for(
unsigned int i=0; i<likelihoodTermNames.size(); ++i){
1284 if( proto_arg==
nullptr ) {
1285 cxcoutF(HistFactory) <<
"Error: Cannot find arg set: " << likelihoodTermNames.at(i)
1289 likelihoodTerms.add( *proto_arg );
1291 proto.defineSet(
"constraintTerms",constraintTerms);
1292 proto.defineSet(
"likelihoodTerms",likelihoodTerms);
1296 std::string observablesStr;
1300 if (!observablesStr.empty()) { observablesStr +=
","; }
1301 observablesStr +=
name;
1307 proto.defineSet(
"observables", observablesStr.c_str());
1308 proto.defineSet(
"observablesSet", observablesStr.c_str());
1312 cxcoutP(HistFactory) <<
"\n-----------------------------------------\n"
1313 <<
"\timport model into workspace"
1314 <<
"\n-----------------------------------------\n" << endl;
1316 auto model = make_unique<RooProdPdf>(
1317 (
"model_"+channel_name).c_str(),
1318 "product of Poissons across bins for a single channel",
1326 proto_config->SetPdf(*model);
1327 proto_config->SetObservables(observables);
1328 proto_config->SetGlobalObservables(*
proto.set(
"globalObservables"));
1332 proto.import(*proto_config,proto_config->GetName());
1333 proto.importClassCode();
1340 int asymcalcPrintLevel = 0;
1353 proto.import(dataset);
1358 if(
data.GetName().empty()) {
1359 cxcoutF(HistFactory) <<
"Error: Additional Data histogram for channel: " << channel.
GetName()
1360 <<
" has no name! The name always needs to be set for additional datasets, "
1361 <<
"either via the \"Name\" tag in the XML or via RooStats::HistFactory::Data::SetName()." << std::endl;
1364 std::string
const& dataName =
data.GetName();
1365 TH1 const* mnominal =
data.GetHisto();
1367 cxcoutF(HistFactory) <<
"Error: Additional Data histogram for channel: " << channel.
GetName()
1368 <<
" with name: " << dataName <<
" is nullptr" << std::endl;
1375 proto.import(dataset);
1388 TH1 const& mnominal,
1390 std::vector<std::string>
const& obsNameVec) {
1396 if (obsNameVec.empty() ) {
1397 Error(
"ConfigureHistFactoryDataset",
"Invalid input - return");
1405 for (
int i=1; i<=ax->
GetNbins(); ++i) {
1408 proto.var( obsNameVec[0] )->setVal( xval );
1410 if(obsNameVec.size()==1) {
1412 obsDataUnbinned.
add( *
proto.set(
"observables"), fval );
1415 for(
int j=1; j<=ay->
GetNbins(); ++j) {
1417 proto.var( obsNameVec[1] )->setVal( yval );
1419 if(obsNameVec.size()==2) {
1421 obsDataUnbinned.
add( *
proto.set(
"observables"), fval );
1424 for(
int k=1; k<=az->
GetNbins(); ++k) {
1426 proto.var( obsNameVec[2] )->setVal( zval );
1428 obsDataUnbinned.
add( *
proto.set(
"observables"), fval );
1445 std::vector<std::unique_ptr<RooWorkspace>> &chs)
1450 if (ch_names.empty() || chs.empty() ) {
1451 Error(
"MakeCombinedModel",
"Input vectors are empty - return a nullptr");
1454 if (chs.size() < ch_names.size() ) {
1455 Error(
"MakeCombinedModel",
"Input vector of workspace has an invalid size - return a nullptr");
1463 map<string, RooAbsPdf*> pdfMap;
1464 vector<RooAbsPdf*> models;
1467 for(
unsigned int i = 0; i< ch_names.size(); ++i){
1468 obsList.
add(*
static_cast<ModelConfig *
>(chs[i]->obj(
"ModelConfig"))->GetObservables());
1470 cxcoutI(HistFactory) <<
"full list of observables:\n" << obsList << std::endl;
1473 stringstream channelString;
1474 channelString <<
"channelCat[";
1475 for(
unsigned int i = 0; i< ch_names.size(); ++i){
1476 string channel_name=ch_names[i];
1477 if (i == 0 && isdigit(channel_name[0])) {
1478 throw std::invalid_argument(
"The first channel name for HistFactory cannot start with a digit. Got " + channel_name);
1480 if (channel_name.find(
',') != std::string::npos) {
1481 throw std::invalid_argument(
"Channel names for HistFactory cannot contain ','. Got " + channel_name);
1484 if (i == 0) channelString << channel_name ;
1485 else channelString <<
',' << channel_name ;
1489 if(!model) cout <<
"failed to find model for channel"<<endl;
1491 models.push_back(model);
1492 globalObs.
add(*ch->
set(
"globalObservables"),
true);
1495 pdfMap[channel_name]=model;
1497 channelString <<
"]";
1499 cxcoutP(HistFactory) <<
"\n-----------------------------------------\n"
1500 <<
"\tEntering combination"
1501 <<
"\n-----------------------------------------\n" << endl;
1502 auto combined = std::make_unique<RooWorkspace>(
"combined");
1506 if (!channelCat)
throw std::runtime_error(
"Unable to construct a category from string " + channelString.str());
1508 auto simPdf= std::make_unique<RooSimultaneous>(
"simPdf",
"",pdfMap, *channelCat);
1509 auto combined_config = std::make_unique<ModelConfig>(
"ModelConfig", combined.get());
1510 combined_config->SetWorkspace(*combined);
1513 combined->import(globalObs);
1514 combined->defineSet(
"globalObservables",globalObs);
1515 combined_config->SetGlobalObservables(*combined->set(
"globalObservables"));
1517 combined->defineSet(
"observables",{obsList, *channelCat},
true);
1518 combined_config->SetObservables(*combined->set(
"observables"));
1525 if(std::string(
"asimovData") ==
data->GetName()) {
1530 std::map<std::string, RooAbsData*> dataMap;
1531 for(
unsigned int i = 0; i < ch_names.size(); ++i){
1532 dataMap[ch_names[i]] = chs[i]->data(
data->GetName());
1542 cxcoutP(HistFactory) <<
"\n-----------------------------------------\n"
1543 <<
"\tImporting combined model"
1544 <<
"\n-----------------------------------------\n" << endl;
1549 std::string paramName = param_itr.first;
1550 double paramVal = param_itr.second;
1552 if(
RooRealVar* temp = combined->var( paramName )) {
1553 temp->setVal( paramVal );
1554 cxcoutI(HistFactory) <<
"setting " << paramName <<
" to the value: " << paramVal << endl;
1556 cxcoutE(HistFactory) <<
"could not find variable " << paramName <<
" could not set its value" << endl;
1560 for(
unsigned int i=0; i<
fSystToFix.size(); ++i){
1563 temp->setConstant();
1566 cxcoutE(HistFactory) <<
"could not find variable " <<
fSystToFix.at(i) <<
" could not set it to constant" << endl;
1574 combined_config->SetPdf(*simPdf);
1577 combined->import(*combined_config,combined_config->GetName());
1578 combined->importClassCode();
1584 cxcoutP(HistFactory) <<
"\n-----------------------------------------\n"
1585 <<
"\tcreate toy data for " << channelString.str()
1586 <<
"\n-----------------------------------------\n" << endl;
1594 *combined->pdf(
"simPdf"),
1596 if( asimov_combined ) {
1597 combined->import( *asimov_combined,
RooFit::Rename(
"asimovData"));
1600 std::cout <<
"Error: Failed to create combined asimov dataset" << std::endl;
1614 auto ErrorHist =
static_cast<TH1*
>(Nominal->
Clone( Name.c_str() ));
1621 for(
int i_bin = 0; i_bin < numBins; ++i_bin) {
1629 double histError = Nominal->
GetBinError( binNumber );
1632 if( histError != histError ) {
1633 std::cout <<
"Warning: In histogram " << Nominal->
GetName()
1634 <<
" bin error for bin " << i_bin
1635 <<
" is NAN. Not using Error!!!"
1643 if( histError < 0 ) {
1644 std::cout <<
"Warning: In histogram " << Nominal->
GetName()
1645 <<
" bin error for bin " << binNumber
1646 <<
" is < 0. Setting Error to 0"
1652 ErrorHist->SetBinContent( binNumber, histError );
1671 unsigned int numHists = HistVec.size();
1673 if( numHists == 0 ) {
1674 cxcoutE(HistFactory) <<
"Warning: Empty Hist Vector, cannot create total uncertainty" << std::endl;
1678 const TH1* HistTemplate = HistVec.at(0).first;
1683 for(
unsigned int i = 0; i < HistVec.size(); ++i ) {
1685 const TH1* nominal = HistVec.at(i).first;
1686 const TH1* error = HistVec.at(i).second.get();
1689 cxcoutE(HistFactory) <<
"Error: Provided hists have unequal bins" << std::endl;
1693 cxcoutE(HistFactory) <<
"Error: Provided hists have unequal bins" << std::endl;
1698 std::vector<double> TotalBinContent( numBins, 0.0);
1699 std::vector<double> HistErrorsSqr( numBins, 0.0);
1704 for(
int i_bins = 0; i_bins < numBins; ++i_bins) {
1711 for(
unsigned int i_hist = 0; i_hist < numHists; ++i_hist ) {
1713 const TH1* nominal = HistVec.at(i_hist).first;
1714 const TH1* error = HistVec.at(i_hist).second.get();
1721 if( histError != histError ) {
1723 <<
" bin error for bin " << binNumber
1724 <<
" is NAN. Not using error!!";
1728 TotalBinContent.at(i_bins) += histValue;
1729 HistErrorsSqr.at(i_bins) += histError*histError;
1737 TH1* ErrorHist = (
TH1*) HistTemplate->
Clone( Name.c_str() );
1741 for(
int i = 0; i < numBins; ++i) {
1749 double ErrorsSqr = HistErrorsSqr.at(i);
1750 double TotalVal = TotalBinContent.at(i);
1752 if( TotalVal <= 0 ) {
1753 cxcoutW(HistFactory) <<
"Warning: Sum of histograms for bin: " << binNumber
1754 <<
" is <= 0. Setting error to 0"
1761 double RelativeError = sqrt(ErrorsSqr) / TotalVal;
1765 if( RelativeError != RelativeError ) {
1766 cxcoutE(HistFactory) <<
"Error: bin " << i <<
" error is NAN\n"
1767 <<
" HistErrorsSqr: " << ErrorsSqr
1768 <<
" TotalVal: " << TotalVal;
1781 cxcoutI(HistFactory) <<
"Making Total Uncertainty for bin " << binNumber
1782 <<
" Error = " << sqrt(ErrorsSqr)
1783 <<
" CentralVal = " << TotalVal
1784 <<
" RelativeError = " << RelativeError <<
"\n";
1788 return std::unique_ptr<TH1>(ErrorHist);
std::vector< double > histToVector(TH1 const &hist)
constexpr double alphaHigh
constexpr double alphaLow
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
A class which maps the current values of a RooRealVar (or a set of RooRealVars) to one of a number of...
void setConstant(bool constant)
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)
The PiecewiseInterpolation is a class that can morph distributions into each other,...
Common abstract base class for objects that represent a value and a "shape" in RooFit.
void Print(Option_t *options=nullptr) const override
Print the object to the defaultPrintStream().
void setAttribute(const Text_t *name, bool value=true)
Set (default) or clear a named boolean attribute of this object.
Int_t getSize() const
Return the number of elements in the collection.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
const_iterator begin() const
Abstract base class for binned and unbinned datasets.
Abstract interface for all probability density functions.
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
void setConstant(bool value=true)
Abstract base class for objects that represent a real value and implements functionality common to al...
RooNumIntConfig * specialIntegratorConfig() const
Returns the specialized integrator configuration for this RooAbsReal.
virtual void forceNumInt(bool flag=true)
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooBinWidthFunction is a class that returns the bin width (or volume) given a RooHistFunc.
Class RooBinning is an implements RooAbsBinning in terms of an array of boundary values,...
Object to represent discrete states.
bool setLabel(const char *label, bool printError=true) override
Set value by specifying the name of the desired state.
RooConstVar represent a constant real-valued object.
The RooDataHist is a container class to hold N-dimensional binned data.
RooDataSet is a container class to hold unbinned data.
void add(const RooArgSet &row, double weight, double weightError)
Add one ore more rows of data.
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
Switches the message service to a different level while the instance is alive.
RooHistFunc implements a real-valued function sampled from a multidimensional histogram.
static RooMsgService & instance()
Return reference to singleton instance.
bool isActive(T self, RooFit::MsgTopic topic, RooFit::MsgLevel level)
Check if logging is active for given object/topic/RooFit::MsgLevel combination.
A RooProduct represents the product of a given set of RooAbsReal objects.
Implements a PDF constructed from a sum of functions:
RooRealVar represents a variable that can be changed from the outside.
static void SetPrintLevel(int level)
set print level (static function)
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.
void ConfigureWorkspace(RooWorkspace *)
This class encapsulates all information for the statistical interpretation of one experiment.
std::vector< RooStats::HistFactory::Data > & GetAdditionalData()
retrieve vector of additional data objects
void Print(std::ostream &=std::cout)
HistFactory::StatErrorConfig & GetStatErrorConfig()
get information about threshold for statistical uncertainties and constraint term
RooStats::HistFactory::Data & GetData()
get data object
bool CheckHistograms() const
std::vector< RooStats::HistFactory::Sample > & GetSamples()
get vector of samples for this channel
std::string GetName() const
get name of channel
void setAllInterpCodes(int code)
Configuration for a constrained, coherent shape variation of affected samples.
This class provides helper functions for creating likelihood models from histograms.
std::unique_ptr< RooProduct > CreateNormFactor(RooWorkspace &proto, std::string &channel, std::string &sigmaEpsilon, Sample &sample, bool doRatio)
void GuessObsNameVec(const TH1 *hist)
std::unique_ptr< RooWorkspace > MakeSingleChannelWorkspace(Measurement &measurement, Channel &channel)
void MakeTotalExpected(RooWorkspace &proto, const std::string &totName, const std::vector< RooProduct * > &sampleScaleFactors, std::vector< std::vector< RooAbsArg * > > &sampleHistFuncs) const
std::unique_ptr< TH1 > MakeScaledUncertaintyHist(const std::string &Name, std::vector< std::pair< const TH1 *, std::unique_ptr< TH1 > > > const &HistVec) const
std::vector< std::string > fPreprocessFunctions
RooHistFunc * MakeExpectedHistFunc(const TH1 *hist, RooWorkspace &proto, std::string prefix, const RooArgList &observables) const
Create the nominal hist function from hist, and register it in the workspace.
void SetFunctionsToPreprocess(std::vector< std::string > lines)
std::vector< std::string > fObsNameVec
RooFit::OwningPtr< RooWorkspace > MakeSingleChannelModel(Measurement &measurement, Channel &channel)
RooFit::OwningPtr< RooWorkspace > MakeCombinedModel(std::vector< std::string >, std::vector< std::unique_ptr< RooWorkspace > > &)
TH1 * MakeAbsolUncertaintyHist(const std::string &Name, const TH1 *Hist)
std::map< std::string, double > fParamValues
static void ConfigureWorkspaceForMeasurement(const std::string &ModelName, RooWorkspace *ws_single, Measurement &measurement)
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)
void ConfigureHistFactoryDataset(RooDataSet &obsData, TH1 const &nominal, RooWorkspace &proto, std::vector< std::string > const &obsNameVec)
static void PrintCovarianceMatrix(RooFitResult *result, RooArgSet *params, std::string filename)
std::vector< std::string > fSystToFix
HistoToWorkspaceFactoryFast()
RooArgList createObservables(const TH1 *hist, RooWorkspace &proto) const
Create observables of type RooRealVar. Creates 1 to 3 observables, depending on the type of the histo...
const TH1 * GetHistoHigh() const
const TH1 * GetHistoLow() const
The RooStats::HistFactory::Measurement class can be used to construct a model by combining multiple R...
std::map< std::string, double > & GetGammaSyst()
std::map< std::string, double > & GetLogNormSyst()
std::map< std::string, double > & GetNoSyst()
std::vector< std::string > & GetPOIList()
get vector of PoI names
std::map< std::string, double > & GetUniformSyst()
std::vector< std::string > & GetConstantParams()
get vector of all constant parameters
std::vector< RooStats::HistFactory::Channel > & GetChannels()
std::vector< RooStats::HistFactory::Asimov > & GetAsimovDatasets()
get vector of defined Asimov Datasets
std::vector< std::string > GetPreprocessFunctions() const
Returns a list of defined preprocess function expressions.
double GetLumi()
retrieve integrated luminosity
Configuration for an un- constrained overall systematic to scale sample normalisations.
Configuration for a constrained overall systematic to scale sample normalisations.
const std::string & GetName() const
std::string GetName() const
get name of sample
std::vector< RooStats::HistFactory::NormFactor > & GetNormFactorList()
*Un*constrained bin-by-bin variation of affected histogram.
Constrained bin-by-bin variation of affected histogram.
double GetRelErrorThreshold() const
Constraint::Type GetConstraintType() const
ModelConfig is a simple class that holds configuration information specifying how a model should be u...
void GuessObsAndNuisance(const RooAbsData &data, bool printModelConfig=true)
Makes sensible guesses of observables, parameters of interest and nuisance parameters if one or multi...
virtual void SetParametersOfInterest(const RooArgSet &set)
Specify parameters of interest.
Persistable container for RooFit projects.
TObject * obj(RooStringView name) const
Return any type of object (RooAbsArg, RooAbsData or generic object) with given name)
RooAbsPdf * pdf(RooStringView name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
RooArgSet allVars() const
Return set with all variable objects.
const RooArgSet * set(RooStringView name)
Return pointer to previously defined named set with given nmame If no such set is found a null pointe...
bool saveSnapshot(RooStringView, const char *paramNames)
Save snapshot of values and attributes (including "Constant") of given parameters.
bool import(const RooAbsArg &arg, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}, const RooCmdArg &arg9={})
Import a RooAbsArg object, e.g.
RooFactoryWSTool & factory()
Return instance to factory tool.
RooRealVar * var(RooStringView name) const
Retrieve real-valued variable (RooRealVar) with given name. A null pointer is returned if not found.
RooAbsData * data(RooStringView name) const
Retrieve dataset (binned or unbinned) with given name. A null pointer is returned if not found.
bool loadSnapshot(const char *name)
Load the values and attributes of the parameters in the snapshot saved with the given name.
const Double_t * GetArray() const
Class to manage histogram axis.
Bool_t IsVariableBinSize() const
const char * GetTitle() const override
Returns title of object.
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
const TArrayD * GetXbins() const
TH1 is the base class of all histogram classes in ROOT.
virtual Int_t GetNbinsY() const
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
virtual Int_t GetNbinsZ() const
virtual Int_t GetDimension() const
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
virtual Int_t GetNbinsX() const
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
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...
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
const char * GetName() const override
Returns name of object.
const char * GetTitle() const override
Returns title of object.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
RooCmdArg RecycleConflictNodes(bool flag=true)
RooCmdArg Rename(const char *suffix)
RooCmdArg Conditional(const RooArgSet &pdfSet, const RooArgSet &depSet, bool depsAreCond=false)
RooCmdArg Index(RooCategory &icat)
RooCmdArg WeightVar(const char *name="weight", bool reinterpretAsWeight=false)
RooCmdArg Import(const char *state, TH1 &histo)
OwningPtr< T > owningPtr(std::unique_ptr< T > &&ptr)
Internal helper to turn a std::unique_ptr<T> into an OwningPtr.
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
constexpr double defaultShapeSysGammaMax
constexpr double minShapeUncertainty
constexpr double defaultShapeFactorGammaMax
constexpr double defaultStatErrorGammaMax
constexpr double defaultGammaMin
CreateGammaConstraintsOutput createGammaConstraints(RooArgList const ¶mList, std::span< const double > relSigmas, double minSigma, Constraint::Type type)
Namespace for the RooStats classes.
bool binnedFitOptimization