32 ClassImp(RooMomentMorph);
37 RooMomentMorph::RooMomentMorph() : _curNormSet(0), _mref(0), _M(0), _useHorizMorph(true)
39 _varItr = _varList.createIterator() ;
40 _pdfItr = _pdfList.createIterator() ;
46 RooMomentMorph::RooMomentMorph(
const char *name,
const char *title,
48 const RooArgList& varList,
49 const RooArgList& pdfList,
50 const TVectorD& mrefpoints,
52 RooAbsPdf(name,title),
53 _cacheMgr(this,10,kTRUE,kTRUE),
55 _varList(
"varList",
"List of variables",this),
56 _pdfList(
"pdfList",
"List of pdfs",this),
61 TIterator* varItr = varList.createIterator() ;
63 for (Int_t i=0; (var = (RooAbsArg*)varItr->Next()); ++i) {
64 if (!dynamic_cast<RooAbsReal*>(var)) {
65 coutE(InputArguments) <<
"RooMomentMorph::ctor(" << GetName() <<
") ERROR: variable " << var->GetName() <<
" is not of type RooAbsReal" << endl ;
66 throw string(
"RooPolyMorh::ctor() ERROR variable is not of type RooAbsReal") ;
73 TIterator* pdfItr = pdfList.createIterator() ;
75 for (Int_t i=0; (pdf =
dynamic_cast<RooAbsPdf*
>(pdfItr->Next())); ++i) {
77 coutE(InputArguments) <<
"RooMomentMorph::ctor(" << GetName() <<
") ERROR: pdf " << pdf->GetName() <<
" is not of type RooAbsPdf" << endl ;
78 throw string(
"RooPolyMorh::ctor() ERROR pdf is not of type RooAbsPdf") ;
84 _mref =
new TVectorD(mrefpoints);
85 _varItr = _varList.createIterator() ;
86 _pdfItr = _pdfList.createIterator() ;
95 RooMomentMorph::RooMomentMorph(
const char *name,
const char *title,
97 const RooArgList& varList,
98 const RooArgList& pdfList,
99 const RooArgList& mrefList,
101 RooAbsPdf(name,title),
102 _cacheMgr(this,10,kTRUE,kTRUE),
104 _varList(
"varList",
"List of variables",this),
105 _pdfList(
"pdfList",
"List of pdfs",this),
110 TIterator* varItr = varList.createIterator() ;
112 for (Int_t i=0; (var = (RooAbsArg*)varItr->Next()); ++i) {
113 if (!dynamic_cast<RooAbsReal*>(var)) {
114 coutE(InputArguments) <<
"RooMomentMorph::ctor(" << GetName() <<
") ERROR: variable " << var->GetName() <<
" is not of type RooAbsReal" << endl ;
115 throw string(
"RooPolyMorh::ctor() ERROR variable is not of type RooAbsReal") ;
122 TIterator* pdfItr = pdfList.createIterator() ;
124 for (Int_t i=0; (pdf =
dynamic_cast<RooAbsPdf*
>(pdfItr->Next())); ++i) {
126 coutE(InputArguments) <<
"RooMomentMorph::ctor(" << GetName() <<
") ERROR: pdf " << pdf->GetName() <<
" is not of type RooAbsPdf" << endl ;
127 throw string(
"RooPolyMorh::ctor() ERROR pdf is not of type RooAbsPdf") ;
134 _mref =
new TVectorD(mrefList.getSize());
135 TIterator* mrefItr = mrefList.createIterator() ;
137 for (Int_t i=0; (mref =
dynamic_cast<RooAbsReal*
>(mrefItr->Next())); ++i) {
139 coutE(InputArguments) <<
"RooMomentMorph::ctor(" << GetName() <<
") ERROR: mref " << mref->GetName() <<
" is not of type RooAbsReal" << endl ;
140 throw string(
"RooPolyMorh::ctor() ERROR mref is not of type RooAbsReal") ;
142 if (!dynamic_cast<RooConstVar*>(mref)) {
143 coutW(InputArguments) <<
"RooMomentMorph::ctor(" << GetName() <<
") WARNING mref point " << i <<
" is not a constant, taking a snapshot of its value" << endl ;
145 (*_mref)[i] = mref->getVal() ;
149 _varItr = _varList.createIterator() ;
150 _pdfItr = _pdfList.createIterator() ;
158 RooMomentMorph::RooMomentMorph(
const RooMomentMorph& other,
const char* name) :
159 RooAbsPdf(other,name),
160 _cacheMgr(other._cacheMgr,this),
163 _varList(
"varList",this,other._varList),
164 _pdfList(
"pdfList",this,other._pdfList),
165 _setting(other._setting),
166 _useHorizMorph(other._useHorizMorph)
168 _mref =
new TVectorD(*other._mref) ;
169 _varItr = _varList.createIterator() ;
170 _pdfItr = _pdfList.createIterator() ;
178 RooMomentMorph::~RooMomentMorph()
180 if (_mref)
delete _mref;
181 if (_varItr)
delete _varItr;
182 if (_pdfItr)
delete _pdfItr;
188 void RooMomentMorph::initialize()
190 Int_t nPdf = _pdfList.getSize();
193 if (nPdf!=_mref->GetNrows()) {
194 coutE(InputArguments) <<
"RooMomentMorph::initialize(" << GetName() <<
") ERROR: nPdf != nRefPoints" << endl ;
198 TVectorD* dm =
new TVectorD(nPdf);
199 _M =
new TMatrixD(nPdf,nPdf);
202 TMatrixD M(nPdf,nPdf);
203 for (Int_t i=0; i<_mref->GetNrows(); ++i) {
204 (*dm)[i] = (*_mref)[i]-(*_mref)[0];
206 if (i>0) M(0,i) = 0.;
208 for (Int_t i=1; i<_mref->GetNrows(); ++i) {
209 for (Int_t j=1; j<_mref->GetNrows(); ++j) {
210 M(i,j) = TMath::Power((*dm)[i],(
double)j);
220 RooMomentMorph::CacheElem* RooMomentMorph::getCache(
const RooArgSet* )
const
222 CacheElem* cache = (CacheElem*) _cacheMgr.getObj(0,(RooArgSet*)0) ;
226 Int_t nVar = _varList.getSize();
227 Int_t nPdf = _pdfList.getSize();
229 RooAbsReal* null = 0 ;
230 vector<RooAbsReal*> meanrv(nPdf*nVar,null);
231 vector<RooAbsReal*> sigmarv(nPdf*nVar,null);
232 vector<RooAbsReal*> myrms(nVar,null);
233 vector<RooAbsReal*> mypos(nVar,null);
234 vector<RooAbsReal*> slope(nPdf*nVar,null);
235 vector<RooAbsReal*> offs(nPdf*nVar,null);
236 vector<RooAbsReal*> transVar(nPdf*nVar,null);
237 vector<RooAbsReal*> transPdf(nPdf,null);
239 RooArgSet ownedComps ;
244 RooArgList coefList(
"coefList");
245 RooArgList coefList2(
"coefList2");
246 for (Int_t i=0; i<2*nPdf; ++i) {
247 std::string fracName = Form(
"frac_%d",i);
249 RooRealVar* frac =
new RooRealVar(fracName.c_str(),fracName.c_str(),1.) ;
252 if (i<nPdf) coefList.add(*(RooRealVar*)(fracl.at(i))) ;
253 else coefList2.add(*(RooRealVar*)(fracl.at(i))) ;
254 ownedComps.add(*(RooRealVar*)(fracl.at(i))) ;
257 RooAddPdf* theSumPdf = 0;
258 std::string sumpdfName = Form(
"%s_sumpdf",GetName());
260 if (_useHorizMorph) {
262 RooArgList varList(_varList) ;
263 for (Int_t i=0; i<nPdf; ++i) {
264 for (Int_t j=0; j<nVar; ++j) {
266 std::string meanName = Form(
"%s_mean_%d_%d",GetName(),i,j);
267 std::string sigmaName = Form(
"%s_sigma_%d_%d",GetName(),i,j);
269 RooAbsMoment* mom = nVar==1 ?
270 ((RooAbsPdf*)_pdfList.at(i))->sigma((RooRealVar&)*varList.at(j)) :
271 ((RooAbsPdf*)_pdfList.at(i))->sigma((RooRealVar&)*varList.at(j),varList) ;
273 mom->setLocalNoDirtyInhibit(kTRUE) ;
274 mom->mean()->setLocalNoDirtyInhibit(kTRUE) ;
276 sigmarv[ij(i,j)] = mom ;
277 meanrv[ij(i,j)] = mom->mean() ;
279 ownedComps.add(*sigmarv[ij(i,j)]) ;
284 for (Int_t j=0; j<nVar; ++j) {
285 RooArgList meanList(
"meanList");
286 RooArgList rmsList(
"rmsList");
287 for (Int_t i=0; i<nPdf; ++i) {
288 meanList.add(*meanrv[ij(i,j)]);
289 rmsList.add(*sigmarv[ij(i,j)]);
291 std::string myrmsName = Form(
"%s_rms_%d",GetName(),j);
292 std::string myposName = Form(
"%s_pos_%d",GetName(),j);
293 myrms[j] =
new RooAddition(myrmsName.c_str(),myrmsName.c_str(),rmsList,coefList2);
294 mypos[j] =
new RooAddition(myposName.c_str(),myposName.c_str(),meanList,coefList2);
295 ownedComps.add(RooArgSet(*myrms[j],*mypos[j])) ;
301 RooArgList transPdfList;
303 for (Int_t i=0; i<nPdf; ++i) {
307 pdf = (RooAbsPdf*)_pdfItr->Next();
308 std::string pdfName = Form(
"pdf_%d",i);
309 RooCustomizer cust(*pdf,pdfName.c_str());
311 for (Int_t j=0; j<nVar; ++j) {
313 std::string slopeName = Form(
"%s_slope_%d_%d",GetName(),i,j);
314 std::string offsetName = Form(
"%s_offset_%d_%d",GetName(),i,j);
315 slope[ij(i,j)] =
new RooFormulaVar(slopeName.c_str(),
"@0/@1",RooArgList(*sigmarv[ij(i,j)],*myrms[j]));
316 offs[ij(i,j)] =
new RooFormulaVar(offsetName.c_str(),
"@0-(@1*@2)",RooArgList(*meanrv[ij(i,j)],*mypos[j],*slope[ij(i,j)]));
317 ownedComps.add(RooArgSet(*slope[ij(i,j)],*offs[ij(i,j)])) ;
319 var = (RooRealVar*)(_varItr->Next());
320 std::string transVarName = Form(
"%s_transVar_%d_%d",GetName(),i,j);
323 transVar[ij(i,j)] =
new RooLinearVar(transVarName.c_str(),transVarName.c_str(),*var,*slope[ij(i,j)],*offs[ij(i,j)]);
327 transVar[ij(i,j)]->addServer((RooAbsArg&)m.arg()) ;
329 ownedComps.add(*transVar[ij(i,j)]) ;
330 cust.replaceArg(*var,*transVar[ij(i,j)]);
332 transPdf[i] = (RooAbsPdf*) cust.build() ;
333 transPdfList.add(*transPdf[i]);
334 ownedComps.add(*transPdf[i]) ;
337 theSumPdf =
new RooAddPdf(sumpdfName.c_str(),sumpdfName.c_str(),transPdfList,coefList);
340 theSumPdf =
new RooAddPdf(sumpdfName.c_str(),sumpdfName.c_str(),_pdfList,coefList);
345 theSumPdf->addServer((RooAbsArg&)m.arg()) ;
346 theSumPdf->addOwnedComponents(ownedComps) ;
349 std::string trackerName = Form(
"%s_frac_tracker",GetName()) ;
350 RooChangeTracker* tracker =
new RooChangeTracker(trackerName.c_str(),trackerName.c_str(),m.arg(),kTRUE) ;
353 cache =
new CacheElem(*theSumPdf,*tracker,fracl) ;
354 _cacheMgr.setObj(0,0,cache,0) ;
356 cache->calculateFractions(*
this, kFALSE);
362 RooArgList RooMomentMorph::CacheElem::containedArgs(Action)
364 return RooArgList(*_sumPdf,*_tracker) ;
369 RooMomentMorph::CacheElem::~CacheElem()
378 Double_t RooMomentMorph::getVal(
const RooArgSet* set)
const
380 _curNormSet = set ? (RooArgSet*)set : (RooArgSet*)&_varList ;
381 return RooAbsPdf::getVal(set) ;
386 RooAbsPdf* RooMomentMorph::sumPdf(
const RooArgSet* nset)
388 CacheElem* cache = getCache(nset ? nset : _curNormSet) ;
390 if (cache->_tracker->hasChanged(kTRUE)) {
391 cache->calculateFractions(*
this,kFALSE);
394 return cache->_sumPdf ;
399 Double_t RooMomentMorph::evaluate()
const
401 CacheElem* cache = getCache(_curNormSet) ;
403 if (cache->_tracker->hasChanged(kTRUE)) {
404 cache->calculateFractions(*
this,kFALSE);
407 Double_t ret = cache->_sumPdf->getVal(_pdfList.nset());
413 RooRealVar* RooMomentMorph::CacheElem::frac(Int_t i )
415 return (RooRealVar*)(_frac.at(i)) ;
420 const RooRealVar* RooMomentMorph::CacheElem::frac(Int_t i )
const
422 return (RooRealVar*)(_frac.at(i)) ;
427 void RooMomentMorph::CacheElem::calculateFractions(
const RooMomentMorph&
self, Bool_t verbose)
const
429 Int_t nPdf =
self._pdfList.getSize();
431 Double_t dm =
self.m - (*
self._mref)[0];
434 double sumposfrac=0.;
435 for (Int_t i=0; i<nPdf; ++i) {
437 for (Int_t j=0; j<nPdf; ++j) { ffrac += (*
self._M)(j,i) * (j==0?1.:TMath::Power(dm,(
double)j)); }
438 if (ffrac>=0) sumposfrac+=ffrac;
440 ((RooRealVar*)frac(i))->setVal(ffrac);
442 ((RooRealVar*)frac(nPdf+i))->setVal(ffrac);
443 if (verbose) { cout << ffrac << endl; }
447 int imin =
self.idxmin(
self.m);
448 int imax =
self.idxmax(
self.m);
449 double mfrac = (
self.m-(*
self._mref)[imin])/((*
self._mref)[imax]-(*
self._mref)[imin]);
450 switch (
self._setting) {
456 mfrac = TMath::Sin( TMath::PiOver2()*mfrac );
461 for (Int_t i=0; i<2*nPdf; ++i)
462 ((RooRealVar*)frac(i))->setVal(0.);
464 ((RooRealVar*)frac(imin))->setVal(1.-mfrac);
465 ((RooRealVar*)frac(nPdf+imin))->setVal(1.-mfrac);
466 ((RooRealVar*)frac(imax))->setVal(mfrac);
467 ((RooRealVar*)frac(nPdf+imax))->setVal(mfrac);
468 }
else if (imax==imin) {
469 ((RooRealVar*)frac(imin))->setVal(1.);
470 ((RooRealVar*)frac(nPdf+imin))->setVal(1.);
473 case NonLinearLinFractions:
474 for (Int_t i=0; i<nPdf; ++i)
475 ((RooRealVar*)frac(i))->setVal(0.);
477 ((RooRealVar*)frac(imin))->setVal(1.-mfrac);
478 ((RooRealVar*)frac(imax))->setVal(mfrac);
479 }
else if (imax==imin) {
480 ((RooRealVar*)frac(imin))->setVal(1.);
483 case NonLinearPosFractions:
484 for (Int_t i=0; i<nPdf; ++i) {
485 if (((RooRealVar*)frac(i))->getVal()<0) ((RooRealVar*)frac(i))->setVal(0.);
486 ((RooRealVar*)frac(i))->setVal(((RooRealVar*)frac(i))->getVal()/sumposfrac);
495 int RooMomentMorph::idxmin(
const double& mval)
const
498 Int_t nPdf = _pdfList.getSize();
499 double mmin=-DBL_MAX;
500 for (Int_t i=0; i<nPdf; ++i)
501 if ( (*_mref)[i]>mmin && (*_mref)[i]<=mval ) { mmin=(*_mref)[i]; imin=i; }
508 int RooMomentMorph::idxmax(
const double& mval)
const
511 Int_t nPdf = _pdfList.getSize();
513 for (Int_t i=0; i<nPdf; ++i)
514 if ( (*_mref)[i]<mmax && (*_mref)[i]>=mval ) { mmax=(*_mref)[i]; imax=i; }