Support for filling histograms with alphanumeric bins in RDataFrame

Hi @will_cern ,
the tricky part here is that TH1’s Fill overload for alphanumeric labels accepts a const char *, but RDataFrame does not handle columns of pointer type very well – in RDF you would rather manipulate std::strings or RVec<char>.

So you need a small adapter class to make things work, but with that you can use RDF’s generic Fill method and it should happily fill bins with alphanumeric labels:

#include <ROOT/RDataFrame.hxx>
#include <TApplication.h>
#include <TH1D.h>

struct AlphaNumHist {
  TH1D h;

  AlphaNumHist() : h("h", "h", 3, 0, 3) {
    auto *xaxis = h.GetXaxis();
    xaxis->SetAlphanumeric(true);
    xaxis->SetBinLabel(1, "0");
    xaxis->SetBinLabel(2, "1");
    xaxis->SetBinLabel(3, "2");
  }
  AlphaNumHist(const AlphaNumHist &) = default;
  AlphaNumHist(AlphaNumHist &&) = default;

  void Fill(const std::string &s) { h.Fill(s.c_str(), 1.); }

  void Merge(const std::vector<AlphaNumHist *> &others) {
     TList l;
     for (auto *o : others)
        l.Add(&o->h);
      h.Merge(&l);
  }
};

int main() {
  TApplication app("app", nullptr, nullptr);
  auto df = ROOT::RDataFrame(3)
                .Define("s", [](ULong64_t e) { return std::to_string(e); },
                        {"rdfentry_"})
                .Define("w", [] { return 1; });

  AlphaNumHist h;
  auto r = df.Fill<std::string>(h, {"s"});
  r->h.Draw();
  app.Run();
}

I hope this helps!
Enrico

1 Like