diff --git a/compact/far_backward/beamline_tracking.xml b/compact/far_backward/beamline_tracking.xml
new file mode 100644
index 000000000..1a85527e1
--- /dev/null
+++ b/compact/far_backward/beamline_tracking.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ system:8,pipe:8,end:2
+
+
+
+
+
\ No newline at end of file
diff --git a/compact/far_backward/extended.xml b/compact/far_backward/extended.xml
index bcbb157de..1d98929d8 100644
--- a/compact/far_backward/extended.xml
+++ b/compact/far_backward/extended.xml
@@ -2,7 +2,7 @@
-
+
@@ -13,4 +13,6 @@
+
+
diff --git a/compact/far_backward/magnets.xml b/compact/far_backward/magnets.xml
index 3d578667f..0c58616e7 100644
--- a/compact/far_backward/magnets.xml
+++ b/compact/far_backward/magnets.xml
@@ -9,13 +9,10 @@
+ vis="BeamPipeVis">
-
-
-
-
- system:8,pipe:8,end:2
-
-
-
diff --git a/src/BeamPipeTracking_geo.cpp b/src/BeamPipeTracking_geo.cpp
new file mode 100644
index 000000000..844d3a074
--- /dev/null
+++ b/src/BeamPipeTracking_geo.cpp
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// Copyright (C) 2024 Simon Gardner
+
+//==========================================================================
+//
+// Places a small sensitive disk of vacuum at the end of beam pipes
+//
+//==========================================================================
+
+#include "DD4hep/DetFactoryHelper.h"
+#include "DD4hep/Printout.h"
+#include "TMath.h"
+#include
+
+using namespace std;
+using namespace dd4hep;
+
+static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
+
+
+ using namespace ROOT::Math;
+ xml_det_t x_det = e;
+ string det_name = x_det.nameStr();
+ int det_id = x_det.id();
+ Material m_Vacuum = description.material("Vacuum");
+ string vis_name = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "BeamPipeVis");
+
+ sens.setType("tracker");
+
+ DetElement sdet(det_name, det_id);
+ Assembly assembly(det_name + "_assembly");
+
+ // Grab info for beamline magnets
+ for (xml_coll_t slice_coll(x_det, _Unicode(slice)); slice_coll; slice_coll++) { // pipes
+
+ string grandmotherName = slice_coll.attr(_Unicode(grandmother));
+ string motherName = slice_coll.attr(_Unicode(mother));
+ bool detStart = getAttrOrDefault(slice_coll, _Unicode(end), true);
+ int pipe_id = getAttrOrDefault (slice_coll, _Unicode(pipe_id), 0);
+ string slice_name = slice_coll.attr(_Unicode(name));
+ DetElement mother = description.detector(grandmotherName).child(motherName);
+
+ // Get the mother volume
+ Volume mother_vol = mother.volume();
+
+ // Get mother volume shape as cone segment
+ ConeSegment mother_shape = mother_vol.solid();
+
+ // Get the parameters of the mother volume
+ double rOuter1 = mother_shape.rMax1();
+ double rOuter2 = mother_shape.rMax2();
+ double length = 2*mother_shape.dZ();
+
+ double sensitive_thickness = 0.1 * mm;
+
+ //Calculate R or cone after sensitive layer
+
+ double rEnd = rOuter2 - (rOuter2 - rOuter1) * sensitive_thickness / length;
+ double zPos = length / 2.0 - sensitive_thickness / 2.0;
+ if (detStart){
+ rEnd = rOuter1 - (rOuter1 - rOuter2) * sensitive_thickness / length;
+ zPos = -length / 2.0 + sensitive_thickness / 2.0;
+ }
+
+ ConeSegment s_start_disk(sensitive_thickness / 2, 0.0, rOuter2, 0.0, rEnd);
+ Volume v_start_disk("v_start_disk_" + motherName, s_start_disk, m_Vacuum);
+ v_start_disk.setSensitiveDetector(sens);
+
+ auto disk_placement = mother_vol.placeVolume(v_start_disk, Position(0.0, 0.0, zPos));
+ disk_placement.addPhysVolID("end", detStart );
+ disk_placement.addPhysVolID("pipe", pipe_id );
+ disk_placement.addPhysVolID("system", det_id );
+
+ DetElement slice_element(sdet, slice_name, pipe_id);
+
+ slice_element.setPlacement(disk_placement);
+ description.declareParent(slice_name, mother);
+
+ }
+
+ auto pv_assembly = description.worldVolume().placeVolume(assembly, Position(0.0, 0.0, 0.0));
+ sdet.setPlacement(pv_assembly);
+
+ return sdet;
+}
+
+DECLARE_DETELEMENT(BeamPipeTracking, create_detector)