Some questions when using vector<Struct> as branches with RDataFrame

Dear experts,
How can I use a lambda expression for different Define. For example, I need define a lot of column

  auto dr1 = dr.Define("FD0_adcv", cut_valueFD0, {"FD0_adcvr", "FD0_stripidr"})
            .Define("FD1_adcv", cut_valueFD1, {"FD1_adcvr", "FD1_stripidr"})
            .Define("BD0_adcv", cut_valueBD0, {"BD0_adcvr", "BD0_stripidr"})
            .Define("BD1_adcv", cut_valueBD1, {"BD1_adcvr", "BD1_stripidr"})
....

The only different value in the lambda expression is sname.

  auto cut_valueFD0 = [&m_cut](ints& vadcv, shorts& stripid){
    ints c_vadcv;
    TString sname = "FD0";
    for (size_t i = 0; i < vadcv.size(); i++)
    {
      if (vadcv[i]<4095&&vadcv[i]>m_cut.find(sname)->second.find(stripid[i])->second)
      {
        c_vadcv.emplace_back(vadcv[i]);
      }    
    }
    return c_vadcv;
  };

How can I simplify this process.

_ROOT Version: 6.26/00
Platform: Not Provided
Compiler: Not Provided


Hi @qyj ,

one possible way is a “function factory” (I haven’t tested the code but it should give you the idea):

auto make_cut(const std::string &sname) {
   auto &c = m_cut.find(sname)->second;
   return [&c](ints &vadcv, shorts& stripid) {
      ints c_vadcv;
      for (size_t i = 0; i < vadcv.size(); i++) {
         if (vadcv[i]<4095 && vadcv[i] > c.find(stripid[i])->second)
            c_vadcv.emplace_back(vadcv[i]);
      }
      return c_vadcv;
   };
}
...
ROOT::RDF::RNode df = dataframe;
for (const auto &str : {"FD0", "FD1", "BD0", "BD1"})
   df = df.Define(str + "_adcv", make_cut(str), {str + "_adcvr", str + "_stripidr"})

Another possible idea is to write a small class that takes sname as parameter in its constructor and then in its call operator, operator(), applies the appropriate cut. You can then do e.g. df.Define("FD1_adcv", MyCutEvaluator("FD1"), {"FD0_adcvr", "FD0_stripidr"}).

I hope this helps!
Enrico

Thank you!
The first method with another lambda is OK.

  auto make_val_cut = [&m_cut](const std::string &sname) {
    auto &c = m_cut.find(sname)->second;
    return [&c](ints &vadcv, shorts& stripid) {
        ints c_vadcv;
        for (size_t i = 0; i < vadcv.size(); i++) {
          if (vadcv[i]<4095 && vadcv[i] > c.find(stripid[i])->second)
              c_vadcv.emplace_back(vadcv[i]);
        }
        return c_vadcv;
    };
  };

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