// Class RooParamBinning is an implementation of RooAbsBinning that constructs
// a binning with a range definition that depends on external RooAbsReal objects.
// The external RooAbsReal definitions are explicitly allowed to depend on other
// observables and parameters, and make it possible to define non-rectangular
// range definitions in RooFit. Objects of class RooParamBinning are made
// by the RooRealVar::setRange() that takes RooAbsReal references as arguments
// END_HTML
#include "RooFit.h"
#include "RooParamBinning.h"
#include "RooParamBinning.h"
#include "RooMsgService.h"
#include "Riostream.h"
using namespace std;
ClassImp(RooParamBinning)
;
RooParamBinning::RooParamBinning(const char* name) :
RooAbsBinning(name), _xlo(0), _xhi(0), _nbins(100), _binw(0), _lp(0), _owner(0)
{
_array = 0 ;
}
RooParamBinning::RooParamBinning(RooAbsReal& xloIn, RooAbsReal& xhiIn, Int_t nBins, const char* name) :
RooAbsBinning(name),
_array(0),
_xlo(&xloIn),
_xhi(&xhiIn),
_nbins(nBins),
_binw(0),
_lp(0),
_owner(0)
{
}
RooParamBinning::~RooParamBinning()
{
if (_array) delete[] _array ;
if (_lp) delete _lp ;
}
RooParamBinning::RooParamBinning(const RooParamBinning& other, const char* name) :
RooAbsBinning(name), _binw(0), _owner(0)
{
_array = 0 ;
if (other._lp) {
_xlo = (RooAbsReal*) other._lp->at(0) ;
_xhi = (RooAbsReal*) other._lp->at(1) ;
} else {
_xlo = other._xlo ;
_xhi = other._xhi ;
}
_nbins = other._nbins ;
_lp = 0 ;
}
void RooParamBinning::insertHook(RooAbsRealLValue& owner) const
{
_owner = &owner ;
if (_lp) {
_xlo = xlo() ;
_xhi = xhi() ;
delete _lp ;
}
_lp = new RooListProxy(Form("range::%s",GetName()),"lp",&owner,kFALSE,kTRUE) ;
_lp->add(*_xlo) ;
_lp->add(*_xhi) ;
_xlo = 0 ;
_xhi = 0 ;
}
void RooParamBinning::removeHook(RooAbsRealLValue& ) const
{
_owner = 0 ;
if (_lp) {
_xlo = xlo() ;
_xhi = xhi() ;
delete _lp ;
_lp = 0 ;
}
}
void RooParamBinning::setRange(Double_t newxlo, Double_t newxhi)
{
if (newxlo>newxhi) {
coutE(InputArguments) << "RooParamBinning::setRange: ERROR low bound > high bound" << endl ;
return ;
}
RooAbsRealLValue* xlolv = dynamic_cast<RooAbsRealLValue*>(xlo()) ;
if (xlolv) {
xlolv->setVal(newxlo) ;
} else {
coutW(InputArguments) << "RooParamBinning::setRange: WARNING lower bound not represented by lvalue, cannot set lower bound value through setRange()" << endl ;
}
RooAbsRealLValue* xhilv = dynamic_cast<RooAbsRealLValue*>(xhi()) ;
if (xhilv) {
xhilv->setVal(newxhi) ;
} else {
coutW(InputArguments) << "RooParamBinning::setRange: WARNING upper bound not represented by lvalue, cannot set upper bound value through setRange()" << endl ;
}
}
Int_t RooParamBinning::binNumber(Double_t x) const
{
if (x >= xhi()->getVal()) return _nbins-1 ;
if (x < xlo()->getVal()) return 0 ;
return Int_t((x - xlo()->getVal())/averageBinWidth()) ;
}
Double_t RooParamBinning::binCenter(Int_t i) const
{
if (i<0 || i>=_nbins) {
coutE(InputArguments) << "RooParamBinning::binCenter ERROR: bin index " << i
<< " is out of range (0," << _nbins-1 << ")" << endl ;
return 0 ;
}
return xlo()->getVal() + (i + 0.5)*averageBinWidth() ;
}
Double_t RooParamBinning::binWidth(Int_t ) const
{
return (xhi()->getVal()-xlo()->getVal())/_nbins ;
}
Double_t RooParamBinning::binLow(Int_t i) const
{
if (i<0 || i>=_nbins) {
coutE(InputArguments) << "RooParamBinning::binLow ERROR: bin index " << i
<< " is out of range (0," << _nbins-1 << ")" << endl ;
return 0 ;
}
return xlo()->getVal() + i*binWidth(i) ;
}
Double_t RooParamBinning::binHigh(Int_t i) const
{
if (i<0 || i>=_nbins) {
coutE(InputArguments) << "RooParamBinning::fitBinHigh ERROR: bin index " << i
<< " is out of range (0," << _nbins-1 << ")" << endl ;
return 0 ;
}
return xlo()->getVal() + (i + 1)*binWidth(i) ;
}
Double_t* RooParamBinning::array() const
{
if (_array) delete[] _array ;
_array = new Double_t[_nbins+1] ;
Int_t i ;
for (i=0 ; i<=_nbins ; i++) {
_array[i] = xlo()->getVal() + i*binWidth(i) ;
}
return _array ;
}
void RooParamBinning::printMultiline(ostream &os, Int_t , Bool_t , TString indent) const
{
os << indent << "_xlo = " << _xlo << endl ;
os << indent << "_xhi = " << _xhi << endl ;
if (_lp) {
os << indent << "xlo() = " << xlo() << endl ;
os << indent << "xhi() = " << xhi() << endl ;
}
if (xlo()) {
xlo()->Print("t") ;
}
if (xhi()) {
xhi()->Print("t") ;
}
}