61 if (exclLVBranches.
empty())
75 if (!(exclLVBranches.
find(client->GetName()) == client)) {
76 if (allBranches.
find(client->GetName()) == client) {
77 if (!servesExclusively(client, exclLVBranches, allBranches)) {
88 return (numLVServ == 1);
92 ServerToAdd(RooAbsArg *theArg,
bool isShape) : arg{theArg}, isShapeServer{isShape} {}
93 RooAbsArg *arg =
nullptr;
94 bool isShapeServer =
false;
97void addObservableToServers(
RooAbsReal const &function,
RooAbsArg &leaf, std::vector<ServerToAdd> &serversToAdd,
98 const char *rangeName)
101 if (leaflv && leaflv->getBinning(rangeName).isParameterized()) {
104 <<
" has parameterized binning, add value dependence of boundary objects rather than shape of leaf"
106 if (leaflv->getBinning(rangeName).lowBoundFunc()) {
107 serversToAdd.emplace_back(leaflv->getBinning(rangeName).lowBoundFunc(),
false);
109 if (leaflv->getBinning(rangeName).highBoundFunc()) {
110 serversToAdd.emplace_back(leaflv->getBinning(rangeName).highBoundFunc(),
false);
114 <<
" as shape dependent" << std::endl;
115 serversToAdd.emplace_back(&leaf,
true);
119void addParameterToServers(
RooAbsReal const &function,
RooAbsArg &leaf, std::vector<ServerToAdd> &serversToAdd,
122 if (!isShapeServer) {
124 <<
" as value dependent" << std::endl;
127 <<
" as shape dependent" << std::endl;
129 serversToAdd.emplace_back(&leaf, isShapeServer);
132enum class MarkedState { Dependent, Independent, AlreadyAdded };
135void unmarkDepValueClients(
RooAbsArg const &dep,
RooArgSet const &args, std::vector<MarkedState> &marked)
137 assert(args.
size() == marked.size());
138 auto index = args.
index(dep);
140 marked[index] = MarkedState::Dependent;
142 unmarkDepValueClients(*client, args, marked);
147std::vector<ServerToAdd>
148getValueAndShapeServers(
RooAbsReal const &function,
RooArgSet const &depList,
const char *rangeName)
150 std::vector<ServerToAdd> serversToAdd;
154 function.treeNodeServerList(&allArgsList,
nullptr,
true,
true,
false,
false);
160 function.treeNodeServerList(&allValueArgsList,
nullptr,
true,
true,
true,
false);
161 RooArgSet allValueArgs{allValueArgsList};
164 std::vector<MarkedState> marked(allArgs.
size(), MarkedState::Independent);
165 marked.back() = MarkedState::Dependent;
173 unmarkDepValueClients(*depInArgs, allArgs, marked);
174 addObservableToServers(function, *depInArgs, serversToAdd, rangeName);
180 for (std::size_t i = 0; i < allArgs.
size(); ++i) {
181 if (marked[i] == MarkedState::Dependent) {
182 for (
RooAbsArg *server : allArgs[i]->servers()) {
184 if (index >= 0 && marked[index] == MarkedState::Independent) {
185 addParameterToServers(function, *server, serversToAdd, !allValueArgs.
find(*server));
186 marked[index] = MarkedState::AlreadyAdded;
209 if (intDep->namePtr() != branch->namePtr() && branch->dependsOnValue(*intDep)) {
215 filteredIntDeps.
add(*intDep);
219 for (
const auto arg :
function.servers()) {
222 if (!arg->dependsOnValue(filteredIntDeps)) {
224 }
else if (!arg->isValueServer(function) && !arg->isShapeServer(function)) {
232 if (arg->isDerived()) {
235 if ((realArgLV && filteredIntDeps.
find(realArgLV->
GetName()) &&
243 bool overlapOK =
true;
244 for (
const auto otherArg :
function.servers()) {
250 if (arg->overlaps(*otherArg,
true)) {
264 anIntOKDepList.
add(*arg,
true);
266 <<
function.GetName() <<
": Observable " << arg->GetName()
267 <<
" is suitable for analytical integration (if supported by p.d.f)" << std::endl;
299 const char* rangeName) :
303 _sumList(
"!sumList",
"Categories to be summed numerically",this,false,false),
304 _intList(
"!intList",
"Variables to be integrated numerically",this,false,false),
305 _anaList(
"!anaList",
"Variables to be integrated analytically",this,false,false),
306 _jacList(
"!jacList",
"Jacobian product term",this,false,false),
307 _facList(
"!facList",
"Variables independent of function",this,false,true),
308 _function(
"!func",
"Function to be integrated",this,false,false),
310 _sumCat(
"!sumCat",
"SuperCategory for summation",this,false,false),
334 oocxcoutI(&function,Integration) <<
"RooRealIntegral::ctor(" <<
GetName() <<
") Constructing integral of function "
335 << function.GetName() <<
" over observables" << depList <<
" with normalization "
337 << (rangeName?rangeName:
"<none>") << std::endl ;
351 if (function.dependsOn(*nArg)) {
367 for (
auto arg : intDepList) {
368 if(!arg->isLValue()) {
373 if (!function.dependsOn(*arg)) {
374 std::unique_ptr<RooAbsArg> argClone{
static_cast<RooAbsArg*
>(arg->Clone())};
381 oocxcoutI(&function,Integration) << function.GetName() <<
": Factorizing observables are " <<
_facList << std::endl ;
392 RooArgSet exclLVBranches(
"exclLVBranches") ;
394 function.branchNodeServerList(&branchList) ;
397 function.treeNodeServerList(&branchListVDAll,
nullptr,
true,
false,
true);
402 for (
RooAbsArg *branch : branchListVDAll) {
403 if (branch != &function) {
407 branchListVD.
add(*branch,
true);
411 for (
auto branch: branchList) {
414 if ((realArgLV && (realArgLV->
isJacobianOK(intDepList)!=0)) || catArgLV) {
415 exclLVBranches.
add(*branch) ;
418 exclLVBranches.
remove(depList,
true,
true) ;
422 RooArgSet exclLVServers(
"exclLVServers") ;
423 function.getObservables(&intDepList, exclLVServers);
426 bool converged(
false) ;
431 std::vector<RooAbsArg*> toBeRemoved;
432 for (
auto server : exclLVServers) {
433 if (!servesExclusively(server,exclLVBranches,branchListVD)) {
434 toBeRemoved.push_back(server);
438 exclLVServers.remove(toBeRemoved.begin(), toBeRemoved.end());
442 for (std::size_t i=0; i < exclLVBranches.
size(); ++i) {
443 const RooAbsArg* branch = exclLVBranches[i];
447 bsList.
remove(exclLVServers,
true,
true) ;
448 if (!bsList.
empty()) {
449 exclLVBranches.
remove(*branch,
true,
true) ;
458 for (std::size_t i=0; i < exclLVBranches.
size(); ++i) {
459 const RooAbsArg* branch = exclLVBranches[i];
461 exclLVBranches.
remove(*branch,
true,
true) ;
468 if (!exclLVServers.
empty() && !function.isBinnedDistribution(exclLVBranches)) {
469 intDepList.
remove(exclLVServers) ;
470 intDepList.
add(exclLVBranches) ;
480 for (
auto arg : intDepList) {
481 if (function.forceAnalyticalInt(*arg)) {
482 anIntOKDepList.
add(*arg) ;
486 if (!anIntOKDepList.
empty()) {
487 oocxcoutI(&function,Integration) << function.GetName() <<
": Observables that function forcibly requires to be integrated internally " << anIntOKDepList << std::endl ;
496 auto serversToAdd = getValueAndShapeServers(function, depList, rangeName);
497 fillAnIntOKDepList(function, intDepList, anIntOKDepList, branchListVD);
514 oocxcoutI(&function,Integration) << function.GetName() <<
": Function integrated observables " <<
_anaList <<
" internally with code " <<
_mode << std::endl ;
540 std::unique_ptr<RooArgSet> argDepList{arg->getObservables(&intDepList)};
541 for (
const auto argDep : *argDepList) {
552 if (!exclLVServers.
empty()) {
554 intDepList.
remove(exclLVBranches) ;
555 intDepList.
add(exclLVServers) ;
561 for (
const auto arg : function.servers()) {
564 if (!
_anaList.find(arg->GetName()) && arg->dependsOn(intDepList)) {
573 auto argDeps = std::unique_ptr<RooArgSet>(arg->getObservables(&intDepList));
577 for (
const auto dep : *argDeps) {
587 oocxcoutI(&function,Integration) << function.GetName() <<
": Observables " <<
_anaList <<
" are analytically integrated with code " <<
_mode << std::endl ;
590 oocxcoutI(&function,Integration) << function.GetName() <<
": Observables " <<
_intList <<
" are numerically integrated" << std::endl ;
593 oocxcoutI(&function,Integration) << function.GetName() <<
": Observables " <<
_sumList <<
" are numerically summed" << std::endl ;
628 for(
auto const& toAdd : serversToAdd) {
629 addServer(*toAdd.arg, !toAdd.isShapeServer, toAdd.isShapeServer);
647 for (
const auto leaf : leafSet) {
689 coutE(Integration) <<
ClassName() <<
"::" <<
GetName() <<
": failed to create valid integrand." << std::endl;
699 coutE(Integration) <<
ClassName() <<
"::" <<
GetName() <<
": failed to create valid integrator." << std::endl;
703 cxcoutI(NumericIntegration) <<
"RooRealIntegral::init(" <<
GetName() <<
") using numeric integrator "
704 << integratorName <<
" to calculate Int" <<
_intList << std::endl ;
707 cxcoutI(NumericIntegration) <<
"RooRealIntegral::init(" <<
GetName() <<
") evaluation requires " <<
_intList.size() <<
"-D numeric integration step. Evaluation may be slow, sufficient numeric precision for fitting & minimization is not guaranteed" << std::endl ;
734 _funcNormSet = std::make_unique<RooArgSet>();
735 other._funcNormSet->snapshot(*_funcNormSet, false);
768 std::unique_ptr<RooArgSet> tmp;
774 tmp = std::make_unique<RooArgSet>();
777 newNormSet = tmp.get();
779 return _function->createIntegral(isetAll,newNormSet,cfg,rangeName);
821 <<
":evaluate: cannot initialize numerical integrator" << std::endl;
843 _function->treeNodeServerList(&serverList,
nullptr,
true,
true,
false,
true);
846 for (
auto *arg : serverList) {
861 operModeRAII.
clear();
871 cxcoutD(Tracing) <<
"RooRealIntegral::evaluate_analytic(" <<
GetName()
903 retVal *= argLV->numTypes() ;
916 ccxcoutD(Tracing) <<
"raw*fact = " << retVal << std::endl ;
934 jacProd *= arg->jacobian() ;
939 return std::abs(jacProd) ;
952 for (
const auto& nameIdx : *sumCat) {
985 bool mustReplaceAll,
bool nameChange,
bool isRecursive)
1008 _params = std::make_unique<RooArgSet>(
"params") ;
1059 os <<
"d[Ana]" << tmp <<
" ";
1065 if (!tmp2.
empty()) {
1066 os <<
" d[Num]" << tmp2 <<
" ";
1076 os <<
indent <<
"--- RooRealIntegral ---" << std::endl;
1077 os <<
indent <<
" Integrates ";
1081 os <<
indent <<
" operating mode is "
1083 os <<
indent <<
" Summed discrete args are " <<
_sumList << std::endl ;
1084 os <<
indent <<
" Numerically integrated args are " <<
_intList << std::endl;
1085 os <<
indent <<
" Analytically integrated args using mode " <<
_mode <<
" are " <<
_anaList << std::endl ;
1086 os <<
indent <<
" Arguments included in Jacobian are " <<
_jacList << std::endl ;
1087 os <<
indent <<
" Factorized arguments are " <<
_facList << std::endl ;
1088 os <<
indent <<
" Function normalization set " ;
1114std::unique_ptr<RooAbsArg>
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int).
static void indent(ostringstream &buf, int indent_level)
static unsigned int total
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Scope guard that temporarily changes the operation mode of one or more RooAbsArg instances.
void change(RooAbsArg *arg, RooAbsArg::OperMode opMode)
Record arg's current operMode and flip it to opMode.
void clear()
Restore every recorded change right away, emptying this guard.
Common abstract base class for objects that represent a value and a "shape" in RooFit.
void setOperMode(OperMode mode, bool recurseADirty=true)
Set the operation mode of this node.
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.
const RefCountList_t & valueClients() const
List of all value clients of this object. Value clients receive value updates.
virtual void setExpensiveObjectCache(RooExpensiveObjectCache &cache)
bool addOwnedComponents(const RooAbsCollection &comps)
Take ownership of the contents of 'comps'.
virtual std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) const
const RefCountList_t & servers() const
List of all servers of this object.
bool dependsOnValue(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr) const
Check whether this object depends on values from an element in the serverList.
void addServer(RooAbsArg &server, bool valueProp=true, bool shapeProp=false, std::size_t refCount=1)
Register another RooAbsArg as a server to us, ie, declare that we depend on it.
virtual bool isDerived() const
Does value or shape of this arg depend on any other arg?
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
bool isValueOrShapeDirtyAndClear() const
void setProxyNormSet(const RooArgSet *nset)
Forward a change in the cached normalization argset to all the registered proxies.
RefCountList_t _serverList
void leafNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=nullptr, bool recurseNonDerived=false) const
Fill supplied list with all leaf nodes of the arg tree, starting with ourself as top node.
bool isValueServer(const RooAbsArg &arg) const
Check if this is serving values to arg.
RooAbsArg()
Default constructor.
friend class RooAbsCollection
OperMode operMode() const
Query the operation mode of this node.
Abstract base class for objects that represent a discrete value that can be set from the outside,...
bool contains(const char *name) const
Check if collection contains an argument with a specific name.
RooFit::UniqueId< RooAbsCollection > const & uniqueId() const
Returns a unique ID that is different for every instantiated RooAbsCollection.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
void sortTopologically()
Sort collection topologically: the servers of any RooAbsArg will be before that RooAbsArg in the coll...
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Int_t index(const RooAbsArg *arg) const
Returns index of given arg, or -1 if arg is not in the collection.
Storage_t::size_type size() const
void reserve(Storage_t::size_type count)
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for objects that are lvalues, i.e.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
virtual bool isJacobianOK(const RooArgSet &depList) const
Abstract base class for objects that represent a real value and implements functionality common to al...
RooAbsReal()
coverity[UNINIT_CTOR] Default constructor
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Structure printing.
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
Function that is called at the end of redirectServers().
double _value
Cache for current value of object.
double traceEval(const RooArgSet *set) const
Calculate current value of object, with error tracing wrapper.
RooFit::UniqueId< RooArgSet >::Value_t _lastNormSetId
!
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, 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 an object that represents the integral of the function over one or more observables listed in ...
static bool _globalSelectComp
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Represents a constant real-valued object.
Registry for const char* names.
static const char * str(const TNamed *ptr)
Return C++ string corresponding to given TNamed pointer.
Holds the configuration parameters of the various numeric integrators used by RooRealIntegral.
std::unique_ptr< RooAbsIntegrator > createIntegrator(RooAbsFunc &func, const RooNumIntConfig &config, int ndim=0, bool isBinned=false) const
Construct a numeric integrator instance that operates on function 'func' and is configured with 'conf...
std::string getIntegratorName(RooAbsFunc &func, const RooNumIntConfig &config, int ndim=0, bool isBinned=false) const
static RooNumIntFactory & instance()
Static method returning reference to singleton instance of factory.
RooNumIntConfig * _iconfig
bool initNumIntegrator() const
(Re)Initialize numerical integration engine if necessary.
RooArgSet const * funcNormSet() const
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, const RooArgSet *nset=nullptr, const RooNumIntConfig *cfg=nullptr, const char *rangeName=nullptr) const override
Create an object that represents the integral of the function over one or more observables listed in ...
void setAllowComponentSelection(bool allow)
Set component selection to be allowed/forbidden.
RooRealProxy _function
Function being integrated.
RooArgSet intVars() const
RooSetProxy _intList
Set of continuous observables over which is integrated numerically.
virtual double sum() const
Perform summation of list of category dependents to be integrated.
RooSetProxy _facList
Set of observables on which function does not depends, which are integrated nevertheless.
std::unique_ptr< RooArgSet > _params
! cache for set of parameters
static void setCacheAllNumeric(Int_t ndim)
Global switch to cache all integral values that integrate at least ndim dimensions numerically.
IntOperMode _intOperMode
integration operation mode
double evaluate() const override
Perform the integration and return the result.
const RooArgSet & parameters() const
std::unique_ptr< RooAbsFunc > _numIntegrand
!
void addNumIntDep(RooAbsArg const &arg)
Sort numeric integration variables in summation and integration lists.
RooSetProxy _jacList
Set of lvalue observables over which is analytically integration that have a non-unit Jacobian.
bool isValidReal(double value, bool printError=false) const override
Check if current value is valid.
double getValV(const RooArgSet *set=nullptr) const override
Return value of object.
RooSetProxy _anaList
Set of observables over which is integrated/summed analytically.
bool _restartNumIntEngine
!
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursive) override
Intercept server redirects and reconfigure internal object accordingly.
RooSetProxy _sumList
Set of discrete observable over which is summed numerically.
~RooRealIntegral() override
void printMetaArgs(std::ostream &os) const override
Customized printing of arguments of a RooRealIntegral to more intuitively reflect the contents of the...
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Print the state of this object to the specified output stream.
std::unique_ptr< RooAbsIntegrator > _numIntEngine
!
virtual double integrate() const
Perform hybrid numerical/analytical integration over all real-valued dependents.
virtual double jacobianProduct() const
Return product of jacobian terms originating from analytical integration.
static Int_t getCacheAllNumeric()
Return minimum dimensions of numeric integration for which values are cached.
static Int_t _cacheAllNDim
! Cache all integrals with given numeric dimension
RooArgSet const * actualFuncNormSet() const
std::unique_ptr< RooArgSet > _funcNormSet
Optional normalization set passed to function.
std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) const override
void autoSelectDirtyMode()
Set appropriate cache operation mode for integral depending on cache operation mode of server objects...
const char * intRange() const
bool getAllowComponentSelection() const
Check if component selection is allowed.
Joins several RooAbsCategoryLValue objects into a single category.
bool setIndex(value_type index, bool printError=true) override
Set the value of the super category to the specified index.
bool inRange(const char *rangeName) const override
Check that all input category states are in the given range.
const char * GetName() const override
Returns name of object.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
TString & Append(const char *cs)
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
constexpr Value_t value() const
Return numerical value of ID.