00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "RooFit.h"
00033
00034 #include "RooXYChi2Var.h"
00035 #include "RooDataSet.h"
00036 #include "RooAbsReal.h"
00037
00038 #include "Riostream.h"
00039
00040 #include "RooRealVar.h"
00041
00042 #include "RooGaussKronrodIntegrator1D.h"
00043 #include "RooRealBinding.h"
00044 #include "RooNumIntFactory.h"
00045
00046 ClassImp(RooXYChi2Var)
00047 ;
00048
00049
00050
00051 RooXYChi2Var::RooXYChi2Var()
00052 {
00053
00054 _funcInt = 0 ;
00055 _rrvIter = _rrvArgs.createIterator() ;
00056 }
00057
00058
00059
00060 RooXYChi2Var::RooXYChi2Var(const char *name, const char* title, RooAbsReal& func, RooDataSet& xydata, Bool_t integrate) :
00061 RooAbsOptTestStatistic(name,title,func,xydata,RooArgSet(),0,0,1,1,0,0),
00062 _extended(kFALSE),
00063 _integrate(integrate),
00064 _intConfig(*defaultIntegratorConfig()),
00065 _funcInt(0)
00066 {
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 _extended = kFALSE ;
00081 _yvar = 0 ;
00082
00083 initialize() ;
00084 }
00085
00086
00087
00088 RooXYChi2Var::RooXYChi2Var(const char *name, const char* title, RooAbsReal& func, RooDataSet& xydata, RooRealVar& yvar, Bool_t integrate) :
00089 RooAbsOptTestStatistic(name,title,func,xydata,RooArgSet(),0,0,1,1,0,0),
00090 _extended(kFALSE),
00091 _integrate(integrate),
00092 _intConfig(*defaultIntegratorConfig()),
00093 _funcInt(0)
00094 {
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 _extended = kFALSE ;
00108 _yvar = (RooRealVar*) _dataClone->get()->find(yvar.GetName()) ;
00109
00110 initialize() ;
00111 }
00112
00113
00114
00115 RooXYChi2Var::RooXYChi2Var(const char *name, const char* title, RooAbsPdf& extPdf, RooDataSet& xydata, Bool_t integrate) :
00116 RooAbsOptTestStatistic(name,title,extPdf,xydata,RooArgSet(),0,0,1,1,0,0),
00117 _extended(kTRUE),
00118 _integrate(integrate),
00119 _intConfig(*defaultIntegratorConfig()),
00120 _funcInt(0)
00121 {
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 if (!extPdf.canBeExtended()) {
00138 throw(string(Form("RooXYChi2Var::ctor(%s) ERROR: Input p.d.f. must be an extendible",GetName()))) ;
00139 }
00140 _yvar = 0 ;
00141 initialize() ;
00142 }
00143
00144
00145
00146
00147
00148 RooXYChi2Var::RooXYChi2Var(const char *name, const char* title, RooAbsPdf& extPdf, RooDataSet& xydata, RooRealVar& yvar, Bool_t integrate) :
00149 RooAbsOptTestStatistic(name,title,extPdf,xydata,RooArgSet(),0,0,1,1,0,0),
00150 _extended(kTRUE),
00151 _integrate(integrate),
00152 _intConfig(*defaultIntegratorConfig()),
00153 _funcInt(0)
00154 {
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 if (!extPdf.canBeExtended()) {
00171 throw(string(Form("RooXYChi2Var::ctor(%s) ERROR: Input p.d.f. must be an extendible",GetName()))) ;
00172 }
00173 _yvar = (RooRealVar*) _dataClone->get()->find(yvar.GetName()) ;
00174 initialize() ;
00175 }
00176
00177
00178
00179
00180
00181 RooXYChi2Var::RooXYChi2Var(const RooXYChi2Var& other, const char* name) :
00182 RooAbsOptTestStatistic(other,name),
00183 _extended(other._extended),
00184 _integrate(other._integrate),
00185 _intConfig(other._intConfig),
00186 _funcInt(0)
00187 {
00188
00189
00190 _yvar = other._yvar ? (RooRealVar*) _dataClone->get()->find(other._yvar->GetName()) : 0 ;
00191 initialize() ;
00192
00193 }
00194
00195
00196
00197
00198
00199 void RooXYChi2Var::initialize()
00200 {
00201
00202
00203 TIterator* iter = _dataClone->get()->createIterator() ;
00204 RooAbsArg* arg ;
00205 while((arg=(RooAbsArg*)iter->Next())) {
00206 RooRealVar* var = dynamic_cast<RooRealVar*>(arg) ;
00207 if (var) {
00208 _rrvArgs.add(*var) ;
00209 }
00210 }
00211 delete iter ;
00212 _rrvIter = _rrvArgs.createIterator() ;
00213
00214
00215
00216
00217 _intConfig.setEpsRel(1e-7) ;
00218 _intConfig.setEpsAbs(1e-7) ;
00219 _intConfig.method1D().setLabel("RooGaussKronrodIntegrator1D") ;
00220 _intConfig.methodND().setLabel("RooAdaptiveIntegratorND") ;
00221
00222 initIntegrator() ;
00223
00224 }
00225
00226
00227
00228
00229 void RooXYChi2Var::initIntegrator()
00230 {
00231
00232
00233 if (!_funcInt) {
00234 _funcInt = _funcClone->createIntegral(_rrvArgs,_rrvArgs,_intConfig,"bin") ;
00235 _rrvIter->Reset() ;
00236 RooRealVar* x ;
00237 while((x=(RooRealVar*)_rrvIter->Next())) {
00238 _binList.push_back(&x->getBinning("bin",kFALSE,kTRUE)) ;
00239 }
00240 }
00241
00242 }
00243
00244
00245
00246
00247 RooXYChi2Var::~RooXYChi2Var()
00248 {
00249
00250
00251 delete _rrvIter ;
00252 if (_funcInt) delete _funcInt ;
00253 }
00254
00255
00256
00257
00258
00259 Double_t RooXYChi2Var::xErrorContribution(Double_t ydata) const
00260 {
00261
00262
00263
00264 RooRealVar* var ;
00265 Double_t ret(0) ;
00266 _rrvIter->Reset() ;
00267 while((var=(RooRealVar*)_rrvIter->Next())) {
00268
00269 if (var->hasAsymError()) {
00270
00271
00272 Double_t cxval = var->getVal() ;
00273 Double_t xerrLo = -var->getAsymErrorLo() ;
00274 Double_t xerrHi = var->getAsymErrorHi() ;
00275 Double_t xerr = (xerrLo+xerrHi)/2 ;
00276
00277
00278 var->setVal(cxval - xerr/100) ;
00279 Double_t fxmin = fy() ;
00280
00281
00282 var->setVal(cxval + xerr/100) ;
00283 Double_t fxmax = fy() ;
00284
00285
00286 Double_t slope = (fxmax-fxmin)/(2*xerr/100.) ;
00287
00288
00289 if ((ydata>cxval && fxmax>fxmin) || (ydata<=cxval && fxmax<=fxmin)) {
00290
00291 ret += pow(xerrHi*slope,2) ;
00292 } else {
00293
00294 ret += pow(xerrLo*slope,2) ;
00295 }
00296
00297 } else if (var->hasError()) {
00298
00299
00300 Double_t cxval = var->getVal() ;
00301 Double_t xerr = var->getError() ;
00302
00303
00304 var->setVal(cxval - xerr/100) ;
00305 Double_t fxmin = fy() ;
00306
00307
00308 var->setVal(cxval + xerr/100) ;
00309 Double_t fxmax = fy() ;
00310
00311
00312 Double_t slope = (fxmax-fxmin)/(2*xerr/100.) ;
00313
00314
00315 ret += pow(xerr*slope,2) ;
00316 }
00317 }
00318 return ret ;
00319 }
00320
00321
00322
00323
00324
00325 Double_t RooXYChi2Var::fy() const
00326 {
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 Double_t yfunc ;
00339 if (!_integrate) {
00340 yfunc = _funcClone->getVal(_dataClone->get()) ;
00341 } else {
00342 Double_t volume(1) ;
00343 _rrvIter->Reset() ;
00344 for (list<RooAbsBinning*>::const_iterator iter = _binList.begin() ; iter != _binList.end() ; iter++) {
00345 RooRealVar* x = (RooRealVar*) _rrvIter->Next() ;
00346 Double_t xmin = x->getVal() + x->getErrorLo() ;
00347 Double_t xmax = x->getVal() + x->getErrorHi() ;
00348 (*iter)->setRange(xmin,xmax) ;
00349 x->setShapeDirty() ;
00350 volume *= (xmax - xmin) ;
00351 }
00352 Double_t ret = _funcInt->getVal() ;
00353 return ret / volume ;
00354 }
00355 if (_extended) {
00356 RooAbsPdf* pdf = (RooAbsPdf*) _funcClone ;
00357
00358 yfunc *= pdf->expectedEvents(_dataClone->get()) ;
00359 }
00360 return yfunc ;
00361 }
00362
00363
00364
00365
00366 Double_t RooXYChi2Var::evaluatePartition(Int_t firstEvent, Int_t lastEvent, Int_t stepSize) const
00367 {
00368
00369
00370 Double_t result(0) ;
00371
00372
00373 RooDataSet* xydata = (RooDataSet*) _dataClone ;
00374
00375 for (Int_t i=firstEvent ; i<lastEvent ; i+=stepSize) {
00376
00377
00378 xydata->get(i);
00379
00380 if (!xydata->valid()) {
00381 continue ;
00382 }
00383
00384
00385 Double_t yfunc = fy() ;
00386
00387
00388 Double_t ydata ;
00389 Double_t eylo,eyhi ;
00390 if (_yvar) {
00391 ydata = _yvar->getVal() ;
00392 eylo = -1*_yvar->getErrorLo() ;
00393 eyhi = _yvar->getErrorHi() ;
00394 } else {
00395 ydata = xydata->weight() ;
00396 xydata->weightError(eylo,eyhi) ;
00397 }
00398
00399
00400 Double_t eExt = yfunc-ydata ;
00401
00402
00403 Double_t eInt = (eExt>0) ? eyhi : eylo ;
00404
00405
00406 Double_t eIntX2 = _integrate ? 0 : xErrorContribution(ydata) ;
00407
00408
00409 if (eInt==0.) {
00410 coutE(Eval) << "RooXYChi2Var::RooXYChi2Var(" << GetName() << ") INFINITY ERROR: data point " << i
00411 << " has zero error, but function is not zero (f=" << yfunc << ")" << endl ;
00412 return 0 ;
00413 }
00414
00415
00416 result += eExt*eExt/(eInt*eInt+ eIntX2) ;
00417 }
00418
00419 return result ;
00420 }
00421
00422
00423
00424 RooArgSet RooXYChi2Var::requiredExtraObservables() const
00425 {
00426
00427 if (_yvar) return RooArgSet(*_yvar) ;
00428 return RooArgSet() ;
00429 }
00430
00431
00432