diff --git a/Control/CalypsoExample/Digitization/CMakeLists.txt b/Control/CalypsoExample/Digitization/CMakeLists.txt
index f8caebb598f6cea848edafea449a0bd19e657c6d..bf7afee06a4381117ab59b11b1a2d4d3f92df5b9 100644
--- a/Control/CalypsoExample/Digitization/CMakeLists.txt
+++ b/Control/CalypsoExample/Digitization/CMakeLists.txt
@@ -5,22 +5,11 @@
 # Declare the package name:
 atlas_subdir( Digitization )
 
-# Component(s) in the package:
-#atlas_add_component( GeoModelTest
-#                     src/GeoModelTestAlg.cxx
-#                     src/components/GeoModelTest_entries.cxx
-#                     INCLUDE_DIRS ${GEOMODEL_INCLUDE_DIRS}
-#                     LINK_LIBRARIES ${GEOMODEL_LIBRARIES} AthenaBaseComps GeoModelFaserUtilities ScintReadoutGeometry TrackerReadoutGeometry MagFieldInterfaces MagFieldElements MagFieldConditions )
-
 # Install files from the package:
-#atlas_install_joboptions( share/*.py )
-#atlas_install_python_modules( python/*.py )
 atlas_install_scripts( scripts/*.sh scripts/*.py )
 
-#atlas_add_test( ProdRecoTI12
-#    SCRIPT scripts/faser_reco.py ${CMAKE_CURRENT_SOURCE_DIR}/../rawdata/Faser-Physics-001920-filtered.raw TI12Data
-#    PROPERTIES TIMEOUT 300 )
-#atlas_add_test( ProdRecoTestBeam
-#    SCRIPT scripts/faser_reco.py ${CMAKE_CURRENT_SOURCE_DIR}/../RAWDATA/Faser-Physics-003613-filtered.raw TestBeamData
-#    PROPERTIES TIMEOUT 300 )
+atlas_add_test( ProdDigi
+    SCRIPT scripts/faser_digi.py ${CMAKE_CURRENT_SOURCE_DIR}/../rawdata/FaserMC-MC22_PG_muon_fasernu_100GeV-100012-00000-HITS.root
+    PROPERTIES TIMEOUT 300 )
+
 
diff --git a/Control/CalypsoExample/Digitization/scripts/submit_faser_digi.sh b/Control/CalypsoExample/Digitization/scripts/submit_faser_digi.sh
index 76abf8172614a17a1f3290f45896f1c6978b5439..aac6abcf2928e78c4995f290e95a217686b23514 100644
--- a/Control/CalypsoExample/Digitization/scripts/submit_faser_digi.sh
+++ b/Control/CalypsoExample/Digitization/scripts/submit_faser_digi.sh
@@ -136,7 +136,7 @@ source run/setup.sh
 #
 # Try to find a release tag
 cd calypso
-recotag=`git describe`
+recotag=`git describe --tags`
 if [[ "$recotag" == "reco/r"???? ]]; then
   tag=`echo "$recotag" | cut -c 6-11`
   echo "Found reco tag: $tag"
diff --git a/Control/CalypsoExample/Digitization/scripts/submit_faser_digi_merge.sh b/Control/CalypsoExample/Digitization/scripts/submit_faser_digi_merge.sh
index fd2fe20e2d5f3b5829a6f57dbb83d9a6480ab6b6..20812091b8555717cf73bb673a58406ec8bef302 100755
--- a/Control/CalypsoExample/Digitization/scripts/submit_faser_digi_merge.sh
+++ b/Control/CalypsoExample/Digitization/scripts/submit_faser_digi_merge.sh
@@ -170,7 +170,7 @@ source run/setup.sh
 #
 # Try to find a release tag
 cd calypso
-recotag=`git describe`
+recotag=`git describe --tags`
 if [[ "$recotag" == "reco/r"???? ]]; then
   tag=`echo "$recotag" | cut -c 6-11`
   echo "Found reco tag: $tag"
diff --git a/Control/CalypsoExample/Generation/scripts/submit_faser_particlegun.sh b/Control/CalypsoExample/Generation/scripts/submit_faser_particlegun.sh
index ec13600f7a94ce8f1958652f83a6e36f72b4563f..44870497ad9e03c85fd7ac5b6a37c8d23a972e5d 100755
--- a/Control/CalypsoExample/Generation/scripts/submit_faser_particlegun.sh
+++ b/Control/CalypsoExample/Generation/scripts/submit_faser_particlegun.sh
@@ -145,7 +145,7 @@ source build/x86*/setup.sh
 #
 # Try to find a release tag
 cd calypso
-gentag=`git describe`
+gentag=`git describe --tags`
 if [[ "$gentag" == "gen/g"???? ]]; then
   tag=`echo "$gentag" | cut -c 5-10`
   echo "Found gen tag: $tag"
diff --git a/Control/CalypsoExample/NeutrinoHits/CMakeLists.txt b/Control/CalypsoExample/NeutrinoHits/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..299a9213811b1c6e6b94d44f4d6d70c661f1533a
--- /dev/null
+++ b/Control/CalypsoExample/NeutrinoHits/CMakeLists.txt
@@ -0,0 +1,14 @@
+################################################################################
+# Package: NeutrinoHits
+################################################################################
+
+# Declare the package name:
+atlas_subdir( NeutrinoHits )
+
+# Install files from the package:
+atlas_install_scripts( scripts/*.sh scripts/*.py )
+
+atlas_add_test( ProdNeutrinoHits
+    SCRIPT scripts/faser_dumpnu.py ${CMAKE_CURRENT_SOURCE_DIR}/../rawdata/FaserMC-MC22_PG_muon_fasernu_100GeV-100012-00000-HITS.root
+    PROPERTIES TIMEOUT 300 )
+
diff --git a/Control/CalypsoExample/NeutrinoHits/scripts/faser_dumpnu.py b/Control/CalypsoExample/NeutrinoHits/scripts/faser_dumpnu.py
new file mode 100755
index 0000000000000000000000000000000000000000..1b9d0f36b43a3780c8dfcaf9fa35d48251d689c8
--- /dev/null
+++ b/Control/CalypsoExample/NeutrinoHits/scripts/faser_dumpnu.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Run with:
+# ./faser_dumpnu.py filepath 
+# 
+# filepath - fully qualified path, including url if needed, to the input HITS file
+#   example: "root://eospublic.cern.ch//eos/experiment/faser/sim/GeniePilot/HITS/1/faser.150fbInv.1.001.HITS.pool.root"
+# 
+# Options:
+#
+import sys
+import time
+import argparse
+
+a = time.time()
+
+parser = argparse.ArgumentParser(description="Run FASER NeutrinoRecAlgs")
+
+parser.add_argument("file_path",
+                    help="Fully qualified path of the raw input file")
+parser.add_argument("-t", "--tag", default="",
+                    help="Specify digi tag (to append to output filename)")
+parser.add_argument("-n", "--nevts", type=int, default=-1,
+                    help="Specify number of events to process (default: all)")
+parser.add_argument("-v", "--verbose", action='store_true', 
+                    help="Turn on DEBUG output")
+
+args = parser.parse_args()
+
+from pathlib import Path
+
+filepath=Path(args.file_path)
+
+print(f"Starting processing of {filepath.name}")
+if args.nevts > 0:
+    print(f"Processing {args.nevts} events by command-line option")
+
+# Start ntuple dumping
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+from AthenaCommon.Constants import VERBOSE, INFO
+
+from AthenaCommon.Configurable import Configurable
+from CalypsoConfiguration.AllConfigFlags import ConfigFlags
+
+Configurable.configurableRun3Behavior = True
+    
+# Flags for this job
+ConfigFlags.Input.isMC = True                    # Needed to bypass autoconfig
+ConfigFlags.IOVDb.DatabaseInstance = "OFLP200"   # Use MC conditions for now
+
+ConfigFlags.Input.ProjectName = "mc20"
+ConfigFlags.GeoModel.Align.Dynamic    = False
+ConfigFlags.Beam.NumberOfCollisions = 0.
+
+ConfigFlags.GeoModel.FaserVersion = "FASERNU-03" 
+ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-03"
+
+ConfigFlags.Detector.GeometryEmulsion = True
+ConfigFlags.Detector.GeometryTrench   = True
+
+# Must use original input string here, as pathlib mangles double // in path names
+ConfigFlags.Input.Files = [ args.file_path ]
+
+filestem = filepath.stem
+# Remove any filetype modifier
+if filestem[-5:] == "-HITS":
+    filestem = filestem[:-5]
+
+if len(args.tag) > 0:
+    print(f"{args.tag} in {filestem}?")
+    if args.tag in filestem:
+        print(f"Not adding tag {args.tag} to file {filestem}")
+    else:
+        filestem += f"-{args.tag}"
+
+outfile = f"{filestem}-NTUP.root"
+print(f'Writing output file {outfile}')
+
+ConfigFlags.lock()
+
+#
+# Configure components
+from CalypsoConfiguration.MainServicesConfig import MainServicesCfg
+from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
+    
+acc = MainServicesCfg(ConfigFlags)
+acc.merge(PoolReadCfg(ConfigFlags))
+
+# Algorithm
+from NeutrinoRecAlgs.NeutrinoRecAlgsConfig import NeutrinoRecAlgsCfg 
+acc.merge(NeutrinoRecAlgsCfg(ConfigFlags, McEventCollection = "TruthEvent", OutputFile=outfile))
+
+# Configure verbosity    
+if args.verbose:
+    acc.foreach_component("*").OutputLevel = VERBOSE
+    ConfigFlags.dump()
+
+else:
+    acc.foreach_component("*").OutputLevel = INFO
+
+acc.foreach_component("*ClassID*").OutputLevel = INFO
+
+acc.getService("MessageSvc").Format = "% F%40W%S%7W%R%T %0W%M"
+
+# Execute and finish
+sc = acc.run(maxEvents=args.nevts)
+
+b = time.time()
+from AthenaCommon.Logging import log
+log.info(f"Finish execution in {b-a} seconds")
+
+sys.exit(not sc.isSuccess())
diff --git a/Control/CalypsoExample/NeutrinoHits/scripts/submit_faser_dumpnu.sh b/Control/CalypsoExample/NeutrinoHits/scripts/submit_faser_dumpnu.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c6333c1c2c02e899ab0d216278313d00a247af21
--- /dev/null
+++ b/Control/CalypsoExample/NeutrinoHits/scripts/submit_faser_dumpnu.sh
@@ -0,0 +1,193 @@
+#!/bin/bash
+# Used with a condor file to submit to vanilla universe
+#
+# Usage:
+# submit_faser_dumpnu.sh filepath [release_directory] [working_directory]
+#
+# Options:
+#   --out - specify output location (in EOS) to copy output HITS file
+#   --log - specify output location (in EOS) for log file
+# 
+# filepath - full file name (with path)
+# release_directory - optional path to release install directory (default pwd)
+# working_directory - optional path to output directory location (default pwd)
+#
+# The release directory must already be set up 
+# (so an unqualified asetup can set up the release properly)
+#
+# Script will use git describe to find the release tag.  
+# If this matches sim/s???? or digi/d???? it will be passed to the job
+#
+#----------------------------------------
+# Keep track of time
+SECONDS=0
+#
+# Parse command-line options
+while [ -n "$1" ]
+do 
+  case "$1" in
+      -l | --log)
+	  logdest="$2";
+	  shift;
+	  shift;; # Must eat 2 options here
+
+      -o | --out)
+	  outdest="$2";
+	  shift;
+	  shift;;
+
+      --) # End of options
+	  shift; # Eat this
+	  break;; # And stop parsing
+
+    -*) 
+	  echo "Unknown option $1"
+	  shift;;
+
+    *) break;;  # Not an option, don't shift
+  esac
+done
+#
+# Parse command-line options
+file_path=${1}
+release_directory=${2}
+working_directory=${3}
+#
+# Set defaults if arguments aren't provided
+if [ -z "$file_path" ]
+then
+  echo "No file specified!"
+  echo "Usage: submit_faser_dumpnu.sh file [release dir] [output dir]"
+  exit 1
+fi
+#
+if [ -z "$release_directory" ]
+then
+  release_directory=`pwd`
+fi
+#
+if [ -z "$working_directory" ]
+then
+  working_directory=`pwd`
+fi
+#
+starting_directory=`pwd`
+#
+# Now extract the run number and file stem
+#
+# First, get the filename
+file_name=$(basename "$file_path")
+# 
+# Now split based on '.' to get stem
+defaultIFS=$IFS
+IFS='.'
+read file_stem ext <<< "$file_name"
+#
+# Finally extract the run number
+IFS='-'
+# Read the split words into an array based on delimiter
+read faser short run_number segment <<< "$file_stem"
+#
+# Set the IFS delimeter back or else echo doesn't work...
+IFS=$defaultIFS
+#
+# Make output directory if needed
+output_directory="$working_directory/$run_number"
+mkdir -p "$output_directory"
+#
+# This magic redirects everything in this script to our log file
+logfile="${file_stem}.ntp.log"
+exec >& "${output_directory}/${logfile}"
+echo `date` - $HOSTNAME
+echo "File: $file_name"
+echo "Release: $release_directory"
+echo "Output: $output_directory"
+echo "Starting: $starting_directory"
+#
+# Set up the release (do this automatically)?
+export ATLAS_LOCAL_ROOT_BASE=/cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase
+source ${ATLAS_LOCAL_ROOT_BASE}/user/atlasLocalSetup.sh 
+#
+# Always go back to the starting directory in case paths are relative
+cd "$starting_directory"
+cd "$release_directory"
+#
+# Do this by hand
+asetup --input=calypso/asetup.faser Athena,22.0.49
+source run/setup.sh
+#
+# Try to find a release tag
+cd calypso
+recotag=`git describe --tags`
+if [[ "$recotag" == "reco/r"???? ]]; then
+  tag=`echo "$recotag" | cut -c 6-11`
+  echo "Found reco tag: $tag"
+fi
+if [[ "$recotag" == "digi/d"???? ]]; then
+  tag=`echo "$recotag" | cut -c 6-11`
+  echo "Found digi tag: $tag"
+fi
+if [[ "$recotag" == "sim/s"???? ]]; then
+  tag=`echo "$recotag" | cut -c 5-10`
+  echo "Found sim tag: $tag"
+fi
+#
+if [[ -z "$tag" ]]; then
+    tagstr=""
+else
+    tagstr="--tag $tag"
+fi
+#
+# Move to the run directory
+cd "$starting_directory"
+cd "$output_directory"
+#
+# Remove any previous directory if it exists
+#if [[ -e "$file_stem" ]]; then
+#    echo "Remove previous directory $file_stem"
+#    rm -rf "$file_stem"
+#fi
+#
+# Make run directory
+if [[ -e "$file_stem" ]]; then
+    echo "Directory $file_stem already exists"
+else
+    mkdir "$file_stem"
+fi
+cd "$file_stem"
+#
+# Run job
+#
+faser_dumpnu.py $tagstr "$file_path"
+#
+# Print out ending time
+date
+echo "Job finished after $SECONDS seconds"
+# 
+# Copy output to EOS if desired
+export EOS_MGM_URL=root://eospublic.cern.ch
+#
+if ! [ -z "$outdest" ]
+then
+    ls -l
+    echo "copy *-NTUP.root to $outdest"
+    mkdir -p $outdest
+    eos cp *-NTUP.root ${outdest}/ || true
+fi
+#
+# Also copy log file
+if ! [ -z "$logdest" ]
+then
+    cd ..
+    ls -l
+    echo "copy $logfile to $logdest"
+    mkdir -p $logdest
+    eos cp $logfile $logdest/$logfile
+elif ! [ -z "$outdest" ]
+then 
+    cd ..
+    ls -l
+    echo "copy $logfile to $outdest"
+    mkdir -p $outdest
+    eos cp $logfile $outdest/$logfile
+fi
diff --git a/Control/CalypsoExample/Reconstruction/scripts/submit_faser_reco.sh b/Control/CalypsoExample/Reconstruction/scripts/submit_faser_reco.sh
index 6924506133cddacd3ad7f4f88aec64121719b9b8..2734d8e9df3a48f5026edd7cafb43579903924e1 100755
--- a/Control/CalypsoExample/Reconstruction/scripts/submit_faser_reco.sh
+++ b/Control/CalypsoExample/Reconstruction/scripts/submit_faser_reco.sh
@@ -141,7 +141,7 @@ source run/setup.sh
 #
 # Try to find a release tag
 cd calypso
-recotag=`git describe`
+recotag=`git describe --tags`
 if [[ "$recotag" == "reco/r"???? ]]; then
   tag=`echo "$recotag" | cut -c 6-11`
   echo "Found reco tag: $tag"
diff --git a/Neutrino/NeutrinoRecAlgs/python/NeutrinoRecAlgsConfig.py b/Neutrino/NeutrinoRecAlgs/python/NeutrinoRecAlgsConfig.py
index 9a9fd9327209aa4f205c93ed1c67810ad793f78b..de1dcdf9a5e8a92f7e68778ba4a5e23761096fee 100644
--- a/Neutrino/NeutrinoRecAlgs/python/NeutrinoRecAlgsConfig.py
+++ b/Neutrino/NeutrinoRecAlgs/python/NeutrinoRecAlgsConfig.py
@@ -11,13 +11,16 @@ def NeutrinoRecAlgsCfg(flags, name="NeutrinoRecAlgs", **kwargs):
     from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg
     a = FaserGeometryCfg(flags)
 
+    # Get the output filename
+    outfile = kwargs.pop("OutputFile", 'myHistoFile.root')
+
     # Configure the algorithm itself
     NeutrinoRecAlgs = CompFactory.NeutrinoRecAlgs
     a.addEventAlgo(NeutrinoRecAlgs(name, **kwargs))
 
     # Set up histogramming
     thistSvc = CompFactory.THistSvc()
-    thistSvc.Output += ["HIST DATAFILE='myHistoFile.root' OPT='RECREATE'"]
+    thistSvc.Output += [f"HIST DATAFILE='{outfile}' OPT='RECREATE'"]
     a.addService(thistSvc)
 
     return a