From 4f35f2a8d844dcd8cb275fb0bc5bd0fe2d82b0ea Mon Sep 17 00:00:00 2001
From: Wouter Deconinck <wouter.deconinck@umanitoba.ca>
Date: Thu, 29 Jul 2021 04:37:46 +0000
Subject: [PATCH] Imaging cluster seeded tracking benchmark

---
 benchmarks/tracking/config.yml                |  18 +-
 .../options/imagingcluster_seeded_tracking.py | 179 ++++++++++++++++++
 .../tracking/run_tracking_benchmarks.py       |  11 +-
 3 files changed, 201 insertions(+), 7 deletions(-)
 create mode 100644 benchmarks/tracking/options/imagingcluster_seeded_tracking.py

diff --git a/benchmarks/tracking/config.yml b/benchmarks/tracking/config.yml
index 070ff3a8..7c902906 100644
--- a/benchmarks/tracking/config.yml
+++ b/benchmarks/tracking/config.yml
@@ -19,11 +19,25 @@ tracking_truth_init_electrons:
   stage: run
   timeout: 24 hours
   script:
-    - python benchmarks/tracking/run_tracking_benchmarks.py --nametag=electron --particle=electron --etamin=-3 --etamax=3 -n 100
+    - python benchmarks/tracking/run_tracking_benchmarks.py --options truth_seeded_tracking.py --nametag=truth_electron --particle=electron --etamin=-3 --etamax=3 -n 100
 
 tracking_truth_init_pions:
   extends: .rec_benchmark
   stage: run
   timeout: 24 hours
   script:
-    - python benchmarks/tracking/run_tracking_benchmarks.py --nametag=pion --particle=pion+ --etamin=-3 --etamax=3 -n 100
+    - python benchmarks/tracking/run_tracking_benchmarks.py --options truth_seeded_tracking.py --nametag=truth_pion --particle=pion+ --etamin=-3 --etamax=3 -n 100
+
+tracking_imclust_init_electrons:
+  extends: .rec_benchmark
+  stage: run
+  timeout: 24 hours
+  script:
+    - python benchmarks/tracking/run_tracking_benchmarks.py --options imagingcluster_seeded_tracking.py --nametag=imclust_electron --particle=electron --etamin=-3 --etamax=3 -n 100
+
+tracking_imclust_init_pions:
+  extends: .rec_benchmark
+  stage: run
+  timeout: 24 hours
+  script:
+    - python benchmarks/tracking/run_tracking_benchmarks.py --options imagingcluster_seeded_tracking.py --nametag=imclust_pion --particle=pion+ --etamin=-3 --etamax=3 -n 100
diff --git a/benchmarks/tracking/options/imagingcluster_seeded_tracking.py b/benchmarks/tracking/options/imagingcluster_seeded_tracking.py
new file mode 100644
index 00000000..f5a47fc0
--- /dev/null
+++ b/benchmarks/tracking/options/imagingcluster_seeded_tracking.py
@@ -0,0 +1,179 @@
+from Gaudi.Configuration import *
+
+from Configurables import ApplicationMgr, EICDataSvc, PodioOutput, GeoSvc
+from GaudiKernel.SystemOfUnits import MeV, GeV, mm, cm, mrad
+
+detector_name = str(os.environ.get("JUGGLER_DETECTOR", "athena"))
+detector_path = str(os.environ.get("JUGGLER_DETECTOR_PATH", "."))
+compact_path = str(os.environ.get("JUGGLER_COMPACT_PATH", "{}.xml".format(os.path.join(detector_path, detector_name))))
+
+# CAL reconstruction
+# get sampling fractions from system environment variable, 1.0 by default
+cb_ecal_sf = float(os.environ.get("CB_ECAL_SAMP_FRAC", 0.01324))
+
+# todo add checks
+input_sims = [f.strip() for f in str.split(os.environ["JUGGLER_SIM_FILE"], ",") if f.strip()]
+output_rec = str(os.environ["JUGGLER_REC_FILE"])
+n_events = int(os.environ["JUGGLER_N_EVENTS"])
+
+geo_service = GeoSvc("GeoSvc", detectors=[compact_path], OutputLevel=WARNING)
+podioevent = EICDataSvc("EventDataSvc", inputs=input_sims, OutputLevel=WARNING)
+
+from Configurables import PodioInput
+from Configurables import Jug__Digi__UFSDTrackerDigi as TrackerDigi
+from Configurables import Jug__Reco__TrackerHitReconstruction as TrackerReco
+
+from Configurables import Jug__Reco__TrackerSourceLinker as TrackerSourceLinker
+from Configurables import Jug__Reco__TrackerSourcesLinker as TrackerSourcesLinker
+#from Configurables import Jug__Reco__TrackingHitsSourceLinker as TrackingHitsSourceLinker
+from Configurables import Jug__Reco__TrackParamImagingClusterInit as TrackParamImagingClusterInit
+
+from Configurables import Jug__Reco__TrackFindingAlgorithm as TrackFindingAlgorithm
+from Configurables import Jug__Reco__ParticlesFromTrackFit as ParticlesFromTrackFit
+from Configurables import Jug__Base__InputCopier_dd4pod__Geant4ParticleCollection_dd4pod__Geant4ParticleCollection_ as MCCopier
+
+from Configurables import Jug__Digi__CalorimeterHitDigi as CalHitDigi
+from Configurables import Jug__Reco__ImagingPixelReco as ImCalPixelReco
+from Configurables import Jug__Reco__ImagingTopoCluster as ImagingCluster
+from Configurables import Jug__Reco__ImagingClusterReco as ImagingClusterReco
+
+
+sim_colls = [
+    "mcparticles",
+    "TrackerEndcapHits",
+    "TrackerBarrelHits",
+    "VertexBarrelHits",
+    "VertexEndcapHits",
+    "EcalBarrelHits"
+]
+podin = PodioInput("PodioReader", collections=sim_colls)
+podout = PodioOutput("out", filename=output_rec)
+
+## copiers to get around input --> output copy bug. Note the "2" appended to the output collection.
+mccopier = MCCopier("MCCopier",
+        inputCollection="mcparticles",
+        outputCollection="mcparticles2")
+
+trk_b_digi = TrackerDigi("trk_b_digi",
+        inputHitCollection="TrackerBarrelHits",
+        outputHitCollection="TrackerBarrelRawHits",
+        timeResolution=8)
+trk_ec_digi = TrackerDigi("trk_ec_digi",
+        inputHitCollection="TrackerEndcapHits",
+        outputHitCollection="TrackerEndcapRawHits",
+        timeResolution=8)
+
+vtx_b_digi = TrackerDigi("vtx_b_digi",
+        inputHitCollection="VertexBarrelHits",
+        outputHitCollection="VertexBarrelRawHits",
+        timeResolution=8)
+
+vtx_ec_digi = TrackerDigi("vtx_ec_digi",
+        inputHitCollection="VertexEndcapHits",
+        outputHitCollection="VertexEndcapRawHits",
+        timeResolution=8)
+
+# Tracker and vertex reconstruction
+trk_b_reco = TrackerReco("trk_b_reco",
+        inputHitCollection = trk_b_digi.outputHitCollection,
+        outputHitCollection="TrackerBarrelRecHits")
+
+trk_ec_reco = TrackerReco("trk_ec_reco",
+        inputHitCollection = trk_ec_digi.outputHitCollection,
+        outputHitCollection="TrackerEndcapRecHits")
+
+vtx_b_reco = TrackerReco("vtx_b_reco",
+        inputHitCollection = vtx_b_digi.outputHitCollection,
+        outputHitCollection="VertexBarrelRecHits")
+
+vtx_ec_reco = TrackerReco("vtx_ec_reco",
+        inputHitCollection = vtx_ec_digi.outputHitCollection,
+        outputHitCollection="VertexEndcapRecHits")
+
+sourcelinker = TrackerSourcesLinker("trk_srcslnkr",
+        inputHitCollections=["VertexBarrelRecHits", "TrackerBarrelRecHits"],
+        outputSourceLinks="TrackerSourceLinks",
+        outputMeasurements="TrackerMeasurements",
+        OutputLevel=DEBUG)
+
+# Central Barrel Ecal (Imaging Cal.)
+cb_ecal_daq = dict(
+        dynamicRangeADC=3*MeV,
+        capacityADC=8192,
+        pedestalMean=400,
+        pedestalSigma=20)   # about 6 keV
+
+cb_ecal_digi = CalHitDigi("cb_ecal_digi",
+        inputHitCollection="EcalBarrelHits",
+        outputHitCollection="EcalBarrelHitsDigi",
+        energyResolutions=[0., 0.02, 0.],   # 2% flat resolution
+        **cb_ecal_daq)
+
+cb_ecal_reco = ImCalPixelReco("cb_ecal_reco",
+        inputHitCollection="EcalBarrelHitsDigi",
+        outputHitCollection="EcalBarrelHitsReco",
+        thresholdFactor=3,  # about 20 keV
+        readoutClass="EcalBarrelHits",  # readout class
+        layerField="layer",             # field to get layer id
+        sectorField="module",           # field to get sector id
+        **cb_ecal_daq)
+
+cb_ecal_cl = ImagingCluster("cb_ecal_cl",
+        inputHitCollection="EcalBarrelHitsReco",
+        outputHitCollection="EcalBarrelClusterHits",
+        localDistXY=[2.*mm, 2*mm],  # same layer
+        layerDistEtaPhi=[10*mrad, 10*mrad],     # adjacent layer
+        neighbourLayersRange=2,                 # id diff for adjacent layer
+        sectorDist=3.*cm)                       # different sector
+
+cb_ecal_clreco = ImagingClusterReco("cb_ecal_clreco",
+        samplingFraction=cb_ecal_sf,
+        inputHitCollection="EcalBarrelClusterHits",
+        outputClusterCollection="EcalBarrelClusters",
+        outputLayerCollection="EcalBarrelLayers")
+
+## Track param init
+imclust_trk_init = TrackParamImagingClusterInit("imclust_trk_init",
+        inputClusters="EcalBarrelClusters",
+        outputInitialTrackParameters="InitTrackParams",
+        OutputLevel=DEBUG)
+
+# Tracking algorithms
+trk_find_alg = TrackFindingAlgorithm("trk_find_alg",
+        inputSourceLinks = sourcelinker.outputSourceLinks,
+        inputMeasurements = sourcelinker.outputMeasurements,
+        inputInitialTrackParameters= imclust_trk_init.outputInitialTrackParameters,
+        outputTrajectories="trajectories",
+        OutputLevel=DEBUG)
+
+parts_from_fit = ParticlesFromTrackFit("parts_from_fit",
+        inputTrajectories=trk_find_alg.outputTrajectories,
+        outputParticles="ReconstructedParticles",
+        outputTrackParameters="outputTrackParameters",
+        OutputLevel=DEBUG)
+
+podout.outputCommands = [
+    "keep *",
+    "drop InitTrackParams",
+    "drop trajectories",
+    "drop outputSourceLinks",
+    "drop outputInitialTrackParameters",
+    "drop mcparticles",
+]
+
+ApplicationMgr(
+    TopAlg = [podin, mccopier,
+              trk_b_digi, trk_ec_digi, vtx_b_digi, vtx_ec_digi,
+              trk_b_reco, trk_ec_reco, vtx_b_reco, vtx_ec_reco,
+              cb_ecal_digi, cb_ecal_reco, cb_ecal_cl, cb_ecal_clreco,
+              sourcelinker,
+              imclust_trk_init,
+              trk_find_alg, parts_from_fit,
+              podout
+              ],
+    EvtSel = 'NONE',
+    EvtMax   = n_events,
+    ExtSvc = [podioevent, geo_service],
+    OutputLevel=WARNING
+ )
+
diff --git a/benchmarks/tracking/run_tracking_benchmarks.py b/benchmarks/tracking/run_tracking_benchmarks.py
index 4929f0e6..cfe4f8ec 100755
--- a/benchmarks/tracking/run_tracking_benchmarks.py
+++ b/benchmarks/tracking/run_tracking_benchmarks.py
@@ -15,11 +15,6 @@ default_compact = os.path.join(
         os.environ.get('JUGGLER_DETECTOR_PATH',  os.environ.get('DETECTOR_PATH', '')),
         '{}.xml'.format(os.environ.get('JUGGLER_DETECTOR', '')))
 
-script_dir = os.path.dirname(os.path.realpath(__file__))
-gen_script = os.path.join(script_dir, 'scripts', 'gen_particles.py')
-option_script = os.path.join(script_dir, 'options', 'truth_seeded_tracking.py')
-analysis_script = os.path.join(script_dir, 'scripts', 'tracking_performance.py')
-
 parser = argparse.ArgumentParser()
 parser.add_argument('-n', '--numberOfEvents', dest='nev', type=int, default=100, help='Number of events to process.')
 parser.add_argument('-t', '--nametag', type=str, default='TRACKING', help='Name tag for output files.')
@@ -33,11 +28,17 @@ parser.add_argument('--etamax', type=float, default=4, help='Maximum pseudorapid
 parser.add_argument('--pmin', type=float, default=5.0, help='Minimum momentum of particles (GeV).')
 parser.add_argument('--pmax', type=float, default=5.0, help='Maximum momentum of particles (GeV).')
 parser.add_argument('--compact', type=str, default=default_compact, help='Path to detector compact file.')
+parser.add_argument('--options', type=str, default='truth_seeded_tracking.py', help='Path to reconstruction options script.')
 parser.add_argument('--uploadSizeLimit', type=float, default=10, help='Upper limit of file size (Mb) to be uploaded.')
 
 args = parser.parse_args()
 kwargs = vars(args)
 
+script_dir = os.path.dirname(os.path.realpath(__file__))
+gen_script = os.path.join(script_dir, 'scripts', 'gen_particles.py')
+option_script = os.path.join(script_dir, 'options', args.options)
+analysis_script = os.path.join(script_dir, 'scripts', 'tracking_performance.py')
+
 gen_file = 'gen_{nametag}_{pmin}_{pmax}.hepmc'.format(**kwargs)
 sim_file = 'sim_{nametag}_{pmin}_{pmax}.root'.format(**kwargs)
 rec_file = 'rec_{nametag}_{pmin}_{pmax}.root'.format(**kwargs)
-- 
GitLab