40using std::string, std::vector;
52 _cacheMgr(this, 10, true, true),
53 _parList(
"parList",
"List of morph parameters", this),
54 _obsList(
"obsList",
"List of observables", this),
55 _referenceGrid(referenceGrid),
56 _pdfList(
"pdfList",
"List of pdfs", this),
77 _cacheMgr(this, 10, true, true),
78 _parList(
"parList",
"List of morph parameters", this),
79 _obsList(
"obsList",
"List of observables", this),
80 _pdfList(
"pdfList",
"List of pdfs", this),
85 RooBinning grid(mrefpoints.GetNrows() - 1, mrefpoints.GetMatrixArray());
88 for (
int i = 0; i < mrefpoints.GetNrows(); ++i) {
89 for (
int j = 0; j < grid.numBoundaries(); ++j) {
90 if (mrefpoints[i] == grid.array()[j]) {
116 _cacheMgr(this, 10, true, true),
117 _parList(
"parList",
"List of morph parameters", this),
118 _obsList(
"obsList",
"List of observables", this),
119 _pdfList(
"pdfList",
"List of pdfs", this),
124 TVectorD mrefpoints(mrefList.size());
126 for (
auto *mref : mrefList) {
128 coutE(InputArguments) <<
"RooMomentMorphFuncND::ctor(" <<
GetName() <<
") ERROR: mref " << mref->GetName()
129 <<
" is not of type RooAbsReal" << std::endl;
130 throw string(
"RooMomentMorphFuncND::ctor() ERROR mref is not of type RooAbsReal");
133 coutW(InputArguments) <<
"RooMomentMorphFuncND::ctor(" <<
GetName() <<
") WARNING mref point " << i
134 <<
" is not a constant, taking a snapshot of its value" << std::endl;
140 RooBinning grid(mrefpoints.GetNrows() - 1, mrefpoints.GetMatrixArray());
142 for (i = 0; i < mrefpoints.GetNrows(); ++i) {
143 for (
int j = 0; j < grid.numBoundaries(); ++j) {
144 if (mrefpoints[i] == grid.array()[j]) {
169 _cacheMgr(other._cacheMgr, this),
170 _parList(
"parList", this, other._parList),
171 _obsList(
"obsList", this, other._obsList),
172 _referenceGrid(other._referenceGrid),
173 _pdfList(
"pdfList", this, other._pdfList),
174 _setting(other._setting),
175 _useHorizMorph(other._useHorizMorph),
176 _isPdfMode{other._isPdfMode}
200 int depth = std::pow(2, nPar);
203 coutE(InputArguments) <<
"RooMomentMorphFuncND::initialize(" <<
GetName() <<
") ERROR: nPar != nDim"
204 <<
": " << nPar <<
" !=" << nDim << std::endl;
209 coutE(InputArguments) <<
"RooMomentMorphFuncND::initialize(" <<
GetName() <<
") ERROR: nPdf != nRef"
210 <<
": " << nPdf <<
" !=" << nRef << std::endl;
215 _M = std::make_unique<TMatrixD>(nPdf, nPdf);
216 _MSqr = std::make_unique<TMatrixD>(depth, depth);
220 vector<vector<double>> dm(nPdf);
221 for (
int k = 0; k < nPdf; ++k) {
223 for (
int idim = 0; idim < nPar; idim++) {
225 dm2.push_back(delta);
230 vector<vector<int>> powers;
231 for (
int idim = 0; idim < nPar; idim++) {
237 powers.push_back(xtmp);
240 vector<vector<int>> output;
242 int nCombs = output.size();
244 for (
int k = 0; k < nPdf; ++k) {
246 for (
int i = 0; i < nCombs; i++) {
248 for (
int ix = 0; ix < nPar; ix++) {
249 double delta = dm[k][ix];
250 tmpDm *= std::pow(delta,
static_cast<double>(output[i][ix]));
268 : _pdfList(other._pdfList), _pdfMap(other._pdfMap), _nref(other._nref)
270 for (
unsigned int i = 0; i < other._grid.size(); i++) {
271 _grid.push_back(other._grid[i]->clone());
286 vector<int> thisBoundaries;
287 vector<double> thisBoundaryCoordinates;
288 thisBoundaries.push_back(bin_x);
289 thisBoundaryCoordinates.push_back(_grid[0]->array()[bin_x]);
292 _nref.push_back(thisBoundaryCoordinates);
298 vector<int> thisBoundaries;
299 vector<double> thisBoundaryCoordinates;
300 thisBoundaries.push_back(bin_x);
301 thisBoundaryCoordinates.push_back(_grid[0]->array()[bin_x]);
302 thisBoundaries.push_back(bin_y);
303 thisBoundaryCoordinates.push_back(_grid[1]->array()[bin_y]);
306 _nref.push_back(thisBoundaryCoordinates);
312 vector<int> thisBoundaries;
313 vector<double> thisBoundaryCoordinates;
314 thisBoundaries.push_back(bin_x);
315 thisBoundaryCoordinates.push_back(_grid[0]->array()[bin_x]);
316 thisBoundaries.push_back(bin_y);
317 thisBoundaryCoordinates.push_back(_grid[1]->array()[bin_y]);
318 thisBoundaries.push_back(bin_z);
319 thisBoundaryCoordinates.push_back(_grid[2]->array()[bin_z]);
322 _nref.push_back(thisBoundaryCoordinates);
328 vector<double> thisBoundaryCoordinates;
329 int nBins = bins.size();
330 thisBoundaryCoordinates.reserve(nBins);
331 for (
int i = 0; i < nBins; i++) {
332 thisBoundaryCoordinates.push_back(_grid[i]->array()[bins[i]]);
336 _nref.push_back(thisBoundaryCoordinates);
340std::unique_ptr<RooAbsArg>
361 cache->
_sum->branchNodeServerList(&branches);
362 for (
auto *
b : branches) {
363 std::vector<std::string> toRemove;
364 for (
auto const &
attr :
b->attributes()) {
365 if (
attr.rfind(
"ORIGNAME:", 0) == 0)
366 toRemove.push_back(
attr);
368 for (
auto const &
attr : toRemove)
369 b->setAttribute(
attr.c_str(),
false);
380 for (
int i = 0; i < nFrac; ++i) {
382 std::string newName = std::string{frac->
GetName()} +
"_compiled";
383 newFractions.addOwned(
384 std::make_unique<RooFit::Detail::RooMomentMorphFraction>(newName.c_str(), frac->GetTitle(), *
this, i));
389 cust.setCloneBranchSet(clonedBranches);
390 for (
int i = 0; i < nFrac; ++i) {
391 cust.replaceArg(*cache->
_frac.
at(i), newFractions[i]);
398 std::unique_ptr<RooAbsReal> newSum{
static_cast<RooAbsReal *
>(cust.build())};
406 newSum->branchNodeServerList(&branches);
407 for (
auto *
b : branches) {
409 ctx.markAsCompiled(*
b);
411 ctx.compileServers(*newSum, normSet);
416 ctx.markSubtreeAsCompiled(*newSum);
417 ctx.compileServers(*newSum, normSet);
428 :
RooAbsReal(
name, title), _parList(
"parList",
"parList", this), _parent(&parent), _index(
index)
434 :
RooAbsReal(other,
name), _parList(
"parList", this, other._parList), _parent(other._parent), _index(other._index)
440 auto *cache =
_parent->getCache(
nullptr);
441 if (cache->_tracker->hasChanged(
true)) {
442 cache->calculateFractions(*
_parent,
false);
444 return cache->frac(
_index)->getVal();
462 vector<RooAbsReal *> meanrv(nPdf * nObs, null);
463 vector<RooAbsReal *> sigmarv(nPdf * nObs, null);
464 vector<RooAbsReal *> myrms(nObs, null);
465 vector<RooAbsReal *> mypos(nObs, null);
466 vector<RooAbsReal *> slope(nPdf * nObs, null);
467 vector<RooAbsReal *> offsets(nPdf * nObs, null);
468 vector<RooAbsReal *> transVar(nPdf * nObs, null);
469 vector<RooAbsReal *> transPdf(nPdf, null);
479 for (
int i = 0; i < 3 * nPdf; ++i) {
480 string fracName =
Form(
"frac_%d", i);
487 }
else if (i < 2 * nPdf) {
488 coefList2.add(*
static_cast<RooRealVar *
>(fracl.at(i)));
490 coefList3.add(*
static_cast<RooRealVar *
>(fracl.at(i)));
492 ownedComps.add(*
static_cast<RooRealVar *
>(fracl.at(i)));
495 std::unique_ptr<RooAbsReal> theSum;
502 for (
int i = 0; i < nPdf; ++i) {
503 for (
int j = 0; j < nObs; ++j) {
507 mom->setLocalNoDirtyInhibit(
true);
508 mom->mean()->setLocalNoDirtyInhibit(
true);
510 sigmarv[
sij(i, j)] = mom;
511 meanrv[
sij(i, j)] = mom->mean();
513 ownedComps.add(*sigmarv[
sij(i, j)]);
518 for (
int j = 0; j < nObs; ++j) {
521 for (
int i = 0; i < nPdf; ++i) {
522 meanList.add(*meanrv[
sij(i, j)]);
523 rmsList.add(*sigmarv[
sij(i, j)]);
525 string myrmsName =
Form(
"%s_rms_%d",
GetName(), j);
526 string myposName =
Form(
"%s_pos_%d",
GetName(), j);
527 mypos[j] =
new RooAddition(myposName.c_str(), myposName.c_str(), meanList, coefList2);
528 myrms[j] =
new RooAddition(myrmsName.c_str(), myrmsName.c_str(), rmsList, coefList3);
529 ownedComps.add(
RooArgSet(*myrms[j], *mypos[j]));
535 for (
auto const *pdf : static_range_cast<Base_t *>(
_pdfList)) {
537 string pdfName =
Form(
"pdf_%d", i);
541 for (
auto *var : static_range_cast<RooRealVar *>(obsList)) {
543 string slopeName =
Form(
"%s_slope_%d_%d",
GetName(), i, j);
544 string offsetName =
Form(
"%s_offset_%d_%d",
GetName(), i, j);
553 string transVarName =
Form(
"%s_transVar_%d_%d",
GetName(), i, j);
554 transVar[
sij(i, j)] =
new RooLinearVar(transVarName.c_str(), transVarName.c_str(), *var, *slope[
sij(i, j)],
555 *offsets[
sij(i, j)]);
561 ownedComps.add(*transVar[
sij(i, j)]);
562 cust.replaceArg(*var, *transVar[
sij(i, j)]);
565 transPdf[i] =
static_cast<Base_t *
>(cust.build());
566 transPdfList.add(*transPdf[i]);
567 ownedComps.add(*transPdf[i]);
575 theSum = std::make_unique<RooAddPdf>(sumName.c_str(), sumName.c_str(), pdfList, coefList);
577 theSum = std::make_unique<RooRealSumFunc>(sumName.c_str(), sumName.c_str(), pdfList, coefList);
583 theSum->addOwnedComponents(ownedComps);
586 std::string trackerName = std::string(
GetName()) +
"_frac_tracker";
590 std::make_unique<RooChangeTracker>(trackerName.c_str(), trackerName.c_str(),
_parList,
true),
598 std::unique_ptr<RooChangeTracker> &&tracker,
const RooArgList &flist)
599 : _sum(std::move(sumFunc)), _tracker(std::move(tracker))
626 if (cache->
_tracker->hasChanged(
true)) {
629 return cache->
_sum.get();
637 if (cache->
_tracker->hasChanged(
true)) {
649 return static_cast<RooRealVar *
>(_frac.at(i));
655 return static_cast<RooRealVar *
>(_frac.at(i));
661 int nPdf = self._pdfList.size();
662 int nPar = self._parList.size();
664 double fracLinear(1.);
665 double fracNonLinear(1.);
670 for (
int idim = 0; idim < nPar; idim++) {
671 double delta = (
static_cast<RooRealVar *
>(self._parList.at(idim)))->getVal() - self._referenceGrid._nref[0][idim];
672 dm2.push_back(delta);
675 vector<vector<int>> powers;
676 for (
int idim = 0; idim < nPar; idim++) {
678 xtmp.reserve(self._referenceGrid._nnuis[idim]);
679 for (
int ix = 0; ix < self._referenceGrid._nnuis[idim]; ix++) {
682 powers.push_back(xtmp);
685 vector<vector<int>> output;
687 int nCombs = output.size();
689 vector<double> deltavec(nPdf, 1.0);
692 for (
int i = 0; i < nCombs; i++) {
694 for (
int ix = 0; ix < nPar; ix++) {
695 double delta = dm2[ix];
696 tmpDm *= std::pow(delta,
static_cast<double>(output[i][ix]));
698 deltavec[nperm] = tmpDm;
702 double sumposfrac = 0.0;
703 for (
int i = 0; i < nPdf; ++i) {
706 for (
int j = 0; j < nPdf; ++j) {
707 ffrac += (*self._M)(j, i) * deltavec[j] * fracNonLinear;
716 const_cast<RooRealVar *
>(frac(i))->setVal(ffrac);
720 const_cast<RooRealVar *
>(frac(nPdf + i))->setVal(ffrac);
721 const_cast<RooRealVar *
>(frac(2 * nPdf + i))->setVal(ffrac);
724 std::cout <<
"NonLinear fraction " << ffrac << std::endl;
726 frac(nPdf + i)->Print();
727 frac(2 * nPdf + i)->Print();
732 for (
int i = 0; i < nPdf; ++i) {
733 if (frac(i)->
getVal() < 0)
734 const_cast<RooRealVar *
>(frac(i))->setVal(0.);
735 const_cast<RooRealVar *
>(frac(i))->setVal(frac(i)->getVal() / sumposfrac);
743 for (
int i = 0; i < nPdf; ++i) {
745 const_cast<RooRealVar *
>(frac(i))->setVal(initval);
746 const_cast<RooRealVar *
>(frac(nPdf + i))->setVal(initval);
747 const_cast<RooRealVar *
>(frac(2 * nPdf + i))->setVal(initval);
750 std::vector<double> mtmp;
753 for (
auto *
m : static_range_cast<RooRealVar *>(self._parList)) {
754 mtmp.push_back(
m->getVal());
757 self.findShape(mtmp);
759 int depth = std::pow(2, nPar);
760 vector<double> deltavec(depth, 1.0);
766 for (
int ix = 0; ix < nPar; ix++) {
770 for (
int iperm = 1; iperm <= nPar; ++iperm) {
772 double dtmp = mtmp[xtmp[0]] - self._squareVec[0][xtmp[0]];
773 for (
int itmp = 1; itmp < iperm; ++itmp) {
774 dtmp *= mtmp[xtmp[itmp]] - self._squareVec[0][xtmp[itmp]];
776 deltavec[nperm + 1] = dtmp;
781 double origFrac1(0.);
782 double origFrac2(0.);
783 for (
int i = 0; i < depth; ++i) {
785 for (
int j = 0; j < depth; ++j) {
786 ffrac += (*self._MSqr)(j, i) * deltavec[j] * fracLinear;
790 origFrac1 = frac(self._squareIdx[i])->getVal();
791 const_cast<RooRealVar *
>(frac(self._squareIdx[i]))->setVal(origFrac1 + ffrac);
796 frac(nPdf + self._squareIdx[i])->
getVal();
797 const_cast<RooRealVar *
>(frac(nPdf + self._squareIdx[i]))->setVal(origFrac2 + ffrac);
798 const_cast<RooRealVar *
>(frac(2 * nPdf + self._squareIdx[i]))->setVal(origFrac2 + ffrac);
802 std::cout <<
"Linear fraction " << ffrac << std::endl;
803 frac(self._squareIdx[i])->
Print();
804 frac(nPdf + self._squareIdx[i])->Print();
805 frac(2 * nPdf + self._squareIdx[i])->Print();
828 int depth = std::pow(2, nPar);
830 vector<vector<double>> boundaries(nPar);
831 for (
int idim = 0; idim < nPar; idim++) {
835 boundaries[idim].push_back(lo);
836 boundaries[idim].push_back(
hi);
839 vector<vector<double>> output;
843 for (
int isq = 0; isq < depth; isq++) {
851 for (
int iref = 0; iref < nRef; iref++) {
858 coutE(InputArguments) <<
"RooMomentMorphFuncND::findShape(" <<
GetName()
859 <<
") ERROR: no reference pdf found for grid corner (";
860 for (
unsigned int ix = 0; ix <
_squareVec[isq].size(); ++ix) {
863 ccoutE(InputArguments) <<
") of the hypercube enclosing the current morphing "
864 <<
"parameter point. The reference grid is missing a pdf at this "
865 <<
"coordinate -- check that RooMomentMorphFuncND::Grid::addPdf() was "
866 <<
"called for every corner of the parameter range." << std::endl;
867 throw string(
"RooMomentMorphFuncND::findShape() ERROR: incomplete reference grid");
887 for (
int ix = 0; ix < nPar; ix++) {
891 for (
int k = 0; k < depth; ++k) {
897 for (
int iperm = 1; iperm <= nPar; ++iperm) {
899 double dtmp =
_squareVec[k][xtmp[0]] - squareBase[xtmp[0]];
900 for (
int itmp = 1; itmp < iperm; ++itmp) {
901 dtmp *=
_squareVec[k][xtmp[itmp]] - squareBase[xtmp[itmp]];
903 M(k, nperm + 1) = dtmp;
910 (*_MSqr) = M.Invert();
916 if (allVars.
size() == 1) {
923 std::cout <<
"Currently BinIntegrator only knows how to deal with 1-d " << std::endl;
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
void Print(Option_t *options=nullptr) const override
Print the object to the defaultPrintStream().
bool addOwnedComponents(const RooAbsCollection &comps)
Take ownership of the contents of 'comps'.
Abstract base class for RooRealVar binning definitions.
Abstract container object that can hold multiple RooAbsArg objects.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
RooAbsArg * first() const
bool addTyped(const RooAbsCollection &list, bool silent=false)
Adds elements of a given RooAbsCollection to the container if they match the specified type.
const RooArgSet * nset() const
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.
virtual double getValV(const RooArgSet *normalisationSet=nullptr) const
Return value of object.
RooNumIntConfig * specialIntegratorConfig() const
Returns the specialized integrator configuration for this RooAbsReal.
Calculates the sum of a set of RooAbsReal terms, or when constructed with two sets,...
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 setLabel(const char *label, bool printError=true) override
Set value by specifying the name of the desired state.
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...
Represents a constant real-valued object.
RooCustomizer is a factory class to produce clones of a prototype composite PDF object with the same ...
Helper compute-graph node that exposes one of the morph mixing fractions to the RooFit::Evaluator.
const RooMomentMorphFuncND * _parent
! morph that owns the cache (not owned)
double evaluate() const override
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
RooLinearVar is the most general form of a derived real-valued object that can be used by RooRealInte...
void calculateFractions(const RooMomentMorphFuncND &self, bool verbose=true) const
std::unique_ptr< RooChangeTracker > _tracker
std::unique_ptr< RooAbsReal > _sum
RooArgList containedArgs(Action) override
CacheElem(std::unique_ptr< RooAbsReal > &&sumFunc, std::unique_ptr< RooChangeTracker > &&tracker, const RooArgList &flist)
std::vector< int > _nnuis
void addBinning(const RooAbsBinning &binning)
std::vector< RooAbsBinning * > _grid
std::vector< std::vector< double > > _nref
void addPdf(const RooAbsReal &func, int bin_x)
RooObjCacheManager _cacheMgr
! Transient cache manager
std::unique_ptr< TMatrixD > _MSqr
void findShape(const std::vector< double > &x) const
double evaluate() const override
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
RooAbsReal * sumFunc(const RooArgSet *nset)
CacheElem * getCache(const RooArgSet *nset) const
std::unique_ptr< TMatrixD > _M
RooArgSet * _curNormSet
! Transient cache manager
bool setBinIntegrator(RooArgSet &allVars)
double getValV(const RooArgSet *set=nullptr) const override
Return value of object.
std::vector< std::vector< double > > _squareVec
int sij(const int &i, const int &j) const
std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) const override
~RooMomentMorphFuncND() override
std::vector< int > _squareIdx
const RooArgSet & getConfigSection(const char *name) const
Retrieve configuration information specific to integrator with given name.
Variable that can be changed from the outside.
const char * GetName() const override
Returns name of object.
void cartesianProduct(std::vector< std::vector< T > > &out, std::vector< std::vector< T > > &in)
bool nextCombination(const Iterator first, Iterator k, const Iterator last)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...