Hello,
I am trying to sequentially optimize some cuts on my data , using RDataFrame and ROOT::Math::Minimizer.
I want to apply a cut (filter) depending on two parameters to one column of the dataframe, and use the minimizer to find the best cut parameters, determined by a value, which I calculate from the dataframe. This process I want to apply sequentially on multiple columns, while each time the dataframe keeps the previous filters.
My first unsuccessful approach was to write a function
double calculateFOM(double cutpar1, double cutpar2, ROOT::RDF::RInterface<ROOT::Detail::RDF::RJittedFilter, void> filteredDF, string columnName)
{
... // apply a filter and calculate a figure of merit (double FOM)
return FOM;
}
and then to fix the dataframe and column name in my macro by defining a lambda expression, which has only the cut parameters as input:
auto calculateFOM1 = [&](const double *x){return calculateFOM(x[0], x[1], MyFilteredDF, MyColumnName);};
However, I didn’t manage to pass a lambda expression to the minimizer. I tried it e.g. by doing ROOT::Math::Functor f1(&calculateFOM1,2);
following this example, but this method doesn’t accept lambdas.
Is there a way to minimize a lambda expression?
My second approach is to write a class, that generates a function calculateFOM
, which the minimizer hopefully will accept. This class includes a method SetParameters
, which allows me to pass the filtered dataframe and column name to the function:
class generateFunction
{
private:
string columnName;
ROOT::RDF::RInterface<ROOT::Detail::RDF::RJittedFilter, void> filteredDF;
public:
void SetParameters(ROOT::RDF::RInterface<ROOT::Detail::RDF::RJittedFilter, void> df1, string name)
{
auto filteredDF1= df1;
auto columnName = name;
}
double calculateFOM(double cutpar1, double cutpar2){
filteredDF= filteredDF.Filter(std::to_string(cutpar1) + " < " + columnName + " < " + std::to_string(cutpar2));
... // do some calculation that returns a figure of merit (double FOM) ***
return FOM;
}
};
However this doesn’t compile:
... error: call to implicitly-deleted default constructor of 'generateFunction'
... default constructor of 'generateFunction' is implicitly deleted because field 'filteredDF' has no default constructor
ROOT::RDF::RInterface<ROOT::Detail::RDF::RJittedFilter, void> filteredDF;
I guess the problem is the declaration of the filteredDF. What is the correct way to do this?
Or should I better use a different approach?
Thanks in advance!
Konrad
ROOT Version: 6.24.02
Platform: linuxx8664gcc
Compiler: Not Provided