7 #include "RooFormulaVar.h"
21 flags_[
"check-negative-bins-on-import"] =
true;
22 flags_[
"zero-negative-bins-on-import"] =
false;
23 flags_[
"allow-missing-shapes"] =
true;
24 flags_[
"workspaces-use-clone"] =
false;
25 flags_[
"workspace-uuid-recycle"] =
true;
26 flags_[
"import-parameter-err"] =
true;
27 flags_[
"filters-use-regex"] =
false;
28 flags_[
"fix-rooconstvar"] =
false;
40 swap(first.obs_, second.obs_);
41 swap(first.procs_, second.procs_);
42 swap(first.systs_, second.systs_);
43 swap(first.params_, second.params_);
44 swap(first.wspaces_, second.wspaces_);
45 swap(first.verbosity_, second.verbosity_);
46 swap(first.flags_, second.flags_);
47 swap(first.post_lines_, second.post_lines_);
48 swap(first.log_, second.log_);
49 swap(first.auto_stats_settings_, second.auto_stats_settings_);
56 params_(other.params_),
57 wspaces_(other.wspaces_),
59 auto_stats_settings_(other.auto_stats_settings_),
60 post_lines_(other.post_lines_),
61 verbosity_(other.verbosity_),
69 auto it = flags_.find(flag);
70 if (it != flags_.end()) {
71 FNLOG(std::cout) <<
"Changing value of flag \"" << it->first <<
"\" from " << it->second <<
" to " << value <<
"\n";
74 FNLOG(std::cout) <<
"Created new flag \"" << flag <<
"\" with value " << value <<
"\n";
80 auto it = flags_.find(flag);
81 if (it != flags_.end()) {
84 throw std::runtime_error(
FNERROR(
"Flag " + flag +
" is not defined"));
92 cpy.obs_.resize(obs_.size());
93 cpy.procs_.resize(procs_.size());
94 cpy.systs_.resize(systs_.size());
96 cpy.verbosity_ = verbosity_;
97 cpy.post_lines_ = post_lines_;
101 std::map<RooAbsData const*, RooAbsData *> dat_map;
102 std::map<RooAbsReal const*, RooAbsReal *> pdf_map;
103 std::map<RooRealVar const*, RooRealVar *> var_map;
104 std::map<RooAbsReal const*, RooAbsReal *> fun_map;
107 for (
auto const& it : wspaces_) {
108 std::string ws_name = it.first;
109 RooWorkspace
const& o_wsp = *(it.second.get());
110 cpy.wspaces_.insert({ws_name, std::make_shared<RooWorkspace>(o_wsp)});
111 RooWorkspace & n_wsp = *(cpy.wspaces_.at(ws_name).get());
113 std::list<RooAbsData *> o_dat = o_wsp.allData();
114 RooArgSet
const& o_pdf = o_wsp.allPdfs();
115 RooArgSet
const& o_var = o_wsp.allVars();
116 RooArgSet
const& o_fun = o_wsp.allFunctions();
118 std::list<RooAbsData *> n_dat = n_wsp.allData();
119 RooArgSet
const& n_pdf = n_wsp.allPdfs();
120 RooArgSet
const& n_var = n_wsp.allVars();
121 RooArgSet
const& n_fun = n_wsp.allFunctions();
123 auto o_dat_it = o_dat.begin();
124 auto n_dat_it = n_dat.begin();
125 for (; o_dat_it != o_dat.end(); ++o_dat_it, ++n_dat_it) {
126 dat_map[*o_dat_it] = *n_dat_it;
129 Int_t nPdf = o_pdf.getSize();
131 for (Int_t i=0; i<nPdf; ++i) {
133 RooAbsReal* o_pdf_ptr =
dynamic_cast<RooAbsReal *
>(o_pdf[i]);
134 RooAbsReal* n_pdf_ptr =
dynamic_cast<RooAbsReal *
>(n_pdf[i]);
135 if (o_pdf_ptr && n_pdf_ptr) pdf_map[o_pdf_ptr] = n_pdf_ptr;
138 Int_t nVar = o_var.getSize();
140 for (Int_t i=0; i<nVar; ++i) {
141 RooRealVar *o_var_ptr =
dynamic_cast<RooRealVar*
>(o_var[i]);
142 RooRealVar *n_var_ptr =
dynamic_cast<RooRealVar*
>(n_var[i]);
143 if (o_var_ptr && n_var_ptr) var_map[o_var_ptr] = n_var_ptr;
146 Int_t nFun = o_fun.getSize();
148 for (Int_t i=0; i<nFun; ++i) {
149 RooAbsReal* o_fun_ptr =
dynamic_cast<RooAbsReal *
>(o_fun[i]);
150 RooAbsReal* n_fun_ptr =
dynamic_cast<RooAbsReal *
>(n_fun[i]);
151 if (o_fun_ptr && n_fun_ptr) fun_map[o_fun_ptr] = n_fun_ptr;
157 for (std::size_t i = 0; i < cpy.obs_.size(); ++i) {
159 cpy.obs_[i] = std::make_shared<Observation>(*(obs_[i]));
161 cpy.obs_[i]->set_data(dat_map.at(obs_[i]->data()));
165 for (std::size_t i = 0; i < cpy.procs_.size(); ++i) {
167 cpy.procs_[i] = std::make_shared<Process>(*(procs_[i]));
168 if (procs_[i]->pdf())
169 cpy.procs_[i]->set_pdf(pdf_map.at(procs_[i]->pdf()));
170 if (procs_[i]->observable())
171 cpy.procs_[i]->set_observable(var_map.at(procs_[i]->observable()));
172 if (procs_[i]->
data())
173 cpy.procs_[i]->set_data(dat_map.at(procs_[i]->data()));
174 if (procs_[i]->norm())
175 cpy.procs_[i]->set_norm(fun_map.at(procs_[i]->norm()));
179 for (std::size_t i = 0; i < cpy.systs_.size(); ++i) {
181 cpy.systs_[i] = std::make_shared<Systematic>(*(systs_[i]));
182 if (systs_[i]->data_u() || systs_[i]->data_d()) {
183 cpy.systs_[i]->set_data(
184 static_cast<RooDataHist*
>(dat_map.at(systs_[i]->data_u())),
185 static_cast<RooDataHist*
>(dat_map.at(systs_[i]->data_d())),
191 for (
auto const& it : params_) {
193 cpy.params_.insert({it.first, std::make_shared<Parameter>(*(it.second))});
195 params_.insert({it.first,
nullptr});
199 for (
auto it : cpy.params_) {
200 for (
unsigned i = 0; i < it.second->vars().size(); ++i) {
201 it.second->vars()[i] = var_map.at(it.second->vars()[i]);
232 for (
unsigned i = 0; i < obs_.size(); ++i)
233 std::cout << *(obs_[i]) <<
"\n";
239 for (
unsigned i = 0; i < procs_.size(); ++i)
240 std::cout << *(procs_[i]) <<
"\n";
246 for (
unsigned i = 0; i < systs_.size(); ++i)
247 std::cout << *(systs_[i]) <<
"\n";
253 for (
auto const& it : params_) std::cout << *(it.second) <<
"\n";
281 void CombineHarvester::LoadShapes(
Observation* entry,
282 std::vector<HistMapping>
const& mappings) {
285 throw std::runtime_error(
FNERROR(
"Observation already contains a shape"));
288 if (verbosity_ >= 2) {
289 LOGLINE(log(),
"Extracting shapes for Observation:");
292 for (HistMapping
const& m : mappings) log() << m <<
"\n";
297 if (mappings.size() == 0) {
298 if (verbosity_ >= 2)
LOGLINE(log(),
"No mappings in this card, assuming FAKE");
301 HistMapping mapping =
302 ResolveMapping(entry->process(), entry->bin(), mappings);
303 boost::replace_all(mapping.pattern,
"$CHANNEL", entry->bin());
304 boost::replace_all(mapping.pattern,
"$BIN", entry->bin());
305 boost::replace_all(mapping.pattern,
"$PROCESS", entry->process());
306 boost::replace_all(mapping.pattern,
"$MASS", entry->mass());
308 if (verbosity_ >= 2) {
309 LOGLINE(log(),
"Resolved Mapping:");
310 log() << mapping <<
"\n";
313 if (mapping.is_fake) {
314 if (verbosity_ >= 2)
LOGLINE(log(),
"Mapping type is FAKE");
315 }
else if (mapping.IsHist()) {
316 if (verbosity_ >= 2)
LOGLINE(log(),
"Mapping type in TH1");
319 std::unique_ptr<TH1> h =
GetClonedTH1(mapping.file.get(), mapping.pattern);
321 entry->set_shape(std::move(h),
true);
322 }
else if (mapping.IsData()) {
323 if (verbosity_ >= 2)
LOGLINE(log(),
"Mapping type is RooAbsData");
326 RooAbsData* dat = mapping.ws->data(mapping.WorkspaceObj().c_str());
328 throw std::runtime_error(
FNERROR(
"RooAbsData not found in workspace"));
331 entry->set_data(dat);
332 entry->set_rate(dat->sumEntries());
365 void CombineHarvester::LoadShapes(Process* entry,
366 std::vector<HistMapping>
const& mappings) {
368 if (entry->shape() || entry->pdf()) {
369 throw std::runtime_error(
FNERROR(
"Process already contains a shape"));
372 if (verbosity_ >= 2) {
373 LOGLINE(log(),
"Extracting shapes for Process:");
376 for (HistMapping
const& m : mappings) log() << m <<
"\n";
381 if (mappings.size() == 0) {
382 if (verbosity_ >= 2)
LOGLINE(log(),
"No mappings in this card, assuming FAKE");
385 HistMapping mapping =
386 ResolveMapping(entry->process(), entry->bin(), mappings);
387 boost::replace_all(mapping.pattern,
"$CHANNEL", entry->bin());
388 boost::replace_all(mapping.pattern,
"$BIN", entry->bin());
389 boost::replace_all(mapping.pattern,
"$PROCESS", entry->process());
390 boost::replace_all(mapping.pattern,
"$MASS", entry->mass());
392 if (verbosity_ >= 2) {
393 LOGLINE(log(),
"Resolved Mapping:");
394 log() << mapping <<
"\n";
397 if (mapping.is_fake) {
398 if (verbosity_ >= 2)
LOGLINE(log(),
"Mapping type is FAKE");
399 }
else if (mapping.IsHist()) {
400 if (verbosity_ >= 2)
LOGLINE(log(),
"Mapping type is TH1");
403 std::unique_ptr<TH1> h =
GetClonedTH1(mapping.file.get(), mapping.pattern);
405 if (flags_.at(
"check-negative-bins-on-import")) {
407 LOGLINE(log(),
"Warning: process shape has negative bins");
409 if (flags_.at(
"zero-negative-bins-on-import")) {
415 entry->set_shape(std::move(h),
true);
416 }
else if (mapping.IsPdf()) {
417 if (verbosity_ >= 2)
LOGLINE(log(),
"Mapping type is RooAbsPdf/RooAbsData");
420 RooAbsData*
data = mapping.ws->
data(mapping.WorkspaceObj().c_str());
421 RooAbsReal* pdf = mapping.ws->function(mapping.WorkspaceObj().c_str());
423 if (verbosity_ >= 2) {
424 data->printStream(log(),
data->defaultPrintContents(0),
425 data->defaultPrintStyle(0),
"[LoadShapes] ");
427 entry->set_data(
data);
428 entry->set_rate(
data->sumEntries());
430 if (verbosity_ >= 2) {
431 pdf->printStream(log(), pdf->defaultPrintContents(0),
432 pdf->defaultPrintStyle(0),
"[LoadShapes] ");
437 if (flags_.at(
"allow-missing-shapes")) {
438 LOGLINE(log(),
"Warning, shape missing:");
441 throw std::runtime_error(
FNERROR(
"RooAbsPdf not found in workspace"));
445 HistMapping norm_mapping = mapping;
446 if (!
data && norm_mapping.syst_pattern !=
"") {
449 norm_mapping.pattern = norm_mapping.syst_pattern;
450 boost::replace_all(norm_mapping.pattern,
"$CHANNEL", entry->bin());
451 boost::replace_all(norm_mapping.pattern,
"$BIN", entry->bin());
452 boost::replace_all(norm_mapping.pattern,
"$PROCESS", entry->process());
453 boost::replace_all(norm_mapping.pattern,
"$MASS", entry->mass());
455 norm_mapping.pattern +=
"_norm";
458 norm_mapping.ws->function(norm_mapping.WorkspaceObj().c_str());
461 entry->set_norm(norm);
462 if (verbosity_ >= 2) {
463 LOGLINE(log(),
"Normalisation RooAbsReal found");
464 norm->printStream(log(), norm->defaultPrintContents(0),
465 norm->defaultPrintStyle(0),
"[LoadShapes] ");
469 RooRealVar* norm_var =
dynamic_cast<RooRealVar*
>(norm);
471 RooArgSet tmp_set(*norm_var);
472 ImportParameters(&tmp_set);
478 RooAbsData
const* data_obj = FindMatchingData(entry);
480 if (verbosity_ >= 2)
LOGLINE(log(),
"Matching RooAbsData has been found");
483 ImportParameters(&argset);
484 if (!entry->observable()) {
485 std::string var_name;
486 if (data_obj) var_name = data_obj->get()->first()->GetName();
487 entry->set_observable(
488 (RooRealVar*)entry->pdf()->findServer(var_name.c_str()));
493 ImportParameters(&argset);
497 LOGLINE(log(),
"No RooAbsData found, assume observable CMS_th1x");
498 RooRealVar mx(
"CMS_th1x" ,
"CMS_th1x", 0, 1);
499 RooArgSet tmp_set(mx);
502 ImportParameters(&argset);
506 ImportParameters(&argset);
512 void CombineHarvester::LoadShapes(Systematic* entry,
513 std::vector<HistMapping>
const& mappings) {
514 if (entry->shape_u() || entry->shape_d() ||
515 entry->data_u() || entry->data_d()) {
516 throw std::runtime_error(
FNERROR(
"Systematic already contains a shape"));
519 if (verbosity_ >= 2) {
520 LOGLINE(log(),
"Extracting shapes for Systematic:");
523 for (HistMapping
const& m : mappings) log() << m <<
"\n";
528 HistMapping mapping =
529 ResolveMapping(entry->process(), entry->bin(), mappings);
530 boost::replace_all(mapping.pattern,
"$CHANNEL", entry->bin());
531 boost::replace_all(mapping.pattern,
"$BIN", entry->bin());
532 boost::replace_all(mapping.pattern,
"$PROCESS", entry->process());
533 boost::replace_all(mapping.pattern,
"$MASS", entry->mass());
535 mapping.IsPdf() ? mapping.SystWorkspaceObj() : mapping.syst_pattern;
536 boost::replace_all(p_s,
"$CHANNEL", entry->bin());
537 boost::replace_all(p_s,
"$BIN", entry->bin());
538 boost::replace_all(p_s,
"$PROCESS", entry->process());
539 boost::replace_all(p_s,
"$MASS", entry->mass());
540 std::string p_s_hi = p_s;
541 std::string p_s_lo = p_s;
542 boost::replace_all(p_s_hi,
"$SYSTEMATIC", entry->name() +
"Up");
543 boost::replace_all(p_s_lo,
"$SYSTEMATIC", entry->name() +
"Down");
544 if (mapping.IsHist()) {
545 if (verbosity_ >= 2)
LOGLINE(log(),
"Mapping type is TH1");
546 std::unique_ptr<TH1> h =
GetClonedTH1(mapping.file.get(), mapping.pattern);
547 std::unique_ptr<TH1> h_u =
GetClonedTH1(mapping.file.get(), p_s_hi);
548 std::unique_ptr<TH1> h_d =
GetClonedTH1(mapping.file.get(), p_s_lo);
550 if (flags_.at(
"check-negative-bins-on-import")) {
552 LOGLINE(log(),
"Warning: Systematic shape has negative bins");
554 if (flags_.at(
"zero-negative-bins-on-import")) {
560 LOGLINE(log(),
"Warning: Systematic shape_u has negative bins");
562 if (flags_.at(
"zero-negative-bins-on-import")) {
568 LOGLINE(log(),
"Warning: Systematic shape_d has negative bins");
570 if (flags_.at(
"zero-negative-bins-on-import")) {
575 entry->set_shapes(std::move(h_u), std::move(h_d), h.get());
576 }
else if (mapping.IsPdf()) {
577 if (verbosity_ >= 2)
LOGLINE(log(),
"Mapping type is RooDataHist");
581 (mapping.sys_ws) ?
dynamic_cast<RooDataHist*
>(mapping.sys_ws->data(mapping.WorkspaceObj().c_str())) :
nullptr;
583 (mapping.sys_ws) ?
dynamic_cast<RooDataHist*
>(mapping.sys_ws->data(p_s_hi.c_str())):
nullptr;
585 (mapping.sys_ws) ?
dynamic_cast<RooDataHist*
>(mapping.sys_ws->data(p_s_lo.c_str())):
nullptr;
586 RooAbsReal* pdf = (mapping.sys_ws) ? mapping.sys_ws->function(mapping.WorkspaceObj().c_str()):
nullptr;
587 RooAbsReal* pdf_u = (mapping.sys_ws) ? mapping.sys_ws->function(p_s_hi.c_str()):
nullptr;
588 RooAbsReal* pdf_d = (mapping.sys_ws) ? mapping.sys_ws->function(p_s_lo.c_str()):
nullptr;
590 if ((!h || !h_u || !h_d) && (!pdf || !pdf_u || !pdf_d)) {
591 if (flags_.at(
"allow-missing-shapes")) {
592 LOGLINE(log(),
"Warning, shape missing:");
595 throw std::runtime_error(
596 FNERROR(
"All shapes must be of type RooDataHist"));
598 }
else if (h && h_u && h_d){
599 entry->set_data(h_u, h_d, h);
600 }
else if (pdf && pdf_u &&pdf_d){
601 entry->set_pdf(pdf_u,pdf_d,pdf);
604 throw std::runtime_error(
605 FNERROR(
"Resolved mapping is not of TH1 / RooAbsData type"));
628 HistMapping
const& CombineHarvester::ResolveMapping(
629 std::string
const& process, std::string
const& bin,
630 std::vector<HistMapping>
const& mappings) {
631 StrPairVec attempts = GenerateShapeMapAttempts(
process,
bin);
632 for (
unsigned a = 0; a < attempts.size(); ++a) {
633 for (
unsigned m = 0; m < mappings.size(); ++m) {
634 if ((attempts[a].first == mappings[m].
process) &&
635 (attempts[a].second == mappings[m].category)) {
641 FNLOG(log()) <<
"Searching for mapping for (" <<
bin <<
"," <<
process <<
")\n";
642 FNLOG(log()) <<
"Avaiable mappings:\n";
643 for (
auto const& m : mappings) {
644 FNLOG(log()) << m <<
"\n";
646 throw std::runtime_error(
FNERROR(
"Valid mapping not found"));
649 CombineHarvester::StrPairVec CombineHarvester::GenerateShapeMapAttempts(
650 std::string process, std::string category) {
651 CombineHarvester::StrPairVec result;
652 result.push_back(std::make_pair(
process , category));
653 result.push_back(std::make_pair(
"*" , category));
654 result.push_back(std::make_pair(
process ,
"*"));
655 result.push_back(std::make_pair(
"*" ,
"*"));
659 std::shared_ptr<RooWorkspace> CombineHarvester::SetupWorkspace(
660 RooWorkspace
const& ws,
bool can_rename) {
661 bool name_in_use =
false;
664 for (
auto const& it : wspaces_) {
666 if (it.second->uuid() == ws.uuid() && flags_[
"workspace-uuid-recycle"]) {
667 FNLOGC(log(), verbosity_ >= 1)
668 <<
"Workspace with name " << it.second->GetName()
669 <<
" has the same UUID, will use this one\n";
672 if (!name_in_use && strcmp(it.second->GetName(), ws.GetName()) == 0) {
682 if (
GetFlag(
"workspaces-use-clone")) {
683 wspaces_[std::string(ws.GetName())] = std::shared_ptr<RooWorkspace>(
684 reinterpret_cast<RooWorkspace*
>(ws.Clone(ws.GetName()))
687 wspaces_[std::string(ws.GetName())] =
688 std::make_shared<RooWorkspace>(RooWorkspace(ws));
690 return wspaces_.at(ws.GetName());
696 throw std::runtime_error(
FNERROR(
"A different workspace with name " +
697 std::string(ws.GetName()) +
702 std::set<int> used_ints = {0};
703 std::string src_name(ws.GetName());
704 for (
auto const& it : wspaces_) {
705 std::string test_name(it.second->GetName());
706 if (test_name.find(src_name) == 0) {
707 std::string postfix = test_name.substr(src_name.size());
709 int number = boost::lexical_cast<int>(postfix);
710 used_ints.insert(number);
711 }
catch (boost::bad_lexical_cast & e) {
715 std::string new_name =
716 src_name + boost::lexical_cast<std::string>(*(used_ints.rbegin()) + 1);
717 FNLOGC(log(), verbosity_ >= 1) <<
"Workspace with name " << src_name
718 <<
" already defined, renaming to " << new_name
721 std::shared_ptr<RooWorkspace> new_wsp;
722 if (
GetFlag(
"workspaces-use-clone")) {
723 new_wsp = std::shared_ptr<RooWorkspace>(
724 reinterpret_cast<RooWorkspace*
>(ws.Clone(new_name.c_str()))
727 new_wsp = std::make_shared<RooWorkspace>(RooWorkspace(ws));
729 new_wsp->SetName(new_name.c_str());
730 wspaces_[new_name] = new_wsp;
731 return wspaces_.at(new_name);
734 void CombineHarvester::ImportParameters(RooArgSet *vars) {
735 for (RooAbsArg *x : *vars) {
736 RooRealVar *y =
dynamic_cast<RooRealVar*
>(x);
738 if (!params_.count(y->GetName())) {
739 if (verbosity_ >= 1) {
740 log() <<
"[ImportParameters] Creating parameter from RooRealVar:\n";
741 y->printStream(log(), y->defaultPrintContents(0),
742 y->defaultPrintStyle(0),
"[ImportParameters] ");
745 par.set_name(y->GetName());
746 par.set_val(y->getVal());
747 if ((y->hasError() || y->hasAsymError()) &&
748 flags_[
"import-parameter-err"]) {
749 par.set_err_d(y->getErrorLo());
750 par.set_err_u(y->getErrorHi());
755 params_[y->GetName()] = std::make_shared<Parameter>(par);
758 log() <<
"[ImportParameters] Parameter \"" << y->GetName()
759 <<
"\" already exists\n";
761 Parameter *param = params_[y->GetName()].get();
762 std::vector<RooRealVar *> & p_vars = param->vars();
763 if (std::find(p_vars.begin(), p_vars.end(), y) == p_vars.end()) {
766 log() <<
"[ImportParameters] Parameter now stores " << p_vars.size()
767 <<
" link(s) to RooRealVar objects\n";
770 log() <<
"[ImportParameters] Parameter already stores link to "
771 "RooRealVar object\n";
777 RooAbsData
const* CombineHarvester::FindMatchingData(Process
const* proc) {
778 RooAbsData
const* data_obj =
nullptr;
779 for (
unsigned i = 0; i < obs_.size(); ++i) {
780 if (proc->bin() == obs_[i]->bin() &&
781 proc->bin_id() == obs_[i]->bin_id()) {
782 data_obj = obs_[i]->data();
788 ch::Parameter* CombineHarvester::SetupRateParamVar(std::string
const& name,
789 double val,
bool is_ext_arg) {
790 RooWorkspace *ws =
nullptr;
791 if (!wspaces_.count(
"_rateParams")) {
792 ws = this->SetupWorkspace(RooWorkspace(
"_rateParams",
"_rateParams")).get();
794 ws = wspaces_.at(
"_rateParams").get();
797 RooRealVar *var = ws->var(name.c_str());
800 RooRealVar tmp_var(name.c_str(), name.c_str(), 0);
802 var = ws->var(name.c_str());
803 FNLOGC(log(), verbosity_ > 1)
804 <<
"Created new RooRealVar for rateParam: " << name <<
"\n";
805 if (verbosity_ > 1) var->Print();
807 FNLOGC(log(), verbosity_ > 1)
808 <<
"Reusing existing RooRealVar for rateParam: " << name <<
"\n";
810 if (is_ext_arg) var->setAttribute(
"extArg");
811 Parameter * param =
nullptr;
812 if (!params_.count(name)) {
813 params_[name] = std::make_shared<Parameter>(Parameter());
814 param = params_.at(name).get();
815 param->set_name(name);
816 param->set_err_u(0.);
817 param->set_err_d(0.);
819 param = params_.at(name).get();
822 bool var_in_par =
false;
823 for (
auto const& ptr : param->vars()) {
830 param->vars().push_back(var);
833 FNLOGC(log(), verbosity_ > 1) <<
"Updating parameter value from "
836 if (verbosity_ > 1) log() <<
" to " << param->val() <<
"\n";
840 void CombineHarvester::SetupRateParamFunc(std::string
const& name,
841 std::string
const& formula,
842 std::string
const& pars) {
843 RooWorkspace *ws =
nullptr;
844 if (!wspaces_.count(
"_rateParams")) {
845 ws = this->SetupWorkspace(RooWorkspace(
"_rateParams",
"_rateParams")).get();
847 ws = wspaces_.at(
"_rateParams").get();
849 RooAbsReal *form = ws->function(name.c_str());
852 RooFormulaVar formularvar(name.c_str(), name.c_str(),
854 RooArgList(ws->argSet(pars.c_str())));
855 ws->import(formularvar);
856 form = ws->function(name.c_str());
857 FNLOGC(log(), verbosity_ > 1)
858 <<
"Created new RooFormulaVar for rateParam: " << name <<
"\n";
859 if (verbosity_ > 1) form->Print();
863 void CombineHarvester::SetupRateParamWspObj(std::string
const& name,
864 std::string
const& obj,
bool is_ext_arg) {
865 RooWorkspace *ws =
nullptr;
866 if (!wspaces_.count(
"_rateParams")) {
867 ws = this->SetupWorkspace(RooWorkspace(
"_rateParams",
"_rateParams")).get();
869 ws = wspaces_.at(
"_rateParams").get();
871 ws->import((obj+
":"+name).c_str(), RooFit::RecycleConflictNodes());
872 ws->arg(name.c_str())->setStringAttribute(
"wspSource", obj.c_str());
873 if (is_ext_arg) ws->arg(name.c_str())->setAttribute(
"extArg");
876 bool CombineHarvester::SetupRateParamWspObjFromWsStore(std::string
const& name, std::string
const& obj,
877 std::map<std::string, std::shared_ptr<RooWorkspace>>
const& ws_store) {
878 bool found_arg_in_ws =
false;
879 RooWorkspace *ws =
nullptr;
880 if (!wspaces_.count(
"_rateParams")) {
881 ws = this->SetupWorkspace(RooWorkspace(
"_rateParams",
"_rateParams")).get();
883 ws = wspaces_.at(
"_rateParams").get();
885 std::vector<std::string> tokens;
886 boost::split(tokens, obj, boost::is_any_of(
":"));
888 std::string file_name_extArg = tokens[0];
889 std::string wsp_name_extArg = tokens[1];
891 RooAbsArg* warg =
nullptr;
892 for (
auto const& it : ws_store) {
893 if (boost::ends_with(it.first, file_name_extArg+wsp_name_extArg)){
894 warg = it.second->arg(name.c_str()) ;
899 if(warg && !ws->arg(name.c_str())) {
900 ws->import(*warg, RooFit::RecycleConflictNodes());
901 ws->arg(name.c_str())->setStringAttribute(
"wspSource", obj.c_str());
902 ws->arg(name.c_str())->setAttribute(
"extArg");
903 found_arg_in_ws =
true;
905 return found_arg_in_ws;
910 target.auto_stats_settings_[
bin] = AutoMCStatsSettings(thresh, sig, mode);
915 auto it = auto_stats_settings_.find(oldname);
916 if (it != auto_stats_settings_.end()) {
917 auto_stats_settings_[newname] = it->second;
918 auto_stats_settings_.erase(it);
923 std::set<std::string> result;
924 for (
auto const& it : auto_stats_settings_) {
925 result.insert(it.first);
937 double r=0.;
bool found=
false;
938 for (
auto & item : wspaces_) {
939 if (item.second.get()->var(name.c_str())) {
940 if (found) std::cout<<
"WARNING-DUPLICATE: ALREADY FOUND "<<name<<
"in an other ws"<<r<<std::endl;
941 r=item.second.get()->var(name.c_str())->getVal();
949 for (
auto & item : wspaces_) {
950 if (item.second.get()->var(name.c_str())){
951 if ( item.second.get()->var(name.c_str())->getMin() >value) item.second.get()->var(name.c_str())->setMin(value-0.001);
952 if ( item.second.get()->var(name.c_str())->getMax() <value) item.second.get()->var(name.c_str())->setMax(value+0.001);
953 item.second.get()->var(name.c_str())->setVal(value);
960 for (
auto & item : wspaces_) {
961 if ( (wsName==
"" or item.first == wsName ) and item.second.get()->var(name.c_str())){
962 item.second.get()->var(name.c_str())->SetName(newName.c_str());
CombineHarvester & PrintObs()
CombineHarvester & process(std::vector< std::string > const &vec, bool cond=true)
void RenameAutoMCStatsBin(std::string const &oldname, std::string const &newname)
void renameParInWs(const std::string &name, const std::string &newName, const std::string &wsName="")
CombineHarvester & data()
void SetFlag(std::string const &flag, bool const &value)
Set a named flag value.
CombineHarvester & operator=(CombineHarvester other)
CombineHarvester & PrintAll()
friend void swap(CombineHarvester &first, CombineHarvester &second)
CombineHarvester & bin(std::vector< std::string > const &vec, bool cond=true)
void SetAutoMCStats(CombineHarvester &target, double thresh, bool sig=false, int mode=1)
std::set< std::string > bin_set()
bool GetFlag(std::string const &flag) const
CombineHarvester & PrintParams()
std::set< std::string > GetAutoMCStatsBins() const
CombineHarvester & PrintProcs()
CombineHarvester deep()
Creates and retunrs a deep copy of the CombineHarvester instance.
CombineHarvester & PrintSysts()
double getParFromWs(const std::string name)
CombineHarvester cp()
Creates and returns a shallow copy of the CombineHarvester instance.
void AddExtArgValue(std::string const &name, double const &value)
void setParInWs(const std::string name, double value)
TH1 const * shape() const
static std::ostream & PrintHeader(std::ostream &out)
RooAbsData const * data() const
void set_err_u(double const &err_u)
void set_err_d(double const &err_d)
static std::ostream & PrintHeader(std::ostream &out)
static std::ostream & PrintHeader(std::ostream &out)
static std::ostream & PrintHeader(std::ostream &out)
bool HasNegativeBins(TH1 const *h)
void swap(CombineHarvester &first, CombineHarvester &second)
std::unique_ptr< TH1 > GetClonedTH1(TFile *file, std::string const &path)
void ZeroNegativeBins(TH1 *h)
RooArgSet ParametersByName(RooAbsReal const *pdf, RooArgSet const *dat_vars)