From e6639cae5aea94f484ec1c7d01f5e7042b7dae4e Mon Sep 17 00:00:00 2001 From: Wouter Deconinck <wouter.deconinck@umanitoba.ca> Date: Tue, 28 Sep 2021 17:44:17 +0000 Subject: [PATCH] ecal and hcal hits reconstruction --- benchmarks/dis/dis.sh | 21 ++-- benchmarks/dvcs/dvcs.sh | 9 +- benchmarks/dvmp/dvmp.sh | 22 ++--- benchmarks/u_omega/u_omega.sh | 9 +- options/reconstruction.ecal.py | 168 ++++++++++++++++++++++++++++++++ options/reconstruction.hcal.py | 170 +++++++++++++++++++++++++++++++++ 6 files changed, 370 insertions(+), 29 deletions(-) create mode 100644 options/reconstruction.ecal.py create mode 100644 options/reconstruction.hcal.py diff --git a/benchmarks/dis/dis.sh b/benchmarks/dis/dis.sh index a01af459..9ceb0de8 100755 --- a/benchmarks/dis/dis.sh +++ b/benchmarks/dis/dis.sh @@ -84,19 +84,16 @@ echo "Running the digitization and reconstruction" ## - JUGGLER_DETECTOR: detector package (part of global environment) export JUGGLER_SIM_FILE=${SIM_FILE} export JUGGLER_REC_FILE=${REC_FILE} -xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py options/reconstruction.py -## on-error, first retry running juggler again as there is still a random -## crash we need to address FIXME +for rec in options/*.py ; do + unset tag + [[ $(basename ${rec} .py) =~ (.*)\.(.*) ]] && tag=".${BASH_REMATCH[2]}" + JUGGLER_REC_FILE=${JUGGLER_REC_FILE/.root/${tag:-}.root} \ + xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ + gaudirun.py ${rec} +done if [ "$?" -ne "0" ] ; then - echo "Juggler crashed, retrying..." - xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py options/reconstruction.py \ - 2>&1 > ${REC_LOG} - if [ "$?" -ne "0" ] ; then - echo "ERROR running juggler, both attempts failed" - exit 1 - fi + echo "ERROR running juggler" + exit 1 fi ## ============================================================================= diff --git a/benchmarks/dvcs/dvcs.sh b/benchmarks/dvcs/dvcs.sh index 1dd20afb..7a47ac14 100644 --- a/benchmarks/dvcs/dvcs.sh +++ b/benchmarks/dvcs/dvcs.sh @@ -115,8 +115,13 @@ fi ### Step 3. Run the reconstruction (juggler) if [[ -n "${DO_REC}" || -n "${DO_ALL}" ]] ; then - xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py options/reconstruction.py + for rec in options/*.py ; do + unset tag + [[ $(basename ${rec} .py) =~ (.*)\.(.*) ]] && tag=".${BASH_REMATCH[2]}" + JUGGLER_REC_FILE=${JUGGLER_REC_FILE/.root/${tag:-}.root} \ + xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ + gaudirun.py ${rec} + done if [[ "$?" -ne "0" ]] ; then echo "ERROR running juggler" exit 1 diff --git a/benchmarks/dvmp/dvmp.sh b/benchmarks/dvmp/dvmp.sh index 58a289fb..e9d608e1 100755 --- a/benchmarks/dvmp/dvmp.sh +++ b/benchmarks/dvmp/dvmp.sh @@ -84,20 +84,16 @@ echo "Running the digitization and reconstruction" ## - JUGGLER_DETECTOR: detector package (part of global environment) export JUGGLER_SIM_FILE=${SIM_FILE} export JUGGLER_REC_FILE=${REC_FILE} -xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py options/reconstruction.py -## 2>&1 > ${REC_LOG} -## on-error, first retry running juggler again as there is still a random -## crash we need to address FIXME +for rec in options/*.py ; do + unset tag + [[ $(basename ${rec} .py) =~ (.*)\.(.*) ]] && tag=".${BASH_REMATCH[2]}" + JUGGLER_REC_FILE=${JUGGLER_REC_FILE/.root/${tag:-}.root} \ + xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ + gaudirun.py ${rec} +done if [ "$?" -ne "0" ] ; then - echo "Juggler crashed, retrying..." - xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py options/reconstruction.py \ - 2>&1 > ${REC_LOG} - if [ "$?" -ne "0" ] ; then - echo "ERROR running juggler, both attempts failed" - exit 1 - fi + echo "ERROR running juggler, both attempts failed" + exit 1 fi ## ============================================================================= diff --git a/benchmarks/u_omega/u_omega.sh b/benchmarks/u_omega/u_omega.sh index fa0f69bb..6d051589 100644 --- a/benchmarks/u_omega/u_omega.sh +++ b/benchmarks/u_omega/u_omega.sh @@ -114,8 +114,13 @@ fi ### Step 3. Run the reconstruction (juggler) if [[ -n "${DO_REC}" || -n "${DO_ALL}" ]] ; then - xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py options/reconstruction.py + for rec in options/*.py ; do + unset tag + [[ $(basename ${rec} .py) =~ (.*)\.(.*) ]] && tag=".${BASH_REMATCH[2]}" + JUGGLER_REC_FILE=${JUGGLER_REC_FILE/.root/${tag:-}.root} \ + xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ + gaudirun.py ${rec} + done if [[ "$?" -ne "0" ]] ; then echo "ERROR running juggler" exit 1 diff --git a/options/reconstruction.ecal.py b/options/reconstruction.ecal.py new file mode 100644 index 00000000..9407fae8 --- /dev/null +++ b/options/reconstruction.ecal.py @@ -0,0 +1,168 @@ +from Gaudi.Configuration import * + +from Configurables import ApplicationMgr, AuditorSvc, EICDataSvc, PodioOutput, GeoSvc +from GaudiKernel import SystemOfUnits as units +from GaudiKernel.SystemOfUnits import MeV, GeV, mm, cm, mrad + +import json + +detector_name = "athena" +if "JUGGLER_DETECTOR" in os.environ : + detector_name = str(os.environ["JUGGLER_DETECTOR"]) + +detector_path = "" +if "DETECTOR_PATH" in os.environ : + detector_path = str(os.environ["DETECTOR_PATH"]) + +compact_path = os.path.join(detector_path, detector_name) + +# CAL reconstruction +# get sampling fractions from system environment variable +ci_ecal_sf = float(os.environ.get("CI_ECAL_SAMP_FRAC", 0.253)) + +# input and output +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"]) + +# services +services = [] +# geometry service +services.append(GeoSvc("GeoSvc", detectors=["{}.xml".format(compact_path)], OutputLevel=WARNING)) +# data service +services.append(EICDataSvc("EventDataSvc", inputs=input_sims, OutputLevel=WARNING)) + +# juggler components +from Configurables import PodioInput +from Configurables import Jug__Digi__CalorimeterHitDigi as CalHitDigi +from Configurables import Jug__Reco__CalorimeterHitReco as CalHitReco +from Configurables import Jug__Reco__CalorimeterHitsMerger as CalHitsMerger +from Configurables import Jug__Reco__CalorimeterIslandCluster as IslandCluster +from Configurables import Jug__Reco__ClusterRecoCoG as RecoCoG + +# branches needed from simulation root file +sim_coll = [ + "mcparticles", + "EcalEndcapNHits", + "EcalEndcapPHits", +] + +# list of algorithms +algorithms = [] + +# input +podin = PodioInput("PodioReader", collections=sim_coll) +algorithms.append(podin) + +# Crystal Endcap Ecal +ce_ecal_daq = dict( + dynamicRangeADC=5.*units.GeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=3) + +ce_ecal_digi = CalHitDigi("ce_ecal_digi", + inputHitCollection="EcalEndcapNHits", + outputHitCollection="EcalEndcapNRawHits", + energyResolutions=[0., 0.02, 0.], + **ce_ecal_daq) +algorithms.append(ce_ecal_digi) + +ce_ecal_reco = CalHitReco("ce_ecal_reco", + inputHitCollection=ce_ecal_digi.outputHitCollection, + outputHitCollection="EcalEndcapNRecHits", + thresholdFactor=4, # 4 sigma cut on pedestal sigma + readoutClass="EcalEndcapNHits", + sectorField="sector", + **ce_ecal_daq) +algorithms.append(ce_ecal_reco) + +ce_ecal_cl = IslandCluster("ce_ecal_cl", + inputHitCollection=ce_ecal_reco.outputHitCollection, + outputProtoClusterCollection="EcalEndcapNProtoClusters", + splitCluster=False, + minClusterHitEdep=1.0*units.MeV, # discard low energy hits + minClusterCenterEdep=30*units.MeV, + sectorDist=5.0*units.cm, + dimScaledLocalDistXY=[1.8, 1.8]) # dimension scaled dist is good for hybrid sectors with different module size +algorithms.append(ce_ecal_cl) + +ce_ecal_clreco = RecoCoG("ce_ecal_clreco", + inputHitCollection=ce_ecal_cl.inputHitCollection, + inputProtoClusterCollection=ce_ecal_cl.outputProtoClusterCollection, + outputClusterCollection="EcalEndcapNClusters", + mcHits="EcalEndcapNHits", + samplingFraction=0.998, # this accounts for a small fraction of leakage + logWeightBase=4.6) +algorithms.append(ce_ecal_clreco) + +# Endcap Sampling Ecal +ci_ecal_daq = dict( + dynamicRangeADC=50.*units.MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10) + +ci_ecal_digi = CalHitDigi("ci_ecal_digi", + inputHitCollection="EcalEndcapPHits", + outputHitCollection="EcalEndcapPRawHits", + **ci_ecal_daq) +algorithms.append(ci_ecal_digi) + +ci_ecal_reco = CalHitReco("ci_ecal_reco", + inputHitCollection=ci_ecal_digi.outputHitCollection, + outputHitCollection="EcalEndcapPRecHits", + thresholdFactor=5.0, + **ci_ecal_daq) +algorithms.append(ci_ecal_reco) + +# merge hits in different layer (projection to local x-y plane) +ci_ecal_merger = CalHitsMerger("ci_ecal_merger", + inputHitCollection=ci_ecal_reco.outputHitCollection, + outputHitCollection="EcalEndcapPRecMergedHits", + fields=["fiber_x", "fiber_y"], + fieldRefNumbers=[1, 1], + # fields=["layer", "slice"], + # fieldRefNumbers=[1, 0], + readoutClass="EcalEndcapPHits") +algorithms.append(ci_ecal_merger) + +ci_ecal_cl = IslandCluster("ci_ecal_cl", + inputHitCollection=ci_ecal_merger.outputHitCollection, + outputProtoClusterCollection="EcalEndcapPProtoClusters", + splitCluster=False, + minClusterCenterEdep=10.*units.MeV, + localDistXY=[10*units.mm, 10*units.mm]) +algorithms.append(ci_ecal_cl) + +ci_ecal_clreco = RecoCoG("ci_ecal_clreco", + inputHitCollection=ci_ecal_cl.inputHitCollection, + inputProtoClusterCollection=ci_ecal_cl.outputProtoClusterCollection, + outputClusterCollection="EcalEndcapPClusters", + mcHits="EcalEndcapPHits", + logWeightBase=6.2, + samplingFraction=ci_ecal_sf) +algorithms.append(ci_ecal_clreco) + +# Output +podout = PodioOutput("out", filename=output_rec) +podout.outputCommands = [ + "keep *", + "drop *Hits", + "keep *RecHits", + "keep *Layers", + "keep *Clusters", + "drop *ProtoClusters", + "drop outputParticles", + "drop InitTrackParams", + ] + [ "drop " + c for c in sim_coll] +algorithms.append(podout) + +ApplicationMgr( + TopAlg = algorithms, + EvtSel = 'NONE', + EvtMax = n_events, + ExtSvc = services, + OutputLevel = WARNING, + AuditAlgorithms = True + ) diff --git a/options/reconstruction.hcal.py b/options/reconstruction.hcal.py new file mode 100644 index 00000000..0bf946c6 --- /dev/null +++ b/options/reconstruction.hcal.py @@ -0,0 +1,170 @@ +from Gaudi.Configuration import * + +from Configurables import ApplicationMgr, AuditorSvc, EICDataSvc, PodioOutput, GeoSvc +from GaudiKernel import SystemOfUnits as units +from GaudiKernel.SystemOfUnits import MeV, GeV, mm, cm, mrad + +import json + +detector_name = "athena" +if "JUGGLER_DETECTOR" in os.environ : + detector_name = str(os.environ["JUGGLER_DETECTOR"]) + +detector_path = "" +if "DETECTOR_PATH" in os.environ : + detector_path = str(os.environ["DETECTOR_PATH"]) + +compact_path = os.path.join(detector_path, detector_name) + +# CAL reconstruction +# get sampling fractions from system environment variable +cb_hcal_sf = float(os.environ.get("CB_HCAL_SAMP_FRAC", 0.038)) +ci_hcal_sf = float(os.environ.get("CI_HCAL_SAMP_FRAC", 0.025)) +ce_hcal_sf = float(os.environ.get("CE_HCAL_SAMP_FRAC", 0.025)) + +# input and output +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"]) + +# services +services = [] +# geometry service +services.append(GeoSvc("GeoSvc", detectors=["{}.xml".format(compact_path)], OutputLevel=WARNING)) +# data service +services.append(EICDataSvc("EventDataSvc", inputs=input_sims, OutputLevel=WARNING)) + +# juggler components +from Configurables import PodioInput +from Configurables import Jug__Digi__CalorimeterHitDigi as CalHitDigi +from Configurables import Jug__Reco__CalorimeterHitReco as CalHitReco +from Configurables import Jug__Reco__CalorimeterHitsMerger as CalHitsMerger +from Configurables import Jug__Reco__CalorimeterIslandCluster as IslandCluster +from Configurables import Jug__Reco__ClusterRecoCoG as RecoCoG + +# branches needed from simulation root file +sim_coll = [ + "mcparticles", + "HcalEndcapPHits", + "HcalEndcapNHits", +] + +# list of algorithms +algorithms = [] + +# input +podin = PodioInput("PodioReader", collections=sim_coll) +algorithms.append(podin) + +# Hcal Hadron Endcap +ci_hcal_daq = dict( + dynamicRangeADC=50.*units.MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10) + +ci_hcal_digi = CalHitDigi("ci_hcal_digi", + inputHitCollection="HcalEndcapPHits", + outputHitCollection="HcalEndcapPRawHits", + **ci_hcal_daq) +algorithms.append(ci_hcal_digi) + +ci_hcal_reco = CalHitReco("ci_hcal_reco", + inputHitCollection=ci_hcal_digi.outputHitCollection, + outputHitCollection="HcalEndcapPRecHits", + thresholdFactor=5.0, + **ci_hcal_daq) +algorithms.append(ci_hcal_reco) + +ci_hcal_merger = CalHitsMerger("ci_hcal_merger", + inputHitCollection=ci_hcal_reco.outputHitCollection, + outputHitCollection="HcalEndcapPMergedHits", + readoutClass="HcalEndcapPHits", + fields=["layer", "slice"], + fieldRefNumbers=[1, 0]) +algorithms.append(ci_hcal_merger) + +ci_hcal_cl = IslandCluster("ci_hcal_cl", + inputHitCollection=ci_hcal_merger.outputHitCollection, + outputProtoClusterCollection="HcalEndcapPProtoClusters", + splitCluster=False, + minClusterCenterEdep=30.*units.MeV, + localDistXY=[15.*units.cm, 15.*units.cm]) +algorithms.append(ci_hcal_cl) + +ci_hcal_clreco = RecoCoG("ci_hcal_clreco", + inputHitCollection=ci_hcal_cl.inputHitCollection, + inputProtoClusterCollection=ci_hcal_cl.outputProtoClusterCollection, + outputClusterCollection="HcalEndcapPClusters", + mcHits="HcalEndcapPHits", + logWeightBase=6.2, + samplingFraction=ci_hcal_sf) +algorithms.append(ci_hcal_clreco) + +# Hcal Electron Endcap +ce_hcal_daq = dict( + dynamicRangeADC=50.*units.MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10) + +ce_hcal_digi = CalHitDigi("ce_hcal_digi", + inputHitCollection="HcalEndcapNHits", + outputHitCollection="HcalEndcapNRawHits", + **ce_hcal_daq) +algorithms.append(ce_hcal_digi) + +ce_hcal_reco = CalHitReco("ce_hcal_reco", + inputHitCollection=ce_hcal_digi.outputHitCollection, + outputHitCollection="HcalEndcapNRecHits", + thresholdFactor=5.0, + **ce_hcal_daq) +algorithms.append(ce_hcal_reco) + +ce_hcal_merger = CalHitsMerger("ce_hcal_merger", + inputHitCollection=ce_hcal_reco.outputHitCollection, + outputHitCollection="HcalEndcapNMergedHits", + readoutClass="HcalEndcapNHits", + fields=["layer", "slice"], + fieldRefNumbers=[1, 0]) +algorithms.append(ce_hcal_merger) + +ce_hcal_cl = IslandCluster("ce_hcal_cl", + inputHitCollection=ce_hcal_merger.outputHitCollection, + outputProtoClusterCollection="HcalEndcapNProtoClusters", + splitCluster=False, + minClusterCenterEdep=30.*units.MeV, + localDistXY=[15.*units.cm, 15.*units.cm]) +algorithms.append(ce_hcal_cl) + +ce_hcal_clreco = RecoCoG("ce_hcal_clreco", + inputHitCollection=ce_hcal_cl.inputHitCollection, + inputProtoClusterCollection=ce_hcal_cl.outputProtoClusterCollection, + outputClusterCollection="HcalEndcapNClusters", + mcHits="HcalEndcapNHits", + logWeightBase=6.2, + samplingFraction=ce_hcal_sf) +algorithms.append(ce_hcal_clreco) + +# Output +podout = PodioOutput("out", filename=output_rec) +podout.outputCommands = [ + "keep *", + "drop *Hits", + "keep *RecHits", + "keep *Layers", + "keep *Clusters", + "drop *ProtoClusters", + "drop outputParticles", + "drop InitTrackParams", + ] + [ "drop " + c for c in sim_coll] +algorithms.append(podout) + +ApplicationMgr( + TopAlg = algorithms, + EvtSel = 'NONE', + EvtMax = n_events, + ExtSvc = services, + OutputLevel = WARNING, + AuditAlgorithms = True + ) -- GitLab