// RooAbsData is the common abstract base class for binned and unbinned
// datasets. The abstract interface defines plotting and tabulating entry
// points for its contents and provides an iterator over its elements
// (bins for binned data sets, data points for unbinned datasets).
// END_HTML
#include "RooFit.h"
#include "Riostream.h"
#include "TClass.h"
#include "TMath.h"
#include "RooAbsData.h"
#include "RooAbsData.h"
#include "RooFormulaVar.h"
#include "RooCmdConfig.h"
#include "RooAbsRealLValue.h"
#include "RooMsgService.h"
#include "RooMultiCategory.h"
#include "Roo1DTable.h"
#include "RooAbsDataStore.h"
#include "RooVectorDataStore.h"
#include "RooTreeDataStore.h"
#include "RooDataHist.h"
#include "RooCompositeDataStore.h"
#include "RooCategory.h"
#include "RooTrace.h"
#include "RooRealVar.h"
#include "RooGlobalFunc.h"
#include "RooPlot.h"
#include "RooCurve.h"
#include "RooHist.h"
#include "TMatrixDSym.h"
#include "TPaveText.h"
#include "TH1.h"
#include "TH2.h"
#include "TH3.h"
using namespace std;
ClassImp(RooAbsData)
;
static std::map<RooAbsData*,int> _dcc ;
RooAbsData::StorageType RooAbsData::defaultStorageType=RooAbsData::Vector ;
void RooAbsData::setDefaultStorageType(RooAbsData::StorageType s)
{
defaultStorageType = s ;
}
RooAbsData::StorageType RooAbsData::getDefaultStorageType( )
{
return defaultStorageType;
}
void RooAbsData::claimVars(RooAbsData* data)
{
_dcc[data]++ ;
}
Bool_t RooAbsData::releaseVars(RooAbsData* data)
{
if (_dcc[data]>0) {
_dcc[data]-- ;
}
return (_dcc[data]==0) ;
}
RooAbsData::RooAbsData()
{
claimVars(this) ;
_dstore = 0 ;
_iterator = _vars.createIterator() ;
_cacheIter = _cachedVars.createIterator() ;
RooTrace::create(this) ;
}
RooAbsData::RooAbsData(const char *name, const char *title, const RooArgSet& vars, RooAbsDataStore* dstore) :
TNamed(name,title), _vars("Dataset Variables"), _cachedVars("Cached Variables"), _dstore(dstore)
{
claimVars(this) ;
TIterator* iter = vars.createIterator() ;
RooAbsArg *var;
while((0 != (var= (RooAbsArg*)iter->Next()))) {
if (!var->isFundamental()) {
coutE(InputArguments) << "RooAbsDataStore::initialize(" << GetName()
<< "): Data set cannot contain non-fundamental types, ignoring "
<< var->GetName() << endl ;
} else {
_vars.addClone(*var);
}
}
delete iter ;
iter = _vars.createIterator() ;
while((0 != (var= (RooAbsArg*)iter->Next()))) {
var->attachDataSet(*this) ;
}
delete iter ;
_iterator= _vars.createIterator();
_cacheIter = _cachedVars.createIterator() ;
RooTrace::create(this) ;
}
RooAbsData::RooAbsData(const RooAbsData& other, const char* newname) :
TNamed(newname?newname:other.GetName(),other.GetTitle()),
RooPrintable(other), _vars(),
_cachedVars("Cached Variables")
{
claimVars(this) ;
_vars.addClone(other._vars) ;
TIterator* iter = _vars.createIterator() ;
RooAbsArg* var ;
while((0 != (var= (RooAbsArg*)iter->Next()))) {
var->attachDataSet(*this) ;
}
delete iter ;
_iterator= _vars.createIterator();
_cacheIter = _cachedVars.createIterator() ;
if (other._ownedComponents.size()>0) {
map<string,RooAbsDataStore*> smap ;
for (std::map<std::string,RooAbsData*>::const_iterator itero =other._ownedComponents.begin() ; itero!=other._ownedComponents.end() ; ++itero ) {
RooAbsData* dclone = (RooAbsData*) itero->second->Clone() ;
_ownedComponents[itero->first] = dclone ;
smap[itero->first] = dclone->store() ;
}
RooCategory* idx = (RooCategory*) _vars.find(*((RooCompositeDataStore*)other.store())->index()) ;
_dstore = new RooCompositeDataStore(newname?newname:other.GetName(),other.GetTitle(),_vars,*idx,smap) ;
} else {
_dstore = other._dstore->clone(_vars,newname?newname:other.GetName()) ;
}
RooTrace::create(this) ;
}
RooAbsData::~RooAbsData()
{
if (releaseVars(this)) {
} else {
_vars.releaseOwnership() ;
}
delete _dstore ;
delete _iterator ;
delete _cacheIter ;
for(map<std::string,RooAbsData*>::iterator iter = _ownedComponents.begin() ; iter!= _ownedComponents.end() ; ++iter) {
delete iter->second ;
}
RooTrace::destroy(this) ;
}
void RooAbsData::convertToVectorStore()
{
if (dynamic_cast<RooTreeDataStore*>(_dstore)) {
RooVectorDataStore* newStore = new RooVectorDataStore(*(RooTreeDataStore*)_dstore,_vars,GetName()) ;
delete _dstore ;
_dstore = newStore ;
}
}
Bool_t RooAbsData::changeObservableName(const char* from, const char* to)
{
Bool_t ret = _dstore->changeObservableName(from,to) ;
RooAbsArg* tmp = _vars.find(from) ;
if (tmp) {
tmp->SetName(to) ;
}
return ret ;
}
void RooAbsData::fill()
{
_dstore->fill() ;
}
Int_t RooAbsData::numEntries() const
{
return _dstore->numEntries() ;
}
void RooAbsData::reset()
{
_dstore->reset() ;
}
const RooArgSet* RooAbsData::get(Int_t index) const
{
checkInit() ;
return _dstore->get(index) ;
}
void RooAbsData::cacheArgs(const RooAbsArg* cacheOwner, RooArgSet& varSet, const RooArgSet* nset, Bool_t skipZeroWeights)
{
_dstore->cacheArgs(cacheOwner,varSet,nset,skipZeroWeights) ;
}
void RooAbsData::resetCache()
{
_dstore->resetCache() ;
_cachedVars.removeAll() ;
}
void RooAbsData::attachCache(const RooAbsArg* newOwner, const RooArgSet& cachedVars)
{
_dstore->attachCache(newOwner, cachedVars) ;
}
void RooAbsData::setArgStatus(const RooArgSet& set, Bool_t active)
{
_dstore->setArgStatus(set,active) ;
}
void RooAbsData::setDirtyProp(Bool_t flag)
{
_dstore->setDirtyProp(flag) ;
}
RooAbsData* RooAbsData::reduce(const RooCmdArg& arg1,const RooCmdArg& arg2,const RooCmdArg& arg3,const RooCmdArg& arg4,
const RooCmdArg& arg5,const RooCmdArg& arg6,const RooCmdArg& arg7,const RooCmdArg& arg8)
{
RooCmdConfig pc(Form("RooAbsData::reduce(%s)",GetName())) ;
pc.defineString("name","Name",0,"") ;
pc.defineString("title","Title",0,"") ;
pc.defineString("cutRange","CutRange",0,"") ;
pc.defineString("cutSpec","CutSpec",0,"") ;
pc.defineObject("cutVar","CutVar",0,0) ;
pc.defineInt("evtStart","EventRange",0,0) ;
pc.defineInt("evtStop","EventRange",1,2000000000) ;
pc.defineObject("varSel","SelectVars",0,0) ;
pc.defineMutex("CutVar","CutSpec") ;
pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
if (!pc.ok(kTRUE)) {
return 0 ;
}
const char* cutRange = pc.getString("cutRange",0,kTRUE) ;
const char* cutSpec = pc.getString("cutSpec",0,kTRUE) ;
RooFormulaVar* cutVar = static_cast<RooFormulaVar*>(pc.getObject("cutVar",0)) ;
Int_t nStart = pc.getInt("evtStart",0) ;
Int_t nStop = pc.getInt("evtStop",2000000000) ;
RooArgSet* varSet = static_cast<RooArgSet*>(pc.getObject("varSel")) ;
const char* name = pc.getString("name",0,kTRUE) ;
const char* title = pc.getString("title",0,kTRUE) ;
RooArgSet varSubset ;
if (varSet) {
varSubset.add(*varSet) ;
TIterator* iter = varSubset.createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
if (!_vars.find(arg->GetName())) {
coutW(InputArguments) << "RooAbsData::reduce(" << GetName() << ") WARNING: variable "
<< arg->GetName() << " not in dataset, ignored" << endl ;
varSubset.remove(*arg) ;
}
}
delete iter ;
} else {
varSubset.add(*get()) ;
}
RooAbsData* ret = 0 ;
if (cutSpec) {
RooFormulaVar cutVarTmp(cutSpec,cutSpec,*get()) ;
ret = reduceEng(varSubset,&cutVarTmp,cutRange,nStart,nStop,kFALSE) ;
} else if (cutVar) {
ret = reduceEng(varSubset,cutVar,cutRange,nStart,nStop,kFALSE) ;
} else {
ret = reduceEng(varSubset,0,cutRange,nStart,nStop,kFALSE) ;
}
if (!ret) return 0 ;
if (name) {
ret->SetName(name) ;
}
if (title) {
ret->SetTitle(title) ;
}
return ret ;
}
RooAbsData* RooAbsData::reduce(const char* cut)
{
RooFormulaVar cutVar(cut,cut,*get()) ;
return reduceEng(*get(),&cutVar,0,0,2000000000,kFALSE) ;
}
RooAbsData* RooAbsData::reduce(const RooFormulaVar& cutVar)
{
return reduceEng(*get(),&cutVar,0,0,2000000000,kFALSE) ;
}
RooAbsData* RooAbsData::reduce(const RooArgSet& varSubset, const char* cut)
{
RooArgSet varSubset2(varSubset) ;
TIterator* iter = varSubset.createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
if (!_vars.find(arg->GetName())) {
coutW(InputArguments) << "RooAbsData::reduce(" << GetName() << ") WARNING: variable "
<< arg->GetName() << " not in dataset, ignored" << endl ;
varSubset2.remove(*arg) ;
}
}
delete iter ;
if (cut && strlen(cut)>0) {
RooFormulaVar cutVar(cut,cut,*get()) ;
return reduceEng(varSubset2,&cutVar,0,0,2000000000,kFALSE) ;
}
return reduceEng(varSubset2,0,0,0,2000000000,kFALSE) ;
}
RooAbsData* RooAbsData::reduce(const RooArgSet& varSubset, const RooFormulaVar& cutVar)
{
RooArgSet varSubset2(varSubset) ;
TIterator* iter = varSubset.createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
if (!_vars.find(arg->GetName())) {
coutW(InputArguments) << "RooAbsData::reduce(" << GetName() << ") WARNING: variable "
<< arg->GetName() << " not in dataset, ignored" << endl ;
varSubset2.remove(*arg) ;
}
}
delete iter ;
return reduceEng(varSubset2,&cutVar,0,0,2000000000,kFALSE) ;
}
Double_t RooAbsData::weightError(ErrorType) const
{
return 0 ;
}
void RooAbsData::weightError(Double_t& lo, Double_t& hi, ErrorType) const
{
lo=0 ; hi=0 ;
}
RooPlot* RooAbsData::plotOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
{
RooLinkedList l ;
l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
return plotOn(frame,l) ;
}
TH1 *RooAbsData::createHistogram(const char* varNameList, Int_t xbins, Int_t ybins, Int_t zbins) const
{
char buf[1024] ;
strlcpy(buf,varNameList,1024) ;
char* varName = strtok(buf,",:") ;
RooRealVar* xvar = (RooRealVar*) get()->find(varName) ;
if (!xvar) {
coutE(InputArguments) << "RooAbsData::createHistogram(" << GetName() << ") ERROR: dataset does not contain an observable named " << varName << endl ;
return 0 ;
}
varName = strtok(0,",") ;
RooRealVar* yvar = varName ? (RooRealVar*) get()->find(varName) : 0 ;
if (varName && !yvar) {
coutE(InputArguments) << "RooAbsData::createHistogram(" << GetName() << ") ERROR: dataset does not contain an observable named " << varName << endl ;
return 0 ;
}
varName = strtok(0,",") ;
RooRealVar* zvar = varName ? (RooRealVar*) get()->find(varName) : 0 ;
if (varName && !zvar) {
coutE(InputArguments) << "RooAbsData::createHistogram(" << GetName() << ") ERROR: dataset does not contain an observable named " << varName << endl ;
return 0 ;
}
RooLinkedList argList ;
if (xbins<=0 || !xvar->hasMax() || !xvar->hasMin() ) {
argList.Add(RooFit::AutoBinning(xbins==0?xvar->numBins():abs(xbins)).Clone()) ;
} else {
argList.Add(RooFit::Binning(xbins).Clone()) ;
}
if (yvar) {
if (ybins<=0 || !yvar->hasMax() || !yvar->hasMin() ) {
argList.Add(RooFit::YVar(*yvar,RooFit::AutoBinning(ybins==0?yvar->numBins():abs(ybins))).Clone()) ;
} else {
argList.Add(RooFit::YVar(*yvar,RooFit::Binning(ybins)).Clone()) ;
}
}
if (zvar) {
if (zbins<=0 || !zvar->hasMax() || !zvar->hasMin() ) {
argList.Add(RooFit::ZVar(*zvar,RooFit::AutoBinning(zbins==0?zvar->numBins():abs(zbins))).Clone()) ;
} else {
argList.Add(RooFit::ZVar(*zvar,RooFit::Binning(zbins)).Clone()) ;
}
}
TH1* result = createHistogram(GetName(),*xvar,argList) ;
argList.Delete() ;
return result ;
}
TH1 *RooAbsData::createHistogram(const char *name, const RooAbsRealLValue& xvar,
const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
{
RooLinkedList l ;
l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
return createHistogram(name,xvar,l) ;
}
TH1 *RooAbsData::createHistogram(const char *name, const RooAbsRealLValue& xvar, const RooLinkedList& argListIn) const
{
RooLinkedList argList(argListIn) ;
RooCmdConfig pc(Form("RooAbsData::createHistogram(%s)",GetName())) ;
pc.defineString("cutRange","CutRange",0,"",kTRUE) ;
pc.defineString("cutString","CutSpec",0,"") ;
pc.defineObject("yvar","YVar",0,0) ;
pc.defineObject("zvar","ZVar",0,0) ;
pc.allowUndefined() ;
pc.process(argList) ;
if (!pc.ok(kTRUE)) {
return 0 ;
}
const char* cutSpec = pc.getString("cutString",0,kTRUE) ;
const char* cutRange = pc.getString("cutRange",0,kTRUE) ;
RooArgList vars(xvar) ;
RooAbsArg* yvar = static_cast<RooAbsArg*>(pc.getObject("yvar")) ;
if (yvar) {
vars.add(*yvar) ;
}
RooAbsArg* zvar = static_cast<RooAbsArg*>(pc.getObject("zvar")) ;
if (zvar) {
vars.add(*zvar) ;
}
pc.stripCmdList(argList,"CutRange,CutSpec") ;
RooLinkedList ownedCmds ;
RooCmdArg* autoRD = (RooCmdArg*) argList.find("AutoRangeData") ;
if (autoRD) {
Double_t xmin,xmax ;
getRange((RooRealVar&)xvar,xmin,xmax,autoRD->getDouble(0),autoRD->getInt(0)) ;
RooCmdArg* bincmd = (RooCmdArg*) RooFit::Binning(autoRD->getInt(1),xmin,xmax).Clone() ;
ownedCmds.Add(bincmd) ;
argList.Replace(autoRD,bincmd) ;
}
if (yvar) {
RooCmdArg* autoRDY = (RooCmdArg*) ((RooCmdArg*)argList.find("YVar"))->subArgs().find("AutoRangeData") ;
if (autoRDY) {
Double_t ymin,ymax ;
getRange((RooRealVar&)(*yvar),ymin,ymax,autoRDY->getDouble(0),autoRDY->getInt(0)) ;
RooCmdArg* bincmd = (RooCmdArg*) RooFit::Binning(autoRDY->getInt(1),ymin,ymax).Clone() ;
((RooCmdArg*)argList.find("YVar"))->subArgs().Replace(autoRDY,bincmd) ;
delete autoRDY ;
}
}
if (zvar) {
RooCmdArg* autoRDZ = (RooCmdArg*) ((RooCmdArg*)argList.find("ZVar"))->subArgs().find("AutoRangeData") ;
if (autoRDZ) {
Double_t zmin,zmax ;
getRange((RooRealVar&)(*zvar),zmin,zmax,autoRDZ->getDouble(0),autoRDZ->getInt(0)) ;
RooCmdArg* bincmd = (RooCmdArg*) RooFit::Binning(autoRDZ->getInt(1),zmin,zmax).Clone() ;
((RooCmdArg*)argList.find("ZVar"))->subArgs().Replace(autoRDZ,bincmd) ;
delete autoRDZ ;
}
}
TH1* histo = xvar.createHistogram(name,argList) ;
fillHistogram(histo,vars,cutSpec,cutRange) ;
ownedCmds.Delete() ;
return histo ;
}
Roo1DTable* RooAbsData::table(const RooArgSet& catSet, const char* cuts, const char* opts) const
{
RooArgSet catSet2 ;
string prodName("(") ;
TIterator* iter = catSet.createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
if (dynamic_cast<RooAbsCategory*>(arg)) {
RooAbsCategory* varsArg = dynamic_cast<RooAbsCategory*>(_vars.find(arg->GetName())) ;
if (varsArg != 0) catSet2.add(*varsArg) ;
else catSet2.add(*arg) ;
if (prodName.length()>1) {
prodName += " x " ;
}
prodName += arg->GetName() ;
} else {
coutW(InputArguments) << "RooAbsData::table(" << GetName() << ") non-RooAbsCategory input argument " << arg->GetName() << " ignored" << endl ;
}
}
prodName += ")" ;
delete iter ;
RooMultiCategory tmp(prodName.c_str(),prodName.c_str(),catSet2) ;
return table(tmp,cuts,opts) ;
}
void RooAbsData::printName(ostream& os) const
{
os << GetName() ;
}
void RooAbsData::printTitle(ostream& os) const
{
os << GetTitle() ;
}
void RooAbsData::printClassName(ostream& os) const
{
os << IsA()->GetName() ;
}
void RooAbsData::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
{
_dstore->printMultiline(os,contents,verbose,indent) ;
}
Int_t RooAbsData::defaultPrintContents(Option_t* ) const
{
return kName|kClassName|kArgs|kValue ;
}
Double_t RooAbsData::standMoment(RooRealVar &var, Double_t order, const char* cutSpec, const char* cutRange) const
{
if (order==1) return 0 ;
if (order==2) return 1 ;
return moment(var,order,cutSpec,cutRange) / TMath::Power(sigma(var,cutSpec,cutRange),order) ;
}
Double_t RooAbsData::moment(RooRealVar &var, Double_t order, const char* cutSpec, const char* cutRange) const
{
Double_t offset = order>1 ? moment(var,1,cutSpec,cutRange) : 0 ;
return moment(var,order,offset,cutSpec,cutRange) ;
}
Double_t RooAbsData::moment(RooRealVar &var, Double_t order, Double_t offset, const char* cutSpec, const char* cutRange) const
{
RooRealVar *varPtr= (RooRealVar*) _vars.find(var.GetName());
if(0 == varPtr) {
coutE(InputArguments) << "RooDataSet::moment(" << GetName() << ") ERROR: unknown variable: " << var.GetName() << endl ;
return 0;
}
if (!dynamic_cast<RooRealVar*>(varPtr)) {
coutE(InputArguments) << "RooDataSet::moment(" << GetName() << ") ERROR: variable " << var.GetName() << " is not of type RooRealVar" << endl ;
return 0;
}
if(sumEntries(cutSpec, cutRange) == 0.) {
coutE(InputArguments) << "RooDataSet::moment(" << GetName() << ") WARNING: empty dataset" << endl ;
return 0;
}
RooFormula* select = 0 ;
if (cutSpec) {
select = new RooFormula("select",cutSpec,*get()) ;
}
Double_t sum(0);
const RooArgSet* vars ;
for(Int_t index= 0; index < numEntries(); index++) {
vars = get(index) ;
if (select && select->eval()==0) continue ;
if (cutRange && vars->allInRange(cutRange)) continue ;
sum+= weight() * TMath::Power(varPtr->getVal() - offset,order);
}
return sum/sumEntries(cutSpec, cutRange);
}
RooRealVar* RooAbsData::dataRealVar(const char* methodname, RooRealVar& extVar) const
{
RooRealVar *xdata = (RooRealVar*) _vars.find(extVar.GetName());
if(!xdata) {
coutE(InputArguments) << "RooDataSet::" << methodname << "(" << GetName() << ") ERROR: variable : " << extVar.GetName() << " is not in data" << endl ;
return 0;
}
if (!dynamic_cast<RooRealVar*>(xdata)) {
coutE(InputArguments) << "RooDataSet::" << methodname << "(" << GetName() << ") ERROR: variable : " << extVar.GetName() << " is not of type RooRealVar in data" << endl ;
return 0;
}
return xdata;
}
Double_t RooAbsData::corrcov(RooRealVar &x,RooRealVar &y, const char* cutSpec, const char* cutRange, Bool_t corr) const
{
RooRealVar *xdata = dataRealVar(corr?"correlation":"covariance",x) ;
RooRealVar *ydata = dataRealVar(corr?"correlation":"covariance",y) ;
if (!xdata||!ydata) return 0 ;
if(sumEntries(cutSpec, cutRange) == 0.) {
coutW(InputArguments) << "RooDataSet::" << (corr?"correlation":"covariance") << "(" << GetName() << ") WARNING: empty dataset, returning zero" << endl ;
return 0;
}
RooFormula* select = cutSpec ? new RooFormula("select",cutSpec,*get()) : 0 ;
Double_t xysum(0),xsum(0),ysum(0),x2sum(0),y2sum(0);
const RooArgSet* vars ;
for(Int_t index= 0; index < numEntries(); index++) {
vars = get(index) ;
if (select && select->eval()==0) continue ;
if (cutRange && vars->allInRange(cutRange)) continue ;
xysum += weight()*xdata->getVal()*ydata->getVal() ;
xsum += weight()*xdata->getVal() ;
ysum += weight()*ydata->getVal() ;
if (corr) {
x2sum += weight()*xdata->getVal()*xdata->getVal() ;
y2sum += weight()*ydata->getVal()*ydata->getVal() ;
}
}
xysum/=sumEntries(cutSpec, cutRange) ;
xsum/=sumEntries(cutSpec, cutRange) ;
ysum/=sumEntries(cutSpec, cutRange) ;
if (corr) {
x2sum/=sumEntries(cutSpec, cutRange) ;
y2sum/=sumEntries(cutSpec, cutRange) ;
}
if (select) delete select ;
if (corr) {
return (xysum-xsum*ysum)/(sqrt(x2sum-(xsum*xsum))*sqrt(y2sum-(ysum*ysum))) ;
} else {
return (xysum-xsum*ysum);
}
}
TMatrixDSym* RooAbsData::corrcovMatrix(const RooArgList& vars, const char* cutSpec, const char* cutRange, Bool_t corr) const
{
RooArgList varList ;
TIterator* iter = vars.createIterator() ;
RooRealVar* var ;
while((var=(RooRealVar*)iter->Next())) {
RooRealVar* datavar = dataRealVar("covarianceMatrix",*var) ;
if (!datavar) {
delete iter ;
return 0 ;
}
varList.add(*datavar) ;
}
delete iter ;
if(sumEntries(cutSpec, cutRange) == 0.) {
coutW(InputArguments) << "RooDataSet::covariance(" << GetName() << ") WARNING: empty dataset, returning zero" << endl ;
return 0;
}
RooFormula* select = cutSpec ? new RooFormula("select",cutSpec,*get()) : 0 ;
iter = varList.createIterator() ;
TIterator* iter2 = varList.createIterator() ;
TMatrixDSym xysum(varList.getSize()) ;
vector<double> xsum(varList.getSize()) ;
vector<double> x2sum(varList.getSize()) ;
for(Int_t index= 0; index < numEntries(); index++) {
const RooArgSet* dvars = get(index) ;
if (select && select->eval()==0) continue ;
if (cutRange && dvars->allInRange(cutRange)) continue ;
RooRealVar* varx, *vary ;
iter->Reset() ;
Int_t ix=0,iy=0 ;
while((varx=(RooRealVar*)iter->Next())) {
xsum[ix] += weight()*varx->getVal() ;
if (corr) {
x2sum[ix] += weight()*varx->getVal()*varx->getVal() ;
}
*iter2=*iter ; iy=ix ;
vary=varx ;
while(vary) {
xysum(ix,iy) += weight()*varx->getVal()*vary->getVal() ;
xysum(iy,ix) = xysum(ix,iy) ;
iy++ ;
vary=(RooRealVar*)iter2->Next() ;
}
ix++ ;
}
}
for (Int_t ix=0 ; ix<varList.getSize() ; ix++) {
xsum[ix] /= sumEntries(cutSpec, cutRange) ;
if (corr) {
x2sum[ix] /= sumEntries(cutSpec, cutRange) ;
}
for (Int_t iy=0 ; iy<varList.getSize() ; iy++) {
xysum(ix,iy) /= sumEntries(cutSpec, cutRange) ;
}
}
TMatrixDSym* C = new TMatrixDSym(varList.getSize()) ;
for (Int_t ix=0 ; ix<varList.getSize() ; ix++) {
for (Int_t iy=0 ; iy<varList.getSize() ; iy++) {
(*C)(ix,iy) = xysum(ix,iy)-xsum[ix]*xsum[iy] ;
if (corr) {
(*C)(ix,iy) /= sqrt((x2sum[ix]-(xsum[ix]*xsum[ix]))*(x2sum[iy]-(xsum[iy]*xsum[iy]))) ;
}
}
}
if (select) delete select ;
delete iter ;
delete iter2 ;
return C ;
}
RooRealVar* RooAbsData::meanVar(RooRealVar &var, const char* cutSpec, const char* cutRange) const
{
TString name(var.GetName()),title("Mean of ") ;
name.Append("Mean");
title.Append(var.GetTitle());
RooRealVar *meanv= new RooRealVar(name,title,0) ;
meanv->setConstant(kFALSE) ;
TString label("<") ;
label.Append(var.getPlotLabel());
label.Append(">");
meanv->setPlotLabel(label.Data());
Double_t meanVal=moment(var,1,0,cutSpec,cutRange) ;
Double_t N(sumEntries(cutSpec,cutRange)) ;
Double_t rmsVal= sqrt(moment(var,2,meanVal,cutSpec,cutRange)*N/(N-1));
meanv->setVal(meanVal) ;
meanv->setError(N > 0 ? rmsVal/sqrt(N) : 0);
return meanv;
}
RooRealVar* RooAbsData::rmsVar(RooRealVar &var, const char* cutSpec, const char* cutRange) const
{
TString name(var.GetName()),title("RMS of ") ;
name.Append("RMS");
title.Append(var.GetTitle());
RooRealVar *rms= new RooRealVar(name,title,0) ;
rms->setConstant(kFALSE) ;
TString label(var.getPlotLabel());
label.Append("_{RMS}");
rms->setPlotLabel(label);
Double_t meanVal(moment(var,1,0,cutSpec,cutRange)) ;
Double_t N(sumEntries(cutSpec, cutRange));
Double_t rmsVal= sqrt(moment(var,2,meanVal,cutSpec,cutRange)*N/(N-1));
rms->setVal(rmsVal) ;
rms->setError(rmsVal/sqrt(2*N));
return rms;
}
RooPlot* RooAbsData::statOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
{
RooLinkedList cmdList;
cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
RooCmdConfig pc(Form("RooTreeData::statOn(%s)",GetName())) ;
pc.defineString("what","What",0,"MNR") ;
pc.defineString("label","Label",0,"") ;
pc.defineDouble("xmin","Layout",0,0.65) ;
pc.defineDouble("xmax","Layout",1,0.99) ;
pc.defineInt("ymaxi","Layout",0,Int_t(0.95*10000)) ;
pc.defineString("formatStr","Format",0,"NELU") ;
pc.defineInt("sigDigit","Format",0,2) ;
pc.defineInt("dummy","FormatArgs",0,0) ;
pc.defineString("cutRange","CutRange",0,"",kTRUE) ;
pc.defineString("cutString","CutSpec",0,"") ;
pc.defineMutex("Format","FormatArgs") ;
pc.process(cmdList) ;
if (!pc.ok(kTRUE)) {
return frame ;
}
const char* label = pc.getString("label") ;
Double_t xmin = pc.getDouble("xmin") ;
Double_t xmax = pc.getDouble("xmax") ;
Double_t ymax = pc.getInt("ymaxi") / 10000. ;
const char* formatStr = pc.getString("formatStr") ;
Int_t sigDigit = pc.getInt("sigDigit") ;
const char* what = pc.getString("what") ;
const char* cutSpec = pc.getString("cutString",0,kTRUE) ;
const char* cutRange = pc.getString("cutRange",0,kTRUE) ;
if (pc.hasProcessed("FormatArgs")) {
RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
return statOn(frame,what,label,0,0,xmin,xmax,ymax,cutSpec,cutRange,formatCmd) ;
} else {
return statOn(frame,what,label,sigDigit,formatStr,xmin,xmax,ymax,cutSpec,cutRange) ;
}
}
RooPlot* RooAbsData::statOn(RooPlot* frame, const char* what, const char *label, Int_t sigDigits,
Option_t *options, Double_t xmin, Double_t xmax, Double_t ymax,
const char* cutSpec, const char* cutRange, const RooCmdArg* formatCmd)
{
Bool_t showLabel= (label != 0 && strlen(label) > 0);
TString whatStr(what) ;
whatStr.ToUpper() ;
Bool_t showN = whatStr.Contains("N") ;
Bool_t showR = whatStr.Contains("R") ;
Bool_t showM = whatStr.Contains("M") ;
Int_t nPar= 0;
if (showN) nPar++ ;
if (showR) nPar++ ;
if (showM) nPar++ ;
Double_t dy(0.06), ymin(ymax-nPar*dy);
if(showLabel) ymin-= dy;
TPaveText *box= new TPaveText(xmin,ymax,xmax,ymin,"BRNDC");
if(!box) return 0;
box->SetName(Form("%s_statBox",GetName())) ;
box->SetFillColor(0);
box->SetBorderSize(1);
box->SetTextAlign(12);
box->SetTextSize(0.04F);
box->SetFillStyle(1001);
RooRealVar N("N","Number of Events",sumEntries(cutSpec,cutRange));
N.setPlotLabel("Entries") ;
RooRealVar *meanv= meanVar(*(RooRealVar*)frame->getPlotVar(),cutSpec,cutRange);
meanv->setPlotLabel("Mean") ;
RooRealVar *rms= rmsVar(*(RooRealVar*)frame->getPlotVar(),cutSpec,cutRange);
rms->setPlotLabel("RMS") ;
TString *rmsText, *meanText, *NText ;
if (options) {
rmsText= rms->format(sigDigits,options);
meanText= meanv->format(sigDigits,options);
NText= N.format(sigDigits,options);
} else {
rmsText= rms->format(*formatCmd);
meanText= meanv->format(*formatCmd);
NText= N.format(*formatCmd);
}
if (showR) box->AddText(rmsText->Data());
if (showM) box->AddText(meanText->Data());
if (showN) box->AddText(NText->Data());
delete NText;
delete meanText;
delete rmsText;
delete meanv;
delete rms;
if(showLabel) box->AddText(label);
frame->addObject(box) ;
return frame ;
}
TH1 *RooAbsData::fillHistogram(TH1 *hist, const RooArgList &plotVars, const char *cuts, const char* cutRange) const
{
if(0 == hist) {
coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: no valid histogram to fill" << endl;
return 0;
}
Int_t hdim= hist->GetDimension();
if(hdim != plotVars.getSize()) {
coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: plotVars has the wrong dimension" << endl;
return 0;
}
RooArgSet plotClones,localVars;
for(Int_t index= 0; index < plotVars.getSize(); index++) {
const RooAbsArg *var= plotVars.at(index);
const RooAbsReal *realVar= dynamic_cast<const RooAbsReal*>(var);
if(0 == realVar) {
coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: cannot plot variable \"" << var->GetName()
<< "\" of type " << var->ClassName() << endl;
return 0;
}
RooAbsArg *found= _vars.find(realVar->GetName());
if(!found) {
RooAbsArg *clone= plotClones.addClone(*realVar,kTRUE);
assert(0 != clone);
if(!clone->dependsOn(_vars)) {
coutW(InputArguments) << ClassName() << "::" << GetName()
<< ":fillHistogram: WARNING: data does not contain variable: " << realVar->GetName() << endl;
}
else {
clone->recursiveRedirectServers(_vars);
}
localVars.add(*clone);
}
else {
localVars.add(*found);
}
}
RooFormula* select = 0;
if(0 != cuts && strlen(cuts)) {
select=new RooFormula(cuts,cuts,_vars);
if (!select || !select->ok()) {
coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: invalid cuts \"" << cuts << "\"" << endl;
delete select;
return 0 ;
}
}
const RooAbsReal *xvar = 0;
const RooAbsReal *yvar = 0;
const RooAbsReal *zvar = 0;
switch(hdim) {
case 3:
zvar= dynamic_cast<RooAbsReal*>(localVars.find(plotVars.at(2)->GetName()));
assert(0 != zvar);
case 2:
yvar= dynamic_cast<RooAbsReal*>(localVars.find(plotVars.at(1)->GetName()));
assert(0 != yvar);
case 1:
xvar= dynamic_cast<RooAbsReal*>(localVars.find(plotVars.at(0)->GetName()));
assert(0 != xvar);
break;
default:
coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: cannot fill histogram with "
<< hdim << " dimensions" << endl;
break;
}
vector<string> cutVec ;
if (cutRange && strlen(cutRange)>0) {
if (strchr(cutRange,',')==0) {
cutVec.push_back(cutRange) ;
} else {
const size_t bufSize = strlen(cutRange)+1;
char* buf = new char[bufSize] ;
strlcpy(buf,cutRange,bufSize) ;
const char* oneRange = strtok(buf,",") ;
while(oneRange) {
cutVec.push_back(oneRange) ;
oneRange = strtok(0,",") ;
}
delete[] buf ;
}
}
if (hist->GetSumw2()->fN==0) {
hist->Sumw2() ;
}
Int_t nevent= numEntries() ;
for(Int_t i=0; i < nevent; ++i) {
get(i);
if (select && select->eval()==0) {
continue ;
}
Bool_t selectByRange = kTRUE ;
if (cutRange) {
_iterator->Reset() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)_iterator->Next())) {
Bool_t selectThisArg = kFALSE ;
UInt_t icut ;
for (icut=0 ; icut<cutVec.size() ; icut++) {
if (arg->inRange(cutVec[icut].c_str())) {
selectThisArg = kTRUE ;
break ;
}
}
if (!selectThisArg) {
selectByRange = kFALSE ;
break ;
}
}
}
if (!selectByRange) {
continue ;
}
Int_t bin(0);
switch(hdim) {
case 1:
bin= hist->FindBin(xvar->getVal());
hist->Fill(xvar->getVal(),weight()) ;
break;
case 2:
bin= hist->FindBin(xvar->getVal(),yvar->getVal());
static_cast<TH2*>(hist)->Fill(xvar->getVal(),yvar->getVal(),weight()) ;
break;
case 3:
bin= hist->FindBin(xvar->getVal(),yvar->getVal(),zvar->getVal());
static_cast<TH3*>(hist)->Fill(xvar->getVal(),yvar->getVal(),zvar->getVal(),weight()) ;
break;
default:
assert(hdim < 3);
break;
}
Double_t error2 = TMath::Power(hist->GetBinError(bin),2)-TMath::Power(weight(),2) ;
Double_t we = weightError(RooAbsData::SumW2) ;
if (we==0) we = weight() ;
error2 += TMath::Power(we,2) ;
hist->SetBinError(bin,sqrt(error2)) ;
}
if(0 != select) delete select;
return hist;
}
TList* RooAbsData::split(const RooAbsCategory& splitCat, Bool_t createEmptyDataSets) const
{
if (!splitCat.dependsOn(*get())) {
coutE(InputArguments) << "RooTreeData::split(" << GetName() << ") ERROR category " << splitCat.GetName()
<< " doesn't depend on any variable in this dataset" << endl ;
return 0 ;
}
RooAbsCategory* cloneCat =0;
RooArgSet* cloneSet = 0;
if (splitCat.isDerived()) {
cloneSet = (RooArgSet*) RooArgSet(splitCat).snapshot(kTRUE) ;
if (!cloneSet) {
coutE(InputArguments) << "RooTreeData::split(" << GetName() << ") Couldn't deep-clone splitting category, abort." << endl ;
return 0 ;
}
cloneCat = (RooAbsCategory*) cloneSet->find(splitCat.GetName()) ;
cloneCat->attachDataSet(*this) ;
} else {
cloneCat = dynamic_cast<RooAbsCategory*>(get()->find(splitCat.GetName())) ;
if (!cloneCat) {
coutE(InputArguments) << "RooTreeData::split(" << GetName() << ") ERROR category " << splitCat.GetName()
<< " is fundamental and does not appear in this dataset" << endl ;
return 0 ;
}
}
TList* dsetList = new TList ;
RooArgSet subsetVars(*get()) ;
if (splitCat.isDerived()) {
RooArgSet* vars = splitCat.getVariables() ;
subsetVars.remove(*vars,kTRUE,kTRUE) ;
delete vars ;
} else {
subsetVars.remove(splitCat,kTRUE,kTRUE) ;
}
Bool_t addWV(kFALSE) ;
RooRealVar newweight("weight","weight",-1e9,1e9) ;
if (isWeighted() && !IsA()->InheritsFrom(RooDataHist::Class())) {
subsetVars.add(newweight) ;
addWV = kTRUE ;
}
if (createEmptyDataSets) {
TIterator* stateIter = cloneCat->typeIterator() ;
RooCatType* state ;
while ((state=(RooCatType*)stateIter->Next())) {
RooAbsData* subset = emptyClone(state->GetName(),state->GetName(),&subsetVars,(addWV?"weight":0)) ;
dsetList->Add((RooAbsArg*)subset) ;
}
delete stateIter ;
}
const bool propWeightSquared = isWeighted();
for (Int_t i = 0; i < numEntries(); ++i) {
const RooArgSet* row = get(i);
RooAbsData* subset = (RooAbsData*) dsetList->FindObject(cloneCat->getLabel());
if (!subset) {
subset = emptyClone(cloneCat->getLabel(),cloneCat->getLabel(),&subsetVars,(addWV?"weight":0));
dsetList->Add((RooAbsArg*)subset);
}
if (!propWeightSquared) {
subset->add(*row, weight());
} else {
subset->add(*row, weight(), weightSquared());
}
}
delete cloneSet;
return dsetList;
}
RooPlot* RooAbsData::plotOn(RooPlot* frame, const RooLinkedList& argList) const
{
RooCmdConfig pc(Form("RooTreeData::plotOn(%s)",GetName())) ;
pc.defineString("drawOption","DrawOption",0,"P") ;
pc.defineString("cutRange","CutRange",0,"",kTRUE) ;
pc.defineString("cutString","CutSpec",0,"") ;
pc.defineString("histName","Name",0,"") ;
pc.defineObject("cutVar","CutVar",0) ;
pc.defineObject("binning","Binning",0) ;
pc.defineString("binningName","BinningName",0,"") ;
pc.defineInt("nbins","BinningSpec",0,100) ;
pc.defineDouble("xlo","BinningSpec",0,0) ;
pc.defineDouble("xhi","BinningSpec",1,1) ;
pc.defineObject("asymCat","Asymmetry",0) ;
pc.defineObject("effCat","Efficiency",0) ;
pc.defineInt("lineColor","LineColor",0,-999) ;
pc.defineInt("lineStyle","LineStyle",0,-999) ;
pc.defineInt("lineWidth","LineWidth",0,-999) ;
pc.defineInt("markerColor","MarkerColor",0,-999) ;
pc.defineInt("markerStyle","MarkerStyle",0,-999) ;
pc.defineDouble("markerSize","MarkerSize",0,-999) ;
pc.defineInt("fillColor","FillColor",0,-999) ;
pc.defineInt("fillStyle","FillStyle",0,-999) ;
pc.defineInt("errorType","DataError",0,(Int_t)RooAbsData::Auto) ;
pc.defineInt("histInvisible","Invisible",0,0) ;
pc.defineInt("refreshFrameNorm","RefreshNorm",0,1) ;
pc.defineString("addToHistName","AddTo",0,"") ;
pc.defineDouble("addToWgtSelf","AddTo",0,1.) ;
pc.defineDouble("addToWgtOther","AddTo",1,1.) ;
pc.defineDouble("xErrorSize","XErrorSize",0,1.) ;
pc.defineDouble("scaleFactor","Rescale",0,1.) ;
pc.defineMutex("DataError","Asymmetry","Efficiency") ;
pc.defineMutex("Binning","BinningName","BinningSpec") ;
pc.process(argList) ;
if (!pc.ok(kTRUE)) {
return frame ;
}
PlotOpt o ;
o.drawOptions = pc.getString("drawOption") ;
o.cuts = pc.getString("cutString") ;
if (pc.hasProcessed("Binning")) {
o.bins = (RooAbsBinning*) pc.getObject("binning") ;
} else if (pc.hasProcessed("BinningName")) {
o.bins = &frame->getPlotVar()->getBinning(pc.getString("binningName")) ;
} else if (pc.hasProcessed("BinningSpec")) {
Double_t xlo = pc.getDouble("xlo") ;
Double_t xhi = pc.getDouble("xhi") ;
o.bins = new RooUniformBinning((xlo==xhi)?frame->getPlotVar()->getMin():xlo,
(xlo==xhi)?frame->getPlotVar()->getMax():xhi,pc.getInt("nbins")) ;
}
const RooAbsCategoryLValue* asymCat = (const RooAbsCategoryLValue*) pc.getObject("asymCat") ;
const RooAbsCategoryLValue* effCat = (const RooAbsCategoryLValue*) pc.getObject("effCat") ;
o.etype = (RooAbsData::ErrorType) pc.getInt("errorType") ;
o.histInvisible = pc.getInt("histInvisible") ;
o.xErrorSize = pc.getDouble("xErrorSize") ;
o.cutRange = pc.getString("cutRange",0,kTRUE) ;
o.histName = pc.getString("histName",0,kTRUE) ;
o.addToHistName = pc.getString("addToHistName",0,kTRUE) ;
o.addToWgtSelf = pc.getDouble("addToWgtSelf") ;
o.addToWgtOther = pc.getDouble("addToWgtOther") ;
o.refreshFrameNorm = pc.getInt("refreshFrameNorm") ;
o.scaleFactor = pc.getDouble("scaleFactor") ;
if (o.etype == Auto) {
o.etype = isNonPoissonWeighted() ? SumW2 : Poisson ;
if (o.etype == SumW2) {
coutI(InputArguments) << "RooAbsData::plotOn(" << GetName()
<< ") INFO: dataset has non-integer weights, auto-selecting SumW2 errors instead of Poisson errors" << endl ;
}
}
if (o.addToHistName && !frame->findObject(o.addToHistName,RooHist::Class())) {
coutE(InputArguments) << "RooAbsData::plotOn(" << GetName() << ") cannot find existing histogram " << o.addToHistName
<< " to add to in RooPlot" << endl ;
return frame ;
}
RooPlot* ret ;
if (!asymCat && !effCat) {
ret = plotOn(frame,o) ;
} else if (asymCat) {
ret = plotAsymOn(frame,*asymCat,o) ;
} else {
ret = plotEffOn(frame,*effCat,o) ;
}
Int_t lineColor = pc.getInt("lineColor") ;
Int_t lineStyle = pc.getInt("lineStyle") ;
Int_t lineWidth = pc.getInt("lineWidth") ;
Int_t markerColor = pc.getInt("markerColor") ;
Int_t markerStyle = pc.getInt("markerStyle") ;
Size_t markerSize = pc.getDouble("markerSize") ;
Int_t fillColor = pc.getInt("fillColor") ;
Int_t fillStyle = pc.getInt("fillStyle") ;
if (lineColor!=-999) ret->getAttLine()->SetLineColor(lineColor) ;
if (lineStyle!=-999) ret->getAttLine()->SetLineStyle(lineStyle) ;
if (lineWidth!=-999) ret->getAttLine()->SetLineWidth(lineWidth) ;
if (markerColor!=-999) ret->getAttMarker()->SetMarkerColor(markerColor) ;
if (markerStyle!=-999) ret->getAttMarker()->SetMarkerStyle(markerStyle) ;
if (markerSize!=-999) ret->getAttMarker()->SetMarkerSize(markerSize) ;
if (fillColor!=-999) ret->getAttFill()->SetFillColor(fillColor) ;
if (fillStyle!=-999) ret->getAttFill()->SetFillStyle(fillStyle) ;
if (pc.hasProcessed("BinningSpec")) {
delete o.bins ;
}
return ret ;
}
RooPlot *RooAbsData::plotOn(RooPlot *frame, PlotOpt o) const
{
if(0 == frame) {
coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOn: frame is null" << endl;
return 0;
}
RooAbsRealLValue *var= (RooAbsRealLValue*) frame->getPlotVar();
if(0 == var) {
coutE(Plotting) << ClassName() << "::" << GetName()
<< ":plotOn: frame does not specify a plot variable" << endl;
return 0;
}
TString histName(GetName());
histName.Append("_plot");
TH1F *hist ;
if (o.bins) {
hist= static_cast<TH1F*>(var->createHistogram(histName.Data(), RooFit::AxisLabel("Events"), RooFit::Binning(*o.bins))) ;
} else {
hist= var->createHistogram(histName.Data(), "Events",
frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(), frame->GetNbinsX());
}
hist->Sumw2() ;
if(0 == fillHistogram(hist,RooArgList(*var),o.cuts,o.cutRange)) {
coutE(Plotting) << ClassName() << "::" << GetName()
<< ":plotOn: fillHistogram() failed" << endl;
return 0;
}
Double_t nomBinWidth ;
if (frame->getFitRangeNEvt()==0 && o.bins) {
nomBinWidth = o.bins->averageBinWidth() ;
} else {
nomBinWidth = o.bins ? frame->getFitRangeBinW() : 0 ;
}
RooHist *graph= new RooHist(*hist,nomBinWidth,1,o.etype,o.xErrorSize,o.correctForBinWidth,o.scaleFactor);
if(0 == graph) {
coutE(Plotting) << ClassName() << "::" << GetName()
<< ":plotOn: unable to create a RooHist object" << endl;
delete hist;
return 0;
}
RooAbsRealLValue* dataVar = (RooAbsRealLValue*) _vars.find(var->GetName()) ;
Double_t nEnt(sumEntries()) ;
if (dataVar->getMin()<var->getMin() || dataVar->getMax()>var->getMax()) {
RooAbsData* tmp = ((RooAbsData*)this)->reduce(*var) ;
nEnt = tmp->sumEntries() ;
delete tmp ;
}
if ((o.cuts && strlen(o.cuts)) || o.cutRange) {
coutI(Plotting) << "RooTreeData::plotOn: plotting " << hist->GetSum() << " events out of " << nEnt << " total events" << endl ;
graph->setRawEntries(nEnt) ;
}
if (o.addToHistName) {
RooHist* otherGraph = static_cast<RooHist*>(frame->findObject(o.addToHistName,RooHist::Class())) ;
if (!graph->hasIdenticalBinning(*otherGraph)) {
coutE(Plotting) << "RooTreeData::plotOn: ERROR Histogram to be added to, '" << o.addToHistName << "',has different binning" << endl ;
delete graph ;
return frame ;
}
RooHist* sumGraph = new RooHist(*graph,*otherGraph,o.addToWgtSelf,o.addToWgtOther,o.etype) ;
delete graph ;
graph = sumGraph ;
}
if (o.histName) {
graph->SetName(o.histName) ;
} else {
TString hname(Form("h_%s",GetName())) ;
if (o.cutRange && strlen(o.cutRange)>0) {
hname.Append(Form("_CutRange[%s]",o.cutRange)) ;
}
if (o.cuts && strlen(o.cuts)>0) {
hname.Append(Form("_Cut[%s]",o.cuts)) ;
}
graph->SetName(hname.Data()) ;
}
frame->updateNormVars(_vars);
frame->addPlotable(graph,o.drawOptions,o.histInvisible,o.refreshFrameNorm);
delete hist;
return frame;
}
RooPlot* RooAbsData::plotAsymOn(RooPlot* frame, const RooAbsCategoryLValue& asymCat, PlotOpt o) const
{
if(0 == frame) {
coutE(Plotting) << ClassName() << "::" << GetName() << ":plotAsymOn: frame is null" << endl;
return 0;
}
RooAbsRealLValue *var= (RooAbsRealLValue*) frame->getPlotVar();
if(0 == var) {
coutE(Plotting) << ClassName() << "::" << GetName()
<< ":plotAsymOn: frame does not specify a plot variable" << endl;
return 0;
}
TString hist1Name(GetName()),hist2Name(GetName());
hist1Name.Append("_plot1");
TH1F *hist1, *hist2 ;
hist2Name.Append("_plot2");
if (o.bins) {
hist1= var->createHistogram(hist1Name.Data(), "Events", *o.bins) ;
hist2= var->createHistogram(hist2Name.Data(), "Events", *o.bins) ;
} else {
hist1= var->createHistogram(hist1Name.Data(), "Events",
frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
frame->GetNbinsX());
hist2= var->createHistogram(hist2Name.Data(), "Events",
frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
frame->GetNbinsX());
}
assert(0 != hist1 && 0 != hist2);
TString cuts1,cuts2 ;
if (o.cuts && strlen(o.cuts)) {
cuts1 = Form("(%s)&&(%s>0)",o.cuts,asymCat.GetName());
cuts2 = Form("(%s)&&(%s<0)",o.cuts,asymCat.GetName());
} else {
cuts1 = Form("(%s>0)",asymCat.GetName());
cuts2 = Form("(%s<0)",asymCat.GetName());
}
if(0 == fillHistogram(hist1,RooArgList(*var),cuts1.Data(),o.cutRange) ||
0 == fillHistogram(hist2,RooArgList(*var),cuts2.Data(),o.cutRange)) {
coutE(Plotting) << ClassName() << "::" << GetName()
<< ":plotAsymOn: createHistogram() failed" << endl;
return 0;
}
RooHist *graph= new RooHist(*hist1,*hist2,0,1,o.etype,o.xErrorSize,kFALSE,o.scaleFactor);
graph->setYAxisLabel(Form("Asymmetry in %s",asymCat.GetName())) ;
frame->updateNormVars(_vars);
if (o.histName) {
graph->SetName(o.histName) ;
} else {
TString hname(Form("h_%s_Asym[%s]",GetName(),asymCat.GetName())) ;
if (o.cutRange && strlen(o.cutRange)>0) {
hname.Append(Form("_CutRange[%s]",o.cutRange)) ;
}
if (o.cuts && strlen(o.cuts)>0) {
hname.Append(Form("_Cut[%s]",o.cuts)) ;
}
graph->SetName(hname.Data()) ;
}
frame->addPlotable(graph,o.drawOptions,o.histInvisible,o.refreshFrameNorm);
delete hist1;
delete hist2;
return frame;
}
RooPlot* RooAbsData::plotEffOn(RooPlot* frame, const RooAbsCategoryLValue& effCat, PlotOpt o) const
{
if(0 == frame) {
coutE(Plotting) << ClassName() << "::" << GetName() << ":plotEffOn: frame is null" << endl;
return 0;
}
RooAbsRealLValue *var= (RooAbsRealLValue*) frame->getPlotVar();
if(0 == var) {
coutE(Plotting) << ClassName() << "::" << GetName()
<< ":plotEffOn: frame does not specify a plot variable" << endl;
return 0;
}
TString hist1Name(GetName()),hist2Name(GetName());
hist1Name.Append("_plot1");
TH1F *hist1, *hist2 ;
hist2Name.Append("_plot2");
if (o.bins) {
hist1= var->createHistogram(hist1Name.Data(), "Events", *o.bins) ;
hist2= var->createHistogram(hist2Name.Data(), "Events", *o.bins) ;
} else {
hist1= var->createHistogram(hist1Name.Data(), "Events",
frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
frame->GetNbinsX());
hist2= var->createHistogram(hist2Name.Data(), "Events",
frame->GetXaxis()->GetXmin(), frame->GetXaxis()->GetXmax(),
frame->GetNbinsX());
}
assert(0 != hist1 && 0 != hist2);
TString cuts1,cuts2 ;
if (o.cuts && strlen(o.cuts)) {
cuts1 = Form("(%s)&&(%s==1)",o.cuts,effCat.GetName());
cuts2 = Form("(%s)&&(%s==0)",o.cuts,effCat.GetName());
} else {
cuts1 = Form("(%s==1)",effCat.GetName());
cuts2 = Form("(%s==0)",effCat.GetName());
}
if(0 == fillHistogram(hist1,RooArgList(*var),cuts1.Data(),o.cutRange) ||
0 == fillHistogram(hist2,RooArgList(*var),cuts2.Data(),o.cutRange)) {
coutE(Plotting) << ClassName() << "::" << GetName()
<< ":plotEffOn: createHistogram() failed" << endl;
return 0;
}
RooHist *graph= new RooHist(*hist1,*hist2,0,1,o.etype,o.xErrorSize,kTRUE);
graph->setYAxisLabel(Form("Efficiency of %s=%s",effCat.GetName(),effCat.lookupType(1)->GetName())) ;
frame->updateNormVars(_vars);
if (o.histName) {
graph->SetName(o.histName) ;
} else {
TString hname(Form("h_%s_Eff[%s]",GetName(),effCat.GetName())) ;
if (o.cutRange && strlen(o.cutRange)>0) {
hname.Append(Form("_CutRange[%s]",o.cutRange)) ;
}
if (o.cuts && strlen(o.cuts)>0) {
hname.Append(Form("_Cut[%s]",o.cuts)) ;
}
graph->SetName(hname.Data()) ;
}
frame->addPlotable(graph,o.drawOptions,o.histInvisible,o.refreshFrameNorm);
delete hist1;
delete hist2;
return frame;
}
Roo1DTable* RooAbsData::table(const RooAbsCategory& cat, const char* cuts, const char* ) const
{
RooAbsCategory* tableVar = (RooAbsCategory*) _vars.find(cat.GetName()) ;
RooArgSet *tableSet = 0;
Bool_t ownPlotVar(kFALSE) ;
if (!tableVar) {
if (!cat.dependsOn(_vars)) {
coutE(Plotting) << "RooTreeData::Table(" << GetName() << "): Argument " << cat.GetName()
<< " is not in dataset and is also not dependent on data set" << endl ;
return 0 ;
}
tableSet = (RooArgSet*) RooArgSet(cat).snapshot(kTRUE) ;
if (!tableSet) {
coutE(Plotting) << "RooTreeData::table(" << GetName() << ") Couldn't deep-clone table category, abort." << endl ;
return 0 ;
}
tableVar = (RooAbsCategory*) tableSet->find(cat.GetName()) ;
ownPlotVar = kTRUE ;
tableVar->recursiveRedirectServers(_vars) ;
}
TString tableName(GetName()) ;
if (cuts && strlen(cuts)) {
tableName.Append("(") ;
tableName.Append(cuts) ;
tableName.Append(")") ;
}
Roo1DTable* table2 = tableVar->createTable(tableName) ;
RooFormulaVar* cutVar = 0;
if (cuts && strlen(cuts)) {
cutVar = new RooFormulaVar("cutVar",cuts,_vars) ;
}
Int_t nevent= numEntries() ;
for(Int_t i=0; i < nevent; ++i) {
get(i);
if (cutVar && cutVar->getVal()==0) continue ;
table2->fill(*tableVar,weight()) ;
}
if (ownPlotVar) delete tableSet ;
if (cutVar) delete cutVar ;
return table2 ;
}
Bool_t RooAbsData::getRange(RooRealVar& var, Double_t& lowest, Double_t& highest, Double_t marginFrac, Bool_t symMode) const
{
RooRealVar *varPtr= (RooRealVar*) _vars.find(var.GetName());
if(0 == varPtr) {
coutE(InputArguments) << "RooDataSet::getRange(" << GetName() << ") ERROR: unknown variable: " << var.GetName() << endl ;
return kTRUE;
}
if (!dynamic_cast<RooRealVar*>(varPtr)) {
coutE(InputArguments) << "RooDataSet::getRange(" << GetName() << ") ERROR: variable " << var.GetName() << " is not of type RooRealVar" << endl ;
return kTRUE;
}
if(sumEntries() == 0.) {
coutE(InputArguments) << "RooDataSet::getRange(" << GetName() << ") WARNING: empty dataset" << endl ;
return kTRUE;
}
lowest = RooNumber::infinity() ;
highest = -RooNumber::infinity() ;
for (Int_t i=0 ; i<numEntries() ; i++) {
get(i) ;
if (varPtr->getVal()<lowest) {
lowest = varPtr->getVal() ;
}
if (varPtr->getVal()>highest) {
highest = varPtr->getVal() ;
}
}
if (marginFrac>0) {
if (symMode==kFALSE) {
Double_t margin = marginFrac*(highest-lowest) ;
lowest -= margin ;
highest += margin ;
if (lowest<var.getMin()) lowest = var.getMin() ;
if (highest>var.getMax()) highest = var.getMax() ;
} else {
Double_t mom1 = moment(var,1) ;
Double_t delta = ((highest-mom1)>(mom1-lowest)?(highest-mom1):(mom1-lowest))*(1+marginFrac) ;
lowest = mom1-delta ;
highest = mom1+delta ;
if (lowest<var.getMin()) lowest = var.getMin() ;
if (highest>var.getMax()) highest = var.getMax() ;
}
}
return kFALSE ;
}
void RooAbsData::optimizeReadingWithCaching(RooAbsArg& arg, const RooArgSet& cacheList, const RooArgSet& keepObsList)
{
RooArgSet pruneSet ;
pruneSet.add(*get()) ;
RooArgSet* usedObs = arg.getObservables(*this) ;
pruneSet.remove(*usedObs,kTRUE,kTRUE) ;
TIterator* vIter = get()->createIterator() ;
RooAbsArg *var ;
while ((var=(RooAbsArg*) vIter->Next())) {
if (allClientsCached(var,cacheList)) {
pruneSet.add(*var) ;
}
}
delete vIter ;
if (pruneSet.getSize()!=0) {
TIterator* uIter = usedObs->createIterator() ;
RooAbsArg* obs ;
while((obs=(RooAbsArg*)uIter->Next())) {
RooRealVar* rrv = dynamic_cast<RooRealVar*>(obs) ;
if (rrv && !rrv->getBinning().isShareable()) {
RooArgSet depObs ;
RooAbsReal* loFunc = rrv->getBinning().lowBoundFunc() ;
RooAbsReal* hiFunc = rrv->getBinning().highBoundFunc() ;
if (loFunc) {
loFunc->leafNodeServerList(&depObs,0,kTRUE) ;
}
if (hiFunc) {
hiFunc->leafNodeServerList(&depObs,0,kTRUE) ;
}
if (depObs.getSize()>0) {
pruneSet.remove(depObs,kTRUE,kTRUE) ;
}
}
}
delete uIter ;
}
pruneSet.remove(keepObsList,kTRUE,kTRUE) ;
if (pruneSet.getSize()!=0) {
cxcoutI(Optimization) << "RooTreeData::optimizeReadingForTestStatistic(" << GetName() << "): Observables " << pruneSet
<< " in dataset are either not used at all, orserving exclusively p.d.f nodes that are now cached, disabling reading of these observables for TTree" << endl ;
setArgStatus(pruneSet,kFALSE) ;
}
delete usedObs ;
}
Bool_t RooAbsData::allClientsCached(RooAbsArg* var, const RooArgSet& cacheList)
{
Bool_t ret(kTRUE), anyClient(kFALSE) ;
TIterator* cIter = var->valueClientIterator() ;
RooAbsArg* client ;
while ((client=(RooAbsArg*) cIter->Next())) {
anyClient = kTRUE ;
if (!cacheList.find(client->GetName())) {
ret &= allClientsCached(client,cacheList) ;
}
}
delete cIter ;
return anyClient?ret:kFALSE ;
}
void RooAbsData::attachBuffers(const RooArgSet& extObs)
{
_dstore->attachBuffers(extObs) ;
}
void RooAbsData::resetBuffers()
{
_dstore->resetBuffers() ;
}
Bool_t RooAbsData::canSplitFast() const
{
if (_ownedComponents.size()>0) {
return kTRUE ;
}
return kFALSE ;
}
RooAbsData* RooAbsData::getSimData(const char* name)
{
map<string,RooAbsData*>::iterator i = _ownedComponents.find(name) ;
if (i==_ownedComponents.end()) return 0 ;
return i->second ;
}
void RooAbsData::addOwnedComponent(const char* idxlabel, RooAbsData& data)
{
_ownedComponents[idxlabel]= &data ;
}
void RooAbsData::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
R__b.ReadClassBuffer(RooAbsData::Class(),this);
if (defaultStorageType==RooAbsData::Vector) {
convertToVectorStore() ;
}
} else {
R__b.WriteClassBuffer(RooAbsData::Class(),this);
}
}
void RooAbsData::checkInit() const
{
_dstore->checkInit() ;
}
void RooAbsData::Draw(Option_t* option)
{
if (_dstore) _dstore->Draw(option) ;
}
Bool_t RooAbsData::hasFilledCache() const
{
return _dstore->hasFilledCache() ;
}
const TTree* RooAbsData::tree() const
{
return _dstore->tree() ;
}