38void replaceAll(std::string &str,
const std::string &from,
const std::string &to)
44 str.replace(
start_pos, from.length(), to);
53namespace Experimental {
73 auto found =
spans.find(key);
74 return found !=
spans.
end() ? found->second.size() : -1;
82 ctx.
addResult(param,
"params[" + std::to_string(idx) +
"]");
91 if (
item.second.size == 1) {
92 ctx.addResult(
obsName,
"obs[" + std::to_string(
item.second.idx) +
"]");
114 _funcName(
other._funcName),
117 _hasGradient(
other._hasGradient),
118 _gradientVarBuffer(
other._gradientVarBuffer),
119 _observables(
other._observables)
123std::map<RooFit::Detail::DataKey, std::span<const double>>
128 std::map<RooFit::Detail::DataKey, std::span<const double>>
spans;
136 std::size_t
n =
item.second.size();
139 for (std::size_t i = 0; i <
n; ++i) {
148 if (param->isConstant()) {
152 errorMsg <<
"In creation of function " << GetName()
153 <<
" wrapper: input param expected to be of type RooAbsReal.";
155 throw std::runtime_error(
errorMsg.str().c_str());
161 _gradientVarBuffer.resize(_params.size());
166void RooFuncWrapper::createGradient()
169 std::string
gradName = _funcName +
"_grad_0";
173 gInterpreter->Declare(
"#include <Math/CladDerivator.h>\n");
179 " clad::gradient(" << _funcName <<
", \"params\");\n"
192 errorMsg <<
"Function " << GetName() <<
" could not be differentiated. See above for details.";
194 throw std::runtime_error(
errorMsg.str().c_str());
200 std::stringstream
ss;
202 ss <<
"static_cast<void (*)(double *, double const *, double const *, double *)>(" <<
gradName <<
");";
206 _hasGradient =
false;
208 errorMsg <<
"Function " << GetName() <<
" could not be differentiated since ROOT was built without Clad support.";
210 throw std::runtime_error(
errorMsg.str().c_str());
214void RooFuncWrapper::gradient(
double *out)
const
216 updateGradientVarBuffer();
217 std::fill(out, out + _params.size(), 0.0);
219 _grad(_gradientVarBuffer.data(), _observables.data(), _xlArr.data(), out);
222void RooFuncWrapper::updateGradientVarBuffer()
const
224 std::transform(_params.begin(), _params.end(), _gradientVarBuffer.begin(),
225 [](
RooAbsArg *obj) { return static_cast<RooAbsReal *>(obj)->getVal(); });
228double RooFuncWrapper::evaluate()
const
231 return _absReal->getVal();
232 updateGradientVarBuffer();
234 return _func(_gradientVarBuffer.data(), _observables.data(), _xlArr.data());
237void RooFuncWrapper::gradient(
const double *
x,
double *
g)
const
239 std::fill(
g,
g + _params.size(), 0.0);
241 _grad(
const_cast<double *
>(
x), _observables.data(), _xlArr.data(),
g);
245void RooFuncWrapper::writeDebugMacro(std::string
const &
filename)
const
251 for (std::string
const &
name : _collectedFunctions) {
256 std::unique_ptr<TInterpreterValue>
v =
gInterpreter->MakeInterpreterValue();
258 std::string s =
v->ToString();
259 for (
int i = 0; i < 2; ++i) {
260 s = s.erase(0, s.find(
"\n") + 1);
267 outFile << R
"(//auto-generated test macro
268#include <RooFit/Detail/MathFuncs.h>
269#include <Math/CladDerivator.h>
271#pragma cling optimize(2)
275void gradient_request() {
277 << _funcName << R"(, "params");
282 updateGradientVarBuffer();
285 std::stringstream
decl;
286 decl <<
"std::vector<double> " <<
name <<
" = {";
287 for (std::size_t i = 0; i <
vec.size(); ++i) {
291 if (i <
vec.size() - 1)
298 replaceAll(
declStr,
"inf",
"std::numeric_limits<double>::infinity()");
299 replaceAll(
declStr,
"nan",
"NAN");
304 outFile <<
"// clang-format off\n" << std::endl;
311 outFile <<
"// clang-format on\n" << std::endl;
314// To run as a ROOT macro
318 std::vector<double> gradientVec(parametersVec.size());
320 auto func = [&](std::span<double> params) {
322 << _funcName << R"((params.data(), observablesVec.data(), auxConstantsVec.data());
324 auto grad = [&](std::span<double> params, std::span<double> out) {
326 << _funcName << R"(_grad_0(parametersVec.data(), observablesVec.data(), auxConstantsVec.data(),
330 grad(parametersVec, gradientVec);
332 auto numDiff = [&](int i) {
333 const double eps = 1e-6;
334 std::vector<double> p{parametersVec};
335 p[i] = parametersVec[i] - eps;
336 double funcValDown = func(p);
337 p[i] = parametersVec[i] + eps;
338 double funcValUp = func(p);
339 return (funcValUp - funcValDown) / (2 * eps);
342 for (std::size_t i = 0; i < parametersVec.size(); ++i) {
343 std::cout << i << ":" << std::endl;
344 std::cout << " numr : " << numDiff(i) << std::endl;
345 std::cout << " clad : " << gradientVec[i] << std::endl;
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
const_iterator end() const
Common abstract base class for objects that represent a value and a "shape" in RooFit.
RooFit::OwningPtr< RooArgSet > getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
Abstract base class for binned and unbinned datasets.
Abstract base class for objects that represent a real value and implements functionality common to al...
RooArgSet is a container object that can hold multiple RooAbsArg objects.
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.
A wrapper class to store a C++ function of type 'double (*)(double*, double*)'.
std::unique_ptr< RooAbsReal > _absReal
std::vector< std::string > _collectedFunctions
std::vector< double > _xlArr
std::vector< double > _observables
std::map< RooFit::Detail::DataKey, std::span< const double > > loadParamsAndData(RooArgSet const ¶mSet, const RooAbsData *data, RooSimultaneous const *simPdf)
std::map< RooFit::Detail::DataKey, ObsInfo > _obsInfos
RooFuncWrapper(const char *name, const char *title, RooAbsReal &obj, const RooAbsData *data=nullptr, RooSimultaneous const *simPdf=nullptr, bool useEvaluator=false)
Facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
void replaceAll(std::string &inOut, std::string_view what, std::string_view with)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...