rarSPlot.cc

Go to the documentation of this file.
00001 /*****************************************************************************
00002 * Project: BaBar detector at the SLAC PEP-II B-factory
00003 * Package: RooRarFit
00004  *    File: $Id: rarSPlot.cc,v 1.12 2011/06/16 13:18:50 fwilson Exp $
00005  * Authors: Lei Zhang
00006  * History:
00007  *
00008  * Copyright (C) 2005-2012, University of California, Riverside
00009  *****************************************************************************/
00010 
00011 // -- CLASS DESCRIPTION [RooRarFit] --
00012 // This class provides sPlot class for RooRarFit
00014 //
00015 // BEGIN_HTML
00016 // This class provides sPlot class for RooRarFit
00017 // END_HTML
00018 //
00019 
00020 #include "RooRarFit/rarVersion.hh"
00021 
00022 #include "RooRarFit/rarSPlot.hh"
00023 #include "RooFitCore/RooAbsPdf.hh"
00024 
00025 #include "TMatrixD.h"
00026 using std::cout;
00027 using std::endl;
00028 
00029 ClassImp(rarSPlot) ;
00030 
00034 rarSPlot::rarSPlot() :
00035   TNamed(),
00036   _obs(0), _fitRes(0),
00037   _nComps(0), _nComp0s(0), _idxMap(0), _covM(0,0), _iV(0,0), _V(0,0),
00038   _sHist(0), _sData(0),
00039   _verbose(kFALSE)
00040 {
00041   // Default constructor
00042 }
00043 
00059 rarSPlot::rarSPlot(const char* name, const char *title, RooAbsReal *obs,
00060                    RooDataSet &data, RooFitResult *fitRes,
00061                    const RooArgList &pdfs, const RooArgList &yields,
00062                    const RooArgList &pdf0s, const RooArgList &yield0s,
00063                    const RooArgSet &projDeps, const Bool_t verbose) :
00064   TNamed(name, title),
00065   _obs(obs), _data(data), _nEvts(_data.numEntries()),
00066   _fitRes(fitRes), _fitPars(fitRes->floatParsFinal()),
00067   _pdfs(pdfs), _yields(yields), _pdf0s(pdf0s), _yield0s(yield0s),
00068   _projDeps(projDeps), _normVars(*pdfs[0].getDependents(&data)),
00069   _nComps(0), _nComp0s(0), _idxMap(0), _covM(0,0), _iV(0,0), _V(0,0),
00070   _sHist(0), _sData(0),
00071   _verbose(verbose)
00072 {
00073   init();
00074 }
00075 
00077 rarSPlot::~rarSPlot()
00078 {
00079 }
00080 
00084 void rarSPlot::init()
00085 {
00086   
00087   if (_verbose) {
00088     cout<<" rarSPlot:  yields:"<<endl;
00089     _yields.Print();
00090     cout<<" pdfs:"<<endl;
00091     _pdfs.Print();
00092     cout<<" data:"<<endl;
00093     _data.Print();
00094     //_data.Print("v");
00095     cout<<endl;
00096   }
00097   
00098   _nComps=_yields.getSize();
00099   if (_nComps<=0) {
00100     cout<<" No comp found"<<endl;
00101     _nComps=0;
00102     return;
00103   }
00104   if (_pdfs.getSize()!=_nComps) {
00105     cout<<" The size of yields and pdfs do not match"<<endl;
00106     _nComps=0;
00107     return;
00108   }
00109   if (_fitPars.getSize()!=_nComps) {
00110     cout<<" The size of yields and floating params do not match"<<endl;
00111     _yields.Print();
00112     _fitPars.Print();
00113     _nComps=0;
00114     return;
00115   }
00116   _nComp0s=_yield0s.getSize();
00117   if (_pdf0s.getSize()!=_nComp0s) {
00118     cout<<" The size of yield0s and pdf0s do not match"<<endl;
00119     _nComps=0;
00120     return;
00121   }
00122   if ((_nComp0s!=0)&&_verbose) {
00123     cout<<" yield0s:"<<endl;
00124     _yield0s.Print();
00125     cout<<" pdf0s:"<<endl;
00126     _pdf0s.Print();
00127     cout<<endl;
00128   }
00129 
00130   // Set the right size
00131   _idxMap.Set(_nComps);
00132   _covM.ResizeTo(_nComps, _nComps);
00133   _iV.ResizeTo(_nComps, _nComps);
00134   _V.ResizeTo(_nComps, _nComps);
00135   
00136   // Remember, the order of finalPars is not necessarily the same
00137   // as in #_yields, and we'd better map between them
00138   for (Int_t i=0; i<_nComps; i++) {
00139     RooAbsArg *theYield(0);
00140     if(theYield=_yields.find(_fitPars[i].GetName()))
00141       _idxMap[i]=_yields.index(theYield);
00142     else {
00143       cout<<" Can not find "<<_fitPars[i].GetName()
00144           <<" in yields:"<<endl;
00145       _yields.Print();
00146       _nComps=0;
00147       return;
00148     }
00149     if (_verbose)
00150       cout<<" fitPar #"<<i<<" --> yield #"<<_idxMap[i]
00151           <<" "<<_fitPars[i].GetName()<<endl;
00152   }
00153   if (_verbose) cout<<endl;
00154   
00155   // normalization ignored obs
00156   // The list of variables to normalize over when calculating PDF values.
00157   _normVars.remove(_projDeps, kTRUE, kTRUE);
00158   if (_verbose) {
00159     cout<<" Normalization variables" << endl;
00160     _normVars.Print();
00161     cout<<" Norm ignored variables"<<endl;
00162     _projDeps.Print();
00163     cout<<endl;
00164   }
00165 
00166   // create full snapshot
00167   RooArgList *pdfs=(RooArgList*)_pdfs.snapshot();
00168   RooArgList *yields=(RooArgList*)_yields.snapshot();
00169   RooArgList *pdf0s=(RooArgList*)_pdf0s.snapshot();
00170   RooArgList *yield0s=(RooArgList*)_yield0s.snapshot();
00171   _pdfs.removeAll();
00172   _pdfs.add(*pdfs);
00173   _yields.removeAll();
00174   _yields.add(*yields);
00175   _pdf0s.removeAll();
00176   _pdf0s.add(*pdf0s);
00177   _yield0s.removeAll();
00178   _yield0s.add(*yield0s);
00179   // attach dataset
00180   for (Int_t i = 0; i<_nComps; i++) {
00181     RooAbsPdf *pdf = (RooAbsPdf*)_pdfs.at(_idxMap[i]);
00182     pdf->attachDataSet(_data);
00183   }
00184   for (Int_t i = 0; i<_nComp0s; i++) {
00185     RooAbsPdf *pdf = (RooAbsPdf*)_pdf0s.at(i);
00186     pdf->attachDataSet(_data);
00187   }
00188   
00189   // Loop over all the parameters to make the covariance matrix.
00190   for (Int_t i=0; i<_nComps; i++) {
00191     for (Int_t j=0; j<_nComps; j++) {
00192       const RooRealVar *rowVar= (const RooRealVar*)_fitPars.at(i);
00193       const RooRealVar *colVar= (const RooRealVar*)_fitPars.at(j);
00194       assert(0 != rowVar && 0 != colVar);
00195       _covM(i,j) = rowVar->getError()*colVar->getError()
00196         *_fitRes->correlation(rowVar->GetName(),colVar->GetName());
00197       _V(i,j)=_covM(i,j);
00198     }
00199   }
00200   
00201   // Get the inverse of the covariance matrix
00202   // First check if it's singular
00203   if (_covM.Determinant() == 0) {
00204     cout << "rarSPlot Error: covariance matrix is singular;"
00205          << " I can't invert it!" << endl;
00206     _covM.Print();
00207     _nComps=0;
00208     return;
00209   }
00210   _iV=TMatrixD(TMatrixD::kInverted, _V);
00211   
00212   if (_verbose) {
00213     cout << "Covariance matrix:" << endl;
00214     _V.Print();
00215     cout << "Inverse of covariance matrix:" << endl;
00216     _iV.Print();
00217   }
00218   
00219   // calculate all denominators
00220   _dens.Set(_nEvts);
00221   cout<<" calculate denominators ";
00222   for (Int_t ievt=0; ievt<_nEvts; ievt++) {
00223     if (_verbose&&ievt%1000==0) {
00224       cout << ".";
00225       cout.flush();
00226     }
00227     _data.get(ievt);
00228     _dens[ievt]=0;
00229     for (Int_t k=0; k<_nComps; k++) {
00230       _dens[ievt]+=((RooAbsReal*)_yields.at(_idxMap[k]))->getVal()*
00231         ((RooAbsPdf*)_pdfs.at(_idxMap[k]))->getVal(&_normVars);
00232       if (0==((RooAbsPdf*)_pdfs.at(_idxMap[k]))->getVal(&_normVars)) {
00233         _data.get(ievt);
00234         _dens[ievt]+=((RooAbsReal*)_yields.at(_idxMap[k]))->getVal()*
00235           ((RooAbsPdf*)_pdfs.at(_idxMap[k]))->getVal(&_normVars);
00236       }
00237     }
00238     for (Int_t k=0; k<_nComp0s; k++) {
00239       _dens[ievt]+=((RooAbsReal*)_yield0s.at(k))->getVal()*
00240         ((RooAbsPdf*)_pdf0s.at(k))->getVal(&_normVars);
00241     }
00242   }
00243   cout<<endl;
00244   
00245   // init _sPns
00246   _sPns.Set((_nComps+1)*_nEvts);
00247   _sPnb.Set(_nComps+1);
00248   _sPnb.Reset();
00249   
00250   if (_nComp0s>0) {
00251     // now using eqn 15 in BAD 509 to calculate #_iV
00252     for (Int_t i=0; i<_nComps; i++) {
00253       RooAbsPdf *fi=(RooAbsPdf*)_pdfs.at(_idxMap[i]);
00254       for (Int_t j=i; j<_nComps; j++) {
00255         RooAbsPdf *fj=(RooAbsPdf*)_pdfs.at(_idxMap[j]);
00256         Double_t iVij(0);
00257         for(Int_t ievt=0; ievt<_nEvts; ievt++) {
00258           _data.get(ievt);
00259           iVij+=fi->getVal(&_normVars)*fj->getVal(&_normVars)
00260             /_dens[ievt]/_dens[ievt];
00261         }
00262         _iV(i,j)=iVij;
00263       }
00264     }
00265     for (Int_t i=0; i<_nComps; i++) {
00266       for (Int_t j=0; j<i; j++) {
00267         _iV(i,j)=_iV(j,i);
00268       }
00269     }
00270     
00271     _V=TMatrixD(TMatrixD::kInverted, _iV);
00272     
00273     if (_verbose) {
00274       cout << "Covariance matrix:" << endl;
00275       _V.Print();
00276       cout << "Inverse of covariance matrix:" << endl;
00277       _iV.Print();
00278     }
00279     
00280     // get sP0
00281     fillsPn(_nComps);
00282   }
00283 }
00284 
00287 void rarSPlot::fillsPn(Int_t compIdx)
00288 {
00289   if ((compIdx>_nComps)||(compIdx<0)) {
00290     cout<<" Invalid comp index "<<compIdx<<endl;
00291     return;
00292   }
00293   // check if done already
00294   if (_sPnb[compIdx]) return;
00295   if (compIdx==_nComps) {
00296     // fill sPn's
00297     for (Int_t i=0; i<_nComps; i++) {
00298       fillsPn(i);
00299     }
00300     // fill sP0
00301     cout<<" fill sP0 ";
00302     for (Int_t i=0; i<_nEvts; i++) {
00303       if (_verbose&&i%1000==0) {
00304         cout << ".";
00305         cout.flush();
00306       }
00307       _sPns[compIdx*_nEvts+i]=1;
00308       for (Int_t j=0; j<_nComps; j++) {
00309         _sPns[compIdx*_nEvts+i]-=_sPns[j*_nEvts+i];
00310       }
00311     }
00312   } else {
00313     // fill sPn
00314     cout<<" fill sPn for fitPar #"<<compIdx
00315         <<" "<<_fitPars[compIdx].GetName()<<" ";
00316     for (Int_t i=0; i<_nEvts; i++) {
00317       if (_verbose&&i%1000==0) {
00318         cout << ".";
00319         cout.flush();
00320       }
00321       _data.get(i);
00322       Double_t numerator=0.;
00323       for (Int_t j=0; j<_nComps; j++) {
00324         numerator+=_V(compIdx,j)*
00325           ((RooAbsPdf*)_pdfs.at(_idxMap[j]))->getVal(&_normVars);
00326       }
00327       _sPns[compIdx*_nEvts+i]=numerator/_dens[i];
00328     }
00329   }
00330   cout<<endl;
00331   
00332   _sPnb[compIdx]=1;
00333   return;
00334 }
00335 
00345 RooDataSet* rarSPlot::fill(RooAbsReal &yield, Int_t nbins,
00346                            Double_t min, Double_t max, Bool_t doErrors)
00347 {
00348   if (_nComps<=0) {
00349     _sHist=0;
00350     _sData=0;
00351     return 0;
00352   }
00353   
00354   // create sPlot histogram
00355   TString histName=Form("hist_%s_%s",GetName(), yield.GetName());
00356   _sHist=new TH1F(histName, histName, nbins, min, max);
00357   // Size of bins...
00358   Double_t binSize = (max-min)/nbins;
00359   if (_verbose) {
00360     cout <<" SPlot histogram bins: " << min << " to " << max
00361          <<" with " << nbins << " bins."
00362          <<" binSize = " << binSize << endl;
00363   }
00364   
00365   Int_t istar=_fitPars.index(_fitPars.find(yield.GetName()));
00366   // get sPns
00367   fillsPn(istar);
00368   if (_verbose) {
00369     Double_t sum = 0;
00370     for (Int_t j=0; j<_nComps; j++) {
00371       sum += _V(j,istar);
00372     }
00373     cout <<" Sum of star column in V: " << sum << endl
00374          <<" fitted yield "<<yield.GetName()<<" = "<<yield.getVal()<<endl;
00375   }
00376   // add a weight column to the dataset
00377   RooArgSet obs = *_data.get();
00378   RooRealVar evtWgt("evtWgt", "Weight for sPlot entry", 1.);
00379   obs.add(evtWgt); // add weight to list of observables
00380   _sData = new RooDataSet("sPlotData", "sPlotData", obs, "evtWgt");
00381   
00382   Double_t sum = 0;
00383   Double_t sumtmp = 0;
00384   // This forces the error in a bin to be calculated
00385   // as the sqrt of the sum of the squares of weights, as they should be.
00386   if (doErrors) _sHist->Sumw2();
00387   
00388   Double_t Nstar= yield.getVal();
00389   Double_t Vstar=0;
00390   for (Int_t j=0; j<_nComps; j++) {
00391     Vstar+=_V(istar, j);
00392   }
00393   Double_t Vsum=0;
00394   for(Int_t i=0; i<_nComps; i++) {
00395     for (Int_t j=0; j<_nComps; j++) {
00396       Vsum+=_V(i,j);
00397     }
00398   }
00399   Double_t Nratio=(Nstar-Vstar)/(_nEvts-Vsum);
00400   Double_t Nratio2=(Nstar-Vstar)*Nratio;
00401   if (_nComp0s>0) cout<<" Nratio = "<<Nratio<<" \tNratio2 = "<<Nratio2<<endl;
00402   cout<<" loop over dataset to fill sPlot ";
00403   //_data.write("/tmp/sd.txt");
00404   for (Int_t ievt=0; ievt<_nEvts; ievt++) {
00405     if (_verbose&&ievt%1000==0) {
00406       cout << ".";
00407       cout.flush();
00408     }
00409     // Read this event and find the value of x for this event.
00410     const RooArgSet *row=_data.get(ievt);
00411     Double_t obsVal = ((RooAbsReal*)row->find(_obs->GetName()))->getVal();
00412     Double_t p=1/Nstar*_sPns[istar*_nEvts+ievt];
00413     if (_nComp0s>0) {
00414       p=1/Nstar*(_sPns[istar*_nEvts+ievt]+Nratio*_sPns[_nComps*_nEvts+ievt]);
00415     }
00416     sumtmp += ((RooAbsPdf*)_pdfs.at(istar))->getVal(&_normVars)/_dens[ievt];
00417     
00418     //if (obsVal > min && obsVal < max)
00419     sum += p*Nstar;
00420     
00421     // Add weighted event to the sPlot histogram
00422     _sHist->Fill(obsVal, p*Nstar);
00423     // ... and to the dataSet
00424     _sData->add(*row, p*Nstar);
00425     
00426   }// end event loop
00427   cout<<endl;
00428   
00429   _sHist->SetEntries(sum*Double_t(binSize));
00430   
00431   if (_verbose)
00432     cout << " Entries should be: " << sum*Double_t(binSize)
00433          << " (" << sum << " events)" << endl
00434          << " Sum of likelihood ratios for nstar: " << sumtmp << endl;
00435   
00436   return _sData;
00437 }

Generated on 30 Oct 2013 for RooRarFit by  doxygen 1.4.7