ROOT Version: 6.24/02 Platform: Scientific Linux 7.3 (Nitrogen) Compiler: gcc 4.8.5(Red Hat 4.8.5-28)
I am using RDataFrame to analyze some data in a root file, which involves the filtering of string data.
i.e.
auto Si = d.Filter("ParticleName == \"proton\"").Histo1D({"Si","Si",4000,0,400},"particleEnergy");
That is to filter out the energy of protons.
However, there is a problem with the above filter statement, and the error is as follows:
/opt/root62402/include/ROOT/RVec.hxx:609:23: error: comparison between pointer and integer ('cha
RVEC_LOGICAL_OPERATOR(==)
~~~~~~~~~~~~~~~~~~~~~~^~~
/opt/root62402/include/ROOT/RVec.hxx:579:49: note: expanded from macro 'RVEC_LOGICAL_OPERATOR'
auto op = [y](const T0 &x) -> int { return x OP y; }; \
~ ^ ~
input_line_32:2:65: note: in instantiation of function template specialization 'ROOT::VecOps::op
auto lambda0 = [](ROOT::VecOps::RVec<Char_t>& var0){return var0 == "proton"
^
terminate called after throwing an instance of 'std::runtime_error'
what():
RDataFrame: An error occurred during just-in-time compilation. The lines above might indicate th
All RDF objects that have not run an event loop yet should be considered in an invalid state.
Hi @CY_Han ,
and welcome to the ROOT forum!
What type is ParticleName stored as? (e.g. what does TTree::Print say the type of the branch is?)
The problem is that RDF reads the branch as an RVec<char> instead of e.g. a std::string.
This should be a workaround:
d.Filter("std::string s(ParticleName.begin(), ParticleName.end()); return s == \"proton\";")
The code you mentioned did not report an error, but I did not get the data I wanted. It seems that there is no data meets the filter criteria, which is incomprehensible. Since we can clearly see the data meets the condition.
In order to better illustrate the problem, I uploaded a data file and the processing code I used. Could you please help me find out where the problem is?
Hi Han,
thanks a lot for the complete reproducer, that always simplifies debugging
It’s C-string shenanigans. It seems that ParticleName is always an array of 8 characters, padded with \0 if the actual ParticleName is shorter. So we were comparing s which could be e.g. proton\0\0 with "proton". I found out by adding std::cout << s << ' ' << s.size() << '\\n'; in the middle of the Filter expression.
This is a workaround:
auto Si = d.Filter(" std::string s(ParticleName.begin(), ParticleName.end()); return s.substr(0, 6) == \"proton\";")
An alternative is to store std::strings instead of arrays of characters.