diff --git a/PhysicsAnalysis/NtupleDumper/CMakeLists.txt b/PhysicsAnalysis/NtupleDumper/CMakeLists.txt
index 03fd7a2d205dd40b0945c32ab72d7e72bf0a64cc..dc2dae3126aaa00283775626da1b29bbb0dd3ac3 100644
--- a/PhysicsAnalysis/NtupleDumper/CMakeLists.txt
+++ b/PhysicsAnalysis/NtupleDumper/CMakeLists.txt
@@ -5,7 +5,7 @@ atlas_add_component(
         src/NtupleDumperAlg.h
         src/NtupleDumperAlg.cxx
         src/component/NtupleDumper_entries.cxx
-        LINK_LIBRARIES AthenaBaseComps StoreGateLib xAODFaserWaveform xAODFaserCalorimeter xAODFaserTrigger ScintIdentifier FaserCaloIdentifier GeneratorObjects FaserActsGeometryLib TrackerSimEvent TrackerSimData TrackerIdentifier TrackerReadoutGeometry TrkTrack GeoPrimitives TrackerRIO_OnTrack TrackerSpacePoint FaserActsKalmanFilterLib
+        LINK_LIBRARIES AthenaBaseComps StoreGateLib xAODFaserWaveform xAODFaserCalorimeter xAODFaserTrigger xAODFaserLHC ScintIdentifier FaserCaloIdentifier GeneratorObjects FaserActsGeometryLib TrackerSimEvent TrackerSimData TrackerIdentifier TrackerReadoutGeometry TrkTrack GeoPrimitives TrackerRIO_OnTrack TrackerSpacePoint FaserActsKalmanFilterLib
 )
 
 atlas_install_python_modules(python/*.py)
diff --git a/PhysicsAnalysis/NtupleDumper/src/NtupleDumperAlg.cxx b/PhysicsAnalysis/NtupleDumper/src/NtupleDumperAlg.cxx
index c78a4bba944c776724177b38200cc84af36078fd..9fa645d4162b367f79938284a7da2f775cd724b1 100644
--- a/PhysicsAnalysis/NtupleDumper/src/NtupleDumperAlg.cxx
+++ b/PhysicsAnalysis/NtupleDumper/src/NtupleDumperAlg.cxx
@@ -89,6 +89,7 @@ StatusCode NtupleDumperAlg::initialize()
 {
   ATH_CHECK(m_truthEventContainer.initialize());
   ATH_CHECK(m_truthParticleContainer.initialize());
+  ATH_CHECK(m_lhcData.initialize());
   ATH_CHECK(m_trackCollection.initialize());
   ATH_CHECK(m_trackCollectionWithoutIFT.initialize());
   ATH_CHECK(m_trackSegmentCollection.initialize());
@@ -140,6 +141,16 @@ StatusCode NtupleDumperAlg::initialize()
   m_tree->Branch("eventTime", &m_event_time, "eventTime/I");
   m_tree->Branch("BCID", &m_bcid, "BCID/I");
 
+  m_tree->Branch("fillNumber", &m_fillNumber, "fillNumber/I");
+  m_tree->Branch("betaStar", &m_betaStar, "betaStar/F");
+  m_tree->Branch("crossingAngle", &m_crossingAngle, "crossingAngle/F");
+  m_tree->Branch("distanceToCollidingBCID", &m_distanceToCollidingBCID, "distanceToCollidingBCID/I");
+  m_tree->Branch("distanceToUnpairedB1", &m_distanceToUnpairedB1, "distanceToUnpairedB1/I");
+  m_tree->Branch("distanceToUnpairedB2", &m_distanceToUnpairedB2, "distanceToUnpairedB2/I");
+  m_tree->Branch("distanceToInboundB1", &m_distanceToInboundB1, "distanceToInboundB1/I");
+  m_tree->Branch("distanceToTrainStart", &m_distanceToTrainStart, "distanceToTrainStart/I");
+  m_tree->Branch("distanceToPreviousColliding", &m_distanceToPreviousColliding, "distanceToPreviousColliding/I");
+
   m_tree->Branch("TBP", &m_tbp, "TBP/I");
   m_tree->Branch("TAP", &m_tap, "TAP/I");
   m_tree->Branch("inputBits", &m_inputBits, "inputBits/I");
@@ -360,15 +371,15 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
   clearTree();
 
   // check if real data or simulation data
-  bool realData = true;
+  bool isMC = false;
   SG::ReadHandle<xAOD::TruthEventContainer> truthEventContainer { m_truthEventContainer, ctx };
   if (truthEventContainer.isValid() && truthEventContainer->size() > 0)
   {
-    realData = false;
+    isMC = true;
   }
 
   // if real data, store charge in histograms from random events and only fill ntuple from coincidence events
-  if (realData) { //no trigger simulation yet
+  if (!isMC) {
     SG::ReadHandle<xAOD::FaserTriggerData> triggerData(m_FaserTriggerData, ctx);
     m_tap=triggerData->tap();
     // unpack trigger word: 1=calo, 2=veotnu|veto1|preshower, 4=TimingLayer, 8=(VetoNu|Veto2)&Preshower, 16=random, 32=LED 
@@ -443,18 +454,65 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
       // don't process events that fail to activate coincidence triggers
       return StatusCode::SUCCESS;
     }
+    // store trigger data in ntuple variables
     m_tbp=triggerData->tbp();
     m_tap=triggerData->tap();
     m_inputBits=triggerData->inputBits();
     m_inputBitsNext=triggerData->inputBitsNextClk();
-  }
+
+    // load in LHC data
+    SG::ReadHandle<xAOD::FaserLHCData> lhcData { m_lhcData, ctx };
+    ATH_CHECK(lhcData.isValid());
+    // don't process events that were not taken during "Stable Beams"
+    if ( !(lhcData->stableBeams()) ) return StatusCode::SUCCESS;
+    // store interesting data in ntuple variables
+    m_fillNumber = lhcData->fillNumber();
+    m_betaStar = lhcData->betaStar();
+    m_crossingAngle = lhcData->crossingAngle();
+    m_distanceToCollidingBCID = lhcData->distanceToCollidingBCID();
+    m_distanceToUnpairedB1 = lhcData->distanceToUnpairedB1();
+    m_distanceToUnpairedB2 = lhcData->distanceToUnpairedB2();
+    m_distanceToInboundB1 = lhcData->distanceToInboundB1();
+    m_distanceToTrainStart = lhcData->distanceToTrainStart();
+    m_distanceToPreviousColliding = lhcData->distanceToPreviousColliding();
+    // debug print out all LHC data info available
+    ATH_MSG_DEBUG("LHC data fillNumber = " << lhcData->fillNumber() );    
+    ATH_MSG_DEBUG("LHC data machineMode = " << lhcData->machineMode() );
+    ATH_MSG_DEBUG("LHC data beamMode = " << lhcData->beamMode() );
+    ATH_MSG_DEBUG("LHC data beamType1 = " << lhcData->beamType1() );
+    ATH_MSG_DEBUG("LHC data beamType2 = " << lhcData->beamType2() );
+    ATH_MSG_DEBUG("LHC data betaStar = " << lhcData->betaStar() );
+    ATH_MSG_DEBUG("LHC data crossingAngle = " << lhcData->crossingAngle() );
+    ATH_MSG_DEBUG("LHC data stableBeams = " << lhcData->stableBeams() );
+    ATH_MSG_DEBUG("LHC data injectionScheme = " << lhcData->injectionScheme() );
+    ATH_MSG_DEBUG("LHC data numBunchBeam1 = " << lhcData->numBunchBeam1() );
+    ATH_MSG_DEBUG("LHC data numBunchBeam2 = " << lhcData->numBunchBeam2() );
+    ATH_MSG_DEBUG("LHC data numBunchColliding = " << lhcData->numBunchColliding() );
+    ATH_MSG_DEBUG("LHC data distanceToCollidingBCID = " << lhcData->distanceToCollidingBCID() );
+    ATH_MSG_DEBUG("LHC data distanceToUnpairedB1 = " << lhcData->distanceToUnpairedB1() );
+    ATH_MSG_DEBUG("LHC data distanceToUnpairedB1 = " << lhcData->distanceToUnpairedB2() );
+    ATH_MSG_DEBUG("LHC data distanceToInboundB1 = " << lhcData->distanceToInboundB1() );
+    ATH_MSG_DEBUG("LHC data distanceToTrainStart = " << lhcData->distanceToTrainStart() );
+    ATH_MSG_DEBUG("LHC data distanceToPreviousColliding = " << lhcData->distanceToPreviousColliding() );
+
+    // correct waveform time with clock phase
+    SG::ReadHandle<xAOD::WaveformClock> clockHandle(m_ClockWaveformContainer, ctx);
+    ATH_CHECK(clockHandle.isValid());
+
+    if (clockHandle->phase() < -2.0) { // wrap around clock pahse so -pi goes to pi
+      m_clock_phase = ((clockHandle->phase() + 2*3.14159) / 3.14159) * 12.5;
+    } else {
+      m_clock_phase = (clockHandle->phase() / 3.14159) * 12.5;
+    }
+
+  } // done with processing only on real data
 
   m_run_number = ctx.eventID().run_number();
   m_event_number = ctx.eventID().event_number();
   m_event_time = ctx.eventID().time_stamp();
   m_bcid = ctx.eventID().bunch_crossing_id();
 
-  if (!realData) { // if simulation find MC cross section and primary lepton
+  if (isMC) { // if simulation find MC cross section and primary lepton
     // Work out effective cross section for MC
     if (m_useFlukaWeights)
     {
@@ -494,9 +552,9 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
 	    m_truthM_y.push_back(particle->prodVtx()->y());
 	    m_truthM_z.push_back(particle->prodVtx()->z());
 	  } else {
-	    m_truthM_x.push_back(-999999);
-	    m_truthM_y.push_back(-999999);
-	    m_truthM_z.push_back(-999999);
+	    m_truthM_x.push_back(NaN);
+	    m_truthM_y.push_back(NaN);
+	    m_truthM_z.push_back(NaN);
 	  }
 
 	  }
@@ -512,9 +570,9 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
 	    m_truthd0_y.push_back(particle->prodVtx()->y());
 	    m_truthd0_z.push_back(particle->prodVtx()->z());
 	  } else {
-	    m_truthd0_x.push_back(-999999);
-	    m_truthd0_y.push_back(-999999);
-	    m_truthd0_z.push_back(-999999);
+	    m_truthd0_x.push_back(NaN);
+	    m_truthd0_y.push_back(NaN);
+	    m_truthd0_z.push_back(NaN);
 	  }
 	  }
 	if ( particle->pdgId() == -11) // daughter particle (electron)
@@ -529,9 +587,9 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
 	    m_truthd1_y.push_back(particle->prodVtx()->y());
 	    m_truthd1_z.push_back(particle->prodVtx()->z());
 	  } else {
-	    m_truthd1_x.push_back(-999999);
-	    m_truthd1_y.push_back(-999999);
-	    m_truthd1_z.push_back(-999999);
+	    m_truthd1_x.push_back(NaN);
+	    m_truthd1_y.push_back(NaN);
+	    m_truthd1_z.push_back(NaN);
 	  }
 	  }
 	}
@@ -580,18 +638,7 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
     ATH_MSG_DEBUG("Calibrated preshower: ch is " << ch << ", edep is " << hit->E_dep() << ", E_EM is " << hit->E_EM() << ", Nmip is " << hit->Nmip() << ", fit_to_raw_ratio is " << hit->fit_to_raw_ratio());
   }
 
-
-  if (realData) { // correct waveform time with clock phase
-    SG::ReadHandle<xAOD::WaveformClock> clockHandle(m_ClockWaveformContainer, ctx);
-    ATH_CHECK(clockHandle.isValid());
-
-    if (clockHandle->phase() < -2.0) { // wrap around clock pahse so -pi goes to pi
-      m_clock_phase = ((clockHandle->phase() + 2*3.14159) / 3.14159) * 12.5;
-    } else {
-      m_clock_phase = (clockHandle->phase() / 3.14159) * 12.5;
-    }
-  }
-
+  // process all waveeform data fro all scintillator and calorimeter channels
   SG::ReadHandle<xAOD::WaveformHitContainer> vetoNuContainer { m_vetoNuContainer, ctx };
   ATH_CHECK(vetoNuContainer.isValid());
 
@@ -613,21 +660,23 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
   FillWaveBranches(*preshowerContainer);
   FillWaveBranches(*ecalContainer);
 
-  if (realData && m_doBlinding) { // enforce blinding such that events that miss the vetoe layers and have a large calo signal are skipped and not in the output root file
-    if ( m_calo_total_E_EM/1000.0 > 10.0 ) { // energy is in MeV so divide bt 1000 to compare to 10 GeV
+  // enforce blinding such that events that miss the veto layers and have a large calo signal are skipped and not in the output root file
+  if ( (!isMC) && m_doBlinding) {
+    if ( m_calo_total_E_EM/1000.0 > 10.0 ) { // energy is in MeV so divide by 1000 to compare to 10 GeV
       if (m_wave_status[4] == 1 and m_wave_status[5] == 1 and m_wave_status[6] == 1 and m_wave_status[7] == 1 and m_wave_status[14] == 1) {  // hit status == 1 means it is below threshold. channles 4 and 5 are vetoNu, channels 6,7, and 14 are veto
         return StatusCode::SUCCESS;
       }
     }
   }
 
-  // loop over clusters
-  SG::ReadHandle<Tracker::FaserSCT_ClusterContainer> clusterContainer { m_clusterContainer, ctx };
-  ATH_CHECK(clusterContainer.isValid());
-
+  // get geometry context
   FaserActsGeometryContext faserGeometryContext = m_trackingGeometryTool->getNominalGeometryContext();
   auto gctx = faserGeometryContext.context();
 
+  // loop over clusters and store how many clusters are in each tracking station
+  SG::ReadHandle<Tracker::FaserSCT_ClusterContainer> clusterContainer { m_clusterContainer, ctx };
+  ATH_CHECK(clusterContainer.isValid());
+
   for (auto collection : *clusterContainer)
   {
     Identifier id = collection->identify();
@@ -659,6 +708,7 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
     }
   }
 
+  // loop over spacepoints and store each space point position
   SG::ReadHandle<FaserSCT_SpacePointContainer> spacePointContainer {m_spacePointContainerKey, ctx};
   ATH_CHECK(spacePointContainer.isValid());
   for (const FaserSCT_SpacePointCollection* spacePointCollection : *spacePointContainer) {
@@ -671,6 +721,7 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
     }
   }
 
+  // loop over track segments and store position, momentum, chi2, and nDOF for each segment
   SG::ReadHandle<TrackCollection> trackSegmentCollection {m_trackSegmentCollection, ctx};
   ATH_CHECK(trackSegmentCollection.isValid());
   for (const Trk::Track* trackSeg : *trackSegmentCollection) {
@@ -689,8 +740,9 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
     m_trackseg_pz.push_back(SegMomentum.z());
   }
 
+  // Write out all truth particle barcodes that have a momentum larger than MinMomentum (default is 50 GeV)
   std::map<int, size_t> truthParticleCount {};
-  if (!realData) {
+  if (isMC) {
     SG::ReadHandle<xAOD::TruthParticleContainer> truthParticleContainer { m_truthParticleContainer, ctx };
     ATH_CHECK(truthParticleContainer.isValid() && truthParticleContainer->size() > 0);
     for (const xAOD::TruthParticle *tp : *truthParticleContainer) {
@@ -699,6 +751,9 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
     }
   }
 
+  // loop over all reconstructed tracks and use only the tracks that have hits in all three tracking stations (excludes IFT)
+  // store track parameters at most upstream measurement and at most downstream measurement
+  // extrapolate track to all scintillator positions and store extrapolated position and angle
   SG::ReadHandle<TrackCollection> trackCollection {m_trackCollectionWithoutIFT, ctx}; // use track collection that excludes IFT
   ATH_CHECK(trackCollection.isValid());
   const Trk::TrackParameters* candidateParameters {nullptr};
@@ -761,7 +816,7 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
     m_pzdown.push_back(candidateDownParameters->momentum().z());
     m_pdown.push_back(sqrt( pow(candidateDownParameters->momentum().x(),2) + pow(candidateDownParameters->momentum().y(),2) + pow(candidateDownParameters->momentum().z(),2) ));
 
-    if (!realData) {
+    if (isMC) { // if simulation, store track truth info as well
       auto [truthParticle, hitCount] = m_trackTruthMatchingTool->getTruthParticle(track);
       if (truthParticle != nullptr) {
         if (truthParticleCount.count(truthParticle->barcode()) > 0)
@@ -804,42 +859,42 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
         m_t_pT.push_back(truthParticle->p4().Pt());
         m_t_eta.push_back(truthParticle->p4().Eta());
       } else {
+        ATH_MSG_WARNING("Can not find truthParticle.");
         setNaN();
       }
     } else {
-      ATH_MSG_WARNING("Can not find truthParticle.");
       setNaN();
     }
 
-    // fill extrapolation vectors with filler values that get changed iif the track extrapolation succeeds
-    m_xVetoNu.push_back(-10000);
-    m_yVetoNu.push_back(-10000);
-    m_thetaxVetoNu.push_back(-10000);
-    m_thetayVetoNu.push_back(-10000);
-    m_xVetoStation1.push_back(-10000);
-    m_yVetoStation1.push_back(-10000);
-    m_thetaxVetoStation1.push_back(-10000);
-    m_thetayVetoStation1.push_back(-10000);
-    m_xVetoStation2.push_back(-10000);
-    m_yVetoStation2.push_back(-10000);
-    m_thetaxVetoStation2.push_back(-10000);
-    m_thetayVetoStation2.push_back(-10000);
-    m_xTrig.push_back(-10000);
-    m_yTrig.push_back(-10000);
-    m_thetaxTrig.push_back(-10000);
-    m_thetayTrig.push_back(-10000);
-    m_xPreshower1.push_back(-10000);
-    m_yPreshower1.push_back(-10000);
-    m_thetaxPreshower1.push_back(-10000);
-    m_thetayPreshower1.push_back(-10000);
-    m_xPreshower2.push_back(-10000);
-    m_yPreshower2.push_back(-10000);
-    m_thetaxPreshower2.push_back(-10000);
-    m_thetayPreshower2.push_back(-10000);
-    m_xCalo.push_back(-10000);
-    m_yCalo.push_back(-10000);
-    m_thetaxCalo.push_back(-10000);
-    m_thetayCalo.push_back(-10000);
+    // fill extrapolation vectors with NaN, will get set to real number if the track extrapolation succeeds
+    m_xVetoNu.push_back(NaN);
+    m_yVetoNu.push_back(NaN);
+    m_thetaxVetoNu.push_back(NaN);
+    m_thetayVetoNu.push_back(NaN);
+    m_xVetoStation1.push_back(NaN);
+    m_yVetoStation1.push_back(NaN);
+    m_thetaxVetoStation1.push_back(NaN);
+    m_thetayVetoStation1.push_back(NaN);
+    m_xVetoStation2.push_back(NaN);
+    m_yVetoStation2.push_back(NaN);
+    m_thetaxVetoStation2.push_back(NaN);
+    m_thetayVetoStation2.push_back(NaN);
+    m_xTrig.push_back(NaN);
+    m_yTrig.push_back(NaN);
+    m_thetaxTrig.push_back(NaN);
+    m_thetayTrig.push_back(NaN);
+    m_xPreshower1.push_back(NaN);
+    m_yPreshower1.push_back(NaN);
+    m_thetaxPreshower1.push_back(NaN);
+    m_thetayPreshower1.push_back(NaN);
+    m_xPreshower2.push_back(NaN);
+    m_yPreshower2.push_back(NaN);
+    m_thetaxPreshower2.push_back(NaN);
+    m_thetayPreshower2.push_back(NaN);
+    m_xCalo.push_back(NaN);
+    m_yCalo.push_back(NaN);
+    m_thetaxCalo.push_back(NaN);
+    m_thetayCalo.push_back(NaN);
 
     // extrapolate track from first station
     if (stationMap.count(1) > 0) { // extrapolation crashes if the track parameters are is too far away to extrapolate
@@ -966,7 +1021,7 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
     m_longTracks++;
   }
 
-  if (!realData) {
+  if (isMC) {
     for (auto &tp : truthParticleCount) {
       m_truthParticleBarcode.push_back(tp.first);
       m_truthParticleMatchedTracks.push_back(tp.second);
@@ -974,24 +1029,16 @@ StatusCode NtupleDumperAlg::execute(const EventContext &ctx) const
     }
   }
 
-  /*
-  // Here we apply the signal selection
-  // Very simple/unrealistic to start
-  if (m_vetoUpstream == 0 || m_vetoDownstream == 0 ||
-        m_triggerTotal == 0 ||
-        m_preshower0 == 0 || m_preshower1 == 0 ||
-        // m_ecalTotal == 0 ||
-        candidateParameters == nullptr)
-      return StatusCode::SUCCESS;
-  */
+  // finished processing event, now fill ntuple tree
   m_tree->Fill();
-
+  m_eventsPassed += 1;
   return StatusCode::SUCCESS;
 }
 
 
 StatusCode NtupleDumperAlg::finalize()
 {
+  ATH_MSG_INFO("Number of events passed Ntuple selectioon = " << m_eventsPassed);
   return StatusCode::SUCCESS;
 }
 
@@ -1004,10 +1051,24 @@ bool NtupleDumperAlg::waveformHitOK(const xAOD::WaveformHit* hit) const
 void
 NtupleDumperAlg::clearTree() const
 {
-  m_run_number = 0;
-  m_event_number = 0;
-  m_event_time = 0;
-  m_bcid = 0;
+  // set all float variables to NaN
+  // set all int variables to 999999 (can't set int to NaN, because NaN is a double)
+  // set all counter variables to zero
+  // set all trigger words to zero
+  m_run_number = 999999; 
+  m_event_number = 999999;
+  m_event_time = 999999;
+  m_bcid = 999999;
+
+  m_fillNumber = 999999;
+  m_betaStar = NaN;
+  m_crossingAngle = NaN;
+  m_distanceToCollidingBCID = 999999;
+  m_distanceToUnpairedB1 = 999999;
+  m_distanceToUnpairedB2 = 999999;
+  m_distanceToInboundB1 = 999999;
+  m_distanceToTrainStart = 999999;
+  m_distanceToPreviousColliding = 999999;
 
   m_tbp=0;
   m_tap=0;
@@ -1015,20 +1076,20 @@ NtupleDumperAlg::clearTree() const
   m_inputBitsNext=0;
 
   for(int ii=0;ii<15;ii++) {
-      m_wave_localtime[ii]=0;
-      m_wave_peak[ii]=0;
-      m_wave_width[ii]=0;
-      m_wave_charge[ii]=0;
-
-      m_wave_raw_peak[ii]=0;
-      m_wave_raw_charge[ii]=0;
-      m_wave_baseline_mean[ii]=0;
-      m_wave_baseline_rms[ii]=0;
-      m_wave_status[ii]=0;
-
-      m_calibrated_nMIP[ii]=0;
-      m_calibrated_E_dep[ii]=0;
-      m_calibrated_E_EM[ii]=0;
+      m_wave_localtime[ii]=NaN;
+      m_wave_peak[ii]=NaN;
+      m_wave_width[ii]=NaN;
+      m_wave_charge[ii]=NaN;
+
+      m_wave_raw_peak[ii]=NaN;
+      m_wave_raw_charge[ii]=NaN;
+      m_wave_baseline_mean[ii]=NaN;
+      m_wave_baseline_rms[ii]=NaN;
+      m_wave_status[ii]=1; // default = 1 means below threshold
+
+      m_calibrated_nMIP[ii]=NaN;
+      m_calibrated_E_dep[ii]=NaN;
+      m_calibrated_E_EM[ii]=NaN;
   }
 
   m_calo_total_nMIP=0;
diff --git a/PhysicsAnalysis/NtupleDumper/src/NtupleDumperAlg.h b/PhysicsAnalysis/NtupleDumper/src/NtupleDumperAlg.h
index 804396fbde42351d743cfb4371c446d90a7be2e8..5cc342021993ca07354e6a4924f7e5cfb07ae552 100644
--- a/PhysicsAnalysis/NtupleDumper/src/NtupleDumperAlg.h
+++ b/PhysicsAnalysis/NtupleDumper/src/NtupleDumperAlg.h
@@ -4,6 +4,7 @@
 #include "AthenaBaseComps/AthReentrantAlgorithm.h"
 #include "AthenaBaseComps/AthHistogramming.h"
 #include "TrkTrack/TrackCollection.h"
+#include "xAODFaserLHC/FaserLHCData.h"
 #include "xAODFaserTrigger/FaserTriggerData.h"
 #include "xAODFaserWaveform/WaveformHitContainer.h"
 #include "xAODFaserWaveform/WaveformHit.h"
@@ -62,6 +63,8 @@ private:
   SG::ReadHandleKey<xAOD::TruthParticleContainer> m_truthParticleContainer { this, "ParticleContainer", "TruthParticles", "Truth particle container name." };
   SG::ReadHandleKey<TrackerSimDataCollection> m_simDataCollection {this, "TrackerSimDataCollection", "SCT_SDO_Map"};
 
+  SG::ReadHandleKey<xAOD::FaserLHCData> m_lhcData {this, "FaserLHCDataKey", "FaserLHCData"};
+
   SG::ReadHandleKey<TrackCollection> m_trackCollection { this, "TrackCollection", "CKFTrackCollection", "Input track collection name" };
   SG::ReadHandleKey<TrackCollection> m_trackCollectionWithoutIFT { this, "TrackCollectionWithoutIFT", "CKFTrackCollectionWithoutIFT", "Input track collection name (without IFT)" };
   SG::ReadHandleKey<TrackCollection> m_trackSegmentCollection {this, "TrackSegmentCollection", "SegmentFit", "Input track segment collection name"};
@@ -115,6 +118,16 @@ private:
   mutable unsigned int m_event_time;
   mutable unsigned int m_bcid;
 
+  mutable unsigned int m_fillNumber;
+  mutable float m_betaStar;
+  mutable float m_crossingAngle;
+  mutable int m_distanceToCollidingBCID;
+  mutable int m_distanceToUnpairedB1;
+  mutable int m_distanceToUnpairedB2;
+  mutable int m_distanceToInboundB1;
+  mutable unsigned int m_distanceToTrainStart;
+  mutable unsigned int m_distanceToPreviousColliding;
+
   mutable unsigned int m_tbp;
   mutable unsigned int m_tap;
   mutable unsigned int m_inputBits;
@@ -142,7 +155,6 @@ private:
   mutable float m_preshower_total_nMIP;
   mutable float m_preshower_total_E_dep;
 
-
   mutable float m_Calo0_Edep;
   mutable float m_Calo1_Edep;
   mutable float m_Calo2_Edep;
@@ -291,6 +303,8 @@ private:
   mutable int    m_truthPdg;
   mutable double m_crossSection;
 
+  mutable int    m_eventsPassed = 0;
+
 };
 
 inline const ServiceHandle <ITHistSvc> &NtupleDumperAlg::histSvc() const {