43using std::string, std::vector;
57 _parList(
"parList",
"List of morph parameters", this),
58 _obsList(
"obsList",
"List of observables", this),
60 _pdfList(
"pdfList",
"List of pdfs", this),
83 _parList(
"parList",
"List of morph parameters", this),
84 _obsList(
"obsList",
"List of observables", this),
85 _pdfList(
"pdfList",
"List of pdfs", this),
93 for (
int i = 0; i < mrefpoints.
GetNrows(); ++i) {
95 if (mrefpoints[i] == grid.
array()[j]) {
123 _parList(
"parList",
"List of morph parameters", this),
124 _obsList(
"obsList",
"List of observables", this),
125 _pdfList(
"pdfList",
"List of pdfs", this),
132 for (
auto *mref : mrefList) {
134 coutE(InputArguments) <<
"RooMomentMorphFuncND::ctor(" <<
GetName() <<
") ERROR: mref " << mref->GetName()
135 <<
" is not of type RooAbsReal" << std::endl;
136 throw string(
"RooMomentMorphFuncND::ctor() ERROR mref is not of type RooAbsReal");
139 coutW(InputArguments) <<
"RooMomentMorphFuncND::ctor(" <<
GetName() <<
") WARNING mref point " << i
140 <<
" is not a constant, taking a snapshot of its value" << std::endl;
148 for (i = 0; i < mrefpoints.
GetNrows(); ++i) {
150 if (mrefpoints[i] == grid.
array()[j]) {
198void RooMomentMorphFuncND::initialize()
209 int depth = std::pow(2, nPar);
212 coutE(InputArguments) <<
"RooMomentMorphFuncND::initialize(" <<
GetName() <<
") ERROR: nPar != nDim"
213 <<
": " << nPar <<
" !=" << nDim << std::endl;
218 coutE(InputArguments) <<
"RooMomentMorphFuncND::initialize(" <<
GetName() <<
") ERROR: nPdf != nRef"
219 <<
": " << nPdf <<
" !=" << nRef << std::endl;
224 _M = std::make_unique<TMatrixD>(nPdf, nPdf);
225 _MSqr = std::make_unique<TMatrixD>(depth, depth);
229 vector<vector<double>> dm(nPdf);
230 for (
int k = 0; k < nPdf; ++k) {
232 for (
int idim = 0; idim < nPar; idim++) {
234 dm2.push_back(delta);
239 vector<vector<int>> powers;
240 for (
int idim = 0; idim < nPar; idim++) {
246 powers.push_back(xtmp);
249 vector<vector<int>> output;
251 int nCombs = output.size();
253 for (
int k = 0; k < nPdf; ++k) {
255 for (
int i = 0; i < nCombs; i++) {
257 for (
int ix = 0; ix < nPar; ix++) {
258 double delta = dm[k][ix];
259 tmpDm *= std::pow(delta,
static_cast<double>(output[i][ix]));
279 for (
unsigned int i = 0; i < other.
_grid.size(); i++) {
295 vector<int> thisBoundaries;
296 vector<double> thisBoundaryCoordinates;
297 thisBoundaries.push_back(bin_x);
298 thisBoundaryCoordinates.push_back(
_grid[0]->array()[bin_x]);
301 _nref.push_back(thisBoundaryCoordinates);
307 vector<int> thisBoundaries;
308 vector<double> thisBoundaryCoordinates;
309 thisBoundaries.push_back(bin_x);
310 thisBoundaryCoordinates.push_back(
_grid[0]->array()[bin_x]);
311 thisBoundaries.push_back(bin_y);
312 thisBoundaryCoordinates.push_back(
_grid[1]->array()[bin_y]);
315 _nref.push_back(thisBoundaryCoordinates);
321 vector<int> thisBoundaries;
322 vector<double> thisBoundaryCoordinates;
323 thisBoundaries.push_back(bin_x);
324 thisBoundaryCoordinates.push_back(
_grid[0]->array()[bin_x]);
325 thisBoundaries.push_back(bin_y);
326 thisBoundaryCoordinates.push_back(
_grid[1]->array()[bin_y]);
327 thisBoundaries.push_back(bin_z);
328 thisBoundaryCoordinates.push_back(
_grid[2]->array()[bin_z]);
331 _nref.push_back(thisBoundaryCoordinates);
337 vector<double> thisBoundaryCoordinates;
338 int nBins = bins.size();
339 thisBoundaryCoordinates.reserve(nBins);
340 for (
int i = 0; i < nBins; i++) {
341 thisBoundaryCoordinates.push_back(
_grid[i]->array()[bins[i]]);
345 _nref.push_back(thisBoundaryCoordinates);
349std::unique_ptr<RooAbsArg>
370 cache->
_sum->branchNodeServerList(&branches);
371 for (
auto *
b : branches) {
372 std::vector<std::string> toRemove;
373 for (
auto const &attr :
b->attributes()) {
374 if (attr.rfind(
"ORIGNAME:", 0) == 0)
375 toRemove.push_back(attr);
377 for (
auto const &attr : toRemove)
378 b->setAttribute(attr.c_str(),
false);
387 RooArgList newFractions;
389 for (
int i = 0; i < nFrac; ++i) {
390 auto frac =
static_cast<RooRealVar *
>(cache->
_frac.
at(i));
391 std::string newName = std::string{frac->GetName()} +
"_compiled";
393 std::make_unique<RooFit::Detail::RooMomentMorphFraction>(newName.c_str(), frac->GetTitle(), *
this, i));
396 RooArgSet clonedBranches;
397 RooCustomizer cust(*cache->
_sum,
"compiled");
398 cust.setCloneBranchSet(clonedBranches);
399 for (
int i = 0; i < nFrac; ++i) {
400 cust.replaceArg(*cache->
_frac.
at(i), newFractions[i]);
407 std::unique_ptr<RooAbsReal> newSum{
static_cast<RooAbsReal *
>(cust.build())};
408 newSum->addOwnedComponents(std::move(newFractions));
415 newSum->branchNodeServerList(&branches);
416 for (
auto *
b : branches) {
417 if (
dynamic_cast<RooFit::Detail::RooMomentMorphFraction *
>(
b))
449 auto *cache =
_parent->getCache(
nullptr);
450 if (cache->
_tracker->hasChanged(
true)) {
471 vector<RooAbsReal *> meanrv(nPdf * nObs, null);
472 vector<RooAbsReal *> sigmarv(nPdf * nObs, null);
473 vector<RooAbsReal *> myrms(nObs, null);
474 vector<RooAbsReal *> mypos(nObs, null);
475 vector<RooAbsReal *> slope(nPdf * nObs, null);
476 vector<RooAbsReal *> offsets(nPdf * nObs, null);
477 vector<RooAbsReal *> transVar(nPdf * nObs, null);
478 vector<RooAbsReal *> transPdf(nPdf, null);
480 RooArgSet ownedComps;
484 RooArgList coefList(
"coefList");
485 RooArgList coefList2(
"coefList2");
486 RooArgList coefList3(
"coefList3");
488 for (
int i = 0; i < 3 * nPdf; ++i) {
489 string fracName =
Form(
"frac_%d", i);
491 RooRealVar *frac =
new RooRealVar(fracName.c_str(), fracName.c_str(), initval);
495 coefList.add(*
static_cast<RooRealVar *
>(fracl.
at(i)));
496 }
else if (i < 2 * nPdf) {
497 coefList2.add(*
static_cast<RooRealVar *
>(fracl.
at(i)));
499 coefList3.add(*
static_cast<RooRealVar *
>(fracl.
at(i)));
501 ownedComps.
add(*
static_cast<RooRealVar *
>(fracl.
at(i)));
504 std::unique_ptr<RooAbsReal> theSum;
507 RooArgList transPdfList;
511 for (
int i = 0; i < nPdf; ++i) {
512 for (
int j = 0; j < nObs; ++j) {
513 RooAbsMoment *mom = nObs == 1 ? (
static_cast<Base_t *
>(
_pdfList.
at(i)))->sigma(
static_cast<RooRealVar &
>(*obsList.at(j)))
514 : (
static_cast<Base_t *
>(
_pdfList.
at(i)))->sigma(
static_cast<RooRealVar &
>(*obsList.at(j)), obsList);
519 sigmarv[
sij(i, j)] = mom;
520 meanrv[
sij(i, j)] = mom->
mean();
522 ownedComps.
add(*sigmarv[
sij(i, j)]);
527 for (
int j = 0; j < nObs; ++j) {
528 RooArgList meanList(
"meanList");
529 RooArgList rmsList(
"rmsList");
530 for (
int i = 0; i < nPdf; ++i) {
531 meanList.add(*meanrv[
sij(i, j)]);
532 rmsList.add(*sigmarv[
sij(i, j)]);
534 string myrmsName =
Form(
"%s_rms_%d",
GetName(), j);
535 string myposName =
Form(
"%s_pos_%d",
GetName(), j);
536 mypos[j] =
new RooAddition(myposName.c_str(), myposName.c_str(), meanList, coefList2);
537 myrms[j] =
new RooAddition(myrmsName.c_str(), myrmsName.c_str(), rmsList, coefList3);
538 ownedComps.
add(RooArgSet(*myrms[j], *mypos[j]));
546 string pdfName =
Form(
"pdf_%d", i);
547 RooCustomizer cust(*pdf, pdfName.c_str());
552 string slopeName =
Form(
"%s_slope_%d_%d",
GetName(), i, j);
553 string offsetName =
Form(
"%s_offset_%d_%d",
GetName(), i, j);
556 new RooFormulaVar(slopeName.c_str(),
"@0/@1", RooArgList(*sigmarv[
sij(i, j)], *myrms[j]));
557 offsets[
sij(i, j)] =
new RooFormulaVar(offsetName.c_str(),
"@0-(@1*@2)",
558 RooArgList(*meanrv[
sij(i, j)], *mypos[j], *slope[
sij(i, j)]));
559 ownedComps.
add(RooArgSet(*slope[
sij(i, j)], *offsets[
sij(i, j)]));
562 string transVarName =
Form(
"%s_transVar_%d_%d",
GetName(), i, j);
563 transVar[
sij(i, j)] =
new RooLinearVar(transVarName.c_str(), transVarName.c_str(), *var, *slope[
sij(i, j)],
564 *offsets[
sij(i, j)]);
570 ownedComps.
add(*transVar[
sij(i, j)]);
571 cust.replaceArg(*var, *transVar[
sij(i, j)]);
574 transPdf[i] =
static_cast<Base_t *
>(cust.build());
575 transPdfList.
add(*transPdf[i]);
576 ownedComps.
add(*transPdf[i]);
584 theSum = std::make_unique<RooAddPdf>(sumName.c_str(), sumName.c_str(), pdfList, coefList);
586 theSum = std::make_unique<RooRealSumFunc>(sumName.c_str(), sumName.c_str(), pdfList, coefList);
592 theSum->addOwnedComponents(ownedComps);
595 std::string trackerName = std::string(
GetName()) +
"_frac_tracker";
599 std::make_unique<RooChangeTracker>(trackerName.c_str(), trackerName.c_str(),
_parList,
true),
607 std::unique_ptr<RooChangeTracker> &&tracker,
const RooArgList &flist)
635 if (cache->_tracker->hasChanged(
true)) {
636 cache->calculateFractions(*
this,
false);
638 return cache->_sum.get();
646 if (cache->_tracker->hasChanged(
true)) {
647 cache->calculateFractions(*
this,
false);
670 int nPdf = self._pdfList.size();
671 int nPar = self._parList.size();
673 double fracLinear(1.);
674 double fracNonLinear(1.);
679 for (
int idim = 0; idim < nPar; idim++) {
680 double delta = (
static_cast<RooRealVar *
>(self._parList.at(idim)))->getVal() - self._referenceGrid._nref[0][idim];
681 dm2.push_back(delta);
684 vector<vector<int>> powers;
685 for (
int idim = 0; idim < nPar; idim++) {
687 xtmp.reserve(self._referenceGrid._nnuis[idim]);
688 for (
int ix = 0; ix < self._referenceGrid._nnuis[idim]; ix++) {
691 powers.push_back(xtmp);
694 vector<vector<int>> output;
696 int nCombs = output.size();
698 vector<double> deltavec(nPdf, 1.0);
701 for (
int i = 0; i < nCombs; i++) {
703 for (
int ix = 0; ix < nPar; ix++) {
704 double delta = dm2[ix];
705 tmpDm *= std::pow(delta,
static_cast<double>(output[i][ix]));
707 deltavec[nperm] = tmpDm;
711 double sumposfrac = 0.0;
712 for (
int i = 0; i < nPdf; ++i) {
715 for (
int j = 0; j < nPdf; ++j) {
716 ffrac += (*self._M)(j, i) * deltavec[j] * fracNonLinear;
733 std::cout <<
"NonLinear fraction " << ffrac << std::endl;
735 frac(nPdf + i)->Print();
736 frac(2 * nPdf + i)->Print();
741 for (
int i = 0; i < nPdf; ++i) {
752 for (
int i = 0; i < nPdf; ++i) {
759 std::vector<double> mtmp;
763 mtmp.push_back(
m->getVal());
766 self.findShape(mtmp);
768 int depth = std::pow(2, nPar);
769 vector<double> deltavec(depth, 1.0);
775 for (
int ix = 0; ix < nPar; ix++) {
779 for (
int iperm = 1; iperm <= nPar; ++iperm) {
781 double dtmp = mtmp[xtmp[0]] - self._squareVec[0][xtmp[0]];
782 for (
int itmp = 1; itmp < iperm; ++itmp) {
783 dtmp *= mtmp[xtmp[itmp]] - self._squareVec[0][xtmp[itmp]];
785 deltavec[nperm + 1] = dtmp;
790 double origFrac1(0.);
791 double origFrac2(0.);
792 for (
int i = 0; i < depth; ++i) {
794 for (
int j = 0; j < depth; ++j) {
795 ffrac += (*self._MSqr)(j, i) * deltavec[j] * fracLinear;
799 origFrac1 =
frac(self._squareIdx[i])->getVal();
800 const_cast<RooRealVar *
>(
frac(self._squareIdx[i]))->setVal(origFrac1 + ffrac);
805 frac(nPdf + self._squareIdx[i])->getVal();
806 const_cast<RooRealVar *
>(
frac(nPdf + self._squareIdx[i]))->setVal(origFrac2 + ffrac);
807 const_cast<RooRealVar *
>(
frac(2 * nPdf + self._squareIdx[i]))->setVal(origFrac2 + ffrac);
811 std::cout <<
"Linear fraction " << ffrac << std::endl;
812 frac(self._squareIdx[i])->Print();
813 frac(nPdf + self._squareIdx[i])->Print();
814 frac(2 * nPdf + self._squareIdx[i])->Print();
821void RooMomentMorphFuncND::findShape(
const vector<double> &
x)
const
837 int depth = std::pow(2, nPar);
839 vector<vector<double>> boundaries(nPar);
840 for (
int idim = 0; idim < nPar; idim++) {
844 boundaries[idim].push_back(lo);
845 boundaries[idim].push_back(
hi);
848 vector<vector<double>> output;
852 for (
int isq = 0; isq < depth; isq++) {
853 for (
int iref = 0; iref < nRef; iref++) {
877 for (
int ix = 0; ix < nPar; ix++) {
881 for (
int k = 0; k < depth; ++k) {
887 for (
int iperm = 1; iperm <= nPar; ++iperm) {
889 double dtmp =
_squareVec[k][xtmp[0]] - squareBase[xtmp[0]];
890 for (
int itmp = 1; itmp < iperm; ++itmp) {
891 dtmp *=
_squareVec[k][xtmp[itmp]] - squareBase[xtmp[itmp]];
893 M(k, nperm + 1) = dtmp;
900 (*_MSqr) = M.Invert();
904bool RooMomentMorphFuncND::setBinIntegrator(RooArgSet &allVars)
906 if (allVars.
size() == 1) {
908 temp->specialIntegratorConfig(
true)->method1D().setLabel(
"RooBinIntegrator");
909 int nbins = (
static_cast<RooRealVar *
>(allVars.
first()))->numBins();
910 temp->specialIntegratorConfig(
true)->getConfigSection(
"RooBinIntegrator").setRealValue(
"numBins", nbins);
913 std::cout <<
"Currently BinIntegrator only knows how to deal with 1-d " << std::endl;
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
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.
TVectorT< Double_t > TVectorD
void setLocalNoDirtyInhibit(bool flag) const
virtual std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) 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
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
const RooArgSet * nset() const
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
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.
Represents a constant real-valued object.
void markAsCompiled(RooAbsArg &arg) const
void compileServers(RooAbsArg &arg, RooArgSet const &normSet)
void markSubtreeAsCompiled(RooAbsArg &arg) const
Mark arg and every branch node reachable through its server tree as already compiled.
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.
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
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)