Support for filling histograms with alphanumeric bins in RDataFrame

Hi,

I was wondering if its possible to fill histograms with alphanumeric bin labels using RDataFrame. It doesn’t look like the TH1DModel will support this type of histogram, but if its not too hard to add it, it would certainly be a useful feature to support, filling from a column with string type.

Thanks
Will

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

Thanks. Why does the dataframe’s Fill method take std::string as its template argument? Looking at the docs I’d have thought it would be an AlphaNumHist type (or non at all and so autoinferred).

Like with Histo1D, the template parameter should be the type of the input column, i.e. the type of "s".
The type of the helper is inferred from the argument.

If you leave out all template parameters, RDataFrame will just-in-time compile that action at runtime, but with just the code above you will get an error because ROOT’s interpreter does not know how to generate code that involves AlphaNumHist (you would at least need to gInterpreter->Declare("#include \"AlphaNumHist.h\"") so the interpreter knows the type).

Feel free to ask further questions.
Cheers,
Enrico

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.