Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooAbsDataFiller.cxx
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * Stephan Hageboeck, CERN 2021
5 *
6 * Copyright (c) 2024, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
13#include <RooAbsDataFiller.h>
14
15#include <RooMsgService.h>
16
17#include <TROOT.h>
18
19#include <stdexcept>
20
21namespace RooFit {
22namespace Detail {
23
25{
26 const auto nSlots = ROOT::IsImplicitMTEnabled() ? ROOT::GetThreadPoolSize() : 1;
27 _events.resize(nSlots);
28}
29
31{
32 RooAbsData &absData = GetAbsData();
33
34 _eventSize = absData.get()->size();
35 _isWeighted = absData.isWeighted();
36 _isDataHist = std::string{absData.ClassName()} != "RooDataSet";
37}
38
39/// Append all `events` to the internal RooDataSet or increment the bins of a RooDataHist at the given locations.
40///
41/// \param events Events to fill into `data`. The layout is assumed to be `(x, y, z, ...) (x, y, z, ...), (...)`.
42/// \note The order of the variables inside `events` must be consistent with the order given in the constructor.
43/// No matching by name is performed.
44/// \param eventSize Size of a single event.
45void RooAbsDataFiller::FillAbsData(const std::vector<double> &events, unsigned int eventSize)
46{
47 if (events.empty())
48 return;
49
50 RooAbsData &absData = GetAbsData();
51 const RooArgSet &argSet = *absData.get();
52
53 // Relevant for weighted RooDataSet
54 RooRealVar *weightVar = !_isDataHist && _isWeighted ? static_cast<RooDataSet &>(absData).weightVar() : nullptr;
55
56 for (std::size_t i = 0; i < events.size(); i += eventSize) {
57
58 // The RooDataHist has no dedicated RooRealVar for the weight. So we just
59 // use a double.
60 double weightVal = 1.0;
61
62 // Creating a RooDataSet from an RDataFrame should be consistent with the
63 // creation from a TTree. The construction from a TTree discards entries
64 // outside the variable definition range, so we have to do that too (see
65 // also RooTreeDataStore::loadValues).
66
67 bool allOK = true;
68 for (std::size_t j = 0; j < eventSize; ++j) {
69 RooAbsRealLValue *destArg = nullptr;
70 if (j < argSet.size()) {
71 destArg = static_cast<RooAbsRealLValue *>(argSet[j]);
72 } else {
73 destArg = weightVar;
74 }
75 double sourceVal = events[i + j];
76
77 if (destArg && !destArg->inRange(sourceVal, nullptr)) {
79 allOK = false;
80 const auto prefix = std::string(absData.ClassName()) + "Helper::FillAbsData(" + absData.GetName() + ") ";
81 if (_numInvalid < 5) {
82 // Unlike in the TreeVectorStore case, we don't log the event
83 // number here because we don't know it anyway, because of
84 // RDataFrame slots and multithreading.
85 oocoutI(nullptr, DataHandling) << prefix << "Skipping event because " << destArg->GetName()
86 << " cannot accommodate the value " << sourceVal << "\n";
87 } else if (_numInvalid == 5) {
88 oocoutI(nullptr, DataHandling) << prefix << "Skipping ...\n";
89 }
90 break;
91 }
92 if (destArg) {
93 destArg->setVal(sourceVal);
94 } else {
95 weightVal = sourceVal;
96 }
97 }
98 if (allOK) {
99 absData.add(argSet, weightVar ? weightVar->getVal() : weightVal);
100 }
101 }
102}
103
104/// Empty all buffers into the dataset/hist to finish processing.
106{
107 RooAbsData &absData = GetAbsData();
108
109 for (auto &vector : _events) {
110 FillAbsData(vector, _nValues);
111 vector.clear();
112 }
113
114 if (_numInvalid > 0) {
115 const auto prefix = std::string(absData.ClassName()) + "Helper::Finalize(" + absData.GetName() + ") ";
116 oocoutW(nullptr, DataHandling) << prefix << "Ignored " << _numInvalid << " out-of-range events\n";
117 }
118}
119
120void RooAbsDataFiller::ExecImpl(std::size_t nValues, std::vector<double> &vector)
121{
122 if (nValues != _eventSize && !(_isWeighted && nValues == _eventSize + 1)) {
123 throw std::invalid_argument(std::string("RooAbsData can hold ") + std::to_string(_eventSize) +
124 " variables per event (plus an optional weight in case of weighted data), but RDataFrame passed " +
125 std::to_string(nValues) + " columns.");
126 }
127
128 _nValues = nValues;
129
130 if (vector.size() > 1024 && _mutexDataset.try_lock()) {
131 const std::lock_guard<std::mutex> guard(_mutexDataset, std::adopt_lock_t());
132 FillAbsData(vector, _nValues);
133 vector.clear();
134 }
135}
136
137} // namespace Detail
138} // namespace RooFit
#define oocoutW(o, a)
#define oocoutI(o, a)
Storage_t::size_type size() const
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:57
virtual const RooArgSet * get() const
Definition RooAbsData.h:101
virtual bool isWeighted() const
Definition RooAbsData.h:152
virtual void add(const RooArgSet &row, double weight=1)=0
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
virtual void setVal(double value)=0
Set the current value of the object. Needs to be overridden by implementations.
bool inRange(const char *name) const override
Check if current value is inside range with given name.
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
Container class to hold unbinned data.
Definition RooDataSet.h:57
virtual RooAbsData & GetAbsData()=0
void Initialize()
RDataFrame interface method.
void FillAbsData(const std::vector< double > &events, unsigned int eventSize)
Append all events to the internal RooDataSet or increment the bins of a RooDataHist at the given loca...
std::vector< std::vector< double > > _events
void Finalize()
Empty all buffers into the dataset/hist to finish processing.
void ExecImpl(std::size_t nValues, std::vector< double > &vector)
Variable that can be changed from the outside.
Definition RooRealVar.h:37
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
Definition TROOT.cxx:570
UInt_t GetThreadPoolSize()
Returns the size of ROOT's thread pool.
Definition TROOT.cxx:577
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition JSONIO.h:26