// RDataFrame add new column with Define does not follow manual? using namespace ROOT; RDataFrame df("T","htree.root"); // Try to plot the size of a vector object in the TTree. // This one completely crashes root! // auto h = df.Histo1D("vec_list.size()") // ==> libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: Unknown column: vec_list.size() // FROM THE MANUAL // Custom columns // //Custom columns are created by invoking Define(name, f, columnList). As usual, f can be any callable object // (function, lambda expression, functor class...); it takes the values of the columns listed in columnList // (a list of strings) as parameters, in the same order as they are listed in columnList. // f must return the value that will be assigned to the temporary column. // Comment: This appears not to be the case!! See below. // We first need to create a new column with the vector size. // Getting the size of a vector<> object, many different ways. // For the vector size, this seems simplest: auto dfplus0 = df.Define("num_list_size","vec_list.size()"); // Lambda function for the size of a vector; !! Templated Lambda's not until c++20 !! auto getsize_l = [](vector &vec){ return vec.size(); }; // Using a Lambda function, the define needs special 3 args form: auto dfplus1 = df.Define("num_list_size",getsize_l,{"num_list"}); // The 2 argument form does not work: // auto dfplus = df.Define("num_list_size","getsize_l(num_list)"); // non-templated standard function. It does not matter if it is inline or not. inline auto getsize_f(vector &vec){ return vec.size(); }; auto dfplus2 = df.Define("num_list_size",getsize_f,{"num_list"}); // Again the 2 argument form does not work: // auto dfplus = df.Define("num_list_size","getsize_f(num_list)"); // Templated (inline) standard function. template inline auto getsize( T& vec){ return vec.size();}; // The 3 argument form now crashes! // auto dfplus = df.Define("num_list_size",getsize,{"num_list"}); // The 2 argument form now works! auto dfplus3 = df.Define("num_list_size","getsize(num_list)"); auto h1 = dfplus0.Histo1D({"num_list_size","Vector Size 1",101u,-0.5,100.5},"num_list_size"); h1->SetLineColor(kRed); // This already triggers the LOOP! h1->Draw(); // Accessing the X() component of the TVector3 in vec_list: auto getX = [](vector &v){RVec out; for( auto p: v) out.push_back(p.X()); return out;}; auto h2=df.Define("X",getX,{"vec_list"}).Histo1D("X") h2->Draw();