00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "Riostream.h"
00010
00011 #include "RooMomentMorph.h"
00012 #include "RooAbsCategory.h"
00013 #include "RooRealIntegral.h"
00014 #include "RooRealConstant.h"
00015 #include "RooRealVar.h"
00016 #include "RooFormulaVar.h"
00017 #include "RooCustomizer.h"
00018 #include "RooAddPdf.h"
00019 #include "RooAddition.h"
00020 #include "RooMoment.h"
00021 #include "RooLinearVar.h"
00022 #include "RooChangeTracker.h"
00023
00024 #include "TMath.h"
00025
00026 ClassImp(RooMomentMorph)
00027
00028
00029
00030 RooMomentMorph::RooMomentMorph() : _curNormSet(0), _mref(0), _M(0)
00031 {
00032
00033 _varItr = _varList.createIterator() ;
00034 _pdfItr = _pdfList.createIterator() ;
00035 }
00036
00037
00038
00039
00040 RooMomentMorph::RooMomentMorph(const char *name, const char *title,
00041 RooAbsReal& _m,
00042 const RooArgList& varList,
00043 const RooArgList& pdfList,
00044 const TVectorD& mrefpoints,
00045 const Setting& setting) :
00046 RooAbsPdf(name,title),
00047 _cacheMgr(this,10),
00048 m("m","m",this,_m),
00049 _varList("varList","List of variables",this),
00050 _pdfList("pdfList","List of pdfs",this),
00051 _setting(setting)
00052 {
00053
00054
00055
00056 TIterator* varItr = varList.createIterator() ;
00057 RooAbsArg* var ;
00058 for (Int_t i=0; (var = (RooAbsArg*)varItr->Next()); ++i) {
00059 if (!dynamic_cast<RooAbsReal*>(var)) {
00060 coutE(InputArguments) << "RooMomentMorph::ctor(" << GetName() << ") ERROR: variable " << var->GetName() << " is not of type RooAbsReal" << endl ;
00061 throw string("RooPolyMorh::ctor() ERROR variable is not of type RooAbsReal") ;
00062 }
00063 _varList.add(*var) ;
00064 }
00065 delete varItr ;
00066
00067
00068 TIterator* pdfItr = pdfList.createIterator() ;
00069 RooAbsPdf* pdf ;
00070 for (Int_t i=0; (pdf = dynamic_cast<RooAbsPdf*>(pdfItr->Next())); ++i) {
00071 if (!pdf) {
00072 coutE(InputArguments) << "RooMomentMorph::ctor(" << GetName() << ") ERROR: pdf " << pdf->GetName() << " is not of type RooAbsPdf" << endl ;
00073 throw string("RooPolyMorh::ctor() ERROR pdf is not of type RooAbsPdf") ;
00074 }
00075 _pdfList.add(*pdf) ;
00076 }
00077 delete pdfItr ;
00078
00079 _mref = new TVectorD(mrefpoints);
00080 _varItr = _varList.createIterator() ;
00081 _pdfItr = _pdfList.createIterator() ;
00082
00083
00084 initialize();
00085 }
00086
00087
00088
00089
00090 RooMomentMorph::RooMomentMorph(const char *name, const char *title,
00091 RooAbsReal& _m,
00092 const RooArgList& varList,
00093 const RooArgList& pdfList,
00094 const RooArgList& mrefList,
00095 const Setting& setting) :
00096 RooAbsPdf(name,title),
00097 _cacheMgr(this,10),
00098 m("m","m",this,_m),
00099 _varList("varList","List of variables",this),
00100 _pdfList("pdfList","List of pdfs",this),
00101 _setting(setting)
00102 {
00103
00104
00105
00106 TIterator* varItr = varList.createIterator() ;
00107 RooAbsArg* var ;
00108 for (Int_t i=0; (var = (RooAbsArg*)varItr->Next()); ++i) {
00109 if (!dynamic_cast<RooAbsReal*>(var)) {
00110 coutE(InputArguments) << "RooMomentMorph::ctor(" << GetName() << ") ERROR: variable " << var->GetName() << " is not of type RooAbsReal" << endl ;
00111 throw string("RooPolyMorh::ctor() ERROR variable is not of type RooAbsReal") ;
00112 }
00113 _varList.add(*var) ;
00114 }
00115 delete varItr ;
00116
00117
00118 TIterator* pdfItr = pdfList.createIterator() ;
00119 RooAbsPdf* pdf ;
00120 for (Int_t i=0; (pdf = dynamic_cast<RooAbsPdf*>(pdfItr->Next())); ++i) {
00121 if (!pdf) {
00122 coutE(InputArguments) << "RooMomentMorph::ctor(" << GetName() << ") ERROR: pdf " << pdf->GetName() << " is not of type RooAbsPdf" << endl ;
00123 throw string("RooPolyMorh::ctor() ERROR pdf is not of type RooAbsPdf") ;
00124 }
00125 _pdfList.add(*pdf) ;
00126 }
00127 delete pdfItr ;
00128
00129
00130 _mref = new TVectorD(mrefList.getSize());
00131 TIterator* mrefItr = mrefList.createIterator() ;
00132 RooAbsReal* mref ;
00133 for (Int_t i=0; (mref = dynamic_cast<RooAbsReal*>(mrefItr->Next())); ++i) {
00134 if (!mref) {
00135 coutE(InputArguments) << "RooMomentMorph::ctor(" << GetName() << ") ERROR: mref " << mref->GetName() << " is not of type RooAbsReal" << endl ;
00136 throw string("RooPolyMorh::ctor() ERROR mref is not of type RooAbsReal") ;
00137 }
00138 if (!dynamic_cast<RooConstVar*>(mref)) {
00139 coutW(InputArguments) << "RooMomentMorph::ctor(" << GetName() << ") WARNING mref point " << i << " is not a constant, taking a snapshot of its value" << endl ;
00140 }
00141 (*_mref)[i] = mref->getVal() ;
00142 }
00143 delete mrefItr ;
00144
00145 _varItr = _varList.createIterator() ;
00146 _pdfItr = _pdfList.createIterator() ;
00147
00148
00149 initialize();
00150 }
00151
00152
00153
00154
00155 RooMomentMorph::RooMomentMorph(const RooMomentMorph& other, const char* name) :
00156 RooAbsPdf(other,name),
00157 _cacheMgr(other._cacheMgr,this),
00158 _curNormSet(0),
00159 m("m",this,other.m),
00160 _varList("varList",this,other._varList),
00161 _pdfList("pdfList",this,other._pdfList),
00162 _setting(other._setting)
00163 {
00164 _mref = new TVectorD(*other._mref) ;
00165 _varItr = _varList.createIterator() ;
00166 _pdfItr = _pdfList.createIterator() ;
00167
00168
00169 initialize();
00170 }
00171
00172
00173 RooMomentMorph::~RooMomentMorph()
00174 {
00175 if (_mref) delete _mref;
00176 if (_varItr) delete _varItr;
00177 if (_pdfItr) delete _pdfItr;
00178 if (_M) delete _M;
00179 }
00180
00181
00182
00183
00184 void RooMomentMorph::initialize()
00185 {
00186
00187 Int_t nPdf = _pdfList.getSize();
00188
00189
00190 if (nPdf!=_mref->GetNrows()) {
00191 coutE(InputArguments) << "RooMomentMorph::initialize(" << GetName() << ") ERROR: nPdf != nRefPoints" << endl ;
00192 assert(0) ;
00193 }
00194
00195 TVectorD* dm = new TVectorD(nPdf);
00196 _M = new TMatrixD(nPdf,nPdf);
00197
00198
00199 TMatrixD M(nPdf,nPdf);
00200 for (Int_t i=0; i<_mref->GetNrows(); ++i) {
00201 (*dm)[i] = (*_mref)[i]-(*_mref)[0];
00202 M(i,0) = 1.;
00203 if (i>0) M(0,i) = 0.;
00204 }
00205 for (Int_t i=1; i<_mref->GetNrows(); ++i) {
00206 for (Int_t j=1; j<_mref->GetNrows(); ++j) {
00207 M(i,j) = TMath::Power((*dm)[i],(double)j);
00208 }
00209 }
00210 (*_M) = M.Invert();
00211
00212 delete dm ;
00213 }
00214
00215
00216 RooMomentMorph::CacheElem* RooMomentMorph::getCache(const RooArgSet* nset) const
00217 {
00218 CacheElem* cache = (CacheElem*) _cacheMgr.getObj(nset,(RooArgSet*)0) ;
00219 if (cache) {
00220 return cache ;
00221 }
00222 Int_t nVar = _varList.getSize();
00223 Int_t nPdf = _pdfList.getSize();
00224
00225 RooAbsReal* null = 0 ;
00226 vector<RooAbsReal*> meanrv(nPdf*nVar,null);
00227 vector<RooAbsReal*> sigmarv(nPdf*nVar,null);
00228 vector<RooAbsReal*> myrms(nVar,null);
00229 vector<RooAbsReal*> mypos(nVar,null);
00230 vector<RooAbsReal*> slope(nPdf*nVar,null);
00231 vector<RooAbsReal*> offset(nPdf*nVar,null);
00232 vector<RooAbsReal*> transVar(nPdf*nVar,null);
00233 vector<RooAbsReal*> transPdf(nPdf,null);
00234
00235 RooArgSet ownedComps ;
00236
00237 RooArgList fracl ;
00238
00239
00240 RooArgList coefList("coefList");
00241 RooArgList coefList2("coefList2");
00242 for (Int_t i=0; i<2*nPdf; ++i) {
00243 std::string fracName = Form("frac_%d",i);
00244 fracl.add(*new RooRealVar(fracName.c_str(),fracName.c_str(),1.));
00245 if (i<nPdf) coefList.add(*(RooRealVar*)(fracl.at(i))) ;
00246 else coefList2.add(*(RooRealVar*)(fracl.at(i))) ;
00247 ownedComps.add(*(RooRealVar*)(fracl.at(i))) ;
00248 }
00249
00250 RooArgList varList(_varList) ;
00251 for (Int_t i=0; i<nPdf; ++i) {
00252 for (Int_t j=0; j<nVar; ++j) {
00253
00254 std::string meanName = Form("%s_mean_%d_%d",GetName(),i,j);
00255 std::string sigmaName = Form("%s_sigma_%d_%d",GetName(),i,j);
00256
00257
00258
00259
00260 RooMoment* mom = nset ? ((RooAbsPdf*)_pdfList.at(i))->sigma((RooRealVar&)*varList.at(j),*nset)
00261 : ((RooAbsPdf*)_pdfList.at(i))->sigma((RooRealVar&)*varList.at(j)) ;
00262
00263 sigmarv[ij(i,j)] = mom ;
00264 meanrv[ij(i,j)] = mom->mean() ;
00265
00266 ownedComps.add(*sigmarv[ij(i,j)]) ;
00267 }
00268 }
00269
00270 for (Int_t j=0; j<nVar; ++j) {
00271 RooArgList meanList("meanList");
00272 RooArgList rmsList("rmsList");
00273 for (Int_t i=0; i<nPdf; ++i) {
00274 meanList.add(*meanrv[ij(i,j)]);
00275 rmsList.add(*sigmarv[ij(i,j)]);
00276 }
00277 std::string myrmsName = Form("%s_rms_%d",GetName(),j);
00278 std::string myposName = Form("%s_pos_%d",GetName(),j);
00279 myrms[j] = new RooAddition(myrmsName.c_str(),myrmsName.c_str(),rmsList,coefList2);
00280 mypos[j] = new RooAddition(myposName.c_str(),myposName.c_str(),meanList,coefList2);
00281 ownedComps.add(RooArgSet(*myrms[j],*mypos[j])) ;
00282 }
00283
00284 _pdfItr->Reset();
00285 RooAbsPdf* pdf;
00286 RooArgList transPdfList;
00287
00288 for (Int_t i=0; i<nPdf; ++i) {
00289 _varItr->Reset() ;
00290 RooRealVar* var ;
00291
00292 pdf = (RooAbsPdf*)_pdfItr->Next();
00293 std::string pdfName = Form("pdf_%d",i);
00294 RooCustomizer cust(*pdf,pdfName.c_str());
00295
00296 for (Int_t j=0; j<nVar; ++j) {
00297
00298 std::string slopeName = Form("%s_slope_%d_%d",GetName(),i,j);
00299 std::string offsetName = Form("%s_offset_%d_%d",GetName(),i,j);
00300 slope[ij(i,j)] = new RooFormulaVar(slopeName.c_str(),"@0/@1",RooArgList(*sigmarv[ij(i,j)],*myrms[j]));
00301 offset[ij(i,j)] = new RooFormulaVar(offsetName.c_str(),"@0-(@1*@2)",RooArgList(*meanrv[ij(i,j)],*mypos[j],*slope[ij(i,j)]));
00302 ownedComps.add(RooArgSet(*slope[ij(i,j)],*offset[ij(i,j)])) ;
00303
00304 var = (RooRealVar*)(_varItr->Next());
00305 std::string transVarName = Form("%s_transVar_%d_%d",GetName(),i,j);
00306
00307 transVar[ij(i,j)] = new RooLinearVar(transVarName.c_str(),transVarName.c_str(),*var,*slope[ij(i,j)],*offset[ij(i,j)]);
00308
00309 ownedComps.add(*transVar[ij(i,j)]) ;
00310 cust.replaceArg(*var,*transVar[ij(i,j)]);
00311 }
00312 transPdf[i] = (RooAbsPdf*) cust.build() ;
00313 transPdfList.add(*transPdf[i]);
00314 ownedComps.add(*transPdf[i]) ;
00315 }
00316
00317
00318 std::string sumpdfName = Form("%s_sumpdf",GetName());
00319
00320
00321 RooAbsPdf* theSumPdf = new RooAddPdf(sumpdfName.c_str(),sumpdfName.c_str(),transPdfList,coefList);
00322 theSumPdf->addOwnedComponents(ownedComps) ;
00323
00324
00325 std::string trackerName = Form("%s_frac_tracker",GetName()) ;
00326 RooChangeTracker* tracker = new RooChangeTracker(trackerName.c_str(),trackerName.c_str(),m.arg(),kTRUE) ;
00327
00328
00329
00330 cache = new CacheElem(*theSumPdf,*tracker,fracl) ;
00331 _cacheMgr.setObj(nset,0,cache,0) ;
00332
00333 return cache ;
00334 }
00335
00336
00337
00338
00339 RooArgList RooMomentMorph::CacheElem::containedArgs(Action)
00340 {
00341 return RooArgList(*_sumPdf,*_tracker) ;
00342 }
00343
00344
00345
00346
00347 RooMomentMorph::CacheElem::~CacheElem()
00348 {
00349 delete _sumPdf ;
00350 delete _tracker ;
00351 }
00352
00353
00354
00355
00356 Double_t RooMomentMorph::getVal(const RooArgSet* set) const
00357 {
00358
00359 _curNormSet = set ? (RooArgSet*)set : (RooArgSet*)&_varList ;
00360 return RooAbsPdf::getVal(set) ;
00361 }
00362
00363
00364
00365
00366 RooAbsPdf* RooMomentMorph::sumPdf(const RooArgSet* nset)
00367 {
00368 CacheElem* cache = getCache(nset ? nset : _curNormSet) ;
00369
00370 if (cache->_tracker->hasChanged(kTRUE)) {
00371 cache->calculateFractions(*this,kFALSE);
00372 }
00373
00374 return cache->_sumPdf ;
00375 }
00376
00377
00378
00379 Double_t RooMomentMorph::evaluate() const
00380 {
00381 CacheElem* cache = getCache(_curNormSet) ;
00382
00383 if (cache->_tracker->hasChanged(kTRUE)) {
00384 cache->calculateFractions(*this,kFALSE);
00385 }
00386
00387 Double_t ret = cache->_sumPdf->getVal(_pdfList.nset());
00388 return ret ;
00389 }
00390
00391
00392 RooRealVar* RooMomentMorph::CacheElem::frac(Int_t i )
00393 {
00394 return (RooRealVar*)(_frac.at(i)) ;
00395 }
00396
00397
00398
00399
00400 const RooRealVar* RooMomentMorph::CacheElem::frac(Int_t i ) const
00401 {
00402 return (RooRealVar*)(_frac.at(i)) ;
00403 }
00404
00405
00406
00407 void RooMomentMorph::CacheElem::calculateFractions(const RooMomentMorph& self, Bool_t verbose) const
00408 {
00409 Int_t nPdf = self._pdfList.getSize();
00410
00411 Double_t dm = self.m - (*self._mref)[0];
00412
00413
00414 double sumposfrac=0.;
00415 for (Int_t i=0; i<nPdf; ++i) {
00416 double ffrac=0.;
00417 for (Int_t j=0; j<nPdf; ++j) { ffrac += (*self._M)(j,i) * (j==0?1.:TMath::Power(dm,(double)j)); }
00418 if (ffrac>=0) sumposfrac+=ffrac;
00419
00420 ((RooRealVar*)frac(i))->setVal(ffrac);
00421
00422 ((RooRealVar*)frac(nPdf+i))->setVal(ffrac);
00423 if (verbose) { cout << ffrac << endl; }
00424 }
00425
00426
00427 int imin = self.idxmin(self.m);
00428 int imax = self.idxmax(self.m);
00429 double mfrac = (self.m-(*self._mref)[imin])/((*self._mref)[imax]-(*self._mref)[imin]);
00430 switch (self._setting) {
00431 case NonLinear:
00432
00433 break;
00434 case Linear:
00435 for (Int_t i=0; i<2*nPdf; ++i)
00436 ((RooRealVar*)frac(i))->setVal(0.);
00437 if (imax>imin) {
00438 ((RooRealVar*)frac(imin))->setVal(1.-mfrac);
00439 ((RooRealVar*)frac(nPdf+imin))->setVal(1.-mfrac);
00440 ((RooRealVar*)frac(imax))->setVal(mfrac);
00441 ((RooRealVar*)frac(nPdf+imax))->setVal(mfrac);
00442 } else if (imax==imin) {
00443 ((RooRealVar*)frac(imin))->setVal(1.);
00444 ((RooRealVar*)frac(nPdf+imin))->setVal(1.);
00445 }
00446 break;
00447 case NonLinearLinFractions:
00448 for (Int_t i=0; i<nPdf; ++i)
00449 ((RooRealVar*)frac(i))->setVal(0.);
00450 if (imax>imin) {
00451 ((RooRealVar*)frac(imin))->setVal(1.-mfrac);
00452 ((RooRealVar*)frac(imax))->setVal(mfrac);
00453 } else if (imax==imin) {
00454 ((RooRealVar*)frac(imin))->setVal(1.);
00455 }
00456 break;
00457 case NonLinearPosFractions:
00458 for (Int_t i=0; i<nPdf; ++i) {
00459 if (((RooRealVar*)frac(i))->getVal()<0) ((RooRealVar*)frac(i))->setVal(0.);
00460 ((RooRealVar*)frac(i))->setVal(((RooRealVar*)frac(i))->getVal()/sumposfrac);
00461 }
00462 break;
00463 }
00464
00465 }
00466
00467
00468 int RooMomentMorph::idxmin(const double& mval) const
00469 {
00470 int imin(0);
00471 Int_t nPdf = _pdfList.getSize();
00472 double mmin=-DBL_MAX;
00473 for (Int_t i=0; i<nPdf; ++i)
00474 if ( (*_mref)[i]>mmin && (*_mref)[i]<=mval ) { mmin=(*_mref)[i]; imin=i; }
00475 return imin;
00476 }
00477
00478
00479
00480 int RooMomentMorph::idxmax(const double& mval) const
00481 {
00482 int imax(0);
00483 Int_t nPdf = _pdfList.getSize();
00484 double mmax=DBL_MAX;
00485 for (Int_t i=0; i<nPdf; ++i)
00486 if ( (*_mref)[i]<mmax && (*_mref)[i]>=mval ) { mmax=(*_mref)[i]; imax=i; }
00487 return imax;
00488 }
00489
00490
00491