58 ClassImp(RooAbsTestStatistic);
63 RooAbsTestStatistic::RooAbsTestStatistic() :
64 _func(0), _data(0), _projDeps(0), _splitRange(0), _simCount(0),
65 _verbose(kFALSE), _init(kFALSE), _gofOpMode(Slave), _nEvents(0), _setNum(0),
66 _numSets(0), _extSet(0), _nGof(0), _gofArray(0), _nCPU(1), _mpfeArray(0),
67 _mpinterl(RooFit::BulkPartition), _doOffset(kFALSE), _offset(0),
68 _offsetCarry(0), _evalCarry(0)
99 RooAbsTestStatistic::RooAbsTestStatistic(
const char *name,
const char *title, RooAbsReal& real, RooAbsData& data,
100 const RooArgSet& projDeps,
const char* rangeName,
const char* addCoefRangeName,
101 Int_t nCPU, RooFit::MPSplit interleave, Bool_t verbose, Bool_t splitCutRange) :
102 RooAbsReal(name,title),
103 _paramSet(
"paramSet",
"Set of parameters",this),
106 _projDeps((RooArgSet*)projDeps.Clone()),
107 _rangeName(rangeName?rangeName:
""),
108 _addCoefRangeName(addCoefRangeName?addCoefRangeName:
""),
109 _splitRange(splitCutRange),
116 _mpinterl(interleave),
123 RooArgSet* params = real.getParameters(&data) ;
124 _paramSet.add(*params) ;
127 if (_nCPU>1 || _nCPU==-1) {
133 _gofOpMode = MPMaster ;
138 Bool_t simMode =
dynamic_cast<RooSimultaneous*
>(&real)?kTRUE:kFALSE ;
141 _gofOpMode = SimMaster ;
151 _nEvents = data.numEntries() ;
159 RooAbsTestStatistic::RooAbsTestStatistic(
const RooAbsTestStatistic& other,
const char* name) :
160 RooAbsReal(other,name),
161 _paramSet(
"paramSet",
"Set of parameters",this),
164 _projDeps((RooArgSet*)other._projDeps->Clone()),
165 _rangeName(other._rangeName),
166 _addCoefRangeName(other._addCoefRangeName),
167 _splitRange(other._splitRange),
169 _verbose(other._verbose),
172 _gofSplitMode(other._gofSplitMode),
175 _mpinterl(other._mpinterl),
176 _doOffset(other._doOffset),
177 _offset(other._offset),
178 _offsetCarry(other._offsetCarry),
179 _evalCarry(other._evalCarry)
182 _paramSet.add(other._paramSet) ;
184 if (_nCPU>1 || _nCPU==-1) {
190 _gofOpMode = MPMaster ;
195 Bool_t simMode =
dynamic_cast<RooSimultaneous*
>(_func)?kTRUE:kFALSE ;
198 _gofOpMode = SimMaster ;
208 _nEvents = _data->numEntries() ;
218 RooAbsTestStatistic::~RooAbsTestStatistic()
220 if (MPMaster == _gofOpMode && _init) {
221 for (Int_t i = 0; i < _nCPU; ++i)
delete _mpfeArray[i];
222 delete[] _mpfeArray ;
225 if (SimMaster == _gofOpMode && _init) {
226 for (Int_t i = 0; i < _nGof; ++i)
delete _gofArray[i];
243 Double_t RooAbsTestStatistic::evaluate()
const
247 const_cast<RooAbsTestStatistic*
>(
this)->initialize() ;
250 if (SimMaster == _gofOpMode) {
254 if (_mpinterl == RooFit::BulkPartition || _mpinterl == RooFit::Interleave ) {
255 ret = combinedValue((RooAbsReal**)_gofArray,_nGof);
257 Double_t sum = 0., carry = 0.;
258 for (Int_t i = 0 ; i < _nGof; ++i) {
259 if (i % _numSets == _setNum || (_mpinterl==RooFit::Hybrid && _gofSplitMode[i] != RooFit::SimComponents )) {
260 Double_t y = _gofArray[i]->getValV();
261 carry += _gofArray[i]->getCarry();
263 const Double_t t = sum + y;
264 carry = (t - sum) - y;
274 const Double_t norm = globalNormalization();
281 }
else if (MPMaster == _gofOpMode) {
284 for (Int_t i = 0; i < _nCPU; ++i) _mpfeArray[i]->calculate();
287 Double_t sum(0), carry = 0.;
288 for (Int_t i = 0; i < _nCPU; ++i) {
289 Double_t y = _mpfeArray[i]->getValV();
290 carry += _mpfeArray[i]->getCarry();
292 const Double_t t = sum + y;
293 carry = (t - sum) - y;
304 Int_t nFirst(0), nLast(_nEvents), nStep(1) ;
307 case RooFit::BulkPartition:
308 nFirst = _nEvents * _setNum / _numSets ;
309 nLast = _nEvents * (_setNum+1) / _numSets ;
313 case RooFit::Interleave:
319 case RooFit::SimComponents:
326 throw(std::string(
"this should never happen")) ;
330 Double_t ret = evaluatePartition(nFirst,nLast,nStep);
333 const Double_t norm = globalNormalization();
350 Bool_t RooAbsTestStatistic::initialize()
352 if (_init)
return kFALSE;
354 if (MPMaster == _gofOpMode) {
355 initMPMode(_func,_data,_projDeps,_rangeName.size()?_rangeName.c_str():0,_addCoefRangeName.size()?_addCoefRangeName.c_str():0) ;
356 }
else if (SimMaster == _gofOpMode) {
357 initSimMode((RooSimultaneous*)_func,_data,_projDeps,_rangeName.size()?_rangeName.c_str():0,_addCoefRangeName.size()?_addCoefRangeName.c_str():0) ;
368 Bool_t RooAbsTestStatistic::redirectServersHook(
const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t)
370 if (SimMaster == _gofOpMode && _gofArray) {
372 for (Int_t i = 0; i < _nGof; ++i) {
374 _gofArray[i]->recursiveRedirectServers(newServerList,mustReplaceAll,nameChange);
377 }
else if (MPMaster == _gofOpMode&& _mpfeArray) {
379 for (Int_t i = 0; i < _nCPU; ++i) {
381 _mpfeArray[i]->recursiveRedirectServers(newServerList,mustReplaceAll,nameChange);
395 void RooAbsTestStatistic::printCompactTreeHook(ostream& os,
const char* indent)
397 if (SimMaster == _gofOpMode) {
399 os << indent <<
"RooAbsTestStatistic begin GOF contents" << endl ;
400 for (Int_t i = 0; i < _nGof; ++i) {
402 TString indent2(indent);
403 indent2 += Form(
"[%d] ",i);
404 _gofArray[i]->printCompactTreeHook(os,indent2);
407 os << indent <<
"RooAbsTestStatistic end GOF contents" << endl;
408 }
else if (MPMaster == _gofOpMode) {
419 void RooAbsTestStatistic::constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt)
422 if (SimMaster == _gofOpMode) {
424 for (Int_t i = 0; i < _nGof; ++i) {
426 RooFit::MPSplit effSplit = (_mpinterl!=RooFit::Hybrid) ? _mpinterl : _gofSplitMode[i];
427 if ( (i % _numSets == _setNum) || (effSplit != RooFit::SimComponents) ) {
428 if (_gofArray[i]) _gofArray[i]->constOptimizeTestStatistic(opcode,doAlsoTrackingOpt);
431 }
else if (MPMaster == _gofOpMode) {
432 for (Int_t i = 0; i < _nCPU; ++i) {
433 _mpfeArray[i]->constOptimizeTestStatistic(opcode,doAlsoTrackingOpt);
443 void RooAbsTestStatistic::setMPSet(Int_t inSetNum, Int_t inNumSets)
445 _setNum = inSetNum; _numSets = inNumSets;
446 _extSet = _mpinterl==RooFit::SimComponents ? _setNum : (_numSets - 1);
448 if (SimMaster == _gofOpMode) {
451 for (Int_t i = 0; i < _nGof; ++i) {
452 if (_gofArray[i]) _gofArray[i]->setMPSet(inSetNum,inNumSets);
463 void RooAbsTestStatistic::initMPMode(RooAbsReal* real, RooAbsData* data,
const RooArgSet* projDeps,
const char* rangeName,
const char* addCoefRangeName)
465 _mpfeArray =
new pRooRealMPFE[_nCPU];
468 RooAbsTestStatistic* gof = create(GetName(),GetTitle(),*real,*data,*projDeps,rangeName,addCoefRangeName,1,_mpinterl,_verbose,_splitRange);
469 gof->recursiveRedirectServers(_paramSet);
471 for (Int_t i = 0; i < _nCPU; ++i) {
472 gof->setMPSet(i,_nCPU);
473 gof->SetName(Form(
"%s_GOF%d",GetName(),i));
474 gof->SetTitle(Form(
"%s_GOF%d",GetTitle(),i));
476 ccoutD(Eval) <<
"RooAbsTestStatistic::initMPMode: starting remote server process #" << i << endl;
477 _mpfeArray[i] =
new RooRealMPFE(Form(
"%s_%lx_MPFE%d",GetName(),(ULong_t)
this,i),Form(
"%s_%lx_MPFE%d",GetTitle(),(ULong_t)
this,i),*gof,
false);
479 _mpfeArray[i]->initialize();
481 _mpfeArray[i]->followAsSlave(*_mpfeArray[0]);
484 _mpfeArray[_nCPU - 1]->addOwnedComponents(*gof);
485 coutI(Eval) <<
"RooAbsTestStatistic::initMPMode: started " << _nCPU <<
" remote server process." << endl;
498 void RooAbsTestStatistic::initSimMode(RooSimultaneous* simpdf, RooAbsData* data,
499 const RooArgSet* projDeps,
const char* rangeName,
const char* addCoefRangeName)
502 RooAbsCategoryLValue& simCat = (RooAbsCategoryLValue&) simpdf->indexCat();
504 TString simCatName(simCat.GetName());
505 TList* dsetList =
const_cast<RooAbsData*
>(data)->split(simCat,processEmptyDataSets());
507 coutE(Fitting) <<
"RooAbsTestStatistic::initSimMode(" << GetName() <<
") ERROR: index category of simultaneous pdf is missing in dataset, aborting" << endl;
508 throw std::string(
"RooAbsTestStatistic::initSimMode() ERROR, index category of simultaneous pdf is missing in dataset, aborting");
516 TIterator* catIter = simCat.typeIterator();
517 while ((type = (RooCatType*) catIter->Next())) {
519 RooAbsPdf* pdf = simpdf->getPdf(type->GetName());
520 RooAbsData* dset = (RooAbsData*) dsetList->FindObject(type->GetName());
522 if (pdf && dset && (0. != dset->sumEntries() || processEmptyDataSets())) {
528 _gofArray =
new pRooAbsTestStatistic[_nGof];
529 _gofSplitMode.resize(_nGof);
533 while ((type = (RooCatType*) catIter->Next())) {
535 RooAbsPdf* pdf = simpdf->getPdf(type->GetName());
536 RooAbsData* dset = (RooAbsData*) dsetList->FindObject(type->GetName());
538 if (pdf && dset && (0. != dset->sumEntries() || processEmptyDataSets())) {
539 ccoutI(Fitting) <<
"RooAbsTestStatistic::initSimMode: creating slave calculator #" << n <<
" for state " << type->GetName()
540 <<
" (" << dset->numEntries() <<
" dataset entries)" << endl;
545 RooAbsPdf* binnedPdf = 0 ;
546 Bool_t binnedL = kFALSE ;
547 if (pdf->getAttribute(
"BinnedLikelihood") && pdf->IsA()->InheritsFrom(RooRealSumPdf::Class())) {
551 }
else if (pdf->IsA()->InheritsFrom(RooProdPdf::Class())) {
553 RooFIter iter = ((RooProdPdf*)pdf)->pdfList().fwdIterator() ;
554 RooAbsArg* component ;
555 while ((component = iter.next())) {
556 if (component->getAttribute(
"BinnedLikelihood") && component->IsA()->InheritsFrom(RooRealSumPdf::Class())) {
557 binnedPdf = (RooAbsPdf*) component ;
560 if (component->getAttribute(
"MAIN_MEASUREMENT")) {
562 binnedPdf = (RooAbsPdf*) component ;
569 if (_splitRange && rangeName) {
570 _gofArray[n] = create(type->GetName(),type->GetName(),(binnedPdf?*binnedPdf:*pdf),*dset,*projDeps,
571 Form(
"%s_%s",rangeName,type->GetName()),addCoefRangeName,_nCPU*(_mpinterl?-1:1),_mpinterl,_verbose,_splitRange,binnedL);
573 _gofArray[n] = create(type->GetName(),type->GetName(),(binnedPdf?*binnedPdf:*pdf),*dset,*projDeps,
574 rangeName,addCoefRangeName,_nCPU,_mpinterl,_verbose,_splitRange,binnedL);
576 _gofArray[n]->setSimCount(_nGof);
580 if (_mpinterl==RooFit::Hybrid) {
581 if (dset->numEntries()<10) {
583 _gofSplitMode[n] = RooFit::SimComponents;
584 _gofArray[n]->_mpinterl = RooFit::SimComponents;
587 _gofSplitMode[n] = RooFit::BulkPartition;
588 _gofArray[n]->_mpinterl = RooFit::BulkPartition;
594 RooArgSet *actualParams = binnedPdf ? binnedPdf->getParameters(dset) : pdf->getParameters(dset);
595 RooArgSet* selTargetParams = (RooArgSet*) _paramSet.selectCommon(*actualParams);
597 _gofArray[n]->recursiveRedirectServers(*selTargetParams);
599 delete selTargetParams;
605 if ((!dset || (0. != dset->sumEntries() && !processEmptyDataSets())) && pdf) {
607 ccoutD(Fitting) <<
"RooAbsTestStatistic::initSimMode: state " << type->GetName()
608 <<
" has no data entries, no slave calculator created" << endl;
613 coutI(Fitting) <<
"RooAbsTestStatistic::initSimMode: created " << n <<
" slave calculators." << endl;
626 Bool_t RooAbsTestStatistic::setData(RooAbsData& indata, Bool_t cloneData)
629 if (isOffsetting()) {
630 enableOffsetting(kFALSE);
631 enableOffsetting(kTRUE);
637 return setDataSlave(indata, cloneData);
641 if (indata.canSplitFast()) {
642 for (Int_t i = 0; i < _nGof; ++i) {
643 RooAbsData* compData = indata.getSimData(_gofArray[i]->GetName());
644 _gofArray[i]->setDataSlave(*compData, cloneData);
646 }
else if (0 == indata.numEntries()) {
648 for (Int_t i = 0; i < _nGof; ++i) {
649 _gofArray[i]->setDataSlave(indata, cloneData);
652 const RooAbsCategoryLValue& indexCat =
static_cast<RooSimultaneous*
>(_func)->indexCat();
653 TList* dlist = indata.split(indexCat, kTRUE);
655 coutF(DataHandling) <<
"Tried to split '" << indata.GetName() <<
"' into categories of '" << indexCat.GetName()
656 <<
"', but splitting failed. Input data:" << std::endl;
658 throw std::runtime_error(
"Error when setting up test statistic: dataset couldn't be split into categories.");
661 for (Int_t i = 0; i < _nGof; ++i) {
662 RooAbsData* compData = (RooAbsData*) dlist->FindObject(_gofArray[i]->GetName());
665 _gofArray[i]->setDataSlave(*compData,kFALSE,kTRUE);
667 coutE(DataHandling) <<
"RooAbsTestStatistic::setData(" << GetName() <<
") ERROR: Cannot find component data for state " << _gofArray[i]->GetName() << endl;
674 coutF(DataHandling) <<
"RooAbsTestStatistic::setData(" << GetName() <<
") FATAL: setData() is not supported in multi-processor mode" << endl;
675 throw std::runtime_error(
"RooAbsTestStatistic::setData is not supported in MPMaster mode");
684 void RooAbsTestStatistic::enableOffsetting(Bool_t flag)
688 const_cast<RooAbsTestStatistic*
>(
this)->initialize() ;
703 for (Int_t i = 0; i < _nGof; ++i) {
704 _gofArray[i]->enableOffsetting(flag);
709 for (Int_t i = 0; i < _nCPU; ++i) {
710 _mpfeArray[i]->enableOffsetting(flag);
717 Double_t RooAbsTestStatistic::getCarry()
const
718 {
return _evalCarry; }