35 ClassImp(RooMomentMorphFuncND)
38 ClassImp(RooMomentMorphFuncND::Grid2)
41 RooMomentMorphFuncND::RooMomentMorphFuncND()
42 : _curNormSet(0), _M(0), _MSqr(0), _setting(RooMomentMorphFuncND::Linear), _useHorizMorph(true)
44 _parItr = _parList.createIterator();
45 _obsItr = _obsList.createIterator();
51 RooMomentMorphFuncND::RooMomentMorphFuncND(
const char *name,
const char *title,
const RooArgList &parList,
52 const RooArgList &obsList,
const Grid2 &referenceGrid,
53 const Setting &setting)
54 : RooAbsReal(name, title), _cacheMgr(this, 10, kTRUE, kTRUE), _parList(
"parList",
"List of morph parameters", this),
55 _obsList(
"obsList",
"List of observables", this), _referenceGrid(referenceGrid),
56 _pdfList(
"pdfList",
"List of pdfs", this), _setting(setting), _useHorizMorph(true)
59 initializeParameters(parList);
62 initializeObservables(obsList);
64 _pdfList.add(_referenceGrid._pdfList);
73 RooMomentMorphFuncND::RooMomentMorphFuncND(
const char *name,
const char *title, RooAbsReal &_m,
74 const RooArgList &varList,
const RooArgList &pdfList,
75 const TVectorD &mrefpoints, Setting setting)
76 : RooAbsReal(name, title), _cacheMgr(this, 10, kTRUE, kTRUE), _parList(
"parList",
"List of morph parameters", this),
77 _obsList(
"obsList",
"List of observables", this), _pdfList(
"pdfList",
"List of pdfs", this), _setting(setting),
81 RooBinning grid(mrefpoints.GetNrows() - 1, mrefpoints.GetMatrixArray());
82 _referenceGrid.addBinning(grid);
84 for (
int i = 0; i < mrefpoints.GetNrows(); ++i) {
85 for (
int j = 0; j < grid.numBoundaries(); ++j) {
86 if (mrefpoints[i] == grid.array()[j]) {
87 _referenceGrid.addPdf(*(RooAbsReal *)pdfList.at(i), j);
93 _pdfList.add(_referenceGrid._pdfList);
98 initializeParameters(parList);
101 initializeObservables(varList);
110 RooMomentMorphFuncND::RooMomentMorphFuncND(
const char *name,
const char *title, RooAbsReal &_m,
111 const RooArgList &varList,
const RooArgList &pdfList,
112 const RooArgList &mrefList, Setting setting)
113 : RooAbsReal(name, title), _cacheMgr(this, 10, kTRUE, kTRUE), _parList(
"parList",
"List of morph parameters", this),
114 _obsList(
"obsList",
"List of observables", this), _pdfList(
"pdfList",
"List of pdfs", this), _setting(setting),
118 TVectorD mrefpoints(mrefList.getSize());
119 TIterator *mrefItr = mrefList.createIterator();
121 for (
int i = 0; (mref =
dynamic_cast<RooAbsReal *
>(mrefItr->Next())); ++i) {
123 coutE(InputArguments) <<
"RooMomentMorphFuncND::ctor(" << GetName() <<
") ERROR: mref " << mref->GetName()
124 <<
" is not of type RooAbsReal" << endl;
125 throw string(
"RooMomentMorphFuncND::ctor() ERROR mref is not of type RooAbsReal");
127 if (!dynamic_cast<RooConstVar *>(mref)) {
128 coutW(InputArguments) <<
"RooMomentMorphFuncND::ctor(" << GetName() <<
") WARNING mref point " << i
129 <<
" is not a constant, taking a snapshot of its value" << endl;
131 mrefpoints[i] = mref->getVal();
135 RooBinning grid(mrefpoints.GetNrows() - 1, mrefpoints.GetMatrixArray());
136 _referenceGrid.addBinning(grid);
138 for (
int i = 0; i < mrefpoints.GetNrows(); ++i) {
139 for (
int j = 0; j < grid.numBoundaries(); ++j) {
140 if (mrefpoints[i] == grid.array()[j]) {
141 _referenceGrid.addPdf(*(RooAbsReal *)pdfList.at(i), j);
147 _pdfList.add(_referenceGrid._pdfList);
152 initializeParameters(parList);
155 initializeObservables(varList);
164 RooMomentMorphFuncND::RooMomentMorphFuncND(
const RooMomentMorphFuncND &other,
const char *name)
165 : RooAbsReal(other, name), _cacheMgr(other._cacheMgr, this), _curNormSet(0),
166 _parList(
"parList", this, other._parList), _obsList(
"obsList", this, other._obsList),
167 _referenceGrid(other._referenceGrid), _pdfList(
"pdfList", this, other._pdfList), _M(0), _MSqr(0),
168 _setting(other._setting), _useHorizMorph(other._useHorizMorph)
170 _parItr = _parList.createIterator();
171 _obsItr = _obsList.createIterator();
180 RooMomentMorphFuncND::~RooMomentMorphFuncND()
195 void RooMomentMorphFuncND::initializeParameters(
const RooArgList &parList)
197 TIterator *parItr = parList.createIterator();
199 for (
int i = 0; (par = (RooAbsArg *)parItr->Next()); ++i) {
200 if (!dynamic_cast<RooAbsReal *>(par)) {
201 coutE(InputArguments) <<
"RooMomentMorphFuncND::ctor(" << GetName() <<
") ERROR: parameter " << par->GetName()
202 <<
" is not of type RooAbsReal" << endl;
203 throw string(
"RooMomentMorphFuncND::initializeParameters() ERROR parameter is not of type RooAbsReal");
209 _parItr = _parList.createIterator();
213 void RooMomentMorphFuncND::initializeObservables(
const RooArgList &obsList)
215 TIterator *obsItr = obsList.createIterator();
217 for (
int i = 0; (var = (RooAbsArg *)obsItr->Next()); ++i) {
218 if (!dynamic_cast<RooAbsReal *>(var)) {
219 coutE(InputArguments) <<
"RooMomentMorphFuncND::ctor(" << GetName() <<
") ERROR: variable " << var->GetName()
220 <<
" is not of type RooAbsReal" << endl;
221 throw string(
"RooMomentMorphFuncND::initializeObservables() ERROR variable is not of type RooAbsReal");
227 _obsItr = _obsList.createIterator();
232 template <
typename T>
233 void RooMomentMorphFuncND::cartesian_product(vector<vector<T>> &out, vector<vector<T>> &in)
235 vector<Digits<T>> vd;
237 for (
typename vector<vector<T>>::const_iterator it = in.begin(); it != in.end(); ++it) {
238 Digits<T> d = {(*it).begin(), (*it).end(), (*it).begin()};
244 for (
typename vector<Digits<T>>::const_iterator it = vd.begin(); it != vd.end(); ++it) {
245 result.push_back(*(it->me));
247 out.push_back(result);
249 for (
typename vector<Digits<T>>::iterator it = vd.begin();;) {
251 if (it->me == it->end) {
252 if (it + 1 == vd.end()) {
266 void RooMomentMorphFuncND::initialize()
280 for (vector<RooAbsBinning *>::iterator itr = _referenceGrid._grid.begin(); itr != _referenceGrid._grid.end();
282 _referenceGrid._nnuis.push_back((*itr)->numBins() + 1);
285 int nPar = _parList.getSize();
286 int nDim = _referenceGrid._grid.size();
287 int nPdf = _referenceGrid._pdfList.getSize();
288 int nRef = _referenceGrid._nref.size();
289 int depth = TMath::Power(2, nPar);
292 coutE(InputArguments) <<
"RooMomentMorphFuncND::initialize(" << GetName() <<
") ERROR: nPar != nDim"
293 <<
": " << nPar <<
" !=" << nDim << endl;
298 coutE(InputArguments) <<
"RooMomentMorphFuncND::initialize(" << GetName() <<
") ERROR: nPdf != nRef"
299 <<
": " << nPdf <<
" !=" << nRef << endl;
304 _M =
new TMatrixD(nPdf, nPdf);
305 _MSqr =
new TMatrixD(depth, depth);
306 if (_setting == NonLinear || _setting == NonLinearPosFractions || _setting == NonLinearLinFractions) {
307 TMatrixD M(nPdf, nPdf);
309 vector<vector<double>> dm(nPdf);
310 for (
int k = 0; k < nPdf; ++k) {
312 for (
int idim = 0; idim < nPar; idim++) {
313 Double_t delta = _referenceGrid._nref[k][idim] - _referenceGrid._nref[0][idim];
314 dm2.push_back(delta);
319 vector<vector<int>> powers;
320 for (
int idim = 0; idim < nPar; idim++) {
322 for (
int ix = 0; ix < _referenceGrid._nnuis[idim]; ix++) {
325 powers.push_back(xtmp);
328 vector<vector<int>> output;
329 cartesian_product(output, powers);
330 int nCombs = output.size();
332 for (
int k = 0; k < nPdf; ++k) {
334 for (
int i = 0; i < nCombs; i++) {
336 for (
int ix = 0; ix < nPar; ix++) {
337 Double_t delta = dm[k][ix];
338 tmpDm *= TMath::Power(delta, static_cast<double>(output[i][ix]));
350 _squareVec.resize(TMath::Power(2, nPar));
351 _squareIdx.resize(TMath::Power(2, nPar));
355 RooMomentMorphFuncND::Grid2::Grid2(
const RooMomentMorphFuncND::Grid2 &other)
356 : _grid(other._grid), _pdfList(other._pdfList), _pdfMap(other._pdfMap), _nref(other._nref)
361 RooMomentMorphFuncND::Grid2::~Grid2()
366 void RooMomentMorphFuncND::Grid2::addPdf(
const RooAbsReal &pdf,
int bin_x)
368 vector<int> thisBoundaries;
369 vector<double> thisBoundaryCoordinates;
370 thisBoundaries.push_back(bin_x);
371 thisBoundaryCoordinates.push_back(_grid[0]->array()[bin_x]);
373 _pdfMap[thisBoundaries] = _pdfList.getSize() - 1;
374 _nref.push_back(thisBoundaryCoordinates);
378 void RooMomentMorphFuncND::Grid2::addPdf(
const RooAbsReal &pdf,
int bin_x,
int bin_y)
380 vector<int> thisBoundaries;
381 vector<double> thisBoundaryCoordinates;
382 thisBoundaries.push_back(bin_x);
383 thisBoundaryCoordinates.push_back(_grid[0]->array()[bin_x]);
384 thisBoundaries.push_back(bin_y);
385 thisBoundaryCoordinates.push_back(_grid[1]->array()[bin_y]);
387 _pdfMap[thisBoundaries] = _pdfList.getSize() - 1;
388 _nref.push_back(thisBoundaryCoordinates);
392 void RooMomentMorphFuncND::Grid2::addPdf(
const RooAbsReal &pdf,
int bin_x,
int bin_y,
int bin_z)
394 vector<int> thisBoundaries;
395 vector<double> thisBoundaryCoordinates;
396 thisBoundaries.push_back(bin_x);
397 thisBoundaryCoordinates.push_back(_grid[0]->array()[bin_x]);
398 thisBoundaries.push_back(bin_y);
399 thisBoundaryCoordinates.push_back(_grid[1]->array()[bin_y]);
400 thisBoundaries.push_back(bin_z);
401 thisBoundaryCoordinates.push_back(_grid[2]->array()[bin_z]);
403 _pdfMap[thisBoundaries] = _pdfList.getSize() - 1;
404 _nref.push_back(thisBoundaryCoordinates);
408 void RooMomentMorphFuncND::Grid2::addPdf(
const RooAbsReal &pdf, vector<int> bins)
410 vector<double> thisBoundaryCoordinates;
411 int nBins = bins.size();
412 for (
int i = 0; i < nBins; i++) {
413 thisBoundaryCoordinates.push_back(_grid[i]->array()[bins[i]]);
416 _pdfMap[bins] = _pdfList.getSize() - 1;
417 _nref.push_back(thisBoundaryCoordinates);
421 RooMomentMorphFuncND::CacheElem *RooMomentMorphFuncND::getCache(
const RooArgSet * )
const
423 CacheElem *cache =
static_cast<CacheElem *
>(_cacheMgr.getObj(0, (RooArgSet *)0));
428 int nObs = _obsList.getSize();
429 int nPdf = _referenceGrid._pdfList.getSize();
431 TIterator *pdfItr = _pdfList.createIterator();
433 RooAbsReal *null = 0;
434 vector<RooAbsReal *> meanrv(nPdf * nObs, null);
435 vector<RooAbsReal *> sigmarv(nPdf * nObs, null);
436 vector<RooAbsReal *> myrms(nObs, null);
437 vector<RooAbsReal *> mypos(nObs, null);
438 vector<RooAbsReal *> slope(nPdf * nObs, null);
439 vector<RooAbsReal *> offsets(nPdf * nObs, null);
440 vector<RooAbsReal *> transVar(nPdf * nObs, null);
441 vector<RooAbsReal *> transPdf(nPdf, null);
443 RooArgSet ownedComps;
447 RooArgList coefList(
"coefList");
448 RooArgList coefList2(
"coefList2");
449 RooArgList coefList3(
"coefList3");
451 for (
int i = 0; i < 3 * nPdf; ++i) {
452 string fracName = Form(
"frac_%d", i);
453 double initval = 0.0;
454 RooRealVar *frac =
new RooRealVar(fracName.c_str(), fracName.c_str(), initval);
458 coefList.add(*(RooRealVar *)(fracl.at(i)));
459 else if (i < 2 * nPdf)
460 coefList2.add(*(RooRealVar *)(fracl.at(i)));
462 coefList3.add(*(RooRealVar *)(fracl.at(i)));
463 ownedComps.add(*(RooRealVar *)(fracl.at(i)));
466 RooRealSumFunc *theSumFunc = 0;
467 string sumfuncName = Form(
"%s_sumfunc", GetName());
469 if (_useHorizMorph) {
471 RooArgList obsList(_obsList);
472 for (
int i = 0; i < nPdf; ++i) {
473 for (
int j = 0; j < nObs; ++j) {
474 RooAbsMoment *mom = nObs == 1
475 ? ((RooAbsReal *)_pdfList.at(i))->sigma((RooRealVar &)*obsList.at(j))
476 : ((RooAbsReal *)_pdfList.at(i))->sigma((RooRealVar &)*obsList.at(j), obsList);
478 mom->setLocalNoDirtyInhibit(kTRUE);
479 mom->mean()->setLocalNoDirtyInhibit(kTRUE);
481 sigmarv[sij(i, j)] = mom;
482 meanrv[sij(i, j)] = mom->mean();
484 ownedComps.add(*sigmarv[sij(i, j)]);
489 for (
int j = 0; j < nObs; ++j) {
490 RooArgList meanList(
"meanList");
491 RooArgList rmsList(
"rmsList");
492 for (
int i = 0; i < nPdf; ++i) {
493 meanList.add(*meanrv[sij(i, j)]);
494 rmsList.add(*sigmarv[sij(i, j)]);
496 string myrmsName = Form(
"%s_rms_%d", GetName(), j);
497 string myposName = Form(
"%s_pos_%d", GetName(), j);
498 mypos[j] =
new RooAddition(myposName.c_str(), myposName.c_str(), meanList, coefList2);
499 myrms[j] =
new RooAddition(myrmsName.c_str(), myrmsName.c_str(), rmsList, coefList3);
500 ownedComps.add(RooArgSet(*myrms[j], *mypos[j]));
506 RooArgList transPdfList;
508 for (
int i = 0; i < nPdf; ++i) {
512 pdf = (RooAbsReal *)pdfItr->Next();
513 string pdfName = Form(
"pdf_%d", i);
514 RooCustomizer cust(*pdf, pdfName.c_str());
516 for (
int j = 0; j < nObs; ++j) {
518 string slopeName = Form(
"%s_slope_%d_%d", GetName(), i, j);
519 string offsetName = Form(
"%s_offset_%d_%d", GetName(), i, j);
522 new RooFormulaVar(slopeName.c_str(),
"@0/@1", RooArgList(*sigmarv[sij(i, j)], *myrms[j]));
523 offsets[sij(i, j)] =
new RooFormulaVar(offsetName.c_str(),
"@0-(@1*@2)",
524 RooArgList(*meanrv[sij(i, j)], *mypos[j], *slope[sij(i, j)]));
525 ownedComps.add(RooArgSet(*slope[sij(i, j)], *offsets[sij(i, j)]));
528 var = (RooRealVar *)(_obsItr->Next());
529 string transVarName = Form(
"%s_transVar_%d_%d", GetName(), i, j);
530 transVar[sij(i, j)] =
new RooLinearVar(transVarName.c_str(), transVarName.c_str(), *var, *slope[sij(i, j)],
531 *offsets[sij(i, j)]);
535 transVar[sij(i, j)]->addServerList((RooAbsCollection &)_parList);
537 ownedComps.add(*transVar[sij(i, j)]);
538 cust.replaceArg(*var, *transVar[sij(i, j)]);
540 transPdf[i] = (RooAbsReal *)cust.build();
541 transPdfList.add(*transPdf[i]);
542 ownedComps.add(*transPdf[i]);
546 theSumFunc =
new RooRealSumFunc(sumfuncName.c_str(), sumfuncName.c_str(), transPdfList, coefList);
548 theSumFunc =
new RooRealSumFunc(sumfuncName.c_str(), sumfuncName.c_str(), _pdfList, coefList);
553 theSumFunc->addServerList((RooAbsCollection &)_parList);
554 theSumFunc->addOwnedComponents(ownedComps);
557 string trackerName = Form(
"%s_frac_tracker", GetName());
558 RooChangeTracker *tracker =
new RooChangeTracker(trackerName.c_str(), trackerName.c_str(), _parList, kTRUE);
561 cache =
new CacheElem(*theSumFunc, *tracker, fracl);
562 _cacheMgr.setObj(0, 0, cache, 0);
568 RooArgList RooMomentMorphFuncND::CacheElem::containedArgs(Action)
570 return RooArgList(*_sumFunc, *_tracker);
574 RooMomentMorphFuncND::CacheElem::~CacheElem()
581 Double_t RooMomentMorphFuncND::getVal(
const RooArgSet *set)
const
584 _curNormSet = set ? (RooArgSet *)set : (RooArgSet *)&_obsList;
585 return RooAbsReal::getVal(set);
589 RooAbsReal *RooMomentMorphFuncND::sumFunc(
const RooArgSet *nset)
591 CacheElem *cache = getCache(nset ? nset : _curNormSet);
593 if (cache->_tracker->hasChanged(kTRUE)) {
594 cache->calculateFractions(*
this, kFALSE);
596 return cache->_sumFunc;
600 Double_t RooMomentMorphFuncND::evaluate()
const
602 CacheElem *cache = getCache(_curNormSet);
604 if (cache->_tracker->hasChanged(kTRUE)) {
605 cache->calculateFractions(*
this, kFALSE);
608 Double_t ret = cache->_sumFunc->getVal(_obsList.nset());
614 RooRealVar *RooMomentMorphFuncND::CacheElem::frac(
int i)
616 return (RooRealVar *)(_frac.at(i));
620 const RooRealVar *RooMomentMorphFuncND::CacheElem::frac(
int i)
const
622 return (RooRealVar *)(_frac.at(i));
627 template <
typename Iterator>
628 bool RooMomentMorphFuncND::next_combination(
const Iterator first, Iterator k,
const Iterator last)
630 if ((first == last) || (first == k) || (last == k)) {
633 Iterator itr1 = first;
634 Iterator itr2 = last;
643 while (first != itr1) {
644 if (*--itr1 < *itr2) {
646 while (!(*itr1 < *j)) ++j;
651 rotate(itr1, j, last);
656 rotate(k, itr2, last);
660 rotate(first, k, last);
665 void RooMomentMorphFuncND::CacheElem::calculateFractions(
const RooMomentMorphFuncND &
self, Bool_t verbose)
const
667 int nPdf =
self._pdfList.getSize();
668 int nPar =
self._parList.getSize();
670 Double_t fracLinear(1.);
671 Double_t fracNonLinear(1.);
673 if (
self._setting == NonLinear ||
self._setting == NonLinearLinFractions ||
self._setting == NonLinearPosFractions) {
676 for (
int idim = 0; idim < nPar; idim++) {
677 Double_t delta = ((RooRealVar *)
self._parList.at(idim))->getVal() -
self._referenceGrid._nref[0][idim];
678 dm2.push_back(delta);
681 vector<vector<int>> powers;
682 for (
int idim = 0; idim < nPar; idim++) {
684 for (
int ix = 0; ix <
self._referenceGrid._nnuis[idim]; ix++) {
687 powers.push_back(xtmp);
690 vector<vector<int>> output;
691 cartesian_product(output, powers);
692 int nCombs = output.size();
694 vector<double> deltavec(nPdf, 1.0);
697 for (
int i = 0; i < nCombs; i++) {
699 for (
int ix = 0; ix < nPar; ix++) {
700 Double_t delta = dm2[ix];
701 tmpDm *= TMath::Power(delta, static_cast<double>(output[i][ix]));
703 deltavec[nperm] = tmpDm;
707 double sumposfrac = 0.0;
708 for (
int i = 0; i < nPdf; ++i) {
711 for (
int j = 0; j < nPdf; ++j) {
712 ffrac += (*
self._M)(j, i) * deltavec[j] * fracNonLinear;
720 if (
self._setting != NonLinearLinFractions) {
721 ((RooRealVar *)frac(i))->setVal(ffrac);
725 ((RooRealVar *)frac(nPdf + i))->setVal(ffrac);
726 ((RooRealVar *)frac(2 * nPdf + i))->setVal(ffrac);
729 cout <<
"NonLinear fraction " << ffrac << endl;
731 frac(nPdf + i)->Print();
732 frac(2 * nPdf + i)->Print();
736 if (
self._setting == NonLinearPosFractions) {
737 for (
int i = 0; i < nPdf; ++i) {
738 if (((RooRealVar *)frac(i))->getVal() < 0)
739 ((RooRealVar *)frac(i))->setVal(0.);
740 ((RooRealVar *)frac(i))->setVal(((RooRealVar *)frac(i))->getVal() / sumposfrac);
745 if (
self._setting == Linear ||
self._setting == NonLinearLinFractions) {
747 self._parItr->Reset();
751 for (
int i = 0; i < nPdf; ++i) {
753 ((RooRealVar *)frac(i))->setVal(initval);
754 ((RooRealVar *)frac(nPdf + i))->setVal(initval);
755 ((RooRealVar *)frac(2 * nPdf + i))->setVal(initval);
760 for (
int j = 0; j < nPar; j++) {
761 RooRealVar *m = (RooRealVar *)(
self._parItr->Next());
762 mtmp.push_back(m->getVal());
765 self.findShape(mtmp);
767 int depth = TMath::Power(2, nPar);
768 vector<double> deltavec(depth, 1.0);
773 for (
int ix = 0; ix < nPar; ix++) {
777 for (
int iperm = 1; iperm <= nPar; ++iperm) {
779 double dtmp = mtmp[xtmp[0]] -
self._squareVec[0][xtmp[0]];
780 for (
int itmp = 1; itmp < iperm; ++itmp) {
781 dtmp *= mtmp[xtmp[itmp]] -
self._squareVec[0][xtmp[itmp]];
783 deltavec[nperm + 1] = dtmp;
785 }
while (next_combination(xtmp.begin(), xtmp.begin() + iperm, xtmp.end()));
788 Double_t origFrac1(0.), origFrac2(0.);
789 for (
int i = 0; i < depth; ++i) {
791 for (
int j = 0; j < depth; ++j) {
792 ffrac += (*
self._MSqr)(j, i) * deltavec[j] * fracLinear;
796 origFrac1 = ((RooRealVar *)frac(
self._squareIdx[i]))->getVal();
797 ((RooRealVar *)frac(
self._squareIdx[i]))->setVal(origFrac1 + ffrac);
800 if (
self._setting != NonLinearLinFractions) {
802 ((RooRealVar *)frac(nPdf +
self._squareIdx[i]))->getVal();
803 ((RooRealVar *)frac(nPdf +
self._squareIdx[i]))->setVal(origFrac2 + ffrac);
804 ((RooRealVar *)frac(2 * nPdf +
self._squareIdx[i]))->setVal(origFrac2 + ffrac);
808 cout <<
"Linear fraction " << ffrac << endl;
809 frac(
self._squareIdx[i])->Print();
810 frac(nPdf +
self._squareIdx[i])->Print();
811 frac(2 * nPdf +
self._squareIdx[i])->Print();
818 void RooMomentMorphFuncND::findShape(
const vector<double> &x)
const
820 int nPar = _parList.getSize();
821 int nRef = _referenceGrid._nref.size();
824 bool isEnclosed =
true;
825 for (
int i = 0; i < nPar; i++) {
826 if (x[i] < _referenceGrid._grid[i]->lowBound())
828 if (x[i] > _referenceGrid._grid[i]->highBound())
834 int depth = TMath::Power(2, nPar);
836 vector<vector<double>> boundaries(nPar);
837 for (
int idim = 0; idim < nPar; idim++) {
838 int bin = _referenceGrid._grid[idim]->binNumber(x[idim]);
839 double lo = _referenceGrid._grid[idim]->binLow(bin);
840 double hi = _referenceGrid._grid[idim]->binHigh(bin);
841 boundaries[idim].push_back(lo);
842 boundaries[idim].push_back(hi);
845 vector<vector<double>> output;
846 cartesian_product(output, boundaries);
849 for (
int isq = 0; isq < depth; isq++) {
850 for (
int iref = 0; iref < nRef; iref++) {
851 if (_squareVec[isq] == _referenceGrid._nref[iref]) {
852 _squareIdx[isq] = iref;
870 TMatrixD M(depth, depth);
873 for (
int ix = 0; ix < nPar; ix++) {
877 for (
int k = 0; k < depth; ++k) {
881 vector<double> squareBase = _squareVec[0];
883 for (
int iperm = 1; iperm <= nPar; ++iperm) {
885 double dtmp = _squareVec[k][xtmp[0]] - squareBase[xtmp[0]];
886 for (
int itmp = 1; itmp < iperm; ++itmp) {
887 dtmp *= _squareVec[k][xtmp[itmp]] - squareBase[xtmp[itmp]];
889 M(k, nperm + 1) = dtmp;
891 }
while (next_combination(xtmp.begin(), xtmp.begin() + iperm, xtmp.end()));
896 (*_MSqr) = M.Invert();
900 Bool_t RooMomentMorphFuncND::setBinIntegrator(RooArgSet &allVars)
902 if (allVars.getSize() == 1) {
903 RooAbsReal *temp =
const_cast<RooMomentMorphFuncND *
>(
this);
904 temp->specialIntegratorConfig(kTRUE)->method1D().setLabel(
"RooBinIntegrator");
905 int nbins = ((RooRealVar *)allVars.first())->numBins();
906 temp->specialIntegratorConfig(kTRUE)->getConfigSection(
"RooBinIntegrator").setRealValue(
"numBins", nbins);
909 cout <<
"Currently BinIntegrator only knows how to deal with 1-d " << endl;