43using std::cout, std::endl, std::string, std::vector;
59 _parList(
"parList",
"List of morph parameters", this),
60 _obsList(
"obsList",
"List of observables", this),
62 _pdfList(
"pdfList",
"List of pdfs", this),
85 _parList(
"parList",
"List of morph parameters", this),
86 _obsList(
"obsList",
"List of observables", this),
87 _pdfList(
"pdfList",
"List of pdfs", this),
97 if (mrefpoints[
i] == grid.
array()[j]) {
125 _parList(
"parList",
"List of morph parameters", this),
126 _obsList(
"obsList",
"List of observables", this),
127 _pdfList(
"pdfList",
"List of pdfs", this),
134 for (
auto *mref : mrefList) {
136 coutE(InputArguments) <<
"RooMomentMorphFuncND::ctor(" <<
GetName() <<
") ERROR: mref " << mref->GetName()
137 <<
" is not of type RooAbsReal" << endl;
138 throw string(
"RooMomentMorphFuncND::ctor() ERROR mref is not of type RooAbsReal");
141 coutW(InputArguments) <<
"RooMomentMorphFuncND::ctor(" <<
GetName() <<
") WARNING mref point " <<
i
142 <<
" is not a constant, taking a snapshot of its value" << endl;
152 if (mrefpoints[
i] == grid.
array()[j]) {
200void RooMomentMorphFuncND::initialize()
211 int depth = std::pow(2, nPar);
214 coutE(InputArguments) <<
"RooMomentMorphFuncND::initialize(" <<
GetName() <<
") ERROR: nPar != nDim"
215 <<
": " << nPar <<
" !=" << nDim << endl;
220 coutE(InputArguments) <<
"RooMomentMorphFuncND::initialize(" <<
GetName() <<
") ERROR: nPdf != nRef"
221 <<
": " << nPdf <<
" !=" << nRef << endl;
226 _M = std::make_unique<TMatrixD>(nPdf, nPdf);
227 _MSqr = std::make_unique<TMatrixD>(depth, depth);
231 vector<vector<double>> dm(nPdf);
232 for (
int k = 0; k < nPdf; ++k) {
234 for (
int idim = 0; idim < nPar; idim++) {
236 dm2.push_back(delta);
241 vector<vector<int>> powers;
242 for (
int idim = 0; idim < nPar; idim++) {
248 powers.push_back(xtmp);
251 vector<vector<int>>
output;
253 int nCombs =
output.size();
255 for (
int k = 0; k < nPdf; ++k) {
257 for (
int i = 0;
i < nCombs;
i++) {
259 for (
int ix = 0; ix < nPar; ix++) {
260 double delta = dm[k][ix];
261 tmpDm *= std::pow(delta,
static_cast<double>(
output[
i][ix]));
281 for (
unsigned int i = 0;
i < other.
_grid.size();
i++) {
297 vector<int> thisBoundaries;
298 vector<double> thisBoundaryCoordinates;
299 thisBoundaries.push_back(bin_x);
300 thisBoundaryCoordinates.push_back(
_grid[0]->array()[bin_x]);
303 _nref.push_back(thisBoundaryCoordinates);
309 vector<int> thisBoundaries;
310 vector<double> thisBoundaryCoordinates;
311 thisBoundaries.push_back(bin_x);
312 thisBoundaryCoordinates.push_back(
_grid[0]->array()[bin_x]);
313 thisBoundaries.push_back(bin_y);
314 thisBoundaryCoordinates.push_back(
_grid[1]->array()[bin_y]);
317 _nref.push_back(thisBoundaryCoordinates);
323 vector<int> thisBoundaries;
324 vector<double> thisBoundaryCoordinates;
325 thisBoundaries.push_back(bin_x);
326 thisBoundaryCoordinates.push_back(
_grid[0]->array()[bin_x]);
327 thisBoundaries.push_back(bin_y);
328 thisBoundaryCoordinates.push_back(
_grid[1]->array()[bin_y]);
329 thisBoundaries.push_back(bin_z);
330 thisBoundaryCoordinates.push_back(
_grid[2]->array()[bin_z]);
333 _nref.push_back(thisBoundaryCoordinates);
339 vector<double> thisBoundaryCoordinates;
340 int nBins = bins.size();
341 thisBoundaryCoordinates.reserve(nBins);
342 for (
int i = 0;
i < nBins;
i++) {
343 thisBoundaryCoordinates.push_back(
_grid[
i]->array()[bins[
i]]);
347 _nref.push_back(thisBoundaryCoordinates);
362 vector<RooAbsReal *> meanrv(nPdf * nObs, null);
363 vector<RooAbsReal *> sigmarv(nPdf * nObs, null);
364 vector<RooAbsReal *> myrms(nObs, null);
365 vector<RooAbsReal *> mypos(nObs, null);
366 vector<RooAbsReal *> slope(nPdf * nObs, null);
367 vector<RooAbsReal *> offsets(nPdf * nObs, null);
368 vector<RooAbsReal *> transVar(nPdf * nObs, null);
369 vector<RooAbsReal *> transPdf(nPdf, null);
379 for (
int i = 0;
i < 3 * nPdf; ++
i) {
380 string fracName =
Form(
"frac_%d",
i);
387 }
else if (
i < 2 * nPdf) {
388 coefList2.add(*
static_cast<RooRealVar *
>(fracl.
at(
i)));
390 coefList3.add(*
static_cast<RooRealVar *
>(fracl.
at(
i)));
392 ownedComps.
add(*
static_cast<RooRealVar *
>(fracl.
at(
i)));
395 std::unique_ptr<RooAbsReal> theSum;
398 RooArgList transPdfList;
402 for (
int i = 0;
i < nPdf; ++
i) {
403 for (
int j = 0; j < nObs; ++j) {
404 RooAbsMoment *mom = nObs == 1 ? (
static_cast<Base_t *
>(
_pdfList.
at(
i)))->sigma(
static_cast<RooRealVar &
>(*obsList.at(j)))
405 : (
static_cast<Base_t *
>(
_pdfList.
at(
i)))->sigma(
static_cast<RooRealVar &
>(*obsList.at(j)), obsList);
410 sigmarv[
sij(
i, j)] = mom;
413 ownedComps.
add(*sigmarv[
sij(
i, j)]);
418 for (
int j = 0; j < nObs; ++j) {
419 RooArgList meanList(
"meanList");
420 RooArgList rmsList(
"rmsList");
421 for (
int i = 0;
i < nPdf; ++
i) {
422 meanList.add(*meanrv[
sij(
i, j)]);
423 rmsList.add(*sigmarv[
sij(
i, j)]);
425 string myrmsName =
Form(
"%s_rms_%d",
GetName(), j);
426 string myposName =
Form(
"%s_pos_%d",
GetName(), j);
427 mypos[j] =
new RooAddition(myposName.c_str(), myposName.c_str(), meanList, coefList2);
428 myrms[j] =
new RooAddition(myrmsName.c_str(), myrmsName.c_str(), rmsList, coefList3);
429 ownedComps.
add(RooArgSet(*myrms[j], *mypos[j]));
437 string pdfName =
Form(
"pdf_%d",
i);
438 RooCustomizer cust(*pdf, pdfName.c_str());
443 string slopeName =
Form(
"%s_slope_%d_%d",
GetName(),
i, j);
444 string offsetName =
Form(
"%s_offset_%d_%d",
GetName(),
i, j);
447 new RooFormulaVar(slopeName.c_str(),
"@0/@1", RooArgList(*sigmarv[
sij(
i, j)], *myrms[j]));
448 offsets[
sij(
i, j)] =
new RooFormulaVar(offsetName.c_str(),
"@0-(@1*@2)",
449 RooArgList(*meanrv[
sij(
i, j)], *mypos[j], *slope[
sij(
i, j)]));
450 ownedComps.
add(RooArgSet(*slope[
sij(
i, j)], *offsets[
sij(
i, j)]));
453 string transVarName =
Form(
"%s_transVar_%d_%d",
GetName(),
i, j);
454 transVar[
sij(
i, j)] =
new RooLinearVar(transVarName.c_str(), transVarName.c_str(), *var, *slope[
sij(
i, j)],
455 *offsets[
sij(
i, j)]);
461 ownedComps.
add(*transVar[
sij(
i, j)]);
462 cust.replaceArg(*var, *transVar[
sij(
i, j)]);
465 transPdf[
i] =
static_cast<Base_t *
>(cust.build());
466 transPdfList.
add(*transPdf[
i]);
467 ownedComps.
add(*transPdf[
i]);
475 theSum = std::make_unique<RooAddPdf>(sumName.c_str(), sumName.c_str(), pdfList, coefList);
477 theSum = std::make_unique<RooRealSumFunc>(sumName.c_str(), sumName.c_str(), pdfList, coefList);
483 theSum->addOwnedComponents(ownedComps);
486 std::string trackerName = std::string(
GetName()) +
"_frac_tracker";
490 std::make_unique<RooChangeTracker>(trackerName.c_str(), trackerName.c_str(),
_parList,
true),
498 std::unique_ptr<RooChangeTracker> &&tracker,
const RooArgList &flist)
526 if (cache->_tracker->hasChanged(
true)) {
527 cache->calculateFractions(*
this,
false);
529 return cache->_sum.get();
537 if (cache->_tracker->hasChanged(
true)) {
538 cache->calculateFractions(*
this,
false);
561 int nPdf = self._pdfList.size();
562 int nPar = self._parList.size();
564 double fracLinear(1.);
565 double fracNonLinear(1.);
570 for (
int idim = 0; idim < nPar; idim++) {
571 double delta = (
static_cast<RooRealVar *
>(self._parList.at(idim)))->getVal() - self._referenceGrid._nref[0][idim];
572 dm2.push_back(delta);
575 vector<vector<int>> powers;
576 for (
int idim = 0; idim < nPar; idim++) {
578 xtmp.reserve(self._referenceGrid._nnuis[idim]);
579 for (
int ix = 0; ix < self._referenceGrid._nnuis[idim]; ix++) {
582 powers.push_back(xtmp);
585 vector<vector<int>>
output;
587 int nCombs =
output.size();
589 vector<double> deltavec(nPdf, 1.0);
592 for (
int i = 0;
i < nCombs;
i++) {
594 for (
int ix = 0; ix < nPar; ix++) {
595 double delta = dm2[ix];
596 tmpDm *= std::pow(delta,
static_cast<double>(
output[
i][ix]));
598 deltavec[nperm] = tmpDm;
602 double sumposfrac = 0.0;
603 for (
int i = 0;
i < nPdf; ++
i) {
606 for (
int j = 0; j < nPdf; ++j) {
607 ffrac += (*self._M)(j,
i) * deltavec[j] * fracNonLinear;
624 cout <<
"NonLinear fraction " << ffrac << endl;
626 frac(nPdf +
i)->Print();
627 frac(2 * nPdf +
i)->Print();
632 for (
int i = 0;
i < nPdf; ++
i) {
643 for (
int i = 0;
i < nPdf; ++
i) {
650 std::vector<double> mtmp;
654 mtmp.push_back(
m->getVal());
657 self.findShape(mtmp);
659 int depth = std::pow(2, nPar);
660 vector<double> deltavec(depth, 1.0);
666 for (
int ix = 0; ix < nPar; ix++) {
670 for (
int iperm = 1; iperm <= nPar; ++iperm) {
672 double dtmp = mtmp[xtmp[0]] - self._squareVec[0][xtmp[0]];
673 for (
int itmp = 1; itmp < iperm; ++itmp) {
674 dtmp *= mtmp[xtmp[itmp]] - self._squareVec[0][xtmp[itmp]];
676 deltavec[nperm + 1] = dtmp;
681 double origFrac1(0.);
682 double origFrac2(0.);
683 for (
int i = 0;
i < depth; ++
i) {
685 for (
int j = 0; j < depth; ++j) {
686 ffrac += (*self._MSqr)(j,
i) * deltavec[j] * fracLinear;
690 origFrac1 =
frac(self._squareIdx[
i])->getVal();
691 const_cast<RooRealVar *
>(
frac(self._squareIdx[
i]))->setVal(origFrac1 + ffrac);
696 frac(nPdf + self._squareIdx[
i])->getVal();
697 const_cast<RooRealVar *
>(
frac(nPdf + self._squareIdx[
i]))->setVal(origFrac2 + ffrac);
698 const_cast<RooRealVar *
>(
frac(2 * nPdf + self._squareIdx[
i]))->setVal(origFrac2 + ffrac);
702 cout <<
"Linear fraction " << ffrac << endl;
703 frac(self._squareIdx[
i])->Print();
704 frac(nPdf + self._squareIdx[
i])->Print();
705 frac(2 * nPdf + self._squareIdx[
i])->Print();
712void RooMomentMorphFuncND::findShape(
const vector<double> &
x)
const
728 int depth = std::pow(2, nPar);
730 vector<vector<double>> boundaries(nPar);
731 for (
int idim = 0; idim < nPar; idim++) {
735 boundaries[idim].push_back(lo);
736 boundaries[idim].push_back(
hi);
739 vector<vector<double>>
output;
743 for (
int isq = 0; isq < depth; isq++) {
744 for (
int iref = 0; iref < nRef; iref++) {
768 for (
int ix = 0; ix < nPar; ix++) {
772 for (
int k = 0; k < depth; ++k) {
778 for (
int iperm = 1; iperm <= nPar; ++iperm) {
780 double dtmp =
_squareVec[k][xtmp[0]] - squareBase[xtmp[0]];
781 for (
int itmp = 1; itmp < iperm; ++itmp) {
782 dtmp *=
_squareVec[k][xtmp[itmp]] - squareBase[xtmp[itmp]];
784 M(k, nperm + 1) = dtmp;
791 (*_MSqr) = M.Invert();
795bool RooMomentMorphFuncND::setBinIntegrator(RooArgSet &allVars)
797 if (allVars.
size() == 1) {
800 int nbins = (
static_cast<RooRealVar *
>(allVars.
first()))->numBins();
804 cout <<
"Currently BinIntegrator only knows how to deal with 1-d " << endl;
true
Register systematic variations for multiple existing columns using auto-generated tags.
ROOT::RRangeCast< T, false, Range_t > static_range_cast(Range_t &&coll)
CacheElem * getCache(const RooArgSet *nset) const
RooAbsReal * sumFunc(const RooArgSet *nset)
std::vector< int > _squareIdx
std::unique_ptr< TMatrixD > _MSqr
RooObjCacheManager _cacheMgr
! Transient cache manager
std::unique_ptr< TMatrixD > _M
int sij(const int &i, const int &j) const
RooArgSet * _curNormSet
! Transient cache manager
std::vector< std::vector< double > > _squareVec
TMatrixT< Double_t > TMatrixD
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
TVectorT< Double_t > TVectorD
void setLocalNoDirtyInhibit(bool flag) const
RooAbsCache * getCache(Int_t index) const
Return registered cache object by index.
friend class RooAbsCollection
Abstract base class for RooRealVar binning definitions.
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 setRealValue(const char *name, double newVal=0.0, bool verbose=false)
Set value of a RooAbsRealLValue stored in set with given name to newVal No error messages are printed...
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.
RooAbsReal()
coverity[UNINIT_CTOR] Default constructor
RooNumIntConfig * specialIntegratorConfig() const
Returns the specialized integrator configuration for this RooAbsReal.
virtual double evaluate() const =0
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
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...
double * array() const override
Return array of boundary values.
Int_t numBoundaries() const override
Return the number boundaries.
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=nullptr)
Setter function without integration set.
bool setLabel(const char *label, bool printError=true) override
Set value by specifying the name of the desired state.
Represents a constant real-valued object.
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
std::vector< RooAbsBinning * > _grid
std::map< std::vector< int >, int > _pdfMap
std::vector< std::vector< double > > _nref
void addPdf(const RooAbsReal &func, int bin_x)
~RooMomentMorphFuncND() override
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.
Element * GetMatrixArray()
void cartesianProduct(std::vector< std::vector< T > > &out, std::vector< std::vector< T > > &in)
bool nextCombination(const Iterator first, Iterator k, const Iterator last)