00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "RooFit.h"
00014
00015 #include "Riostream.h"
00016 #include "Riostream.h"
00017 #include <math.h>
00018
00019 #include "RooStats/HistFactory/PiecewiseInterpolation.h"
00020 #include "RooAbsReal.h"
00021 #include "RooAbsPdf.h"
00022 #include "RooErrorHandler.h"
00023 #include "RooArgSet.h"
00024 #include "RooNLLVar.h"
00025 #include "RooChi2Var.h"
00026 #include "RooMsgService.h"
00027
00028 ClassImp(PiecewiseInterpolation)
00029 ;
00030
00031
00032
00033 PiecewiseInterpolation::PiecewiseInterpolation()
00034 {
00035 _lowIter = _lowSet.createIterator() ;
00036 _highIter = _highSet.createIterator() ;
00037 _paramIter = _paramSet.createIterator() ;
00038 _positiveDefinite=false;
00039 }
00040
00041
00042
00043
00044 PiecewiseInterpolation::PiecewiseInterpolation(const char* name, const char* title, const RooAbsReal& nominal,
00045 const RooArgList& lowSet,
00046 const RooArgList& highSet,
00047 const RooArgList& paramSet,
00048 Bool_t takeOwnership) :
00049 RooAbsReal(name, title),
00050 _nominal("!nominal","nominal value", this, (RooAbsReal&)nominal),
00051 _lowSet("!lowSet","low-side variation",this),
00052 _highSet("!highSet","high-side variation",this),
00053 _paramSet("!paramSet","high-side variation",this),
00054 _positiveDefinite(false)
00055 {
00056
00057
00058
00059
00060
00061
00062 _lowIter = _lowSet.createIterator() ;
00063 _highIter = _highSet.createIterator() ;
00064 _paramIter = _paramSet.createIterator() ;
00065
00066
00067 if (lowSet.getSize() != highSet.getSize()) {
00068 coutE(InputArguments) << "PiecewiseInterpolation::ctor(" << GetName() << ") ERROR: input lists should be of equal length" << endl ;
00069 RooErrorHandler::softAbort() ;
00070 }
00071
00072 TIterator* inputIter1 = lowSet.createIterator() ;
00073 RooAbsArg* comp ;
00074 while((comp = (RooAbsArg*)inputIter1->Next())) {
00075 if (!dynamic_cast<RooAbsReal*>(comp)) {
00076 coutE(InputArguments) << "PiecewiseInterpolation::ctor(" << GetName() << ") ERROR: component " << comp->GetName()
00077 << " in first list is not of type RooAbsReal" << endl ;
00078 RooErrorHandler::softAbort() ;
00079 }
00080 _lowSet.add(*comp) ;
00081 if (takeOwnership) {
00082 _ownedList.addOwned(*comp) ;
00083 }
00084 }
00085 delete inputIter1 ;
00086
00087
00088 TIterator* inputIter2 = highSet.createIterator() ;
00089 while((comp = (RooAbsArg*)inputIter2->Next())) {
00090 if (!dynamic_cast<RooAbsReal*>(comp)) {
00091 coutE(InputArguments) << "PiecewiseInterpolation::ctor(" << GetName() << ") ERROR: component " << comp->GetName()
00092 << " in first list is not of type RooAbsReal" << endl ;
00093 RooErrorHandler::softAbort() ;
00094 }
00095 _highSet.add(*comp) ;
00096 if (takeOwnership) {
00097 _ownedList.addOwned(*comp) ;
00098 }
00099 }
00100 delete inputIter2 ;
00101
00102
00103 TIterator* inputIter3 = paramSet.createIterator() ;
00104 while((comp = (RooAbsArg*)inputIter3->Next())) {
00105 if (!dynamic_cast<RooAbsReal*>(comp)) {
00106 coutE(InputArguments) << "PiecewiseInterpolation::ctor(" << GetName() << ") ERROR: component " << comp->GetName()
00107 << " in first list is not of type RooAbsReal" << endl ;
00108 RooErrorHandler::softAbort() ;
00109 }
00110 _paramSet.add(*comp) ;
00111 if (takeOwnership) {
00112 _ownedList.addOwned(*comp) ;
00113 }
00114 }
00115 delete inputIter3 ;
00116 }
00117
00118
00119
00120
00121 PiecewiseInterpolation::PiecewiseInterpolation(const PiecewiseInterpolation& other, const char* name) :
00122 RooAbsReal(other, name),
00123 _nominal("!nominal",this,other._nominal),
00124 _lowSet("!lowSet",this,other._lowSet),
00125 _highSet("!highSet",this,other._highSet),
00126 _paramSet("!paramSet",this,other._paramSet),
00127 _positiveDefinite(other._positiveDefinite)
00128 {
00129
00130
00131 _lowIter = _lowSet.createIterator() ;
00132 _highIter = _highSet.createIterator() ;
00133 _paramIter = _paramSet.createIterator() ;
00134
00135
00136 }
00137
00138
00139
00140
00141 PiecewiseInterpolation::~PiecewiseInterpolation()
00142 {
00143
00144
00145 if (_lowIter) delete _lowIter ;
00146 if (_highIter) delete _highIter ;
00147 if (_paramIter) delete _paramIter ;
00148 }
00149
00150
00151
00152
00153
00154 Double_t PiecewiseInterpolation::evaluate() const
00155 {
00156
00157
00158
00159 Double_t nominal = _nominal;
00160 Double_t sum(nominal) ;
00161 _lowIter->Reset() ;
00162 _highIter->Reset() ;
00163 _paramIter->Reset() ;
00164
00165
00166 RooAbsReal* param ;
00167 RooAbsReal* high ;
00168 RooAbsReal* low ;
00169
00170 int i=0;
00171
00172 while((param=(RooAbsReal*)_paramIter->Next())) {
00173 low = (RooAbsReal*)_lowIter->Next() ;
00174 high = (RooAbsReal*)_highIter->Next() ;
00175
00176
00177 if(param->getVal()>0)
00178 sum += param->getVal()*(high->getVal() - nominal );
00179 else
00180 sum += param->getVal()*(nominal - low->getVal());
00181
00182 ++i;
00183 }
00184
00185 if(_positiveDefinite && (sum<0)){
00186 sum = 1e-6;
00187 }
00188 return sum;
00189
00190 }
00191
00192
00193
00194 Int_t PiecewiseInterpolation::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars,
00195 const RooArgSet* normSet, const char* ) const
00196 {
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 if (allVars.getSize()==0) return 0 ;
00213 if (_forceNumInt) return 0 ;
00214
00215
00216
00217 analVars.add(allVars) ;
00218
00219
00220
00221
00222
00223
00224 Int_t sterileIdx(-1) ;
00225 CacheElem* cache = (CacheElem*) _normIntMgr.getObj(normSet,&analVars,&sterileIdx,0) ;
00226 if (cache) {
00227 return _normIntMgr.lastIndex()+1 ;
00228 }
00229
00230
00231 cache = new CacheElem ;
00232
00233
00234 RooAbsReal* param ;
00235 RooAbsReal *func ;
00236
00237
00238
00239 func = (RooAbsReal*)(&_nominal.arg()) ;
00240 RooAbsReal* funcInt = func->createIntegral(analVars) ;
00241 cache->_funcIntList.addOwned(*funcInt) ;
00242
00243
00244 _lowIter->Reset() ;
00245 _highIter->Reset() ;
00246 _paramIter->Reset() ;
00247 int i=0;
00248 while((param=(RooAbsReal*)_paramIter->Next())) {
00249 func = (RooAbsReal*)_lowIter->Next() ;
00250 funcInt = func->createIntegral(analVars) ;
00251 cache->_lowIntList.addOwned(*funcInt) ;
00252
00253 func = (RooAbsReal*)_highIter->Next() ;
00254 funcInt = func->createIntegral(analVars) ;
00255 cache->_highIntList.addOwned(*funcInt) ;
00256
00257 ++i;
00258 }
00259
00260
00261 Int_t code = _normIntMgr.setObj(normSet,&analVars,(RooAbsCacheElement*)cache,0) ;
00262
00263 return code+1 ;
00264 }
00265
00266
00267
00268
00269
00270 Double_t PiecewiseInterpolation::analyticalIntegralWN(Int_t code, const RooArgSet* ,const char* ) const
00271 {
00272
00273
00274
00275 CacheElem* cache = (CacheElem*) _normIntMgr.getObjByIndex(code-1) ;
00276
00277 TIterator* funcIntIter = cache->_funcIntList.createIterator() ;
00278 TIterator* lowIntIter = cache->_lowIntList.createIterator() ;
00279 TIterator* highIntIter = cache->_highIntList.createIterator() ;
00280 RooAbsReal *funcInt(0), *low(0), *high(0), *param(0) ;
00281 Double_t value(0) ;
00282 Double_t nominal(0);
00283
00284
00285 int i=0;
00286 while(( funcInt = (RooAbsReal*)funcIntIter->Next())) {
00287 value += funcInt->getVal() ;
00288 nominal = value;
00289 i++;
00290 }
00291 if(i==0 || i>1)
00292 cout << "problem, wrong number of nominal functions"<<endl;
00293
00294
00295 i = 0;
00296 _paramIter->Reset() ;
00297 while((param=(RooAbsReal*)_paramIter->Next())) {
00298 low = (RooAbsReal*)lowIntIter->Next() ;
00299 high = (RooAbsReal*)highIntIter->Next() ;
00300
00301
00302 if(param->getVal()>0)
00303 value += param->getVal()*(high->getVal() - nominal );
00304 else
00305 value += param->getVal()*(nominal - low->getVal());
00306
00307 ++i;
00308 }
00309
00310 return value;
00311
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358