Skip to content

Commit b3c8804

Browse files
committed
[RF] Add RooRealIntegral param servers only if it's not pass-through
The RooRealIntegral didn't really stick to the client-server interface in the pass-through case, where the only servers should be the actual function and the factorized observables. This commit ensures that the RooRealIntegral sticks to that.
1 parent ead7ca2 commit b3c8804

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

roofit/roofitcore/src/RooRealIntegral.cxx

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,25 @@ ClassImp(RooRealIntegral);
5959

6060
namespace {
6161

62-
void addValueAndShapeServers(RooAbsArg &integral, RooAbsReal const &function, RooArgSet const &depList,
63-
RooArgSet const &intDepList, const char *rangeName, RooArgSet &anIntOKDepList)
62+
struct ServerToAdd {
63+
ServerToAdd(RooAbsArg * theArg, bool isShape) : arg{theArg}, isShapeServer{isShape} {}
64+
RooAbsArg * arg = nullptr;
65+
bool isShapeServer = false;
66+
};
67+
68+
std::vector<ServerToAdd> getValueAndShapeServers(RooAbsReal const &function, RooArgSet const &depList,
69+
RooArgSet const &intDepList, const char *rangeName,
70+
RooArgSet &anIntOKDepList)
6471
{
72+
std::vector<ServerToAdd> serversToAdd;
6573

6674
for (const auto arg : function.servers()) {
6775

6876
// Dependent or parameter?
6977
if (!arg->dependsOnValue(intDepList)) {
7078

7179
if (function.dependsOnValue(*arg)) {
72-
integral.addServer(*arg, true, false);
80+
serversToAdd.emplace_back(arg, false);
7381
}
7482

7583
continue;
@@ -107,26 +115,26 @@ void addValueAndShapeServers(RooAbsArg &integral, RooAbsReal const &function, Ro
107115
<< " has parameterized binning, add value dependence of boundary objects rather than shape of leaf"
108116
<< endl;
109117
if (leaflv->getBinning(rangeName).lowBoundFunc()) {
110-
integral.addServer(*leaflv->getBinning(rangeName).lowBoundFunc(), true, false);
118+
serversToAdd.emplace_back(leaflv->getBinning(rangeName).lowBoundFunc(), false);
111119
}
112120
if (leaflv->getBinning(rangeName).highBoundFunc()) {
113-
integral.addServer(*leaflv->getBinning(rangeName).highBoundFunc(), true, false);
121+
serversToAdd.emplace_back(leaflv->getBinning(rangeName).highBoundFunc(), false);
114122
}
115123
} else {
116124
oocxcoutD(&function, Integration) << function.GetName() << ": Adding observable " << leaf->GetName()
117125
<< " of server " << arg->GetName() << " as shape dependent" << endl;
118-
integral.addServer(*leaf, false, true);
126+
serversToAdd.emplace_back(leaf, true);
119127
}
120128
} else if (!depList.find(leaf->GetName())) {
121129

122130
if (argLeafValueServers.contains(*leaf)) {
123131
oocxcoutD(&function, Integration) << function.GetName() << ": Adding parameter " << leaf->GetName()
124132
<< " of server " << arg->GetName() << " as value dependent" << endl;
125-
integral.addServer(*leaf, true, false);
133+
serversToAdd.emplace_back(leaf, false);
126134
} else {
127135
oocxcoutD(&function, Integration) << function.GetName() << ": Adding parameter " << leaf->GetName()
128136
<< " of server " << arg->GetName() << " as shape dependent" << endl;
129-
integral.addServer(*leaf, false, true);
137+
serversToAdd.emplace_back(leaf, true);
130138
}
131139
}
132140
}
@@ -174,6 +182,8 @@ void addValueAndShapeServers(RooAbsArg &integral, RooAbsReal const &function, Ro
174182
<< " is suitable for analytical integration (if supported by p.d.f)" << endl;
175183
}
176184
}
185+
186+
return serversToAdd;
177187
}
178188

179189
} // namespace
@@ -418,7 +428,10 @@ RooRealIntegral::RooRealIntegral(const char *name, const char *title,
418428
// Add all parameters/dependents as value/shape servers *
419429
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
420430

421-
addValueAndShapeServers(*this, function, depList, intDepList, rangeName, anIntOKDepList);
431+
auto serversToAdd = getValueAndShapeServers(function, depList, intDepList, rangeName, anIntOKDepList);
432+
// We will not add the servers just now, because it makes only sense to add
433+
// them once we have made sure that this integral is not operating in
434+
// pass-through mode. It will be done at the end of this constructor.
422435

423436
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
424437
// * E) interact with function to make list of objects actually integrated analytically *
@@ -581,6 +594,14 @@ RooRealIntegral::RooRealIntegral(const char *name, const char *title,
581594
_sumCat.addOwned(*sumCat) ;
582595
}
583596

597+
// Only if we are not in pass-through mode we need to add the shape and value
598+
// servers separately.
599+
if(_intOperMode != PassThrough) {
600+
for(auto const& toAdd : serversToAdd) {
601+
addServer(*toAdd.arg, !toAdd.isShapeServer, toAdd.isShapeServer);
602+
}
603+
}
604+
584605
TRACE_CREATE
585606
}
586607

@@ -912,6 +933,10 @@ double RooRealIntegral::evaluate() const
912933
// In pass through mode, the RooRealIntegral should have registered the
913934
// function as a value server, because we directly depend on its value.
914935
assert(_function.isValueServer());
936+
// There should be no other servers besides the actual function and the
937+
// factorized observables that the function doesn't depend on but are
938+
// integrated over later.
939+
assert(servers().size() == _facList.size() + 1);
915940

916941
//setDirtyInhibit(true) ;
917942
retVal= _function.arg().getVal(_funcNormSet) ;

0 commit comments

Comments
 (0)