diff --git a/benchmarks/clustering/options/full_cal_reco.py b/benchmarks/clustering/options/full_cal_reco.py index 1c7d0508e61963abbd5f535a95c8e942c2b390e3..830726e4e113e8c2fbe2d90401706700788e0649 100644 --- a/benchmarks/clustering/options/full_cal_reco.py +++ b/benchmarks/clustering/options/full_cal_reco.py @@ -1,5 +1,5 @@ ''' - An example script to digitize/reconstruct calorimeter hits + An example option file to digitize/reconstruct/clustering calorimeter hits ''' from Gaudi.Configuration import * import os @@ -14,7 +14,7 @@ detector_path = str(os.environ.get("JUGGLER_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)) +ci_ecal_sf = float(os.environ.get("CI_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)) @@ -63,60 +63,62 @@ copier = MCCopier("MCCopier", inputCollection="mcparticles", outputCollection="m # Crystal Endcap Ecal +ce_ecal_daq = dict( + dynamicRangeADC=5.*GeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=3) + ce_ecal_digi = CalHitDigi("ce_ecal_digi", inputHitCollection="EcalEndcapNHits", outputHitCollection="EcalEndcapNHitsDigi", energyResolutions=[0., 0.02, 0.], - dynamicRangeADC=5.*GeV, # digi settings must match with reco - capacityADC=32768, - pedestalMean=400, - pedestalSigma=3) + **ce_ecal_daq) ce_ecal_reco = CalHitReco("ce_ecal_reco", inputHitCollection="EcalEndcapNHitsDigi", outputHitCollection="EcalEndcapNHitsReco", - dynamicRangeADC=5.*GeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=3, - thresholdFactor=4, # 4 sigma - minimumHitEdep=1.0*MeV, # discard low energy hits + thresholdFactor=4, # 4 sigma cut on pedestal sigma readoutClass="EcalEndcapNHits", - sectorField="sector") + sectorField="sector", + **ce_ecal_daq) ce_ecal_cl = IslandCluster("ce_ecal_cl", # OutputLevel=DEBUG, inputHitCollection="EcalEndcapNHitsReco", outputHitCollection="EcalEndcapNClusterHits", splitCluster=False, + minClusterHitEdep=1.0*MeV, # discard low energy hits minClusterCenterEdep=30*MeV, - groupRanges=[2.2*cm, 2.2*cm]) + dimScaledDist=1.8) # dimension scaled dist is good for hybrid sectors with different module size ce_ecal_clreco = RecoCoG("ce_ecal_clreco", - inputHitCollection="EcalEndcapNClusterHits", - outputClusterCollection="EcalEndcapNClusters", + inputHitCollection="EcalEndcapNClusterHits", + outputClusterCollection="EcalEndcapNClusters", samplingFraction=0.998, # this accounts for a small fraction of leakage logWeightBase=4.6) # Endcap Sampling Ecal +ci_ecal_daq = dict( + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10) + ci_ecal_digi = CalHitDigi("ci_ecal_digi", - inputHitCollection="EcalEndcapPHits", - outputHitCollection="EcalEndcapPHitsDigi", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10) + inputHitCollection="EcalEndcapPHits", + outputHitCollection="EcalEndcapPHitsDigi", + **ci_ecal_daq) ci_ecal_reco = CalHitReco("ci_ecal_reco", inputHitCollection="EcalEndcapPHitsDigi", outputHitCollection="EcalEndcapPHitsReco", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10, - thresholdFactor=5.0) + thresholdFactor=5.0, + **ci_ecal_daq) + # merge hits in different layer (projection to local x-y plane) ci_ecal_merger = CalHitsMerger("ci_ecal_merger", + # OutputLevel=DEBUG, inputHitCollection="EcalEndcapPHitsReco", outputHitCollection="EcalEndcapPHitsRecoXY", fields=["layer", "slice"], @@ -124,45 +126,49 @@ ci_ecal_merger = CalHitsMerger("ci_ecal_merger", readoutClass="EcalEndcapPHits") ci_ecal_cl = IslandCluster("ci_ecal_cl", + # OutputLevel=DEBUG, inputHitCollection="EcalEndcapPHitsRecoXY", outputHitCollection="EcalEndcapPClusterHits", splitCluster=False, - minClusterCenterEdep=30.*MeV, - groupRanges=[5*mm, 5*mm]) + minClusterCenterEdep=10.*MeV, + localDistXY=[10*mm, 10*mm]) ci_ecal_clreco = RecoCoG("ci_ecal_clreco", inputHitCollection="EcalEndcapPClusterHits", - outputClusterCollection="EcalEndcapPClusters", + outputClusterCollection="EcalEndcapPClusters", logWeightBase=6.2, - samplingFraction=ce_ecal_sf) + samplingFraction=ci_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 +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", - 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 + sectorField="module", # field to get sector id + **cb_ecal_daq) + cb_ecal_cl = ImagingCluster("cb_ecal_cl", inputHitCollection="EcalBarrelHitsReco", outputHitCollection="EcalBarrelClusterHits", - 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 + 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", @@ -170,25 +176,26 @@ cb_ecal_clreco = ImagingClusterReco("cb_ecal_clreco", outputLayerCollection="EcalBarrelLayers") # Central Barrel Hcal -cb_hcal_digi = CalHitDigi("cb_hcal_digi", - inputHitCollection="HcalBarrelHits", - outputHitCollection="HcalBarrelHitsDigi", +cb_hcal_daq = dict( dynamicRangeADC=50.*MeV, capacityADC=32768, pedestalMean=400, pedestalSigma=10) +cb_hcal_digi = CalHitDigi("cb_hcal_digi", + inputHitCollection="HcalBarrelHits", + outputHitCollection="HcalBarrelHitsDigi", + **cb_hcal_daq) + cb_hcal_reco = CalHitReco("cb_hcal_reco", inputHitCollection="HcalBarrelHitsDigi", outputHitCollection="HcalBarrelHitsReco", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10, thresholdFactor=5.0, readoutClass="HcalBarrelHits", layerField="layer", - sectorField="module") + sectorField="module", + **cb_hcal_daq) + cb_hcal_merger = CalHitsMerger("cb_hcal_merger", inputHitCollection="HcalBarrelHitsReco", outputHitCollection="HcalBarrelHitsRecoXY", @@ -201,32 +208,32 @@ cb_hcal_cl = IslandCluster("cb_hcal_cl", outputHitCollection="HcalBarrelClusterHits", splitCluster=False, minClusterCenterEdep=30.*MeV, - groupRanges=[15.*cm, 15.*cm]) + localDistXY=[15.*cm, 15.*cm]) cb_hcal_clreco = RecoCoG("cb_hcal_clreco", inputHitCollection="HcalBarrelClusterHits", - outputClusterCollection="HcalBarrelClusters", + outputClusterCollection="HcalBarrelClusters", logWeightBase=6.2, samplingFraction=cb_hcal_sf) # Hcal Hadron Endcap -ci_hcal_digi = CalHitDigi("ci_hcal_digi", - inputHitCollection="HcalHadronEndcapHits", - outputHitCollection="HcalHadronEndcapHitsDigi", +ci_hcal_daq = dict( dynamicRangeADC=50.*MeV, capacityADC=32768, pedestalMean=400, pedestalSigma=10) +ci_hcal_digi = CalHitDigi("ci_hcal_digi", + inputHitCollection="HcalHadronEndcapHits", + outputHitCollection="HcalHadronEndcapHitsDigi", + **ci_hcal_daq) ci_hcal_reco = CalHitReco("ci_hcal_reco", inputHitCollection="HcalHadronEndcapHitsDigi", outputHitCollection="HcalHadronEndcapHitsReco", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10, - thresholdFactor=5.0) + thresholdFactor=5.0, + **ci_hcal_daq) + ci_hcal_merger = CalHitsMerger("ci_hcal_merger", inputHitCollection="HcalHadronEndcapHitsReco", outputHitCollection="HcalHadronEndcapHitsRecoXY", @@ -239,31 +246,32 @@ ci_hcal_cl = IslandCluster("ci_hcal_cl", outputHitCollection="HcalHadronEndcapClusterHits", splitCluster=False, minClusterCenterEdep=30.*MeV, - groupRanges=[15.*cm, 15.*cm]) + localDistXY=[15.*cm, 15.*cm]) ci_hcal_clreco = RecoCoG("ci_hcal_clreco", inputHitCollection="HcalHadronEndcapClusterHits", - outputClusterCollection="HcalHadronEndcapClusters", + outputClusterCollection="HcalHadronEndcapClusters", logWeightBase=6.2, samplingFraction=ci_hcal_sf) # Hcal Electron Endcap -ce_hcal_digi = CalHitDigi("ce_hcal_digi", - inputHitCollection="HcalElectronEndcapHits", - outputHitCollection="HcalElectronEndcapHitsDigi", +ce_hcal_daq = dict( dynamicRangeADC=50.*MeV, capacityADC=32768, pedestalMean=400, pedestalSigma=10) +ce_hcal_digi = CalHitDigi("ce_hcal_digi", + inputHitCollection="HcalElectronEndcapHits", + outputHitCollection="HcalElectronEndcapHitsDigi", + **ce_hcal_daq) + ce_hcal_reco = CalHitReco("ce_hcal_reco", inputHitCollection="HcalElectronEndcapHitsDigi", outputHitCollection="HcalElectronEndcapHitsReco", - dynamicRangeADC=50.*MeV, - capacityADC=32768, - pedestalMean=400, - pedestalSigma=10, - thresholdFactor=5.0) + thresholdFactor=5.0, + **ce_hcal_daq) + ce_hcal_merger = CalHitsMerger("ce_hcal_merger", inputHitCollection="HcalElectronEndcapHitsReco", outputHitCollection="HcalElectronEndcapHitsRecoXY", @@ -276,34 +284,34 @@ ce_hcal_cl = IslandCluster("ce_hcal_cl", outputHitCollection="HcalElectronEndcapClusterHits", splitCluster=False, minClusterCenterEdep=30.*MeV, - groupRanges=[15.*cm, 15.*cm]) + localDistXY=[15.*cm, 15.*cm]) ce_hcal_clreco = RecoCoG("ce_hcal_clreco", inputHitCollection="HcalElectronEndcapClusterHits", - outputClusterCollection="HcalElectronEndcapClusters", + outputClusterCollection="HcalElectronEndcapClusters", logWeightBase=6.2, samplingFraction=ce_hcal_sf) -podout.outputCommands = ['drop *', 'keep mcparticles*', 'keep *Reco', 'keep *Digi', 'keep *Clusters', 'keep *Layers', 'drop *ProtoClusters'] +podout.outputCommands = ['drop *', + 'keep mcparticles2', + 'keep *Digi', + 'keep *Reco*', + 'keep *ClusterHits', + 'keep *Clusters', + 'keep *Layers'] ApplicationMgr( TopAlg = [podin, copier, - ce_ecal_digi, ce_ecal_reco, - ci_ecal_digi, ci_ecal_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, - ce_ecal_cl, ce_ecal_clreco, - ci_ecal_merger, ci_ecal_cl, ci_ecal_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, + ce_ecal_digi, ce_ecal_reco, ce_ecal_cl, ce_ecal_clreco, + ci_ecal_digi, ci_ecal_reco, ci_ecal_merger, ci_ecal_cl, ci_ecal_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, + ce_hcal_digi, ce_hcal_reco, ce_hcal_merger, ce_hcal_cl, ce_hcal_clreco, + ci_hcal_digi, ci_hcal_reco, ci_hcal_merger, ci_hcal_cl, ci_hcal_clreco, podout], EvtSel = 'NONE', - EvtMax = n_events, + EvtMax = n_events, ExtSvc = [podioevent], OutputLevel=DEBUG ) diff --git a/benchmarks/clustering/scripts/cluster_plots.py b/benchmarks/clustering/scripts/cluster_plots.py index 9d0bd63353adc50144b1f032fd7677fdc8138f12..6f70fa7ff88cfc803324e50e258a8418fa21198a 100644 --- a/benchmarks/clustering/scripts/cluster_plots.py +++ b/benchmarks/clustering/scripts/cluster_plots.py @@ -97,7 +97,7 @@ def general_clusters_figure(df, collection, save, min_nhits=3): fig, axs = plt.subplots(2, 2, figsize=(16, 12), dpi=120) labels = [ ('Number of Hits', 'Counts'), - (r'$E$ (MeV)', 'Counts'), + (r'$E$ (GeV)', 'Counts'), (r'$\theta$ (rad)', 'Counts'), (r'$\phi$ (rad)', 'Counts'), ] diff --git a/benchmarks/clustering/scripts/gen_central_electrons.cxx b/benchmarks/clustering/scripts/deprecated/gen_central_electrons.cxx similarity index 100% rename from benchmarks/clustering/scripts/gen_central_electrons.cxx rename to benchmarks/clustering/scripts/deprecated/gen_central_electrons.cxx diff --git a/benchmarks/clustering/scripts/gen_central_pions.cxx b/benchmarks/clustering/scripts/deprecated/gen_central_pions.cxx similarity index 100% rename from benchmarks/clustering/scripts/gen_central_pions.cxx rename to benchmarks/clustering/scripts/deprecated/gen_central_pions.cxx diff --git a/benchmarks/ecal/config.yml b/benchmarks/ecal/config.yml index 0632b5cba1e104dbf951f7b53b2e627aebdf4be2..c14cb9f66867ad0a3ef88a826d483006747484e4 100644 --- a/benchmarks/ecal/config.yml +++ b/benchmarks/ecal/config.yml @@ -1,42 +1,56 @@ -emcal_crystal_electrons: +ecal_endcap_e_electrons: extends: .rec_benchmark stage: process timeout: 8 hours script: - - bash benchmarks/ecal/emcal_electrons.sh + - python benchmarks/ecal/run_emcal_benchmarks.py endcap_e --particle "electron" -n 100 -t "endcap_e_electron" + --pmin 5.0 --pmax 5.0 --amin 135 --amax 175 -emcal_crystal_pi0s: +ecal_endcap_i_electrons: extends: .rec_benchmark - stage: run - timeout: 12 hours + stage: process + timeout: 8 hours script: - - bash benchmarks/ecal/emcal_pi0s.sh + - python benchmarks/ecal/run_emcal_benchmarks.py endcap_i --particle "electron" -n 100 -t "endcap_i_electron" + --pmin 5.0 --pmax 5.0 --amin 5 --amax 45 -emcal_barrel_electrons: +ecal_barrel_electrons: extends: .rec_benchmark - timeout: 48 hours - stage: run + stage: process + timeout: 8 hours script: - - bash benchmarks/ecal/run_emcal_barrel_electrons.sh + - python benchmarks/ecal/run_emcal_benchmarks.py barrel --particle "electron" -n 100 -t "barrel_electron" + --pmin 5.0 --pmax 5.0 --amin 45 --amax 135 -emcal_barrel_pions: +ecal_endcap_e_pions: extends: .rec_benchmark - timeout: 48 hours - stage: run + stage: process + timeout: 8 hours script: - - bash benchmarks/ecal/run_emcal_barrel_pions.sh + - python benchmarks/ecal/run_emcal_benchmarks.py endcap_e --particle "pion-" -n 100 -t "endcap_e_pion" + --pmin 5.0 --pmax 5.0 --amin 135 --amax 175 -full_emcal_barrel_electrons: +ecal_endcap_i_pions: extends: .rec_benchmark - timeout: 48 hours - stage: run + stage: process + timeout: 8 hours + script: + - python benchmarks/ecal/run_emcal_benchmarks.py endcap_i --particle "pion-" -n 100 -t "endcap_i_pion" + --pmin 5.0 --pmax 5.0 --amin 5 --amax 45 + +ecal_barrel_pions: + extends: .rec_benchmark + stage: process + timeout: 8 hours script: - - bash benchmarks/ecal/full_emcal_electrons.sh + - python benchmarks/ecal/run_emcal_benchmarks.py barrel --particle "pion-" -n 100 -t "barrel_pion" + --pmin 5.0 --pmax 5.0 --amin 45 --amax 135 ecal_collect: stage: collect needs: - - ["emcal_crystal_electrons", "emcal_crystal_pi0s", "emcal_barrel_electrons", "emcal_barrel_pions", "full_emcal_barrel_electrons"] + - ["ecal_endcap_e_electrons", "ecal_endcap_e_pions", "ecal_endcap_i_electrons", "ecal_endcap_i_pions", + "ecal_barrel_electrons", "ecal_barrel_pions"] script: - echo "Done collecting artifacts." diff --git a/benchmarks/ecal/emcal_electrons.sh b/benchmarks/ecal/emcal_electrons.sh deleted file mode 100644 index 67e082318e3ba4356b2f74b26f89afa5229dcd27..0000000000000000000000000000000000000000 --- a/benchmarks/ecal/emcal_electrons.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash - -print_env.sh - -## To run the reconstruction, we need the following global variables: -## - JUGGLER_INSTALL_PREFIX: Install prefix for Juggler (simu/recon) -## - JUGGLER_DETECTOR: the detector package we want to use for this benchmark -## - JUGGLER_DETECTOR_VERSION: the detector package we want to use for this benchmark -## - DETECTOR_PATH: full path to the detector definitions -## -## You can ready options/env.sh for more in-depth explanations of the variables -## and how they can be controlled. -source options/env.sh -if [[ ! -n "${JUGGLER_DETECTOR_PATH}" ]] ; then - export JUGGLER_DETECTOR_PATH=${DETECTOR_PATH} -fi - -if [[ ! -n "${JUGGLER_N_EVENTS}" ]] ; then - export JUGGLER_N_EVENTS=100 -fi - -if [[ ! -n "${E_start}" ]] ; then - export E_start=0.0 -fi - -if [[ ! -n "${E_end}" ]] ; then - export E_end=30.0 -fi - -export JUGGLER_FILE_NAME_TAG="emcal_uniform_electrons" -export JUGGLER_GEN_FILE="${JUGGLER_FILE_NAME_TAG}.hepmc" - -export JUGGLER_SIM_FILE="sim_${JUGGLER_FILE_NAME_TAG}.root" -export JUGGLER_REC_FILE="rec_${JUGGLER_FILE_NAME_TAG}.root" - -echo "JUGGLER_N_EVENTS = ${JUGGLER_N_EVENTS}" -echo "JUGGLER_DETECTOR = ${JUGGLER_DETECTOR}" - - - -# generate the input events -# note datasets is now only used to develop datasets. -#git clone https://eicweb.phy.anl.gov/EIC/datasets.git datasets -root -b -q "benchmarks/ecal/scripts/emcal_electrons.cxx(${JUGGLER_N_EVENTS}, ${E_start}, ${E_end}, \"${JUGGLER_FILE_NAME_TAG}.hepmc\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running script" - exit 1 -fi -root -b -q "benchmarks/ecal/scripts/emcal_electrons_reader.cxx(${E_start}, ${E_end}, \"${JUGGLER_FILE_NAME_TAG}.hepmc\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running script" - exit 1 -fi - -# run geant4 simulations -npsim --runType batch \ - --part.minimalKineticEnergy 1000*GeV \ - -v WARNING \ - --numberOfEvents ${JUGGLER_N_EVENTS} \ - --compactFile ${JUGGLER_DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml \ - --inputFiles ${JUGGLER_FILE_NAME_TAG}.hepmc \ - --outputFile ${JUGGLER_SIM_FILE} -# Need to figure out how to pass file name to juggler from the commandline -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running npdet" - exit 1 -fi -xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py benchmarks/ecal/options/crystal_calorimeter_reco.py -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running juggler" - exit 1 -fi - - -mkdir -p results - -#rootls ${JUGGLER_DETECTOR}/${JUGGLER_REC_FILE} -root -b -q "benchmarks/ecal/scripts/rec_emcal_electrons_reader.C(${E_start}, ${E_end}, \"${JUGGLER_REC_FILE}\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi -#root -b -q "ecal/scripts/makeplot.C(${E_start}, ${E_end}, \"${JUGGLER_DETECTOR}/${JUGGLER_REC_FILE}\", \"results/rec_${JUGGLER_FILE_NAME_TAG}.txt\")" -#root -b -q "ecal/scripts/makeplot_input.C(\"${JUGGLER_DETECTOR}/${JUGGLER_SIM_FILE}\", \"results/sim_${JUGGLER_FILE_NAME_TAG}.txt\")" - -root -b -q "benchmarks/ecal/scripts/crystal_cal_electrons.cxx(\"${JUGGLER_REC_FILE}\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi - -root -b -q "benchmarks/ecal/scripts/emcal_electrons_analysis.cxx(\"${JUGGLER_REC_FILE}\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi - -# Script to generate energy resolution plots -root -b -q "benchmarks/ecal/scripts/rec_emcal_resolution_analysis.cxx(\"${JUGGLER_REC_FILE}\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi - -#paste results/sim_${JUGGLER_FILE_NAME_TAG}.txt results/rec_${JUGGLER_FILE_NAME_TAG}.txt > results/eng_${JUGGLER_FILE_NAME_TAG}.txt -#root -b -q "ecal/scripts/read_eng.C(\"results/eng_${JUGGLER_FILE_NAME_TAG}.root\", \"results/eng_${JUGGLER_FILE_NAME_TAG}.txt\")" -#root -b -q "ecal/scripts/cal_eng_res.C(\"results/eng_${JUGGLER_FILE_NAME_TAG}.root\")" -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 ${JUGGLER_REC_FILE} results/. - fi -fi - diff --git a/benchmarks/ecal/emcal_pi0s.sh b/benchmarks/ecal/emcal_pi0s.sh deleted file mode 100644 index c3895aedd6ea6680d3a395ac815d4aafbb4d258e..0000000000000000000000000000000000000000 --- a/benchmarks/ecal/emcal_pi0s.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash -# Based on emcal_electrons.sh script - -print_env.sh - -## To run the reconstruction, we need the following global variables: -## - JUGGLER_INSTALL_PREFIX: Install prefix for Juggler (simu/recon) -## - JUGGLER_DETECTOR: the detector package we want to use for this benchmark -## - JUGGLER_DETECTOR_VERSION: the detector package we want to use for this benchmark -## - DETECTOR_PATH: full path to the detector definitions -## -## You can read .local/bin/env.sh for more in-depth explanations of the variables -## and how they can be controlled. - -if [[ ! -n "${JUGGLER_N_EVENTS}" ]] ; then - export JUGGLER_N_EVENTS=100 -fi - -if [[ ! -n "${JUGGLER_DETECTOR_PATH}" ]] ; then - export JUGGLER_DETECTOR_PATH=${DETECTOR_PATH} -fi - -# File names -export JUGGLER_FILE_NAME_TAG="emcal_uniform_pi0s" -export JUGGLER_GEN_FILE="${JUGGLER_FILE_NAME_TAG}.hepmc" - -export JUGGLER_SIM_FILE="sim_${JUGGLER_FILE_NAME_TAG}.root" -export JUGGLER_REC_FILE="rec_${JUGGLER_FILE_NAME_TAG}.root" - -echo "JUGGLER_N_EVENTS = ${JUGGLER_N_EVENTS}" -echo "JUGGLER_DETECTOR = ${JUGGLER_DETECTOR}" -# Datasets -#git clone https://eicweb.phy.anl.gov/EIC/datasets.git datasets -root -b -q "benchmarks/ecal/scripts/emcal_pi0.cxx(${JUGGLER_N_EVENTS}, \"${JUGGLER_FILE_NAME_TAG}.hepmc\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi -root -b -q "benchmarks/ecal/scripts/emcal_pi0_reader.cxx(\"${JUGGLER_FILE_NAME_TAG}.hepmc\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi - -echo "CHECK POINT FOR GEANT4 SIMULATION" - -echo "JUGGLER_N_EVENTS = ${JUGGLER_N_EVENTS}" -echo "JUGGLER_DETECTOR = ${JUGGLER_DETECTOR}" -echo "JUGGLER_FILE_NAME_TAG = ${JUGGLER_FILE_NAME_TAG}" -echo "JUGGLER_SIM_FILE = ${JUGGLER_SIM_FILE}" -# run geant4 simulations -npsim --runType batch \ - --part.minimalKineticEnergy 1000*GeV \ - -v WARNING \ - --numberOfEvents ${JUGGLER_N_EVENTS} \ - --compactFile ${JUGGLER_DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml \ - --inputFiles ${JUGGLER_FILE_NAME_TAG}.hepmc \ - --outputFile ${JUGGLER_SIM_FILE} -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running npdet" - exit 1 -fi - -# Need to figure out how to pass file name to juggler from the commandline -gaudirun.py benchmarks/ecal/options/crystal_calorimeter_reco.py -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running juggler" - exit 1 -fi - - -mkdir -p results -root -b -q "benchmarks/ecal/scripts/emcal_pion_anlaysis.cxx(\"${JUGGLER_REC_FILE}\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi - -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 ${JUGGLER_REC_FILE} results/. - fi -fi - diff --git a/benchmarks/ecal/full_emcal_electrons.sh b/benchmarks/ecal/full_emcal_electrons.sh deleted file mode 100644 index b634d19e3441206eeab780ab9abc479d5be6bbbb..0000000000000000000000000000000000000000 --- a/benchmarks/ecal/full_emcal_electrons.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash - -print_env.sh - -## To run the reconstruction, we need the following global variables: -## - JUGGLER_INSTALL_PREFIX: Install prefix for Juggler (simu/recon) -## - JUGGLER_DETECTOR: the detector package we want to use for this benchmark -## - JUGGLER_DETECTOR_VERSION: the detector package we want to use for this benchmark -## - DETECTOR_PATH: full path to the detector definitions -## -## You can ready options/env.sh for more in-depth explanations of the variables -## and how they can be controlled. -source options/env.sh -if [[ ! -n "${JUGGLER_DETECTOR_PATH}" ]] ; then - export JUGGLER_DETECTOR_PATH=${DETECTOR_PATH} -fi - -if [[ ! -n "${JUGGLER_N_EVENTS}" ]] ; then - export JUGGLER_N_EVENTS=100 -fi - -if [[ ! -n "${E_start}" ]] ; then - export E_start=0.5 -fi - -if [[ ! -n "${E_end}" ]] ; then - export E_end=5.0 -fi - -export JUGGLER_FILE_NAME_TAG="emcal_uniform_electrons" -export JUGGLER_GEN_FILE="${JUGGLER_FILE_NAME_TAG}.hepmc" - -export JUGGLER_SIM_FILE="sim_${JUGGLER_FILE_NAME_TAG}.root" -export JUGGLER_REC_FILE="rec_${JUGGLER_FILE_NAME_TAG}.root" - -echo "JUGGLER_N_EVENTS = ${JUGGLER_N_EVENTS}" -echo "JUGGLER_DETECTOR = ${JUGGLER_DETECTOR}" - -# generate the input events -# note datasets is now only used to develop datasets. -#git clone https://eicweb.phy.anl.gov/EIC/datasets.git datasets -root -b -q "benchmarks/ecal/scripts/full_emcal_electrons.cxx(${JUGGLER_N_EVENTS}, ${E_start}, ${E_end}, \"${JUGGLER_FILE_NAME_TAG}.hepmc\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running script" - exit 1 -fi - -# run geant4 simulations -npsim --runType batch \ - -v WARNING \ - --part.minimalKineticEnergy 1*GeV \ - --numberOfEvents ${JUGGLER_N_EVENTS} \ - --compactFile ${JUGGLER_DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml \ - --inputFiles ${JUGGLER_FILE_NAME_TAG}.hepmc \ - --outputFile ${JUGGLER_SIM_FILE} -# Need to figure out how to pass file name to juggler from the commandline -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running npdet" - exit 1 -fi - -xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py benchmarks/ecal/options/full_em_calorimeter_reco.py -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running juggler" - exit 1 -fi - -root -b -q "benchmarks/ecal/scripts/full_emcal_electrons_analysis.cxx(\"${JUGGLER_REC_FILE}\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi - -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 ${JUGGLER_REC_FILE} results/. - fi -fi - diff --git a/benchmarks/ecal/options/barrel.py b/benchmarks/ecal/options/barrel.py new file mode 100644 index 0000000000000000000000000000000000000000..f44bf58fca4c4e76ce84125f76d0b10269b3e6de --- /dev/null +++ b/benchmarks/ecal/options/barrel.py @@ -0,0 +1,99 @@ +''' + An example script to digitize/reconstruct/clustering endcap ecal 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("JUGGLER_DETECTOR_PATH", ".")) +compact_path = str(os.environ.get("JUGGLER_COMPACT_PATH", "{}.xml".format(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_REC_FILE"]) +n_events = int(os.environ["JUGGLER_N_EVENTS"]) +cb_ecal_sf = float(os.environ.get("CB_ECAL_SAMP_FRAC", 0.01324)) + +# geometry service +geo_service = GeoSvc("GeoSvc", detectors=[compact_path], OutputLevel=INFO) +# 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__ImagingPixelReco as ImCalPixelReco +from Configurables import Jug__Reco__ImagingTopoCluster as ImagingCluster +from Configurables import Jug__Reco__ImagingClusterReco as ImagingClusterReco + +# branches needed from simulation root file +sim_coll = [ + "mcparticles", + "EcalBarrelHits", +] + +# 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") + + +# 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") + +podout.outputCommands = ['drop *', + 'keep mcparticles2', + 'keep *HitsReco', + 'keep *HitsDigi', + 'keep *ClusterHits', + 'keep *Clusters'] + +ApplicationMgr( + TopAlg = [podin, copier, + cb_ecal_digi, cb_ecal_reco, cb_ecal_cl, cb_ecal_clreco, + podout], + EvtSel = 'NONE', + EvtMax = n_events, + ExtSvc = [podioevent], + OutputLevel=DEBUG +) diff --git a/benchmarks/ecal/options/crystal_calorimeter_reco.py b/benchmarks/ecal/options/deprecated/crystal_calorimeter_reco.py similarity index 100% rename from benchmarks/ecal/options/crystal_calorimeter_reco.py rename to benchmarks/ecal/options/deprecated/crystal_calorimeter_reco.py diff --git a/benchmarks/ecal/options/emcal_barrel_reco.py b/benchmarks/ecal/options/deprecated/emcal_barrel_reco.py similarity index 100% rename from benchmarks/ecal/options/emcal_barrel_reco.py rename to benchmarks/ecal/options/deprecated/emcal_barrel_reco.py diff --git a/benchmarks/ecal/options/full_em_calorimeter_reco.py b/benchmarks/ecal/options/deprecated/full_em_calorimeter_reco.py similarity index 100% rename from benchmarks/ecal/options/full_em_calorimeter_reco.py rename to benchmarks/ecal/options/deprecated/full_em_calorimeter_reco.py diff --git a/benchmarks/ecal/options/endcap_e.py b/benchmarks/ecal/options/endcap_e.py new file mode 100644 index 0000000000000000000000000000000000000000..9dee7fb8c6fa8a94643d8a030b1c6020b8433384 --- /dev/null +++ b/benchmarks/ecal/options/endcap_e.py @@ -0,0 +1,98 @@ +''' + An example script to digitize/reconstruct/clustering endcap ecal 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("JUGGLER_DETECTOR_PATH", ".")) +compact_path = str(os.environ.get("JUGGLER_COMPACT_PATH", "{}.xml".format(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_REC_FILE"]) +n_events = int(os.environ["JUGGLER_N_EVENTS"]) + +# geometry service +geo_service = GeoSvc("GeoSvc", detectors=[compact_path], OutputLevel=INFO) +# 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__CalorimeterIslandCluster as IslandCluster +from Configurables import Jug__Reco__ClusterRecoCoG as RecoCoG + +# branches needed from simulation root file +sim_coll = [ + "mcparticles", + "EcalEndcapNHits", +] + +# 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_daq = dict( + dynamicRangeADC=5.*GeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=3) + +ce_ecal_digi = CalHitDigi("ce_ecal_digi", + inputHitCollection="EcalEndcapNHits", + outputHitCollection="EcalEndcapNHitsDigi", + energyResolutions=[0., 0.02, 0.], + **ce_ecal_daq) + +ce_ecal_reco = CalHitReco("ce_ecal_reco", + inputHitCollection="EcalEndcapNHitsDigi", + outputHitCollection="EcalEndcapNHitsReco", + thresholdFactor=4, # 4 sigma cut on pedestal sigma + readoutClass="EcalEndcapNHits", + sectorField="sector", + **ce_ecal_daq) + +ce_ecal_cl = IslandCluster("ce_ecal_cl", + # OutputLevel=DEBUG, + inputHitCollection="EcalEndcapNHitsReco", + outputHitCollection="EcalEndcapNClusterHits", + splitCluster=False, + minClusterHitEdep=1.0*MeV, # discard low energy hits + minClusterCenterEdep=30*MeV, + dimScaledDist=1.8) # hybrid calorimeter with different dimensions, using a scaled dist + +ce_ecal_clreco = RecoCoG("ce_ecal_clreco", + inputHitCollection="EcalEndcapNClusterHits", + outputClusterCollection="EcalEndcapNClusters", + samplingFraction=0.998, # this accounts for a small fraction of leakage + logWeightBase=4.6) + +podout.outputCommands = ['drop *', + 'keep mcparticles2', + 'keep *HitsReco', + 'keep *HitsDigi', + 'keep *ClusterHits', + 'keep *Clusters'] + +ApplicationMgr( + TopAlg = [podin, copier, + ce_ecal_digi, ce_ecal_reco, ce_ecal_cl, ce_ecal_clreco, + podout], + EvtSel = 'NONE', + EvtMax = n_events, + ExtSvc = [podioevent], + OutputLevel=DEBUG +) diff --git a/benchmarks/ecal/options/endcap_i.py b/benchmarks/ecal/options/endcap_i.py new file mode 100644 index 0000000000000000000000000000000000000000..7e5553b609cd27cc1c00ba20c31501fbff9fc87c --- /dev/null +++ b/benchmarks/ecal/options/endcap_i.py @@ -0,0 +1,106 @@ + +''' + An example script to digitize/reconstruct/clustering endcap ecal 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("JUGGLER_DETECTOR_PATH", ".")) +compact_path = str(os.environ.get("JUGGLER_COMPACT_PATH", "{}.xml".format(os.path.join(detector_path, detector_name)))) +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"]) + +# geometry service +geo_service = GeoSvc("GeoSvc", detectors=[compact_path], OutputLevel=INFO) +# 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__ClusterRecoCoG as RecoCoG + +# branches needed from simulation root file +sim_coll = [ + "mcparticles", + "EcalEndcapPHits", +] + +# 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") + + +# Endcap sampling Ecal +ci_ecal_daq = dict( + dynamicRangeADC=50.*MeV, + capacityADC=32768, + pedestalMean=400, + pedestalSigma=10) + +ci_ecal_digi = CalHitDigi("ci_ecal_digi", + inputHitCollection="EcalEndcapPHits", + outputHitCollection="EcalEndcapPHitsDigi", + **ci_ecal_daq) + +ci_ecal_reco = CalHitReco("ci_ecal_reco", + inputHitCollection="EcalEndcapPHitsDigi", + outputHitCollection="EcalEndcapPHitsReco", + thresholdFactor=5.0, + **ci_ecal_daq) + +# merge hits in different layer (projection to local x-y plane) +ci_ecal_merger = CalHitsMerger("ci_ecal_merger", + # OutputLevel=DEBUG, + inputHitCollection="EcalEndcapPHitsReco", + outputHitCollection="EcalEndcapPHitsRecoXY", + fields=["layer", "slice"], + fieldRefNumbers=[1, 0], + readoutClass="EcalEndcapPHits") + +ci_ecal_cl = IslandCluster("ci_ecal_cl", + # OutputLevel=DEBUG, + inputHitCollection="EcalEndcapPHitsRecoXY", + outputHitCollection="EcalEndcapPClusterHits", + splitCluster=False, + minClusterCenterEdep=10.*MeV, + localDistXY=[10*mm, 10*mm]) + +ci_ecal_clreco = RecoCoG("ci_ecal_clreco", + inputHitCollection="EcalEndcapPClusterHits", + outputClusterCollection="EcalEndcapPClusters", + logWeightBase=6.2, + samplingFraction=ci_ecal_sf) + +podout.outputCommands = ['drop *', + 'keep mcparticles2', + 'keep *HitsReco*', + 'keep *HitsDigi', + 'keep *ClusterHits', + 'keep *Clusters'] + +ApplicationMgr( + TopAlg = [podin, copier, + ci_ecal_digi, ci_ecal_reco, ci_ecal_merger, ci_ecal_cl, ci_ecal_clreco, + podout], + EvtSel = 'NONE', + EvtMax = n_events, + ExtSvc = [podioevent], + OutputLevel=DEBUG +) diff --git a/benchmarks/ecal/run_emcal_barrel_electrons.sh b/benchmarks/ecal/run_emcal_barrel_electrons.sh deleted file mode 100755 index bd6351d8c9200ddb33c31e2a2ea068b170e7bd72..0000000000000000000000000000000000000000 --- a/benchmarks/ecal/run_emcal_barrel_electrons.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash - -print_env.sh - -## To run the reconstruction, we need the following global variables: -## - JUGGLER_INSTALL_PREFIX: Install prefix for Juggler (simu/recon) -## - JUGGLER_DETECTOR: the detector package we want to use for this benchmark -## - JUGGLER_DETECTOR_VERSION: the detector package we want to use for this benchmark -## - DETECTOR_PATH: full path to the detector definitions -## -## You can ready options/env.sh for more in-depth explanations of the variables -## and how they can be controlled. -source options/env.sh -if [[ ! -n "${JUGGLER_DETECTOR_PATH}" ]] ; then - export JUGGLER_DETECTOR_PATH=${DETECTOR_PATH} -fi - -if [[ ! -n "${JUGGLER_N_EVENTS}" ]] ; then - export JUGGLER_N_EVENTS=1000 -fi - -if [[ ! -n "${E_start}" ]] ; then - export E_start=5.0 -fi - -if [[ ! -n "${E_end}" ]] ; then - export E_end=5.0 -fi - -if [[ ! -n "${CB_EMCAL_SAMP_FRAC}" ]] ; then - export CB_EMCAL_SAMP_FRAC=0.014 -fi - -export JUGGLER_FILE_NAME_TAG="emcal_barrel_uniform_electrons" -export JUGGLER_GEN_FILE="${JUGGLER_FILE_NAME_TAG}.hepmc" - -export JUGGLER_SIM_FILE="sim_${JUGGLER_FILE_NAME_TAG}.root" -export JUGGLER_REC_FILE="rec_${JUGGLER_FILE_NAME_TAG}.root" - -echo "JUGGLER_N_EVENTS = ${JUGGLER_N_EVENTS}" -echo "JUGGLER_DETECTOR = ${JUGGLER_DETECTOR}" - -# Generate the input events -root -b -q "benchmarks/ecal/scripts/emcal_barrel_electrons.cxx(${JUGGLER_N_EVENTS}, ${E_start}, ${E_end}, \"${JUGGLER_FILE_NAME_TAG}.hepmc\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running script: generating input events" - exit 1 -fi -# Plot the input events -root -b -q "benchmarks/ecal/scripts/emcal_barrel_electrons_reader.cxx(${E_start}, ${E_end}, \"${JUGGLER_FILE_NAME_TAG}.hepmc\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running script: plotting input events" - exit 1 -fi - -# Run geant4 simulations -npsim --runType batch \ - -v WARNING \ - --part.minimalKineticEnergy 0.5*GeV \ - --numberOfEvents ${JUGGLER_N_EVENTS} \ - --compactFile ${JUGGLER_DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml \ - --inputFiles ${JUGGLER_FILE_NAME_TAG}.hepmc \ - --outputFile ${JUGGLER_SIM_FILE} - -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running npdet" - exit 1 -fi - - -rootls -t "${JUGGLER_SIM_FILE}" - -# Run Juggler -xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py benchmarks/ecal/options/emcal_barrel_reco.py -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running juggler" - exit 1 -fi - -# Directory for plots -mkdir -p results - -# Run analysis script -root -b -q "benchmarks/ecal/scripts/emcal_barrel_electrons_analysis.cxx(\"${JUGGLER_REC_FILE}\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi - -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 ${JUGGLER_REC_FILE} results/. - fi -fi - diff --git a/benchmarks/ecal/run_emcal_barrel_pions.sh b/benchmarks/ecal/run_emcal_barrel_pions.sh deleted file mode 100755 index b25086a56bfcccabdb480173582b25de6d5cfb52..0000000000000000000000000000000000000000 --- a/benchmarks/ecal/run_emcal_barrel_pions.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash - -print_env.sh - -## To run the reconstruction, we need the following global variables: -## - JUGGLER_INSTALL_PREFIX: Install prefix for Juggler (simu/recon) -## - JUGGLER_DETECTOR: the detector package we want to use for this benchmark -## - JUGGLER_DETECTOR_VERSION: the detector package we want to use for this benchmark -## - DETECTOR_PATH: full path to the detector definitions -## -## You can ready options/env.sh for more in-depth explanations of the variables -## and how they can be controlled. -source options/env.sh -if [[ ! -n "${JUGGLER_DETECTOR_PATH}" ]] ; then - export JUGGLER_DETECTOR_PATH=${DETECTOR_PATH} -fi - -if [[ ! -n "${JUGGLER_N_EVENTS}" ]] ; then - export JUGGLER_N_EVENTS=1000 -fi - -if [[ ! -n "${E_start}" ]] ; then - export E_start=5.0 -fi - -if [[ ! -n "${E_end}" ]] ; then - export E_end=5.0 -fi - -if [[ ! -n "${CB_EMCAL_SAMP_FRAC}" ]] ; then - export CB_EMCAL_SAMP_FRAC=0.01 -fi - -export JUGGLER_FILE_NAME_TAG="emcal_barrel_uniform_pions" -export JUGGLER_GEN_FILE="${JUGGLER_FILE_NAME_TAG}.hepmc" - -export JUGGLER_SIM_FILE="sim_${JUGGLER_FILE_NAME_TAG}.root" -export JUGGLER_REC_FILE="rec_${JUGGLER_FILE_NAME_TAG}.root" - -echo "JUGGLER_N_EVENTS = ${JUGGLER_N_EVENTS}" -echo "JUGGLER_DETECTOR = ${JUGGLER_DETECTOR}" - -# Generate the input events -root -b -q "benchmarks/ecal/scripts/emcal_barrel_pions.cxx(${JUGGLER_N_EVENTS}, ${E_start}, ${E_end}, \"${JUGGLER_FILE_NAME_TAG}.hepmc\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running script: generating input events" - exit 1 -fi -# Plot the input events -root -b -q "benchmarks/ecal/scripts/emcal_barrel_pions_reader.cxx(${E_start}, ${E_end}, \"${JUGGLER_FILE_NAME_TAG}.hepmc\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running script: plotting input events" - exit 1 -fi - -# Run geant4 simulations -npsim --runType batch \ - -v WARNING \ - --part.minimalKineticEnergy 0.5*GeV \ - --numberOfEvents ${JUGGLER_N_EVENTS} \ - --compactFile ${JUGGLER_DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml \ - --inputFiles ${JUGGLER_FILE_NAME_TAG}.hepmc \ - --outputFile ${JUGGLER_SIM_FILE} - -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running npdet" - exit 1 -fi - -# Run Juggler -xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \ - gaudirun.py benchmarks/ecal/options/emcal_barrel_reco.py -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running juggler" - exit 1 -fi - -# Directory for plots -mkdir -p results - -# Run analysis script -root -b -q "benchmarks/ecal/scripts/emcal_barrel_pions_analysis.cxx(\"${JUGGLER_REC_FILE}\")" -if [[ "$?" -ne "0" ]] ; then - echo "ERROR running analysis script" - exit 1 -fi - -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 ${JUGGLER_REC_FILE} results/. - fi -fi - diff --git a/benchmarks/ecal/run_emcal_benchmarks.py b/benchmarks/ecal/run_emcal_benchmarks.py new file mode 100755 index 0000000000000000000000000000000000000000..c895735e6fb0917594803a1f3f8fc34dd7b205bd --- /dev/null +++ b/benchmarks/ecal/run_emcal_benchmarks.py @@ -0,0 +1,121 @@ +#! /usr/local/bin/python3 +''' + A python script to help run emcal benchmarks + simulation -> reconstruction -> analysis + Author: Chao Peng, Jihee Kim (ANL) + Date: 07/04/2021 +''' +import os +import sys +import subprocess +import argparse + + +# type: option files, analysis files +default_type = { + 'endcap_e': [['endcap_e.py'], []], + 'endcap_i': [['endcap_i.py'], []], + 'barrel': [['barrel.py'], []], +# 'all': [['all_ecal.py'], []], +} + +default_compact = os.path.join(os.environ.get('JUGGLER_DETECTOR_PATH', os.environ.get('DETECTOR_PATH', '')), + '{}.xml'.format(os.environ.get('JUGGLER_DETECTOR', ''))) +parser = argparse.ArgumentParser() +parser.add_argument('run_type', help='Run type, support {}'.format(list(default_type.keys()))) +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='IMCAL_ML', help='Name tag for output files.') +parser.add_argument('--seed', type=int, default=-1, help='Random seed to scripts.') +parser.add_argument('--process', type=str, default='sim, rec, ana', help='Processes to be executed (sim, rec, ana).') +parser.add_argument('--numberOfLayers', dest='nlayer', type=int, default=20, help='number of layers in ML data.') +parser.add_argument('--numberOfHits', dest='nhit', type=int, default=20, help='number of hits in ML data.') +parser.add_argument('--particles', type=str, default='electron', help='Partcile names, separated by \",\".') +parser.add_argument('--amin', type=float, default=5, help='Minimum polar angle of particles (degree).') +parser.add_argument('--amax', type=float, default=175, help='Maximum polar angle of particles (degree).') +parser.add_argument('--pmin', type=float, default=0.5, help='Minimum momentum of particles (GeV).') +parser.add_argument('--pmax', type=float, default=10, help='Maximum momentum of particles (GeV).') +parser.add_argument('--compact', type=str, default=default_compact, help='Path to detector compact file.') +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) + +if args.run_type not in default_type: + print('ERROR unsupported run type {}, must in {}'.format(args.run_type, list(default_type.keys()))) + exit(1) +opt_scripts, ana_scripts = default_type[args.run_type] + +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) + +procs = [p.strip() for p in args.process.split(',')] +sdir = os.path.dirname(os.path.realpath(__file__)) + +if 'sim' in procs: + # generate particles + gen_cmd = ['python', os.path.join(sdir, 'scripts', 'gen_particles.py'), gen_file, + '-n', '{}'.format(args.nev), + '-s', '{}'.format(args.seed), + '--angmin', '{}'.format(args.amin), '--angmax', '{}'.format(args.amax), + '--pmin', '{}'.format(args.pmin), '--pmax', '{}'.format(args.pmax), + '--particles', args.particles] + subprocess.run(gen_cmd) + # simulation + sim_cmd = ['npsim', + '--part.minimalKineticEnergy', '1*TeV', + '--numberOfEvents', '{}'.format(args.nev), + '--runType', 'batch', + '--inputFiles', gen_file, + '--outputFile', sim_file, + '--compact', args.compact, + '-v', 'WARNING'] + if args.seed > 0: + sim_cmd += ['--random.seed', args.seed] + print(sim_cmd) + return_code = subprocess.run(sim_cmd).returncode + if return_code is not None and return_code < 0: + print("ERROR running simulation!") + exit(1) + subprocess.run(['rootls', '-t', sim_file]) + + +if 'rec' in procs: + # export to environment variables (used to pass arguments to the option file) + os.environ['JUGGLER_SIM_FILE'] = sim_file + os.environ['JUGGLER_REC_FILE'] = rec_file + os.environ['JUGGLER_COMPACT_PATH'] = args.compact + os.environ['JUGGLER_N_EVENTS'] = '{}'.format(args.nev) + + juggler_xenv = os.path.join(os.environ.get('JUGGLER_INSTALL_PREFIX', '../local'), 'Juggler.xenv') + + for opt in opt_scripts: + rec_cmd = ['xenv', '-x', juggler_xenv, 'gaudirun.py', os.path.join(sdir, 'options', opt)] + return_code = subprocess.run(rec_cmd).returncode + if return_code is not None and return_code < 0: + print('ERROR running juggler ({})!'.format(opt)) + exit(1) + process = subprocess.run(['rootls', '-t', rec_file]) + + +if 'ana' in procs: + os.makedirs('results', exist_ok=True) + for ana in ana_scripts: + ana_cmd = ['python', os.path.join(sdir, 'scripts', ana), rec_file, '-o', 'results'] + return_code = subprocess.run(ana_cmd).returncode + if return_code is not None and return_code < 0: + print('ERROR running analysis ({})!'.format(ana)) + exit(1) + + +# upload generated data files if it was small enough (< 10 Mb) +for upload in [rec_file]: + process = subprocess.run(['stat', '--format=%s', upload], stdout=subprocess.PIPE) + size = int(process.stdout)/1024./1024. + if size > args.uploadSizeLimit: + print('Skip uploading file \"{}\" because its size ({:.2f} Mb) > {:.2f} Mb'\ + .format(upload, size, args.uploadSizeLimit)) + else: + os.system('cp {} results/.'.format(upload)) + print('Upload file \"{}\", size = {:.2f} Mb'.format(upload, size)) + diff --git a/benchmarks/ecal/scripts/cal_eng_res.C b/benchmarks/ecal/scripts/deprecated/cal_eng_res.C similarity index 100% rename from benchmarks/ecal/scripts/cal_eng_res.C rename to benchmarks/ecal/scripts/deprecated/cal_eng_res.C diff --git a/benchmarks/ecal/scripts/crystal_cal_electrons.cxx b/benchmarks/ecal/scripts/deprecated/crystal_cal_electrons.cxx similarity index 100% rename from benchmarks/ecal/scripts/crystal_cal_electrons.cxx rename to benchmarks/ecal/scripts/deprecated/crystal_cal_electrons.cxx diff --git a/benchmarks/ecal/scripts/emcal_barrel_electrons.cxx b/benchmarks/ecal/scripts/deprecated/emcal_barrel_electrons.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_barrel_electrons.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_barrel_electrons.cxx diff --git a/benchmarks/ecal/scripts/emcal_barrel_electrons_analysis.cxx b/benchmarks/ecal/scripts/deprecated/emcal_barrel_electrons_analysis.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_barrel_electrons_analysis.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_barrel_electrons_analysis.cxx diff --git a/benchmarks/ecal/scripts/emcal_barrel_electrons_reader.cxx b/benchmarks/ecal/scripts/deprecated/emcal_barrel_electrons_reader.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_barrel_electrons_reader.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_barrel_electrons_reader.cxx diff --git a/benchmarks/ecal/scripts/emcal_barrel_pions.cxx b/benchmarks/ecal/scripts/deprecated/emcal_barrel_pions.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_barrel_pions.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_barrel_pions.cxx diff --git a/benchmarks/ecal/scripts/emcal_barrel_pions_analysis.cxx b/benchmarks/ecal/scripts/deprecated/emcal_barrel_pions_analysis.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_barrel_pions_analysis.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_barrel_pions_analysis.cxx diff --git a/benchmarks/ecal/scripts/emcal_barrel_pions_reader.cxx b/benchmarks/ecal/scripts/deprecated/emcal_barrel_pions_reader.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_barrel_pions_reader.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_barrel_pions_reader.cxx diff --git a/benchmarks/ecal/scripts/emcal_electrons.cxx b/benchmarks/ecal/scripts/deprecated/emcal_electrons.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_electrons.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_electrons.cxx diff --git a/benchmarks/ecal/scripts/emcal_electrons_analysis.cxx b/benchmarks/ecal/scripts/deprecated/emcal_electrons_analysis.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_electrons_analysis.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_electrons_analysis.cxx diff --git a/benchmarks/ecal/scripts/emcal_electrons_reader.cxx b/benchmarks/ecal/scripts/deprecated/emcal_electrons_reader.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_electrons_reader.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_electrons_reader.cxx diff --git a/benchmarks/ecal/scripts/emcal_pi0.cxx b/benchmarks/ecal/scripts/deprecated/emcal_pi0.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_pi0.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_pi0.cxx diff --git a/benchmarks/ecal/scripts/emcal_pi0_reader.cxx b/benchmarks/ecal/scripts/deprecated/emcal_pi0_reader.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_pi0_reader.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_pi0_reader.cxx diff --git a/benchmarks/ecal/scripts/emcal_pion_anlaysis.cxx b/benchmarks/ecal/scripts/deprecated/emcal_pion_anlaysis.cxx similarity index 100% rename from benchmarks/ecal/scripts/emcal_pion_anlaysis.cxx rename to benchmarks/ecal/scripts/deprecated/emcal_pion_anlaysis.cxx diff --git a/benchmarks/ecal/scripts/full_emcal_electrons.cxx b/benchmarks/ecal/scripts/deprecated/full_emcal_electrons.cxx similarity index 100% rename from benchmarks/ecal/scripts/full_emcal_electrons.cxx rename to benchmarks/ecal/scripts/deprecated/full_emcal_electrons.cxx diff --git a/benchmarks/ecal/scripts/full_emcal_electrons_analysis.cxx b/benchmarks/ecal/scripts/deprecated/full_emcal_electrons_analysis.cxx similarity index 100% rename from benchmarks/ecal/scripts/full_emcal_electrons_analysis.cxx rename to benchmarks/ecal/scripts/deprecated/full_emcal_electrons_analysis.cxx diff --git a/benchmarks/ecal/scripts/makeplot.C b/benchmarks/ecal/scripts/deprecated/makeplot.C similarity index 100% rename from benchmarks/ecal/scripts/makeplot.C rename to benchmarks/ecal/scripts/deprecated/makeplot.C diff --git a/benchmarks/ecal/scripts/makeplot_input.C b/benchmarks/ecal/scripts/deprecated/makeplot_input.C similarity index 100% rename from benchmarks/ecal/scripts/makeplot_input.C rename to benchmarks/ecal/scripts/deprecated/makeplot_input.C diff --git a/benchmarks/ecal/scripts/makeplot_pi0.C b/benchmarks/ecal/scripts/deprecated/makeplot_pi0.C similarity index 100% rename from benchmarks/ecal/scripts/makeplot_pi0.C rename to benchmarks/ecal/scripts/deprecated/makeplot_pi0.C diff --git a/benchmarks/ecal/scripts/rdf_test.cxx b/benchmarks/ecal/scripts/deprecated/rdf_test.cxx similarity index 100% rename from benchmarks/ecal/scripts/rdf_test.cxx rename to benchmarks/ecal/scripts/deprecated/rdf_test.cxx diff --git a/benchmarks/ecal/scripts/read_eng.C b/benchmarks/ecal/scripts/deprecated/read_eng.C similarity index 100% rename from benchmarks/ecal/scripts/read_eng.C rename to benchmarks/ecal/scripts/deprecated/read_eng.C diff --git a/benchmarks/ecal/scripts/rec_emcal_electrons_reader.C b/benchmarks/ecal/scripts/deprecated/rec_emcal_electrons_reader.C similarity index 100% rename from benchmarks/ecal/scripts/rec_emcal_electrons_reader.C rename to benchmarks/ecal/scripts/deprecated/rec_emcal_electrons_reader.C diff --git a/benchmarks/ecal/scripts/rec_emcal_resolution_analysis.cxx b/benchmarks/ecal/scripts/deprecated/rec_emcal_resolution_analysis.cxx similarity index 100% rename from benchmarks/ecal/scripts/rec_emcal_resolution_analysis.cxx rename to benchmarks/ecal/scripts/deprecated/rec_emcal_resolution_analysis.cxx diff --git a/benchmarks/ecal/scripts/gen_particles.py b/benchmarks/ecal/scripts/gen_particles.py new file mode 100644 index 0000000000000000000000000000000000000000..2d0b81c8278d345cff479161f107f08f62c55bf1 --- /dev/null +++ b/benchmarks/ecal/scripts/gen_particles.py @@ -0,0 +1,104 @@ +import os +from pyHepMC3 import HepMC3 as hm +import numpy as np +import argparse + + +PARTICLES = { + "pion0": (111, 0.1349766), # pi0 + "pion+": (211, 0.13957018), # pi+ + "pion-": (-211, 0.13957018), # pi- + "kaon0": (311, 0.497648), # K0 + "kaon+": (321, 0.493677), # K+ + "kaon-": (-321, 0.493677), # K- + "proton": (2212, 0.938272), # proton + "neutron": (2112, 0.939565), # neutron + "electron": (11, 0.51099895e-3), # electron + "positron": (-11, 0.51099895e-3),# positron + "photon": (22, 0), # photon +} + + +def gen_event(p, theta, phi, pid, mass): + evt = hm.GenEvent(momentum_unit=hm.Units.MomentumUnit.GEV, length_unit=hm.Units.LengthUnit.MM) + # final state + state = 1 + e0 = np.sqrt(p*p + mass*mass) + px = np.cos(phi)*np.sin(theta) + py = np.sin(phi)*np.sin(theta) + pz = np.cos(theta) + + # beam + pbeam = hm.GenParticle(hm.FourVector(0, 0, 0, 0.938272), 2212, 4) + ebeam = hm.GenParticle(hm.FourVector(0, 0, e0, np.sqrt(e0*e0 + 0.511e-3*0.511e-3)), 11, 4) + + # out particle + hout = hm.GenParticle(hm.FourVector(px*p, py*p, pz*p, e0), pid, state) + + # vertex + vert = hm.GenVertex() + vert.add_particle_in(ebeam) + vert.add_particle_in(pbeam) + vert.add_particle_out(hout) + evt.add_vertex(vert) + return evt + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('output', help='path to the output file') + parser.add_argument('-n', type=int, default=1000, dest='nev', help='number of events to generate') + parser.add_argument('-s', type=int, default=-1, dest='seed', help='seed for random generator') + parser.add_argument('--parray', type=str, default="", dest='parray', + help='an array of momenta in GeV, separated by \",\"') + parser.add_argument('--pmin', type=float, default=8.0, dest='pmin', help='minimum momentum in GeV') + parser.add_argument('--pmax', type=float, default=100.0, dest='pmax', help='maximum momentum in GeV') + parser.add_argument('--angmin', type=float, default=0.0, dest='angmin', help='minimum angle in degree') + parser.add_argument('--angmax', type=float, default=20.0, dest='angmax', help='maximum angle in degree') + parser.add_argument('--phmin', type=float, default=0.0, dest='phmin', help='minimum angle in degree') + parser.add_argument('--phmax', type=float, default=360.0, dest='phmax', help='maximum angle in degree') + parser.add_argument('--particles', type=str, default='electron', dest='particles', + help='particle names, support {}'.format(list(PARTICLES.keys()))) + + args = parser.parse_args() + + # random seed (< 0 will get it from enviroment variable 'SEED', or a system random number) + if args.seed < 0: + args.seed = os.environ.get('SEED', int.from_bytes(os.urandom(4), byteorder='big', signed=False)) + print("Random seed is {}".format(args.seed)) + np.random.seed(args.seed) + + output = hm.WriterAscii(args.output); + if output.failed(): + print("Cannot open file \"{}\"".format(args.output)) + sys.exit(2) + + # build particle info + parts = [] + for pid in args.particles.split(','): + pid = pid.strip() + if pid not in PARTICLES.keys(): + print('pid {:d} not found in dictionary, ignored.'.format(pid)) + continue + parts.append(PARTICLES[pid]) + + # p values + pvals = np.random.uniform(args.pmin, args.pmax, args.nev) if not args.parray else \ + np.random.choice([float(p.strip()) for p in args.parray.split(',')], args.nev) + thvals = np.random.uniform(args.angmin, args.angmax, args.nev)/180.*np.pi + phivals = np.random.uniform(args.phmin, args.phmax, args.nev)/180.*np.pi + partvals = [parts[i] for i in np.random.choice(len(parts), args.nev)] + + count = 0 + for p, theta, phi, (pid, mass) in zip(pvals, thvals, phivals, partvals): + if (count % 1000 == 0): + print("Generated {} events".format(count), end='\r') + evt = gen_event(p, theta, phi, pid, mass) + output.write_event(evt) + evt.clear() + count += 1 + + print("Generated {} events".format(args.nev)) + output.close() + diff --git a/benchmarks/imaging_ecal/options/imaging_topocluster.py b/benchmarks/imaging_ecal/options/imaging_topocluster.py index 722985117bcb120eaca5921baf673751d766cb6b..fafb38156f47a6ebdaac9e3fc5ef308c0037a223 100644 --- a/benchmarks/imaging_ecal/options/imaging_topocluster.py +++ b/benchmarks/imaging_ecal/options/imaging_topocluster.py @@ -38,51 +38,58 @@ out = PodioOutput("out", filename=kwargs['output']) podioinput = PodioInput("PodioReader", collections=["mcparticles", "EcalBarrelHits"], OutputLevel=DEBUG) copier = MCCopier("MCCopier", - inputCollection="mcparticles", - outputCollection="mcparticles2", - OutputLevel=DEBUG) + OutputLevel=DEBUG, + inputCollection="mcparticles", + outputCollection="mcparticles2") calcopier = CalCopier("CalCopier", - inputCollection="EcalBarrelHits", - outputCollection="EcalBarrelHits2", - OutputLevel=DEBUG) + OutputLevel=DEBUG, + inputCollection="EcalBarrelHits", + outputCollection="EcalBarrelHits2") + +# use the same daq_setting for digi/reco pair +daq_setting = dict( + dynamicRangeADC=3*units.MeV, + capacityADC=32767, + pedestalMean=400, + pedestalSigma=50) # 50/32767*3 MeV ~ 5 keV imcaldigi = CalorimeterHitDigi("imcal_digi", - inputHitCollection="EcalBarrelHits", - outputHitCollection="DigiEcalBarrelHits", - inputEnergyUnit=units.GeV, - inputTimeUnit=units.ns, - energyResolutions=[0., 0.02, 0.], - dynamicRangeADC=3*units.MeV, - pedestalSigma=40, - OutputLevel=DEBUG) + OutputLevel=DEBUG, + inputHitCollection="EcalBarrelHits", + outputHitCollection="DigiEcalBarrelHits", + energyResolutions=[0., 0.02, 0.], + **daq_setting) imcalreco = ImagingPixelReco("imcal_reco", - inputHitCollection="DigiEcalBarrelHits", - outputHitCollection="RecoEcalBarrelHits", - dynamicRangeADC=3.*units.MeV, - pedestalSigma=40, - readoutClass="EcalBarrelHits", - layerField="layer", - sectorField="module") + OutputLevel=DEBUG, + inputHitCollection="DigiEcalBarrelHits", + outputHitCollection="RecoEcalBarrelHits", + readoutClass="EcalBarrelHits", + layerField="layer", + sectorField="module", + **daq_setting) + imcalcluster = ImagingTopoCluster("imcal_cluster", - inputHitCollection="RecoEcalBarrelHits", - outputHitCollection="EcalBarrelClusterHits", - localRanges=[2.*units.mm, 2*units.mm], - adjLayerRanges=[10*units.mrad, 10*units.mrad], - adjLayerDiff=2, - adjSectorDist=3.*units.cm) + OutputLevel=DEBUG, + inputHitCollection="RecoEcalBarrelHits", + outputHitCollection="EcalBarrelClusterHits", + localDistXY=[2.*units.mm, 2*units.mm], + layerDistEtaPhi=[10*units.mrad, 10*units.mrad], + neighbourLayersRange=2, + sectorDist=3.*units.cm) clusterreco = ImagingClusterReco("imcal_clreco", - inputHitCollection="EcalBarrelClusterHits", - outputLayerCollection="EcalBarrelClustersLayers", - outputClusterCollection="EcalBarrelClusters", - samplingFraction=sf, - OutputLevel=DEBUG) + OutputLevel=DEBUG, + inputHitCollection="EcalBarrelClusterHits", + outputLayerCollection="EcalBarrelClustersLayers", + outputClusterCollection="EcalBarrelClusters", + samplingFraction=sf) out.outputCommands = ["keep *"] ApplicationMgr( TopAlg=[podioinput, copier, calcopier, imcaldigi, imcalreco, imcalcluster, clusterreco, out], EvtSel='NONE', - EvtMax=kwargs['nev'], + # EvtMax=kwargs['nev'], + EvtMax=3, ExtSvc=[podioevent], OutputLevel=DEBUG ) diff --git a/benchmarks/imaging_ecal/run_emcal_barrel.sh b/benchmarks/imaging_ecal/run_emcal_barrel.sh index 43cc78c3fcf3523fb8da5241ee62cdf2f0b9b5f2..8584bef24e013b83a3a83808faae29ad43bbd15d 100644 --- a/benchmarks/imaging_ecal/run_emcal_barrel.sh +++ b/benchmarks/imaging_ecal/run_emcal_barrel.sh @@ -141,8 +141,6 @@ for iev in "${ADDR[@]}"; do fi done -# TODO add this part back (solve mismatched EICD issue and add clusterreco back in option file) -":" << COMMENT python ${CB_EMCAL_SCRIPT_DIR}/energy_profile.py \ ${CB_EMCAL_REC_FILE} --type=EM --energy=${CB_EMCAL_ENERGY} -o results/${particle} \ --save=results/profile.csv --color=royalblue @@ -150,7 +148,6 @@ if [[ "$?" -ne "0" ]] ; then echo "ERROR running analysis script: energy_profile" exit 1 fi -COMMENT root_filesize=$(stat --format=%s "${CB_EMCAL_REC_FILE}") if [[ "${CB_EMCAL_NUMEV}" -lt "500" ]] ; then diff --git a/benchmarks/imaging_ecal/scripts/energy_profile.py b/benchmarks/imaging_ecal/scripts/energy_profile.py index 234e646121657f6e958433f56f64aaa1a796cf62..d5b9b8aa21cd59ec2672abb6273f7d00fe6a57ea 100644 --- a/benchmarks/imaging_ecal/scripts/energy_profile.py +++ b/benchmarks/imaging_ecal/scripts/energy_profile.py @@ -47,7 +47,7 @@ if __name__ == '__main__': dfe.loc[:, 'total_edep'] = dfe.groupby(['event', 'cluster'])['edep'].transform('sum') # dfe.loc[:, 'efrac'] = dfe['edep']/dfe['total_edep'] dfe.loc[:, 'efrac'] = dfe['edep']/(args.energy*1000.) - dfe = dfe[dfe['cluster'] == 1] + dfe = dfe[dfe['cluster'] == 0] os.makedirs(args.outdir, exist_ok=True) @@ -102,6 +102,8 @@ if __name__ == '__main__': for ax, layer in zip(ax.flat, layers.flatten()): data = dfe[dfe['layer'] == layer] + if not len(data): + continue ax.hist(data['efrac'].values*100., weights=[1/float(len(data))]*len(data), bins=layers_bins, ec='black', color=args.color) ax.tick_params(labelsize=24) diff --git a/benchmarks/imaging_ecal/scripts/utils.py b/benchmarks/imaging_ecal/scripts/utils.py index ff8e368829eef58aa89e9585de3c05535a8e4ae0..8c9bfadfac14a56dcbf2b31ccef212088339b256 100644 --- a/benchmarks/imaging_ecal/scripts/utils.py +++ b/benchmarks/imaging_ecal/scripts/utils.py @@ -98,7 +98,7 @@ def get_hits_data(path, evnums=None, branch='RecoEcalBarrelHits'): events.GetEntry(iev) for hit in getattr(events, branch): - dbuf[idb] = (iev, hit.clusterID, hit.layerID, hit.position.x, hit.position.y, hit.position.z, hit.edep) + dbuf[idb] = (iev, hit.clusterID, hit.layerID, hit.position.x, hit.position.y, hit.position.z, hit.edep*1000.) idb += 1 return pd.DataFrame(data=dbuf[:idb], columns=['event', 'cluster', 'layer', 'x', 'y', 'z', 'edep']) @@ -123,7 +123,7 @@ def get_layers_data(path, evnums=None, branch="EcalBarrelClustersLayers"): events.GetEntry(iev) for layer in getattr(events, branch): dbuf[idb] = (iev, layer.clusterID, layer.layerID, - layer.position.x, layer.position.y, layer.position.z, layer.edep) + layer.position.x, layer.position.y, layer.position.z, layer.edep*1000.) idb += 1 return pd.DataFrame(data=dbuf[:idb], columns=['event', 'cluster', 'layer', 'x', 'y', 'z', 'edep']) @@ -147,7 +147,7 @@ def get_clusters_data(path, evnums=None, branch='EcalBarrelClustersReco'): events.GetEntry(iev) for k, cl in enumerate(getattr(events, branch)): - dbuf[idb] = (iev, k, cl.nhits, cl.edep, cl.cl_theta, cl.cl_phi) + dbuf[idb] = (iev, k, cl.nhits, cl.edep*1000., cl.cl_theta, cl.cl_phi) idb += 1 return pd.DataFrame(data=dbuf[:idb], columns=['event', 'cluster', 'nhits', 'edep', 'cl_theta', 'cl_phi'])