33void assignSpan(std::span<T> &to, std::span<T>
const &from)
38std::map<RooFit::Detail::DataKey, std::span<const double>>
39getSingleDataSpans(
RooAbsData const &data, std::string_view rangeName, std::string
const &prefix,
40 std::stack<std::vector<double>> &buffers,
bool skipZeroWeights)
42 std::map<RooFit::Detail::DataKey, std::span<const double>> dataSpans;
46 auto insert = [&](
const char *key, std::span<const double> span) {
47 const TNamed *namePtr = nameReg.constPtr((prefix + key).c_str());
48 dataSpans[namePtr] = span;
51 auto retrieve = [&](
const char *key) {
52 const TNamed *namePtr = nameReg.constPtr((prefix + key).c_str());
53 return dataSpans.at(namePtr);
56 std::size_t nEvents =
static_cast<size_t>(data.numEntries());
58 auto weight = data.getWeightBatch(0, nEvents,
false);
59 auto weightSumW2 = data.getWeightBatch(0, nEvents,
true);
61 std::vector<bool> hasZeroWeight;
62 hasZeroWeight.resize(nEvents);
63 std::size_t nNonZeroWeight = 0;
70 auto &buffer = buffers.top();
72 auto &bufferSumW2 = buffers.top();
73 buffer.reserve(nEvents);
74 bufferSumW2.reserve(nEvents);
75 for (std::size_t i = 0; i < nEvents; ++i) {
78 buffer.push_back(1.0);
79 bufferSumW2.push_back(1.0);
81 }
else if (!skipZeroWeights || weight[i] != 0) {
82 buffer.push_back(weight[i]);
83 bufferSumW2.push_back(weightSumW2[i]);
86 hasZeroWeight[i] =
true;
89 assignSpan(weight, {buffer.data(), nNonZeroWeight});
90 assignSpan(weightSumW2, {bufferSumW2.data(), nNonZeroWeight});
91 insert(RooFit::Detail::RooNLLVarNew::weightVarName, weight);
92 insert(RooFit::Detail::RooNLLVarNew::weightVarNameSumW2, weightSumW2);
98 if (
auto const *dataHist =
dynamic_cast<RooDataHist const *
>(&data)) {
99 auto binVolumes = dataHist->binVolumes(0,
static_cast<std::size_t
>(data.numEntries()));
101 auto &bufferBinVol = buffers.top();
102 bufferBinVol.reserve(nNonZeroWeight);
104 auto &bufferErrLo = buffers.top();
105 bufferErrLo.reserve(nNonZeroWeight);
107 auto &bufferErrHi = buffers.top();
108 bufferErrHi.reserve(nNonZeroWeight);
110 auto *dataHistMutable =
const_cast<RooDataHist *
>(dataHist);
111 for (std::size_t i = 0; i < binVolumes.size(); ++i) {
112 if (hasZeroWeight[i]) {
115 bufferBinVol.push_back(binVolumes[i]);
116 dataHistMutable->get(
static_cast<int>(i));
120 bufferErrLo.push_back(lo);
121 bufferErrHi.push_back(
hi);
123 insert(RooFit::Detail::RooNLLVarNew::binVolumeVarName, {bufferBinVol.data(), bufferBinVol.size()});
124 insert(RooFit::Detail::RooNLLVarNew::weightErrorLoVarName, {bufferErrLo.data(), bufferErrLo.size()});
125 insert(RooFit::Detail::RooNLLVarNew::weightErrorHiVarName, {bufferErrHi.data(), bufferErrHi.size()});
130 for (
auto const &item : data.getBatches(0, nEvents)) {
132 std::span<const double> span{item.second};
135 auto &buffer = buffers.top();
136 buffer.reserve(nNonZeroWeight);
138 for (std::size_t i = 0; i < nEvents; ++i) {
139 if (!hasZeroWeight[i]) {
140 buffer.push_back(span[i]);
143 insert(item.first->GetName(), {buffer.data(), buffer.size()});
148 for (
auto const &item : data.getCategoryBatches(0, nEvents)) {
150 std::span<const RooAbsCategory::value_type> intSpan{item.second};
153 auto &buffer = buffers.top();
154 buffer.reserve(nNonZeroWeight);
156 for (std::size_t i = 0; i < nEvents; ++i) {
157 if (!hasZeroWeight[i]) {
158 buffer.push_back(
static_cast<double>(intSpan[i]));
161 insert(item.first->GetName(), {buffer.data(), buffer.size()});
164 nEvents = nNonZeroWeight;
167 if (!rangeName.empty()) {
169 std::vector<bool> isInRange(nEvents,
false);
170 for (
auto const &range :
ROOT::Split(rangeName,
",")) {
171 std::vector<bool> isInSubRange(nEvents,
true);
175 observable->inRange({
retrieve(observable->GetName()).data(), nEvents}, range, isInSubRange);
178 for (std::size_t i = 0; i < isInSubRange.size(); ++i) {
179 isInRange[i] = isInRange[i] || isInSubRange[i];
184 nEvents = std::accumulate(isInRange.begin(), isInRange.end(), 0);
187 for (
auto const &item : dataSpans) {
188 auto const &allValues = item.second;
189 if (allValues.size() == 1) {
192 buffers.emplace(nEvents);
193 double *buffer = buffers.top().data();
195 for (std::size_t i = 0; i < isInRange.size(); ++i) {
197 buffer[j] = allValues[i];
201 assignSpan(dataSpans[item.first], {buffer, nEvents});
234std::map<RooFit::Detail::DataKey, std::span<const double>>
235RooFit::BatchModeDataHelpers::getDataSpans(
RooAbsData const &data, std::string
const &rangeName,
237 bool takeGlobalObservablesFromData, std::stack<std::vector<double>> &buffers)
239 std::vector<std::pair<std::string, RooAbsData const *>> datasets;
240 std::vector<bool> isBinnedL;
241 bool splitRange =
false;
244 std::vector<std::unique_ptr<RooAbsData>> splitDataSets;
247 splitDataSets = data.split(*simPdf,
true);
248 for (
auto const &
d : splitDataSets) {
254 datasets.emplace_back(std::string(
"_") +
d->GetName() +
"_",
d.get());
255 isBinnedL.emplace_back(simComponent->
getAttribute(
"BinnedLikelihoodActive"));
259 datasets.emplace_back(
"", &data);
260 isBinnedL.emplace_back(
false);
263 std::map<RooFit::Detail::DataKey, std::span<const double>> dataSpans;
265 for (std::size_t iData = 0; iData < datasets.size(); ++iData) {
266 auto const &toAdd = datasets[iData];
267 auto spans = getSingleDataSpans(
269 toAdd.first, buffers, skipZeroWeights && !isBinnedL[iData]);
270 for (
auto const &item : spans) {
271 dataSpans.insert(item);
275 if (takeGlobalObservablesFromData && data.getGlobalObservables()) {
277 auto &buffer = buffers.top();
278 buffer.reserve(data.getGlobalObservables()->size());
280 buffer.push_back(arg->getVal());
281 assignSpan(dataSpans[arg], {&buffer.back(), 1});
297std::map<RooFit::Detail::DataKey, std::size_t>
298RooFit::BatchModeDataHelpers::determineOutputSizes(
RooAbsArg const &topNode,
301 std::map<RooFit::Detail::DataKey, std::size_t> output;
307 int inputSize = inputSizeFunc(arg);
310 if (inputSize != -1) {
311 output[arg] = inputSize;
316 std::size_t
size = 1;
317 if (output.find(arg) != output.end()) {
320 if (!arg->isReducerNode()) {
322 if (server->isValueServer(*arg)) {
323 std::size_t inputSize = output.at(server);
324 if (inputSize != 1) {
ROOT::RRangeCast< T, true, Range_t > dynamic_range_cast(Range_t &&coll)
ROOT::RRangeCast< T, false, Range_t > static_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
Common abstract base class for objects that represent a value and a "shape" in RooFit.
const RefCountList_t & servers() const
List of all servers of this object.
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Abstract base class for binned and unbinned datasets.
Abstract interface for all probability density functions.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Container class to hold N-dimensional binned data.
static RooNameReg & instance()
Return reference to singleton instance.
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.
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
std::string getRangeNameForSimComponent(std::string const &rangeName, bool splitRange, std::string const &catName)
void getSortedComputationGraph(RooAbsArg const &func, RooArgSet &out)