Error in TTreeReaderValueBase using TDataFrame

Hello,

I’m trying to read a TTree:

rootls -t crmc_eposlhc_969677293_p_C_671.root
TTree  Mar 06 19:23 2018 Particle  "particles produced"
  nPart            "nPart/I"            476
  ImpactParameter  "ImpactParameter/D"  886
  pdgid            "pdgid[nPart]/I"     73636
  status           "status[nPart]/I"    73639
  px               "px[nPart]/D"        146773
  py               "py[nPart]/D"        146773
  pz               "pz[nPart]/D"        146773
  E                "E[nPart]/D"         146768
  m                "m[nPart]/D"         146768

In the file the variables px, py … are D : Double, but I get the following
error:

Error in <TTreeReaderValueBase::CreateProxy()>: The branch px contains data of type double. It cannot be accessed by a TTreeReaderValue<array_view<double>>
Error in <TTreeReaderValueBase::CreateProxy()>: The branch px contains data of type double. It cannot be accessed by a TTreeReaderValue<array_view<double>>
Error in <TTreeReaderValueBase::CreateProxy()>: The branch px contains data of type double. It cannot be accessed by a TTreeReaderValue<array_view<double>>
Error in <TTreeReaderValueBase::CreateProxy()>: The branch px contains data of type double. It cannot be accessed by a TTreeReaderValue<array_view<double>>

In my “program” I using TDataFrame where the variable are double,

void program(){
        
       
        ROOT::Experimental::TDataFrame d("Particle","crmc_eposlhc_969677293_p_C_671.root");
       
        std::vector<double> v;
        using doubles = std::array_view<double>;
        
        auto ptCalc = [&v](doubles pxs, doubles pys) {
            v. clear(); 
            for (unsigned int i=0;i < pxs.size(); ++i) v.emplace_back(sqrt(pxs[i]*pxs[i] + pys[i]*pys[i]));
            return v;};

            auto dd = d.Define("pt", ptCalc, {"px", "py"});
            auto hpt = dd.Histo1D({"hpt", "p_{T} distribution", 100, 0, 15}, "pt");
        
            //drawing
            auto c1 = new TCanvas("c1", "c1", 10, 10, 700, 500);
            c1->SetGrid(1,1);
            c1->SetLogx(0); // 0 == scale without Log, 1 == scale with Log
            c1->SetLogy(1);
            hpt->GetYaxis()->SetTitle("dN/dp_{T} [GeV^{-1}]");
            hpt->GetXaxis()->SetTitle("p_{T} [GeV]");
            hpt->DrawClone();
        

Someone know how to fix this?

Thanks in advanced, Cheers!

Hi Andre,

what version of ROOT is this?

Cheers,
D

Hi Danilo,

I’m using

root
   -----------------------------------------------------------------
  | Welcome to ROOT 6.13/01                     http://root.cern.ch |
  |                                    (c) 1995-2017, The ROOT Team |
  | Built for linuxx8664gcc                                         |
  | From heads/master@v6-11-02-1148-g4192bcf, Dez 13 2017, 13:12:44 |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q'      |
   -----------------------------------------------------------------

Cheers, Andre

Hi Andre,
it looks like you are using ROOT’s master branch (next unreleased version) but you are on commit 4192bcf, which dates back to December the 13th.

Several changes were introduced in TDataFrame since then. In particular, now we read arrays like your px and py using TVec objects instead of array_view.

The lambda in your macro should simply change signature to:

using ROOT::Experimental::VecOps;
using doubles = TVec<double>;
auto ptCalc = [](doubles pxs, doubles pys) { ... };

The rest should stay the same. TVec can be used as a std::vector, but it also offers many more convenient operations.

Please upgrade to the ROOT’s latest master and let us know if you still experience this problem.

Cheers,
Enrico

Hi Enrico

Thanks for the reply. I did the upgrade to the ROOT’s lastest ROOT 6.13/01 (heads/master@v6-11-02-2013-gd639b6a, Mar 09 2018, 10:15:08)

And I did the changes that you suggestion:

    using namespace std;

    void analysis_EPOS_LHC(){
        
        using ROOT::Experimental::VecOps;
        ROOT::Experimental::TDataFrame d("Particle","crmc_eposlhc_374415082_p_C_617.root");
        
        std::vector<double> v;
        using doubles = TVec<double>;
        
        auto ptCalc = [&v](doubles pxs, doubles pys) {
            v.clear(); 
            for (unsigned int i=0;i < pxs.size(); ++i) v.emplace_back(sqrt(pxs[i]*pxs[i] + pys[i]*pys[i]));
            return v;};
            
            auto dd = d.Define("pt", ptCalc, {"px", "py"});
            auto hpt = dd.Histo1D({"hpt", "p_{T} distribution", 100, 0, 15}, "pt");

     ...

    }

Error:

/home/andre/Dropbox/Doutorado/CRMC/Analysis_EPOS_LHC.C:24:35: error: using declaration cannot refer to a namespace
        using ROOT::Experimental::VecOps;
              ~~~~~~~~~~~~~~~~~~~~^
/home/andre/Dropbox/Doutorado/CRMC/Analysis_EPOS_LHC.C:29:25: error: no template named 'TVec'
        using doubles = TVec<double>;
                        ^
/home/andre/Dropbox/Doutorado/CRMC/Analysis_EPOS_LHC.C:31:28: error: unknown type name 'doubles'
        auto ptCalc = [&v](doubles pxs, doubles pys) {
                           ^
/home/andre/Dropbox/Doutorado/CRMC/Analysis_EPOS_LHC.C:31:41: error: unknown type name 'doubles'
        auto ptCalc = [&v](doubles pxs, doubles pys) {
                                        ^

 *** Break *** segmentation violation

Cheers, Andre

Sorry, as per compiler error, it should have been using namespace ROOT::Experimental::VecOps, to be put right after using namespace std

Thank you, It worked very well.

Cheers, Andre

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