76using std::string, std::make_unique, std::vector;
86#define NaN std::numeric_limits<double>::quiet_NaN()
95template <
typename Test,
template <
typename...>
class Ref>
99template <
template <
typename...>
class Ref,
typename... Args>
110template <
class MatrixT>
111inline size_t size(
const MatrixT &matrix);
121template <
class MatrixT>
124 if (!stream.good()) {
127 for (
size_t i = 0; i <
size(matrix); ++i) {
128 for (
size_t j = 0; j <
size(matrix); ++j) {
130 stream << std::setprecision(RooFit::SuperFloatPrecision::digits10) << matrix(i, j) <<
"\t";
132 stream << matrix(i, j) <<
"\t";
142template <
class MatrixT>
145 std::ofstream of(fname);
147 std::cerr <<
"unable to read file '" << fname <<
"'!" << std::endl;
156#pragma GCC diagnostic push
157#pragma GCC diagnostic ignored "-Wshadow"
158#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
159#include <boost/numeric/ublas/io.hpp>
160#include <boost/numeric/ublas/lu.hpp>
161#include <boost/numeric/ublas/matrix.hpp>
162#include <boost/numeric/ublas/matrix_expression.hpp>
163#include <boost/numeric/ublas/symmetric.hpp>
164#include <boost/numeric/ublas/triangular.hpp>
165#include <boost/operators.hpp>
167#pragma GCC diagnostic pop
169typedef boost::numeric::ublas::matrix<RooFit::SuperFloat>
Matrix;
176 for (
size_t i = 0; i < mat.size1(); ++i) {
177 for (
size_t j = 0; j < mat.size2(); ++j) {
178 std::cout << std::setprecision(RooFit::SuperFloatPrecision::digits10) << mat(i, j) <<
" ,\t";
180 std::cout << std::endl;
190 return matrix.size1();
198 return boost::numeric::ublas::identity_matrix<RooFit::SuperFloat>(
n);
208 for (
size_t i = 0; i <
n; ++i) {
209 for (
size_t j = 0; j <
n; ++j) {
210 mat(i, j) =
double(in(i, j));
223 for (
size_t i = 0; i <
n; ++i) {
224 for (
size_t j = 0; j <
n; ++j) {
225 mat(i, j) =
double(in(i, j));
237 return prod(
m, otherM);
245 boost::numeric::ublas::permutation_matrix<size_t> pm(
size(matrix));
249 int res = lu_factorize(lu, pm);
251 std::stringstream ss;
253 cxcoutP(Eval) << ss.str << std::endl;
256 lu_substitute(lu, pm, inverse);
257 }
catch (boost::numeric::ublas::internal_logic &error) {
311 bool status = lu.
Invert(inverse);
314 std::cerr <<
" matrix is not invertible!" << std::endl;
317 const size_t n =
size(inverse);
319 for (
size_t i = 0; i <
n; ++i) {
320 for (
size_t j = 0; j <
n; ++j) {
321 if (std::abs(inverse(i, j)) < 1
e-9)
340typedef std::vector<std::vector<bool>> FeynmanDiagram;
341typedef std::vector<std::vector<int>> MorphFuncPattern;
342typedef std::map<int, std::unique_ptr<RooAbsReal>> FormulaList;
347inline TString makeValidName(std::string
const& input)
350 retval.ReplaceAll(
"/",
"_");
351 retval.ReplaceAll(
"^",
"");
352 retval.ReplaceAll(
"*",
"X");
353 retval.ReplaceAll(
"[",
"");
354 retval.ReplaceAll(
"]",
"");
362std::string concatNames(
const List &
c,
const char *sep)
364 std::stringstream ss;
369 ss << itr->GetName();
379template <
class A,
class B>
380inline void assignElement(A &
a,
const B &
b)
382 a =
static_cast<A
>(
b);
387template <
class MatrixT>
388inline MatrixT readMatrixFromStreamT(std::istream &stream)
390 std::vector<std::vector<RooFit::SuperFloat>> matrix;
391 std::vector<RooFit::SuperFloat>
line;
392 while (!stream.eof()) {
393 if (stream.peek() ==
'\n') {
401 while (stream.peek() ==
' ' || stream.peek() ==
'\t') {
404 if (stream.peek() ==
'\n') {
405 matrix.push_back(
line);
409 MatrixT retval(matrix.size(), matrix.size());
410 for (
size_t i = 0; i < matrix.size(); ++i) {
411 if (matrix[i].
size() != matrix.size()) {
412 std::cerr <<
"matrix read from stream doesn't seem to be square!" << std::endl;
414 for (
size_t j = 0; j < matrix[i].size(); ++j) {
415 assignElement(retval(i, j), matrix[i][j]);
424template <
class MatrixT>
425inline MatrixT readMatrixFromFileT(
const char *fname)
427 std::ifstream in(fname);
429 std::cerr <<
"unable to read file '" << fname <<
"'!" << std::endl;
431 MatrixT mat = readMatrixFromStreamT<MatrixT>(in);
440void readValues(std::map<const std::string, T> &myMap,
TH1 *h_pc)
444 for (
int ibx = 1; ibx <= h_pc->
GetNbinsX(); ++ibx) {
449 if (!s_coup.empty()) {
450 myMap[s_coup] = T(coup_val);
459void setOwnerRecursive(
TFolder *theFolder)
464 for (
auto *subdir : *subdirs) {
465 auto thisfolder =
dynamic_cast<TFolder *
>(subdir);
468 setOwnerRecursive(thisfolder);
481std::unique_ptr<TFolder> readOwningFolderFromFile(
TDirectory *inFile,
const std::string &folderName)
483 std::unique_ptr<TFolder> theFolder(inFile->
Get<
TFolder>(folderName.c_str()));
485 std::cerr <<
"Error: unable to access data from folder '" << folderName <<
"' from file '" << inFile->
GetName()
486 <<
"'!" << std::endl;
489 setOwnerRecursive(theFolder.get());
502template <
class AObjType>
503std::unique_ptr<AObjType> loadFromFileResidentFolder(
TDirectory *inFile,
const std::string &folderName,
504 const std::string &objName,
bool notFoundError =
true)
506 auto folder = readOwningFolderFromFile(inFile, folderName);
510 AObjType *loadedObject =
dynamic_cast<AObjType *
>(folder->FindObject(objName.c_str()));
513 std::stringstream errstr;
514 errstr <<
"Error: unable to retrieve object '" << objName <<
"' from folder '" << folderName
515 <<
"'. contents are:";
516 TIter next(folder->GetListOfFolders()->begin());
518 while ((
f =
static_cast<TFolder *
>(next()))) {
519 errstr <<
" " <<
f->GetName();
521 std::cerr << errstr.str() << std::endl;
527 return std::unique_ptr<AObjType>{
static_cast<AObjType *
>(loadedObject->Clone())};
534void readValues(std::map<const std::string, T> &myMap,
TDirectory *file,
const std::string &
name,
535 const std::string &key =
"param_card",
bool notFoundError =
true)
537 auto h_pc = loadFromFileResidentFolder<TH1F>(file,
name, key, notFoundError);
538 readValues(myMap, h_pc.get());
547void readValues(std::map<
const std::string, std::map<const std::string, T>> &inputParameters,
TDirectory *
f,
548 const std::vector<std::string> &names,
const std::string &key =
"param_card",
bool notFoundError =
true)
550 inputParameters.clear();
553 for (
size_t i = 0; i < names.size(); i++) {
554 const std::string
name(names[i]);
556 readValues(inputParameters[
name],
f,
name, key, notFoundError);
565inline TDirectory *openFile(
const std::string &filename)
567 if (filename.empty()) {
571 if (!file || !file->
IsOpen()) {
574 std::cerr <<
"could not open file '" << filename <<
"'!" << std::endl;
596inline void extractServers(
const RooAbsArg &coupling,
T2 &operators)
599 for (
const auto server : coupling.
servers()) {
600 extractServers(*server, operators);
604 operators.add(coupling);
611template <class T1, class T2, typename std::enable_if<!is_specialization<T1, std::vector>::value,
T1>::type * =
nullptr>
612inline void extractOperators(
const T1 &couplings,
T2 &operators)
616 for (
auto itr : couplings) {
617 extractServers(*itr, operators);
624template <class T1, class T2, typename std::enable_if<is_specialization<T1, std::vector>::value,
T1>::type * =
nullptr>
625inline void extractOperators(
const T1 &
vec,
T2 &operators)
627 for (
const auto &
v :
vec) {
628 extractOperators(
v, operators);
635template <
class T1,
class T2>
636inline void extractCouplings(
const T1 &inCouplings,
T2 &outCouplings)
638 for (
auto itr : inCouplings) {
639 if (!outCouplings.find(itr->GetName())) {
642 outCouplings.add(*itr);
651inline bool setParam(
RooRealVar *p,
double val,
bool force)
658 std::cerr <<
": parameter " << p->
GetName() <<
" out of bounds: " << val <<
" > " << p->
getMax() << std::endl;
661 }
else if (val < p->getMin()) {
665 std::cerr <<
": parameter " << p->
GetName() <<
" out of bounds: " << val <<
" < " << p->
getMin() << std::endl;
678template <
class T1,
class T2>
679inline bool setParams(
const T2 &args,
T1 val)
681 for (
auto itr : args) {
685 setParam(param, val,
true);
694template <
class T1,
class T2>
696setParams(
const std::map<const std::string, T1> &point,
const T2 &args,
bool force =
false,
T1 defaultVal = 0)
699 for (
auto itr : args) {
703 ok = setParam(param, defaultVal, force) && ok;
706 for (
auto paramit : point) {
708 const std::string param(paramit.first);
714 ok = setParam(p, paramit.second, force) && ok;
724inline bool setParams(
TH1 *hist,
const T &args,
bool force =
false)
728 for (
auto itr : args) {
732 ok = setParam(param, 0., force) && ok;
737 for (
int i = 1; i <= ax->GetNbins(); ++i) {
755 for (
auto itr : parameters) {
772 bool binningOK =
false;
773 for (
auto sampleit : inputParameters) {
774 const std::string sample(sampleit.first);
775 auto hist = loadFromFileResidentFolder<TH1>(file, sample, varname,
true);
783 auto it = list_hf.find(sample);
784 if (it != list_hf.end()) {
796 std::vector<double> bins;
797 for (
int i = 1; i <
n + 1; ++i) {
805 TString histname = makeValidName(
"dh_" + sample +
"_" +
name);
806 TString funcname = makeValidName(
"phys_" + sample +
"_" +
name);
810 auto dh = std::make_unique<RooDataHist>(histname.
Data(), histname.
Data(), vars, hist.get());
812 auto hf = std::make_unique<RooHistFunc>(funcname.
Data(), funcname.
Data(), var, std::move(dh));
813 int idx = physics.
size();
814 list_hf[sample] = idx;
825void collectRooAbsReal(
const char * ,
TDirectory *file, std::map<std::string, int> &list_hf,
826 RooArgList &physics,
const std::string &varname,
829 for (
auto sampleit : inputParameters) {
830 const std::string sample(sampleit.first);
831 auto obj = loadFromFileResidentFolder<RooAbsReal>(file, sample, varname,
true);
834 auto it = list_hf.find(sample);
835 if (it == list_hf.end()) {
836 int idx = physics.
size();
837 list_hf[sample] = idx;
848void collectCrosssections(
const char *
name,
TDirectory *file, std::map<std::string, int> &list_xs,
RooArgList &physics,
851 for (
auto sampleit : inputParameters) {
852 const std::string sample(sampleit.first);
853 auto obj = loadFromFileResidentFolder<TObject>(file, sample, varname,
false);
866 std::stringstream errstr;
867 errstr <<
"Error: unable to retrieve cross section '" << varname <<
"' from folder '" << sample;
871 auto it = list_xs.find(sample);
873 if (it != list_xs.end()) {
877 std::string objname =
"phys_" + std::string(
name) +
"_" + sample;
878 auto xsOwner = std::make_unique<RooRealVar>(objname.c_str(), objname.c_str(), xsection->
GetVal());
881 int idx = physics.
size();
882 list_xs[sample] = idx;
883 physics.
addOwned(std::move(xsOwner));
884 assert(physics.
at(idx) == xs);
896void collectCrosssectionsTPair(
const char *
name,
TDirectory *file, std::map<std::string, int> &list_xs,
897 RooArgList &physics,
const std::string &varname,
const std::string &basefolder,
900 auto pair = loadFromFileResidentFolder<TPair>(file, basefolder, varname,
false);
904 collectCrosssections<double>(
name, file, list_xs, physics, varname, inputParameters);
906 collectCrosssections<float>(
name, file, list_xs, physics, varname, inputParameters);
908 std::cerr <<
"cannot morph objects of class 'TPair' if parameter is not "
922void collectPolynomialsHelper(
const FeynmanDiagram &diagram, MorphFuncPattern &morphfunc, std::vector<int> &term,
923 int vertexid,
bool first)
926 for (
size_t i = 0; i < diagram[vertexid - 1].size(); ++i) {
927 if (!diagram[vertexid - 1][i])
929 std::vector<int> newterm(term);
932 ::collectPolynomialsHelper(diagram, morphfunc, newterm, vertexid,
false);
934 ::collectPolynomialsHelper(diagram, morphfunc, newterm, vertexid - 1,
true);
939 for (
size_t i = 0; i < morphfunc.size(); ++i) {
940 bool thisfound =
true;
941 for (
size_t j = 0; j < morphfunc[i].size(); ++j) {
942 if (morphfunc[i][j] != term[j]) {
953 morphfunc.push_back(term);
961void collectPolynomials(MorphFuncPattern &morphfunc,
const FeynmanDiagram &diagram)
963 int nvtx(diagram.size());
964 std::vector<int> term(diagram[0].
size(), 0);
966 ::collectPolynomialsHelper(diagram, morphfunc, term, nvtx,
true);
973inline void fillFeynmanDiagram(FeynmanDiagram &diagram,
const std::vector<List *> &vertices,
RooArgList &couplings)
975 const int ncouplings = couplings.
size();
977 for (
auto const &vertex : vertices) {
978 std::vector<bool> vertexCouplings(ncouplings,
false);
981 for (
auto citr : couplings) {
985 std::cerr <<
"encountered invalid list of couplings in vertex!" << std::endl;
988 if (vertex->find(coupling->
GetName())) {
989 vertexCouplings[idx] =
true;
992 diagram.push_back(vertexCouplings);
999template <
class MatrixT,
class T1,
class T2>
1003 const size_t dim = inputParameters.size();
1004 MatrixT matrix(dim, dim);
1006 for (
auto sampleit : inputParameters) {
1007 const std::string sample(sampleit.first);
1009 if (!setParams<double>(sampleit.second, args,
true, 0)) {
1010 std::cout <<
"unable to set parameters for sample " << sample <<
"!" << std::endl;
1012 auto flagit = flagValues.find(sample);
1013 if (flagit != flagValues.end() && !setParams<int>(flagit->second, flags,
true, 1)) {
1014 std::cout <<
"unable to set parameters for sample " << sample <<
"!" << std::endl;
1018 for (
auto const &formula : formulas) {
1019 if (!formula.second) {
1020 std::cerr <<
"Error: invalid formula encountered!" << std::endl;
1022 matrix(row, col) = formula.second->getVal();
1035 if (inputParameters.size() != formulas.size()) {
1036 std::stringstream ss;
1037 ss <<
"matrix is not square, consistency check failed: " << inputParameters.size() <<
" samples, "
1038 << formulas.size() <<
" expressions:" << std::endl;
1039 ss <<
"formulas: " << std::endl;
1040 for (
auto const &formula : formulas) {
1041 ss << formula.second->GetTitle() << std::endl;
1043 ss <<
"samples: " << std::endl;
1044 for (
auto sample : inputParameters) {
1045 ss << sample.first << std::endl;
1047 std::cerr << ss.str() << std::endl;
1054inline void inverseSanity(
const Matrix &matrix,
const Matrix &inverse,
double &unityDeviation,
double &largestWeight)
1056 Matrix unity(inverse * matrix);
1058 unityDeviation = 0.;
1060 const size_t dim =
size(unity);
1061 for (
size_t i = 0; i <
dim; ++i) {
1062 for (
size_t j = 0; j <
dim; ++j) {
1063 if (inverse(i, j) > largestWeight) {
1064 largestWeight = (
double)inverse(i, j);
1066 if (std::abs(unity(i, j) -
static_cast<int>(i == j)) > unityDeviation) {
1067 unityDeviation = std::abs((
double)unity(i, j)) -
static_cast<int>(i == j);
1075template <
class List>
1078 for (
auto sampleit : inputParameters) {
1079 const std::string sample(sampleit.first);
1080 RooAbsArg *arg = args.find(sample.c_str());
1082 std::cerr <<
"detected name conflict: cannot use sample '" << sample
1083 <<
"' - a parameter with the same name of type '" << arg->
ClassName() <<
"' is present in set '"
1084 << args.GetName() <<
"'!" << std::endl;
1096 const std::vector<std::vector<std::string>> &nonInterfering)
1105 const int ncouplings = couplings.
size();
1106 std::vector<bool> couplingsZero(ncouplings,
true);
1107 std::map<TString, bool> flagsZero;
1110 extractOperators(couplings, operators);
1111 size_t nOps = operators.
size();
1113 for (
auto sampleit : inputParameters) {
1114 const std::string sample(sampleit.first);
1115 if (!setParams(sampleit.second, operators,
true)) {
1116 std::cerr <<
"unable to set parameters for sample '" << sample <<
"'!" << std::endl;
1119 if (nOps != (operators.
size())) {
1120 std::cerr <<
"internal error, number of operators inconsistent!" << std::endl;
1126 for (
auto itr1 : couplings) {
1128 if (obj0->
getVal() != 0) {
1129 couplingsZero[idx] =
false;
1135 for (
auto itr2 : flags) {
1136 auto obj1 =
dynamic_cast<RooAbsReal *
>(itr2);
1139 for (
auto sampleit : inputFlags) {
1140 const auto &flag = sampleit.second.find(obj1->GetName());
1141 if (flag != sampleit.second.end()) {
1142 if (flag->second == 0.) {
1149 if (nZero > 0 && nNonZero == 0) {
1150 flagsZero[obj1->GetName()] =
true;
1152 flagsZero[obj1->GetName()] =
false;
1156 FormulaList formulas;
1157 for (
size_t i = 0; i < morphfunc.size(); ++i) {
1159 bool isZero =
false;
1162 for (
const auto &
group : nonInterfering) {
1163 int nInterferingOperators = 0;
1164 for (
size_t j = 0; j < morphfunc[i].size(); ++j) {
1165 if (morphfunc[i][j] % 2 == 0)
1168 if (std::find(
group.begin(),
group.end(), couplings.at(j)->GetName()) !=
group.end()) {
1169 nInterferingOperators++;
1172 if (nInterferingOperators > 1) {
1174 reason =
"blacklisted interference term!";
1180 for (
size_t j = 0; j < morphfunc[i].size(); ++j) {
1181 const int exponent = morphfunc[i][j];
1185 for (
int k = 0; k < exponent; ++k) {
1191 std::string cname(coupling->
GetName());
1194 reason =
"coupling " + cname +
" was listed as leading-order-only";
1197 if (!isZero && couplingsZero[j]) {
1199 reason =
"coupling " + cname +
" is zero!";
1204 bool removedByFlag =
false;
1206 for (
auto itr : flags) {
1210 TString sval(obj->getStringAttribute(
"NewPhysics"));
1211 int val = atoi(sval);
1213 if (flagsZero.find(obj->GetName()) != flagsZero.end() && flagsZero.at(obj->GetName())) {
1214 removedByFlag =
true;
1215 reason =
"flag " + std::string(obj->GetName()) +
" is zero";
1222 if (!isZero && !removedByFlag) {
1224 const auto name = std::string(mfname) +
"_pol" + std::to_string(i);
1225 formulas[i] = std::make_unique<RooProduct>(
name.c_str(), ::concatNames(ss,
" * ").c_str(), ss);
1236 const std::vector<std::vector<RooArgList *>> &diagrams,
RooArgList &couplings,
1237 const RooArgList &flags,
const std::vector<std::vector<std::string>> &nonInterfering)
1239 MorphFuncPattern morphfuncpattern;
1241 for (
const auto &vertices : diagrams) {
1243 ::fillFeynmanDiagram(
d, vertices, couplings);
1244 ::collectPolynomials(morphfuncpattern,
d);
1246 FormulaList retval = buildFormulas(
name, inputs, inputFlags, morphfuncpattern, couplings, flags, nonInterfering);
1247 if (retval.empty()) {
1248 std::stringstream errorMsgStream;
1250 <<
"no formulas are non-zero, check if any if your couplings is floating and missing from your param_cards!"
1252 const auto errorMsg = errorMsgStream.str();
1253 throw std::runtime_error(errorMsg);
1255 checkMatrix(inputs, retval);
1264 FormulaList &formulas,
const Matrix &inverse)
1268 for (
auto sampleit : inputParameters) {
1269 const std::string sample(sampleit.first);
1270 std::stringstream title;
1271 TString name_full(makeValidName(sample));
1273 name_full.Append(
"_");
1274 name_full.Append(fname);
1275 name_full.Prepend(
"w_");
1280 auto sampleformula = std::make_unique<RooLinearCombination>(name_full.Data());
1281 for (
auto const &formulait : formulas) {
1283 sampleformula->add(val, formulait.second.get());
1286 weights.addOwned(std::move(sampleformula));
1291inline std::map<std::string, std::string>
1296 std::map<std::string, std::string> weights;
1297 for (
auto sampleit : inputParameters) {
1298 const std::string sample(sampleit.first);
1299 std::stringstream str;
1302 for (
auto const &formulait : formulas) {
1303 double val(inverse(formulaidx, sampleidx));
1305 if (formulaidx > 0 && val > 0)
1307 str << val <<
"*(" << formulait.second->GetTitle() <<
")";
1311 weights[sample] = str.str();
1346 args.
add(*(it.second));
1356 const std::vector<std::vector<RooListProxy *>> &diagramProxyList,
1357 const std::vector<std::vector<std::string>> &nonInterfering,
const RooArgList &flags)
1360 std::vector<std::vector<RooArgList *>> diagrams;
1361 for (
const auto &diagram : diagramProxyList) {
1362 diagrams.emplace_back();
1365 diagrams.back().emplace_back(vertex);
1369 _formulas = ::createFormulas(funcname, inputParameters, inputFlags, diagrams,
_couplings, flags, nonInterfering);
1374 template <
class List>
1380 Matrix matrix(buildMatrixT<Matrix>(inputParameters,
_formulas, operators, inputFlags, flags));
1381 if (
size(matrix) < 1) {
1382 std::cerr <<
"input matrix is empty, please provide suitable input samples!" << std::endl;
1387 double unityDeviation;
1388 double largestWeight;
1389 inverseSanity(matrix, inverse, unityDeviation, largestWeight);
1395 oocxcoutW((
TObject *)
nullptr, Eval) <<
"Warning: The matrix inversion seems to be unstable. This can "
1396 "be a result to input samples that are not sufficiently "
1397 "different to provide any morphing power."
1399 }
else if (weightwarning) {
1400 oocxcoutW((
TObject *)
nullptr, Eval) <<
"Warning: Some weights are excessively large. This can be a "
1401 "result to input samples that are not sufficiently different to "
1402 "provide any morphing power."
1406 "encoded in your samples to cross-check:"
1408 for (
auto sampleit : inputParameters) {
1409 const std::string sample(sampleit.first);
1412 setParams(sampleit.second, operators,
true);
1439 const std::map<std::string, int> &storage,
const RooArgList &physics,
1443 std::cerr <<
"invalid bin width given!" << std::endl;
1447 std::cerr <<
"invalid observable given!" << std::endl;
1461 for (
auto sampleit : inputParameters) {
1463 TString prodname(makeValidName(sampleit.first));
1468 std::cerr <<
"unable to access physics object for " << prodname << std::endl;
1475 std::cerr <<
"unable to access weight object for " << prodname << std::endl;
1482 allowNegativeYields =
true;
1483 auto prod = std::make_unique<RooProduct>(prodname, prodname, prodElems);
1484 if (!allowNegativeYields) {
1485 auto maxname = std::string(prodname) +
"_max0";
1488 auto max = std::make_unique<RooFormulaVar>(maxname.c_str(),
"max(0," + prodname +
")", prodset);
1489 max->addOwnedComponents(std::move(prod));
1490 sumElements.
addOwned(std::move(max));
1492 sumElements.
addOwned(std::move(prod));
1494 scaleElements.
add(*(binWidth));
1499 _sumFunc = make_unique<RooRealSumFunc>((std::string(
name) +
"_morphfunc").c_str(),
name, sumElements, scaleElements);
1502 std::cerr <<
"unable to access observable" << std::endl;
1505 std::cerr <<
"unable to access bin width" << std::endl;
1507 if (operators.
empty())
1508 std::cerr <<
"no operators listed" << std::endl;
1509 _sumFunc->addServerList(operators);
1511 std::cerr <<
"unable to access weight objects" << std::endl;
1512 _sumFunc->addOwnedComponents(std::move(sumElements));
1513 _sumFunc->addServerList(sumElements);
1514 _sumFunc->addServerList(scaleElements);
1517 std::cout.precision(std::numeric_limits<double>::digits);
1534 if (obsName.empty()) {
1535 std::cerr <<
"Matrix inversion succeeded, but no observable was "
1536 "supplied. quitting..."
1544 setParams(func->
_flags, 1);
1548 setParams(func->
_flags, 1);
1571 setParams(func->
_flags, 1);
1575 setParams(func->
_flags, 1);
1605 return readMatrixFromFileT<TMatrixD>(fname);
1613 return readMatrixFromStreamT<TMatrixD>(stream);
1623 bool obsExists(
false);
1630 obs =
static_cast<RooRealVar *
>(
dynamic_cast<RooHistFunc *
>(inputExample)->getHistObsList().first());
1644 TH1 *hist =
static_cast<TH1 *
>(inputExample);
1647 obs = obsOwner.get();
1651 auto obsOwner = std::make_unique<RooRealVar>(obsname, obsname, 0, 1);
1652 obs = obsOwner.get();
1658 if (strcmp(obsname, obs->
GetName()) != 0) {
1659 coutW(ObjectHandling) <<
" name of existing observable " <<
_observables.at(0)->GetName()
1660 <<
" does not match expected name " << obsname << std::endl;
1665 auto binWidth = std::make_unique<RooRealVar>(sbw.
Data(), sbw.
Data(), 1.);
1667 binWidth->setVal(bw);
1668 binWidth->setConstant(
true);
1687 const size_t n(
size(cache->_inverse));
1688 for (
auto sampleit :
_config.paramCards) {
1689 const std::string sample(sampleit.first);
1692 if (!sampleformula) {
1693 coutE(ObjectHandling) <<
Form(
"unable to access formula for sample '%s'!", sample.c_str()) << std::endl;
1696 cxcoutP(ObjectHandling) <<
"updating formula for sample '" << sample <<
"'" << std::endl;
1697 for (
size_t formulaidx = 0; formulaidx <
n; ++formulaidx) {
1702 if (std::isnan(val)) {
1704 coutE(ObjectHandling) <<
"refusing to propagate NaN!" << std::endl;
1706 cxcoutP(ObjectHandling) <<
" " << formulaidx <<
":" << sampleformula->
getCoefficient(formulaidx) <<
" -> "
1707 << val << std::endl;
1727 readValues<double>(
_config.paramCards,
f,
_config.folderNames,
"param_card",
true);
1728 readValues<int>(
_config.flagValues,
f,
_config.folderNames,
"flags",
false);
1736 std::string obsName;
1739 if (
_config.observableName.empty()) {
1742 obsName =
_config.observableName;
1745 obsName =
_config.observableName;
1748 cxcoutP(InputArguments) <<
"initializing physics inputs from file " << file->
GetName() <<
" with object name(s) '"
1749 << obsName <<
"'" << std::endl;
1750 auto folderNames =
_config.folderNames;
1751 auto obj = loadFromFileResidentFolder<TObject>(file, folderNames.front(), obsName,
true);
1753 std::cerr <<
"unable to locate object '" << obsName <<
"' in folder '" << folderNames.front() <<
"'!"
1757 std::string classname = obj->ClassName();
1761 if (classname.find(
"TH1") != std::string::npos) {
1764 }
else if (classname.find(
"RooHistFunc") != std::string::npos ||
1765 classname.find(
"RooParamHistFunc") != std::string::npos ||
1766 classname.find(
"PiecewiseInterpolation") != std::string::npos) {
1768 }
else if (classname.find(
"TParameter<double>") != std::string::npos) {
1770 }
else if (classname.find(
"TParameter<float>") != std::string::npos) {
1772 }
else if (classname.find(
"TPair") != std::string::npos) {
1776 std::cerr <<
"cannot morph objects of class '" << mode->
GetName() <<
"'!" << std::endl;
1785 for (
const auto ¶m :
_config.paramCards.at(samplename)) {
1787 std::cout << param.first <<
" = " << param.second;
1789 std::cout <<
" (const)";
1790 std::cout << std::endl;
1801 for (
auto folder :
_config.folderNames) {
1802 std::cout << folder << std::endl;
1824 _operators(
"operators",
"set of operators", this),
_observables(
"observables",
"morphing observables", this),
1840 if (!
_config.couplings.empty()) {
1842 std::vector<RooListProxy *> vertices;
1843 extractOperators(
_config.couplings, operators);
1844 vertices.push_back(
new RooListProxy(
"!couplings",
"set of couplings in the vertex",
this,
true,
false));
1847 vertices[0]->addOwned(
_config.couplings);
1850 vertices[0]->add(
_config.couplings);
1855 else if (!
_config.prodCouplings.empty() && !
_config.decCouplings.empty()) {
1856 std::vector<RooListProxy *> vertices;
1858 cxcoutP(InputArguments) <<
"prod/dec couplings provided" << std::endl;
1859 extractOperators(
_config.prodCouplings, operators);
1860 extractOperators(
_config.decCouplings, operators);
1862 new RooListProxy(
"!production",
"set of couplings in the production vertex",
this,
true,
false));
1863 vertices.push_back(
new RooListProxy(
"!decay",
"set of couplings in the decay vertex",
this,
true,
false));
1866 vertices[0]->addOwned(
_config.prodCouplings);
1867 vertices[1]->addOwned(
_config.decCouplings);
1869 cxcoutP(InputArguments) <<
"adding non-own operators" << std::endl;
1871 vertices[0]->add(
_config.prodCouplings);
1872 vertices[1]->add(
_config.decCouplings);
1884 std::stringstream
name;
1885 name <<
"noInterference";
1886 for (
auto c : nonInterfering) {
1890 for (
auto c : nonInterfering) {
1901 for (
size_t i = 0; i < nonInterfering.size(); ++i) {
1911 std::string filename =
_config.fileName;
1914 coutE(InputArguments) <<
"unable to open file '" << filename <<
"'!" << std::endl;
1921 auto nNP0 = std::make_unique<RooRealVar>(
"nNP0",
"nNP0", 1., 0, 1.);
1922 nNP0->setStringAttribute(
"NewPhysics",
"0");
1923 nNP0->setConstant(
true);
1924 _flags.addOwned(std::move(nNP0));
1925 auto nNP1 = std::make_unique<RooRealVar>(
"nNP1",
"nNP1", 1., 0, 1.);
1926 nNP1->setStringAttribute(
"NewPhysics",
"1");
1927 nNP1->setConstant(
true);
1928 _flags.addOwned(std::move(nNP1));
1929 auto nNP2 = std::make_unique<RooRealVar>(
"nNP2",
"nNP2", 1., 0, 1.);
1930 nNP2->setStringAttribute(
"NewPhysics",
"2");
1931 nNP2->setConstant(
true);
1932 _flags.addOwned(std::move(nNP2));
1933 auto nNP3 = std::make_unique<RooRealVar>(
"nNP3",
"nNP3", 1., 0, 1.);
1934 nNP3->setStringAttribute(
"NewPhysics",
"3");
1935 nNP3->setConstant(
true);
1936 _flags.addOwned(std::move(nNP3));
1937 auto nNP4 = std::make_unique<RooRealVar>(
"nNP4",
"nNP4", 1., 0, 1.);
1938 nNP4->setStringAttribute(
"NewPhysics",
"4");
1939 nNP4->setConstant(
true);
1940 _flags.addOwned(std::move(nNP4));
1954 for (
size_t j = 0; j < other.
_diagrams.size(); ++j) {
1955 std::vector<RooListProxy *> diagram;
1956 for (
size_t i = 0; i < other.
_diagrams[j].size(); ++i) {
1958 diagram.push_back(list);
1985 :
_cacheMgr(this, 10, true, true),
_operators(
"operators",
"set of operators", this, true, false),
1986 _observables(
"observable",
"morphing observable", this, true, false),
1987 _binWidths(
"binWidths",
"set of bin width objects", this, true, false)
2011 FeynmanDiagram diagram;
2012 std::vector<bool> prod;
2013 std::vector<bool> dec;
2014 for (
int i = 0; i < nboth; ++i) {
2015 prod.push_back(
true);
2016 dec.push_back(
true);
2018 for (
int i = 0; i < nprod; ++i) {
2019 prod.push_back(
true);
2020 dec.push_back(
false);
2022 for (
int i = 0; i < ndec; ++i) {
2023 prod.push_back(
false);
2024 dec.push_back(
true);
2026 diagram.push_back(prod);
2027 diagram.push_back(dec);
2028 MorphFuncPattern morphfuncpattern;
2029 ::collectPolynomials(morphfuncpattern, diagram);
2030 return morphfuncpattern.size();
2040 for (
auto vertex : vertices) {
2041 extractOperators(*vertex, operators);
2042 extractCouplings(*vertex, couplings);
2044 FeynmanDiagram diagram;
2045 ::fillFeynmanDiagram(diagram, vertices, couplings);
2046 MorphFuncPattern morphfuncpattern;
2047 ::collectPolynomials(morphfuncpattern, diagram);
2048 return morphfuncpattern.size();
2054std::map<std::string, std::string>
2056 const std::vector<std::vector<std::string>> &vertices_str)
2058 std::stack<RooArgList> ownedVertices;
2059 std::vector<RooArgList *> vertices;
2061 for (
const auto &vtx : vertices_str) {
2062 ownedVertices.emplace();
2063 auto &vertex = ownedVertices.top();
2064 for (
const auto &
c : vtx) {
2067 auto couplingOwner = std::make_unique<RooRealVar>(
c.c_str(),
c.c_str(), 1., 0., 10.);
2068 coupling = couplingOwner.get();
2069 couplings.
addOwned(std::move(couplingOwner));
2071 vertex.add(*coupling);
2073 vertices.push_back(&vertex);
2082std::map<std::string, std::string>
2084 const std::vector<RooArgList *> &vertices,
RooArgList &couplings)
2092std::map<std::string, std::string>
2094 const std::vector<RooArgList *> &vertices,
RooArgList &couplings,
2096 const std::vector<std::vector<std::string>> &nonInterfering)
2098 FormulaList formulas = ::createFormulas(
"", inputs, flagValues, {vertices}, couplings, flags, nonInterfering);
2100 extractOperators(couplings, operators);
2101 Matrix matrix(::buildMatrixT<Matrix>(inputs, formulas, operators, flagValues, flags));
2102 if (
size(matrix) < 1) {
2103 std::cerr <<
"input matrix is empty, please provide suitable input samples!" << std::endl;
2107 auto retval = buildSampleWeightStrings(inputs, formulas, inverse);
2115 const std::vector<RooArgList *> &vertices,
RooArgList &couplings,
2118 const std::vector<std::vector<std::string>> &nonInterfering)
2120 FormulaList formulas = ::createFormulas(
"", inputs, flagValues, {vertices}, couplings, flags, nonInterfering);
2122 extractOperators(couplings, operators);
2123 Matrix matrix(::buildMatrixT<Matrix>(inputs, formulas, operators, flagValues, flags));
2124 if (
size(matrix) < 1) {
2125 std::cerr <<
"input matrix is empty, please provide suitable input samples!" << std::endl;
2130 ::buildSampleWeights(retval, (
const char *)
nullptr , inputs, formulas, inverse);
2138 const std::vector<RooArgList *> &vertices,
RooArgList &couplings)
2153 coutE(Eval) <<
"unable to retrieve morphing function" << std::endl;
2156 std::unique_ptr<RooArgSet> args{mf->getComponents()};
2161 for (
auto itr : *args) {
2186 auto wname = std::string(
"w_") +
name +
"_" + this->
GetName();
2187 return dynamic_cast<RooAbsReal *
>(cache->_weights.find(wname.c_str()));
2205 auto weightName = std::string(
"w_") + sample.first +
"_" + this->
GetName();
2206 auto weight =
static_cast<RooAbsReal *
>(cache->_weights.find(weightName.c_str()));
2223 double val = obj->
getVal();
2226 double variation =
r.Gaus(1, z);
2227 obj->
setVal(val * variation);
2239 std::string filename =
_config.fileName;
2242 coutE(InputArguments) <<
"unable to open file '" << filename <<
"'!" << std::endl;
2268 std::string filename =
_config.fileName;
2269 cache->_inverse =
m;
2272 coutE(InputArguments) <<
"unable to open file '" << filename <<
"'!" << std::endl;
2287 coutE(Caching) <<
"unable to create cache!" << std::endl;
2288 _cacheMgr.setObj(
nullptr,
nullptr, cache,
nullptr);
2306 coutE(Caching) <<
"unable to create cache!" << std::endl;
2307 _cacheMgr.setObj(
nullptr,
nullptr, cache,
nullptr);
2331 cxcoutP(Caching) <<
"creating cache from getCache function for " <<
this << std::endl;
2332 cxcoutP(Caching) <<
"current storage has size " <<
_sampleMap.size() << std::endl;
2335 _cacheMgr.setObj(
nullptr,
nullptr, cache,
nullptr);
2337 coutE(Caching) <<
"unable to create cache!" << std::endl;
2360 if (value > param->
getMax())
2362 if (value < param->getMin())
2484 std::string filename =
_config.fileName;
2486 auto paramhist = loadFromFileResidentFolder<TH1>(file, foldername,
"param_card");
2487 setParams(paramhist.get(),
_operators,
false);
2497 const std::string
name(foldername);
2507 for (
auto itr : *list) {
2521 coutE(InputArguments) <<
"observable not available!" << std::endl;
2533 coutE(InputArguments) <<
"bin width not available!" << std::endl;
2552 auto mf = std::make_unique<RooRealSumFunc>(*(this->
getFunc()));
2555 const int nbins = observable->
getBins();
2559 std::unique_ptr<RooArgSet> args{mf->getComponents()};
2560 for (
int i = 0; i < nbins; ++i) {
2565 for (
auto itr : *args) {
2576 double weight = formula->
getVal();
2578 unc2 += w2 * weight * weight;
2579 unc += sqrt(w2) * weight;
2580 val += dhist.
weight(i) * weight;
2583 hist->
SetBinError(i + 1, correlateErrors ? unc : sqrt(unc2));
2585 return hist.release();
2594 auto mf = std::make_unique<RooRealSumFunc>(*(this->
getFunc()));
2596 coutE(InputArguments) <<
"unable to retrieve morphing function" << std::endl;
2597 std::unique_ptr<RooArgSet> args{mf->getComponents()};
2598 for (
auto itr : *args) {
2600 if (prod->
getVal() != 0) {
2614 std::string pname(paramname);
2616 bool isUsed =
false;
2617 for (
const auto &sample :
_config.paramCards) {
2618 double thisval = sample.second.at(pname);
2619 if (thisval != val) {
2635 std::string cname(couplname);
2642 bool isUsed =
false;
2643 for (
const auto &sample :
_config.paramCards) {
2645 double thisval = coupling->
getVal();
2646 if (thisval != val) {
2671 return cache->_formulas.size();
2679 auto mf = std::make_unique<RooRealSumFunc>(*(this->
getFunc()));
2681 std::cerr <<
"Error: unable to retrieve morphing function" << std::endl;
2684 std::unique_ptr<RooArgSet> args{mf->getComponents()};
2689 name.Prepend(
"phys_");
2690 if (!args->find(
name.Data())) {
2693 double val = formula->getVal();
2695 std::cout << formula->GetName() <<
": " << val <<
" = " << formula->GetTitle() << std::endl;
2715 return &(cache->_couplings);
2729 double val = var->
getVal();
2730 couplings[
name] = val;
2757 auto func = std::make_unique<RooRealSumFunc>(*(cache->_sumFunc));
2760 return std::make_unique<RooWrapperPdf>(
Form(
"pdf_%s", func->GetName()),
Form(
"pdf of %s", func->GetTitle()), *func);
2769 return cache->_sumFunc.get();
2786 return this->
createPdf()->expectedEvents(nset);
2796 return this->
createPdf()->expectedEvents(set);
2805 return createPdf()->expectedEvents(&nset);
2818 auto weightName = std::string(
"w_") + sample.first +
"_" + this->
GetName();
2819 auto weight =
static_cast<RooAbsReal *
>(cache->_weights.find(weightName.c_str()));
2821 coutE(InputArguments) <<
"unable to find object " + weightName << std::endl;
2835 double w = weight->getVal();
2836 unc2 += newunc2 * w * w;
2863 for (
auto flag :
_flags) {
2877 for (
auto c : couplings) {
2878 std::cout <<
c.first <<
": " <<
c.second << std::endl;
2912 std::cerr <<
"unable to acquire in-built function!" << std::endl;
2945 const char *rangeName)
const
2989 coutE(Caching) <<
"unable to retrieve cache!" << std::endl;
3000 coutE(Caching) <<
"unable to retrieve cache!" << std::endl;
3013 coutE(Caching) <<
"unable to retrieve cache!" << std::endl;
3014 return cache->_condition;
3020std::unique_ptr<RooRatio>
3025 for (
auto it : nr) {
3028 for (
auto it : dr) {
3032 return make_unique<RooRatio>(
name, title, num, denom);
3040std::vector<std::string> asStringV(std::string
const &arg)
3042 std::vector<std::string> out;
3044 for (std::string &tok :
ROOT::Split(arg,
",{}",
true)) {
3045 if (tok[0] ==
'\'') {
3046 out.emplace_back(tok.substr(1, tok.size() - 2));
3048 throw std::runtime_error(
"Strings in factory expressions need to be in single quotes!");
3058 create(RooFactoryWSTool &,
const char *typeName,
const char *instName, std::vector<std::string> args)
override;
3061std::string LMIFace::create(
RooFactoryWSTool &ft,
const char * ,
const char *instanceName,
3062 std::vector<std::string> args)
3065 const std::array<std::string, 4> funcArgs{{
"fileName",
"observableName",
"couplings",
"folders"}};
3066 std::map<string, string> mappedInputs;
3068 for (
unsigned int i = 1; i < args.size(); i++) {
3069 if (args[i].find(
"$fileName(") != 0 && args[i].find(
"$observableName(") != 0 &&
3070 args[i].find(
"$couplings(") != 0 && args[i].find(
"$folders(") != 0 && args[i].find(
"$NewPhysics(") != 0) {
3071 throw std::string(
Form(
"%s::create() ERROR: unknown token %s encountered", instanceName, args[i].c_str()));
3075 for (
unsigned int i = 0; i < args.size(); i++) {
3076 if (args[i].find(
"$NewPhysics(") == 0) {
3078 for (
const auto &subarg : subargs) {
3079 std::vector<std::string> parts =
ROOT::Split(subarg,
"=");
3080 if (parts.size() == 2) {
3083 throw std::string(
Form(
"%s::create() ERROR: unknown token %s encountered, check input provided for %s",
3084 instanceName, subarg.c_str(), args[i].c_str()));
3089 if (subargs.size() == 1) {
3091 for (
auto const ¶m : funcArgs) {
3092 if (args[i].find(param) != string::npos)
3093 mappedInputs[param] = subargs[0];
3097 Form(
"Incorrect number of arguments in %s, have %d, expect 1", args[i].c_str(), (
Int_t)subargs.size()));
3102 RooLagrangianMorphFunc::Config config;
3103 config.
fileName = asStringV(mappedInputs[
"fileName"])[0];
3104 config.
observableName = asStringV(mappedInputs[
"observableName"])[0];
3105 config.
folderNames = asStringV(mappedInputs[
"folders"]);
3110 return instanceName;
3119 RooFactoryWSTool::IFace *iface =
new LMIFace;
RooCollectionProxy< RooArgList > RooListProxy
ROOT::RRangeCast< T, true, Range_t > dynamic_range_cast(Range_t &&coll)
size_t size< TMatrixD >(const TMatrixD &mat)
void writeMatrixToStreamT(const MatrixT &matrix, std::ostream &stream)
write a matrix to a stream
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
static constexpr double morphUnityDeviation
Matrix makeSuperMatrix(const TMatrixD &in)
convert a TMatrixD into a Matrix
static constexpr double morphLargestWeight
void writeMatrixToFileT(const MatrixT &matrix, const char *fname)
write a matrix to a text file
double invertMatrix(const Matrix &matrix, Matrix &inverse)
TMatrixD makeRootMatrix(const Matrix &in)
convert a matrix into a TMatrixD
Matrix diagMatrix(size_t n)
create a new diagonal matrix of size n
void printMatrix(const TMatrixD &mat)
write a matrix
int Int_t
Signed integer 4 bytes (int).
TMatrixT< Double_t > TMatrixD
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
std::string & operator+=(std::string &left, const TString &right)
TTime operator*(const TTime &t1, const TTime &t2)
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().
bool isConstant() const
Check if the "Constant" attribute is set.
bool addOwnedComponents(const RooAbsCollection &comps)
Take ownership of the contents of 'comps'.
const RefCountList_t & servers() const
List of all servers of this object.
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
void setAttribute(const Text_t *name, bool value=true)
Set (default) or clear a named boolean attribute of this object.
RooAbsArg()
Default constructor.
virtual double * array() const =0
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.
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
Int_t numBins(const char *rangeName=nullptr) const override
virtual Int_t getBins(const char *name=nullptr) const
Get number of bins of currently defined range.
void setConstant(bool value=true)
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
void setBin(Int_t ibin, const char *rangeName=nullptr) override
Set value to center of bin 'ibin' of binning 'rangeName' (or of default binning if no range is specif...
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...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
RooAbsReal()
coverity[UNINIT_CTOR] Default constructor
friend class RooRealSumFunc
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Implements a RooAbsBinning in terms of an array of boundary values, posing no constraints on the choi...
Container class to hold N-dimensional binned data.
double weight(std::size_t i) const
Return weight of i-th bin.
double weightSquared(std::size_t i) const
Return squared weight sum of i-th bin.
A real-valued function sampled from a multidimensional histogram.
RooDataHist & dataHist()
Return RooDataHist that is represented.
static RooLagrangianMorphFunc::CacheElem * createCache(const RooLagrangianMorphFunc *func)
create all the temporary objects required by the class
void buildMatrix(const RooLagrangianMorphFunc::ParamMap &inputParameters, const RooLagrangianMorphFunc::FlagMap &inputFlags, const List &flags)
build and invert the morphing matrix
static RooLagrangianMorphFunc::CacheElem * createCache(const RooLagrangianMorphFunc *func, const Matrix &inverse)
create all the temporary objects required by the class function variant with precomputed inverse matr...
std::unique_ptr< RooRealSumFunc > _sumFunc
RooArgList containedArgs(Action) override
retrieve the list of contained args
void operModeHook(RooAbsArg::OperMode) override
Interface for changes of operation mode.
void createComponents(const RooLagrangianMorphFunc::ParamMap &inputParameters, const RooLagrangianMorphFunc::FlagMap &inputFlags, const char *funcname, const std::vector< std::vector< RooListProxy * > > &diagramProxyList, const std::vector< std::vector< std::string > > &nonInterfering, const RooArgList &flags)
create the basic objects required for the morphing
void buildMorphingFunction(const char *name, const RooLagrangianMorphFunc::ParamMap &inputParameters, const std::map< std::string, int > &storage, const RooArgList &physics, bool allowNegativeYields, RooRealVar *observable, RooRealVar *binWidth)
build the final morphing function
bool isParameterConstant(const char *paramname) const
return true if the parameter with the given name is set constant, false otherwise
bool isBinnedDistribution(const RooArgSet &obs) const override
check if this PDF is a binned distribution in the given observable
int nPolynomials() const
return the number of samples in this morphing function
void setParameter(const char *name, double value)
set one parameter to a specific value
RooArgSet createWeights(const ParamMap &inputs, const std::vector< RooArgList * > &vertices, RooArgList &couplings, const FlagMap &inputFlags, const RooArgList &flags, const std::vector< std::vector< std::string > > &nonInterfering)
create only the weight formulas. static function for external usage.
ParamSet getMorphParameters() const
retrieve the parameter set
double evaluate() const override
call getVal on the internal function
void disableInterference(const std::vector< const char * > &nonInterfering)
disable interference between terms
RooProduct * getSumElement(const char *name) const
return the RooProduct that is the element of the RooRealSumPdfi corresponding to the given sample nam...
RooRealVar * getBinWidth() const
retrieve the histogram observable
void writeMatrixToFile(const TMatrixD &matrix, const char *fname)
write a matrix to a file
RooRealVar * getParameter(const char *name) const
retrieve the RooRealVar object incorporating the parameter with the given name
bool useCoefficients(const TMatrixD &inverse)
setup the morphing function with a predefined inverse matrix call this function before any other afte...
const RooArgSet * getParameterSet() const
get the set of parameters
TMatrixD readMatrixFromStream(std::istream &stream)
read a matrix from a stream
std::vector< std::vector< std::string > > _nonInterfering
std::vector< std::string > getSamples() const
return the vector of sample names, used to build the morph func
int countSamples(std::vector< RooArgList * > &vertices)
calculate the number of samples needed to morph a certain physics process
void setCacheAndTrackHints(RooArgSet &) override
Retrieve the matrix of coefficients.
ParamSet getCouplings() const
retrieve a set of couplings (-?-)
void printSampleWeights() const
print the current sample weights
std::map< const std::string, double > ParamSet
void writeMatrixToStream(const TMatrixD &matrix, std::ostream &stream)
write a matrix to a stream
std::map< const std::string, ParamSet > ParamMap
bool updateCoefficients()
Retrieve the new physics objects and update the weights in the morphing function.
RooRealVar * getObservable() const
retrieve the histogram observable
int countContributingFormulas() const
count the number of formulas that correspond to the current parameter set
std::list< double > * plotSamplingHint(RooAbsRealLValue &, double, double) const override
retrieve the sample Hint
RooRealVar * getFlag(const char *name) const
retrieve the RooRealVar object incorporating the flag with the given name
void randomizeParameters(double z)
randomize the parameters a bit useful to test and debug fitting
bool isCouplingUsed(const char *couplname)
check if there is any morphing power provided for the given coupling morphing power is provided as so...
void readParameters(TDirectory *f)
read the parameters from the input file
double getScale()
get energy scale of the EFT expansion
double getCondition() const
Retrieve the condition of the coefficient matrix.
TMatrixD getMatrix() const
Retrieve the matrix of coefficients.
void printWeights() const
print the current sample weights
void printCouplings() const
print a set of couplings
TMatrixD readMatrixFromFile(const char *fname)
read a matrix from a text file
~RooLagrangianMorphFunc() override
default destructor
void printParameters() const
print the parameters and their current values
void printPhysics() const
print the current physics values
static std::unique_ptr< RooRatio > makeRatio(const char *name, const char *title, RooArgList &nr, RooArgList &dr)
Return the RooRatio form of products and denominators of morphing functions.
void setFlag(const char *name, double value)
set one flag to a specific value
TH1 * createTH1(const std::string &name)
retrieve a histogram output of the current morphing settings
double expectedUncertainty() const
return the expected uncertainty for the current parameter set
int nParameters() const
return the number of parameters in this morphing function
bool hasParameter(const char *paramname) const
check if a parameter of the given name is contained in the list of known parameters
bool checkObservables(const RooArgSet *nset) const override
check if observable exists in the RooArgSet (-?-)
bool hasCache() const
return true if a cache object is present, false otherwise
void printFlags() const
print the flags and their current values
void setScale(double val)
set energy scale of the EFT expansion
TMatrixD getInvertedMatrix() const
Retrieve the matrix of coefficients after inversion.
double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Retrieve the matrix of coefficients.
RooAbsArg::CacheMode canNodeBeCached() const override
Retrieve the matrix of coefficients.
void updateSampleWeights()
update sample weight (-?-)
void setParameters(const char *foldername)
set the morphing parameters to those supplied in the sample with the given name
RooObjCacheManager _cacheMgr
! The cache manager
bool isParameterUsed(const char *paramname) const
check if there is any morphing power provided for the given parameter morphing power is provided as s...
RooListProxy _observables
RooAbsPdf::ExtendMode extendMode() const
return extended mored capabilities
std::map< const std::string, FlagSet > FlagMap
bool forceAnalyticalInt(const RooAbsArg &arg) const override
Force analytical integration for the given observable.
void setParameterConstant(const char *paramname, bool constant) const
call setConstant with the boolean argument provided on the parameter with the given name
void disableInterferences(const std::vector< std::vector< const char * > > &nonInterfering)
disable interference between terms
void printSamples() const
print all the known samples to the console
double getParameterValue(const char *name) const
set one parameter to a specific value
void setup(bool ownParams=true)
setup this instance with the given set of operators and vertices if own=true, the class will own the ...
void printMetaArgs(std::ostream &os) const override
Retrieve the matrix of coefficients.
std::unique_ptr< RooWrapperPdf > createPdf() const
(currently similar to cloning the Pdf
RooAbsReal * getSampleWeight(const char *name)
retrieve the weight (prefactor) of a sample with the given name
std::map< std::string, std::string > createWeightStrings(const ParamMap &inputs, const std::vector< std::vector< std::string > > &vertices)
create only the weight formulas. static function for external usage.
Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &numVars, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Retrieve the mat.
std::vector< std::vector< RooListProxy * > > _diagrams
double expectedEvents() const
return the number of expected events for the current parameter set
std::map< std::string, int > _sampleMap
RooLagrangianMorphFunc::CacheElem * getCache() const
retrieve the cache object
RooRealVar * setupObservable(const char *obsname, TClass *mode, TObject *inputExample)
setup observable, recycle existing observable if defined
const RooArgList * getCouplingSet() const
get the set of couplings
RooRealSumFunc * getFunc() const
get the func
std::list< double > * binBoundaries(RooAbsRealLValue &, double, double) const override
retrieve the list of bin boundaries
void printEvaluation() const
print the contributing samples and their respective weights
bool writeCoefficients(const char *filename)
write the inverse matrix to a file
void collectInputs(TDirectory *f)
retrieve the physics inputs
void init()
initialise inputs required for the morphing function
RooLinearCombination is a class that helps perform linear combination of floating point numbers and p...
void setCoefficient(size_t idx, RooFit::SuperFloat c)
RooFit::SuperFloat getCoefficient(size_t idx)
A histogram function that assigns scale parameters to every bin.
const RooArgList & paramList() const
Represents the product of a given set of RooAbsReal objects.
std::list< double > * binBoundaries(RooAbsRealLValue &, double, double) const override
Retrieve bin boundaries if this distribution is binned in obs.
void printMetaArgs(std::ostream &os) const override
Customized printing of arguments of a RooRealSumFunc to more intuitively reflect the contents of the ...
Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &numVars, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Variant of getAnalyticalIntegral that is also passed the normalization set that should be applied to ...
CacheMode canNodeBeCached() const override
double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
bool isBinnedDistribution(const RooArgSet &obs) const override
Tests if the distribution is binned. Unless overridden by derived classes, this always returns false.
bool checkObservables(const RooArgSet *nset) const override
Overloadable function in which derived classes can implement consistency checks of the variables.
void setCacheAndTrackHints(RooArgSet &) override
std::list< double > * plotSamplingHint(RooAbsRealLValue &, double, double) const override
Interface for returning an optional hint for initial sampling points when constructing a curve projec...
bool forceAnalyticalInt(const RooAbsArg &arg) const override
Variable that can be changed from the outside.
void setVal(double value) override
Set value of variable to 'value'.
void setError(double value)
void setMin(const char *name, double value, bool shared=true)
Set minimum of name range to given value.
void setBins(Int_t nBins, const char *name=nullptr, bool shared=true)
Create a uniform binning under name 'name' for this variable.
void setBinning(const RooAbsBinning &binning, const char *name=nullptr, bool shared=true)
Add given binning under name 'name' with this variable.
void setMax(const char *name, double value, bool shared=true)
Set maximum of name range to given value.
const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false, bool shared=true) const override
Return binning definition with name.
RooAbsArg * arg(RooStringView name) const
Return RooAbsArg with given name. A null pointer is returned if none is 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.
Class to manage histogram axis.
const char * GetBinLabel(Int_t bin) const
Return label for bin.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Double_t GetCondition() const
Bool_t Invert(TMatrixD &inv)
For a matrix A(m,m), its inverse A_inv is defined as A * A_inv = A_inv * A = unit (m x m) Ainv is ret...
Describe directory structure in memory.
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
<div class="legacybox"><h2>Legacy Code</h2> TFolder is a legacy interface: there will be no bug fixes...
TCollection * GetListOfFolders() const
virtual void SetOwner(Bool_t owner=kTRUE)
Set ownership.
TH1 is the base class of all histogram classes in ROOT.
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...
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
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 GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
virtual TMatrixTBase< Element > & UnitMatrix()
Make a unit matrix (matrix need not be a square one).
TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t=-1) override
Set size of the matrix to nrows x ncols New dynamic elements are created, the overlapping part of the...
const char * GetName() const override
Returns name of object.
Mother of all ROOT objects.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Class used by TMap to store (key,value) pairs.
Named parameter, streamable and storable.
const AParamType & GetVal() const
Random number generator class based on M.
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
const char * Data() const
TString & Append(const char *cs)
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
RooCmdArg Silence(bool flag=true)
void(off) SmallVectorTemplateBase< T
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
std::string observableName
std::vector< std::string > folderNames