RDataFrame use of undeclared identifier error when used with std::vector

I am currently building a program with RDataFrame and I have two basic C++ objects I use inside the RDataFrame.
Object 1:

class Track {
  public :
    TLorentzVector p4;       ///< 4-momentum

    // Default empty tracks will have this set to false
    // while properly filled tracks will have it set to true.
    // Where we have event/region confusion this will help keep
    // "default" tracks from sneaking into our plots.
    bool isValidTrack;

    bool isMuonSignal;      ///< Does it come from a muon

    // Does this have a p compatible with a nominal or validation region?
    std::vector<region_type> sub_region;

    // Other track quantities
    double qoverp;
    double qoverpErr;
    int q;
    double p;
    double dEdx;
    double iso30Pt;
    double calib_mass;
    unsigned char nUsedHits_dEdx;
    unsigned char nSCTHits;
    unsigned char nIBLOverflows_dEdx;
    double betacalo;
    double betacalo_uncalibrated;
    double betadEdx;
    double mass_calo;
    bool good_lowbetacut;
    bool good_highbetacut;
    bool good_lowbetacut_lowmetVR;
    bool lowmetVR_lowmet;
    bool good_lowbetacut_lowdEdxVR;
    bool Inclusive;

Track() : p4(), isValidTrack(false), isMuonSignal(false), sub_region(), qoverp(-1E9), qoverpErr(-1E9), q(1), p(-1E9), dEdx(-
100.), iso30Pt(-1.), calib_mass(-1), nUsedHits_dEdx(-1), nSCTHits(-1), nIBLOverflows_dEdx(-1), betacalo(-1.), betacalo_uncali
brated(-1.), betadEdx(-1.), mass_calo(-1.0), good_lowbetacut(false), good_highbetacut(false), good_lowbetacut_lowmetVR(false)
, lowmetVR_lowmet(false), good_lowbetacut_lowdEdxVR(false) {}
    Track(float pT, float eta, float phi, float M, std::vector<region_type> subRegion, bool isMuonSignal,
          double qoverp_raw, double qoverpErr_raw, double dEdx, double iso30Pt, unsigned char nUsedHits, unsigned char nSCTHi
ts, unsigned char nIBLOverflows, double dEdxMass, double betacalo, double betacalo_uncalibrated, double betadEdx, double mass
_calo, bool good_lowbetacut, bool good_highbetacut, bool good_lowbetacut_lowmetVR, bool lowmetVR_lowmet, bool good_lowbetacut
      : p4(), isValidTrack(true), isMuonSignal(isMuonSignal), sub_region(subRegion), dEdx(dEdx), iso30Pt(iso30Pt), calib_mass
(dEdxMass), nUsedHits_dEdx(nUsedHits), nSCTHits(nSCTHits), nIBLOverflows_dEdx(nIBLOverflows), betacalo(betacalo), betacalo_un
calibrated(betacalo_uncalibrated), betadEdx(betadEdx), mass_calo(mass_calo), good_lowbetacut(good_lowbetacut), good_highbetac
ut(good_highbetacut), good_lowbetacut_lowmetVR(good_lowbetacut_lowmetVR), lowmetVR_lowmet(lowmetVR_lowmet), good_lowbetacut_l
owdEdxVR(good_lowbetacut_lowdEdxVR) {
        p4.SetPtEtaPhiM(pT, eta, phi, M);
        qoverp = 1000.*qoverp_raw;
        qoverpErr = 1000.*qoverpErr_raw;
        p = 1./qoverp;
        if (qoverp < 0) q = -1;
        else q = 1;

        // A bit of a hacky variable defenition to work with definning an inclusive distribution for Inclusive-High/Low
        //It's now ideal but works
        Inclusive = (nIBLOverflows_dEdx == 0 && nUsedHits_dEdx >= 2)   ||  nIBLOverflows_dEdx == 1;



Object 2:

class DiTrack {

 public :
  TLorentzVector p4;       ///< 4-momentum
  bool isTight;      ///< Does it come from a Tight
  double qoverp;
  double qoverpErr;
  double dEdx;
  double TMass;

  DiTrack() {

  DiTrack(float pT, float eta, float phi, float M, float iTMass, bool iisTight,
  	  double qoverp_raw, double qoverpErr_raw, double idEdx) {

    qoverp = 1000.*qoverp_raw;
    qoverpErr = 1000.*qoverpErr_raw;




Both objects are defined in the same header file back-to-back.

When I generate an RDataFrame column with Define function for std::vector or Object1 or Object2. RDataFrame functions/runs properly.

When I use std::vector inside the RDataFrame things crash (It compiles without issues in all versions) with the following error.

. input_line_35:4:49: error: use of undeclared identifier 'DiTrack'
namespace __rdf1 {  using tracks6_type = vector<DiTrack>; }namespace __rdf1 {  using W_WR_mass17_type = double; }

Function I use for defining the objects

    auto with_tracks = weighted_frame.Define("tracks", []
                                          (const std::vector<double>& pt,
                                           const std::vector<double>& eta,
                                           const std::vector<double>& phi,
                                           const std::vector<float>& M,
                                           const std::vector<float>& TMass,
                                           const std::vector<char>& passesInput_tight,
                                           const std::vector<char>& passesInput_loose,
                                           const std::vector<float>& qoverp,
                                           const std::vector<float>& qoverpErr,
                                           const std::vector<float>& dEdxFinal
                                            std::vector<DiTrack> track_vec; //Doesn't work
                                            std::vector<Track> track_vec; //works (ofcourse the others parts of the code needs to be changed
                                            unsigned i=0;
                                            DiTrack twoTrack(pt.at(i),eta.at(i),phi.at(i),M.at(i), TMass.at(i),
                                                             passesInput_tight.at(i), qoverp.at(i), qoverpErr.at(i),

                                            return track_vec;
                                          {track_prefix+"pt", track_prefix+"eta", track_prefix+"phi",
                                              track_prefix+"dEdxMass", track_prefix+"TransverseMass",

Dear Ismet,

Thanks for the interesting post and welcome to the ROOT community!

I cannot reproduce the problem because the code seems to have lost some information while being formatted for the post.

However, irrespective of that, I’d like to try to converge towards a solution in more abstract terms.

I understand you have two classes, A and B, and if you use them in an RDF instance, an error is prompted. This is because, and here I am guessing, you are using in RDF interpreted strings and the classes are known only to the compiler generating the binaries.

I see two rough options here.
If you want to use macros, you can include the header at the top of your macro, and happily run the RDF analysis. It will just work.
If you have a compiled program using RDF, you can include the header (as per C++ practice) in the program source and use the compiled version of RDF, i.e. w/o strings.

A third option of course exists, which is to use a compiled RDF program that uses interpreted strings for the actions, but maybe we can unfold this case after some additional feedback on your side.


Dear Danilo,

Thank you for the fast repose.
I realized my issues were cause because I forgot to add #pragma definition of the DiTrack object.

the bug was solved after I added the lines:

#ifdef __CINT__
#pragma link C++ class Track+;
#pragma link C++ class DiTrack+;
#pragma link C++ class HistogramMapper+;

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