48 if (binning.isUniform()) {
50 axis[
"min"] << obs.
getMin();
51 axis[
"max"] << obs.
getMax();
53 auto &edges = axis[
"edges"];
55 double val = binning.binLow(0);
56 edges.append_child() << val;
57 for (
int i = 0; i < binning.numBins(); ++i) {
58 val = binning.binHigh(i);
59 edges.append_child() << val;
68 int ndigits = std::floor(std::log10(std::abs(
d))) + 1 -
nSig;
70 if (std::abs(
d /
sf) < 2)
72 return sf * std::round(
d /
sf);
81void erasePrefix(std::string &str, std::string_view prefix)
84 str.erase(0, prefix.size());
91 str.erase(str.size() -
suffix.size());
101 std::sort(
coll.
begin(),
coll.
end(), [](
auto &
l,
auto &
r) { return l.name < r.name; });
107 for (
const auto &client :
gamma->clients()) {
108 if (
auto casted =
dynamic_cast<T *
>(client)) {
152 return "gamma_" +
sysname +
"_bin_" + std::to_string(i);
160 for (std::size_t i = 0; i <
paramNames.size(); ++i) {
171 nom.setConstant(
true);
190 const std::vector<std::string> &
parnames,
const std::vector<double> &vals,
197 for (std::size_t i = 0; i < vals.size(); ++i) {
213 gamma->setConstant(
true);
222 if (!
comp.has_child(
"modifiers"))
224 for (
const auto &
mod :
comp[
"modifiers"].children()) {
225 if (
mod[
"type"].val() == ::Literals::staterror)
233 if (
comp.has_child(
"modifiers")) {
234 for (
const auto &
mod :
comp[
"modifiers"].children()) {
235 if (
mod[
"type"].val() == ::Literals::staterror)
240 ::Literals::staterror +
" modifier!");
255 if (!
p.has_child(
"data")) {
271 if (
p.has_child(
"modifiers")) {
281 for (
const auto &
mod :
p[
"modifiers"].children()) {
282 std::string
const &
modtype =
mod[
"type"].val();
284 mod.has_child(
"name")
286 : (
mod.has_child(
"parameter") ?
mod[
"parameter"].val() :
"syst_" + std::to_string(idx));
290 }
else if (
modtype ==
"normfactor") {
295 if (
auto gauss =
dynamic_cast<RooGaussian const *
>(constraint)) {
298 constraints.
add(*constraint);
300 }
else if (
modtype ==
"normsys") {
311 : std::numeric_limits<
double>::epsilon());
313 : std::numeric_limits<
double>::epsilon());
315 }
else if (
modtype ==
"histosys") {
328 }
else if (
modtype ==
"shapesys") {
331 std::vector<double> vals;
332 for (
const auto &
v :
mod[
"data"][
"vals"].children()) {
333 vals.push_back(
v.val_double());
336 for (
const auto &
v :
mod[
"parameters"].children()) {
342 std::string constraint(
mod[
"constraint"].val());
345 }
else if (
modtype ==
"custom") {
370 v.setAllInterpCodes(4);
392 if (!
p.has_child(
"samples")) {
397 if (
p.has_child(::Literals::staterror)) {
398 auto &
staterr =
p[::Literals::staterror];
399 if (
staterr.has_child(
"relThreshold"))
401 if (
staterr.has_child(
"constraint"))
404 std::vector<double>
sumW;
405 std::vector<double>
sumW2;
411 std::vector<std::unique_ptr<RooDataHist>>
data;
412 for (
const auto &
comp :
p[
"samples"].children()) {
415 size_t nbins =
dh->numEntries();
422 for (
size_t i = 0; i < nbins; ++i) {
424 sumW2[i] +=
dh->weightSquared(i);
434 data.emplace_back(std::move(
dh));
443 std::vector<double>
errs(
sumW.size());
444 for (
size_t i = 0; i <
sumW.size(); ++i) {
458 for (
const auto &
comp :
p[
"samples"].children()) {
467 if (constraints.
empty()) {
482 std::string
const &key()
const override
484 static const std::string
keystring =
"interpolation0d";
490 elem[
"type"] << key();
491 elem[
"interpolationCodes"].fill_seq(
fip->interpolationCodes());
494 elem[
"high"].fill_seq(
fip->high(),
fip->variables().size());
495 elem[
"low"].fill_seq(
fip->low(),
fip->variables().size());
502 std::string
const &key()
const override
504 static const std::string
keystring =
"interpolation";
510 elem[
"type"] << key();
511 elem[
"interpolationCodes"].fill_seq(
pip->interpolationCodes());
512 elem[
"positiveDefinite"] <<
pip->positiveDefinite();
514 elem[
"nom"] <<
pip->nominalHist()->GetName();
533 pip.setPositiveDefinite(
p[
"positiveDefinite"].val_bool());
535 if (
p.has_child(
"interpolationCodes")) {
537 for (
auto const &node :
p[
"interpolationCodes"].children()) {
538 pip.setInterpCode(*
static_cast<RooAbsReal *
>(vars.at(i)), node.val_int(),
true);
552 if (!
p.has_child(
"high")) {
555 if (!
p.has_child(
"low")) {
558 if (!
p.has_child(
"nom")) {
562 double nom(
p[
"nom"].val_double());
566 std::vector<double> high;
569 std::vector<double> low;
572 if (vars.size() != low.size() || vars.size() != high.size()) {
574 "' has non-matching lengths of 'vars', 'high' and 'low'!");
579 if (
p.has_child(
"interpolationCodes")) {
581 for (
auto const &node :
p[
"interpolationCodes"].children()) {
582 fip.setInterpCode(*
static_cast<RooAbsReal *
>(vars.at(i)), node.val_int());
593 if (
auto prod =
dynamic_cast<RooProduct *
>(arg)) {
594 for (
const auto &
e : prod->components()) {
619 :
name(
n), param(
p), low(
l), high(
h), constraint(
c)
626 std::vector<double> low;
627 std::vector<double> high;
630 :
name(
n), param(
p), constraint(
c)
632 low.assign(
l->dataHist().weightArray(),
l->dataHist().weightArray() +
l->dataHist().numEntries());
633 high.assign(
h->dataHist().weightArray(),
h->dataHist().weightArray() +
h->dataHist().numEntries());
638 std::vector<double> constraints;
639 std::vector<std::string> parameters;
640 TClass *constraint =
nullptr;
645 std::vector<double> hist;
646 std::vector<double> histError;
647 std::vector<NormFactor> normfactors;
648 std::vector<NormSys> normsys;
649 std::vector<HistoSys> histosys;
650 std::vector<ShapeSys> shapesys;
651 std::vector<RooAbsReal *> otherElements;
652 bool useBarlowBeestonLight =
false;
653 std::vector<std::string> staterrorParameters;
662 for (
RooAbsArg const *pdf : ws->allPdfs()) {
663 if (
auto gauss =
dynamic_cast<RooGaussian const *
>(pdf)) {
664 if (
parname == gauss->getX().GetName()) {
665 sample.normfactors.emplace_back(*par, gauss);
671 sample.normfactors.emplace_back(*par);
688 std::cout <<
pdfname <<
" is not a sumpdf" << std::endl;
700 std::cout <<
"sample " <<
sample->GetName() <<
" is no RooProduct or RooRealSumPdf in " <<
pdfname
710 long unsigned int nBins = 0;
716 std::vector<RooStats::HistFactory::FlexibleInterpVar *>
fips;
717 std::vector<ParamHistFunc *>
phfs;
732 nBins = dataHist.numEntries();
734 if (
sample.hist.empty()) {
735 auto *
w = dataHist.weightArray();
736 sample.hist.assign(
w,
w + dataHist.numEntries());
751 sample.normfactors.emplace_back(*
e);
753 }
else if (
auto par =
dynamic_cast<RooRealVar *
>(
e)) {
781 for (
size_t i = 0; i <
fip->variables().
size(); ++i) {
790 constraint ? constraint->
IsA() : nullptr);
798 for (
size_t i = 0; i <
pip->paramList().
size(); ++i) {
802 if (
auto lo =
dynamic_cast<RooHistFunc *
>(
pip->lowList().at(i))) {
808 sample.histosys.emplace_back(
sysname, var, lo,
hi, constraint ? constraint->
IsA() : nullptr);
819 for (
const auto &
g :
phf->paramList()) {
820 sample.staterrorParameters.push_back(
g->GetName());
830 sample.barlowBeestonLightConstraint = constraint->
IsA();
839 "currently, only RooPoisson and RooGaussian are supported as constraint types");
843 sample.useBarlowBeestonLight =
true;
850 for (
const auto &
g :
phf->paramList()) {
851 sys.parameters.push_back(
g->GetName());
857 if (!constraint && !
g->isConstant()) {
864 sys.constraints.push_back(0.0);
866 sys.constraints.push_back(1. / std::sqrt(
constraint_p->getX().getVal()));
867 if (!sys.constraint) {
872 if (!sys.constraint) {
877 sample.shapesys.emplace_back(std::move(sys));
889 if (
sample.hist.empty()) {
892 if (
sample.useBarlowBeestonLight) {
897 const int i = bin.first;
899 const double count =
sample.hist[i - 1];
910 elem[
"type"] <<
"histfactory_dist";
917 for (
const auto &
nf :
sample.normfactors) {
920 mod[
"name"] <<
nf.name;
921 mod[
"parameter"] <<
nf.param->GetName();
922 mod[
"type"] <<
"normfactor";
924 mod[
"constraint_name"] <<
nf.constraint->GetName();
925 tool->queueExport(*
nf.constraint);
929 for (
const auto &sys :
sample.normsys) {
932 mod[
"name"] << sys.name;
933 mod[
"type"] <<
"normsys";
934 mod[
"parameter"] << sys.param->GetName();
935 mod[
"constraint"] << toString(sys.constraint);
936 auto &
data =
mod[
"data"].set_map();
937 data[
"lo"] << sys.low;
938 data[
"hi"] << sys.high;
941 for (
const auto &sys :
sample.histosys) {
944 mod[
"name"] << sys.name;
945 mod[
"type"] <<
"histosys";
946 mod[
"parameter"] << sys.param->GetName();
947 mod[
"constraint"] << toString(sys.constraint);
948 auto &
data =
mod[
"data"].set_map();
949 if (nBins != sys.low.size() || nBins != sys.high.size()) {
950 std::stringstream
ss;
951 ss <<
"inconsistent binning: " << nBins <<
" bins expected, but " << sys.low.size() <<
"/"
952 << sys.high.size() <<
" found in nominal histogram errors!";
959 for (
const auto &sys :
sample.shapesys) {
962 mod[
"name"] << sys.name;
963 mod[
"type"] <<
"shapesys";
965 mod[
"constraint"] << toString(sys.constraint);
966 if (sys.constraint) {
967 auto &vals =
mod[
"data"].set_map()[
"vals"];
968 vals.fill_seq(sys.constraints);
970 auto &vals =
mod[
"data"].set_map()[
"vals"];
972 for (std::size_t i = 0; i < sys.parameters.size(); ++i) {
973 vals.append_child() << 0;
983 mod[
"type"] <<
"custom";
986 if (
sample.useBarlowBeestonLight) {
989 mod[
"name"] << ::Literals::staterror;
990 mod[
"type"] << ::Literals::staterror;
992 mod[
"constraint"] << toString(
sample.barlowBeestonLightConstraint);
998 auto &
out =
output.append_child().set_map();
1006 auto &
dataNode = s[
"data"].set_map();
1007 if (nBins !=
sample.hist.size()) {
1008 std::stringstream
ss;
1009 ss <<
"inconsistent binning: " << nBins <<
" bins expected, but " <<
sample.hist.size()
1010 <<
" found in nominal histogram!";
1014 if (!
sample.histError.empty()) {
1015 if (nBins !=
sample.histError.size()) {
1016 std::stringstream
ss;
1017 ss <<
"inconsistent binning: " << nBins <<
" bins expected, but " <<
sample.histError.size()
1018 <<
" found in nominal histogram errors!";
1036 tool->queueExport(*param);
1045 bool autoExportDependants()
const override {
return false; }
1063 std::string
const &key()
const override
1065 static const std::string
keystring =
"histfactory_dist";
1076 bool autoExportDependants()
const override {
return false; }
1081 std::string
const &key()
const override
1083 static const std::string
keystring =
"histfactory_dist";
bool startsWith(std::string_view str, std::string_view prefix)
bool endsWith(std::string_view str, std::string_view suffix)
ROOT::RRangeCast< T, false, Range_t > static_range_cast(Range_t &&coll)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
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 r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void funcs
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t modifier
A class which maps the current values of a RooRealVar (or a set of RooRealVars) to one of a number of...
The PiecewiseInterpolation is a class that can morph distributions into each other,...
void setPositiveDefinite(bool flag=true)
const_iterator begin() const
const_iterator end() const
Common abstract base class for objects that represent a value and a "shape" in RooFit.
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
bool isConstant() const
Check if the "Constant" attribute is set.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Abstract interface for all probability density functions.
TClass * IsA() const override
Int_t numBins(const char *rangeName=nullptr) const override
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
virtual double getMin(const char *name=nullptr) const
Get minimum of currently defined range.
Abstract base class for objects that represent a real value and implements functionality common to al...
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Returns the bin width (or volume) given a RooHistFunc.
Represents a constant real-valued object.
Container class to hold N-dimensional binned data.
virtual JSONNode & set_seq()=0
A real-valued function sampled from a multidimensional histogram.
Efficient implementation of a product of PDFs of the form.
Represents the product of a given set of RooAbsReal objects.
Implements a PDF constructed from a sum of functions:
Variable that can be changed from the outside.
const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false) const override
Return binning definition with name.
void setAllInterpCodes(int code)
Configuration for a constrained, coherent shape variation of affected samples.
Configuration for an un- constrained overall systematic to scale sample normalisations.
std::string GetName() const
Constrained bin-by-bin variation of affected histogram.
Persistable container for RooFit projects.
RooAbsPdf * pdf(RooStringView name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
RooAbsReal * function(RooStringView name) const
Retrieve function (RooAbsReal) with given name. Note that all RooAbsPdfs are also RooAbsReals....
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.
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.
TClass instances represent classes, structs and namespaces in the ROOT type system.
TClass * IsA() const override
const char * GetName() const override
Returns name of object.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
RooCmdArg RecycleConflictNodes(bool flag=true)
RooCmdArg Conditional(const RooArgSet &pdfSet, const RooArgSet &depSet, bool depsAreCond=false)
constexpr double defaultShapeSysGammaMax
constexpr double minShapeUncertainty
constexpr double defaultStatErrorGammaMax
constexpr double defaultGammaMin
CreateGammaConstraintsOutput createGammaConstraints(RooArgList const ¶mList, std::span< const double > relSigmas, double minSigma, Constraint::Type type)
#define STATIC_EXECUTE(MY_FUNC)
static uint64_t sum(uint64_t i)