diff --git a/Snakefile b/Snakefile
index d645066a69052c7d36350c45d865c4c1ff718ea3..c001f8b08cc33e8b3306cdd1849a6263dcbed9f1 100644
--- a/Snakefile
+++ b/Snakefile
@@ -51,6 +51,7 @@ include: "benchmarks/insert_tau/Snakefile"
 include: "benchmarks/femc_electron/Snakefile"
 include: "benchmarks/femc_photon/Snakefile"
 include: "benchmarks/femc_pi0/Snakefile"
+include: "benchmarks/beamline/Snakefile"
 
 use_s3 = config["remote_provider"].lower() == "s3"
 use_xrootd = config["remote_provider"].lower() == "xrootd"
diff --git a/benchmarks/beamline/Snakefile b/benchmarks/beamline/Snakefile
new file mode 100644
index 0000000000000000000000000000000000000000..70eaf753da4eacc3fc841c92c3b110404dba3408
--- /dev/null
+++ b/benchmarks/beamline/Snakefile
@@ -0,0 +1,25 @@
+rule beamline_sim:
+    input:
+        inputfile="/scratch/EIC/Events/el_beam_18.hepmc",
+    output:
+        "/scratch/EIC/G4out/beamline/beamlineTest.edm4hep.root",
+    log:
+        "/scratch/EIC/G4out/beamline/beamlineTest.edm4hep.root.log",
+    params:
+        N_EVENTS=10000
+    shell:
+        """
+            exec npsim \
+            --runType batch \
+            --inputFiles {input.inputfile} \
+            --random.seed 1234 \
+            --numberOfEvents {params.N_EVENTS} \
+            --compactFile $DETECTOR_PATH/epic_ip6_extended.xml \
+            --outputFile {output}
+        """
+rule beamline_analysis
+    input:
+        "/scratch/EIC/G4out/beamline/beamlineTest.edm4hep.root",
+    output:
+        "/scratch/EIC/ReconOut/beamline/beamlineTestAnalysis.root"
+    log:
\ No newline at end of file
diff --git a/benchmarks/beamline/analysis.C b/benchmarks/beamline/analysis.C
new file mode 100644
index 0000000000000000000000000000000000000000..a0551139c667e2dc9d069dc300e0f21d5c755adb
--- /dev/null
+++ b/benchmarks/beamline/analysis.C
@@ -0,0 +1,50 @@
+// Script to plot the x and y positions and momentum of beamline particles as they pass through the magnets
+
+#include <iostream>
+#include "DD4hep/Detector.h"
+#include "DDRec/CellIDPositionConverter.h"
+#include "edm4hep/MCParticleCollection.h"
+#include "edm4hep/SimTrackerHit.h"
+#include "edm4hep/SimCalorimeterHit.h"
+#include "ROOT/RDataFrame.hxx"
+#include "ROOT/RDF/RInterface.hxx"
+#include "ROOT/RVec.hxx"
+#include "functors.h"
+
+using RVecS       = ROOT::VecOps::RVec<string>;
+using RNode       = ROOT::RDF::RNode;
+
+void analysis(  std::string inFile      = "/scratch/EIC/G4out/beamline/beamlineTest.edm4hep.root",
+                std::string compactName = "/home/simong/EIC/epic/install/share/epic/epic_ip6_extended.xml"){
+
+    //Set implicit multi-threading
+    ROOT::EnableImplicitMT();
+
+    //Load the detector config
+    dd4hep::Detector& detector = dd4hep::Detector::getInstance();
+    detector.fromCompact(compactName);
+ 
+    ROOT::RDataFrame d0("events",inFile, {"BackwardsBeamlineHits"});
+    RNode d1 = d0;
+    RVecS colNames = d1.GetColumnNames();
+    
+    //Get the collection 
+    std::string readoutName = "BackwardsBeamlineHits";
+
+    if(Any(colNames==readoutName)){
+
+        auto ids = detector.readout(readoutName).idSpec().fields();
+
+        for(auto &[key,id]: ids){
+            TString colName = key+"ID";
+            d1              = d1.Define(colName,getSubID(key,detector),{readoutName});
+        }
+    }
+    else{
+        std::cout << "Collection " << readoutName << " not found in file" << std::endl;
+        return;
+    }
+    
+    d1.Snapshot("events","output.root");
+
+}
diff --git a/benchmarks/beamline/functors.h b/benchmarks/beamline/functors.h
new file mode 100644
index 0000000000000000000000000000000000000000..d81b456765f689e8be2a0c63117c1dbe3d2ca79a
--- /dev/null
+++ b/benchmarks/beamline/functors.h
@@ -0,0 +1,36 @@
+#include "DD4hep/Detector.h"
+#include "DDRec/CellIDPositionConverter.h"
+#include "edm4hep/MCParticleCollection.h"
+#include "edm4hep/SimTrackerHit.h"
+#include "edm4hep/SimCalorimeterHit.h"
+
+using RVecHits = ROOT::VecOps::RVec<edm4hep::SimTrackerHitData>;
+
+//-----------------------------------------------------------------------------------------
+// Grab Component functor
+//-----------------------------------------------------------------------------------------
+struct getSubID{
+  getSubID(std::string cname, dd4hep::Detector& det, std::string rname = "BackwardsBeamlineHits") : componentName(cname), detector(det), readoutName(rname){}
+  
+  ROOT::VecOps::RVec<int> operator()(const RVecHits& evt) {
+    auto decoder = detector.readout(readoutName).idSpec().decoder();
+    auto indexID = decoder->index(componentName);
+    ROOT::VecOps::RVec<int> result;
+    for(const auto& h: evt) {
+      result.push_back(decoder->get(h.cellID,indexID));      
+    }
+    return result;    
+  };
+  
+  void SetComponent(std::string cname){
+    componentName = cname;
+  }
+  void SetReadout(std::string rname){
+    readoutName = rname;
+  }
+  
+  private: 
+  std::string componentName;
+  dd4hep::Detector& detector;
+  std::string readoutName;
+};
\ No newline at end of file