28void assignSpan(std::span<T> &to, std::span<T>
const &from)
33std::map<RooFit::Detail::DataKey, std::span<const double>>
34getSingleDataSpans(
RooAbsData const &
data, std::string_view rangeName, std::string
const &prefix,
35 std::stack<std::vector<double>> &buffers,
bool skipZeroWeights)
37 std::map<RooFit::Detail::DataKey, std::span<const double>> dataSpans;
41 auto insert = [&](
const char *key, std::span<const double> span) {
42 const TNamed *namePtr = nameReg.constPtr((prefix + key).c_str());
43 dataSpans[namePtr] = span;
46 auto retrieve = [&](
const char *key) {
47 const TNamed *namePtr = nameReg.constPtr((prefix + key).c_str());
48 return dataSpans.at(namePtr);
51 std::size_t nEvents =
static_cast<size_t>(
data.numEntries());
59 auto weight =
data.getWeightBatch(0, nEvents,
false);
60 auto weightSumW2 =
data.getWeightBatch(0, nEvents,
true);
62 std::vector<bool> hasZeroWeight;
63 hasZeroWeight.resize(nEvents);
64 std::size_t nNonZeroWeight = 0;
71 auto &buffer = buffers.top();
73 auto &bufferSumW2 = buffers.top();
78 buffer.push_back(1.0);
79 bufferSumW2.push_back(1.0);
80 assignSpan(weight, {buffer.data(), 1});
81 assignSpan(weightSumW2, {bufferSumW2.data(), 1});
82 nNonZeroWeight = nEvents;
84 buffer.reserve(nEvents);
85 bufferSumW2.reserve(nEvents);
86 for (std::size_t i = 0; i < nEvents; ++i) {
87 if (!skipZeroWeights || weight[i] != 0) {
88 buffer.push_back(weight[i]);
89 bufferSumW2.push_back(weightSumW2[i]);
92 hasZeroWeight[i] =
true;
95 assignSpan(weight, {buffer.data(), nNonZeroWeight});
96 assignSpan(weightSumW2, {bufferSumW2.data(), nNonZeroWeight});
104 for (
auto const &item :
data.getBatches(0, nEvents)) {
106 std::span<const double> span{item.second};
109 auto &buffer = buffers.top();
110 buffer.reserve(nNonZeroWeight);
112 for (std::size_t i = 0; i < nEvents; ++i) {
113 if (!hasZeroWeight[i]) {
114 buffer.push_back(span[i]);
117 insert(item.first->GetName(), {buffer.data(), buffer.size()});
122 for (
auto const &item :
data.getCategoryBatches(0, nEvents)) {
124 std::span<const RooAbsCategory::value_type> intSpan{item.second};
127 auto &buffer = buffers.top();
128 buffer.reserve(nNonZeroWeight);
130 for (std::size_t i = 0; i < nEvents; ++i) {
131 if (!hasZeroWeight[i]) {
132 buffer.push_back(
static_cast<double>(intSpan[i]));
135 insert(item.first->GetName(), {buffer.data(), buffer.size()});
138 nEvents = nNonZeroWeight;
141 if (!rangeName.empty()) {
143 std::vector<bool> isInRange(nEvents,
false);
144 for (
auto const &range :
ROOT::
Split(rangeName,
",")) {
145 std::vector<bool> isInSubRange(nEvents,
true);
149 observable->inRange({
retrieve(observable->GetName()).data(), nEvents}, range, isInSubRange);
152 for (std::size_t i = 0; i < isInSubRange.size(); ++i) {
153 isInRange[i] = isInRange[i] || isInSubRange[i];
158 nEvents = std::accumulate(isInRange.begin(), isInRange.end(), 0);
161 for (
auto const &item : dataSpans) {
162 auto const &allValues = item.second;
163 if (allValues.size() == 1) {
166 buffers.emplace(nEvents);
167 double *buffer = buffers.top().data();
169 for (std::size_t i = 0; i < isInRange.size(); ++i) {
171 buffer[j] = allValues[i];
175 assignSpan(dataSpans[item.first], {buffer, nEvents});
208std::map<RooFit::Detail::DataKey, std::span<const double>>
211 bool takeGlobalObservablesFromData, std::stack<std::vector<double>> &buffers)
213 std::vector<std::pair<std::string, RooAbsData const *>> datasets;
214 std::vector<bool> isBinnedL;
215 bool splitRange =
false;
216 std::vector<std::unique_ptr<RooAbsData>> splitDataSets;
219 std::unique_ptr<TList> splits{
data.split(*simPdf,
true)};
220 for (
auto *
d : static_range_cast<RooAbsData *>(*splits)) {
226 datasets.emplace_back(std::string(
"_") +
d->GetName() +
"_",
d);
227 isBinnedL.emplace_back(simComponent->
getAttribute(
"BinnedLikelihoodActive"));
229 splitDataSets.emplace_back(
d);
233 datasets.emplace_back(
"", &
data);
234 isBinnedL.emplace_back(
false);
237 std::map<RooFit::Detail::DataKey, std::span<const double>> dataSpans;
239 for (std::size_t iData = 0; iData < datasets.size(); ++iData) {
240 auto const &toAdd = datasets[iData];
241 auto spans = getSingleDataSpans(
243 toAdd.first, buffers, skipZeroWeights && !isBinnedL[iData]);
244 for (
auto const &item : spans) {
245 dataSpans.insert(item);
249 if (takeGlobalObservablesFromData &&
data.getGlobalObservables()) {
251 auto &buffer = buffers.top();
252 buffer.reserve(
data.getGlobalObservables()->size());
253 for (
auto *arg : static_range_cast<RooRealVar const *>(*
data.getGlobalObservables())) {
254 buffer.push_back(arg->getVal());
255 assignSpan(dataSpans[arg], {&buffer.back(), 1});
274 std::map<RooFit::Detail::DataKey, std::size_t>
output;
280 std::size_t inputSize = inputSizeFunc(arg);
287 std::size_t
size = 1;
291 if (!arg->isReducerNode()) {
292 for (
RooAbsArg *server : arg->servers()) {
293 if (server->isValueServer(*arg)) {
ROOT::RRangeCast< T, true, Range_t > dynamic_range_cast(Range_t &&coll)
static void retrieve(const gsl_integration_workspace *workspace, double *a, double *b, double *r, double *e)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
RooAbsData is the common abstract base class for binned and unbinned datasets.
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
RooArgSet is a container object that can hold multiple RooAbsArg objects.
static constexpr const char * weightVarName
static constexpr const char * weightVarNameSumW2
static RooNameReg & instance()
Return reference to singleton instance.
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
RooAbsPdf * getPdf(RooStringView catName) const
Return the p.d.f associated with the given index category name.
The TNamed class is the base class for all named ROOT classes.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
std::map< RooFit::Detail::DataKey, std::span< const double > > getDataSpans(RooAbsData const &data, std::string const &rangeName, RooSimultaneous const *simPdf, bool skipZeroWeights, bool takeGlobalObservablesFromData, std::stack< std::vector< double > > &buffers)
Extract all content from a RooFit datasets as a map of spans.
std::map< RooFit::Detail::DataKey, std::size_t > determineOutputSizes(RooAbsArg const &topNode, std::function< std::size_t(RooFit::Detail::DataKey)> const &inputSizeFunc)
Figure out the output size for each node in the computation graph that leads up to the top node,...
std::string getRangeNameForSimComponent(std::string const &rangeName, bool splitRange, std::string const &catName)
void getSortedComputationGraph(RooAbsArg const &func, RooArgSet &out)
Get the topologically-sorted list of all nodes in the computation graph.
#define Split(a, ahi, alo)