29 ClassImp(RooMomentMorphFunc)
32 RooMomentMorphFunc::RooMomentMorphFunc()
33 : _curNormSet(0), _mref(0), _M(0), _useHorizMorph(true)
36 _varItr = _varList.createIterator();
37 _pdfItr = _pdfList.createIterator();
41 RooMomentMorphFunc::RooMomentMorphFunc(
const char *name,
const char *title, RooAbsReal &_m,
const RooArgList &varList,
42 const RooArgList &pdfList,
const TVectorD &mrefpoints, Setting setting)
43 : RooAbsReal(name, title), _cacheMgr(this, 10, kTRUE, kTRUE), m(
"m",
"m", this, _m),
44 _varList(
"varList",
"List of variables", this), _pdfList(
"pdfList",
"List of pdfs", this), _setting(setting),
50 TIterator *varItr = varList.createIterator();
52 for (Int_t i = 0; (var = (RooAbsArg *)varItr->Next()); ++i) {
53 if (!dynamic_cast<RooAbsReal *>(var)) {
54 coutE(InputArguments) <<
"RooMomentMorphFunc::ctor(" << GetName() <<
") ERROR: variable " << var->GetName()
55 <<
" is not of type RooAbsReal" << endl;
56 throw string(
"RooPolyMorh::ctor() ERROR variable is not of type RooAbsReal");
63 TIterator *pdfItr = pdfList.createIterator();
65 for (Int_t i = 0; (pdf =
dynamic_cast<RooAbsReal *
>(pdfItr->Next())); ++i) {
67 coutE(InputArguments) <<
"RooMomentMorphFunc::ctor(" << GetName() <<
") ERROR: func " << pdf->GetName()
68 <<
" is not of type RooAbsReal" << endl;
69 throw string(
"RooMomentMorhFunc::ctor() ERROR func is not of type RooAbsReal");
75 _mref =
new TVectorD(mrefpoints);
76 _varItr = _varList.createIterator();
77 _pdfItr = _pdfList.createIterator();
84 RooMomentMorphFunc::RooMomentMorphFunc(
const char *name,
const char *title, RooAbsReal &_m,
const RooArgList &varList,
85 const RooArgList &pdfList,
const RooArgList &mrefList, Setting setting)
86 : RooAbsReal(name, title), _cacheMgr(this, 10, kTRUE, kTRUE), m(
"m",
"m", this, _m),
87 _varList(
"varList",
"List of variables", this), _pdfList(
"pdfList",
"List of pdfs", this), _setting(setting),
93 TIterator *varItr = varList.createIterator();
95 for (Int_t i = 0; (var = (RooAbsArg *)varItr->Next()); ++i) {
96 if (!dynamic_cast<RooAbsReal *>(var)) {
97 coutE(InputArguments) <<
"RooMomentMorphFunc::ctor(" << GetName() <<
") ERROR: variable " << var->GetName()
98 <<
" is not of type RooAbsReal" << endl;
99 throw string(
"RooMomentMorh::ctor() ERROR variable is not of type RooAbsReal");
106 TIterator *pdfItr = pdfList.createIterator();
108 for (Int_t i = 0; (pdf =
dynamic_cast<RooAbsReal *
>(pdfItr->Next())); ++i) {
110 coutE(InputArguments) <<
"RooMomentMorphFunc::ctor(" << GetName() <<
") ERROR: function " << pdf->GetName()
111 <<
" is not of type RooAbsReal" << endl;
112 throw string(
"RooMomentMorh::ctor() ERROR function is not of type RooAbsReal");
119 _mref =
new TVectorD(mrefList.getSize());
120 TIterator *mrefItr = mrefList.createIterator();
122 for (Int_t i = 0; (mref =
dynamic_cast<RooAbsReal *
>(mrefItr->Next())); ++i) {
124 coutE(InputArguments) <<
"RooMomentMorphFunc::ctor(" << GetName() <<
") ERROR: mref " << mref->GetName()
125 <<
" is not of type RooAbsReal" << endl;
126 throw string(
"RooPolyMorh::ctor() ERROR mref is not of type RooAbsReal");
128 if (!dynamic_cast<RooConstVar *>(mref)) {
129 coutW(InputArguments) <<
"RooMomentMorphFunc::ctor(" << GetName() <<
") WARNING mref point " << i
130 <<
" is not a constant, taking a snapshot of its value" << endl;
132 (*_mref)[i] = mref->getVal();
136 _varItr = _varList.createIterator();
137 _pdfItr = _pdfList.createIterator();
144 RooMomentMorphFunc::RooMomentMorphFunc(
const RooMomentMorphFunc &other,
const char *name)
145 : RooAbsReal(other, name), _cacheMgr(other._cacheMgr, this), _curNormSet(0), m(
"m", this, other.m),
146 _varList(
"varList", this, other._varList), _pdfList(
"pdfList", this, other._pdfList), _setting(other._setting),
147 _useHorizMorph(other._useHorizMorph)
149 _mref =
new TVectorD(*other._mref);
150 _varItr = _varList.createIterator();
151 _pdfItr = _pdfList.createIterator();
158 RooMomentMorphFunc::~RooMomentMorphFunc()
171 void RooMomentMorphFunc::initialize()
174 Int_t nPdf = _pdfList.getSize();
177 if (nPdf != _mref->GetNrows()) {
178 coutE(InputArguments) <<
"RooMomentMorphFunc::initialize(" << GetName() <<
") ERROR: nPdf != nRefPoints" << endl;
182 TVectorD *dm =
new TVectorD(nPdf);
183 _M =
new TMatrixD(nPdf, nPdf);
186 TMatrixD M(nPdf, nPdf);
187 for (Int_t i = 0; i < _mref->GetNrows(); ++i) {
188 (*dm)[i] = (*_mref)[i] - (*_mref)[0];
193 for (Int_t i = 1; i < _mref->GetNrows(); ++i) {
194 for (Int_t j = 1; j < _mref->GetNrows(); ++j) {
195 M(i, j) = TMath::Power((*dm)[i], (
double)j);
204 RooMomentMorphFunc::CacheElem *RooMomentMorphFunc::getCache(
const RooArgSet * )
const
206 CacheElem *cache = (CacheElem *)_cacheMgr.getObj(0, (RooArgSet *)0);
210 Int_t nVar = _varList.getSize();
211 Int_t nPdf = _pdfList.getSize();
213 RooAbsReal *null = 0;
214 vector<RooAbsReal *> meanrv(nPdf * nVar, null);
215 vector<RooAbsReal *> sigmarv(nPdf * nVar, null);
216 vector<RooAbsReal *> myrms(nVar, null);
217 vector<RooAbsReal *> mypos(nVar, null);
218 vector<RooAbsReal *> slope(nPdf * nVar, null);
219 vector<RooAbsReal *> offs(nPdf * nVar, null);
220 vector<RooAbsReal *> transVar(nPdf * nVar, null);
221 vector<RooAbsReal *> transPdf(nPdf, null);
223 RooArgSet ownedComps;
228 RooArgList coefList(
"coefList");
229 RooArgList coefList2(
"coefList2");
230 for (Int_t i = 0; i < 2 * nPdf; ++i) {
231 std::string fracName = Form(
"frac_%d", i);
233 RooRealVar *frac =
new RooRealVar(fracName.c_str(), fracName.c_str(), 1.);
237 coefList.add(*(RooRealVar *)(fracl.at(i)));
239 coefList2.add(*(RooRealVar *)(fracl.at(i)));
240 ownedComps.add(*(RooRealVar *)(fracl.at(i)));
243 RooRealSumFunc *theSumFunc = 0;
244 std::string sumfuncName = Form(
"%s_sumfunc", GetName());
246 if (_useHorizMorph) {
248 RooArgList varList(_varList);
249 for (Int_t i = 0; i < nPdf; ++i) {
250 for (Int_t j = 0; j < nVar; ++j) {
252 std::string meanName = Form(
"%s_mean_%d_%d", GetName(), i, j);
253 std::string sigmaName = Form(
"%s_sigma_%d_%d", GetName(), i, j);
255 RooAbsMoment *mom = nVar == 1 ? ((RooAbsPdf *)_pdfList.at(i))->sigma((RooRealVar &)*varList.at(j))
256 : ((RooAbsPdf *)_pdfList.at(i))->sigma((RooRealVar &)*varList.at(j), varList);
258 mom->setLocalNoDirtyInhibit(kTRUE);
259 mom->mean()->setLocalNoDirtyInhibit(kTRUE);
261 sigmarv[ij(i, j)] = mom;
262 meanrv[ij(i, j)] = mom->mean();
264 ownedComps.add(*sigmarv[ij(i, j)]);
269 for (Int_t j = 0; j < nVar; ++j) {
270 RooArgList meanList(
"meanList");
271 RooArgList rmsList(
"rmsList");
272 for (Int_t i = 0; i < nPdf; ++i) {
273 meanList.add(*meanrv[ij(i, j)]);
274 rmsList.add(*sigmarv[ij(i, j)]);
276 std::string myrmsName = Form(
"%s_rms_%d", GetName(), j);
277 std::string myposName = Form(
"%s_pos_%d", GetName(), j);
278 myrms[j] =
new RooAddition(myrmsName.c_str(), myrmsName.c_str(), rmsList, coefList2);
279 mypos[j] =
new RooAddition(myposName.c_str(), myposName.c_str(), meanList, coefList2);
280 ownedComps.add(RooArgSet(*myrms[j], *mypos[j]));
286 RooArgList transPdfList;
288 for (Int_t i = 0; i < nPdf; ++i) {
292 pdf = (RooAbsPdf *)_pdfItr->Next();
293 std::string pdfName = Form(
"pdf_%d", i);
294 RooCustomizer cust(*pdf, pdfName.c_str());
296 for (Int_t j = 0; j < nVar; ++j) {
298 std::string slopeName = Form(
"%s_slope_%d_%d", GetName(), i, j);
299 std::string offsetName = Form(
"%s_offset_%d_%d", GetName(), i, j);
300 slope[ij(i, j)] =
new RooFormulaVar(slopeName.c_str(),
"@0/@1", RooArgList(*sigmarv[ij(i, j)], *myrms[j]));
301 offs[ij(i, j)] =
new RooFormulaVar(offsetName.c_str(),
"@0-(@1*@2)",
302 RooArgList(*meanrv[ij(i, j)], *mypos[j], *slope[ij(i, j)]));
303 ownedComps.add(RooArgSet(*slope[ij(i, j)], *offs[ij(i, j)]));
305 var = (RooRealVar *)(_varItr->Next());
306 std::string transVarName = Form(
"%s_transVar_%d_%d", GetName(), i, j);
311 new RooLinearVar(transVarName.c_str(), transVarName.c_str(), *var, *slope[ij(i, j)], *offs[ij(i, j)]);
315 transVar[ij(i, j)]->addServer((RooAbsArg &)m.arg());
317 ownedComps.add(*transVar[ij(i, j)]);
318 cust.replaceArg(*var, *transVar[ij(i, j)]);
320 transPdf[i] = (RooAbsPdf *)cust.build();
321 transPdfList.add(*transPdf[i]);
322 ownedComps.add(*transPdf[i]);
325 theSumFunc =
new RooRealSumFunc(sumfuncName.c_str(), sumfuncName.c_str(), transPdfList, coefList);
327 theSumFunc =
new RooRealSumFunc(sumfuncName.c_str(), sumfuncName.c_str(), _pdfList, coefList);
332 theSumFunc->addServer((RooAbsArg &)m.arg());
333 theSumFunc->addOwnedComponents(ownedComps);
336 std::string trackerName = Form(
"%s_frac_tracker", GetName());
337 RooChangeTracker *tracker =
new RooChangeTracker(trackerName.c_str(), trackerName.c_str(), m.arg(), kTRUE);
340 cache =
new CacheElem(*theSumFunc, *tracker, fracl);
341 _cacheMgr.setObj(0, 0, cache, 0);
347 RooArgList RooMomentMorphFunc::CacheElem::containedArgs(Action)
349 return RooArgList(*_sumFunc, *_tracker);
353 RooMomentMorphFunc::CacheElem::~CacheElem()
360 Double_t RooMomentMorphFunc::getVal(
const RooArgSet *set)
const
363 _curNormSet = set ? (RooArgSet *)set : (RooArgSet *)&_varList;
364 return RooAbsReal::getVal(set);
368 RooAbsReal *RooMomentMorphFunc::sumFunc(
const RooArgSet *nset)
370 CacheElem *cache = getCache(nset ? nset : _curNormSet);
372 if (cache->_tracker->hasChanged(kTRUE)) {
373 cache->calculateFractions(*
this, kFALSE);
376 return cache->_sumFunc;
380 const RooAbsReal *RooMomentMorphFunc::sumFunc(
const RooArgSet *nset)
const
382 CacheElem *cache = getCache(nset ? nset : _curNormSet);
384 if (cache->_tracker->hasChanged(kTRUE)) {
385 cache->calculateFractions(*
this, kFALSE);
388 return cache->_sumFunc;
392 Double_t RooMomentMorphFunc::evaluate()
const
394 CacheElem *cache = getCache(_curNormSet);
396 if (cache->_tracker->hasChanged(kTRUE)) {
397 cache->calculateFractions(*
this, kFALSE);
400 Double_t ret = cache->_sumFunc->getVal(_pdfList.nset());
405 RooRealVar *RooMomentMorphFunc::CacheElem::frac(Int_t i)
407 return (RooRealVar *)(_frac.at(i));
411 const RooRealVar *RooMomentMorphFunc::CacheElem::frac(Int_t i)
const
413 return (RooRealVar *)(_frac.at(i));
417 void RooMomentMorphFunc::CacheElem::calculateFractions(
const RooMomentMorphFunc &
self, Bool_t verbose)
const
419 Int_t nPdf =
self._pdfList.getSize();
421 Double_t dm =
self.m - (*
self._mref)[0];
424 double sumposfrac = 0.;
425 for (Int_t i = 0; i < nPdf; ++i) {
427 for (Int_t j = 0; j < nPdf; ++j) {
428 ffrac += (*
self._M)(j, i) * (j == 0 ? 1. : TMath::Power(dm, (
double)j));
433 ((RooRealVar *)frac(i))->setVal(ffrac);
435 ((RooRealVar *)frac(nPdf + i))->setVal(ffrac);
437 cout << ffrac << endl;
442 int imin =
self.idxmin(
self.m);
443 int imax =
self.idxmax(
self.m);
444 double mfrac = (
self.m - (*
self._mref)[imin]) / ((*
self._mref)[imax] - (*
self._mref)[imin]);
445 switch (
self._setting) {
452 TMath::Sin(TMath::PiOver2() * mfrac);
457 for (Int_t i = 0; i < 2 * nPdf; ++i) ((RooRealVar *)frac(i))->setVal(0.);
459 ((RooRealVar *)frac(imin))->setVal(1. - mfrac);
460 ((RooRealVar *)frac(nPdf + imin))->setVal(1. - mfrac);
461 ((RooRealVar *)frac(imax))->setVal(mfrac);
462 ((RooRealVar *)frac(nPdf + imax))->setVal(mfrac);
463 }
else if (imax == imin) {
464 ((RooRealVar *)frac(imin))->setVal(1.);
465 ((RooRealVar *)frac(nPdf + imin))->setVal(1.);
468 case NonLinearLinFractions:
469 for (Int_t i = 0; i < nPdf; ++i) ((RooRealVar *)frac(i))->setVal(0.);
471 ((RooRealVar *)frac(imin))->setVal(1. - mfrac);
472 ((RooRealVar *)frac(imax))->setVal(mfrac);
473 }
else if (imax == imin) {
474 ((RooRealVar *)frac(imin))->setVal(1.);
477 case NonLinearPosFractions:
478 for (Int_t i = 0; i < nPdf; ++i) {
479 if (((RooRealVar *)frac(i))->getVal() < 0)
480 ((RooRealVar *)frac(i))->setVal(0.);
481 ((RooRealVar *)frac(i))->setVal(((RooRealVar *)frac(i))->getVal() / sumposfrac);
488 int RooMomentMorphFunc::idxmin(
const double &mval)
const
491 Int_t nPdf = _pdfList.getSize();
492 double mmin = -DBL_MAX;
493 for (Int_t i = 0; i < nPdf; ++i)
494 if ((*_mref)[i] > mmin && (*_mref)[i] <= mval) {
502 int RooMomentMorphFunc::idxmax(
const double &mval)
const
505 Int_t nPdf = _pdfList.getSize();
506 double mmax = DBL_MAX;
507 for (Int_t i = 0; i < nPdf; ++i)
508 if ((*_mref)[i] < mmax && (*_mref)[i] >= mval) {
516 std::list<Double_t> *RooMomentMorphFunc::plotSamplingHint(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi)
const
518 return sumFunc(0)->plotSamplingHint(obs, xlo, xhi);
522 std::list<Double_t> *RooMomentMorphFunc::binBoundaries(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi)
const
524 return sumFunc(0)->binBoundaries(obs, xlo, xhi);
528 Bool_t RooMomentMorphFunc::isBinnedDistribution(
const RooArgSet &obs)
const
530 return sumFunc(0)->isBinnedDistribution(obs);