19#ifndef ROOT_RDFOPERATIONS 
   20#define ROOT_RDFOPERATIONS 
   75   std::vector<TBranch *> fBranches;
 
   76   std::vector<std::string> fNames;
 
   81      auto it = std::find(fNames.begin(), fNames.end(), 
name);
 
   82      if (it == fNames.end())
 
   84      return fBranches[std::distance(fNames.begin(), it)];
 
   87   void Insert(
const std::string &
name, 
TBranch *address)
 
   89      if (address == 
nullptr) {
 
   90         throw std::logic_error(
"Trying to insert a null branch address.");
 
   92      if (std::find(fBranches.begin(), fBranches.end(), address) != fBranches.end()) {
 
   93         throw std::logic_error(
"Trying to insert a branch address that's already present.");
 
   95      if (std::find(fNames.begin(), fNames.end(), 
name) != fNames.end()) {
 
   96         throw std::logic_error(
"Trying to insert a branch name that's already present.");
 
   98      fNames.emplace_back(
name);
 
   99      fBranches.emplace_back(address);
 
  108   void AssertNoNullBranchAddresses()
 
  110      std::vector<TBranch *> branchesWithNullAddress;
 
  111      std::copy_if(fBranches.begin(), fBranches.end(), std::back_inserter(branchesWithNullAddress),
 
  112                   [](
TBranch *
b) { return b->GetAddress() == nullptr; });
 
  114      if (branchesWithNullAddress.empty())
 
  118      std::vector<std::string> missingBranchNames;
 
  119      std::transform(branchesWithNullAddress.begin(), branchesWithNullAddress.end(),
 
  120                     std::back_inserter(missingBranchNames), [](
TBranch *
b) { return b->GetName(); });
 
  121      std::string msg = 
"RDataFrame::Snapshot:";
 
  122      if (missingBranchNames.size() == 1) {
 
  123         msg += 
" branch " + missingBranchNames[0] +
 
  124                " is needed as it provides the size for one or more branches containing dynamically sized arrays, but " 
  128         for (
const auto &bName : missingBranchNames)
 
  130         msg.resize(msg.size() - 2); 
 
  132            " are needed as they provide the size of other branches containing dynamically sized arrays, but they are";
 
  134      msg += 
" not part of the set of branches that are being written out.";
 
  135      throw std::runtime_error(msg);
 
  144using Results = std::conditional_t<std::is_same<T, bool>::value, std::deque<T>, std::vector<T>>;
 
  147class R__CLING_PTRCHECK(off) ForeachSlotHelper : 
public RActionImpl<ForeachSlotHelper<F>> {
 
  153   ForeachSlotHelper(ForeachSlotHelper &&) = 
default;
 
  154   ForeachSlotHelper(
const ForeachSlotHelper &) = 
delete;
 
  158   template <
typename... Args>
 
  159   void Exec(
unsigned int slot, Args &&... args)
 
  162      static_assert(std::is_same<TypeList<std::decay_t<Args>...>, ColumnTypes_t>
::value, 
"");
 
  163      fCallable(slot, std::forward<Args>(args)...);
 
  170   std::string GetActionName() { 
return "ForeachSlot"; }
 
  173class R__CLING_PTRCHECK(off) CountHelper : 
public RActionImpl<CountHelper> {
 
  174   std::shared_ptr<ULong64_t> fResultCount;
 
  175   Results<ULong64_t> fCounts;
 
  179   CountHelper(
const std::shared_ptr<ULong64_t> &resultCount, 
const unsigned int nSlots);
 
  180   CountHelper(CountHelper &&) = 
default;
 
  181   CountHelper(
const CountHelper &) = 
delete;
 
  183   void Exec(
unsigned int slot);
 
  190      return std::make_unique<RMergeableCount>(*fResultCount);
 
  193   ULong64_t &PartialUpdate(
unsigned int slot);
 
  195   std::string GetActionName() { 
return "Count"; }
 
  197   CountHelper MakeNew(
void *newResult)
 
  199      auto &
result = *
static_cast<std::shared_ptr<ULong64_t> *
>(newResult);
 
  200      return CountHelper(
result, fCounts.size());
 
  204template <
typename RNode_t>
 
  205class R__CLING_PTRCHECK(off) ReportHelper : 
public RActionImpl<ReportHelper<RNode_t>> {
 
  206   std::shared_ptr<RCutFlowReport> fReport;
 
  210   bool fReturnEmptyReport;
 
  214   ReportHelper(
const std::shared_ptr<RCutFlowReport> &report, RNode_t *node, 
bool emptyRep)
 
  215      : fReport(report), fNode(node), fReturnEmptyReport(emptyRep){};
 
  216   ReportHelper(ReportHelper &&) = 
default;
 
  217   ReportHelper(
const ReportHelper &) = 
delete;
 
  219   void Exec(
unsigned int ) {}
 
  223      if (!fReturnEmptyReport)
 
  224         fNode->Report(*fReport);
 
  227   std::string GetActionName() { 
return "Report"; }
 
  239class R__CLING_PTRCHECK(off) BufferedFillHelper : 
public RActionImpl<BufferedFillHelper> {
 
  241   static constexpr unsigned int fgTotalBufSize = 2097152;
 
  243   using Buf_t = std::vector<BufEl_t>;
 
  245   std::vector<Buf_t> fBuffers;
 
  246   std::vector<Buf_t> fWBuffers;
 
  247   std::shared_ptr<Hist_t> fResultHist;
 
  248   unsigned int fNSlots;
 
  249   unsigned int fBufSize;
 
  251   Results<std::unique_ptr<Hist_t>> fPartialHists;
 
  255   void UpdateMinMax(
unsigned int slot, 
double v);
 
  258   BufferedFillHelper(
const std::shared_ptr<Hist_t> &
h, 
const unsigned int nSlots);
 
  259   BufferedFillHelper(BufferedFillHelper &&) = 
default;
 
  260   BufferedFillHelper(
const BufferedFillHelper &) = 
delete;
 
  262   void Exec(
unsigned int slot, 
double v);
 
  263   void Exec(
unsigned int slot, 
double v, 
double w);
 
  265   template <typename T, std::enable_if_t<IsDataContainer<T>::value || std::is_same<T, std::string>::value, 
int> = 0>
 
  266   void Exec(
unsigned int slot, 
const T &vs)
 
  268      auto &thisBuf = fBuffers[slot];
 
  270      for (
auto v = vs.begin(); 
v != vs.end(); ++
v) {
 
  271         UpdateMinMax(slot, *
v);
 
  272         thisBuf.emplace_back(*
v); 
 
  276   template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && IsDataContainer<W>::value, 
int> = 0>
 
  277   void Exec(
unsigned int slot, 
const T &vs, 
const W &ws)
 
  279      auto &thisBuf = fBuffers[slot];
 
  282         UpdateMinMax(slot, 
v);
 
  283         thisBuf.emplace_back(
v);
 
  286      auto &thisWBuf = fWBuffers[slot];
 
  288         thisWBuf.emplace_back(
w); 
 
  292   template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && !IsDataContainer<W>::value, 
int> = 0>
 
  293   void Exec(
unsigned int slot, 
const T &vs, 
const W 
w)
 
  295      auto &thisBuf = fBuffers[slot];
 
  297         UpdateMinMax(slot, 
v);
 
  298         thisBuf.emplace_back(
v); 
 
  301      auto &thisWBuf = fWBuffers[slot];
 
  302      thisWBuf.insert(thisWBuf.end(), vs.size(), 
w);
 
  305   template <typename T, typename W, std::enable_if_t<IsDataContainer<W>::value && !IsDataContainer<T>::value, 
int> = 0>
 
  306   void Exec(
unsigned int slot, 
const T 
v, 
const W &ws)
 
  308      UpdateMinMax(slot, 
v);
 
  309      auto &thisBuf = fBuffers[slot];
 
  310      thisBuf.insert(thisBuf.end(), ws.size(), 
v);
 
  312      auto &thisWBuf = fWBuffers[slot];
 
  313      thisWBuf.insert(thisWBuf.end(), ws.begin(), ws.end());
 
  316   Hist_t &PartialUpdate(
unsigned int);
 
  325      return std::make_unique<RMergeableFill<Hist_t>>(*fResultHist);
 
  328   std::string GetActionName()
 
  330      return std::string(fResultHist->IsA()->GetName()) + 
"\\n" + std::string(fResultHist->GetName());
 
  333   BufferedFillHelper MakeNew(
void *newResult)
 
  335      auto &
result = *
static_cast<std::shared_ptr<Hist_t> *
>(newResult);
 
  337      result->SetDirectory(
nullptr);
 
  338      return BufferedFillHelper(
result, fNSlots);
 
  342extern template void BufferedFillHelper::Exec(
unsigned int, 
const std::vector<float> &);
 
  343extern template void BufferedFillHelper::Exec(
unsigned int, 
const std::vector<double> &);
 
  344extern template void BufferedFillHelper::Exec(
unsigned int, 
const std::vector<char> &);
 
  345extern template void BufferedFillHelper::Exec(
unsigned int, 
const std::vector<int> &);
 
  346extern template void BufferedFillHelper::Exec(
unsigned int, 
const std::vector<unsigned int> &);
 
  347extern template void BufferedFillHelper::Exec(
unsigned int, 
const std::vector<float> &, 
const std::vector<float> &);
 
  348extern template void BufferedFillHelper::Exec(
unsigned int, 
const std::vector<double> &, 
const std::vector<double> &);
 
  349extern template void BufferedFillHelper::Exec(
unsigned int, 
const std::vector<char> &, 
const std::vector<char> &);
 
  350extern template void BufferedFillHelper::Exec(
unsigned int, 
const std::vector<int> &, 
const std::vector<int> &);
 
  352BufferedFillHelper::Exec(
unsigned int, 
const std::vector<unsigned int> &, 
const std::vector<unsigned int> &);
 
  356template <
typename HIST = Hist_t>
 
  358   std::vector<HIST *> fObjects;
 
  360   template <typename H = HIST, typename = decltype(std::declval<H>().Reset())>
 
  361   void ResetIfPossible(
H *
h)
 
  369   void ResetIfPossible(...)
 
  371      throw std::runtime_error(
 
  372         "A systematic variation was requested for a custom Fill action, but the type of the object to be filled does " 
  373         "not implement a Reset method, so we cannot safely re-initialize variations of the result. Aborting.");
 
  376   void UnsetDirectoryIfPossible(
TH1 *
h) {
 
  377      h->SetDirectory(
nullptr);
 
  380   void UnsetDirectoryIfPossible(...) {}
 
  383   template <typename H, typename = std::enable_if_t<std::is_base_of<TObject, H>::value, 
int>>
 
  384   auto Merge(std::vector<H *> &objs, 
int )
 
  388      for (
auto it = ++objs.begin(); it != objs.end(); ++it)
 
  394   template <
typename H>
 
  395   auto Merge(std::vector<H *> &objs, 
double )
 
  396      -> 
decltype(objs[0]->Merge(std::vector<HIST *>{}), 
void())
 
  398      objs[0]->Merge({++objs.begin(), objs.end()});
 
  402   template <
typename T>
 
  405      static_assert(
sizeof(
T) < 0,
 
  406                    "The type passed to Fill does not provide a Merge(TCollection*) or Merge(const std::vector&) method.");
 
  410   template <
typename T>
 
  411   class ScalarConstIterator {
 
  415      ScalarConstIterator(
const T *obj) : obj_(obj) {}
 
  417      ScalarConstIterator<T> &operator++() { 
return *
this; }
 
  425   template <typename T, std::enable_if_t<!IsDataContainer<T>::value, 
int> = 0>
 
  426   ScalarConstIterator<T> MakeBegin(
const T &val)
 
  428      return ScalarConstIterator<T>(&val);
 
  432   template <typename T, std::enable_if_t<IsDataContainer<T>::value, 
int> = 0>
 
  433   auto MakeBegin(
const T &val)
 
  435      return std::begin(val);
 
  439   template <typename T, std::enable_if_t<!IsDataContainer<T>::value, 
int> = 0>
 
  440   std::size_t GetSize(
const T &)
 
  446   template <typename T, std::enable_if_t<IsDataContainer<T>::value, 
int> = 0>
 
  447   std::size_t GetSize(
const T &val)
 
  449#if __cplusplus >= 201703L 
  450      return std::size(val);
 
  456   template <std::size_t ColIdx, 
typename End_t, 
typename... Its>
 
  457   void ExecLoop(
unsigned int slot, End_t end, Its... its)
 
  459      auto *thisSlotH = fObjects[slot];
 
  462      auto nop = [](
auto &&...) {};
 
  463      for (; GetNthElement<ColIdx>(its...) != end; nop(++its...)) {
 
  464         thisSlotH->Fill(*its...);
 
  469   FillHelper(FillHelper &&) = 
default;
 
  470   FillHelper(
const FillHelper &) = 
delete;
 
  472   FillHelper(
const std::shared_ptr<HIST> &
h, 
const unsigned int nSlots) : fObjects(nSlots, nullptr)
 
  474      fObjects[0] = 
h.get();
 
  476      for (
unsigned int i = 1; i < nSlots; ++i) {
 
  477         fObjects[i] = 
new HIST(*fObjects[0]);
 
  478         UnsetDirectoryIfPossible(fObjects[i]);
 
  485   template <
typename... ValTypes, std::enable_if_t<!Disjunction<IsDataContainer<ValTypes>...>
::value, 
int> = 0>
 
  486   auto Exec(
unsigned int slot, 
const ValTypes &...
x) -> 
decltype(fObjects[slot]->Fill(
x...), 
void())
 
  488      fObjects[slot]->Fill(
x...);
 
  492   template <
typename... Xs, std::enable_if_t<Disjunction<IsDataContainer<Xs>...>
::value, 
int> = 0>
 
  493   auto Exec(
unsigned int slot, 
const Xs &...xs) -> 
decltype(fObjects[slot]->Fill(*MakeBegin(xs)...), 
void())
 
  496      constexpr std::array<
bool, 
sizeof...(Xs)> isContainer{IsDataContainer<Xs>::value...};
 
  499      constexpr std::size_t colidx = 
FindIdxTrue(isContainer);
 
  501      static_assert(colidx < 
sizeof...(Xs), 
"Error: index of collection-type argument not found.");
 
  504      auto const xrefend = std::end(GetNthElement<colidx>(xs...));
 
  507      std::array<std::size_t, 
sizeof...(xs)> sizes = {{GetSize(xs)...}};
 
  509      for (std::size_t i = 0; i < 
sizeof...(xs); ++i) {
 
  510         if (isContainer[i] && sizes[i] != sizes[colidx]) {
 
  511            throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
 
  515      ExecLoop<colidx>(slot, xrefend, MakeBegin(xs)...);
 
  518   template <
typename T = HIST>
 
  521      static_assert(
sizeof(
T) < 0,
 
  522                    "When filling an object with RDataFrame (e.g. via a Fill action) the number or types of the " 
  523                    "columns passed did not match the signature of the object's `Fill` method.");
 
  530      if (fObjects.size() == 1)
 
  536      for (
auto it = ++fObjects.begin(); it != fObjects.end(); ++it)
 
  540   HIST &PartialUpdate(
unsigned int slot) { 
return *fObjects[slot]; }
 
  545      return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
 
  549   template <typename T = HIST, std::enable_if_t<std::is_base_of<TObject, T>::value, 
int> = 0>
 
  550   std::string GetActionName()
 
  552      return std::string(fObjects[0]->
IsA()->GetName()) + 
"\\n" + std::string(fObjects[0]->GetName());
 
  556   template <typename T = HIST, std::enable_if_t<!std::is_base_of<TObject, T>::value, 
int> = 0>
 
  557   std::string GetActionName()
 
  559      return "Fill custom object";
 
  562   template <
typename H = HIST>
 
  563   FillHelper MakeNew(
void *newResult)
 
  565      auto &
result = *
static_cast<std::shared_ptr<H> *
>(newResult);
 
  566      ResetIfPossible(
result.get());
 
  567      UnsetDirectoryIfPossible(
result.get());
 
  568      return FillHelper(
result, fObjects.size());
 
  577   std::vector<::TGraph *> fGraphs;
 
  580   FillTGraphHelper(FillTGraphHelper &&) = 
default;
 
  581   FillTGraphHelper(
const FillTGraphHelper &) = 
delete;
 
  583   FillTGraphHelper(
const std::shared_ptr<::TGraph> &
g, 
const unsigned int nSlots) : fGraphs(nSlots, nullptr)
 
  585      fGraphs[0] = 
g.get();
 
  587      for (
unsigned int i = 1; i < nSlots; ++i) {
 
  588         fGraphs[i] = 
new TGraph(*fGraphs[0]);
 
  596   template <
typename X0, 
typename X1,
 
  597             std::enable_if_t<IsDataContainer<X0>::value && IsDataContainer<X1>::value, 
int> = 0>
 
  598   void Exec(
unsigned int slot, 
const X0 &x0s, 
const X1 &x1s)
 
  600      if (x0s.size() != x1s.size()) {
 
  601         throw std::runtime_error(
"Cannot fill Graph with values in containers of different sizes.");
 
  603      auto *thisSlotG = fGraphs[slot];
 
  604      auto x0sIt = std::begin(x0s);
 
  605      const auto x0sEnd = std::end(x0s);
 
  606      auto x1sIt = std::begin(x1s);
 
  607      for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
 
  608         thisSlotG->SetPoint(thisSlotG->GetN(), *x0sIt, *x1sIt);
 
  613   template <
typename X0, 
typename X1,
 
  614             std::enable_if_t<!IsDataContainer<X0>::value && !IsDataContainer<X1>::value, 
int> = 0>
 
  615   void Exec(
unsigned int slot, X0 x0, X1 
x1)
 
  617      auto thisSlotG = fGraphs[slot];
 
  618      thisSlotG->SetPoint(thisSlotG->GetN(), x0, 
x1);
 
  623   template <
typename X0, 
typename X1, 
typename... ExtraArgsToLowerPriority>
 
  624   void Exec(
unsigned int, X0, X1, ExtraArgsToLowerPriority...)
 
  626      throw std::runtime_error(
"Graph was applied to a mix of scalar values and collections. This is not supported.");
 
  631      const auto nSlots = fGraphs.size();
 
  632      auto resGraph = fGraphs[0];
 
  635      for (
unsigned int slot = 1; slot < nSlots; ++slot) {
 
  636         l.Add(fGraphs[slot]);
 
  644      return std::make_unique<RMergeableFill<Result_t>>(*fGraphs[0]);
 
  647   std::string GetActionName() { 
return "Graph"; }
 
  649   Result_t &PartialUpdate(
unsigned int slot) { 
return *fGraphs[slot]; }
 
  651   FillTGraphHelper MakeNew(
void *newResult)
 
  653      auto &
result = *
static_cast<std::shared_ptr<TGraph> *
>(newResult);
 
  655      return FillTGraphHelper(
result, fGraphs.size());
 
  659class R__CLING_PTRCHECK(off) FillTGraphAsymmErrorsHelper
 
  665   std::vector<::TGraphAsymmErrors *> fGraphAsymmErrors;
 
  668   FillTGraphAsymmErrorsHelper(FillTGraphAsymmErrorsHelper &&) = 
default;
 
  669   FillTGraphAsymmErrorsHelper(
const FillTGraphAsymmErrorsHelper &) = 
delete;
 
  671   FillTGraphAsymmErrorsHelper(
const std::shared_ptr<::TGraphAsymmErrors> &
g, 
const unsigned int nSlots)
 
  672      : fGraphAsymmErrors(nSlots, nullptr)
 
  674      fGraphAsymmErrors[0] = 
g.get();
 
  676      for (
unsigned int i = 1; i < nSlots; ++i) {
 
  686      typename X, 
typename Y, 
typename EXL, 
typename EXH, 
typename EYL, 
typename EYH,
 
  687      std::enable_if_t<IsDataContainer<X>::value && IsDataContainer<Y>::value && IsDataContainer<EXL>::value &&
 
  688                          IsDataContainer<EXH>::value && IsDataContainer<EYL>::value && IsDataContainer<EYH>::value,
 
  691   Exec(
unsigned int slot, 
const X &xs, 
const Y &ys, 
const EXL &exls, 
const EXH &exhs, 
const EYL &eyls, 
const EYH &eyhs)
 
  693      if ((xs.size() != ys.size()) || (xs.size() != exls.size()) || (xs.size() != exhs.size()) ||
 
  694          (xs.size() != eyls.size()) || (xs.size() != eyhs.size())) {
 
  695         throw std::runtime_error(
"Cannot fill GraphAsymmErrors with values in containers of different sizes.");
 
  697      auto *thisSlotG = fGraphAsymmErrors[slot];
 
  698      auto xsIt = std::begin(xs);
 
  699      auto ysIt = std::begin(ys);
 
  700      auto exlsIt = std::begin(exls);
 
  701      auto exhsIt = std::begin(exhs);
 
  702      auto eylsIt = std::begin(eyls);
 
  703      auto eyhsIt = std::begin(eyhs);
 
  704      while (xsIt != std::end(xs)) {
 
  705         const auto n = thisSlotG->GetN(); 
 
  706         thisSlotG->SetPoint(
n, *xsIt++, *ysIt++);
 
  707         thisSlotG->SetPointError(
n, *exlsIt++, *exhsIt++, *eylsIt++, *eyhsIt++);
 
  713      typename X, 
typename Y, 
typename EXL, 
typename EXH, 
typename EYL, 
typename EYH,
 
  714      std::enable_if_t<!IsDataContainer<X>::value && !IsDataContainer<Y>::value && !IsDataContainer<EXL>::value &&
 
  715                          !IsDataContainer<EXH>::value && !IsDataContainer<EYL>::value && !IsDataContainer<EYH>::value,
 
  717   void Exec(
unsigned int slot, X 
x, Y 
y, EXL exl, EXH exh, EYL eyl, EYH eyh)
 
  719      auto thisSlotG = fGraphAsymmErrors[slot];
 
  720      const auto n = thisSlotG->GetN();
 
  721      thisSlotG->SetPoint(
n, 
x, 
y);
 
  722      thisSlotG->SetPointError(
n, exl, exh, eyl, eyh);
 
  727   template <
typename X, 
typename Y, 
typename EXL, 
typename EXH, 
typename EYL, 
typename EYH,
 
  728             typename... ExtraArgsToLowerPriority>
 
  729   void Exec(
unsigned int, X, Y, EXL, EXH, EYL, EYH, ExtraArgsToLowerPriority...)
 
  731      throw std::runtime_error(
 
  732         "GraphAsymmErrors was applied to a mix of scalar values and collections. This is not supported.");
 
  737      const auto nSlots = fGraphAsymmErrors.size();
 
  738      auto resGraphAsymmErrors = fGraphAsymmErrors[0];
 
  741      for (
unsigned int slot = 1; slot < nSlots; ++slot) {
 
  742         l.Add(fGraphAsymmErrors[slot]);
 
  744      resGraphAsymmErrors->Merge(&
l);
 
  750      return std::make_unique<RMergeableFill<Result_t>>(*fGraphAsymmErrors[0]);
 
  753   std::string GetActionName() { 
return "GraphAsymmErrors"; }
 
  755   Result_t &PartialUpdate(
unsigned int slot) { 
return *fGraphAsymmErrors[slot]; }
 
  757   FillTGraphAsymmErrorsHelper MakeNew(
void *newResult)
 
  759      auto &
result = *
static_cast<std::shared_ptr<TGraphAsymmErrors> *
>(newResult);
 
  761      return FillTGraphAsymmErrorsHelper(
result, fGraphAsymmErrors.size());
 
  771template <
typename V, 
typename COLL>
 
  772void FillColl(V&& 
v, COLL& 
c) {
 
  777template <
typename COLL>
 
  778void FillColl(
bool v, COLL& 
c) {
 
  784template <
typename RealT_t, 
typename T, 
typename COLL>
 
  785class R__CLING_PTRCHECK(off) TakeHelper : 
public RActionImpl<TakeHelper<RealT_t, T, COLL>> {
 
  786   Results<std::shared_ptr<COLL>> fColls;
 
  790   TakeHelper(
const std::shared_ptr<COLL> &resultColl, 
const unsigned int nSlots)
 
  792      fColls.emplace_back(resultColl);
 
  793      for (
unsigned int i = 1; i < nSlots; ++i)
 
  794         fColls.emplace_back(std::make_shared<COLL>());
 
  796   TakeHelper(TakeHelper &&);
 
  797   TakeHelper(
const TakeHelper &) = 
delete;
 
  801   void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
 
  807      auto rColl = fColls[0];
 
  808      for (
unsigned int i = 1; i < fColls.size(); ++i) {
 
  809         const auto &coll = fColls[i];
 
  810         const auto end = coll->end();
 
  813         for (
auto j = coll->begin(); j != end; j++) {
 
  814            FillColl(*j, *rColl);
 
  819   COLL &PartialUpdate(
unsigned int slot) { 
return *fColls[slot].get(); }
 
  821   std::string GetActionName() { 
return "Take"; }
 
  823   TakeHelper MakeNew(
void *newResult)
 
  825      auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
 
  827      return TakeHelper(
result, fColls.size());
 
  833template <
typename RealT_t, 
typename T>
 
  834class R__CLING_PTRCHECK(off) TakeHelper<RealT_t, 
T, std::vector<T>>
 
  835   : 
public RActionImpl<TakeHelper<RealT_t, T, std::vector<T>>> {
 
  836   Results<std::shared_ptr<std::vector<T>>> fColls;
 
  840   TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl, 
const unsigned int nSlots)
 
  842      fColls.emplace_back(resultColl);
 
  843      for (
unsigned int i = 1; i < nSlots; ++i) {
 
  844         auto v = std::make_shared<std::vector<T>>();
 
  846         fColls.emplace_back(
v);
 
  849   TakeHelper(TakeHelper &&);
 
  850   TakeHelper(
const TakeHelper &) = 
delete;
 
  854   void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
 
  862      for (
auto &coll : fColls)
 
  863         totSize += coll->
size();
 
  864      auto rColl = fColls[0];
 
  865      rColl->reserve(totSize);
 
  866      for (
unsigned int i = 1; i < fColls.size(); ++i) {
 
  867         auto &coll = fColls[i];
 
  868         rColl->insert(rColl->end(), coll->begin(), coll->end());
 
  872   std::vector<T> &PartialUpdate(
unsigned int slot) { 
return *fColls[slot]; }
 
  874   std::string GetActionName() { 
return "Take"; }
 
  876   TakeHelper MakeNew(
void *newResult)
 
  878      auto &
result = *
static_cast<std::shared_ptr<std::vector<T>
> *>(newResult);
 
  880      return TakeHelper(
result, fColls.size());
 
  886template <
typename RealT_t, 
typename COLL>
 
  887class R__CLING_PTRCHECK(off) TakeHelper<RealT_t, 
RVec<RealT_t>, COLL>
 
  888   : 
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, COLL>> {
 
  889   Results<std::shared_ptr<COLL>> fColls;
 
  893   TakeHelper(
const std::shared_ptr<COLL> &resultColl, 
const unsigned int nSlots)
 
  895      fColls.emplace_back(resultColl);
 
  896      for (
unsigned int i = 1; i < nSlots; ++i)
 
  897         fColls.emplace_back(std::make_shared<COLL>());
 
  899   TakeHelper(TakeHelper &&);
 
  900   TakeHelper(
const TakeHelper &) = 
delete;
 
  910      auto rColl = fColls[0];
 
  911      for (
unsigned int i = 1; i < fColls.size(); ++i) {
 
  912         auto &coll = fColls[i];
 
  913         for (
auto &
v : *coll) {
 
  914            rColl->emplace_back(
v);
 
  919   std::string GetActionName() { 
return "Take"; }
 
  921   TakeHelper MakeNew(
void *newResult)
 
  923      auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
 
  925      return TakeHelper(
result, fColls.size());
 
  931template <
typename RealT_t>
 
  932class R__CLING_PTRCHECK(off) TakeHelper<RealT_t, 
RVec<RealT_t>, std::vector<RealT_t>>
 
  933   : 
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>> {
 
  935   Results<std::shared_ptr<std::vector<std::vector<RealT_t>>>> fColls;
 
  939   TakeHelper(
const std::shared_ptr<std::vector<std::vector<RealT_t>>> &resultColl, 
const unsigned int nSlots)
 
  941      fColls.emplace_back(resultColl);
 
  942      for (
unsigned int i = 1; i < nSlots; ++i) {
 
  943         auto v = std::make_shared<std::vector<RealT_t>>();
 
  945         fColls.emplace_back(
v);
 
  948   TakeHelper(TakeHelper &&);
 
  949   TakeHelper(
const TakeHelper &) = 
delete;
 
  961      for (
auto &coll : fColls)
 
  962         totSize += coll->
size();
 
  963      auto rColl = fColls[0];
 
  964      rColl->reserve(totSize);
 
  965      for (
unsigned int i = 1; i < fColls.size(); ++i) {
 
  966         auto &coll = fColls[i];
 
  967         rColl->insert(rColl->end(), coll->begin(), coll->end());
 
  971   std::string GetActionName() { 
return "Take"; }
 
  973   TakeHelper MakeNew(
void *newResult)
 
  975      auto &
result = *
static_cast<typename decltype(fColls)::value_type *
>(newResult);
 
  977      return TakeHelper(
result, fColls.size());
 
  984template <
typename RealT_t, 
typename T, 
typename COLL>
 
  985TakeHelper<RealT_t, T, COLL>::TakeHelper(TakeHelper<RealT_t, T, COLL> &&) = 
default;
 
  986template <
typename RealT_t, 
typename T>
 
  987TakeHelper<RealT_t, T, std::vector<T>>::TakeHelper(TakeHelper<RealT_t, T, std::vector<T>> &&) = 
default;
 
  988template <
typename RealT_t, 
typename COLL>
 
  989TakeHelper<RealT_t, RVec<RealT_t>, COLL>::TakeHelper(TakeHelper<RealT_t, 
RVec<RealT_t>, COLL> &&) = 
default;
 
  990template <
typename RealT_t>
 
  991TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>::TakeHelper(TakeHelper<RealT_t, 
RVec<RealT_t>, std::vector<RealT_t>> &&) = 
default;
 
  995extern template class TakeHelper<bool, bool, std::vector<bool>>;
 
  996extern template class TakeHelper<unsigned int, unsigned int, std::vector<unsigned int>>;
 
  997extern template class TakeHelper<unsigned long, unsigned long, std::vector<unsigned long>>;
 
  998extern template class TakeHelper<unsigned long long, unsigned long long, std::vector<unsigned long long>>;
 
  999extern template class TakeHelper<int, int, std::vector<int>>;
 
 1000extern template class TakeHelper<long, long, std::vector<long>>;
 
 1001extern template class TakeHelper<long long, long long, std::vector<long long>>;
 
 1002extern template class TakeHelper<float, float, std::vector<float>>;
 
 1003extern template class TakeHelper<double, double, std::vector<double>>;
 
 1006template <
typename ResultType>
 
 1007class R__CLING_PTRCHECK(off) MinHelper : 
public RActionImpl<MinHelper<ResultType>> {
 
 1008   std::shared_ptr<ResultType> fResultMin;
 
 1009   Results<ResultType> fMins;
 
 1012   MinHelper(MinHelper &&) = 
default;
 
 1013   MinHelper(
const std::shared_ptr<ResultType> &minVPtr, 
const unsigned int nSlots)
 
 1014      : fResultMin(minVPtr), fMins(nSlots, std::numeric_limits<ResultType>::max())
 
 1018   void Exec(
unsigned int slot, ResultType 
v) { fMins[slot] = std::min(
v, fMins[slot]); }
 
 1022   template <typename T, std::enable_if_t<IsDataContainer<T>::value, 
int> = 0>
 
 1023   void Exec(
unsigned int slot, 
const T &vs)
 
 1026         fMins[slot] = std::min(static_cast<ResultType>(
v), fMins[slot]);
 
 1033      *fResultMin = std::numeric_limits<ResultType>::max();
 
 1034      for (
auto &
m : fMins)
 
 1035         *fResultMin = std::min(
m, *fResultMin);
 
 1041      return std::make_unique<RMergeableMin<ResultType>>(*fResultMin);
 
 1044   ResultType &PartialUpdate(
unsigned int slot) { 
return fMins[slot]; }
 
 1046   std::string GetActionName() { 
return "Min"; }
 
 1048   MinHelper MakeNew(
void *newResult)
 
 1050      auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
 
 1051      return MinHelper(
result, fMins.size());
 
 1062template <
typename ResultType>
 
 1063class R__CLING_PTRCHECK(off) MaxHelper : 
public RActionImpl<MaxHelper<ResultType>> {
 
 1064   std::shared_ptr<ResultType> fResultMax;
 
 1065   Results<ResultType> fMaxs;
 
 1068   MaxHelper(MaxHelper &&) = 
default;
 
 1069   MaxHelper(
const MaxHelper &) = 
delete;
 
 1070   MaxHelper(
const std::shared_ptr<ResultType> &maxVPtr, 
const unsigned int nSlots)
 
 1071      : fResultMax(maxVPtr), fMaxs(nSlots, std::numeric_limits<ResultType>::lowest())
 
 1076   void Exec(
unsigned int slot, ResultType 
v) { fMaxs[slot] = std::max(
v, fMaxs[slot]); }
 
 1078   template <typename T, std::enable_if_t<IsDataContainer<T>::value, 
int> = 0>
 
 1079   void Exec(
unsigned int slot, 
const T &vs)
 
 1082         fMaxs[slot] = std::max(static_cast<ResultType>(
v), fMaxs[slot]);
 
 1089      *fResultMax = std::numeric_limits<ResultType>::lowest();
 
 1090      for (
auto &
m : fMaxs) {
 
 1091         *fResultMax = std::max(
m, *fResultMax);
 
 1098      return std::make_unique<RMergeableMax<ResultType>>(*fResultMax);
 
 1101   ResultType &PartialUpdate(
unsigned int slot) { 
return fMaxs[slot]; }
 
 1103   std::string GetActionName() { 
return "Max"; }
 
 1105   MaxHelper MakeNew(
void *newResult)
 
 1107      auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
 
 1108      return MaxHelper(
result, fMaxs.size());
 
 1119template <
typename ResultType>
 
 1120class R__CLING_PTRCHECK(off) SumHelper : 
public RActionImpl<SumHelper<ResultType>> {
 
 1121   std::shared_ptr<ResultType> fResultSum;
 
 1122   Results<ResultType> fSums;
 
 1123   Results<ResultType> fCompensations;
 
 1128   template <
typename T = ResultType>
 
 1129   auto NeutralElement(
const T &
v, 
int ) -> 
decltype(
v - 
v)
 
 1134   template <
typename T = ResultType, 
typename Dummy = 
int>
 
 1135   ResultType NeutralElement(
const T &, Dummy) 
 
 1137      return ResultType{};
 
 1141   SumHelper(SumHelper &&) = 
default;
 
 1142   SumHelper(
const SumHelper &) = 
delete;
 
 1143   SumHelper(
const std::shared_ptr<ResultType> &sumVPtr, 
const unsigned int nSlots)
 
 1144      : fResultSum(sumVPtr), fSums(nSlots, NeutralElement(*sumVPtr, -1)),
 
 1145        fCompensations(nSlots, NeutralElement(*sumVPtr, -1))
 
 1150   void Exec(
unsigned int slot, ResultType 
x)
 
 1153      ResultType 
y = 
x - fCompensations[slot];
 
 1154      ResultType t = fSums[slot] + 
y;
 
 1155      fCompensations[slot] = (t - fSums[slot]) - 
y;
 
 1159   template <typename T, std::enable_if_t<IsDataContainer<T>::value, 
int> = 0>
 
 1160   void Exec(
unsigned int slot, 
const T &vs)
 
 1162      for (
auto &&
v : vs) {
 
 1171      ResultType 
sum(NeutralElement(ResultType{}, -1));
 
 1172      ResultType compensation(NeutralElement(ResultType{}, -1));
 
 1173      ResultType 
y(NeutralElement(ResultType{}, -1));
 
 1174      ResultType t(NeutralElement(ResultType{}, -1));
 
 1175      for (
auto &
m : fSums) {
 
 1177         y = 
m - compensation;
 
 1179         compensation = (t - 
sum) - 
y;
 
 1188      return std::make_unique<RMergeableSum<ResultType>>(*fResultSum);
 
 1191   ResultType &PartialUpdate(
unsigned int slot) { 
return fSums[slot]; }
 
 1193   std::string GetActionName() { 
return "Sum"; }
 
 1195   SumHelper MakeNew(
void *newResult)
 
 1197      auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
 
 1199      return SumHelper(
result, fSums.size());
 
 1203class R__CLING_PTRCHECK(off) MeanHelper : 
public RActionImpl<MeanHelper> {
 
 1204   std::shared_ptr<double> fResultMean;
 
 1205   std::vector<ULong64_t> fCounts;
 
 1206   std::vector<double> fSums;
 
 1207   std::vector<double> fPartialMeans;
 
 1208   std::vector<double> fCompensations;
 
 1211   MeanHelper(
const std::shared_ptr<double> &meanVPtr, 
const unsigned int nSlots);
 
 1212   MeanHelper(MeanHelper &&) = 
default;
 
 1213   MeanHelper(
const MeanHelper &) = 
delete;
 
 1215   void Exec(
unsigned int slot, 
double v);
 
 1217   template <typename T, std::enable_if_t<IsDataContainer<T>::value, 
int> = 0>
 
 1218   void Exec(
unsigned int slot, 
const T &vs)
 
 1220      for (
auto &&
v : vs) {
 
 1224         double y = 
v - fCompensations[slot];
 
 1225         double t = fSums[slot] + 
y;
 
 1226         fCompensations[slot] = (t - fSums[slot]) - 
y;
 
 1238      const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
 
 1239      return std::make_unique<RMergeableMean>(*fResultMean, counts);
 
 1242   double &PartialUpdate(
unsigned int slot);
 
 1244   std::string GetActionName() { 
return "Mean"; }
 
 1246   MeanHelper MakeNew(
void *newResult)
 
 1248      auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
 
 1249      return MeanHelper(
result, fSums.size());
 
 1253extern template void MeanHelper::Exec(
unsigned int, 
const std::vector<float> &);
 
 1254extern template void MeanHelper::Exec(
unsigned int, 
const std::vector<double> &);
 
 1255extern template void MeanHelper::Exec(
unsigned int, 
const std::vector<char> &);
 
 1256extern template void MeanHelper::Exec(
unsigned int, 
const std::vector<int> &);
 
 1257extern template void MeanHelper::Exec(
unsigned int, 
const std::vector<unsigned int> &);
 
 1261   unsigned int fNSlots;
 
 1262   std::shared_ptr<double> fResultStdDev;
 
 1264   std::vector<ULong64_t> fCounts;
 
 1266   std::vector<double> fMeans;
 
 1268   std::vector<double> fDistancesfromMean;
 
 1271   StdDevHelper(
const std::shared_ptr<double> &meanVPtr, 
const unsigned int nSlots);
 
 1272   StdDevHelper(StdDevHelper &&) = 
default;
 
 1273   StdDevHelper(
const StdDevHelper &) = 
delete;
 
 1275   void Exec(
unsigned int slot, 
double v);
 
 1277   template <typename T, std::enable_if_t<IsDataContainer<T>::value, 
int> = 0>
 
 1278   void Exec(
unsigned int slot, 
const T &vs)
 
 1280      for (
auto &&
v : vs) {
 
 1292      const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
 
 1294         std::inner_product(fMeans.begin(), fMeans.end(), fCounts.begin(), 0.) / 
static_cast<Double_t>(counts);
 
 1295      return std::make_unique<RMergeableStdDev>(*fResultStdDev, counts, mean);
 
 1298   std::string GetActionName() { 
return "StdDev"; }
 
 1300   StdDevHelper MakeNew(
void *newResult)
 
 1302      auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
 
 1303      return StdDevHelper(
result, fCounts.size());
 
 1307extern template void StdDevHelper::Exec(
unsigned int, 
const std::vector<float> &);
 
 1308extern template void StdDevHelper::Exec(
unsigned int, 
const std::vector<double> &);
 
 1309extern template void StdDevHelper::Exec(
unsigned int, 
const std::vector<char> &);
 
 1310extern template void StdDevHelper::Exec(
unsigned int, 
const std::vector<int> &);
 
 1311extern template void StdDevHelper::Exec(
unsigned int, 
const std::vector<unsigned int> &);
 
 1313template <
typename PrevNodeType>
 
 1317   std::shared_ptr<Display_t> fDisplayerHelper;
 
 1318   std::shared_ptr<PrevNodeType> fPrevNode;
 
 1319   size_t fEntriesToProcess;
 
 1322   DisplayHelper(
size_t nRows, 
const std::shared_ptr<Display_t> &
d, 
const std::shared_ptr<PrevNodeType> &prevNode)
 
 1323      : fDisplayerHelper(
d), fPrevNode(prevNode), fEntriesToProcess(nRows)
 
 1326   DisplayHelper(DisplayHelper &&) = 
default;
 
 1327   DisplayHelper(
const DisplayHelper &) = 
delete;
 
 1330   template <
typename... 
Columns>
 
 1331   void Exec(
unsigned int, Columns &... columns)
 
 1333      if (fEntriesToProcess == 0)
 
 1336      fDisplayerHelper->AddRow(columns...);
 
 1337      --fEntriesToProcess;
 
 1339      if (fEntriesToProcess == 0) {
 
 1344         fPrevNode->StopProcessing();
 
 1352   std::string GetActionName() { 
return "Display"; }
 
 1355template <
typename T>
 
 1361template <
typename T>
 
 1367template <
typename T>
 
 1368void SetBranchesHelper(
TTree *inputTree, 
TTree &outputTree, 
const std::string &inName, 
const std::string &
name,
 
 1369                       TBranch *&branch, 
void *&branchAddress, T *address, RBranchSet &outputBranches,
 
 1372   static TClassRef TBOClRef(
"TBranchObject");
 
 1374   TBranch *inputBranch = 
nullptr;
 
 1376      inputBranch = inputTree->
GetBranch(inName.c_str());
 
 1378         inputBranch = inputTree->
FindBranch(inName.c_str());
 
 1381   auto *outputBranch = outputBranches.Get(
name);
 
 1384      if (inputBranch && inputBranch->
IsA() == TBOClRef) {
 
 1385         outputBranch->SetAddress(
reinterpret_cast<T **
>(inputBranch->
GetAddress()));
 
 1387         branchAddress = address;
 
 1388         outputBranch->SetAddress(&branchAddress);
 
 1390         outputBranch->SetAddress(address);
 
 1391         branchAddress = address;
 
 1404      if (inputBranch->
IsA() == TBOClRef) {
 
 1407            outputTree.
Branch(
name.c_str(), 
reinterpret_cast<T **
>(inputBranch->
GetAddress()), bufSize, splitLevel);
 
 1409         outputBranch = outputTree.
Branch(
name.c_str(), address, bufSize, splitLevel);
 
 1412      outputBranch = outputTree.
Branch(
name.c_str(), address);
 
 1414   outputBranches.Insert(
name, outputBranch);
 
 1417   branchAddress = 
nullptr;
 
 1430template <
typename T>
 
 1431void SetBranchesHelper(
TTree *inputTree, 
TTree &outputTree, 
const std::string &inName, 
const std::string &outName,
 
 1432                       TBranch *&branch, 
void *&branchAddress, 
RVec<T> *ab, RBranchSet &outputBranches, 
bool isDefine)
 
 1434   TBranch *inputBranch = 
nullptr;
 
 1436      inputBranch = inputTree->
GetBranch(inName.c_str());
 
 1438         inputBranch = inputTree->
FindBranch(inName.c_str());
 
 1440   auto *outputBranch = outputBranches.Get(outName);
 
 1443   bool mustWriteRVec = (inputBranch == 
nullptr || isDefine);
 
 1445   if (!mustWriteRVec && std::string_view(inputBranch->
GetClassName()) == 
"TClonesArray") {
 
 1446      mustWriteRVec = 
true;
 
 1448              "Branch \"%s\" contains TClonesArrays but the type specified to Snapshot was RVec<T>. The branch will " 
 1449              "be written out as a RVec instead of a TClonesArray. Specify that the type of the branch is " 
 1450              "TClonesArray as a Snapshot template parameter to write out a TClonesArray instead.",
 
 1454   if (!mustWriteRVec) {
 
 1457         mustWriteRVec = 
true;
 
 1460   if (mustWriteRVec) {
 
 1467         outputBranch->SetObject(ab);
 
 1469         auto *
b = outputTree.
Branch(outName.c_str(), ab);
 
 1470         outputBranches.Insert(outName, 
b);
 
 1476   auto dataPtr = ab->
data();
 
 1480         branchAddress = dataPtr;
 
 1481         outputBranch->SetAddress(&branchAddress);
 
 1483         outputBranch->SetAddress(dataPtr);
 
 1488      const auto bname = leaf->
GetName();
 
 1489      auto *sizeLeaf = leaf->GetLeafCount();
 
 1490      const auto sizeLeafName = sizeLeaf ? std::string(sizeLeaf->GetName()) : std::to_string(leaf->GetLenStatic());
 
 1492      if (sizeLeaf && !outputBranches.Get(sizeLeafName)) {
 
 1497         const auto sizeBufSize = sizeLeaf->GetBranch()->GetBasketSize();
 
 1499         auto *sizeBranch = outputTree.
Branch(sizeLeafName.c_str(), (
void *)
nullptr,
 
 1500                                              (sizeLeafName + 
'/' + sizeTypeStr).c_str(), sizeBufSize);
 
 1501         outputBranches.Insert(sizeLeafName, sizeBranch);
 
 1504      const auto btype = leaf->GetTypeName();
 
 1506      if (rootbtype == 
' ') {
 
 1508                 "RDataFrame::Snapshot: could not correctly construct a leaflist for C-style array in column %s. This " 
 1509                 "column will not be written out.",
 
 1512         const auto leaflist = std::string(bname) + 
"[" + sizeLeafName + 
"]/" + rootbtype;
 
 1513         outputBranch = outputTree.
Branch(outName.c_str(), dataPtr, leaflist.c_str());
 
 1515         outputBranches.Insert(outName, outputBranch);
 
 1516         branch = outputBranch;
 
 1517         branchAddress = ab->
data();
 
 1525template <
typename... ColTypes>
 
 1526class R__CLING_PTRCHECK(off) SnapshotHelper : 
public RActionImpl<SnapshotHelper<ColTypes...>> {
 
 1527   std::string fFileName;
 
 1528   std::string fDirName;
 
 1529   std::string fTreeName;
 
 1531   std::unique_ptr<TFile> fOutputFile;
 
 1532   std::unique_ptr<TTree> fOutputTree; 
 
 1533   bool fBranchAddressesNeedReset{
true};
 
 1536   TTree *fInputTree = 
nullptr; 
 
 1538   std::vector<TBranch *> fBranches; 
 
 1539   std::vector<void *> fBranchAddresses; 
 
 1540   RBranchSet fOutputBranches;
 
 1541   std::vector<bool> fIsDefine;
 
 1544   using ColumnTypes_t = 
TypeList<ColTypes...>;
 
 1545   SnapshotHelper(std::string_view 
filename, std::string_view dirname, std::string_view treename,
 
 1547                  std::vector<bool> &&isDefine)
 
 1548      : fFileName(
filename), fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
 
 1550        fBranchAddresses(vbnames.
size(), nullptr), fIsDefine(std::move(isDefine))
 
 1555   SnapshotHelper(
const SnapshotHelper &) = 
delete;
 
 1556   SnapshotHelper(SnapshotHelper &&) = 
default;
 
 1559      if (!fTreeName.empty()  && !fOutputFile  && fOptions.
fLazy)
 
 1560         Warning(
"Snapshot", 
"A lazy Snapshot action was booked but never triggered.");
 
 1566         fInputTree = 
r->GetTree();
 
 1567      fBranchAddressesNeedReset = 
true;
 
 1570   void Exec(
unsigned int , ColTypes &... values)
 
 1572      using ind_t = std::index_sequence_for<ColTypes...>;
 
 1573      if (!fBranchAddressesNeedReset) {
 
 1574         UpdateCArraysPtrs(values..., ind_t{});
 
 1576         SetBranches(values..., ind_t{});
 
 1577         fBranchAddressesNeedReset = 
false;
 
 1579      fOutputTree->Fill();
 
 1582   template <std::size_t... 
S>
 
 1583   void UpdateCArraysPtrs(ColTypes &... values, std::index_sequence<S...> )
 
 1591      int expander[] = {(fBranches[
S] && fBranchAddresses[
S] != GetData(values)
 
 1592                         ? fBranches[
S]->SetAddress(GetData(values)),
 
 1593                         fBranchAddresses[
S] = GetData(values), 0 : 0, 0)...,
 
 1598   template <std::size_t... 
S>
 
 1599   void SetBranches(ColTypes &... values, std::index_sequence<S...> )
 
 1602      int expander[] = {(SetBranchesHelper(fInputTree, *fOutputTree, fInputBranchNames[S], fOutputBranchNames[S],
 
 1603                                           fBranches[S], fBranchAddresses[S], &values, fOutputBranches, fIsDefine[S]),
 
 1606      fOutputBranches.AssertNoNullBranchAddresses();
 
 1616         throw std::runtime_error(
"Snapshot: could not create output file " + fFileName);
 
 1619      if (!fDirName.empty()) {
 
 1622         if (checkupdate == 
"update")
 
 1623            outputDir = fOutputFile->
mkdir(fDirName.c_str(), 
"", 
true);  
 
 1625            outputDir = fOutputFile->
mkdir(fDirName.c_str());
 
 1629         std::make_unique<TTree>(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, outputDir);
 
 1632         fOutputTree->SetAutoFlush(fOptions.
fAutoFlush);
 
 1637      assert(fOutputTree != 
nullptr);
 
 1638      assert(fOutputFile != 
nullptr);
 
 1641      fOutputTree->AutoSave(
"flushbaskets");
 
 1643      fOutputTree.reset();
 
 1644      fOutputFile->Close();
 
 1647   std::string GetActionName() { 
return "Snapshot"; }
 
 1651      return [
this](
unsigned int, 
const RSampleInfo &) 
mutable { fBranchAddressesNeedReset = 
true; };
 
 1656template <
typename... ColTypes>
 
 1657class R__CLING_PTRCHECK(off) SnapshotHelperMT : 
public RActionImpl<SnapshotHelperMT<ColTypes...>> {
 
 1658   unsigned int fNSlots;
 
 1659   std::unique_ptr<ROOT::TBufferMerger> fMerger; 
 
 1660   std::vector<std::shared_ptr<ROOT::TBufferMergerFile>> fOutputFiles;
 
 1661   std::vector<std::unique_ptr<TTree>> fOutputTrees;
 
 1662   std::vector<int> fBranchAddressesNeedReset; 
 
 1663   std::string fFileName;           
 
 1664   std::string fDirName;            
 
 1665   std::string fTreeName;           
 
 1669   std::vector<TTree *> fInputTrees; 
 
 1671   std::vector<std::vector<TBranch *>> fBranches;
 
 1673   std::vector<std::vector<void *>> fBranchAddresses;
 
 1674   std::vector<RBranchSet> fOutputBranches;
 
 1675   std::vector<bool> fIsDefine;
 
 1678   using ColumnTypes_t = 
TypeList<ColTypes...>;
 
 1679   SnapshotHelperMT(
const unsigned int nSlots, std::string_view 
filename, std::string_view dirname,
 
 1682      : fNSlots(nSlots), fOutputFiles(fNSlots), fOutputTrees(fNSlots), fBranchAddressesNeedReset(fNSlots, 1),
 
 1683        fFileName(
filename), fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
 
 1685        fBranches(fNSlots, std::vector<
TBranch *>(vbnames.
size(), nullptr)),
 
 1686        fBranchAddresses(fNSlots, std::vector<
void *>(vbnames.
size(), nullptr)), fOutputBranches(fNSlots),
 
 1687        fIsDefine(std::move(isDefine))
 
 1691   SnapshotHelperMT(
const SnapshotHelperMT &) = 
delete;
 
 1692   SnapshotHelperMT(SnapshotHelperMT &&) = 
default;
 
 1695      if (!fTreeName.empty()  && fOptions.
fLazy &&
 
 1696          std::all_of(fOutputFiles.begin(), fOutputFiles.end(), [](
const auto &
f) { return !f; }) )
 
 1697         Warning(
"Snapshot", 
"A lazy Snapshot action was booked but never triggered.");
 
 1703      if (!fOutputFiles[slot]) {
 
 1705         fOutputFiles[slot] = fMerger->GetFile();
 
 1707      TDirectory *treeDirectory = fOutputFiles[slot].get();
 
 1708      if (!fDirName.empty()) {
 
 1710         treeDirectory = fOutputFiles[slot]->
mkdir(fDirName.c_str(), 
"", 
true);
 
 1714      fOutputTrees[slot] =
 
 1715         std::make_unique<TTree>(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, treeDirectory);
 
 1718      fOutputTrees[slot]->SetImplicitMT(
false);
 
 1720         fOutputTrees[slot]->SetAutoFlush(fOptions.
fAutoFlush);
 
 1723         fInputTrees[slot] = 
r->GetTree();
 
 1725      fBranchAddressesNeedReset[slot] = 1; 
 
 1728   void FinalizeTask(
unsigned int slot)
 
 1730      if (fOutputTrees[slot]->GetEntries() > 0)
 
 1731         fOutputFiles[slot]->Write();
 
 1733      fOutputTrees[slot].reset(
nullptr);
 
 1734      fOutputBranches[slot].Clear();
 
 1737   void Exec(
unsigned int slot, ColTypes &... values)
 
 1739      using ind_t = std::index_sequence_for<ColTypes...>;
 
 1740      if (fBranchAddressesNeedReset[slot] == 0) {
 
 1741         UpdateCArraysPtrs(slot, values..., ind_t{});
 
 1743         SetBranches(slot, values..., ind_t{});
 
 1744         fBranchAddressesNeedReset[slot] = 0;
 
 1746      fOutputTrees[slot]->Fill();
 
 1747      auto entries = fOutputTrees[slot]->GetEntries();
 
 1748      auto autoFlush = fOutputTrees[slot]->GetAutoFlush();
 
 1749      if ((autoFlush > 0) && (entries % autoFlush == 0))
 
 1750         fOutputFiles[slot]->Write();
 
 1753   template <std::size_t... 
S>
 
 1754   void UpdateCArraysPtrs(
unsigned int slot, ColTypes &... values, std::index_sequence<S...> )
 
 1762      int expander[] = {(fBranches[slot][
S] && fBranchAddresses[slot][
S] != GetData(values)
 
 1763                         ? fBranches[slot][
S]->SetAddress(GetData(values)),
 
 1764                         fBranchAddresses[slot][
S] = GetData(values), 0 : 0, 0)...,
 
 1769   template <std::size_t... 
S>
 
 1770   void SetBranches(
unsigned int slot, ColTypes &... values, std::index_sequence<S...> )
 
 1773      int expander[] = {(SetBranchesHelper(fInputTrees[slot], *fOutputTrees[slot], fInputBranchNames[S],
 
 1774                                           fOutputBranchNames[S], fBranches[slot][S], fBranchAddresses[slot][S],
 
 1775                                           &values, fOutputBranches[slot], fIsDefine[S]),
 
 1778      fOutputBranches[slot].AssertNoNullBranchAddresses();
 
 1785      auto out_file = 
TFile::Open(fFileName.c_str(), fOptions.
fMode.c_str(), fFileName.c_str(), cs);
 
 1787         throw std::runtime_error(
"Snapshot: could not create output file " + fFileName);
 
 1788      fMerger = std::make_unique<ROOT::TBufferMerger>(std::unique_ptr<TFile>(out_file));
 
 1793      assert(std::any_of(fOutputFiles.begin(), fOutputFiles.end(), [](
const auto &ptr) { return ptr != nullptr; }));
 
 1795      auto fileWritten = 
false;
 
 1796      for (
auto &
file : fOutputFiles) {
 
 1806                 "No input entries (input TTree was empty or no entry passed the Filters). Output TTree is empty.");
 
 1810      fOutputFiles.clear();
 
 1814   std::string GetActionName() { 
return "Snapshot"; }
 
 1818      return [
this](
unsigned int slot, 
const RSampleInfo &) 
mutable { fBranchAddressesNeedReset[slot] = 1; };
 
 1822template <
typename Acc, 
typename Merge, 
typename R, 
typename T, 
typename U,
 
 1823          bool MustCopyAssign = std::is_same<R, U>::value>
 
 1824class R__CLING_PTRCHECK(off) AggregateHelper
 
 1825   : 
public RActionImpl<AggregateHelper<Acc, Merge, R, T, U, MustCopyAssign>> {
 
 1828   std::shared_ptr<U> fResult;
 
 1829   Results<U> fAggregators;
 
 1834   AggregateHelper(Acc &&
f, Merge &&
m, 
const std::shared_ptr<U> &
result, 
const unsigned int nSlots)
 
 1835      : fAggregate(std::move(
f)), fMerge(std::move(
m)), fResult(
result), fAggregators(nSlots, *
result)
 
 1839   AggregateHelper(Acc &
f, Merge &
m, 
const std::shared_ptr<U> &
result, 
const unsigned int nSlots)
 
 1840      : fAggregate(
f), fMerge(
m), fResult(
result), fAggregators(nSlots, *
result)
 
 1844   AggregateHelper(AggregateHelper &&) = 
default;
 
 1845   AggregateHelper(
const AggregateHelper &) = 
delete;
 
 1849   template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<MustCopyAssign_, 
int> = 0>
 
 1850   void Exec(
unsigned int slot, 
const T &
value)
 
 1852      fAggregators[slot] = fAggregate(fAggregators[slot], 
value);
 
 1855   template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<!MustCopyAssign_, 
int> = 0>
 
 1856   void Exec(
unsigned int slot, 
const T &
value)
 
 1858      fAggregate(fAggregators[slot], 
value);
 
 1863   template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
 
 1864             bool MergeAll = std::is_same<void, MergeRet>::value>
 
 1865   std::enable_if_t<MergeAll, void> Finalize()
 
 1867      fMerge(fAggregators);
 
 1868      *fResult = fAggregators[0];
 
 1871   template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
 
 1872             bool MergeTwoByTwo = std::is_same<U, MergeRet>::value>
 
 1873   std::enable_if_t<MergeTwoByTwo, void> Finalize(...) 
 
 1875      for (
const auto &acc : fAggregators)
 
 1876         *fResult = fMerge(*fResult, acc);
 
 1879   U &PartialUpdate(
unsigned int slot) { 
return fAggregators[slot]; }
 
 1881   std::string GetActionName() { 
return "Aggregate"; }
 
 1883   AggregateHelper MakeNew(
void *newResult)
 
 1885      auto &
result = *
static_cast<std::shared_ptr<U> *
>(newResult);
 
 1886      return AggregateHelper(fAggregate, fMerge, 
result, fAggregators.size());
 
Handle_t Display_t
Display handle.
 
#define R(a, b, c, d, e, f, g, h, i)
 
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
 
unsigned long long ULong64_t
 
#define R__CLING_PTRCHECK(ONOFF)
 
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
 
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
 
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 r
 
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 result
 
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
 
Option_t Option_t TPoint TPoint const char x1
 
TClass * IsA() const override
 
TTime operator*(const TTime &t1, const TTime &t2)
 
Base class for action helpers, see RInterface::Book() for more information.
 
iterator begin() noexcept
 
pointer data() noexcept
Return a pointer to the vector's buffer, even if empty().
 
This class is the textual representation of the content of a columnar dataset.
 
This type represents a sample identifier, to be used in conjunction with RDataFrame features such as ...
 
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
 
A "std::vector"-like collection of values implementing handy operation to analyse them.
 
A TTree is a list of TBranches.
 
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any.
 
virtual char * GetAddress() const
 
Int_t GetSplitLevel() const
 
TClass * IsA() const override
 
virtual Int_t GetBasketSize() const
 
TObjArray * GetListOfLeaves()
 
TClassRef is used to implement a permanent reference to a TClass object.
 
Collection abstract base class.
 
TDirectory::TContext keeps track and restore the current directory.
 
Describe directory structure in memory.
 
virtual TDirectory * mkdir(const char *name, const char *title="", Bool_t returnExistingDirectory=kFALSE)
Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
 
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
 
TGraph with asymmetric error bars.
 
A TGraph is an object made of two arrays X and Y with npoints each.
 
1-D histogram with a double per channel (see TH1 documentation)}
 
TH1 is the base class of all histogram classes in ROOT.
 
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
 
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
 
const char * GetName() const override
Returns name of object.
 
const char * GetTitle() const override
Returns title of object.
 
TObject * UncheckedAt(Int_t i) const
 
Statistical variable, defined by its mean and variance (RMS).
 
void ToLower()
Change string to lower-case.
 
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
 
A TTree represents a columnar dataset.
 
virtual TBranch * FindBranch(const char *name)
Return the branch that correspond to the path 'branchname', which can include the name of the tree or...
 
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
 
TBranch * Branch(const char *name, T *obj, Int_t bufsize=32000, Int_t splitlevel=99)
Add a new branch, and infer the data type from the type of obj being passed.
 
@ kEntriesReshuffled
If set, signals that this TTree is the output of the processing of another TTree, and the entries are...
 
RooCmdArg Columns(Int_t ncol)
 
CPYCPPYY_EXTERN bool Exec(const std::string &cmd)
 
std::unique_ptr< RMergeableVariations< T > > GetMergeableValue(ROOT::RDF::Experimental::RResultMap< T > &rmap)
Retrieve mergeable values after calling ROOT::RDF::VariationsFor .
 
std::vector< std::string > ReplaceDotWithUnderscore(const std::vector< std::string > &columnNames)
Replace occurrences of '.
 
void ValidateSnapshotOutput(const RSnapshotOptions &opts, const std::string &treeName, const std::string &fileName)
 
char TypeName2ROOTTypeName(const std::string &b)
Convert type name (e.g.
 
constexpr std::size_t FindIdxTrue(const T &arr)
 
void(off) SmallVectorTemplateBase< T
 
std::vector< std::string > ColumnNames_t
 
std::function< void(unsigned int, const ROOT::RDF::RSampleInfo &)> SampleCallback_t
The type of a data-block callback, registered with a RDataFrame computation graph via e....
 
ROOT type_traits extensions.
 
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
 
int CompressionSettings(RCompressionSetting::EAlgorithm::EValues algorithm, int compressionLevel)
 
RooArgSet S(Args_t &&... args)
 
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
 
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
 
void Initialize(Bool_t useTMVAStyle=kTRUE)
 
A collection of options to steer the creation of the dataset on file.
 
int fAutoFlush
AutoFlush value for output tree.
 
std::string fMode
Mode of creation of output file.
 
ECAlgo fCompressionAlgorithm
Compression algorithm of output file.
 
int fSplitLevel
Split level of output tree.
 
bool fLazy
Do not start the event loop when Snapshot is called.
 
int fCompressionLevel
Compression level of output file.
 
Lightweight storage for a collection of types.
 
static uint64_t sum(uint64_t i)