diff --git a/benchmarks/single/analyze.cxx b/benchmarks/single/analyze.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c99e15f1e34187a72fb7b685e42a8b9582fdcf07
--- /dev/null
+++ b/benchmarks/single/analyze.cxx
@@ -0,0 +1,38 @@
+#include <iostream>
+#include <string>
+
+#include <ROOT/RDataFrame.hxx>
+
+#include <eicd/ReconstructedParticleData.h>
+
+int analyze(std::string name)
+{
+ // open dataframe
+ ROOT::RDataFrame df("events", url, {"mcparticles2", "GeneratedParticles", "ReconstructedParticles"});
+ // count total events
+ auto count = df.Count();
+ if (count == 0) {
+ std::cout << "Error: No events found" << std::endl;
+ return -1;
+ }
+
+ auto n_tracks = [](const std::vector<eic::ReconstructedParticleData> &p) { return (int) p.size(); };
+
+ auto d = df
+ .Define("n_tracks_gen", n_tracks, {"GeneratedParticles"})
+ .Define("n_tracks_rec", n_tracks, {"ReconstructedParticles"})
+ ;
+
+ auto stats_n_tracks_gen = d.Stats("n_tracks_gen");
+ auto stats_n_tracks_rec = d.Stats("n_tracks_rec");
+ if (stats_n_tracks_gen->GetMean() < 1.0
+ || stats_n_tracks_rec->GetMean()) {
+ std::cout << "Error: too few tracks per events " << std::endl;
+ stats_n_tracks_gen->Print();
+ stats_n_tracks_rec->Print();
+ return -1;
+ }
+
+ // success
+ return 0;
+}
diff --git a/benchmarks/single/single.sh b/benchmarks/single/single.sh
index 3f475abafbc9ed8bdd9879b286aeac2705fa2d89..cb153366bae8694164fbcc5ad90e7089a739ccef 100644
--- a/benchmarks/single/single.sh
+++ b/benchmarks/single/single.sh
@@ -31,7 +31,7 @@ if [[ "$?" -ne "0" ]] ; then
fi
# Analysis
-root -l -b -q ${JUGGLER_REC_FILE} -e 'events->Scan("@ReconstructedParticles.size()","","",10)'
+root -l -b -q "benchmarks/single/analyze.cxx+(\"${JUGGLER_REC_FILE}\")"
if [[ "$?" -ne "0" ]] ; then
echo "ERROR analysis failed"
exit 1