33 ClassImp(PiecewiseInterpolation);
39 PiecewiseInterpolation::PiecewiseInterpolation()
41 _positiveDefinite=
false;
49 PiecewiseInterpolation::PiecewiseInterpolation(
const char* name,
const char* title,
const RooAbsReal& nominal,
50 const RooArgList& lowSet,
51 const RooArgList& highSet,
52 const RooArgList& paramSet,
53 Bool_t takeOwnership) :
54 RooAbsReal(name, title),
55 _nominal(
"!nominal",
"nominal value", this, (RooAbsReal&)nominal),
56 _lowSet(
"!lowSet",
"low-side variation",this),
57 _highSet(
"!highSet",
"high-side variation",this),
58 _paramSet(
"!paramSet",
"high-side variation",this),
59 _positiveDefinite(false)
69 if (lowSet.getSize() != highSet.getSize()) {
70 coutE(InputArguments) <<
"PiecewiseInterpolation::ctor(" << GetName() <<
") ERROR: input lists should be of equal length" << endl ;
71 RooErrorHandler::softAbort() ;
74 RooFIter inputIter1 = lowSet.fwdIterator() ;
76 while((comp = inputIter1.next())) {
77 if (!dynamic_cast<RooAbsReal*>(comp)) {
78 coutE(InputArguments) <<
"PiecewiseInterpolation::ctor(" << GetName() <<
") ERROR: component " << comp->GetName()
79 <<
" in first list is not of type RooAbsReal" << endl ;
80 RooErrorHandler::softAbort() ;
84 _ownedList.addOwned(*comp) ;
89 RooFIter inputIter2 = highSet.fwdIterator() ;
90 while((comp = inputIter2.next())) {
91 if (!dynamic_cast<RooAbsReal*>(comp)) {
92 coutE(InputArguments) <<
"PiecewiseInterpolation::ctor(" << GetName() <<
") ERROR: component " << comp->GetName()
93 <<
" in first list is not of type RooAbsReal" << endl ;
94 RooErrorHandler::softAbort() ;
98 _ownedList.addOwned(*comp) ;
103 RooFIter inputIter3 = paramSet.fwdIterator() ;
104 while((comp = inputIter3.next())) {
105 if (!dynamic_cast<RooAbsReal*>(comp)) {
106 coutE(InputArguments) <<
"PiecewiseInterpolation::ctor(" << GetName() <<
") ERROR: component " << comp->GetName()
107 <<
" in first list is not of type RooAbsReal" << endl ;
108 RooErrorHandler::softAbort() ;
110 _paramSet.add(*comp) ;
112 _ownedList.addOwned(*comp) ;
114 _interpCode.push_back(0);
119 specialIntegratorConfig(kTRUE)->method1D().setLabel(
"RooBinIntegrator") ;
128 PiecewiseInterpolation::PiecewiseInterpolation(
const PiecewiseInterpolation& other,
const char* name) :
129 RooAbsReal(other, name),
130 _nominal(
"!nominal",this,other._nominal),
131 _lowSet(
"!lowSet",this,other._lowSet),
132 _highSet(
"!highSet",this,other._highSet),
133 _paramSet(
"!paramSet",this,other._paramSet),
134 _positiveDefinite(other._positiveDefinite),
135 _interpCode(other._interpCode)
146 PiecewiseInterpolation::~PiecewiseInterpolation()
157 Double_t PiecewiseInterpolation::evaluate()
const
160 Double_t nominal = _nominal;
161 Double_t sum(nominal) ;
163 for (
unsigned int i=0; i < _paramSet.size(); ++i) {
164 auto param =
static_cast<RooAbsReal*
>(_paramSet.at(i));
165 auto low =
static_cast<RooAbsReal*
>(_lowSet.at(i));
166 auto high =
static_cast<RooAbsReal*
>(_highSet.at(i));
167 Int_t icode = _interpCode[i] ;
172 if(param->getVal()>0)
173 sum += param->getVal()*(high->getVal() - nominal );
175 sum += param->getVal()*(nominal - low->getVal());
180 if(param->getVal()>=0)
181 sum *= pow(high->getVal()/nominal, +param->getVal());
183 sum *= pow(low->getVal()/nominal, -param->getVal());
188 double a = 0.5*(high->getVal()+low->getVal())-nominal;
189 double b = 0.5*(high->getVal()-low->getVal());
191 if(param->getVal()>1 ){
192 sum += (2*a+b)*(param->getVal()-1)+high->getVal()-nominal;
193 }
else if(param->getVal()<-1 ) {
194 sum += -1*(2*a-b)*(param->getVal()+1)+low->getVal()-nominal;
196 sum += a*pow(param->getVal(),2) + b*param->getVal()+c;
202 double a = 0.5*(high->getVal()+low->getVal())-nominal;
203 double b = 0.5*(high->getVal()-low->getVal());
205 if(param->getVal()>1 ){
206 sum += (2*a+b)*(param->getVal()-1)+high->getVal()-nominal;
207 }
else if(param->getVal()<-1 ) {
208 sum += -1*(2*a-b)*(param->getVal()+1)+low->getVal()-nominal;
210 sum += a*pow(param->getVal(),2) + b*param->getVal()+c;
221 double x = param->getVal();
223 sum += x*(high->getVal() - nominal );
225 sum += x*(nominal - low->getVal());
227 double eps_plus = high->getVal() - nominal;
228 double eps_minus = nominal - low->getVal();
229 double S = 0.5 * (eps_plus + eps_minus);
230 double A = 0.0625 * (eps_plus - eps_minus);
234 double val = nominal + x * (S + x * A * ( 15 + x * x * (-10 + x * x * 3 ) ) );
237 if (val < 0) val = 0;
247 double x = param->getVal();
249 if (x > x0 || x < -x0)
252 sum += x*(high->getVal() - nominal );
254 sum += x*(nominal - low->getVal());
256 else if (nominal != 0)
258 double eps_plus = high->getVal() - nominal;
259 double eps_minus = nominal - low->getVal();
260 double S = (eps_plus + eps_minus)/2;
261 double A = (eps_plus - eps_minus)/2;
265 double b = 3*A/(2*x0);
267 double d = -A/(2*x0*x0*x0);
269 double val = nominal + a*x + b*pow(x, 2) + 0 + d*pow(x, 4);
270 if (val < 0) val = 0;
279 coutE(InputArguments) <<
"PiecewiseInterpolation::evaluate ERROR: " << param->GetName()
280 <<
" with unknown interpolation code" << icode << endl ;
286 if(_positiveDefinite && (sum<0)){
294 cxcoutD(Tracing) <<
"PiecewiseInterpolation::evaluate - sum < 0, not forcing positive definite"<<endl;
302 Bool_t PiecewiseInterpolation::setBinIntegrator(RooArgSet& allVars)
304 if(allVars.getSize()==1){
305 RooAbsReal* temp =
const_cast<PiecewiseInterpolation*
>(
this);
306 temp->specialIntegratorConfig(kTRUE)->method1D().setLabel(
"RooBinIntegrator") ;
307 int nbins = ((RooRealVar*) allVars.first())->numBins();
308 temp->specialIntegratorConfig(kTRUE)->getConfigSection(
"RooBinIntegrator").setRealValue(
"numBins",nbins);
311 cout <<
"Currently BinIntegrator only knows how to deal with 1-d "<<endl;
320 Int_t PiecewiseInterpolation::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars,
321 const RooArgSet* normSet,
const char* )
const
336 if (allVars.getSize()==0)
return 0 ;
337 if (_forceNumInt)
return 0 ;
346 RooFIter paramIterExtra(_paramSet.fwdIterator()) ;
348 while( paramIterExtra.next() ) {
349 if(!_interpCode.empty() && _interpCode[i]!=0){
351 cout <<
"can't factorize integral"<<endl;
358 analVars.add(allVars) ;
365 Int_t sterileIdx(-1) ;
366 CacheElem* cache = (CacheElem*) _normIntMgr.getObj(normSet,&analVars,&sterileIdx) ;
368 return _normIntMgr.lastIndex()+1 ;
372 cache =
new CacheElem ;
379 func = (RooAbsReal*)(&_nominal.arg()) ;
380 RooAbsReal* funcInt = func->createIntegral(analVars) ;
381 cache->_funcIntList.addOwned(*funcInt) ;
384 RooFIter lowIter(_lowSet.fwdIterator()) ;
385 RooFIter highIter(_highSet.fwdIterator()) ;
386 RooFIter paramIter(_paramSet.fwdIterator()) ;
390 while(paramIter.next() ) {
391 func = (RooAbsReal*)lowIter.next() ;
392 funcInt = func->createIntegral(analVars) ;
393 cache->_lowIntList.addOwned(*funcInt) ;
395 func = (RooAbsReal*)highIter.next() ;
396 funcInt = func->createIntegral(analVars) ;
397 cache->_highIntList.addOwned(*funcInt) ;
402 Int_t code = _normIntMgr.setObj(normSet,&analVars,(RooAbsCacheElement*)cache,0) ;
414 Double_t PiecewiseInterpolation::analyticalIntegralWN(Int_t code,
const RooArgSet* ,
const char* )
const
486 CacheElem* cache = (CacheElem*) _normIntMgr.getObjByIndex(code-1) ;
488 std::cout <<
"Error: Cache Element is NULL" << std::endl;
489 throw std::exception();
493 RooFIter funcIntIter = cache->_funcIntList.fwdIterator() ;
494 RooFIter lowIntIter = cache->_lowIntList.fwdIterator() ;
495 RooFIter highIntIter = cache->_highIntList.fwdIterator() ;
496 RooAbsReal *funcInt(0), *low(0), *high(0), *param(0) ;
502 while(( funcInt = (RooAbsReal*)funcIntIter.next())) {
503 value += funcInt->getVal() ;
507 if(i==0 || i>1) { cout <<
"problem, wrong number of nominal functions"<<endl; }
511 RooFIter paramIter(_paramSet.fwdIterator()) ;
514 while( (param=(RooAbsReal*)paramIter.next()) ) {
515 low = (RooAbsReal*)lowIntIter.next() ;
516 high = (RooAbsReal*)highIntIter.next() ;
518 if(param->getVal()>0) {
519 value += param->getVal()*(high->getVal() - nominal );
521 value += param->getVal()*(nominal - low->getVal());
597 void PiecewiseInterpolation::setInterpCode(RooAbsReal& param,
int code){
598 int index = _paramSet.index(¶m);
600 coutE(InputArguments) <<
"PiecewiseInterpolation::setInterpCode ERROR: " << param.GetName()
601 <<
" is not in list" << endl ;
603 coutW(InputArguments) <<
"PiecewiseInterpolation::setInterpCode : " << param.GetName()
604 <<
" is now " << code << endl ;
605 _interpCode.at(index) = code;
612 void PiecewiseInterpolation::setAllInterpCodes(
int code){
613 for(
unsigned int i=0; i<_interpCode.size(); ++i){
614 _interpCode.at(i) = code;
621 void PiecewiseInterpolation::printAllInterpCodes(){
622 for(
unsigned int i=0; i<_interpCode.size(); ++i){
623 coutI(InputArguments) <<
"interp code for " << _paramSet.at(i)->GetName() <<
" = " << _interpCode.at(i) <<endl;
631 std::list<Double_t>* PiecewiseInterpolation::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi)
const
633 return _nominal.arg().binBoundaries(obs,xlo,xhi) ;
640 Bool_t PiecewiseInterpolation::isBinnedDistribution(
const RooArgSet& obs)
const
642 return _nominal.arg().isBinnedDistribution(obs) ;
649 std::list<Double_t>* PiecewiseInterpolation::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi)
const
651 return _nominal.arg().plotSamplingHint(obs,xlo,xhi) ;
657 void PiecewiseInterpolation::Streamer(TBuffer &R__b)
659 if (R__b.IsReading()) {
660 R__b.ReadClassBuffer(PiecewiseInterpolation::Class(),
this);
661 specialIntegratorConfig(kTRUE)->method1D().setLabel(
"RooBinIntegrator") ;
662 if (_interpCode.empty()) _interpCode.resize(_paramSet.getSize());
664 R__b.WriteClassBuffer(PiecewiseInterpolation::Class(),
this);
674 void PiecewiseInterpolation::printMetaArgs(ostream& os) const
681 Bool_t first(kTRUE) ;
683 RooAbsArg* arg1, *arg2 ;
684 if (_highSet.getSize()!=0) {
686 while((arg1=(RooAbsArg*)_lowIter->Next())) {
692 arg2=(RooAbsArg*)_highIter->Next() ;
693 os << arg1->GetName() << " * " << arg2->GetName() ;
698 while((arg1=(RooAbsArg*)_lowIter->Next())) {
704 os << arg1->GetName() ;