RooMomentMorph.cxx

Go to the documentation of this file.
00001 /***************************************************************************** 
00002  * Project: RooFit                                                           * 
00003  *                                                                           * 
00004  * This code was autogenerated by RooClassFactory                            * 
00005  *****************************************************************************/ 
00006 
00007 // Your description goes here... 
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   // coverity[UNINIT_CTOR]
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   // CTOR
00054 
00055   // observables
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   // reference p.d.f.s
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   // initialization
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   // CTOR
00104 
00105   // observables
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   // reference p.d.f.s
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   // reference points in m
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   // initialization
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   // initialization
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   // other quantities needed
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   // transformation matrix for non-linear extrapolation, needed in evaluate()
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   // fraction parameters
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.)); // to be set later 
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   // mean and sigma
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 //       cout << "RooMomentMorph::getCache(" << GetName() << ") nset = " << (nset?*nset:RooArgSet()) << " creating moment for pdf "
00258 //         << _pdfList.at(i)->GetName() << " for observable " << varList.at(j)->GetName() << endl ;
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   // slope and offset (to be set later, depend on m)
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   // construction of unit pdfs
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       // slope and offset formulas
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       // linear transformations, so pdf can be renormalized
00304       var = (RooRealVar*)(_varItr->Next());
00305       std::string transVarName = Form("%s_transVar_%d_%d",GetName(),i,j);
00306       //transVar[ij(i,j)] = new RooFormulaVar(transVarName.c_str(),transVarName.c_str(),"@0*@1+@2",RooArgList(*var,*slope[ij(i,j)],*offset[ij(i,j)]));
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   // sum pdf
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   // change tracker for fraction parameters
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   // Store it in the cache
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   // Special version of getVal() overrides RooAbsReal::getVal() to save value of current normalization set
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); // verbose turned off
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); // verbose turned off
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   // fully non-linear
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     // fractions for pdf
00420     ((RooRealVar*)frac(i))->setVal(ffrac);
00421     // fractions for rms and mean
00422     ((RooRealVar*)frac(nPdf+i))->setVal(ffrac);
00423     if (verbose) { cout << ffrac << endl; }
00424   }
00425 
00426   // various mode settings
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       // default already set above
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) { // m in between mmin and mmax
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) { // m outside mmin and mmax
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) { // m in between mmin and mmax
00451         ((RooRealVar*)frac(imin))->setVal(1.-mfrac);
00452         ((RooRealVar*)frac(imax))->setVal(mfrac);
00453       } else if (imax==imin) { // m outside mmin and mmax
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 

Generated on Tue Jul 5 14:55:16 2011 for ROOT_528-00b_version by  doxygen 1.5.1