96RooAbsOptTestStatistic::RooAbsOptTestStatistic(
const char *
name,
const char *title,
RooAbsReal &real,
98 RooAbsTestStatistic::Configuration
const &cfg)
99 : RooAbsTestStatistic(
name, title, real, indata, projDeps, cfg),
100 _integrateBinsPrecision(cfg.integrateOverBinsPrecision)
103 if (operMode() != Slave) {
107 initSlave(real, indata, projDeps, _rangeName.c_str(), _addCoefRangeName.c_str());
113RooAbsOptTestStatistic::RooAbsOptTestStatistic(
const RooAbsOptTestStatistic &other,
const char *
name)
114 : RooAbsTestStatistic(other,
name),
115 _sealed(other._sealed),
116 _sealNotice(other._sealNotice),
117 _skipZeroWeights(other._skipZeroWeights),
118 _integrateBinsPrecision(other._integrateBinsPrecision)
121 if (operMode() != Slave) {
123 if (other._normSet) {
125 other._normSet->
snapshot(*_normSet);
130 initSlave(*other._funcClone, *other._dataClone, other._projDeps ? *other._projDeps :
RooArgSet(),
131 other._rangeName.c_str(), other._addCoefRangeName.c_str());
139 const char* addCoefRangeName) {
146 _funcCloneSet = nullptr ;
149 _funcObsSet = std::unique_ptr<RooArgSet>{_funcClone->getObservables(indata)}.release();
151 if (_funcClone->getAttribute(
"BinnedLikelihood")) {
152 _funcClone->setAttribute(
"BinnedLikelihoodActive") ;
156 if (!projDeps.
empty()) {
157 std::unique_ptr<RooArgSet> projDataDeps{_funcObsSet->selectCommon(projDeps)};
158 projDataDeps->setAttribAll(
"projectedDependent") ;
170 _paramSet.add(*connPars) ;
174 _funcClone->getParameters(indata.
get(), _paramSet);
183 for (std::size_t i = 0; i < _funcObsSet->size(); ++i) {
185 if (realDepRLV && realDepRLV->isDerived()) {
187 realDepRLV->leafNodeServerList(&tmp2,
nullptr,
true);
188 _funcObsSet->
add(tmp2,
true);
200 for (
const auto arg : *_funcObsSet) {
204 if (!realReal) continue ;
206 if (!datReal) continue ;
211 coutE(InputArguments) <<
"RooAbsOptTestStatistic: ERROR minimum of FUNC observable " << arg->GetName()
212 <<
"(" << realReal->
getMin() <<
") is smaller than that of "
213 << arg->GetName() <<
" in the dataset (" << datReal->
getMin() <<
")" << std::endl ;
219 coutE(InputArguments) <<
"RooAbsOptTestStatistic: ERROR maximum of FUNC observable " << arg->GetName()
220 <<
" is larger than that of " << arg->GetName() <<
" in the dataset" << std::endl ;
227 if (rangeName && strlen(rangeName)) {
240 std::unique_ptr<RooArgSet> origObsSet( real.
getObservables(indata) );
241 if (rangeName && strlen(rangeName)) {
242 cxcoutI(Fitting) <<
"RooAbsOptTestStatistic::ctor(" << GetName() <<
") constructing test statistic for sub-range named " << rangeName << std::endl ;
244 if(
auto pdfClone =
dynamic_cast<RooAbsPdf*
>(_funcClone)) {
245 pdfClone->setNormRange(rangeName);
249 for (
const auto arg : *_funcObsSet) {
251 if (
auto realObs =
dynamic_cast<RooRealVar*
>(arg)) {
254 for(std::string
const& token : tokens) {
255 if(!realObs->hasRange(token.c_str())) {
256 std::stringstream errMsg;
257 errMsg <<
"The observable \"" << realObs->GetName() <<
"\" doesn't define the requested range \""
258 << token <<
"\". Replacing it with the default range." << std::endl;
259 coutI(Fitting) << errMsg.str() << std::endl;
275 if (rangeName && strlen(rangeName)) {
278 _funcClone->fixAddCoefNormalization(*_dataClone->get(),
false) ;
280 if (addCoefRangeName && strlen(addCoefRangeName)) {
281 cxcoutI(Fitting) <<
"RooAbsOptTestStatistic::ctor(" << GetName()
282 <<
") fixing interpretation of coefficients of any RooAddPdf component to range " << addCoefRangeName << std::endl ;
283 _funcClone->fixAddCoefRange(addCoefRangeName,
false) ;
289 _dataClone->attachBuffers(*_funcObsSet) ;
290 setEventCount(_dataClone->numEntries()) ;
300 if (!projDeps.
empty()) {
303 projDeps.
snapshot(*_projDeps,
false) ;
306 _normSet->
remove(*_projDeps,
true,
true) ;
310 _funcObsSet->selectCommon(*_projDeps, projDataDeps);
315 coutI(Optimization) <<
"RooAbsOptTestStatistic::ctor(" << GetName() <<
") optimizing internal clone of p.d.f for likelihood evaluation."
316 <<
"Lazy evaluation and associated change tracking will disabled for all nodes that depend on observables" << std::endl ;
327 _funcClone->getVal(_normSet) ;
334 if(_takeGlobalObservablesFromData && _data->getGlobalObservables()) {
335 recursiveRedirectServers(*_data->getGlobalObservables()) ;
344RooAbsOptTestStatistic::~RooAbsOptTestStatistic()
346 if (operMode()==Slave) {
366double RooAbsOptTestStatistic::combinedValue(
RooAbsReal** array,
Int_t n)
const
371 for (
Int_t i = 0; i <
n; ++i) {
373 carry +=
reinterpret_cast<RooAbsOptTestStatistic*
>(array[i])->getCarry();
375 const double t =
sum +
y;
376 carry = (t -
sum) -
y;
388bool RooAbsOptTestStatistic::redirectServersHook(
const RooAbsCollection& newServerList,
bool mustReplaceAll,
bool nameChange,
bool isRecursive)
390 RooAbsTestStatistic::redirectServersHook(newServerList,mustReplaceAll,nameChange,isRecursive) ;
391 if (operMode()!=Slave)
return false ;
392 bool ret = _funcClone->recursiveRedirectServers(newServerList,
false,nameChange) ;
401void RooAbsOptTestStatistic::printCompactTreeHook(
ostream& os,
const char*
indent)
403 RooAbsTestStatistic::printCompactTreeHook(os,
indent) ;
404 if (operMode()!=Slave)
return ;
406 indent2 +=
"opt >>" ;
407 _funcClone->printCompactTree(os,indent2.Data()) ;
408 os << indent2 <<
" dataset clone = " << _dataClone <<
" first obs = " << _dataClone->get()->first() << std::endl ;
420void RooAbsOptTestStatistic::constOptimizeTestStatistic(ConstOpCode opcode,
bool doAlsoTrackingOpt)
422 static bool hasWarned =
false;
424 std::stringstream ss;
425 ss <<
"Deprecated constant term optimization detected,\n"
426 <<
"enabled via RooFit::Optimize() or RooMinimizer::optimizeConst():\n"
427 <<
" This functionality only affects the legacy evaluation backend.\n"
428 <<
" The vectorized CPU backend performs const term optimization automatically.\n"
429 <<
" The option is ignored and will be removed in ROOT 6.42.\n"
430 <<
" Should your fit not be possible without the legacy backend, please open a GitHub issue.\n";
431 oocoutW(
static_cast<RooAbsArg *
>(
nullptr), InputArguments) << ss.str() << std::endl;
438 RooAbsTestStatistic::constOptimizeTestStatistic(opcode,doAlsoTrackingOpt);
439 if (operMode()!=Slave)
return ;
441 if (_dataClone->hasFilledCache() && _dataClone->store()->cacheOwner()!=
this) {
442 if (opcode==Activate) {
443 cxcoutW(Optimization) <<
"RooAbsOptTestStatistic::constOptimize(" << GetName()
444 <<
") dataset cache is owned by another object, no constant term optimization can be applied" << std::endl ;
449 if (!allowFunctionCache()) {
450 if (opcode==Activate) {
451 cxcoutI(Optimization) <<
"RooAbsOptTestStatistic::constOptimize(" << GetName()
452 <<
") function caching prohibited by test statistic, no constant term optimization is applied" << std::endl ;
457 if (_dataClone->hasFilledCache() && opcode==Activate) {
463 cxcoutI(Optimization) <<
"RooAbsOptTestStatistic::constOptimize(" << GetName()
464 <<
") optimizing evaluation of test statistic by finding all nodes in p.d.f that depend exclusively"
465 <<
" on observables and constant parameters and precalculating their values" << std::endl ;
466 optimizeConstantTerms(
true,doAlsoTrackingOpt) ;
470 cxcoutI(Optimization) <<
"RooAbsOptTestStatistic::constOptimize(" << GetName()
471 <<
") deactivating optimization of constant terms in test statistic" << std::endl ;
472 optimizeConstantTerms(
false) ;
476 cxcoutI(Optimization) <<
"RooAbsOptTestStatistic::constOptimize(" << GetName()
477 <<
") one ore more parameter were changed from constant to floating or vice versa, "
478 <<
"re-evaluating constant term optimization" << std::endl ;
479 optimizeConstantTerms(
false) ;
480 optimizeConstantTerms(
true,doAlsoTrackingOpt) ;
484 cxcoutI(Optimization) <<
"RooAbsOptTestStatistic::constOptimize(" << GetName()
485 <<
") the value of one ore more constant parameter were changed re-evaluating constant term optimization" << std::endl ;
487 _dataClone->store()->forceCacheUpdate() ;
507void RooAbsOptTestStatistic::optimizeCaching()
513 _funcClone->getVal(_normSet) ;
516 _funcClone->optimizeCacheMode(*_funcObsSet) ;
519 _dataClone->setDirtyProp(
false) ;
522 _dataClone->optimizeReadingWithCaching(*_funcClone,
RooArgSet(),requiredExtraObservables()) ;
536void RooAbsOptTestStatistic::optimizeConstantTerms(
bool activate,
bool applyTrackingOpt)
546 _funcClone->getVal(_normSet) ;
550 if (_funcClone->getAttribute(
"NoOptimizeLevel1")) {
551 coutI(Minimization) <<
" Optimization customization: Level-1 constant-term optimization prohibited by attribute NoOptimizeLevel1 set on top-level pdf "
552 << _funcClone->ClassName() <<
"::" << _funcClone->GetName() << std::endl ;
555 if (_funcClone->getAttribute(
"NoOptimizeLevel2")) {
556 coutI(Minimization) <<
" Optimization customization: Level-2 constant-term optimization prohibited by attribute NoOptimizeLevel2 set on top-level pdf "
557 << _funcClone->ClassName() <<
"::" << _funcClone->GetName() << std::endl ;
558 applyTrackingOpt=false ;
570 if (applyTrackingOpt) {
572 coutW(Optimization) <<
"RooAbsOptTestStatistic::optimizeConstantTerms(" << GetName()
573 <<
") WARNING Cache-and-track optimization (Optimize level 2) is only available for datasets"
574 <<
" implement in terms of RooVectorDataStore - ignoring this option for current dataset" << std::endl ;
575 applyTrackingOpt = false ;
579 if (applyTrackingOpt) {
581 _funcClone->branchNodeServerList(&branches) ;
582 for (
auto arg : branches) {
583 arg->setCacheAndTrackHints(trackNodes);
586 trackNodes.
remove(*std::unique_ptr<RooAbsCollection>{trackNodes.
selectByAttrib(
"Constant",
true)});
595 _funcClone->findConstantNodes(*_dataClone->get(),_cachedNodes) ;
598 _dataClone->cacheArgs(
this,_cachedNodes,_normSet, _skipZeroWeights);
601 for (
auto cacheArg : _cachedNodes) {
605 std::unique_ptr<RooAbsCollection> constNodes{_cachedNodes.selectByAttrib(
"ConstantExpressionCached",
true)};
606 RooArgSet actualTrackNodes(_cachedNodes) ;
607 actualTrackNodes.remove(*constNodes) ;
608 if (!constNodes->empty()) {
609 if (constNodes->size()<20) {
610 coutI(Minimization) <<
" The following expressions have been identified as constant and will be precalculated and cached: " << *constNodes << std::endl ;
612 coutI(Minimization) <<
" A total of " << constNodes->size() <<
" expressions have been identified as constant and will be precalculated and cached." << std::endl ;
615 if (!actualTrackNodes.empty()) {
616 if (actualTrackNodes.size()<20) {
617 coutI(Minimization) <<
" The following expressions will be evaluated in cache-and-track mode: " << actualTrackNodes << std::endl ;
619 coutI(Minimization) <<
" A total of " << constNodes->size() <<
" expressions will be evaluated in cache-and-track-mode." << std::endl ;
624 _dataClone->optimizeReadingWithCaching(*_funcClone, _cachedNodes,requiredExtraObservables()) ;
631 _dataClone->resetCache() ;
634 _dataClone->setArgStatus(*_dataClone->get(),
true) ;
640 _dataClone->setDirtyProp(
false) ;
642 _cachedNodes.removeAll() ;
656bool RooAbsOptTestStatistic::setDataSlave(
RooAbsData& indata,
bool cloneData,
bool ownNewData)
659 if (operMode()==SimMaster) {
673 std::unique_ptr<RooAbsData> oldOwnedData;
675 oldOwnedData.reset(_dataClone);
676 _dataClone = nullptr ;
679 if (!cloneData && !_rangeName.empty()) {
680 coutW(InputArguments) <<
"RooAbsOptTestStatistic::setData(" << GetName() <<
") WARNING: test statistic was constructed with range selection on data, "
681 <<
"ignoring request to _not_ clone the input dataset" << std::endl ;
693 _dataClone = &indata ;
694 _ownData = ownNewData ;
699 _dataClone->attachBuffers(*_funcObsSet) ;
700 _dataClone->setDirtyProp(
false) ;
704 if (!_cachedNodes.empty()) {
705 _dataClone->cacheArgs(
this,_cachedNodes,_normSet, _skipZeroWeights);
716 if(_takeGlobalObservablesFromData && _data->getGlobalObservables()) {
717 recursiveRedirectServers(*_data->getGlobalObservables()) ;
731 bool notice = (sealNotice() && strlen(sealNotice())) ;
732 coutW(ObjectHandling) <<
"RooAbsOptTestStatistic::data(" << GetName()
733 <<
") WARNING: object sealed by creator - access to data is not permitted: "
734 << (notice?sealNotice():
"<no user notice>") << std::endl ;
744const RooAbsData& RooAbsOptTestStatistic::data()
const
747 bool notice = (sealNotice() && strlen(sealNotice())) ;
748 coutW(ObjectHandling) <<
"RooAbsOptTestStatistic::data(" << GetName()
749 <<
") WARNING: object sealed by creator - access to data is not permitted: "
750 << (notice?sealNotice():
"<no user notice>") << std::endl ;
765void RooAbsOptTestStatistic::setUpBinSampling() {
767 auto& pdf =
static_cast<RooAbsPdf&
>(*_funcClone);
769 newPdf->addOwnedComponents(*_funcClone);
770 _funcClone = newPdf.release();
778const char* RooAbsOptTestStatistic::cacheUniqueSuffix()
const {
779 return Form(
"_%lx", _dataClone->uniqueId().value()) ;
783void RooAbsOptTestStatistic::runRecalculateCache(std::size_t firstEvent, std::size_t lastEvent, std::size_t stepSize)
const
785 _dataClone->store()->recalculateCache(_projDeps, firstEvent, lastEvent, stepSize, _skipZeroWeights);
int Int_t
Signed integer 4 bytes (int).
static void indent(ostringstream &buf, int indent_level)
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Common abstract base class for objects that represent a value and a "shape" in RooFit.
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
virtual RooAbsReal * highBoundFunc() const
Return pointer to RooAbsReal parameterized upper bound, if any.
virtual RooAbsReal * lowBoundFunc() const
Return pointer to RooAbsReal parameterized lower bound, if any.
Abstract container object that can hold multiple RooAbsArg objects.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
void setAttribAll(const Text_t *name, bool value=true)
Set given attribute in each element of the collection by calling each elements setAttribute() functio...
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for binned and unbinned datasets.
virtual const RooArgSet * get() const
RooFit::OwningPtr< RooAbsData > reduce(const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create a reduced copy of this dataset.
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Abstract interface for all probability density functions.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
virtual double getMin(const char *name=nullptr) const
Get minimum of currently defined range.
Abstract base class for objects that represent a real value and implements functionality common to al...
virtual double getValV(const RooArgSet *normalisationSet=nullptr) const
Return value of object.
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
Function that is called at the end of redirectServers().
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
RooArgSet * selectByAttrib(const char *name, bool value) const
Use RooAbsCollection::selectByAttrib(), but return as RooArgSet.
static std::unique_ptr< RooAbsPdf > create(RooAbsPdf &pdf, RooAbsData const &data, double precision)
Creates a wrapping RooBinSamplingPdf if appropriate.
Container class to hold unbinned data.
static void softAbort()
Soft abort function that interrupts macro execution but doesn't kill ROOT.
Efficient implementation of a product of PDFs of the form.
RooArgSet * getConnectedParameters(const RooArgSet &observables) const
Return all parameter constraint p.d.f.s on parameters listed in constrainedParams.
Variable that can be changed from the outside.
const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false, bool shared=true) const override
Return binning definition with name.
Uses std::vector to store data columns.
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
const char * GetName() const override
Returns name of object.
RooCmdArg SelectVars(const RooArgSet &vars)
RooCmdArg CutRange(const char *rangeName)
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
std::unique_ptr< T > cloneTreeWithSameParameters(T const &arg, RooArgSet const *observables=nullptr)
Clone RooAbsArg object and reattach to original parameters.
static uint64_t sum(uint64_t i)