Expression-argument to wrapper function for RDataFrame::Define()

Hi rooters!

Could anybody please help me with one problem:
I’m using RDataFrame in my analysis and I would like to save few histograms to the root file, I know that I can do it straightforward like:

auto rd = new ROOT::RDataFrame("tree", "....root");
auto f = new TFile("...", "recreate");
f->cd();
auto hist1= rd->Define(col1Name, Pt1, {...}).Filter(...).Histo1D(*histModel, col1Name).GetPtr();
auto hist2= rd->Define(col2Name, Pt2, {...}).Filter(...).Histo1D(*histModel, col2Name).GetPtr();
f->Wirte();
f->Close();

but, I have several function Pt1, Pt2, … which are very similar. Let say it has a difference only in one condition, so I want to use some wrapper for my expressions(Pt1, Pt2). Something like this:

TH1D* GetHist(TString col1Name, TString col1Title, TString filter, Int_t bins, Double_t xLow, Double_t xUp, Int_t Limit) 
{
auto rd = new ROOT::RDataFrame("tree", "....root");
auto Pt = WrapPt(Limit);

return rd->Define(col1Name.Data(), Pt, {...}).Filter(...).Histo1D(*histModel, col1Name.Data()).GetPtr();
}

auto WrapPt(Int_t param)
{
  return [&] (...) 
  {
    int something;
    // ... some calculations
    if (something > param) return -1.;
    return ev;
  };
}

In this case all what I need just:

auto f = new TFile("...", "recreate");
f->cd();
auto hist1 = GetHist(col1Name, col1Title, filter, bins, xLow, xUp, Limit1); 
auto hist2 = GetHist(col2Name, col2Title, filter, bins, xLow, xUp, Limit2); 
f->Wirte();
f->Close();

and I have only one piece of code for my Pt.
So the problem is that syntax parser allows it, but compiler doesn’t:

error: 'auto' return without trailing return type; deduced return types are a C++14 extension
auto WrapPt(Int_t netChargeLimit)
error: no viable conversion from returned value of type to function return type 'int'
  return [&] (...

To be short: how can I create an interface like RDataFrame has it for Define:

name, expression, ...

Perhaps root reinstallation with std=c++14 flag solves this?

Boris


ROOT Version: 6.17/01
Platform: linux
Compiler: gcc 7.3.0


Hi,
as you suggest, reinstalling ROOT with std=c++14 should solve this.
Alternatively, a c++11 workaround is:

TH1D* GetHist(TString col1Name, TString col1Title, TString filter, Int_t bins, Double_t xLow, Double_t xUp, Int_t Limit) 
{
auto rd = new ROOT::RDataFrame("tree", "....root");
auto Pt = [&] (...) {
    int something;
    // ... some calculations
    if (something > Limit) return -1.;
    return ev;
  };

return rd->Define(col1Name.Data(), Pt, {...}).Filter(...).Histo1D(*histModel, col1Name.Data()).GetPtr();
}

Note however that GetPtr forces RDataFrame to run the event loop (to give you a pointer to a valid TH1D). I would suggest that you return what Histo1D returns, i.e. RResultPtr<TH1D>, which lazily triggers the event loop when you try to access the contents.

Cheers,
Enrico

Hi @eguiraud ,
thanks for response.
I’ll try to reinstall root. Your solution is nice, but if I want to change TH1D to TGraph and keep expression (Pt), I should create new function for TGraph and duplicate Pt code there or if I want to get two histogram with different expressions it also will have the same piece of code. That’s why I want to use expression as argument. Yes, I know about running expression after GetPtr(), thanks!

Cheers,
Boris

If you use conda, you can get a c++17 installation of ROOT just with conda install -c conda-forge root – the only caveat is that you need to use the compiler indicated by root-config --cxx to compile your programs, otherwise you might get ABI mismatches.

Otherwise you can build from source, the only extra argument at cmake configuration is -DCMAKE_CXX_STANDARD=14.

I am quite sure there are C++14/17 builds of ROOT on cvmfs too.

1 Like

Yeah, thanks. I’m already ran building with -DCMAKE_CXX_STANDARD=14.

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