59 ServerToAdd(
RooAbsArg *theArg,
bool isShape) : arg{theArg}, isShapeServer{isShape} {}
61 bool isShapeServer =
false;
64void addObservableToServers(
RooAbsReal const &function,
RooAbsArg &leaf, std::vector<ServerToAdd> &serversToAdd,
65 const char *rangeName)
68 if (leaflv && leaflv->getBinning(rangeName).isParameterized()) {
71 <<
" has parameterized binning, add value dependence of boundary objects rather than shape of leaf"
73 if (leaflv->getBinning(rangeName).lowBoundFunc()) {
74 serversToAdd.emplace_back(leaflv->getBinning(rangeName).lowBoundFunc(),
false);
76 if (leaflv->getBinning(rangeName).highBoundFunc()) {
77 serversToAdd.emplace_back(leaflv->getBinning(rangeName).highBoundFunc(),
false);
81 <<
" as shape dependent" << std::endl;
82 serversToAdd.emplace_back(&leaf,
true);
86void addParameterToServers(
RooAbsReal const &function,
RooAbsArg &leaf, std::vector<ServerToAdd> &serversToAdd,
91 <<
" as value dependent" << std::endl;
94 <<
" as shape dependent" << std::endl;
96 serversToAdd.emplace_back(&leaf, isShapeServer);
99enum class MarkedState { Dependent, Independent, AlreadyAdded };
102void unmarkDepValueClients(
RooAbsArg const &dep,
RooArgSet const &args, std::vector<MarkedState> &marked)
104 assert(args.
size() == marked.size());
107 marked[
index] = MarkedState::Dependent;
108 for (
RooAbsArg *client : dep.valueClients()) {
109 unmarkDepValueClients(*client, args, marked);
114std::vector<ServerToAdd>
115getValueAndShapeServers(
RooAbsReal const &function,
RooArgSet const &depList,
const char *rangeName)
117 std::vector<ServerToAdd> serversToAdd;
121 function.treeNodeServerList(&allArgsList,
nullptr,
true,
true,
false,
false);
127 function.treeNodeServerList(&allValueArgsList,
nullptr,
true,
true,
true,
false);
128 RooArgSet allValueArgs{allValueArgsList};
131 std::vector<MarkedState> marked(allArgs.size(), MarkedState::Independent);
132 marked.back() = MarkedState::Dependent;
140 unmarkDepValueClients(*depInArgs, allArgs, marked);
141 addObservableToServers(function, *depInArgs, serversToAdd, rangeName);
147 for (std::size_t i = 0; i < allArgs.size(); ++i) {
148 if(marked[i] == MarkedState::Dependent) {
149 for(
RooAbsArg* server : allArgs[i]->servers()) {
150 int index = allArgs.index(server->GetName());
151 if(
index >= 0 && marked[
index] == MarkedState::Independent) {
152 addParameterToServers(function, *server, serversToAdd, !allValueArgs.find(*server));
153 marked[
index] = MarkedState::AlreadyAdded;
164 for (
const auto arg :
function.servers()) {
167 if (!arg->dependsOnValue(intDepList)) {
169 }
else if (!arg->isValueServer(function) && !arg->isShapeServer(function)) {
177 if (arg->isDerived()) {
187 bool overlapOK =
true;
188 for (
const auto otherArg :
function.servers()) {
194 if (arg->overlaps(*otherArg,
true)) {
208 anIntOKDepList.
add(*arg,
true);
209 oocxcoutI(&function, Integration) <<
function.GetName() <<
": Observable " << arg->GetName()
210 <<
" is suitable for analytical integration (if supported by p.d.f)"
250 const char* rangeName) :
253 _respectCompSelect{!_globalSelectComp},
254 _sumList(
"!sumList",
"Categories to be summed numerically",this,false,false),
255 _intList(
"!intList",
"Variables to be integrated numerically",this,false,false),
256 _anaList(
"!anaList",
"Variables to be integrated analytically",this,false,false),
257 _jacList(
"!jacList",
"Jacobian product term",this,false,false),
258 _facList(
"!facList",
"Variables independent of function",this,false,true),
259 _function(
"!func",
"Function to be integrated",this,false,false),
261 _sumCat(
"!sumCat",
"SuperCategory for summation",this,false,false),
285 oocxcoutI(&function,Integration) <<
"RooRealIntegral::ctor(" <<
GetName() <<
") Constructing integral of function "
286 << function.GetName() <<
" over observables" << depList <<
" with normalization "
288 << (rangeName?rangeName:
"<none>") << std::endl ;
302 if (function.dependsOn(*nArg)) {
318 for (
auto arg : intDepList) {
319 if(!arg->isLValue()) {
324 if (!function.dependsOn(*arg)) {
325 std::unique_ptr<RooAbsArg> argClone{
static_cast<RooAbsArg*
>(arg->Clone())};
333 oocxcoutI(&function,Integration) << function.GetName() <<
": Factorizing obserables are " <<
_facList << std::endl ;
344 RooArgSet exclLVBranches(
"exclLVBranches") ;
346 function.branchNodeServerList(&branchList) ;
348 for (
auto branch: branchList) {
351 if ((realArgLV && (realArgLV->
isJacobianOK(intDepList)!=0)) || catArgLV) {
352 exclLVBranches.
add(*branch) ;
357 branchListVD.
add(*branch) ;
362 exclLVBranches.
remove(depList,
true,
true) ;
366 RooArgSet exclLVServers(
"exclLVServers") ;
367 function.getObservables(&intDepList, exclLVServers);
370 bool converged(
false) ;
375 std::vector<RooAbsArg*> toBeRemoved;
376 for (
auto server : exclLVServers) {
378 toBeRemoved.push_back(server);
382 exclLVServers.
remove(toBeRemoved.begin(), toBeRemoved.end());
386 for (std::size_t i=0; i < exclLVBranches.
size(); ++i) {
387 const RooAbsArg* branch = exclLVBranches[i];
391 bsList.
remove(exclLVServers,
true,
true) ;
392 if (!bsList.
empty()) {
393 exclLVBranches.
remove(*branch,
true,
true) ;
402 for (std::size_t i=0; i < exclLVBranches.
size(); ++i) {
403 const RooAbsArg* branch = exclLVBranches[i];
405 exclLVBranches.
remove(*branch,
true,
true) ;
412 if (!exclLVServers.
empty() && !function.isBinnedDistribution(exclLVBranches)) {
414 intDepList.
remove(exclLVServers) ;
415 intDepList.
add(exclLVBranches) ;
429 for (
auto arg : intDepList) {
430 if (function.forceAnalyticalInt(*arg)) {
431 anIntOKDepList.
add(*arg) ;
435 if (!anIntOKDepList.
empty()) {
436 oocxcoutI(&function,Integration) << function.GetName() <<
": Observables that function forcibly requires to be integrated internally " << anIntOKDepList << std::endl ;
445 auto serversToAdd = getValueAndShapeServers(function, depList, rangeName);
446 fillAnIntOKDepList(function, intDepList, anIntOKDepList);
463 oocxcoutI(&function,Integration) << function.GetName() <<
": Function integrated observables " <<
_anaList <<
" internally with code " <<
_mode << std::endl ;
492 auto argDepList = std::unique_ptr<RooArgSet>(arg->getObservables(&intDepList));
493 for (
const auto argDep : *argDepList) {
495 numIntDepList.
add(*argDep,
true) ;
504 if (!exclLVServers.
empty()) {
506 intDepList.
remove(exclLVBranches) ;
507 intDepList.
add(exclLVServers) ;
513 for (
const auto arg : function.servers()) {
522 numIntDepList.
add(*arg,
true) ;
527 auto argDeps = std::unique_ptr<RooArgSet>(arg->getObservables(&intDepList));
529 if (!argDeps->empty()) {
533 for (
const auto dep : *argDeps) {
535 numIntDepList.
add(*dep,
true) ;
548 for (
const auto arg : numIntDepList) {
557 oocxcoutI(&function,Integration) << function.GetName() <<
": Observables " <<
_anaList <<
" are analytically integrated with code " <<
_mode << std::endl ;
560 oocxcoutI(&function,Integration) << function.GetName() <<
": Observables " <<
_intList <<
" are numerically integrated" << std::endl ;
563 oocxcoutI(&function,Integration) << function.GetName() <<
": Observables " <<
_sumList <<
" are numerically summed" << std::endl ;
568 if (!numIntDepList.
empty()) {
598 for(
auto const& toAdd : serversToAdd) {
599 addServer(*toAdd.arg, !toAdd.isShapeServer, toAdd.isShapeServer);
616 if (server->isValueServer(*
this)) {
618 server->leafNodeServerList(&leafSet) ;
619 for (
const auto leaf : leafSet) {
644 if (exclLVBranches.
empty())
return false ;
657 if (!(exclLVBranches.
find(client->GetName())==client)) {
658 if (allBranches.
find(client->GetName())==client) {
670 return (numLVServ==1) ;
704 coutE(Integration) <<
ClassName() <<
"::" <<
GetName() <<
": failed to create valid integrand." << std::endl;
713 coutE(Integration) <<
ClassName() <<
"::" <<
GetName() <<
": failed to create valid integrator." << std::endl;
717 cxcoutI(NumIntegration) <<
"RooRealIntegral::init(" <<
GetName() <<
") using numeric integrator "
721 cxcoutI(NumIntegration) <<
"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 ;
735 _valid(other._valid),
736 _respectCompSelect(other._respectCompSelect),
737 _sumList(
"!sumList",this,other._sumList),
738 _intList(
"!intList",this,other._intList),
739 _anaList(
"!anaList",this,other._anaList),
740 _jacList(
"!jacList",this,other._jacList),
741 _facList(
"!facList",
"Variables independent of function",this,false,true),
742 _function(
"!func",this,other._function),
743 _iconfig(other._iconfig),
744 _sumCat(
"!sumCat",this,other._sumCat),
746 _intOperMode(other._intOperMode),
747 _restartNumIntEngine(false),
748 _rangeName(other._rangeName),
756 for (
const auto arg : other.
_facList) {
757 std::unique_ptr<RooAbsArg> argClone{
static_cast<RooAbsArg*
>(arg->Clone())};
795 std::unique_ptr<RooArgSet> tmp;
801 tmp = std::make_unique<RooArgSet>();
804 newNormSet = tmp.
get();
871 <<
":evaluate: cannot initialize numerical integrator" << std::endl;
903 cxcoutD(Tracing) <<
"RooRealIntegral::evaluate_analytic(" <<
GetName()
954 ccxcoutD(Tracing) <<
"raw*fact = " << retVal << std::endl ;
974 jacProd *= arg->jacobian() ;
979 return std::abs(jacProd) ;
994 for (
const auto& nameIdx : *sumCat) {
1030 bool mustReplaceAll,
bool nameChange,
bool isRecursive)
1055 _params = std::make_unique<RooArgSet>(
"params") ;
1059 if (server->isValueServer(*
this))
_params->
add(*server) ;
1092 std::stringstream errorMsg;
1093 errorMsg <<
"Only analytical integrals are supported for AD for class" <<
_function.
GetName();
1094 coutE(Minimization) << errorMsg.str() << std::endl;
1095 throw std::runtime_error(errorMsg.str().c_str());
1120 os <<
"d[Ana]" << tmp <<
" ";
1126 if (!tmp2.
empty()) {
1127 os <<
" d[Num]" << tmp2 <<
" ";
1139 os <<
indent <<
"--- RooRealIntegral ---" << std::endl;
1140 os <<
indent <<
" Integrates ";
1144 os <<
indent <<
" operating mode is "
1146 os <<
indent <<
" Summed discrete args are " <<
_sumList << std::endl ;
1147 os <<
indent <<
" Numerically integrated args are " <<
_intList << std::endl;
1148 os <<
indent <<
" Analytically integrated args using mode " <<
_mode <<
" are " <<
_anaList << std::endl ;
1149 os <<
indent <<
" Arguments included in Jacobian are " <<
_jacList << std::endl ;
1150 os <<
indent <<
" Factorized arguments are " <<
_facList << std::endl ;
1151 os <<
indent <<
" Function normalization set " ;
1179std::unique_ptr<RooAbsArg>
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
static void indent(ostringstream &buf, int indent_level)
static unsigned int total
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
RooExpensiveObjectCache & expensiveObjectCache() const
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
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'.
static void setDirtyInhibit(bool flag)
Control global dirty inhibit mode.
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.
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
bool isValueOrShapeDirtyAndClear() const
bool inhibitDirty() const
Delete watch flag.
void setProxyNormSet(const RooArgSet *nset)
Forward a change in the cached normalization argset to all the registered proxies.
RefCountList_t _clientList
RefCountList_t _serverList
bool isValueServer(const RooAbsArg &arg) const
Check if this is serving values to arg.
OperMode operMode() const
Query the operation mode of this node.
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
Int_t numTypes(const char *=nullptr) const
Return number of types defined (in range named rangeName if rangeName!=nullptr)
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
RooFit::UniqueId< RooAbsCollection > const & uniqueId() const
Returns a unique ID that is different for every instantiated RooAbsCollection.
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.
Storage_t const & get() const
Const access to the underlying stl container.
void sortTopologically()
Sort collection topologically: the servers of any RooAbsArg will be before that RooAbsArg in the coll...
bool contains(const RooAbsArg &var) const
Check if collection contains an argument with the same name as var.
Int_t getSize() const
Return the number of elements in the collection.
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.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
Storage_t::size_type size() const
RooAbsArg * first() const
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
RooAbsArg * find(const char *name) const
Find object with given name in list.
void Print(Option_t *options=nullptr) const override
This method must be overridden when a class wants to print itself.
Abstract base class for objects that are lvalues, i.e.
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
virtual bool isJacobianOK(const RooArgSet &depList) const
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.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
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 ...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
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.
virtual std::string buildCallToAnalyticIntegral(Int_t code, const char *rangeName, RooFit::Detail::CodeSquashContext &ctx) const
This function defines the analytical integral translation for the class.
RooFit::UniqueId< RooArgSet >::Value_t _lastNormSetId
Component selection flag for RooAbsPdf::plotCompOn.
virtual double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
virtual bool isBinnedDistribution(const RooArgSet &) const
Tests if the distribution is binned. Unless overridden by derived classes, this always returns false.
RooArgList is a container object that can hold multiple RooAbsArg objects.
bool _valueServer
If true contents is value server of owner.
bool isValueServer() const
Returns true of contents is value server of owner.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
void removeAll() override
Remove all argument inset using remove(const RooAbsArg&).
bool addOwned(RooAbsArg &var, bool silent=false) override
Overloaded RooCollection_t::addOwned() method insert object into owning set and registers object as s...
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
RooDouble is a minimal implementation of a TObject holding a double value.
bool registerObject(const char *ownerName, const char *objectName, TObject &cacheObject, const RooArgSet ¶ms)
Register object associated with given name and given associated parameters with given values in cache...
const TObject * retrieveObject(const char *name, TClass *tclass, const RooArgSet ¶ms)
Retrieve object from cache that was registered under given name with given parameters,...
A class to maintain the context for squashing of RooFit models into code.
void addResult(RooAbsArg const *key, std::string const &value)
A function to save an expression that includes/depends on the result of the input node.
RooNameReg is a registry for const char* names.
static const char * str(const TNamed *ptr)
Return C++ string corresponding to given TNamed pointer.
RooNumIntConfig holds the configuration parameters of the various numeric integrators used by RooReal...
std::unique_ptr< RooAbsIntegrator > createIntegrator(RooAbsFunc &func, const RooNumIntConfig &config, Int_t ndim=0, bool isBinned=false) const
Construct a numeric integrator instance that operates on function 'func' and is configured with 'conf...
static RooNumIntFactory & instance()
Static method returning reference to singleton instance of factory.
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer,...
RooRealIntegral performs hybrid numerical/analytical integrals of RooAbsReal objects.
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 translate(RooFit::Detail::CodeSquashContext &ctx) const override
This function defines a translation for each RooAbsReal based object that can be used to express the ...
void setAllowComponentSelection(bool allow)
Set component selection to be allowed/forbidden.
RooRealProxy _function
Function being integration.
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
bool _cacheNum
Cache integral if numeric.
double evaluate() const override
Perform the integration and return the result.
const RooArgSet & parameters() const
std::unique_ptr< RooAbsFunc > _numIntegrand
! do not persist
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.
RooArgSet _saveInt
! do not persist
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
! do not persist
bool servesExclusively(const RooAbsArg *server, const RooArgSet &exclLVBranches, const RooArgSet &allBranches) const
Utility function that returns true if 'object server' is a server to exactly one of the RooAbsArgs in...
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
! do not persist
virtual double integrate() const
Perform hybrid numerical/analytical integration over all real-valued dependents.
RooListProxy _sumCat
! do not persist
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.
RooArgSet _saveSum
! do not persist
static Int_t _cacheAllNDim
! Cache all integrals with given numeric dimension
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...
RooArgSet _facListOwned
Owned components in _facList.
const char * intRange() const
bool getAllowComponentSelection() const
Check if component selection is allowed.
The RooSuperCategory can join 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.
bool setArg(T &newRef)
Change object held in proxy into newRef.
const T & arg() const
Return reference to object held in proxy.
The TNamed class is the base class for all named ROOT classes.
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.