TDataFrame Filter is not Working

Hello, Everyone!

I’m trying to apply one Energy cut in the data and make a histogram,
using TData Frame, but the Filter isn’t working.

My program:

using namespace std;

using namespace ROOT::Experimental::VecOps;

    void Analysis_EPOS_LHC(){

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

            auto c1 = new TCanvas("c1", "c1", 10, 10, 700, 500);
            c1->SetLogx(0); // 0 == scale without Log, 1 == scale with Log
            hpt->GetYaxis()->SetTitle("dN/dp_{T} [GeV^{-1}]");
            hpt->GetXaxis()->SetTitle("p_{T} [GeV]");


the file.root:
crmc_eposlhc_112108849_p_C_130000.root (304.2 KB)

$ rootls -t crmc_eposlhc_112108849_p_C_130000.root 
TTree  Mar 24 22:09 2018 Particle  "particles produced"
  nPart            "nPart/I"            404
  ImpactParameter  "ImpactParameter/D"  742
  pdgid            "pdgid[nPart]/I"     47480
  status           "status[nPart]/I"    47482
  px               "px[nPart]/D"        94620
  py               "py[nPart]/D"        94620
  pz               "pz[nPart]/D"        94620
  E                "E[nPart]/D"         94616
  m                "m[nPart]/D"         94616

Someone can help me?

Cheers, Andre

"E" is an array of doubles but you are filtering it as if it was a double, could that be the problem?

Otherwise, thanks to you providing reproducer and sample data I can run the macro locally: what is the expected result and what is the result you get?

Finally, what version of ROOT are you on?


EDIT: the problem is definitely that you are reading "E" as a double rather than an array of doubles. What happens is that you filter only on its first value. Give me a bit of time and I’ll post a corrected version of your macro.

Hi Andre,
here’s a version of your macro that properly filters each pt value according to the corresponding E value (I assume this is what you wanted). Now you can also compile this file, for extra speed :slight_smile::

#include <ROOT/TDataFrame.hxx>
#include <TCanvas.h>
#include <TApplication.h>

using namespace ROOT::Experimental;
using namespace ROOT::Experimental::VecOps;

void Analysis_EPOS_LHC()
   TDataFrame d("Particle", "crmc_eposlhc_112108849_p_C_130000.root");

   // TVec supports per-element operations (a-la numpy) and simple filtering with v[v > 3]
   using doubles = TVec<double>;
   auto cutPt = [](doubles &pxs, doubles &pys, doubles &Es) {
      auto all_pts = sqrt(pxs * pxs + pys * pys);
      auto good_pts = all_pts[Es > 200.];
      return good_pts;

   auto hpt = d.Define("pt", cutPt, {"px", "py", "E"}).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
   hpt->GetYaxis()->SetTitle("dN/dp_{T} [GeV^{-1}]");
   hpt->GetXaxis()->SetTitle("p_{T} [GeV]");

int main()
   TApplication app("app", nullptr, nullptr);
   return 0;

I will investigate why we were not erroring out when you were reading E as a single double (we should at least print a warning).

Hope this helps anyway,

1 Like

Hi, Enrico

Thanks for the quick answer.

  • ROOT 6.13/01 Built for linuxx8664gcc
    From heads/master@v6-11-02-2018-g01472a0, Mar 09 2018

The expected result:

The energy cut selects the particles with higher energy.

Cheers, Andre

here’s what I get with the solution proposed above, looks ok?

Right, this is the output that I expected.


#0  0x00007fae6d83907a in __GI___waitpid (pid=5022, stat_loc=stat_loc
entry=0x7ffe7f681b30, options=options
entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:29
#1  0x00007fae6d7b1fbb in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:148
#2  0x00007fae6e555dce in TUnixSystem::Exec(char const*) () from /opt/root6/lib/
#3  0x00007fae6e55668e in TUnixSystem::StackTrace() () from /opt/root6/lib/
#4  0x00007fae68b0b39d in TCling__PrintStackTrace () from /opt/root6/lib/
#5  0x00007fae68c10867 in TClingCallbacks::PrintStackTrace() () from /opt/root6/lib/
#6  0x00007fae68c46ad5 in cling::MultiplexInterpreterCallbacks::PrintStackTrace() () from /opt/root6/lib/
#7  0x00007fae68c465ed in cling_runtime_internal_throwIfInvalidPointer () from /opt/root6/lib/
#8  0x00007fae6eb5a328 in ?? ()
#9  0xfffffffffffffff8 in ?? ()
#10 0x0000000000000001 in ?? ()
#11 0x00007fae68c46550 in ?? () from /opt/root6/lib/
#12 0x00007ffe7f683f58 in ?? ()
#13 0x00007ffe7f683f70 in ?? ()
#14 0x00007fae6eb6a7e9 in ?? ()
#15 0x00007ffe7f683f58 in ?? ()
#16 0x0000000000000001 in ?? ()
#17 0x00007ffe7f683f60 in ?? ()
#18 0xfffffffffffffff8 in ?? ()
#19 0x0000000000000000 in ?? ()
terminate called after throwing an instance of 'cling::InvalidDerefException'
  what():  Trying to access a pointer that points to an invalid memory address.

I don’t understand, is that an error you get when executing my version of the macro? I can execute it correctly, but admittedly I’m on a more recent version of master than you.

Maybe can you try to compile the version I sent you? e.g. with g++ -g Analysis_EPOS_LHC.cpp $(root-config --libs --cflags); ./a.out



Yes, When I’m running the macro that you suggestion, this
error describe above.

I try compile using g++ -g Analysis_EPOS_LHC.cpp:
executable ./a.out, but I don’t work, :sweat_smile:,


*** Break *** segmentation violation

There was a crash (#5 0x00007fbb9750ebf4 in SigHandler(ESignals) () from /opt/root6/lib/
This is the entire stack trace of all threads:
#0  0x00007fbb9553f07a in __GI___waitpid (pid=10085, stat_loc=stat_loc
entry=0x7ffefab97b30, options=options
entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:29
#1  0x00007fbb954b7fbb in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:148
#2  0x00007fbb97512dce in TUnixSystem::Exec(char const*) () from /opt/root6/lib/
#3  0x00007fbb9751368e in TUnixSystem::StackTrace() () from /opt/root6/lib/
#4  0x00007fbb9751728b in TUnixSystem::DispatchSignals(ESignals) () from /opt/root6/lib/
#5  0x00007fbb9750ebf4 in SigHandler(ESignals) () from /opt/root6/lib/
#6  0x00007fbb975171dd in sighandler(int) () from /opt/root6/lib/
#7  <signal handler called>
#8  0x000000000044b66c in std::unique_ptr<TTreeReaderArray<double>, std::default_delete<TTreeReaderArray<double> > >::get (this=0xfffffffffffffff8) at /usr/include/c++/6/bits/unique_ptr.h:308
#9  0x000000000044a65a in std::unique_ptr<TTreeReaderArray<double>, std::default_delete<TTreeReaderArray<double> > >::operator* (this=0xfffffffffffffff8) at /usr/include/c++/6/bits/unique_ptr.h:294
#10 0x0000000000449d0a in ROOT::Internal::TDF::TColumnValue<ROOT::Experimental::VecOps::TVec<double>, true>::Get<ROOT::Experimental::VecOps::TVec<double>, 0> (this=0x62f4620) at /opt/root6/include/ROOT/TDFNodes.hxx:290
#11 0x00007fbb879f8d16 in ?? ()
#12 0x0000000000000000 in ?? ()

Maybe one way to solve this is change the version of master,
by the way, I did the upgrade recently:
ROOT 6.13/01heads/master@v6-11-02-2018-g01472a0, Mar 09 2018

Cheers, Andre

I just tried to run the new version of the macro with your version of master and indeed it crashes.

The commit you are at (01472a0) is precisely in the middle of the upgrade of TDataFrame to integrate usage of TVec, so I’m not too surprised.

Please do upgrade to the latest master, TDataFrame+TVec should be more stable there.


fyi, your original issue (double array silently read as a single double value) is now a bug report, I’ll add a fix for the next release.

Hi, Enrico

Thank you for your support, Now with the upgrade It worked.

ROOT 6.13/03 | Built for linuxx8664gcc heads/master@v6-13-02-120-g3c7fa4a, Mar 27 2018, 09:56:12

Cheers, Andre


The excitement of being bleeding edge :smile:

Have fun with TDF and TVec!

To be forgiven for my incoherent set of commits, I distilled from this thread a new pair of tutorials, simple enough to be understood immediately but sophisticated enough to show the advantages of TVec and TDataFrame:


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