#include "RooFit.h"
#include "RooMsgService.h"
#include "Riostream.h"
#include "Riostream.h"
#include "RooAbsAnaConvPdf.h"
#include "RooResolutionModel.h"
#include "RooRealVar.h"
#include "RooFormulaVar.h"
#include "RooConvGenContext.h"
#include "RooGenContext.h"
#include "RooTruthModel.h"
#include "RooConvCoefVar.h"
#include "RooNameReg.h"
ClassImp(RooAbsAnaConvPdf) 
;
RooAbsAnaConvPdf::RooAbsAnaConvPdf() :
  _isCopy(kFALSE),
  _model(0),
  _convVar(0),
  _convNormSet(0),
  _convSetIter(_convSet.createIterator())
{
}
RooAbsAnaConvPdf::RooAbsAnaConvPdf(const char *name, const char *title, 
				   const RooResolutionModel& model, RooRealVar& convVar) :
  RooAbsPdf(name,title), _isCopy(kFALSE),
  _model((RooResolutionModel*)&model), _convVar((RooRealVar*)&convVar),
  _convSet("convSet","Set of resModel X basisFunc convolutions",this),
  _convNormSet(0), _convSetIter(_convSet.createIterator()),
  _coefNormMgr(this,10),
  _codeReg(10)
{
  
  
  _convNormSet = new RooArgSet(convVar,"convNormSet") ;
}
RooAbsAnaConvPdf::RooAbsAnaConvPdf(const RooAbsAnaConvPdf& other, const char* name) : 
  RooAbsPdf(other,name), _isCopy(kTRUE),
  _model(other._model), 
  _convVar(other._convVar), 
  _convSet("convSet",this,other._convSet),
  _basisList(other._basisList),
  _convNormSet(other._convNormSet? new RooArgSet(*other._convNormSet) : new RooArgSet() ),
  _convSetIter(_convSet.createIterator()),
  _coefNormMgr(other._coefNormMgr,this),
  _codeReg(other._codeReg)
{
  
}
RooAbsAnaConvPdf::~RooAbsAnaConvPdf()
{
  
  if (_convNormSet) {
    delete _convNormSet ;
  }
    
  delete _convSetIter ;
  if (!_isCopy) {
    TIterator* iter = _convSet.createIterator() ;
    RooAbsArg* arg ;
    while (((arg = (RooAbsArg*)iter->Next()))) {
      _convSet.remove(*arg) ;
      delete arg ;
    }
    delete iter ;
  }
}
Int_t RooAbsAnaConvPdf::declareBasis(const char* expression, const RooArgList& params) 
{
  
  
  
  
  
  
  
  
  
  
  
  if (_isCopy) {
    coutE(InputArguments) << "RooAbsAnaConvPdf::declareBasis(" << GetName() << "): ERROR attempt to "
			  << " declare basis functions in a copied RooAbsAnaConvPdf" << endl ;
    return -1 ;
  }
  
  if (!_model->isBasisSupported(expression)) {
    coutE(InputArguments) << "RooAbsAnaConvPdf::declareBasis(" << GetName() << "): resolution model " 
			  << _model->GetName() 
			  << " doesn't support basis function " << expression << endl ;
    return -1 ;
  }
  
  RooArgList basisArgs(*_convVar) ;
  basisArgs.add(params) ;
  TString basisName(expression) ;
  TIterator* iter = basisArgs.createIterator() ;
  RooAbsArg* arg  ;
  while(((arg=(RooAbsArg*)iter->Next()))) {
    basisName.Append("_") ;
    basisName.Append(arg->GetName()) ;
  }
  delete iter ;  
  RooFormulaVar* basisFunc = new RooFormulaVar(basisName,expression,basisArgs) ;
  basisFunc->setOperMode(operMode()) ;
  _basisList.addOwned(*basisFunc) ;
  
  RooAbsReal* conv = _model->convolution(basisFunc,this) ;
  if (!conv) {
    coutE(InputArguments) << "RooAbsAnaConvPdf::declareBasis(" << GetName() << "): unable to construct convolution with basis function '" 
			  << expression << "'" << endl ;
    return -1 ;
  }
  _convSet.add(*conv) ;
  return _convSet.index(conv) ;
}
Bool_t RooAbsAnaConvPdf::changeModel(const RooResolutionModel& newModel) 
{
  
  TIterator* cIter = _convSet.createIterator() ;
  RooResolutionModel* conv ;
  RooArgList newConvSet ;
  Bool_t allOK(kTRUE) ;
  while(((conv=(RooResolutionModel*)cIter->Next()))) {
    
    RooResolutionModel* newConv = newModel.convolution((RooFormulaVar*)&conv->basis(),this) ;
    if (!newConvSet.add(*newConv)) {
      allOK = kFALSE ;
      break ;
    }
  }
  delete cIter ;
  
  if (!allOK) {
    
    TIterator* iter = newConvSet.createIterator() ;
    while(((conv=(RooResolutionModel*)iter->Next()))) delete conv ;
    delete iter ;
    return kTRUE ;
  }
  
  
  _convSet.removeAll() ;
  _convSet.addOwned(newConvSet) ;
  _model = (RooResolutionModel*) &newModel ;
  return kFALSE ;
}
RooAbsGenContext* RooAbsAnaConvPdf::genContext(const RooArgSet &vars, const RooDataSet *prototype, 
					       const RooArgSet* auxProto, Bool_t verbose) const 
{
  RooArgSet* modelDep = _model->getObservables(&vars) ;
  modelDep->remove(*convVar(),kTRUE,kTRUE) ;
  Int_t numAddDep = modelDep->getSize() ;
  delete modelDep ;
  if (dynamic_cast<RooTruthModel*>(_model)) {
    
    RooArgSet forceDirect(*convVar()) ;
    return new RooGenContext(*this,vars,prototype,auxProto,verbose,&forceDirect) ;
  } 
  
  RooArgSet dummy ;
  Bool_t pdfCanDir = (getGenerator(*convVar(),dummy) != 0) ;
  RooResolutionModel* conv = (RooResolutionModel*) _convSet.at(0) ;
  Bool_t resCanDir = conv && (conv->getGenerator(*convVar(),dummy)!=0) && conv->isDirectGenSafe(*convVar()) ;
  if (numAddDep>0 || !pdfCanDir || !resCanDir) {
    
    
    return new RooGenContext(*this,vars,prototype,auxProto,verbose) ;
  } 
  
  
  return new RooConvGenContext(*this,vars,prototype,auxProto,verbose) ;
}
Bool_t RooAbsAnaConvPdf::isDirectGenSafe(const RooAbsArg& arg) const 
{
  
  if (!TString(_convVar->GetName()).CompareTo(arg.GetName()) && 
      dynamic_cast<RooTruthModel*>(_model)) {
    return kTRUE ;
  }
  return RooAbsPdf::isDirectGenSafe(arg) ;
}
const RooRealVar* RooAbsAnaConvPdf::convVar() const
{
  
  RooResolutionModel* conv = (RooResolutionModel*) _convSet.at(0) ;
  if (!conv) return 0 ;  
  return &conv->convVar() ;
}
Double_t RooAbsAnaConvPdf::evaluate() const
{
  
  
  
  
  Double_t result(0) ;
  _convSetIter->Reset() ;
  RooAbsPdf* conv ;
  Int_t index(0) ;
  while(((conv=(RooAbsPdf*)_convSetIter->Next()))) {
    Double_t coef = coefficient(index++) ;
    if (coef!=0.) {
      Double_t c = conv->getVal(0) ;
      Double_t r = coef ;
      cxcoutD(Eval) << "RooAbsAnaConvPdf::evaluate(" << GetName() << ") val += coef*conv [" << index-1 << "/" << _convSet.getSize() << "] coef = " << r << " conv = " << c << endl ;
      result += conv->getVal(0)*coef ;
    } else {
      cxcoutD(Eval) << "RooAbsAnaConvPdf::evaluate(" << GetName() << ") [" << index-1 << "/" << _convSet.getSize() << "] coef = 0" << endl ;
    }
  }
  
  return result ;
}
Int_t RooAbsAnaConvPdf::getAnalyticalIntegralWN(RooArgSet& allVars, 
	  				        RooArgSet& analVars, const RooArgSet* normSet2, const char* ) const 
{
  
  if (allVars.getSize()==0) return 0 ;
  
  RooArgSet* allDeps = getObservables(allVars) ;
  RooArgSet* normSet = normSet2 ? getObservables(normSet2) : 0 ;
  RooAbsArg *arg ;
  RooResolutionModel *conv ;
  RooArgSet* intSetAll = new RooArgSet(*allDeps,"intSetAll") ;
  
  RooArgSet* intCoefSet = new RooArgSet("intCoefSet") ; 
  RooArgSet* intConvSet = new RooArgSet("intConvSet") ;
  TIterator* varIter  = intSetAll->createIterator() ;
  TIterator* convIter = _convSet.createIterator() ;
  while(((arg=(RooAbsArg*) varIter->Next()))) {
    Bool_t ok(kTRUE) ;
    convIter->Reset() ;
    while(((conv=(RooResolutionModel*) convIter->Next()))) {
      if (conv->dependsOn(*arg)) ok=kFALSE ;
    }
    
    if (ok) {
      intCoefSet->add(*arg) ;
    } else {
      intConvSet->add(*arg) ;
    }
    
  }
  delete varIter ;
  
  RooArgSet* normCoefSet = new RooArgSet("normCoefSet") ;  
  RooArgSet* normConvSet = new RooArgSet("normConvSet") ;
  RooArgSet* normSetAll = normSet ? (new RooArgSet(*normSet,"normSetAll")) : 0 ;
  if (normSetAll) {
    varIter  =  normSetAll->createIterator() ;
    while(((arg=(RooAbsArg*) varIter->Next()))) {
      Bool_t ok(kTRUE) ;
      convIter->Reset() ;
      while(((conv=(RooResolutionModel*) convIter->Next()))) {
	if (conv->dependsOn(*arg)) ok=kFALSE ;
      }
      
      if (ok) {
	normCoefSet->add(*arg) ;
      } else {
	normConvSet->add(*arg) ;
      }
      
    }
    delete varIter ;
  }
  delete convIter ;
  if (intCoefSet->getSize()==0) {
    delete intCoefSet ; intCoefSet=0 ;
  }
  if (intConvSet->getSize()==0) {
    delete intConvSet ; intConvSet=0 ;
  }
  if (normCoefSet->getSize()==0) {
    delete normCoefSet ; normCoefSet=0 ;
  }
  if (normConvSet->getSize()==0) {
    delete normConvSet ; normConvSet=0 ;
  }
  
  Int_t masterCode(0) ;
  Int_t tmp(0) ;
  masterCode = _codeReg.store(&tmp,1,intCoefSet,intConvSet,normCoefSet,normConvSet)+1 ; 
  analVars.add(*allDeps) ;
  delete allDeps ;
  if (normSet) delete normSet ;
  if (normSetAll) delete normSetAll ;
  delete intSetAll ;
  
  return masterCode  ;
}
Double_t RooAbsAnaConvPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const 
{
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  if (code==0) return getVal(normSet) ;
  
  RooArgSet *intCoefSet, *intConvSet, *normCoefSet, *normConvSet ;
  _codeReg.retrieve(code-1,intCoefSet,intConvSet,normCoefSet,normConvSet) ;
  
  RooResolutionModel* conv ;
  Int_t index(0) ;
  Double_t answer(0) ;
  _convSetIter->Reset() ;
  if (normCoefSet==0&&normConvSet==0) {
    
    Double_t integral(0) ;
    while(((conv=(RooResolutionModel*)_convSetIter->Next()))) {
      Double_t coef = getCoefNorm(index++,intCoefSet,rangeName) ; 
      
      if (coef!=0) {
	integral += coef*(rangeName ? conv->getNormObj(0,intConvSet,RooNameReg::ptr(rangeName))->getVal() :  conv->getNorm(intConvSet) ) ;       
	cxcoutD(Eval) << "RooAbsAnaConv::aiWN(" << GetName() << ") [" << index-1 << "] integral += " << conv->getNorm(intConvSet) << endl ;
      }
    }
    answer = integral ;
    
  } else {
    
    Double_t integral(0) ;
    Double_t norm(0) ;
    while(((conv=(RooResolutionModel*)_convSetIter->Next()))) {
      Double_t coefInt = getCoefNorm(index,intCoefSet,rangeName) ;
      Double_t term = (rangeName ? conv->getNormObj(0,intConvSet,RooNameReg::ptr(rangeName))->getVal() : conv->getNorm(intConvSet) ) ;
      
      if (coefInt!=0) integral += coefInt*term ;
      Double_t coefNorm = getCoefNorm(index,normCoefSet) ;
      term = conv->getNorm(normConvSet) ;
      
      if (coefNorm!=0) norm += coefNorm*term ;
      index++ ;
    }
    answer = integral/norm ;    
  }
  return answer ;
}
Int_t RooAbsAnaConvPdf::getCoefAnalyticalIntegral(Int_t , RooArgSet& , RooArgSet& , const char* ) const 
{
  
  
  return 0 ;
}
Double_t RooAbsAnaConvPdf::coefAnalyticalIntegral(Int_t coef, Int_t code, const char* ) const 
{
  
  
  if (code==0) return coefficient(coef) ;
  coutE(InputArguments) << "RooAbsAnaConvPdf::coefAnalyticalIntegral(" << GetName() << ") ERROR: unrecognized integration code: " << code << endl ;
  assert(0) ;
  return 1 ;
}
Bool_t RooAbsAnaConvPdf::forceAnalyticalInt(const RooAbsArg& ) const
{
  
  
  
  
  
  
  
  
  return kTRUE ;
}                                                                                                                         
               
Double_t RooAbsAnaConvPdf::getCoefNorm(Int_t coefIdx, const RooArgSet* nset, const char* rangeName) const 
{
  if (nset==0) return coefficient(coefIdx) ;
  CacheElem* cache = (CacheElem*) _coefNormMgr.getObj(nset,0,0,RooNameReg::ptr(rangeName)) ;
  if (!cache) {
    cache = new CacheElem ;
    
    Int_t i ;
    makeCoefVarList(cache->_coefVarList) ;  
    for (i=0 ; i<cache->_coefVarList.getSize() ; i++) {
      RooAbsReal* coefInt = static_cast<RooAbsReal&>(*cache->_coefVarList.at(i)).createIntegral(*nset,rangeName) ;
      cache->_normList.addOwned(*coefInt) ;      
    }  
    _coefNormMgr.setObj(nset,0,cache,RooNameReg::ptr(rangeName)) ;
  }
  return ((RooAbsReal*)cache->_normList.at(coefIdx))->getVal() ;
}
void RooAbsAnaConvPdf::makeCoefVarList(RooArgList& varList) const
{
  
  
  for (Int_t i=0 ; i<_convSet.getSize() ; i++) {
    RooArgSet* cvars = coefVars(i) ;
    RooAbsReal* coefVar = new RooConvCoefVar(Form("%s_coefVar_%d",GetName(),i),"coefVar",*this,i,cvars) ;
    varList.addOwned(*coefVar) ;
    delete cvars ;
  }
  
}
RooArgSet* RooAbsAnaConvPdf::coefVars(Int_t ) const 
{
  RooArgSet* coefVars = getParameters((RooArgSet*)0) ;
  TIterator* iter = coefVars->createIterator() ;
  RooAbsArg* arg ;
  Int_t i ;
  while(((arg=(RooAbsArg*)iter->Next()))) {
    for (i=0 ; i<_convSet.getSize() ; i++) {
      if (_convSet.at(i)->dependsOn(*arg)) {
	coefVars->remove(*arg,kTRUE) ;
      }
    }
  }
  delete iter ;  
  return coefVars ;
}
void RooAbsAnaConvPdf::printToStream(ostream& os, PrintOption opt, TString indent) const {
  
  
  
  
  RooAbsPdf::printToStream(os,opt,indent);
  if(opt >= Verbose) {
    os << indent << "--- RooAbsAnaConvPdf ---" << endl;
    TIterator* iter = _convSet.createIterator() ;
    RooResolutionModel* conv ;
    while (((conv=(RooResolutionModel*)iter->Next()))) {
      conv->printToStream(os,Verbose,"    ") ;
    }
  }
}
Last update: Thu Jan 17 08:43:25 2008
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.