26 RooAbsCategory const &category, std::stack<std::vector<double>> &buffers)
28 std::stack<std::vector<double>> oldBuffers;
29 std::swap(buffers, oldBuffers);
31 auto catVals = dataSpans.at(category.
namePtr());
33 std::map<RooFit::Detail::DataKey, RooSpan<const double>> dataMapSplit;
35 for (
auto const &dataMapItem : dataSpans) {
37 auto const &varNamePtr = dataMapItem.first;
38 auto const &xVals = dataMapItem.second;
40 if (varNamePtr == category.
namePtr())
43 std::map<RooAbsCategory::value_type, std::vector<double>> valuesMap;
45 if (xVals.size() == 1) {
48 for (
auto const &catItem : category) {
49 valuesMap[catItem.second].push_back(xVals[0]);
52 for (std::size_t i = 0; i < xVals.size(); ++i) {
53 valuesMap[catVals[i]].push_back(xVals[i]);
57 for (
auto const &item : valuesMap) {
59 auto variableName = std::string(
"_") + category.
lookupName(index) +
"_" + varNamePtr->GetName();
62 buffers.emplace(std::move(item.second));
63 auto const &values = buffers.top();
68 dataSpans = std::move(dataMapSplit);
97std::map<RooFit::Detail::DataKey, RooSpan<const double>>
99 RooAbsCategory const *indexCat, std::stack<std::vector<double>> &buffers,
100 bool skipZeroWeights)
102 std::map<RooFit::Detail::DataKey, RooSpan<const double>> dataSpans;
104 std::size_t nEvents =
static_cast<size_t>(data.
numEntries());
111 if (!buffers.empty()) {
112 throw std::invalid_argument(
"The buffers container must be empty when passed to getDataSpans()!");
120 std::vector<bool> hasZeroWeight;
121 hasZeroWeight.resize(nEvents);
122 std::size_t nNonZeroWeight = 0;
129 auto &buffer = buffers.top();
131 auto &bufferSumW2 = buffers.top();
132 if (weight.empty()) {
136 buffer.push_back(1.0);
137 bufferSumW2.push_back(1.0);
140 nNonZeroWeight = nEvents;
142 buffer.reserve(nEvents);
143 bufferSumW2.reserve(nEvents);
144 for (std::size_t i = 0; i < nEvents; ++i) {
145 if (!skipZeroWeights || weight[i] != 0) {
146 buffer.push_back(weight[i]);
147 bufferSumW2.push_back(weightSumW2[i]);
150 hasZeroWeight[i] =
true;
157 dataSpans[nameReg.constPtr(RooNLLVarNew::weightVarName)] = weight;
158 dataSpans[nameReg.constPtr(RooNLLVarNew::weightVarNameSumW2)] = weightSumW2;
163 for (
auto const &item : data.
getBatches(0, nEvents)) {
165 const TNamed *namePtr = nameReg.constPtr(item.first->GetName());
169 auto &buffer = buffers.top();
170 buffer.reserve(nNonZeroWeight);
172 for (std::size_t i = 0; i < nEvents; ++i) {
173 if (!hasZeroWeight[i]) {
174 buffer.push_back(span[i]);
184 const TNamed *namePtr = nameReg.constPtr(item.first->GetName());
188 auto &buffer = buffers.top();
189 buffer.reserve(nNonZeroWeight);
191 for (std::size_t i = 0; i < nEvents; ++i) {
192 if (!hasZeroWeight[i]) {
193 buffer.push_back(
static_cast<double>(intSpan[i]));
199 nEvents = nNonZeroWeight;
202 if (!rangeName.empty()) {
204 std::vector<bool> isInRange(nEvents,
false);
205 for (
auto const &range :
ROOT::Split(rangeName,
",")) {
206 std::vector<bool> isInSubRange(nEvents,
true);
207 for (
auto *observable : dynamic_range_cast<RooAbsRealLValue *>(*data.
get())) {
211 observable->inRange({dataSpans.at(observable->namePtr()).data(), nEvents}, range, isInSubRange);
213 for (std::size_t i = 0; i < isInSubRange.size(); ++i) {
214 isInRange[i] = isInRange[i] | isInSubRange[i];
219 nEvents = std::accumulate(isInRange.begin(), isInRange.end(), 0);
222 for (
auto const &item : dataSpans) {
223 auto const &allValues = item.second;
224 if (allValues.size() == 1) {
227 buffers.emplace(nEvents);
228 double *buffer = buffers.top().data();
230 for (std::size_t i = 0; i < isInRange.size(); ++i) {
232 buffer[j] = allValues[i];
241 splitByCategory(dataSpans, *indexCat, buffers);
const TNamed * namePtr() const
De-duplicated pointer to this object's name.
RooAbsCategory is the base class for objects that represent a discrete value with a finite number of ...
const std::string & lookupName(value_type index) const
Get the name corresponding to the given index.
RooAbsData is the common abstract base class for binned and unbinned datasets.
virtual const RooArgSet * get() const
CategorySpans getCategoryBatches(std::size_t first=0, std::size_t len=std::numeric_limits< std::size_t >::max()) const
RealSpans getBatches(std::size_t first=0, std::size_t len=std::numeric_limits< std::size_t >::max()) const
Write information to retrieve data columns into evalData.spans.
virtual RooSpan< const double > getWeightBatch(std::size_t first, std::size_t len, bool sumW2=false) const =0
Return event weights of all events in range [first, first+len).
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
const TNamed * constPtr(const char *stringPtr)
Return a unique TNamed pointer for given C++ string.
static RooNameReg & instance()
Return reference to singleton instance.
A simple container to hold a batch of data values.
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::map< RooFit::Detail::DataKey, RooSpan< const double > > getDataSpans(RooAbsData const &data, std::string_view rangeName, RooAbsCategory const *indexCat, std::stack< std::vector< double > > &buffers, bool skipZeroWeights)
Extract all content from a RooFit datasets as a map of spans.