From 88bbb45318a5486a986c6d93f8b4fbd6be4dea75 Mon Sep 17 00:00:00 2001 From: Chao Peng <cpeng@anl.gov> Date: Fri, 18 Jun 2021 01:23:49 +0000 Subject: [PATCH] split clustering script to two: digi and clustering --- benchmarks/clustering/full_cal_clusters.sh | 63 ++-- .../clustering/options/full_cal_clustering.py | 307 ------------------ .../clustering/options/full_cal_clusters.py | 201 ++++++++++++ .../clustering/options/full_cal_digi.py | 188 +++++++++++ .../clustering/scripts/cluster_plots.py | 24 +- 5 files changed, 440 insertions(+), 343 deletions(-) delete mode 100644 benchmarks/clustering/options/full_cal_clustering.py create mode 100644 benchmarks/clustering/options/full_cal_clusters.py create mode 100644 benchmarks/clustering/options/full_cal_digi.py diff --git a/benchmarks/clustering/full_cal_clusters.sh b/benchmarks/clustering/full_cal_clusters.sh index 54498afd..220a6360 100644 --- a/benchmarks/clustering/full_cal_clusters.sh +++ b/benchmarks/clustering/full_cal_clusters.sh @@ -35,7 +35,7 @@ do shift # past value ;; -n|--nevents) - export FULL_CAL_NUMEV="$2" + export JUGGLER_N_EVENTS="$2" shift # past argument shift # past value ;; @@ -59,31 +59,32 @@ do done set -- "${POSITIONAL[@]}" # restore positional parameters -export FULL_CAL_COMPACT_PATH=${DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml +export JUGGLER_COMPACT_PATH=${DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml -if [[ ! -n "${FULL_CAL_NUMEV}" ]] ; then - export FULL_CAL_NUMEV=1000 +if [[ ! -n "${JUGGLER_N_EVENTS}" ]] ; then + export JUGGLER_N_EVENTS=1000 fi if [[ ! -n "${FULL_CAL_PMIN}" ]] ; then - export FULL_CAL_ENERGY=1.0 + export FULL_CAL_PMIN=1.0 fi if [[ ! -n "${FULL_CAL_PMAX}" ]] ; then - export FULL_CAL_ENERGY=10.0 + export FULL_CAL_PMIN=10.0 fi -export FULL_CAL_NAME_TAG="${nametag}" -export FULL_CAL_GEN_FILE="${FULL_CAL_NAME_TAG}.hepmc" +export JUGGLER_FILE_NAME_TAG="${nametag}" +export JUGGLER_GEN_FILE="gen_${JUGGLER_FILE_NAME_TAG}.hepmc" -export FULL_CAL_SIM_FILE="sim_${FULL_CAL_NAME_TAG}.root" -export FULL_CAL_REC_FILE="rec_${FULL_CAL_NAME_TAG}.root" +export JUGGLER_SIM_FILE="sim_${JUGGLER_FILE_NAME_TAG}.root" +export JUGGLER_DIGI_FILE="digi_${JUGGLER_FILE_NAME_TAG}.root" +export JUGGLER_REC_FILE="rec_${JUGGLER_FILE_NAME_TAG}.root" -echo "FULL_CAL_NUMEV = ${FULL_CAL_NUMEV}" -echo "FULL_CAL_COMPACT_PATH = ${FULL_CAL_COMPACT_PATH}" +echo "JUGGLER_N_EVENTS = ${JUGGLER_N_EVENTS}" +echo "JUGGLER_COMPACT_PATH = ${JUGGLER_COMPACT_PATH}" # Generate the input events -python benchmarks/imaging_ecal/scripts/gen_particles.py ${FULL_CAL_GEN_FILE} -n ${FULL_CAL_NUMEV}\ +python benchmarks/imaging_ecal/scripts/gen_particles.py ${JUGGLER_GEN_FILE} -n ${JUGGLER_N_EVENTS}\ --angmin 5 --angmax 175 --phmin 0 --phmax 360 --pmin ${FULL_CAL_PMIN} --pmax ${FULL_CAL_PMAX}\ --particles="${particle}" @@ -92,23 +93,23 @@ if [[ "$?" -ne "0" ]] ; then exit 1 fi -ls -lh ${FULL_CAL_GEN_FILE} +ls -lh ${JUGGLER_GEN_FILE} # Run geant4 simulations npsim --runType batch \ -v WARNING \ --part.minimalKineticEnergy "1*TeV" \ - --numberOfEvents ${FULL_CAL_NUMEV} \ - --compactFile ${FULL_CAL_COMPACT_PATH} \ - --inputFiles ${FULL_CAL_GEN_FILE} \ - --outputFile ${FULL_CAL_SIM_FILE} + --numberOfEvents ${JUGGLER_N_EVENTS} \ + --compactFile ${JUGGLER_COMPACT_PATH} \ + --inputFiles ${JUGGLER_GEN_FILE} \ + --outputFile ${JUGGLER_SIM_FILE} if [[ "$?" -ne "0" ]] ; then echo "ERROR running npdet" exit 1 fi -rootls -t "${FULL_CAL_SIM_FILE}" +rootls -t "${JUGGLER_SIM_FILE}" # Directory for results mkdir -p results @@ -117,21 +118,31 @@ FULL_CAL_OPTION_DIR=benchmarks/clustering/options FULL_CAL_SCRIPT_DIR=benchmarks/clustering/scripts # Run Juggler +# Digitization xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py ${FULL_CAL_OPTION_DIR}/full_cal_clustering.py + gaudirun.py ${FULL_CAL_OPTION_DIR}/full_cal_digi.py if [[ "$?" -ne "0" ]] ; then - echo "ERROR running juggler" + echo "ERROR running digitization (juggler)" exit 1 fi -# run analysis scripts -python ${FULL_CAL_SCRIPT_DIR}/cluster_plots.py ${FULL_CAL_REC_FILE} -o results +# Clustering +xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ + gaudirun.py ${FULL_CAL_OPTION_DIR}/full_cal_clusters.py +if [[ "$?" -ne "0" ]] ; then + echo "ERROR running clustering (juggler)" + exit 1 +fi + + +# Run analysis scripts +python ${FULL_CAL_SCRIPT_DIR}/cluster_plots.py ${JUGGLER_SIM_FILE} ${JUGGLER_REC_FILE} -o results -root_filesize=$(stat --format=%s "${FULL_CAL_REC_FILE}") -if [[ "${FULL_CAL_NUMEV}" -lt "500" ]] ; then +root_filesize=$(stat --format=%s "${JUGGLER_REC_FILE}") +if [[ "${JUGGLER_N_EVENTS}" -lt "500" ]] ; then # file must be less than 10 MB to upload if [[ "${root_filesize}" -lt "10000000" ]] ; then - cp ${FULL_CAL_REC_FILE} results/. + cp ${JUGGLER_REC_FILE} results/. fi fi diff --git a/benchmarks/clustering/options/full_cal_clustering.py b/benchmarks/clustering/options/full_cal_clustering.py deleted file mode 100644 index 13647aa7..00000000 --- a/benchmarks/clustering/options/full_cal_clustering.py +++ /dev/null @@ -1,307 +0,0 @@ -from Gaudi.Configuration import * -import os -import ROOT - -from GaudiKernel.DataObjectHandleBase import DataObjectHandleBase -from Configurables import ApplicationMgr, EICDataSvc, PodioInput, 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("DETECTOR_PATH", ".")) -compact_path = os.path.join(detector_path, detector_name) - -# get sampling fractions from system environment variable, 1.0 by default -ce_ecal_sf = float(os.environ.get("CE_ECAL_SAMP_FRAC", 0.253)) -cb_ecal_sf = float(os.environ.get("CB_ECAL_SAMP_FRAC", 0.01324)) -cb_hcal_sf = float(os.environ.get("CB_HCAL_SAMP_FRAC", 0.038)) -hcal_hadronendcap_sf = float(os.environ.get("CE_HCAL_HADRONENDCAP_SAMP_FRAC", 0.025)) -hcal_electronendcap_sf = float(os.environ.get("CE_HCAL_ELECTRONENDCAP_SAMP_FRAC", 0.025)) - -# input and output -input_sims = [f.strip() for f in str.split(os.environ["FULL_CAL_SIM_FILE"], ",") if f.strip()] -output_rec = str(os.environ["FULL_CAL_REC_FILE"]) -n_events = int(os.environ["FULL_CAL_NUMEV"]) - -# geometry service -geo_service = GeoSvc("GeoSvc", detectors=["{}.xml".format(compact_path)]) -# data service -podioevent = EICDataSvc("EventDataSvc", inputs=input_sims) - - -# juggler components -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__CalorimeterHitReco as CalHitReco -from Configurables import Jug__Reco__CalorimeterHitsMerger as CalHitsMerger -from Configurables import Jug__Reco__CalorimeterIslandCluster as IslandCluster - -from Configurables import Jug__Reco__ImagingPixelReco as ImCalPixelReco -from Configurables import Jug__Reco__ImagingTopoCluster as ImagingCluster - -from Configurables import Jug__Reco__ClusterRecoCoG as RecoCoG -from Configurables import Jug__Reco__ImagingClusterReco as ImagingClusterReco - -# branches needed from simulation root file -sim_coll = [ - "mcparticles", - "CrystalEcalHits", - "EcalEndcapHits", - "EcalBarrelHits", - "HcalBarrelHits", - "HcalHadronEndcapHits", - "HcalElectronEndcapHits", -] - -# input and output -podin = PodioInput("PodioReader", collections=sim_coll) -podout = PodioOutput("out", filename=output_rec) -# copier needed to get around input --> output copy bug. So truth (mcparticles) can be saved in output file -copier = MCCopier("MCCopier", inputCollection="mcparticles", outputCollection="mcparticles2") - - -# Crystal Endcap Ecal -ce_ecal_digi = CalHitDigi("ce_ecal_digi", - inputHitCollection="CrystalEcalHits", - outputHitCollection="CrystalEcalHitsDigi", - energyResolutions=[0., 0.02, 0.], - dynamicRangeADC=5.*GeV, # digi settings must match with reco - capacityADC=32768, - pedestalMean=400, - pedestalSigma=3) - -ce_ecal_reco = CalHitReco("ce_ecal_reco", - inputHitCollection="CrystalEcalHitsDigi", - outputHitCollection="CrystalEcalHitsReco", - dynamicRangeADC=5.*GeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=3, - thresholdFactor=4, # 4 sigma - minimumHitEdep=1.0*MeV) # discard low energy hits - -ce_ecal_cl = IslandCluster("ce_ecal_cl", - # OutputLevel=DEBUG, - inputHitCollection="CrystalEcalHitsReco", - outputClusterCollection="CrystalEcalClusters", - splitHitCollection="CrystalEcalHitsSplit", - splitCluster=False, - minClusterCenterEdep=30*MeV, - groupRanges=[2.2*cm, 2.2*cm]) - -ce_ecal_clreco = RecoCoG("ce_ecal_clreco", - clusterCollection="CrystalEcalClusters", - samplingFraction=0.998, # this accounts for a small fraction of leakage - logWeightBase=4.6) - - -# Endcap Sampling Ecal -ce_ecal2_digi = CalHitDigi("ce_ecal2_digi", - inputHitCollection="EcalEndcapHits", - outputHitCollection="EcalEndcapHitsDigi", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10) - -ce_ecal2_reco = CalHitReco("ce_ecal2_reco", - inputHitCollection="EcalEndcapHitsDigi", - outputHitCollection="EcalEndcapHitsReco", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10, - thresholdFactor=5.0) - -# merge hits in different layer (projection to local x-y plane) -ce_ecal2_merger = CalHitsMerger("ce_ecal2_merger", - inputHitCollection="EcalEndcapHitsReco", - outputHitCollection="EcalEndcapHitsRecoXY", - fields=["layer", "slice"], - fieldRefNumbers=[1, 0], - readoutClass="EcalEndcapHits") - -ce_ecal2_cl = IslandCluster("ce_ecal2_cl", - inputHitCollection="EcalEndcapHitsRecoXY", - outputClusterCollection="EcalEndcapClusters", - splitHitCollection="EcalEndcapHitsSplit", - splitCluster=False, - minClusterCenterEdep=30.*MeV, - groupRanges=[5*mm, 5*mm]) - -ce_ecal2_clreco = RecoCoG("ce_ecal2_clreco", - clusterCollection="EcalEndcapClusters", - logWeightBase=6.2, - samplingFraction=ce_ecal_sf) - - -# Central Barrel Ecal (Imaging Cal.) -cb_ecal_digi = CalHitDigi("cb_ecal_digi", - inputHitCollection="EcalBarrelHits", - outputHitCollection="EcalBarrelHitsDigi", - energyResolutions=[0., 0.02, 0.], # 2% flat resolution - dynamicRangeADC=3*MeV, - capacityADC=8192, - pedestalMean=400, - pedestalSigma=20) # about 6 keV -cb_ecal_reco = ImCalPixelReco("cb_ecal_reco", - inputHitCollection="EcalBarrelHitsDigi", - outputHitCollection="EcalBarrelHitsReco", - dynamicRangeADC=3.*MeV, - capacityADC=8192, - pedestalMean=400, - pedestalSigma=20, - 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_cl = ImagingCluster("cb_ecal_cl", - inputHitCollection="EcalBarrelHitsReco", - outputClusterCollection="EcalBarrelClusters", - localRanges=[2.*mm, 2*mm], # same layer - adjLayerRanges=[10*mrad, 10*mrad], # adjacent layer - adjLayerDiff=2, # id diff for adjacent layer - adjSectorDist=3.*cm) # different sector -cb_ecal_clreco = ImagingClusterReco("cb_ecal_clreco", - samplingFraction=cb_ecal_sf, - inputClusterCollection="EcalBarrelClusters", - outputLayerCollection="EcalBarrelLayers") - - -# Central Barrel Hcal -cb_hcal_digi = CalHitDigi("cb_hcal_digi", - inputHitCollection="HcalBarrelHits", - outputHitCollection="HcalBarrelHitsDigi", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10) - -cb_hcal_reco = CalHitReco("cb_hcal_reco", - inputHitCollection="HcalBarrelHitsDigi", - outputHitCollection="HcalBarrelHitsReco", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10, - thresholdFactor=5.0) - -# merge hits in different layer (projection to local x-y plane) -cb_hcal_merger = CalHitsMerger("cb_hcal_merger", - inputHitCollection="HcalBarrelHitsReco", - outputHitCollection="HcalBarrelHitsRecoXY", - readoutClass="HcalBarrelHits", - fields=["layer", "slice"], - fieldRefNumbers=[1, 0]) - -cb_hcal_cl = IslandCluster("cb_hcal_cl", - inputHitCollection="HcalBarrelHitsRecoXY", - outputClusterCollection="HcalBarrelClusters", - splitHitCollection="HcalBarrelHitsSplit", - splitCluster=False, - minClusterCenterEdep=30.*MeV, - groupRanges=[15.*cm, 15.*cm]) - -cb_hcal_clreco = RecoCoG("cb_hcal_clreco", - clusterCollection="HcalBarrelClusters", - logWeightBase=6.2, - samplingFraction=cb_hcal_sf) - - -##Hadron Endcap HCal -hcal_hadronendcap_digi = CalHitDigi("hcal_hadronendcap_digi", - inputHitCollection="HcalHadronEndcapHits", - outputHitCollection="HcalHadronEndcapHitsDigi", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10) - -hcal_hadronendcap_reco = CalHitReco("hcal_hadronendcap_reco", - inputHitCollection="HcalHadronEndcapHitsDigi", - outputHitCollection="HcalHadronEndcapHitsReco", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10, - thresholdFactor=5.0) - -hcal_hadronendcap_merger = CalHitsMerger("hcal_hadronendcap_merger", - inputHitCollection="HcalHadronEndcapHitsReco", - outputHitCollection="HcalHadronEndcapHitsRecoXY", - readoutClass="HcalHadronEndcapHits", - fields=["layer", "slice"], - fieldRefNumbers=[1, 0]) - -hcal_hadronendcap_cl = IslandCluster("hcal_hadronendcap_cl", - inputHitCollection="HcalHadronEndcapHitsRecoXY", - outputClusterCollection="HcalHadronEndcapClusters", - splitHitCollection="HcalHadronEndcapHitsSplit", - splitCluster=False, - minClusterCenterEdep=30.*MeV, - groupRanges=[15.*cm, 15.*cm]) - -hcal_hadronendcap_clreco = RecoCoG("hcal_hadronendcap_clreco", - clusterCollection="HcalHadronEndcapClusters", - logWeightBase=6.2, - samplingFraction=hcal_hadronendcap_sf) - -#Hcal Electron Endcap -hcal_electronendcap_digi = CalHitDigi("hcal_electronendcap_digi", - inputHitCollection="HcalElectronEndcapHits", - outputHitCollection="HcalElectronEndcapHitsDigi", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10) - -hcal_electronendcap_reco = CalHitReco("hcal_electronendcap_reco",# - inputHitCollection="HcalElectronEndcapHitsDigi", - outputHitCollection="HcalElectronEndcapHitsReco",# - dynamicRangeADC=50.*MeV,# - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10, - thresholdFactor=5.0) -hcal_electronendcap_merger = CalHitsMerger("hcal_electronendcap_merger", - inputHitCollection="HcalElectronEndcapHitsReco", - outputHitCollection="HcalElectronEndcapHitsRecoXY", - readoutClass="HcalElectronEndcapHits", - fields=["layer", "slice"], - fieldRefNumbers=[1, 0]) - -hcal_electronendcap_cl = IslandCluster("hcal_electronendcap_cl", - inputHitCollection="HcalElectronEndcapHitsRecoXY", - outputClusterCollection="HcalElectronEndcapClusters", - splitHitCollection="HcalElectronEndcapHitsSplit", - splitCluster=False, - minClusterCenterEdep=30.*MeV, - groupRanges=[15.*cm, 15.*cm]) - -hcal_electronendcap_clreco = RecoCoG("hcal_electronendcap_clreco", - clusterCollection="HcalElectronEndcapClusters", - logWeightBase=6.2, - samplingFraction=hcal_electronendcap_sf) - - -podout.outputCommands = ["keep *"] - -ApplicationMgr( - TopAlg = [podin, copier, - ce_ecal_digi, ce_ecal_reco, ce_ecal_cl, ce_ecal_clreco, - ce_ecal2_digi, ce_ecal2_reco, ce_ecal2_merger, ce_ecal2_cl, ce_ecal2_clreco, - cb_ecal_digi, cb_ecal_reco, cb_ecal_cl, cb_ecal_clreco, - cb_hcal_digi, cb_hcal_reco, cb_hcal_merger, cb_hcal_cl, cb_hcal_clreco, - hcal_hadronendcap_digi, hcal_hadronendcap_reco, hcal_hadronendcap_merger, - hcal_hadronendcap_cl, hcal_hadronendcap_clreco, - hcal_electronendcap_digi, - hcal_electronendcap_reco, - hcal_electronendcap_merger, - hcal_electronendcap_cl, - #hcal_electronendcap_clreco, - podout], - EvtSel = 'NONE', - EvtMax = n_events, - ExtSvc = [podioevent], - OutputLevel=DEBUG -) - diff --git a/benchmarks/clustering/options/full_cal_clusters.py b/benchmarks/clustering/options/full_cal_clusters.py new file mode 100644 index 00000000..c091624c --- /dev/null +++ b/benchmarks/clustering/options/full_cal_clusters.py @@ -0,0 +1,201 @@ +''' + An example script to cluster reconstructed calorimeter hits +''' + +from Gaudi.Configuration import * +import os +import ROOT + +from GaudiKernel.DataObjectHandleBase import DataObjectHandleBase +from Configurables import ApplicationMgr, EICDataSvc, PodioInput, 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("DETECTOR_PATH", ".")) +compact_path = os.path.join(detector_path, detector_name) + +# get sampling fractions from system environment variable, 1.0 by default +ce_ecal_sf = float(os.environ.get("CE_ECAL_SAMP_FRAC", 0.253)) +cb_ecal_sf = float(os.environ.get("CB_ECAL_SAMP_FRAC", 0.01324)) +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_digis = [f.strip() for f in str.split(os.environ["JUGGLER_DIGI_FILE"], ",") if f.strip()] +output_rec = str(os.environ["JUGGLER_REC_FILE"]) +n_events = int(os.environ["JUGGLER_N_EVENTS"]) + +# geometry service +geo_service = GeoSvc("GeoSvc", detectors=["{}.xml".format(compact_path)]) +# data service +podioevent = EICDataSvc("EventDataSvc", inputs=input_digis) + + +# juggler components +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__CalorimeterHitReco as CalHitReco +from Configurables import Jug__Reco__CalorimeterHitsMerger as CalHitsMerger +from Configurables import Jug__Reco__CalorimeterIslandCluster as IslandCluster + +from Configurables import Jug__Reco__ImagingPixelReco as ImCalPixelReco +from Configurables import Jug__Reco__ImagingTopoCluster as ImagingCluster + +from Configurables import Jug__Reco__ClusterRecoCoG as RecoCoG +from Configurables import Jug__Reco__ImagingClusterReco as ImagingClusterReco + +# branches needed from simulation root file +digi_coll = [ +# "mcparticles2", + "CrystalEcalHitsReco", + "EcalEndcapHitsReco", + "EcalBarrelHitsReco", + "HcalBarrelHitsReco", + "HcalHadronEndcapHitsReco", + "HcalElectronEndcapHitsReco", +] + +# input and output +podin = PodioInput("PodioReader", collections=digi_coll, OutputLevel=DEBUG) +podout = PodioOutput("out", filename=output_rec) +# copier needed to get around input --> output copy bug. So truth (mcparticles) can be saved in output file +# copier = MCCopier("MCCopier", inputCollection="mcparticles2", outputCollection="mcparticles3") + + +# Crystal Endcap Ecal +ce_ecal_cl = IslandCluster("ce_ecal_cl", + # OutputLevel=DEBUG, + inputHitCollection="CrystalEcalHitsReco", + outputClusterCollection="CrystalEcalClusters", + splitHitCollection="CrystalEcalHitsSplit", + splitCluster=False, + minClusterCenterEdep=30*MeV, + groupRanges=[2.2*cm, 2.2*cm]) + +ce_ecal_clreco = RecoCoG("ce_ecal_clreco", + clusterCollection="CrystalEcalClusters", + samplingFraction=0.998, # this accounts for a small fraction of leakage + logWeightBase=4.6) + + +# Endcap Sampling Ecal +# merge hits in different layer (projection to local x-y plane) +ce_ecal2_merger = CalHitsMerger("ce_ecal2_merger", + inputHitCollection="EcalEndcapHitsReco", + outputHitCollection="EcalEndcapHitsRecoXY", + fields=["layer", "slice"], + fieldRefNumbers=[1, 0], + readoutClass="EcalEndcapHits") + +ce_ecal2_cl = IslandCluster("ce_ecal2_cl", + inputHitCollection="EcalEndcapHitsRecoXY", + outputClusterCollection="EcalEndcapClusters", + splitHitCollection="EcalEndcapHitsSplit", + splitCluster=False, + minClusterCenterEdep=30.*MeV, + groupRanges=[5*mm, 5*mm]) + +ce_ecal2_clreco = RecoCoG("ce_ecal2_clreco", + clusterCollection="EcalEndcapClusters", + logWeightBase=6.2, + samplingFraction=ce_ecal_sf) + + +# Central Barrel Ecal (Imaging Cal.) +cb_ecal_cl = ImagingCluster("cb_ecal_cl", + inputHitCollection="EcalBarrelHitsReco", + outputClusterCollection="EcalBarrelClusters", + localRanges=[2.*mm, 2*mm], # same layer + adjLayerRanges=[10*mrad, 10*mrad], # adjacent layer + adjLayerDiff=2, # id diff for adjacent layer + adjSectorDist=3.*cm) # different sector +cb_ecal_clreco = ImagingClusterReco("cb_ecal_clreco", + samplingFraction=cb_ecal_sf, + inputClusterCollection="EcalBarrelClusters", + outputLayerCollection="EcalBarrelLayers") + + +# Central Barrel Hcal +# merge hits in different layer (projection to local x-y plane) +cb_hcal_merger = CalHitsMerger("cb_hcal_merger", + inputHitCollection="HcalBarrelHitsReco", + outputHitCollection="HcalBarrelHitsRecoXY", + readoutClass="HcalBarrelHits", + fields=["layer", "slice"], + fieldRefNumbers=[1, 0]) + +cb_hcal_cl = IslandCluster("cb_hcal_cl", + inputHitCollection="HcalBarrelHitsRecoXY", + outputClusterCollection="HcalBarrelClusters", + splitHitCollection="HcalBarrelHitsSplit", + splitCluster=False, + minClusterCenterEdep=30.*MeV, + groupRanges=[15.*cm, 15.*cm]) + +cb_hcal_clreco = RecoCoG("cb_hcal_clreco", + clusterCollection="HcalBarrelClusters", + logWeightBase=6.2, + samplingFraction=cb_hcal_sf) + + +# Hcal Hadron Endcap HCal +ci_hcal_merger = CalHitsMerger("ci_hcal_merger", + inputHitCollection="HcalHadronEndcapHitsReco", + outputHitCollection="HcalHadronEndcapHitsRecoXY", + readoutClass="HcalHadronEndcapHits", + fields=["layer", "slice"], + fieldRefNumbers=[1, 0]) + +ci_hcal_cl = IslandCluster("ci_hcal_cl", + inputHitCollection="HcalHadronEndcapHitsRecoXY", + outputClusterCollection="HcalHadronEndcapClusters", + splitHitCollection="HcalHadronEndcapHitsSplit", + splitCluster=False, + minClusterCenterEdep=30.*MeV, + groupRanges=[15.*cm, 15.*cm]) + +ci_hcal_clreco = RecoCoG("ci_hcal_clreco", + clusterCollection="HcalHadronEndcapClusters", + logWeightBase=6.2, + samplingFraction=ci_hcal_sf) + +# Hcal Electron Endcap +ce_hcal_merger = CalHitsMerger("ce_hcal_merger", + inputHitCollection="HcalElectronEndcapHitsReco", + outputHitCollection="HcalElectronEndcapHitsRecoXY", + readoutClass="HcalElectronEndcapHits", + fields=["layer", "slice"], + fieldRefNumbers=[1, 0]) + +ce_hcal_cl = IslandCluster("ce_hcal_cl", + inputHitCollection="HcalElectronEndcapHitsRecoXY", + outputClusterCollection="HcalElectronEndcapClusters", + splitHitCollection="HcalElectronEndcapHitsSplit", + splitCluster=False, + minClusterCenterEdep=30.*MeV, + groupRanges=[15.*cm, 15.*cm]) + +ce_hcal_clreco = RecoCoG("ce_hcal_clreco", + clusterCollection="HcalElectronEndcapClusters", + logWeightBase=6.2, + samplingFraction=ce_hcal_sf) + + +podout.outputCommands = ["drop *", "keep mcparticles", "keep *Clusters", "keep *Layers"] + +ApplicationMgr( + TopAlg = [podin, # copier, + ce_ecal_cl, ce_ecal_clreco, + ce_ecal2_merger, ce_ecal2_cl, ce_ecal2_clreco, + cb_ecal_cl, cb_ecal_clreco, + cb_hcal_merger, cb_hcal_cl, cb_hcal_clreco, + ce_hcal_merger, ce_hcal_cl, ce_hcal_clreco, + ci_hcal_merger, ci_hcal_cl, ci_hcal_clreco, + podout], + EvtSel = 'NONE', + EvtMax = n_events, + ExtSvc = [podioevent], + OutputLevel=DEBUG +) + diff --git a/benchmarks/clustering/options/full_cal_digi.py b/benchmarks/clustering/options/full_cal_digi.py new file mode 100644 index 00000000..dcc584a1 --- /dev/null +++ b/benchmarks/clustering/options/full_cal_digi.py @@ -0,0 +1,188 @@ +''' + An example script to digitize/reconstruct calorimeter hits +''' +from Gaudi.Configuration import * +import os +import ROOT + +from GaudiKernel.DataObjectHandleBase import DataObjectHandleBase +from Configurables import ApplicationMgr, EICDataSvc, PodioInput, 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("DETECTOR_PATH", ".")) +compact_path = os.path.join(detector_path, detector_name) + +# 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_DIGI_FILE"]) +n_events = int(os.environ["JUGGLER_N_EVENTS"]) + +# geometry service +geo_service = GeoSvc("GeoSvc", detectors=["{}.xml".format(compact_path)]) +# data service +podioevent = EICDataSvc("EventDataSvc", inputs=input_sims) + + +# juggler components +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__CalorimeterHitReco as CalHitReco +from Configurables import Jug__Reco__CalorimeterHitsMerger as CalHitsMerger +from Configurables import Jug__Reco__CalorimeterIslandCluster as IslandCluster + +from Configurables import Jug__Reco__ImagingPixelReco as ImCalPixelReco +from Configurables import Jug__Reco__ImagingTopoCluster as ImagingCluster + +from Configurables import Jug__Reco__ClusterRecoCoG as RecoCoG +from Configurables import Jug__Reco__ImagingClusterReco as ImagingClusterReco + +# branches needed from simulation root file +sim_coll = [ + "mcparticles", + "CrystalEcalHits", + "EcalEndcapHits", + "EcalBarrelHits", + "HcalBarrelHits", + "HcalHadronEndcapHits", + "HcalElectronEndcapHits", +] + +# input and output +podin = PodioInput("PodioReader", collections=sim_coll) +podout = PodioOutput("out", filename=output_rec) +# copier needed to get around input --> output copy bug. So truth (mcparticles) can be saved in output file +copier = MCCopier("MCCopier", inputCollection="mcparticles", outputCollection="mcparticles2") + + +# Crystal Endcap Ecal +ce_ecal_digi = CalHitDigi("ce_ecal_digi", + inputHitCollection="CrystalEcalHits", + outputHitCollection="CrystalEcalHitsDigi", + energyResolutions=[0., 0.02, 0.], + dynamicRangeADC=5.*GeV, # digi settings must match with reco + capacityADC=32768, + pedestalMean=400, + pedestalSigma=3) + +ce_ecal_reco = CalHitReco("ce_ecal_reco", + inputHitCollection="CrystalEcalHitsDigi", + outputHitCollection="CrystalEcalHitsReco", + dynamicRangeADC=5.*GeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=3, + thresholdFactor=4, # 4 sigma + minimumHitEdep=1.0*MeV) # discard low energy hits + +# Endcap Sampling Ecal +ce_ecal2_digi = CalHitDigi("ce_ecal2_digi", + inputHitCollection="EcalEndcapHits", + outputHitCollection="EcalEndcapHitsDigi", + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10) + +ce_ecal2_reco = CalHitReco("ce_ecal2_reco", + inputHitCollection="EcalEndcapHitsDigi", + outputHitCollection="EcalEndcapHitsReco", + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10, + thresholdFactor=5.0) + +# Central Barrel Ecal (Imaging Cal.) +cb_ecal_digi = CalHitDigi("cb_ecal_digi", + inputHitCollection="EcalBarrelHits", + outputHitCollection="EcalBarrelHitsDigi", + energyResolutions=[0., 0.02, 0.], # 2% flat resolution + dynamicRangeADC=3*MeV, + capacityADC=8192, + pedestalMean=400, + pedestalSigma=20) # about 6 keV +cb_ecal_reco = ImCalPixelReco("cb_ecal_reco", + inputHitCollection="EcalBarrelHitsDigi", + outputHitCollection="EcalBarrelHitsReco", + dynamicRangeADC=3.*MeV, + capacityADC=8192, + pedestalMean=400, + pedestalSigma=20, + thresholdFactor=3, # about 20 keV + readoutClass="EcalBarrelHits", # readout class + layerField="layer", # field to get layer id + sectorField="module") # field to get sector id + +# Central Barrel Hcal +cb_hcal_digi = CalHitDigi("cb_hcal_digi", + inputHitCollection="HcalBarrelHits", + outputHitCollection="HcalBarrelHitsDigi", + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10) + +cb_hcal_reco = CalHitReco("cb_hcal_reco", + inputHitCollection="HcalBarrelHitsDigi", + outputHitCollection="HcalBarrelHitsReco", + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10, + thresholdFactor=5.0) + +# Hcal Hadron Endcap +ci_hcal_digi = CalHitDigi("ci_hcal_digi", + inputHitCollection="HcalHadronEndcapHits", + outputHitCollection="HcalHadronEndcapHitsDigi", + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10) + +ci_hcal_reco = CalHitReco("ci_hcal_reco", + inputHitCollection="HcalHadronEndcapHitsDigi", + outputHitCollection="HcalHadronEndcapHitsReco", + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10, + thresholdFactor=5.0) + +# Hcal Electron Endcap +ce_hcal_digi = CalHitDigi("ce_hcal_digi", + inputHitCollection="HcalElectronEndcapHits", + outputHitCollection="HcalElectronEndcapHitsDigi", + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10) + +ce_hcal_reco = CalHitReco("ce_hcal_reco", + inputHitCollection="HcalElectronEndcapHitsDigi", + outputHitCollection="HcalElectronEndcapHitsReco", + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10, + thresholdFactor=5.0) + + +podout.outputCommands = ['drop *', 'keep mcparticles2', 'keep *Reco', 'keep *Digi'] + +ApplicationMgr( + TopAlg = [podin, copier, + ce_ecal_digi, ce_ecal_reco, + ce_ecal2_digi, ce_ecal2_reco, + cb_ecal_digi, cb_ecal_reco, + cb_hcal_digi, cb_hcal_reco, + ce_hcal_digi, ce_hcal_reco, + ci_hcal_digi, ci_hcal_reco, + podout], + EvtSel = 'NONE', + EvtMax = n_events, + ExtSvc = [podioevent], + OutputLevel=DEBUG +) + diff --git a/benchmarks/clustering/scripts/cluster_plots.py b/benchmarks/clustering/scripts/cluster_plots.py index 71c59671..b7bcb95b 100644 --- a/benchmarks/clustering/scripts/cluster_plots.py +++ b/benchmarks/clustering/scripts/cluster_plots.py @@ -21,10 +21,10 @@ def load_root_macros(arg_macros): print('Loading root macros: \'{}\' does not exist, skip loading it.'.format(path)) -def thrown_particles_figure(df, save): +def thrown_particles_figure(df, save, mcbranch="mcparticles"): # define truth particle info - df = df.Define('isThrown', 'mcparticles2.genStatus == 1')\ - .Define('thrownParticles', 'mcparticles2[isThrown]')\ + df = df.Define('isThrown', '{}.genStatus == 1'.format(mcbranch))\ + .Define('thrownParticles', '{}[isThrown]'.format(mcbranch))\ .Define('thrownP', 'fourvec(thrownParticles)')\ .Define('thrownPID', 'pid(thrownParticles)')\ .Define('thrownEta', 'eta(thrownParticles)')\ @@ -116,10 +116,13 @@ def general_clusters_figure(df, collection, save, min_nhits=3): if __name__ == '__main__': parser = argparse.ArgumentParser() - parser.add_argument('file', help='Path to reconstruction file.') + parser.add_argument('sim_file', help='Path to simulation output file.') + parser.add_argument('rec_file', help='Path to reconstruction output file.') parser.add_argument('-o', dest='outdir', default='.', help='Output directory.') parser.add_argument('-m', '--macros', dest='macros', default='rootlogon.C', help='Macro files to be loaded by root, separated by \",\".') + parser.add_argument('--mc-branch', dest='mc', default='mcparticles', + help='Branch name of MC particles truth info.') args = parser.parse_args() # multi-threading for RDataFrame @@ -136,15 +139,16 @@ if __name__ == '__main__': # load macros (add libraries/headers root cannot automatically found here) load_root_macros(args.macros) - rdf = ROOT.RDataFrame('events', args.file) + rdf_sim = ROOT.RDataFrame('events', args.sim_file) + rdf_rec = ROOT.RDataFrame('events', args.rec_file) - thrown_particles_figure(rdf, save=os.path.join(args.outdir, 'thrown_particles.png')) - general_clusters_figure(rdf, collection='CrystalEcalClusters', min_nhits=5, + thrown_particles_figure(rdf_sim, save=os.path.join(args.outdir, 'thrown_particles.png'), mcbranch=args.mc) + general_clusters_figure(rdf_rec, collection='CrystalEcalClusters', min_nhits=5, save=os.path.join(args.outdir, 'crystal_ecal_clusters.png')) - general_clusters_figure(rdf, collection='EcalEndcapClusters', min_nhits=10, + general_clusters_figure(rdf_rec, collection='EcalEndcapClusters', min_nhits=10, save=os.path.join(args.outdir, 'ecal_endcap_clusters.png')) - general_clusters_figure(rdf, collection='EcalBarrelClusters', + general_clusters_figure(rdf_rec, collection='EcalBarrelClusters', save=os.path.join(args.outdir, 'ecal_barrel_clusters.png')) - general_clusters_figure(rdf, collection='HcalBarrelClusters', + general_clusters_figure(rdf_rec, collection='HcalBarrelClusters', save=os.path.join(args.outdir, 'hcal_barrel_clusters.png')) -- GitLab