73using std::string, std::make_unique, std::vector;
83#define NaN std::numeric_limits<double>::quiet_NaN()
92template <
typename Test,
template <
typename...>
class Ref>
96template <
template <
typename...>
class Ref,
typename... Args>
107template <
class MatrixT>
108inline size_t size(
const MatrixT &matrix);
112 return mat.GetNrows();
118template <
class MatrixT>
121 if (!stream.good()) {
124 for (
size_t i = 0; i <
size(matrix); ++i) {
125 for (
size_t j = 0; j <
size(matrix); ++j) {
127 stream << std::setprecision(RooFit::SuperFloatPrecision::digits10) << matrix(i, j) <<
"\t";
129 stream << matrix(i, j) <<
"\t";
139template <
class MatrixT>
142 std::ofstream of(fname);
144 std::cerr <<
"unable to read file '" << fname <<
"'!" << std::endl;
153#pragma GCC diagnostic push
154#pragma GCC diagnostic ignored "-Wshadow"
155#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
156#include <boost/numeric/ublas/io.hpp>
157#include <boost/numeric/ublas/lu.hpp>
158#include <boost/numeric/ublas/matrix.hpp>
159#include <boost/numeric/ublas/matrix_expression.hpp>
160#include <boost/numeric/ublas/symmetric.hpp>
161#include <boost/numeric/ublas/triangular.hpp>
162#include <boost/operators.hpp>
164#pragma GCC diagnostic pop
166typedef boost::numeric::ublas::matrix<RooFit::SuperFloat>
Matrix;
173 for (
size_t i = 0; i < mat.size1(); ++i) {
174 for (
size_t j = 0; j < mat.size2(); ++j) {
175 std::cout << std::setprecision(RooFit::SuperFloatPrecision::digits10) << mat(i, j) <<
" ,\t";
177 std::cout << std::endl;
185inline size_t size<Matrix>(
const Matrix &matrix)
187 return matrix.size1();
195 return boost::numeric::ublas::identity_matrix<RooFit::SuperFloat>(
n);
205 for (
size_t i = 0; i <
n; ++i) {
206 for (
size_t j = 0; j <
n; ++j) {
207 mat(i, j) =
double(in(i, j));
220 for (
size_t i = 0; i <
n; ++i) {
221 for (
size_t j = 0; j <
n; ++j) {
222 mat(i, j) =
double(in(i, j));
234 return prod(
m, otherM);
242 boost::numeric::ublas::permutation_matrix<size_t> pm(
size(matrix));
246 int res = lu_factorize(lu, pm);
248 std::stringstream ss;
250 cxcoutP(Eval) << ss.str << std::endl;
253 lu_substitute(lu, pm, inverse);
254 }
catch (boost::numeric::ublas::internal_logic &error) {
308 bool status = lu.Invert(inverse);
311 std::cerr <<
" matrix is not invertible!" << std::endl;
313 double condition = lu.GetCondition();
314 const size_t n =
size(inverse);
316 for (
size_t i = 0; i <
n; ++i) {
317 for (
size_t j = 0; j <
n; ++j) {
318 if (std::abs(inverse(i, j)) < 1
e-9)
337typedef std::vector<std::vector<bool>> FeynmanDiagram;
338typedef std::vector<std::vector<int>> MorphFuncPattern;
339typedef std::map<int, std::unique_ptr<RooAbsReal>> FormulaList;
347 retval.ReplaceAll(
"/",
"_");
348 retval.ReplaceAll(
"^",
"");
349 retval.ReplaceAll(
"*",
"X");
350 retval.ReplaceAll(
"[",
"");
351 retval.ReplaceAll(
"]",
"");
359std::string concatNames(
const List &
c,
const char *sep)
361 std::stringstream ss;
366 ss << itr->GetName();
376template <
class A,
class B>
377inline void assignElement(A &
a,
const B &
b)
379 a =
static_cast<A
>(
b);
384template <
class MatrixT>
385inline MatrixT readMatrixFromStreamT(std::istream &stream)
387 std::vector<std::vector<RooFit::SuperFloat>> matrix;
388 std::vector<RooFit::SuperFloat>
line;
389 while (!stream.eof()) {
390 if (stream.peek() ==
'\n') {
398 while (stream.peek() ==
' ' || stream.peek() ==
'\t') {
401 if (stream.peek() ==
'\n') {
402 matrix.push_back(
line);
406 MatrixT retval(matrix.size(), matrix.size());
407 for (
size_t i = 0; i < matrix.size(); ++i) {
408 if (matrix[i].
size() != matrix.size()) {
409 std::cerr <<
"matrix read from stream doesn't seem to be square!" << std::endl;
411 for (
size_t j = 0; j < matrix[i].size(); ++j) {
412 assignElement(retval(i, j), matrix[i][j]);
421template <
class MatrixT>
422inline MatrixT readMatrixFromFileT(
const char *fname)
424 std::ifstream in(fname);
426 std::cerr <<
"unable to read file '" << fname <<
"'!" << std::endl;
428 MatrixT mat = readMatrixFromStreamT<MatrixT>(in);
437void readValues(std::map<const std::string, T> &myMap,
TH1 *h_pc)
441 for (
int ibx = 1; ibx <= h_pc->GetNbinsX(); ++ibx) {
443 const std::string s_coup(h_pc->GetXaxis()->GetBinLabel(ibx));
444 double coup_val = h_pc->GetBinContent(ibx);
446 if (!s_coup.empty()) {
447 myMap[s_coup] = T(coup_val);
456void setOwnerRecursive(
TFolder *theFolder)
458 theFolder->SetOwner();
460 auto subdirs = theFolder->GetListOfFolders();
464 setOwnerRecursive(thisfolder);
477std::unique_ptr<TFolder> readOwningFolderFromFile(
TDirectory *inFile,
const std::string &folderName)
479 std::unique_ptr<TFolder> theFolder(inFile->Get<
TFolder>(folderName.c_str()));
481 std::cerr <<
"Error: unable to access data from folder '" << folderName <<
"' from file '" << inFile->GetName()
482 <<
"'!" << std::endl;
485 setOwnerRecursive(theFolder.get());
498template <
class AObjType>
499std::unique_ptr<AObjType> loadFromFileResidentFolder(
TDirectory *inFile,
const std::string &folderName,
500 const std::string &objName,
bool notFoundError =
true)
502 auto folder = readOwningFolderFromFile(inFile, folderName);
506 AObjType *loadedObject =
dynamic_cast<AObjType *
>(folder->FindObject(objName.c_str()));
509 std::stringstream errstr;
510 errstr <<
"Error: unable to retrieve object '" << objName <<
"' from folder '" << folderName
511 <<
"'. contents are:";
512 TIter next(folder->GetListOfFolders()->begin());
514 while ((
f =
static_cast<TFolder *
>(next()))) {
517 std::cerr << errstr.str() << std::endl;
523 return std::unique_ptr<AObjType>{
static_cast<AObjType *
>(loadedObject->Clone())};
530void readValues(std::map<const std::string, T> &myMap,
TDirectory *file,
const std::string &
name,
531 const std::string &key =
"param_card",
bool notFoundError =
true)
533 auto h_pc = loadFromFileResidentFolder<TH1F>(file,
name, key, notFoundError);
534 readValues(myMap, h_pc.get());
543void readValues(std::map<
const std::string, std::map<const std::string, T>> &inputParameters,
TDirectory *
f,
544 const std::vector<std::string> &names,
const std::string &key =
"param_card",
bool notFoundError =
true)
546 inputParameters.clear();
549 for (
size_t i = 0; i < names.size(); i++) {
550 const std::string
name(names[i]);
552 readValues(inputParameters[
name],
f,
name, key, notFoundError);
567 if (!file || !file->
IsOpen()) {
570 std::cerr <<
"could not open file '" <<
filename <<
"'!" << std::endl;
592inline void extractServers(
const RooAbsArg &coupling, T2 &operators)
595 for (
const auto server : coupling.servers()) {
596 extractServers(*server, operators);
600 operators.add(coupling);
607template <class T1, class T2, typename std::enable_if<!is_specialization<T1, std::vector>::value, T1>
::type * =
nullptr>
608inline void extractOperators(
const T1 &couplings, T2 &operators)
612 for (
auto itr : couplings) {
613 extractServers(*itr, operators);
620template <class T1, class T2, typename std::enable_if<is_specialization<T1, std::vector>::value, T1>
::type * =
nullptr>
621inline void extractOperators(
const T1 &vec, T2 &operators)
623 for (
const auto &
v : vec) {
624 extractOperators(
v, operators);
631template <
class T1,
class T2>
632inline void extractCouplings(
const T1 &inCouplings, T2 &outCouplings)
634 for (
auto itr : inCouplings) {
635 if (!outCouplings.find(itr->GetName())) {
638 outCouplings.add(*itr);
647inline bool setParam(
RooRealVar *
p,
double val,
bool force)
650 if (val >
p->getMax()) {
654 std::cerr <<
": parameter " <<
p->GetName() <<
" out of bounds: " << val <<
" > " <<
p->getMax() << std::endl;
657 }
else if (val < p->getMin()) {
661 std::cerr <<
": parameter " <<
p->GetName() <<
" out of bounds: " << val <<
" < " <<
p->getMin() << std::endl;
674template <
class T1,
class T2>
675inline bool setParams(
const T2 &args, T1 val)
680 setParam(param, val,
true);
689template <
class T1,
class T2>
691setParams(
const std::map<const std::string, T1> &point,
const T2 &args,
bool force =
false, T1 defaultVal = 0)
695 if (!param || param->isConstant())
697 ok = setParam(param, defaultVal, force) && ok;
700 for (
auto paramit : point) {
702 const std::string param(paramit.first);
708 ok = setParam(
p, paramit.second, force) && ok;
718inline bool setParams(
TH1 *hist,
const T &args,
bool force =
false)
725 ok = setParam(param, 0., force) && ok;
730 for (
int i = 1; i <= ax->GetNbins(); ++i) {
751 retval[param->GetName()] = param->getVal();
764 bool binningOK =
false;
765 for (
auto sampleit : inputParameters) {
766 const std::string sample(sampleit.first);
767 auto hist = loadFromFileResidentFolder<TH1>(file, sample, varname,
true);
775 auto it = list_hf.find(sample);
776 if (it != list_hf.end()) {
788 std::vector<double> bins;
789 for (
int i = 1; i <
n + 1; ++i) {
797 TString histname = makeValidName(
"dh_" + sample +
"_" +
name);
798 TString funcname = makeValidName(
"phys_" + sample +
"_" +
name);
802 auto dh = std::make_unique<RooDataHist>(histname.Data(), histname.Data(), vars, hist.get());
804 auto hf = std::make_unique<RooHistFunc>(funcname.Data(), funcname.Data(), var, std::move(dh));
805 int idx = physics.size();
806 list_hf[sample] = idx;
807 physics.addOwned(std::move(hf));
817void collectRooAbsReal(
const char * ,
TDirectory *file, std::map<std::string, int> &list_hf,
818 RooArgList &physics,
const std::string &varname,
821 for (
auto sampleit : inputParameters) {
822 const std::string sample(sampleit.first);
823 auto obj = loadFromFileResidentFolder<RooAbsReal>(file, sample, varname,
true);
826 auto it = list_hf.find(sample);
827 if (it == list_hf.end()) {
828 int idx = physics.size();
829 list_hf[sample] = idx;
830 physics.addOwned(std::move(obj));
840void collectCrosssections(
const char *
name,
TDirectory *file, std::map<std::string, int> &list_xs,
RooArgList &physics,
843 for (
auto sampleit : inputParameters) {
844 const std::string sample(sampleit.first);
845 auto obj = loadFromFileResidentFolder<TObject>(file, sample, varname,
false);
846 TParameter<T> *xsection =
nullptr;
847 TParameter<T> *error =
nullptr;
848 TParameter<T> *
p =
dynamic_cast<TParameter<T> *
>(obj.get());
852 TPair *pair =
dynamic_cast<TPair *
>(obj.get());
854 xsection =
dynamic_cast<TParameter<T> *
>(pair->
Key());
855 error =
dynamic_cast<TParameter<T> *
>(pair->
Value());
858 std::stringstream errstr;
859 errstr <<
"Error: unable to retrieve cross section '" << varname <<
"' from folder '" << sample;
863 auto it = list_xs.find(sample);
865 if (it != list_xs.end()) {
866 xs =
static_cast<RooRealVar *
>(physics.at(it->second));
867 xs->
setVal(xsection->GetVal());
869 std::string objname =
"phys_" + std::string(
name) +
"_" + sample;
870 auto xsOwner = std::make_unique<RooRealVar>(objname.c_str(), objname.c_str(), xsection->GetVal());
872 xs->setConstant(
true);
873 int idx = physics.size();
874 list_xs[sample] = idx;
875 physics.addOwned(std::move(xsOwner));
876 assert(physics.at(idx) == xs);
879 xs->setError(error->GetVal());
888void collectCrosssectionsTPair(
const char *
name,
TDirectory *file, std::map<std::string, int> &list_xs,
889 RooArgList &physics,
const std::string &varname,
const std::string &basefolder,
892 auto pair = loadFromFileResidentFolder<TPair>(file, basefolder, varname,
false);
895 if (
dynamic_cast<TParameter<double> *
>(pair->
Key())) {
896 collectCrosssections<double>(
name, file, list_xs, physics, varname, inputParameters);
897 }
else if (
dynamic_cast<TParameter<float> *
>(pair->
Key())) {
898 collectCrosssections<float>(
name, file, list_xs, physics, varname, inputParameters);
900 std::cerr <<
"cannot morph objects of class 'TPair' if parameter is not "
914void collectPolynomialsHelper(
const FeynmanDiagram &diagram, MorphFuncPattern &morphfunc, std::vector<int> &term,
915 int vertexid,
bool first)
918 for (
size_t i = 0; i < diagram[vertexid - 1].size(); ++i) {
919 if (!diagram[vertexid - 1][i])
921 std::vector<int> newterm(term);
924 ::collectPolynomialsHelper(diagram, morphfunc, newterm, vertexid,
false);
926 ::collectPolynomialsHelper(diagram, morphfunc, newterm, vertexid - 1,
true);
931 for (
size_t i = 0; i < morphfunc.size(); ++i) {
932 bool thisfound =
true;
933 for (
size_t j = 0; j < morphfunc[i].size(); ++j) {
934 if (morphfunc[i][j] != term[j]) {
945 morphfunc.push_back(term);
953void collectPolynomials(MorphFuncPattern &morphfunc,
const FeynmanDiagram &diagram)
955 int nvtx(diagram.size());
956 std::vector<int> term(diagram[0].
size(), 0);
958 ::collectPolynomialsHelper(diagram, morphfunc, term, nvtx,
true);
965inline void fillFeynmanDiagram(FeynmanDiagram &diagram,
const std::vector<List *> &vertices,
RooArgList &couplings)
967 const int ncouplings = couplings.
size();
969 for (
auto const &vertex : vertices) {
970 std::vector<bool> vertexCouplings(ncouplings,
false);
975 std::cerr <<
"encountered invalid list of couplings in vertex!" << std::endl;
978 if (vertex->find(coupling->GetName())) {
979 vertexCouplings[idx] =
true;
982 diagram.push_back(vertexCouplings);
989template <
class MatrixT,
class T1,
class T2>
993 const size_t dim = inputParameters.size();
994 MatrixT matrix(dim, dim);
996 for (
auto sampleit : inputParameters) {
997 const std::string sample(sampleit.first);
999 if (!setParams<double>(sampleit.second, args,
true, 0)) {
1000 std::cout <<
"unable to set parameters for sample " << sample <<
"!" << std::endl;
1002 auto flagit = flagValues.find(sample);
1003 if (flagit != flagValues.end() && !setParams<int>(flagit->second, flags,
true, 1)) {
1004 std::cout <<
"unable to set parameters for sample " << sample <<
"!" << std::endl;
1008 for (
auto const &formula : formulas) {
1009 if (!formula.second) {
1010 std::cerr <<
"Error: invalid formula encountered!" << std::endl;
1012 matrix(row, col) = formula.second->getVal();
1025 if (inputParameters.size() != formulas.size()) {
1026 std::stringstream ss;
1027 ss <<
"matrix is not square, consistency check failed: " << inputParameters.size() <<
" samples, "
1028 << formulas.size() <<
" expressions:" << std::endl;
1029 ss <<
"formulas: " << std::endl;
1030 for (
auto const &formula : formulas) {
1031 ss << formula.second->GetTitle() << std::endl;
1033 ss <<
"samples: " << std::endl;
1034 for (
auto sample : inputParameters) {
1035 ss << sample.first << std::endl;
1037 std::cerr << ss.str() << std::endl;
1044inline void inverseSanity(
const Matrix &matrix,
const Matrix &inverse,
double &unityDeviation,
double &largestWeight)
1046 Matrix unity(inverse * matrix);
1048 unityDeviation = 0.;
1050 const size_t dim =
size(unity);
1051 for (
size_t i = 0; i < dim; ++i) {
1052 for (
size_t j = 0; j < dim; ++j) {
1053 if (inverse(i, j) > largestWeight) {
1054 largestWeight = (
double)inverse(i, j);
1056 if (std::abs(unity(i, j) -
static_cast<int>(i == j)) > unityDeviation) {
1057 unityDeviation = std::abs((
double)unity(i, j)) -
static_cast<int>(i == j);
1065template <
class List>
1068 for (
auto sampleit : inputParameters) {
1069 const std::string sample(sampleit.first);
1070 RooAbsArg *arg = args.find(sample.c_str());
1072 std::cerr <<
"detected name conflict: cannot use sample '" << sample
1073 <<
"' - a parameter with the same name of type '" << arg->
ClassName() <<
"' is present in set '"
1074 << args.GetName() <<
"'!" << std::endl;
1086 const std::vector<std::vector<std::string>> &nonInterfering)
1095 const int ncouplings = couplings.
size();
1096 std::vector<bool> couplingsZero(ncouplings,
true);
1097 std::map<TString, bool> flagsZero;
1100 extractOperators(couplings, operators);
1101 size_t nOps = operators.size();
1103 for (
auto sampleit : inputParameters) {
1104 const std::string sample(sampleit.first);
1105 if (!setParams(sampleit.second, operators,
true)) {
1106 std::cerr <<
"unable to set parameters for sample '" << sample <<
"'!" << std::endl;
1109 if (nOps != (operators.size())) {
1110 std::cerr <<
"internal error, number of operators inconsistent!" << std::endl;
1116 if (obj0->getVal() != 0) {
1117 couplingsZero[idx] =
false;
1126 for (
auto sampleit : inputFlags) {
1127 const auto &flag = sampleit.second.find(obj1->GetName());
1128 if (flag != sampleit.second.end()) {
1129 if (flag->second == 0.) {
1136 if (nZero > 0 && nNonZero == 0) {
1137 flagsZero[obj1->GetName()] =
true;
1139 flagsZero[obj1->GetName()] =
false;
1143 FormulaList formulas;
1144 for (
size_t i = 0; i < morphfunc.size(); ++i) {
1146 bool isZero =
false;
1149 for (
const auto &
group : nonInterfering) {
1150 int nInterferingOperators = 0;
1151 for (
size_t j = 0; j < morphfunc[i].size(); ++j) {
1152 if (morphfunc[i][j] % 2 == 0)
1156 nInterferingOperators++;
1159 if (nInterferingOperators > 1) {
1161 reason =
"blacklisted interference term!";
1167 for (
size_t j = 0; j < morphfunc[i].size(); ++j) {
1168 const int exponent = morphfunc[i][j];
1172 for (
int k = 0; k < exponent; ++k) {
1174 if (coupling->getAttribute(
"NewPhysics")) {
1178 std::string
cname(coupling->GetName());
1179 if (coupling->getAttribute(
"LO") && exponent > 1) {
1181 reason =
"coupling " +
cname +
" was listed as leading-order-only";
1184 if (!isZero && couplingsZero[j]) {
1186 reason =
"coupling " +
cname +
" is zero!";
1191 bool removedByFlag =
false;
1196 TString sval(obj->getStringAttribute(
"NewPhysics"));
1197 int val = atoi(sval);
1199 if (flagsZero.find(obj->GetName()) != flagsZero.end() && flagsZero.at(obj->GetName())) {
1200 removedByFlag =
true;
1201 reason =
"flag " + std::string(obj->GetName()) +
" is zero";
1208 if (!isZero && !removedByFlag) {
1210 const auto name = std::string(mfname) +
"_pol" + std::to_string(i);
1211 formulas[i] = std::make_unique<RooProduct>(
name.c_str(), ::concatNames(ss,
" * ").c_str(), ss);
1222 const std::vector<std::vector<RooArgList *>> &diagrams,
RooArgList &couplings,
1223 const RooArgList &flags,
const std::vector<std::vector<std::string>> &nonInterfering)
1225 MorphFuncPattern morphfuncpattern;
1227 for (
const auto &vertices : diagrams) {
1229 ::fillFeynmanDiagram(
d, vertices, couplings);
1230 ::collectPolynomials(morphfuncpattern,
d);
1232 FormulaList retval = buildFormulas(
name, inputs, inputFlags, morphfuncpattern, couplings, flags, nonInterfering);
1233 if (retval.empty()) {
1234 std::stringstream errorMsgStream;
1236 <<
"no formulas are non-zero, check if any if your couplings is floating and missing from your param_cards!"
1238 const auto errorMsg = errorMsgStream.str();
1239 throw std::runtime_error(errorMsg);
1241 checkMatrix(inputs, retval);
1250 FormulaList &formulas,
const Matrix &inverse)
1254 for (
auto sampleit : inputParameters) {
1255 const std::string sample(sampleit.first);
1256 std::stringstream title;
1257 TString name_full(makeValidName(sample));
1259 name_full.Append(
"_");
1260 name_full.Append(fname);
1261 name_full.Prepend(
"w_");
1266 auto sampleformula = std::make_unique<RooLinearCombination>(name_full.Data());
1267 for (
auto const &formulait : formulas) {
1269 sampleformula->add(val, formulait.second.get());
1272 weights.addOwned(std::move(sampleformula));
1277inline std::map<std::string, std::string>
1282 std::map<std::string, std::string> weights;
1283 for (
auto sampleit : inputParameters) {
1284 const std::string sample(sampleit.first);
1285 std::stringstream str;
1288 for (
auto const &formulait : formulas) {
1289 double val(inverse(formulaidx, sampleidx));
1291 if (formulaidx > 0 && val > 0)
1293 str << val <<
"*(" << formulait.second->GetTitle() <<
")";
1297 weights[sample] = str.str();
1332 args.
add(*(it.second));
1342 const std::vector<std::vector<RooListProxy *>> &diagramProxyList,
1343 const std::vector<std::vector<std::string>> &nonInterfering,
const RooArgList &flags)
1346 std::vector<std::vector<RooArgList *>> diagrams;
1347 for (
const auto &diagram : diagramProxyList) {
1348 diagrams.emplace_back();
1351 diagrams.back().emplace_back(vertex);
1355 _formulas = ::createFormulas(funcname, inputParameters, inputFlags, diagrams,
_couplings, flags, nonInterfering);
1360 template <
class List>
1366 Matrix matrix(buildMatrixT<Matrix>(inputParameters,
_formulas, operators, inputFlags, flags));
1367 if (
size(matrix) < 1) {
1368 std::cerr <<
"input matrix is empty, please provide suitable input samples!" << std::endl;
1373 double unityDeviation;
1374 double largestWeight;
1375 inverseSanity(matrix, inverse, unityDeviation, largestWeight);
1381 oocxcoutW((
TObject *)
nullptr, Eval) <<
"Warning: The matrix inversion seems to be unstable. This can "
1382 "be a result to input samples that are not sufficiently "
1383 "different to provide any morphing power."
1385 }
else if (weightwarning) {
1386 oocxcoutW((
TObject *)
nullptr, Eval) <<
"Warning: Some weights are excessively large. This can be a "
1387 "result to input samples that are not sufficiently different to "
1388 "provide any morphing power."
1392 "encoded in your samples to cross-check:"
1394 for (
auto sampleit : inputParameters) {
1395 const std::string sample(sampleit.first);
1398 setParams(sampleit.second, operators,
true);
1401 for (
auto *obj : dynamic_range_cast<RooAbsReal *>(
_couplings)) {
1404 oocxcoutW((
TObject *)
nullptr, Eval) << obj->GetName() <<
"=" << obj->getVal();
1423 const std::map<std::string, int> &storage,
const RooArgList &physics,
1427 std::cerr <<
"invalid bin width given!" << std::endl;
1431 std::cerr <<
"invalid observable given!" << std::endl;
1445 for (
auto sampleit : inputParameters) {
1447 TString prodname(makeValidName(sampleit.first));
1452 std::cerr <<
"unable to access physics object for " << prodname << std::endl;
1459 std::cerr <<
"unable to access weight object for " << prodname << std::endl;
1462 prodname.Append(
"_");
1463 prodname.Append(
name);
1466 allowNegativeYields =
true;
1467 auto prod = std::make_unique<RooProduct>(prodname, prodname, prodElems);
1468 if (!allowNegativeYields) {
1469 auto maxname = std::string(prodname) +
"_max0";
1472 auto max = std::make_unique<RooFormulaVar>(maxname.c_str(),
"max(0," + prodname +
")", prodset);
1473 max->addOwnedComponents(std::move(prod));
1474 sumElements.addOwned(std::move(max));
1476 sumElements.addOwned(std::move(prod));
1478 scaleElements.add(*(binWidth));
1483 _sumFunc = make_unique<RooRealSumFunc>((std::string(
name) +
"_morphfunc").c_str(),
name, sumElements, scaleElements);
1486 std::cerr <<
"unable to access observable" << std::endl;
1489 std::cerr <<
"unable to access bin width" << std::endl;
1491 if (operators.empty())
1492 std::cerr <<
"no operators listed" << std::endl;
1493 _sumFunc->addServerList(operators);
1495 std::cerr <<
"unable to access weight objects" << std::endl;
1496 _sumFunc->addOwnedComponents(std::move(sumElements));
1497 _sumFunc->addServerList(sumElements);
1498 _sumFunc->addServerList(scaleElements);
1501 std::cout.precision(std::numeric_limits<double>::digits);
1518 if (obsName.empty()) {
1519 std::cerr <<
"Matrix inversion succeeded, but no observable was "
1520 "supplied. quitting..."
1528 setParams(func->
_flags, 1);
1532 setParams(func->
_flags, 1);
1555 setParams(func->
_flags, 1);
1559 setParams(func->
_flags, 1);
1589 return readMatrixFromFileT<TMatrixD>(fname);
1597 return readMatrixFromStreamT<TMatrixD>(stream);
1607 bool obsExists(
false);
1615#pragma warning(push)
1616#pragma warning(disable : 4996)
1618#pragma GCC diagnostic push
1619#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1622 obs =
static_cast<RooRealVar *
>(
dynamic_cast<RooHistFunc *
>(inputExample)->getHistObsList().first());
1625 }
else if (
mode &&
mode->InheritsFrom(RooParamHistFunc::Class())) {
1633#pragma GCC diagnostic pop
1641 TH1 *hist =
static_cast<TH1 *
>(inputExample);
1644 obs = obsOwner.get();
1648 auto obsOwner = std::make_unique<RooRealVar>(obsname, obsname, 0, 1);
1649 obs = obsOwner.get();
1655 if (strcmp(obsname, obs->
GetName()) != 0) {
1657 <<
" does not match expected name " << obsname << std::endl;
1662 auto binWidth = std::make_unique<RooRealVar>(sbw.Data(), sbw.Data(), 1.);
1664 binWidth->setVal(bw);
1665 binWidth->setConstant(
true);
1684 const size_t n(
size(cache->_inverse));
1686 const std::string sample(sampleit.first);
1689 if (!sampleformula) {
1690 coutE(ObjectHandling) <<
Form(
"unable to access formula for sample '%s'!", sample.c_str()) << std::endl;
1693 cxcoutP(ObjectHandling) <<
"updating formula for sample '" << sample <<
"'" << std::endl;
1694 for (
size_t formulaidx = 0; formulaidx <
n; ++formulaidx) {
1699 if (std::isnan(val)) {
1701 coutE(ObjectHandling) <<
"refusing to propagate NaN!" << std::endl;
1703 cxcoutP(ObjectHandling) <<
" " << formulaidx <<
":" << sampleformula->getCoefficient(formulaidx) <<
" -> "
1704 << val << std::endl;
1705 sampleformula->setCoefficient(formulaidx, val);
1706 assert(sampleformula->getCoefficient(formulaidx) == val);
1708 sampleformula->setValueDirty();
1733 std::string obsName;
1745 cxcoutP(InputArguments) <<
"initializing physics inputs from file " << file->
GetName() <<
" with object name(s) '"
1746 << obsName <<
"'" << std::endl;
1748 auto obj = loadFromFileResidentFolder<TObject>(file, folderNames.front(), obsName,
true);
1750 std::cerr <<
"unable to locate object '" << obsName <<
"' in folder '" << folderNames.front() <<
"'!"
1754 std::string classname = obj->ClassName();
1758 if (classname.find(
"TH1") != std::string::npos) {
1761 }
else if (classname.find(
"RooHistFunc") != std::string::npos ||
1762 classname.find(
"RooParamHistFunc") != std::string::npos ||
1763 classname.find(
"PiecewiseInterpolation") != std::string::npos) {
1765 }
else if (classname.find(
"TParameter<double>") != std::string::npos) {
1767 }
else if (classname.find(
"TParameter<float>") != std::string::npos) {
1769 }
else if (classname.find(
"TPair") != std::string::npos) {
1773 std::cerr <<
"cannot morph objects of class '" <<
mode->GetName() <<
"'!" << std::endl;
1784 std::cout << param.first <<
" = " << param.second;
1786 std::cout <<
" (const)";
1787 std::cout << std::endl;
1799 std::cout << folder << std::endl;
1821 _operators(
"operators",
"set of operators", this),
_observables(
"observables",
"morphing observables", this),
1838 std::vector<RooListProxy *> vertices;
1840 vertices.push_back(
new RooListProxy(
"!couplings",
"set of couplings in the vertex",
this,
true,
false));
1852 std::vector<RooListProxy *> vertices;
1854 cxcoutP(InputArguments) <<
"prod/dec couplings provided" << std::endl;
1858 new RooListProxy(
"!production",
"set of couplings in the production vertex",
this,
true,
false));
1859 vertices.push_back(
new RooListProxy(
"!decay",
"set of couplings in the decay vertex",
this,
true,
false));
1865 cxcoutP(InputArguments) <<
"adding non-own operators" << std::endl;
1880 std::stringstream
name;
1881 name <<
"noInterference";
1882 for (
auto c : nonInterfering) {
1886 for (
auto c : nonInterfering) {
1897 for (
size_t i = 0; i < nonInterfering.size(); ++i) {
1910 coutE(InputArguments) <<
"unable to open file '" <<
filename <<
"'!" << std::endl;
1917 auto nNP0 = std::make_unique<RooRealVar>(
"nNP0",
"nNP0", 1., 0, 1.);
1918 nNP0->setStringAttribute(
"NewPhysics",
"0");
1919 nNP0->setConstant(
true);
1921 auto nNP1 = std::make_unique<RooRealVar>(
"nNP1",
"nNP1", 1., 0, 1.);
1922 nNP1->setStringAttribute(
"NewPhysics",
"1");
1923 nNP1->setConstant(
true);
1925 auto nNP2 = std::make_unique<RooRealVar>(
"nNP2",
"nNP2", 1., 0, 1.);
1926 nNP2->setStringAttribute(
"NewPhysics",
"2");
1927 nNP2->setConstant(
true);
1929 auto nNP3 = std::make_unique<RooRealVar>(
"nNP3",
"nNP3", 1., 0, 1.);
1930 nNP3->setStringAttribute(
"NewPhysics",
"3");
1931 nNP3->setConstant(
true);
1933 auto nNP4 = std::make_unique<RooRealVar>(
"nNP4",
"nNP4", 1., 0, 1.);
1934 nNP4->setStringAttribute(
"NewPhysics",
"4");
1935 nNP4->setConstant(
true);
1943 :
RooAbsReal(other,
name), _cacheMgr(other._cacheMgr, this), _scale(other._scale), _sampleMap(other._sampleMap),
1944 _physics(other._physics.GetName(), this, other._physics),
1945 _operators(other._operators.GetName(), this, other._operators),
1946 _observables(other._observables.GetName(), this, other._observables),
1947 _binWidths(other._binWidths.GetName(), this, other._binWidths), _flags{other._flags.GetName(), this, other._flags},
1948 _config(other._config)
1950 for (
size_t j = 0; j < other._diagrams.size(); ++j) {
1951 std::vector<RooListProxy *> diagram;
1952 for (
auto *elem : other._diagrams[j]) {
1954 diagram.push_back(list);
1980 : _cacheMgr(this, 10, true, true), _operators(
"operators",
"set of operators", this, true, false),
1981 _observables(
"observable",
"morphing observable", this, true, false),
1982 _binWidths(
"binWidths",
"set of bin width objects", this, true, false)
2004 FeynmanDiagram diagram;
2005 std::vector<bool> prod;
2006 std::vector<bool> dec;
2007 for (
int i = 0; i < nboth; ++i) {
2008 prod.push_back(
true);
2009 dec.push_back(
true);
2011 for (
int i = 0; i < nprod; ++i) {
2012 prod.push_back(
true);
2013 dec.push_back(
false);
2015 for (
int i = 0; i < ndec; ++i) {
2016 prod.push_back(
false);
2017 dec.push_back(
true);
2019 diagram.push_back(prod);
2020 diagram.push_back(dec);
2021 MorphFuncPattern morphfuncpattern;
2022 ::collectPolynomials(morphfuncpattern, diagram);
2023 return morphfuncpattern.size();
2033 for (
auto vertex : vertices) {
2034 extractOperators(*vertex, operators);
2035 extractCouplings(*vertex, couplings);
2037 FeynmanDiagram diagram;
2038 ::fillFeynmanDiagram(diagram, vertices, couplings);
2039 MorphFuncPattern morphfuncpattern;
2040 ::collectPolynomials(morphfuncpattern, diagram);
2041 return morphfuncpattern.size();
2047std::map<std::string, std::string>
2049 const std::vector<std::vector<std::string>> &vertices_str)
2051 std::stack<RooArgList> ownedVertices;
2052 std::vector<RooArgList *> vertices;
2054 for (
const auto &vtx : vertices_str) {
2055 ownedVertices.emplace();
2056 auto &vertex = ownedVertices.top();
2057 for (
const auto &
c : vtx) {
2060 auto couplingOwner = std::make_unique<RooRealVar>(
c.c_str(),
c.c_str(), 1., 0., 10.);
2061 coupling = couplingOwner.get();
2062 couplings.
addOwned(std::move(couplingOwner));
2064 vertex.add(*coupling);
2066 vertices.push_back(&vertex);
2075std::map<std::string, std::string>
2077 const std::vector<RooArgList *> &vertices,
RooArgList &couplings)
2085std::map<std::string, std::string>
2087 const std::vector<RooArgList *> &vertices,
RooArgList &couplings,
2089 const std::vector<std::vector<std::string>> &nonInterfering)
2091 FormulaList formulas = ::createFormulas(
"", inputs, flagValues, {vertices}, couplings, flags, nonInterfering);
2093 extractOperators(couplings, operators);
2094 Matrix matrix(::buildMatrixT<Matrix>(inputs, formulas, operators, flagValues, flags));
2095 if (
size(matrix) < 1) {
2096 std::cerr <<
"input matrix is empty, please provide suitable input samples!" << std::endl;
2100 auto retval = buildSampleWeightStrings(inputs, formulas, inverse);
2108 const std::vector<RooArgList *> &vertices,
RooArgList &couplings,
2111 const std::vector<std::vector<std::string>> &nonInterfering)
2113 FormulaList formulas = ::createFormulas(
"", inputs, flagValues, {vertices}, couplings, flags, nonInterfering);
2115 extractOperators(couplings, operators);
2116 Matrix matrix(::buildMatrixT<Matrix>(inputs, formulas, operators, flagValues, flags));
2117 if (
size(matrix) < 1) {
2118 std::cerr <<
"input matrix is empty, please provide suitable input samples!" << std::endl;
2123 ::buildSampleWeights(retval, (
const char *)
nullptr , inputs, formulas, inverse);
2131 const std::vector<RooArgList *> &vertices,
RooArgList &couplings)
2146 coutE(Eval) <<
"unable to retrieve morphing function" << std::endl;
2149 std::unique_ptr<RooArgSet> args{mf->getComponents()};
2151 prodname.Append(
"_");
2152 prodname.Append(this->
GetName());
2154 for (
auto *prod : dynamic_range_cast<RooProduct *>(*args)) {
2157 TString sname(prod->GetName());
2158 if (sname.CompareTo(prodname) == 0) {
2178 auto wname = std::string(
"w_") +
name +
"_" + this->
GetName();
2179 return dynamic_cast<RooAbsReal *
>(cache->_weights.find(wname.c_str()));
2197 auto weightName = std::string(
"w_") + sample.first +
"_" + this->
GetName();
2198 auto weight =
static_cast<RooAbsReal *
>(cache->_weights.find(weightName.c_str()));
2212 for (
auto *obj : dynamic_range_cast<RooRealVar *>(
_operators)) {
2213 double val = obj->getVal();
2214 if (obj->isConstant())
2216 double variation =
r.Gaus(1, z);
2217 obj->setVal(val * variation);
2232 coutE(InputArguments) <<
"unable to open file '" <<
filename <<
"'!" << std::endl;
2259 cache->_inverse =
m;
2262 coutE(InputArguments) <<
"unable to open file '" <<
filename <<
"'!" << std::endl;
2277 coutE(Caching) <<
"unable to create cache!" << std::endl;
2296 coutE(Caching) <<
"unable to create cache!" << std::endl;
2321 cxcoutP(Caching) <<
"creating cache from getCache function for " <<
this << std::endl;
2322 cxcoutP(Caching) <<
"current storage has size " <<
_sampleMap.size() << std::endl;
2327 coutE(Caching) <<
"unable to create cache!" << std::endl;
2352 if (value < param->getMin())
2476 auto paramhist = loadFromFileResidentFolder<TH1>(file, foldername,
"param_card");
2477 setParams(paramhist.get(),
_operators,
false);
2487 const std::string
name(foldername);
2497 for (
auto *param : dynamic_range_cast<RooRealVar *>(*list)) {
2510 coutE(InputArguments) <<
"observable not available!" << std::endl;
2522 coutE(InputArguments) <<
"bin width not available!" << std::endl;
2541 auto mf = std::make_unique<RooRealSumFunc>(*(this->
getFunc()));
2544 const int nbins = observable->
getBins();
2548 std::unique_ptr<RooArgSet> args{mf->getComponents()};
2549 for (
int i = 0; i < nbins; ++i) {
2554 for (
auto *prod : dynamic_range_cast<RooProduct *>(*args)) {
2557 RooAbsArg *phys = prod->components().find(
Form(
"phys_%s", prod->GetName()));
2564 double weight = formula->
getVal();
2565 const double w2 = dhist.weightSquared(i);
2566 unc2 += w2 * weight * weight;
2567 unc += sqrt(w2) * weight;
2568 val += dhist.weight(i) * weight;
2571 hist->
SetBinError(i + 1, correlateErrors ? unc : sqrt(unc2));
2573 return hist.release();
2582 auto mf = std::make_unique<RooRealSumFunc>(*(this->
getFunc()));
2584 coutE(InputArguments) <<
"unable to retrieve morphing function" << std::endl;
2585 std::unique_ptr<RooArgSet> args{mf->getComponents()};
2586 for (
auto *prod : dynamic_range_cast<RooProduct *>(*args)) {
2587 if (prod->getVal() != 0) {
2601 std::string pname(paramname);
2603 bool isUsed =
false;
2605 double thisval = sample.second.at(pname);
2606 if (thisval != val) {
2622 std::string
cname(couplname);
2629 bool isUsed =
false;
2632 double thisval = coupling->getVal();
2633 if (thisval != val) {
2658 return cache->_formulas.size();
2666 auto mf = std::make_unique<RooRealSumFunc>(*(this->
getFunc()));
2668 std::cerr <<
"Error: unable to retrieve morphing function" << std::endl;
2671 std::unique_ptr<RooArgSet> args{mf->getComponents()};
2672 for (
auto *formula : dynamic_range_cast<RooAbsReal*>(*args)) {
2676 name.Prepend(
"phys_");
2677 if (!args->find(
name.Data())) {
2680 double val = formula->getVal();
2682 std::cout << formula->GetName() <<
": " << val <<
" = " << formula->GetTitle() << std::endl;
2702 return &(cache->_couplings);
2711 for (
auto *var : dynamic_range_cast<RooAbsReal *>(*(this->
getCouplingSet()))) {
2715 double val = var->
getVal();
2716 couplings[
name] = val;
2743 auto func = std::make_unique<RooRealSumFunc>(*(cache->_sumFunc));
2746 return std::make_unique<RooWrapperPdf>(
Form(
"pdf_%s", func->GetName()),
Form(
"pdf of %s", func->GetTitle()), *func);
2755 return cache->_sumFunc.get();
2772 return this->
createPdf()->expectedEvents(nset);
2782 return this->
createPdf()->expectedEvents(set);
2791 return createPdf()->expectedEvents(&nset);
2804 auto weightName = std::string(
"w_") + sample.first +
"_" + this->
GetName();
2805 auto weight =
static_cast<RooAbsReal *
>(cache->_weights.find(weightName.c_str()));
2807 coutE(InputArguments) <<
"unable to find object " + weightName << std::endl;
2819 newunc2 = pow(rv->getError(), 2);
2821 double w = weight->getVal();
2822 unc2 += newunc2 *
w *
w;
2836 for (
auto *param : static_range_cast<RooRealVar *>(
_operators)) {
2848 for (
auto *param : static_range_cast<RooRealVar *>(
_flags)) {
2861 for (
auto c : couplings) {
2862 std::cout <<
c.first <<
": " <<
c.second << std::endl;
2896 std::cerr <<
"unable to acquire in-built function!" << std::endl;
2929 const char *rangeName)
const
2957 coutE(Caching) <<
"unable to retrieve cache!" << std::endl;
2968 coutE(Caching) <<
"unable to retrieve cache!" << std::endl;
2981 coutE(Caching) <<
"unable to retrieve cache!" << std::endl;
2982 return cache->_condition;
2988std::unique_ptr<RooRatio>
2993 for (
auto it : nr) {
2996 for (
auto it : dr) {
3000 return make_unique<RooRatio>(
name, title, num, denom);
3008std::vector<std::string> asStringV(std::string
const &arg)
3010 std::vector<std::string> out;
3012 for (std::string &tok :
ROOT::Split(arg,
",{}", true)) {
3013 if (tok[0] ==
'\'') {
3014 out.emplace_back(tok.substr(1, tok.size() - 2));
3016 throw std::runtime_error(
"Strings in factory expressions need to be in single quotes!");
3026 create(
RooFactoryWSTool &,
const char *typeName,
const char *instName, std::vector<std::string> args)
override;
3029std::string LMIFace::create(
RooFactoryWSTool &ft,
const char * ,
const char *instanceName,
3030 std::vector<std::string> args)
3033 const std::array<std::string, 4> funcArgs{{
"fileName",
"observableName",
"couplings",
"folders"}};
3034 std::map<string, string> mappedInputs;
3036 for (
unsigned int i = 1; i < args.size(); i++) {
3037 if (args[i].find(
"$fileName(") != 0 && args[i].find(
"$observableName(") != 0 &&
3038 args[i].find(
"$couplings(") != 0 && args[i].find(
"$folders(") != 0 && args[i].find(
"$NewPhysics(") != 0) {
3039 throw std::string(
Form(
"%s::create() ERROR: unknown token %s encountered", instanceName, args[i].c_str()));
3043 for (
unsigned int i = 0; i < args.size(); i++) {
3044 if (args[i].find(
"$NewPhysics(") == 0) {
3045 vector<string> subargs = ft.splitFunctionArgs(args[i].c_str());
3046 for (
const auto &subarg : subargs) {
3047 std::vector<std::string> parts =
ROOT::Split(subarg,
"=");
3048 if (parts.size() == 2) {
3049 ft.ws().arg(parts[0])->setAttribute(
"NewPhysics", atoi(parts[1].c_str()));
3051 throw std::string(
Form(
"%s::create() ERROR: unknown token %s encountered, check input provided for %s",
3052 instanceName, subarg.c_str(), args[i].c_str()));
3056 std::vector<string> subargs = ft.splitFunctionArgs(args[i].c_str());
3057 if (subargs.size() == 1) {
3058 string expr = ft.processExpression(subargs[0].c_str());
3059 for (
auto const ¶m : funcArgs) {
3060 if (args[i].find(param) != string::npos)
3061 mappedInputs[param] = subargs[0];
3065 Form(
"Incorrect number of arguments in %s, have %d, expect 1", args[i].c_str(), (
Int_t)subargs.size()));
3071 config.
fileName = asStringV(mappedInputs[
"fileName"])[0];
3072 config.
observableName = asStringV(mappedInputs[
"observableName"])[0];
3073 config.
folderNames = asStringV(mappedInputs[
"folders"]);
3074 config.
couplings.
add(ft.asLIST(mappedInputs[
"couplings"].c_str()));
3078 return instanceName;
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)
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
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'.
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
virtual double * array() const =0
Abstract base class for objects to be stored in RooAbsCache cache manager objects.
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.
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...
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=nullptr)
Setter function without integration set.
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=nullptr, const TNamed *isetRangeName=nullptr)
Getter function without integration set.
bool addOwned(RooAbsArg &var, bool silent=false) override
Overloaded RooCollection_t::addOwned() method insert object into owning set and registers object as s...
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
Container class to hold N-dimensional binned data.
double weightSquared(std::size_t i) const
Return squared weight sum of i-th bin.
A real-valued function sampled from a multidimensional histogram.
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
Class RooLagrangianMorphing is a implementation of the method of Effective Lagrangian Morphing,...
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
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.
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...
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 ...
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.
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.
Class to manage histogram axis.
TClass instances represent classes, structs and namespaces in the ROOT type system.
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.
Describe directory structure in memory.
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.
void Close(Option_t *option="") override
Close a file.
<div class="legacybox"><h2>Legacy Code</h2> TFolder is a legacy interface: there will be no bug fixes...
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.
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.
Random number generator class based on M.
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)
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
std::vector< std::vector< const char * > > nonInterfering