diff --git a/.clang-format b/.clang-format index 5c443be69c..6041e26532 100644 --- a/.clang-format +++ b/.clang-format @@ -3,7 +3,7 @@ BasedOnStyle: LLVM BreakConstructorInitializersBeforeComma: true ConstructorInitializerAllOnOneLineOrOnePerLine: true Cpp11BracedListStyle: true -Standard: Cpp11 +Standard: c++20 #SpaceBeforeParens: ControlStatements SpaceAfterControlStatementKeyword: true PointerBindsToType: true @@ -12,4 +12,6 @@ UseTab: Never ColumnLimit: 100 NamespaceIndentation: Inner AlignConsecutiveAssignments: true +SortIncludes: Never +ReflowComments: false ... diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 63f2b09f18..d54fa85cf1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,13 +1,13 @@ { - "image": "ghcr.io/eic/jug_prod:master-nightly", - "postCreateCommand": "./.devcontainer/postCreateCommand.sh", - "customizations": { - "vscode": { - "extensions": [ - "ms-vscode.cmake-tools", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack" - ] - } + "image": "ghcr.io/eic/jug_prod:master-nightly", + "postCreateCommand": "./.devcontainer/postCreateCommand.sh", + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.cmake-tools", + "ms-vscode.cpptools", + "ms-vscode.cpptools-extension-pack" + ] } + } } diff --git a/.github/eicrecon.json b/.github/eicrecon.json index a641e8b2c9..cab74cbf36 100644 --- a/.github/eicrecon.json +++ b/.github/eicrecon.json @@ -1,15 +1,15 @@ { - "problemMatcher": [ + "problemMatcher": [ + { + "owner": "eicrecon", + "pattern": [ { - "owner": "eicrecon", - "pattern": [ - { - "regexp": "^\\[(.*)\\]\\s\\[(error)\\]\\s*(.*)$", - "file": 1, - "severity": 2, - "message": 3 - } - ] + "regexp": "^\\[(.*)\\]\\s\\[(error)\\]\\s*(.*)$", + "file": 1, + "severity": 2, + "message": 3 } - ] + ] + } + ] } diff --git a/.github/ubsan.json b/.github/ubsan.json index d53635db4c..e07589ee51 100644 --- a/.github/ubsan.json +++ b/.github/ubsan.json @@ -1,18 +1,18 @@ { - "problemMatcher": [ + "problemMatcher": [ + { + "owner": "ubsan", + "pattern": [ { - "owner": "ubsan", - "pattern": [ - { - "regexp": "^.*/(src/.+):(\\d+):(\\d+):\\sruntime\\s(error):\\s*(.*)$", - "file": 1, - "fromPath": 1, - "line": 2, - "column": 3, - "severity": 4, - "message": 5 - }, - ] - } - ] + "regexp": "^.*/(src/.+):(\\d+):(\\d+):\\sruntime\\s(error):\\s*(.*)$", + "file": 1, + "fromPath": 1, + "line": 2, + "column": 3, + "severity": 4, + "message": 5 + }, + ] + } + ] } diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 033cb95c37..e7a967de67 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,18 @@ -ci: - skip: [clang-format] repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: + - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/codespell-project/codespell rev: v2.3.0 hooks: - id: codespell +- repo: https://github.com/pre-commit/mirrors-clang-format + rev: v19.1.4 + hooks: + - id: clang-format - repo: https://github.com/Lucas-C/pre-commit-hooks rev: v1.5.5 hooks: @@ -18,11 +21,6 @@ repos: - id: forbid-tabs - id: remove-tabs args: [--whitespaces-count, '8'] -- repo: https://github.com/pocc/pre-commit-hooks - rev: v1.3.5 - hooks: - - id: clang-format - args: [-i] - repo: https://github.com/cheshirekow/cmake-format-precommit rev: v0.6.13 hooks: diff --git a/docs/arches_flags.json b/docs/arches_flags.json index 258b488dc4..05a16ea8a3 100644 --- a/docs/arches_flags.json +++ b/docs/arches_flags.json @@ -1,859 +1,5144 @@ [ - ["acts:InitLogLevel", "info", "info", "log_level: trace, debug, info, warn, error, critical, off"] - ,["acts:LogLevel", "info", "info", "log_level for acts: trace, debug, info, warn, error, critical, off"] - ,["acts:MaterialMap", "calibrations/materials-map.cbor", "calibrations/materials-map.cbor", ""] - ,["acts_init:LogLevel", "info", "info", "log_level for acts_init: trace, debug, info, warn, error, critical, off"] - ,["B0ECAL:B0ECalClusters:depthCorrection", "0", "", ""] - ,["B0ECAL:B0ECalClusters:enableEtaBounds", "0", "", ""] - ,["B0ECAL:B0ECalClusters:energyWeight", "log", "", ""] - ,["B0ECAL:B0ECalClusters:input_protoclust_tag", "B0ECalIslandProtoClusters", "", ""] - ,["B0ECAL:B0ECalClusters:logWeightBase", "3.6", "", ""] - ,["B0ECAL:B0ECalClusters:moduleDimZName", "", "", ""] - ,["B0ECAL:B0ECalClusters:samplingFraction", "1", "", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:dimScaledLocalDistXY", "1.8,1.8", "1.8,1.8", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:globalDistEtaPhi", "", "", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:globalDistRPhi", "", "", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:input_tag", "B0ECalRecHits", "B0ECalRecHits", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:localDistXY", "", "", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:localDistXZ", "", "", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:localDistYZ", "", "", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:minClusterCenterEdep", "1.0", "0.001", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:minClusterHitEdep", "30.0", "0.03", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:sectorDist", "50.0", "5", ""] - ,["B0ECAL:B0ECalIslandProtoClusters:splitCluster", "0", "0", ""] - ,["B0ECAL:B0ECalRawHits:capacityADC", "16384", "16384", ""] - ,["B0ECAL:B0ECalRawHits:dynamicRangeADC", "20000.0", "1", ""] - ,["B0ECAL:B0ECalRawHits:energyResolutions", "0.0,0.02,0.0", "0,0.02,0", ""] - ,["B0ECAL:B0ECalRawHits:fieldRefNumbers", "", "", ""] - ,["B0ECAL:B0ECalRawHits:geoServiceName", "", "", ""] - ,["B0ECAL:B0ECalRawHits:input_tag", "B0ECalHits", "B0ECalHits", "Name of input collection to use"] - ,["B0ECAL:B0ECalRawHits:pedestalMean", "100", "100", ""] - ,["B0ECAL:B0ECalRawHits:pedestalSigma", "1", "1", ""] - ,["B0ECAL:B0ECalRawHits:readoutClass", "", "", ""] - ,["B0ECAL:B0ECalRawHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["B0ECAL:B0ECalRawHits:scaleResponse", "1", "1", ""] - ,["B0ECAL:B0ECalRawHits:signalSumFields", "", "", ""] - ,["B0ECAL:B0ECalRawHits:timeResolution", "0", "0", ""] - ,["B0ECAL:B0ECalRecHits:capacityADC", "16384", "16384", ""] - ,["B0ECAL:B0ECalRecHits:dynamicRangeADC", "20000.0", "20", ""] - ,["B0ECAL:B0ECalRecHits:geoServiceName", "", "", ""] - ,["B0ECAL:B0ECalRecHits:input_tag", "B0ECalRawHits", "B0ECalRawHits", "Name of input collection to use"] - ,["B0ECAL:B0ECalRecHits:layerField", "", "", ""] - ,["B0ECAL:B0ECalRecHits:localDetElement", "", "", ""] - ,["B0ECAL:B0ECalRecHits:localDetFields", "", "", ""] - ,["B0ECAL:B0ECalRecHits:pedestalMean", "100", "100", ""] - ,["B0ECAL:B0ECalRecHits:pedestalSigma", "1", "1", ""] - ,["B0ECAL:B0ECalRecHits:readout", "B0ECalHits", "B0ECalHits", ""] - ,["B0ECAL:B0ECalRecHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["B0ECAL:B0ECalRecHits:samplingFraction", "0.998", "0.998", ""] - ,["B0ECAL:B0ECalRecHits:sectorField", "sector", "sector", ""] - ,["B0ECAL:B0ECalRecHits:thresholdFactor", "4", "4", ""] - ,["B0ECAL:B0ECalRecHits:thresholdValue", "3", "3", ""] - ,["B0ECalClusters:LogLevel", "info", "info", "log_level for B0ECalClusters: trace, debug, info, warn, error, critical, off"] - ,["B0ECalIslandProtoClusters:LogLevel", "info", "info", "log_level for B0ECalIslandProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["B0ECalMergedClusters:LogLevel", "info", "info", "log_level for B0ECalMergedClusters: trace, debug, info, warn, error, critical, off"] - ,["B0ECalRawHits:LogLevel", "info", "info", "log_level for B0ECalRawHits: trace, debug, info, warn, error, critical, off"] - ,["B0ECalRecHits:LogLevel", "info", "info", "log_level for B0ECalRecHits: trace, debug, info, warn, error, critical, off"] - ,["B0ECalTruthProtoClusters:LogLevel", "info", "info", "log_level for B0ECalTruthProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["BEMC:EcalBarrelImagingClusters:input_protoclust_tag", "EcalBarrelImagingProtoClusters", "EcalBarrelImagingProtoClusters", ""] - ,["BEMC:EcalBarrelImagingClusters:trackStopLayer", "6", "6", ""] - ,["BEMC:EcalBarrelImagingMergedClusters:energyAssociation_tag", "EcalBarrelScFiClusterAssociations", "EcalBarrelScFiClusterAssociations", ""] - ,["BEMC:EcalBarrelImagingMergedClusters:energyClusters_tag", "EcalBarrelScFiClusters", "EcalBarrelScFiClusters", ""] - ,["BEMC:EcalBarrelImagingMergedClusters:inputMCParticles_tag", "MCParticles", "MCParticles", ""] - ,["BEMC:EcalBarrelImagingMergedClusters:positionAssociations_tag", "EcalBarrelImagingClusterAssociations", "EcalBarrelImagingClusterAssociations", ""] - ,["BEMC:EcalBarrelImagingMergedClusters:positionClusters_tag", "EcalBarrelImagingClusters", "EcalBarrelImagingClusters", ""] - ,["BEMC:EcalBarrelImagingProtoClusters::layerDistEtaPhi", "0.01,0.01", "", ""] - ,["BEMC:EcalBarrelImagingProtoClusters::localDistXY", "2.0,2.0", "", ""] - ,["BEMC:EcalBarrelImagingProtoClusters::minClusterCenterEdep", "0.", "", ""] - ,["BEMC:EcalBarrelImagingProtoClusters::minClusterEdep", "0.5", "", ""] - ,["BEMC:EcalBarrelImagingProtoClusters::minClusterHitEdep", "0.", "", ""] - ,["BEMC:EcalBarrelImagingProtoClusters::minClusterNhits", "5", "", ""] - ,["BEMC:EcalBarrelImagingProtoClusters::neighbourLayersRange", "2.0", "", ""] - ,["BEMC:EcalBarrelImagingProtoClusters::sectorDist", "30.0", "", ""] - ,["BEMC:EcalBarrelImagingProtoClusters:input_tag", "EcalBarrelImagingRecHits", "", ""] - ,["BEMC:EcalBarrelImagingRawHits:capacityADC", "8192", "8192", ""] - ,["BEMC:EcalBarrelImagingRawHits:dynamicRangeADC", "3.0", "0.1", ""] - ,["BEMC:EcalBarrelImagingRawHits:energyResolutions", "0.0,0.02,0.0", "0,0.02,0", ""] - ,["BEMC:EcalBarrelImagingRawHits:fieldRefNumbers", "", "", ""] - ,["BEMC:EcalBarrelImagingRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["BEMC:EcalBarrelImagingRawHits:input_tag", "EcalBarrelImagingHits", "EcalBarrelImagingHits", ""] - ,["BEMC:EcalBarrelImagingRawHits:pedestalMean", "100", "100", ""] - ,["BEMC:EcalBarrelImagingRawHits:pedestalSigma", "14", "3.2", ""] - ,["BEMC:EcalBarrelImagingRawHits:readoutClass", "pixel", "", ""] - ,["BEMC:EcalBarrelImagingRawHits:resolutionTDC", "10*picosecond", "1e-11", ""] - ,["BEMC:EcalBarrelImagingRawHits:scaleResponse", "1.0", "1", ""] - ,["BEMC:EcalBarrelImagingRawHits:signalSumFields", "", "", ""] - ,["BEMC:EcalBarrelImagingRawHits:timeResolution", "0.0*ns", "0", ""] - ,["BEMC:EcalBarrelImagingRecHits:capacityADC", "8192", "8096", ""] - ,["BEMC:EcalBarrelImagingRecHits:dynamicRangeADC", "3.0", "0.1", ""] - ,["BEMC:EcalBarrelImagingRecHits:input_tag", "EcalBarrelImagingRawHits", "EcalBarrelImagingRawHits", ""] - ,["BEMC:EcalBarrelImagingRecHits:layerField", "layer", "layer", ""] - ,["BEMC:EcalBarrelImagingRecHits:pedestalMean", "100", "400", ""] - ,["BEMC:EcalBarrelImagingRecHits:pedSigmaADC", "14", "14", ""] - ,["BEMC:EcalBarrelImagingRecHits:samplingFraction", "0.005", "0.005", ""] - ,["BEMC:EcalBarrelImagingRecHits:sectorField", "module", "module", ""] - ,["BEMC:EcalBarrelImagingRecHits:thresholdFactor", "3.0", "3", ""] - ,["BEMC:EcalBarrelMergedSciGlassTruthClusters:input_tag", "EcalBarrelSciGlassTruthClusters", "EcalBarrelSciGlassTruthClusters", "Name of input collection to use"] - ,["BEMC:EcalBarrelMergedSciGlassTruthClusters:inputAssociations_tag", "EcalBarrelSciGlassTruthClusterAssociations", "EcalBarrelSciGlassTruthClusterAssociations", ""] - ,["BEMC:EcalBarrelScFiClusters:depthCorrection", "0.0", "0", ""] - ,["BEMC:EcalBarrelScFiClusters:enableEtaBounds", "false", "0", ""] - ,["BEMC:EcalBarrelScFiClusters:energyWeight", "log", "log", ""] - ,["BEMC:EcalBarrelScFiClusters:input_protoclust_tag", "EcalBarrelScFiProtoClusters", "EcalBarrelScFiProtoClusters", ""] - ,["BEMC:EcalBarrelScFiClusters:input_simhit_tag", "EcalBarrelScFiHits", "EcalBarrelScFiHits", ""] - ,["BEMC:EcalBarrelScFiClusters:logWeightBase", "6.2", "6.2", ""] - ,["BEMC:EcalBarrelScFiClusters:moduleDimZName", "", "", ""] - ,["BEMC:EcalBarrelScFiClusters:samplingFraction", "1.0", "1", ""] - ,["BEMC:EcalBarrelscFiMergedHits:fields", "fiber,z", "fiber,z", ""] - ,["BEMC:EcalBarrelscFiMergedHits:input_tag", "EcalBarrelScFiRecHits", "EcalBarrelScFiRecHits", ""] - ,["BEMC:EcalBarrelscFiMergedHits:refs", "1,1", "1,1", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:dimScaledLocalDistXY", "", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:globalDistEtaPhi", "", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:globalDistRPhi", "", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:input_tag", "EcalBarrelScFiMergedHits", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:localDistXY", "", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:localDistXZ", "30.0,30.0", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:localDistYZ", "", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:minClusterCenterEdep", "10.0", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:minClusterHitEdep", "1.0", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:sectorDist", "50.0", "", ""] - ,["BEMC:EcalBarrelScFiProtoClusters:splitCluster", "false", "", ""] - ,["BEMC:EcalBarrelScFiRawHits:capacityADC", "16384", "8096", ""] - ,["BEMC:EcalBarrelScFiRawHits:dynamicRangeADC", "750.0", "0.1", ""] - ,["BEMC:EcalBarrelScFiRawHits:energyResolutions", "", "0", ""] - ,["BEMC:EcalBarrelScFiRawHits:fieldRefNumbers", "", "", ""] - ,["BEMC:EcalBarrelScFiRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["BEMC:EcalBarrelScFiRawHits:input_tag", "EcalBarrelScFiHits", "EcalBarrelScFiHits", ""] - ,["BEMC:EcalBarrelScFiRawHits:pedestalMean", "20", "400", ""] - ,["BEMC:EcalBarrelScFiRawHits:pedestalSigma", "0.3", "3.2", ""] - ,["BEMC:EcalBarrelScFiRawHits:readoutClass", "light_guide", "", ""] - ,["BEMC:EcalBarrelScFiRawHits:resolutionTDC", "10*picosecond", "1e-11", ""] - ,["BEMC:EcalBarrelScFiRawHits:scaleResponse", "1.0", "1", ""] - ,["BEMC:EcalBarrelScFiRawHits:signalSumFields", "", "", ""] - ,["BEMC:EcalBarrelScFiRawHits:timeResolution", "0*ns", "0", ""] - ,["BEMC:EcalBarrelScFiRecHits:capacityADC", "16384", "16384", ""] - ,["BEMC:EcalBarrelScFiRecHits:dynamicRangeADC", "750.0", "0.75", ""] - ,["BEMC:EcalBarrelScFiRecHits:input_tag", "EcalBarrelScFiRawHits", "EcalBarrelScFiRawHits", ""] - ,["BEMC:EcalBarrelScFiRecHits:pedestalMean", "20", "20", ""] - ,["BEMC:EcalBarrelScFiRecHits:pedestalSigma", "0.3", "0.3", ""] - ,["BEMC:EcalBarrelScFiRecHits:resolutionTDC", "10*picosecond", "1e-11", ""] - ,["BEMC:EcalBarrelScFiRecHits:samplingFraction", "0.125", "0.125", ""] - ,["BEMC:EcalBarrelScFiRecHits:thresholdFactor", "5.0", "5", ""] - ,["BEMC:EcalBarrelScFiRecHits:thresholdValue", "0.0", "0", ""] - ,["BEMC:EcalBarrelSciGlassClusters:depthCorrection", "0", "0", ""] - ,["BEMC:EcalBarrelSciGlassClusters:enableEtaBounds", "1", "0", ""] - ,["BEMC:EcalBarrelSciGlassClusters:energyWeight", "log", "log", ""] - ,["BEMC:EcalBarrelSciGlassClusters:input_protoclust_tag", "EcalBarrelSciGlassProtoClusters", "EcalBarrelSciGlassProtoClusters", ""] - ,["BEMC:EcalBarrelSciGlassClusters:input_simhit_tag", "EcalBarrelSciGlassHits", "EcalBarrelSciGlassHits", ""] - ,["BEMC:EcalBarrelSciGlassClusters:logWeightBase", "6.2", "3.6", ""] - ,["BEMC:EcalBarrelSciGlassClusters:moduleDimZName", "", "", ""] - ,["BEMC:EcalBarrelSciGlassClusters:samplingFraction", "1", "1", ""] - ,["BEMC:EcalBarrelSciGlassMergedClusters:input_tag", "EcalBarrelSciGlassClusters", "EcalBarrelSciGlassClusters", "Name of input collection to use"] - ,["BEMC:EcalBarrelSciGlassMergedClusters:inputAssociations_tag", "EcalBarrelSciGlassClusterAssociations", "EcalBarrelSciGlassClusterAssociations", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:dimScaledLocalDistXY", "1.8,1.8", "1.8,1.8", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:globalDistEtaPhi", "", "", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:globalDistRPhi", "", "", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:input_tag", "EcalBarrelSciGlassRecHits", "EcalBarrelSciGlassRecHits", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:localDistXY", "", "", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:localDistXZ", "", "", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:localDistYZ", "", "", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:minClusterCenterEdep", "30.0", "0.03", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:minClusterHitEdep", "1.0", "0.001", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:sectorDist", "50.0", "5", ""] - ,["BEMC:EcalBarrelSciGlassProtoClusters:splitCluster", "0", "0", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:capacityADC", "16384", "8096", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:dynamicRangeADC", "20000.0", "0.1", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:energyResolutions", "0.0,0.02,0.0", "", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:fieldRefNumbers", "", "", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:input_tag", "EcalBarrelSciGlassHits", "EcalBarrelSciGlassHits", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:pedestalMean", "100", "400", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:pedestalSigma", "1", "3.2", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:readoutClass", "", "", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:scaleResponse", "1", "1", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:signalSumFields", "", "", ""] - ,["BEMC:EcalBarrelSciGlassRawHits:timeResolution", "0", "0", ""] - ,["BEMC:EcalBarrelSciGlassRecHits:capacityADC", "16384", "8096", ""] - ,["BEMC:EcalBarrelSciGlassRecHits:dynamicRangeADC", "20000.0", "0.1", ""] - ,["BEMC:EcalBarrelSciGlassRecHits:input_tag", "EcalBarrelSciGlassRawHits", "EcalBarrelSciGlassRawHits", ""] - ,["BEMC:EcalBarrelSciGlassRecHits:pedestalMean", "100", "400", ""] - ,["BEMC:EcalBarrelSciGlassRecHits:pedestalSigma", "1", "3.2", ""] - ,["BEMC:EcalBarrelSciGlassRecHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["BEMC:EcalBarrelSciGlassRecHits:samplingFraction", "0.98", "0.998", ""] - ,["BEMC:EcalBarrelSciGlassRecHits:thresholdFactor", "3", "4", ""] - ,["BEMC:EcalBarrelSciGlassRecHits:thresholdValue", "3", "0", ""] - ,["BEMC:EcalBarrelSciGlassTruthClusters:depthCorrection", "0", "0", ""] - ,["BEMC:EcalBarrelSciGlassTruthClusters:enableEtaBounds", "1", "0", ""] - ,["BEMC:EcalBarrelSciGlassTruthClusters:energyWeight", "log", "log", ""] - ,["BEMC:EcalBarrelSciGlassTruthClusters:input_protoclust_tag", "EcalBarrelSciGlassTruthProtoClusters", "EcalBarrelSciGlassTruthProtoClusters", ""] - ,["BEMC:EcalBarrelSciGlassTruthClusters:input_simhit_tag", "EcalBarrelSciGlassHits", "EcalBarrelSciGlassHits", ""] - ,["BEMC:EcalBarrelSciGlassTruthClusters:logWeightBase", "6.2", "3.6", ""] - ,["BEMC:EcalBarrelSciGlassTruthClusters:moduleDimZName", "", "", ""] - ,["BEMC:EcalBarrelSciGlassTruthClusters:samplingFraction", "1", "1", ""] - ,["BTOF:TOFBarrelRawHit:InputTags", "", "", "Input data tag name"] - ,["BTOF:TOFBarrelRawHit:LogLevel", "info", "info", "log_level for BTOF:TOFBarrelRawHit: trace, debug, info, warn, error, critical, off"] - ,["BTOF:TOFBarrelRawHit:Threshold", "0", "0", ""] - ,["BTOF:TOFBarrelRawHit:TimeResolution", "0.025", "0.025", ""] - ,["BTOF:TOFBarrelTrackerHit:InputTags", "", "", "Input data tag name"] - ,["BTOF:TOFBarrelTrackerHit:LogLevel", "info", "info", "log_level for BTOF:TOFBarrelTrackerHit: trace, debug, info, warn, error, critical, off"] - ,["BTOF:TOFBarrelTrackerHit:TimeResolution", "0.025", "10", ""] - ,["BTRK:BarrelTrackerHit:InputTags", "", "", "Input data tag name"] - ,["BTRK:BarrelTrackerHit:LogLevel", "info", "info", "log_level for BTRK:BarrelTrackerHit: trace, debug, info, warn, error, critical, off"] - ,["BTRK:BarrelTrackerHit:TimeResolution", "8", "10", ""] - ,["BTRK:BarrelTrackerRawHit:InputTags", "", "", "Input data tag name"] - ,["BTRK:BarrelTrackerRawHit:LogLevel", "info", "info", "log_level for BTRK:BarrelTrackerRawHit: trace, debug, info, warn, error, critical, off"] - ,["BTRK:BarrelTrackerRawHit:Threshold", "0", "0", ""] - ,["BTRK:BarrelTrackerRawHit:TimeResolution", "8", "8", ""] - ,["BVTX:BarrelVertexHit:InputTags", "", "", "Input data tag name"] - ,["BVTX:BarrelVertexHit:LogLevel", "info", "info", "log_level for BVTX:BarrelVertexHit: trace, debug, info, warn, error, critical, off"] - ,["BVTX:BarrelVertexHit:TimeResolution", "8", "10", ""] - ,["BVTX:BarrelVertexRawHit:InputTags", "", "", "Input data tag name"] - ,["BVTX:BarrelVertexRawHit:LogLevel", "info", "info", "log_level for BVTX:BarrelVertexRawHit: trace, debug, info, warn, error, critical, off"] - ,["BVTX:BarrelVertexRawHit:Threshold", "0", "0", ""] - ,["BVTX:BarrelVertexRawHit:TimeResolution", "8", "8", ""] - ,["dd4hep:print_level", "4", "4", "Set DD4hep print level (see DD4hep/Printout.h)"] - ,["dd4hep:xml_files", "/opt/detector/epic-nightly/share/epic/epic_arches.xml", "/opt/detector/epic-nightly/share/epic/epic_arches.xml", "Comma separated list of XML files describing the DD4hep geometry. (Defaults to ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml using envars.)"] - ,["Digi:SmearedFarForwardParticles:LogLevel", "info", "info", "log_level for Digi:SmearedFarForwardParticles: trace, debug, info, warn, error, critical, off"] - ,["dump_flags:json", "arches_right_flags.json", "", ""] - ,["dump_flags:LogLevel", "info", "info", "log_level for dump_flags: trace, debug, info, warn, error, critical, off"] - ,["dump_flags:markdown", "", "", "If not empty, a markdown file to generate"] - ,["dump_flags:python", "all_flags_dump_from_run.py", "", ""] - ,["dump_flags:screen", "1", "1", "If not empty, print summary to screen at end of job"] - ,["EcalBarrelImagingClusters:LogLevel", "info", "info", "log_level for EcalBarrelImagingClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelImagingMergedClusters:LogLevel", "info", "info", "log_level for EcalBarrelImagingMergedClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelImagingProtoClusters:LogLevel", "info", "info", "log_level for EcalBarrelImagingProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelImagingRawHits:LogLevel", "info", "info", "log_level for EcalBarrelImagingRawHits: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelImagingRecHits:LogLevel", "info", "info", "log_level for EcalBarrelImagingRecHits: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelScFiClusters:LogLevel", "info", "info", "log_level for EcalBarrelScFiClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelScFiMergedHits:LogLevel", "info", "info", "log_level for EcalBarrelScFiMergedHits: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelScFiProtoClusters:LogLevel", "info", "info", "log_level for EcalBarrelScFiProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelScFiRawHits:LogLevel", "info", "info", "log_level for EcalBarrelScFiRawHits: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelScFiRecHits:LogLevel", "info", "info", "log_level for EcalBarrelScFiRecHits: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelSciGlassClusters:LogLevel", "info", "info", "log_level for EcalBarrelSciGlassClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelSciGlassMergedClusters:LogLevel", "info", "info", "log_level for EcalBarrelSciGlassMergedClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelSciGlassMergedTruthClusters:LogLevel", "info", "info", "log_level for EcalBarrelSciGlassMergedTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelSciGlassProtoClusters:LogLevel", "info", "info", "log_level for EcalBarrelSciGlassProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelSciGlassRawHits:LogLevel", "info", "info", "log_level for EcalBarrelSciGlassRawHits: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelSciGlassRecHits:LogLevel", "info", "info", "log_level for EcalBarrelSciGlassRecHits: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelSciGlassTruthClusters:LogLevel", "info", "info", "log_level for EcalBarrelSciGlassTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalBarrelTruthSciGlassProtoClusters:LogLevel", "info", "info", "log_level for EcalBarrelTruthSciGlassProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapNClusters:LogLevel", "info", "info", "log_level for EcalEndcapNClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapNIslandProtoClusters:LogLevel", "info", "info", "log_level for EcalEndcapNIslandProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapNMergedClusters:LogLevel", "info", "info", "log_level for EcalEndcapNMergedClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapNRawHits:LogLevel", "info", "info", "log_level for EcalEndcapNRawHits: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapNRecHits:LogLevel", "info", "info", "log_level for EcalEndcapNRecHits: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapNTruthClusters:LogLevel", "info", "info", "log_level for EcalEndcapNTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapNTruthProtoClusters:LogLevel", "info", "info", "log_level for EcalEndcapNTruthProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPClusters:LogLevel", "info", "info", "log_level for EcalEndcapPClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPInsertClusters:LogLevel", "info", "info", "log_level for EcalEndcapPInsertClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPInsertIslandProtoClusters:LogLevel", "info", "info", "log_level for EcalEndcapPInsertIslandProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPInsertMergedClusters:LogLevel", "info", "info", "log_level for EcalEndcapPInsertMergedClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPInsertRawHits:LogLevel", "info", "info", "log_level for EcalEndcapPInsertRawHits: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPInsertRecHits:LogLevel", "info", "info", "log_level for EcalEndcapPInsertRecHits: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPInsertTruthClusters:LogLevel", "info", "info", "log_level for EcalEndcapPInsertTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPInsertTruthProtoClusters:LogLevel", "info", "info", "log_level for EcalEndcapPInsertTruthProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPIslandProtoClusters:LogLevel", "info", "info", "log_level for EcalEndcapPIslandProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPMergedClusters:LogLevel", "info", "info", "log_level for EcalEndcapPMergedClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPRawHits:LogLevel", "info", "info", "log_level for EcalEndcapPRawHits: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPRecHits:LogLevel", "info", "info", "log_level for EcalEndcapPRecHits: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPTruthClusters:LogLevel", "info", "info", "log_level for EcalEndcapPTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["EcalEndcapPTruthProtoClusters:LogLevel", "info", "info", "log_level for EcalEndcapPTruthProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["ECTOF:TOFEndcapRawHit:InputTags", "", "", "Input data tag name"] - ,["ECTOF:TOFEndcapRawHit:LogLevel", "info", "info", "log_level for ECTOF:TOFEndcapRawHit: trace, debug, info, warn, error, critical, off"] - ,["ECTOF:TOFEndcapRawHit:Threshold", "0", "0", ""] - ,["ECTOF:TOFEndcapRawHit:TimeResolution", "0.025", "0.025", ""] - ,["ECTOF:TOFEndcapTrackerHit:InputTags", "", "", "Input data tag name"] - ,["ECTOF:TOFEndcapTrackerHit:LogLevel", "info", "info", "log_level for ECTOF:TOFEndcapTrackerHit: trace, debug, info, warn, error, critical, off"] - ,["ECTOF:TOFEndcapTrackerHit:TimeResolution", "0.025", "10", ""] - ,["ECTRK:EndcapTrackerHit:InputTags", "", "", "Input data tag name"] - ,["ECTRK:EndcapTrackerHit:LogLevel", "info", "info", "log_level for ECTRK:EndcapTrackerHit: trace, debug, info, warn, error, critical, off"] - ,["ECTRK:EndcapTrackerHit:TimeResolution", "8", "10", ""] - ,["ECTRK:EndcapTrackerRawHit:InputTags", "", "", "Input data tag name"] - ,["ECTRK:EndcapTrackerRawHit:LogLevel", "info", "info", "log_level for ECTRK:EndcapTrackerRawHit: trace, debug, info, warn, error, critical, off"] - ,["ECTRK:EndcapTrackerRawHit:Threshold", "0", "0", ""] - ,["ECTRK:EndcapTrackerRawHit:TimeResolution", "8", "8", ""] - ,["EEMC:B0ECalClusters:depthCorrection", "0", "0", ""] - ,["EEMC:B0ECalClusters:enableEtaBounds", "0", "0", ""] - ,["EEMC:B0ECalClusters:energyWeight", "log", "log", ""] - ,["EEMC:B0ECalClusters:input_protoclust_tag", "B0ECalIslandProtoClusters", "B0ECalIslandProtoClusters", "Name of input collection to use"] - ,["EEMC:B0ECalClusters:logWeightBase", "3.6", "3.6", ""] - ,["EEMC:B0ECalClusters:moduleDimZName", "", "", ""] - ,["EEMC:B0ECalClusters:samplingFraction", "1", "1", ""] - ,["EEMC:EcalEndcapNClusters:depthCorrection", "0", "0", ""] - ,["EEMC:EcalEndcapNClusters:enableEtaBounds", "0", "0", ""] - ,["EEMC:EcalEndcapNClusters:energyWeight", "log", "log", ""] - ,["EEMC:EcalEndcapNClusters:input_protoclust_tag", "EcalEndcapNIslandProtoClusters", "EcalEndcapNIslandProtoClusters", ""] - ,["EEMC:EcalEndcapNClusters:logWeightBase", "3.6", "3.6", ""] - ,["EEMC:EcalEndcapNClusters:moduleDimZName", "", "", ""] - ,["EEMC:EcalEndcapNClusters:samplingFraction", "1", "1", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:dimScaledLocalDistXY", "1.8,1.8", "1.8,1.8", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:globalDistEtaPhi", "", "", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:globalDistRPhi", "", "", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:input_tag", "EcalEndcapNRecHits", "EcalEndcapNRecHits", "Name of input collection to use"] - ,["EEMC:EcalEndcapNIslandProtoClusters:localDistXY", "", "", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:localDistXZ", "", "", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:localDistYZ", "", "", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:minClusterCenterEdep", "1.0", "0.03", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:minClusterHitEdep", "30.0", "0.001", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:sectorDist", "50.0", "5", ""] - ,["EEMC:EcalEndcapNIslandProtoClusters:splitCluster", "0", "0", ""] - ,["EEMC:EcalEndcapNMergedClusters:input_tag", "EcalEndcapNClusters", "EcalEndcapNClusters", "Name of input collection to use"] - ,["EEMC:EcalEndcapNMergedClusters:inputAssociations_tag", "EcalEndcapNClusterAssociations", "EcalEndcapNClustersAssociations", "Name of input associations collection to use"] - ,["EEMC:EcalEndcapNRawHits:capacityADC", "16384", "8096", ""] - ,["EEMC:EcalEndcapNRawHits:dynamicRangeADC", "20000.0", "0.1", ""] - ,["EEMC:EcalEndcapNRawHits:energyResolutions", "0.0,0.02,0.0", "", ""] - ,["EEMC:EcalEndcapNRawHits:fieldRefNumbers", "", "", ""] - ,["EEMC:EcalEndcapNRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["EEMC:EcalEndcapNRawHits:input_tag", "EcalEndcapNHits", "EcalEndcapNHits", "Name of input collection to use"] - ,["EEMC:EcalEndcapNRawHits:pedestalMean", "100", "400", ""] - ,["EEMC:EcalEndcapNRawHits:pedestalSigma", "1", "3.2", ""] - ,["EEMC:EcalEndcapNRawHits:readoutClass", "", "", ""] - ,["EEMC:EcalEndcapNRawHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["EEMC:EcalEndcapNRawHits:scaleResponse", "1", "1", ""] - ,["EEMC:EcalEndcapNRawHits:signalSumFields", "", "", ""] - ,["EEMC:EcalEndcapNRawHits:timeResolution", "0", "0", ""] - ,["EEMC:EcalEndcapNRecHits:capacityADC", "16384", "8096", ""] - ,["EEMC:EcalEndcapNRecHits:dynamicRangeADC", "20000.0", "0.1", ""] - ,["EEMC:EcalEndcapNRecHits:geoServiceName", "geoServiceName", "geoServiceName", ""] - ,["EEMC:EcalEndcapNRecHits:input_tag", "EcalEndcapNRawHits", "EcalEndcapNRawHits", "Name of input collection to use"] - ,["EEMC:EcalEndcapNRecHits:layerField", "", "", ""] - ,["EEMC:EcalEndcapNRecHits:localDetElement", "", "", ""] - ,["EEMC:EcalEndcapNRecHits:localDetFields", "", "", ""] - ,["EEMC:EcalEndcapNRecHits:pedestalMean", "100", "400", ""] - ,["EEMC:EcalEndcapNRecHits:pedestalSigma", "1", "3.2", ""] - ,["EEMC:EcalEndcapNRecHits:readout", "EcalEndcapNHits", "EcalEndcapNHits", ""] - ,["EEMC:EcalEndcapNRecHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["EEMC:EcalEndcapNRecHits:samplingFraction", "0.998", "0.998", ""] - ,["EEMC:EcalEndcapNRecHits:sectorField", "sector", "sector", ""] - ,["EEMC:EcalEndcapNRecHits:thresholdFactor", "4", "4", ""] - ,["EEMC:EcalEndcapNRecHits:thresholdValue", "3", "0", ""] - ,["EEMC:EcalEndcapNTruthClusters:depthCorrection", "0", "0", ""] - ,["EEMC:EcalEndcapNTruthClusters:enableEtaBounds", "0", "0", ""] - ,["EEMC:EcalEndcapNTruthClusters:energyWeight", "log", "log", ""] - ,["EEMC:EcalEndcapNTruthClusters:input_protoclust_tag", "EcalEndcapNTruthProtoClusters", "EcalEndcapNTruthProtoClusters", "Name of input collection to use"] - ,["EEMC:EcalEndcapNTruthClusters:logWeightBase", "4.6", "3.6", ""] - ,["EEMC:EcalEndcapNTruthClusters:moduleDimZName", "", "", ""] - ,["EEMC:EcalEndcapNTruthClusters:samplingFraction", "0.03", "1", ""] - ,["EEMC:EcalEndcapNTruthProtoClusters:inputHit_tag", "EcalEndcapNRecHits", "EcalEndcapNRecHits", "Name of input collection to use"] - ,["EEMC:EcalEndcapPClusters:depthCorrection", "0", "0", ""] - ,["EEMC:EcalEndcapPClusters:dimScaledLocalDistXY", "1.8,1.8", "1.8,1.8", ""] - ,["EEMC:EcalEndcapPClusters:enableEtaBounds", "0", "0", ""] - ,["EEMC:EcalEndcapPClusters:energyWeight", "log", "log", ""] - ,["EEMC:EcalEndcapPClusters:globalDistEtaPhi", "", "", ""] - ,["EEMC:EcalEndcapPClusters:globalDistRPhi", "", "", ""] - ,["EEMC:EcalEndcapPClusters:input_protoclust_tag", "EcalEndcapPIslandProtoClusters", "EcalEndcapPIslandProtoClusters", ""] - ,["EEMC:EcalEndcapPClusters:input_tag", "EcalEndcapPRecHits", "EcalEndcapPRecHits", "Name of input collection to use"] - ,["EEMC:EcalEndcapPClusters:localDistXY", "", "", ""] - ,["EEMC:EcalEndcapPClusters:localDistXZ", "", "", ""] - ,["EEMC:EcalEndcapPClusters:localDistYZ", "", "", ""] - ,["EEMC:EcalEndcapPClusters:logWeightBase", "3.6", "3.6", ""] - ,["EEMC:EcalEndcapPClusters:minClusterCenterEdep", "0.03", "0.03", ""] - ,["EEMC:EcalEndcapPClusters:minClusterHitEdep", "0.001", "0.001", ""] - ,["EEMC:EcalEndcapPClusters:moduleDimZName", "", "", ""] - ,["EEMC:EcalEndcapPClusters:samplingFraction", "1", "1", ""] - ,["EEMC:EcalEndcapPClusters:sectorDist", "5", "5", ""] - ,["EEMC:EcalEndcapPClusters:splitCluster", "0", "0", ""] - ,["EEMC:EcalEndcapPInsertClusters:depthCorrection", "0", "0", ""] - ,["EEMC:EcalEndcapPInsertClusters:enableEtaBounds", "0", "0", ""] - ,["EEMC:EcalEndcapPInsertClusters:energyWeight", "log", "log", ""] - ,["EEMC:EcalEndcapPInsertClusters:input_protoclust_tag", "EcalEndcapPInsertIslandProtoClusters", "EcalEndcapPInsertIslandProtoClusters", ""] - ,["EEMC:EcalEndcapPInsertClusters:logWeightBase", "3.6", "3.6", ""] - ,["EEMC:EcalEndcapPInsertClusters:moduleDimZName", "", "", ""] - ,["EEMC:EcalEndcapPInsertClusters:samplingFraction", "1", "1", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:dimScaledLocalDistXY", "1.5,1.5", "", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:globalDistEtaPhi", "", "", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:globalDistRPhi", "", "", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:localDistXY", "10,10", "", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:localDistXZ", "", "", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:localDistYZ", "", "", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:minClusterCenterEdep", "10.0", "", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:minClusterHitEdep", "0", "", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:sectorDist", "5", "", ""] - ,["EEMC:EcalEndcapPInsertIslandProtoClusters:splitCluster", "0", "", ""] - ,["EEMC:EcalEndcapPInsertMergedClusters:input_tag", "EcalEndcapPInsertClusters", "EcalEndcapPInsertClusters", "Name of input collection to use"] - ,["EEMC:EcalEndcapPInsertMergedClusters:inputAssociations_tag", "EcalEndcapPInsertClusterAssociations", "EcalEndcapPInsertClustersAssociations", "Name of input associations collection to use"] - ,["EEMC:EcalEndcapPInsertRawHits:capacityADC", "16384", "8096", ""] - ,["EEMC:EcalEndcapPInsertRawHits:dynamicRangeADC", "3000.0", "0.1", ""] - ,["EEMC:EcalEndcapPInsertRawHits:energyResolutions", "0.00316,0.0015,0.0", "", ""] - ,["EEMC:EcalEndcapPInsertRawHits:fieldRefNumbers", "1,1", "", ""] - ,["EEMC:EcalEndcapPInsertRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["EEMC:EcalEndcapPInsertRawHits:input_tag", "EcalEndcapPInsertHits", "EcalEndcapPInsertHits", "Name of input collection to use"] - ,["EEMC:EcalEndcapPInsertRawHits:pedestalMean", "100", "400", ""] - ,["EEMC:EcalEndcapPInsertRawHits:pedestalSigma", "0.7", "3.2", ""] - ,["EEMC:EcalEndcapPInsertRawHits:readoutClass", "", "", ""] - ,["EEMC:EcalEndcapPInsertRawHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["EEMC:EcalEndcapPInsertRawHits:scaleResponse", "0.03", "1", ""] - ,["EEMC:EcalEndcapPInsertRawHits:signalSumFields", "", "", ""] - ,["EEMC:EcalEndcapPInsertRawHits:timeResolution", "0", "0", ""] - ,["EEMC:EcalEndcapPInsertRecHits:capacityADC", "16384", "8096", ""] - ,["EEMC:EcalEndcapPInsertRecHits:dynamicRangeADC", "3000.0", "0.1", ""] - ,["EEMC:EcalEndcapPInsertRecHits:geoServiceName", "geoServiceName", "geoServiceName", ""] - ,["EEMC:EcalEndcapPInsertRecHits:input_tag", "EcalEndcapPInsertRawHits", "EcalEndcapPInsertRawHits", "Name of input collection to use"] - ,["EEMC:EcalEndcapPInsertRecHits:layerField", "", "", ""] - ,["EEMC:EcalEndcapPInsertRecHits:localDetElement", "", "", ""] - ,["EEMC:EcalEndcapPInsertRecHits:localDetFields", "", "", ""] - ,["EEMC:EcalEndcapPInsertRecHits:pedestalMean", "100", "400", ""] - ,["EEMC:EcalEndcapPInsertRecHits:pedestalSigma", "0.7", "3.2", ""] - ,["EEMC:EcalEndcapPInsertRecHits:readout", "EcalEndcapPInsertHits", "EcalEndcapPInsertHits", ""] - ,["EEMC:EcalEndcapPInsertRecHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["EEMC:EcalEndcapPInsertRecHits:samplingFraction", "0.03", "0.998", ""] - ,["EEMC:EcalEndcapPInsertRecHits:sectorField", "", "", ""] - ,["EEMC:EcalEndcapPInsertRecHits:thresholdFactor", "5.0", "4", ""] - ,["EEMC:EcalEndcapPInsertRecHits:thresholdValue", "2", "0", ""] - ,["EEMC:EcalEndcapPInsertTruthClusters:depthCorrection", "0", "0", ""] - ,["EEMC:EcalEndcapPInsertTruthClusters:enableEtaBounds", "1", "0", ""] - ,["EEMC:EcalEndcapPInsertTruthClusters:energyWeight", "log", "log", ""] - ,["EEMC:EcalEndcapPInsertTruthClusters:input_protoclust_tag", "EcalEndcapPInsertTruthProtoClusters", "EcalEndcapPInsertTruthProtoClusters", "Name of input collection to use"] - ,["EEMC:EcalEndcapPInsertTruthClusters:logWeightBase", "6.2", "3.6", ""] - ,["EEMC:EcalEndcapPInsertTruthClusters:moduleDimZName", "", "", ""] - ,["EEMC:EcalEndcapPInsertTruthClusters:samplingFraction", "1", "1", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:dimScaledLocalDistXY", "1.5,1.5", "", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:globalDistEtaPhi", "", "", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:globalDistRPhi", "", "", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:localDistXY", "10,10", "", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:localDistXZ", "", "", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:localDistYZ", "", "", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:minClusterCenterEdep", "10.0", "", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:minClusterHitEdep", "0", "", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:sectorDist", "5", "", ""] - ,["EEMC:EcalEndcapPIslandProtoClusters:splitCluster", "0", "", ""] - ,["EEMC:EcalEndcapPMergedClusters:input_tag", "EcalEndcapPClusters", "EcalEndcapPClusters", "Name of input collection to use"] - ,["EEMC:EcalEndcapPMergedClusters:inputAssociations_tag", "EcalEndcapPClusterAssociations", "EcalEndcapPClustersAssociations", "Name of input associations collection to use"] - ,["EEMC:EcalEndcapPRawHits:capacityADC", "16384", "8096", ""] - ,["EEMC:EcalEndcapPRawHits:dynamicRangeADC", "3000.0", "0.1", ""] - ,["EEMC:EcalEndcapPRawHits:energyResolutions", "0.00316,0.0015,0.0", "", ""] - ,["EEMC:EcalEndcapPRawHits:fieldRefNumbers", "1,1", "", ""] - ,["EEMC:EcalEndcapPRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["EEMC:EcalEndcapPRawHits:input_tag", "EcalEndcapPHits", "EcalEndcapPHits", "Name of input collection to use"] - ,["EEMC:EcalEndcapPRawHits:pedestalMean", "100", "400", ""] - ,["EEMC:EcalEndcapPRawHits:pedestalSigma", "0.7", "3.2", ""] - ,["EEMC:EcalEndcapPRawHits:readoutClass", "", "", ""] - ,["EEMC:EcalEndcapPRawHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["EEMC:EcalEndcapPRawHits:scaleResponse", "0.03", "1", ""] - ,["EEMC:EcalEndcapPRawHits:signalSumFields", "", "", ""] - ,["EEMC:EcalEndcapPRawHits:timeResolution", "0", "0", ""] - ,["EEMC:EcalEndcapPRecHits:capacityADC", "16384", "8096", ""] - ,["EEMC:EcalEndcapPRecHits:dynamicRangeADC", "3000.0", "0.1", ""] - ,["EEMC:EcalEndcapPRecHits:geoServiceName", "geoServiceName", "geoServiceName", ""] - ,["EEMC:EcalEndcapPRecHits:input_tag", "EcalEndcapPRawHits", "EcalEndcapPRawHits", "Name of input collection to use"] - ,["EEMC:EcalEndcapPRecHits:layerField", "", "", ""] - ,["EEMC:EcalEndcapPRecHits:localDetElement", "", "", ""] - ,["EEMC:EcalEndcapPRecHits:localDetFields", "", "", ""] - ,["EEMC:EcalEndcapPRecHits:pedestalMean", "100", "400", ""] - ,["EEMC:EcalEndcapPRecHits:pedestalSigma", "0.7", "3.2", ""] - ,["EEMC:EcalEndcapPRecHits:readout", "EcalEndcapPHits", "EcalEndcapPHits", ""] - ,["EEMC:EcalEndcapPRecHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["EEMC:EcalEndcapPRecHits:samplingFraction", "0.03", "0.998", ""] - ,["EEMC:EcalEndcapPRecHits:sectorField", "", "", ""] - ,["EEMC:EcalEndcapPRecHits:thresholdFactor", "5.0", "4", ""] - ,["EEMC:EcalEndcapPRecHits:thresholdValue", "2", "0", ""] - ,["EEMC:EcalEndcapPTruthClusters:depthCorrection", "0", "0", ""] - ,["EEMC:EcalEndcapPTruthClusters:enableEtaBounds", "1", "0", ""] - ,["EEMC:EcalEndcapPTruthClusters:energyWeight", "log", "log", ""] - ,["EEMC:EcalEndcapPTruthClusters:input_protoclust_tag", "EcalEndcapPTruthProtoClusters", "EcalEndcapPTruthProtoClusters", "Name of input collection to use"] - ,["EEMC:EcalEndcapPTruthClusters:logWeightBase", "6.2", "3.6", ""] - ,["EEMC:EcalEndcapPTruthClusters:moduleDimZName", "", "", ""] - ,["EEMC:EcalEndcapPTruthClusters:samplingFraction", "1", "1", ""] - ,["EEMC:EcalEndcapPTruthProtoClusters:inputHit_tag", "EcalEndcapPRecHits", "EcalEndcapPRecHits", "Name of input collection to use"] - ,["eicrecon:LogLevel", "info", "info", "log_level: trace, debug, info, warn, error, critical, off"] - ,["event_source_type", "", "", ""] - ,["ForwardRomanPotParticles:LogLevel", "info", "info", "log_level for ForwardRomanPotParticles: trace, debug, info, warn, error, critical, off"] - ,["ForwardRomanPotRawHits:LogLevel", "info", "info", "log_level for ForwardRomanPotRawHits: trace, debug, info, warn, error, critical, off"] - ,["ForwardRomanPotRecHits:LogLevel", "info", "info", "log_level for ForwardRomanPotRecHits: trace, debug, info, warn, error, critical, off"] - ,["HCAL:HcalBarrelClusters:depthCorrection", "0", "0", ""] - ,["HCAL:HcalBarrelClusters:enableEtaBounds", "0", "0", ""] - ,["HCAL:HcalBarrelClusters:energyWeight", "log", "log", ""] - ,["HCAL:HcalBarrelClusters:input_protoclust_tag", "HcalBarrelIslandProtoClusters", "HcalBarrelIslandProtoClusters", ""] - ,["HCAL:HcalBarrelClusters:input_simhit_tag", "HcalBarrelHits", "HcalBarrelHits", ""] - ,["HCAL:HcalBarrelClusters:logWeightBase", "6.2", "3.6", ""] - ,["HCAL:HcalBarrelClusters:moduleDimZName", "", "", ""] - ,["HCAL:HcalBarrelClusters:samplingFraction", "1", "1", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:dimScaledLocalDistXY", "5,5", "5,5", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:globalDistEtaPhi", "", "", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:globalDistRPhi", "", "", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:localDistXY", "150,150", "", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:localDistXZ", "", "", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:localDistYZ", "", "", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:minClusterCenterEdep", "0.003", "0.003", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:minClusterHitEdep", "30.0", "0.0001", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:sectorDist", "5", "5", ""] - ,["HCAL:HcalBarrelIslandProtoClusters:splitCluster", "0", "1", ""] - ,["HCAL:HcalBarrelMergedHits:fields", "tower,tile", "layer,slice", ""] - ,["HCAL:HcalBarrelMergedHits:input_tag", "HcalBarrelRecHits", "HcalBarrelRecHits", ""] - ,["HCAL:HcalBarrelMergedHits:refs", "1,0", "1,0", ""] - ,["HCAL:HcalBarrelRawHits:capacityADC", "256", "8096", ""] - ,["HCAL:HcalBarrelRawHits:dynamicRangeADC", "50.0", "50", ""] - ,["HCAL:HcalBarrelRawHits:energyResolutions", "", "", ""] - ,["HCAL:HcalBarrelRawHits:fieldRefNumbers", "1,0", "", ""] - ,["HCAL:HcalBarrelRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["HCAL:HcalBarrelRawHits:pedestalMean", "10", "10", ""] - ,["HCAL:HcalBarrelRawHits:pedestalSigma", "2", "2", ""] - ,["HCAL:HcalBarrelRawHits:readoutClass", "", "", ""] - ,["HCAL:HcalBarrelRawHits:resolutionTDC", "1e-9", "1e-09", ""] - ,["HCAL:HcalBarrelRawHits:scaleResponse", "1", "1", ""] - ,["HCAL:HcalBarrelRawHits:signalSumFields", "", "", ""] - ,["HCAL:HcalBarrelRawHits:timeResolution", "0", "0", ""] - ,["HCAL:HcalBarrelRecHits:capacityADC", "256", "8096", ""] - ,["HCAL:HcalBarrelRecHits:dynamicRangeADC", "20.0", "50", ""] - ,["HCAL:HcalBarrelRecHits:geoServiceName", "geoServiceName", "geoServiceName", ""] - ,["HCAL:HcalBarrelRecHits:layerField", "tower", "tower", ""] - ,["HCAL:HcalBarrelRecHits:localDetElement", "", "", ""] - ,["HCAL:HcalBarrelRecHits:localDetFields", "", "", ""] - ,["HCAL:HcalBarrelRecHits:pedestalMean", "20", "10", ""] - ,["HCAL:HcalBarrelRecHits:pedestalSigma", "0.3", "2", ""] - ,["HCAL:HcalBarrelRecHits:readout", "HcalBarrelHits", "HcalBarrelHits", ""] - ,["HCAL:HcalBarrelRecHits:resolutionTDC", "1e-11", "1e-09", ""] - ,["HCAL:HcalBarrelRecHits:samplingFraction", "0.033", "0.033", ""] - ,["HCAL:HcalBarrelRecHits:sectorField", "sector", "sector", ""] - ,["HCAL:HcalBarrelRecHits:thresholdFactor", "5", "5", ""] - ,["HCAL:HcalBarrelRecHits:thresholdValue", "1", "0", ""] - ,["HCAL:HcalBarrelTruthClusters:depthCorrection", "0", "0", ""] - ,["HCAL:HcalBarrelTruthClusters:enableEtaBounds", "0", "0", ""] - ,["HCAL:HcalBarrelTruthClusters:energyWeight", "log", "log", ""] - ,["HCAL:HcalBarrelTruthClusters:input_protoclust_tag", "HcalBarrelTruthProtoClusters", "HcalBarrelTruthProtoClusters", ""] - ,["HCAL:HcalBarrelTruthClusters:input_simhit_tag", "HcalBarrelHits", "HcalBarrelHits", ""] - ,["HCAL:HcalBarrelTruthClusters:logWeightBase", "6.2", "3.6", ""] - ,["HCAL:HcalBarrelTruthClusters:moduleDimZName", "", "", ""] - ,["HCAL:HcalBarrelTruthClusters:samplingFraction", "1", "1", ""] - ,["HCAL:HcalEndcapNClusters:depthCorrection", "0", "0", ""] - ,["HCAL:HcalEndcapNClusters:enableEtaBounds", "0", "0", ""] - ,["HCAL:HcalEndcapNClusters:energyWeight", "log", "log", ""] - ,["HCAL:HcalEndcapNClusters:input_protoclust_tag", "HcalEndcapNIslandProtoClusters", "HcalEndcapNIslandProtoClusters", ""] - ,["HCAL:HcalEndcapNClusters:input_simhit_tag", "HcalEndcapNHits", "HcalEndcapNHits", ""] - ,["HCAL:HcalEndcapNClusters:logWeightBase", "6.2", "6.2", ""] - ,["HCAL:HcalEndcapNClusters:moduleDimZName", "", "", ""] - ,["HCAL:HcalEndcapNClusters:samplingFraction", "1", "1", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:dimScaledLocalDistXY", "1.5,1.5", "1.5,1.5", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:globalDistEtaPhi", "", "", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:globalDistRPhi", "", "", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:localDistXY", "150,150", "", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:localDistXZ", "", "", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:localDistYZ", "", "", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:minClusterCenterEdep", "30.0", "0.03", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:minClusterHitEdep", "0", "0", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:sectorDist", "5", "5", ""] - ,["HCAL:HcalEndcapNIslandProtoClusters:splitCluster", "1", "1", ""] - ,["HCAL:HcalEndcapNMergedHits:fields", "layer,slice", "layer,slice", ""] - ,["HCAL:HcalEndcapNMergedHits:input_tag", "HcalEndcapNRecHits", "HcalEndcapNRecHits", ""] - ,["HCAL:HcalEndcapNMergedHits:readout", "HcalEndcapNHits", "HcalEndcapNHits", ""] - ,["HCAL:HcalEndcapNMergedHits:refs", "1,0", "1,0", ""] - ,["HCAL:HcalEndcapNRawHits:capacityADC", "1024", "1024", ""] - ,["HCAL:HcalEndcapNRawHits:dynamicRangeADC", "3.6", "0.0036", ""] - ,["HCAL:HcalEndcapNRawHits:energyResolutions", "", "", ""] - ,["HCAL:HcalEndcapNRawHits:fieldRefNumbers", "", "", ""] - ,["HCAL:HcalEndcapNRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["HCAL:HcalEndcapNRawHits:pedestalMean", "20", "400", ""] - ,["HCAL:HcalEndcapNRawHits:pedestalSigma", "0.3", "3.2", ""] - ,["HCAL:HcalEndcapNRawHits:readoutClass", "", "", ""] - ,["HCAL:HcalEndcapNRawHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["HCAL:HcalEndcapNRawHits:scaleResponse", "1", "1", ""] - ,["HCAL:HcalEndcapNRawHits:signalSumFields", "", "", ""] - ,["HCAL:HcalEndcapNRawHits:timeResolution", "0", "0", ""] - ,["HCAL:HcalEndcapNRecHits:capacityADC", "1024", "1024", ""] - ,["HCAL:HcalEndcapNRecHits:dynamicRangeADC", "3.6", "0.0036", ""] - ,["HCAL:HcalEndcapNRecHits:geoServiceName", "geoServiceName", "geoServiceName", ""] - ,["HCAL:HcalEndcapNRecHits:layerField", "", "", ""] - ,["HCAL:HcalEndcapNRecHits:localDetElement", "", "", ""] - ,["HCAL:HcalEndcapNRecHits:localDetFields", "", "", ""] - ,["HCAL:HcalEndcapNRecHits:pedestalMean", "20", "400", ""] - ,["HCAL:HcalEndcapNRecHits:pedestalSigma", "0.3", "3.2", ""] - ,["HCAL:HcalEndcapNRecHits:readout", "HcalEndcapNHits", "HcalEndcapNHits", ""] - ,["HCAL:HcalEndcapNRecHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["HCAL:HcalEndcapNRecHits:samplingFraction", "0.998", "0.998", ""] - ,["HCAL:HcalEndcapNRecHits:sectorField", "", "", ""] - ,["HCAL:HcalEndcapNRecHits:thresholdFactor", "4", "4", ""] - ,["HCAL:HcalEndcapNRecHits:thresholdValue", "1", "0", ""] - ,["HCAL:HcalEndcapNTruthClusters:depthCorrection", "0", "0", ""] - ,["HCAL:HcalEndcapNTruthClusters:enableEtaBounds", "0", "0", ""] - ,["HCAL:HcalEndcapNTruthClusters:energyWeight", "log", "log", ""] - ,["HCAL:HcalEndcapNTruthClusters:input_protoclust_tag", "HcalEndcapNTruthProtoClusters", "HcalEndcapNTruthProtoClusters", ""] - ,["HCAL:HcalEndcapNTruthClusters:input_simhit_tag", "HcalEndcapNHits", "HcalEndcapNHits", ""] - ,["HCAL:HcalEndcapNTruthClusters:logWeightBase", "6.2", "3.6", ""] - ,["HCAL:HcalEndcapNTruthClusters:moduleDimZName", "", "", ""] - ,["HCAL:HcalEndcapNTruthClusters:samplingFraction", "1", "1", ""] - ,["HCAL:HcalEndcapPClusters:depthCorrection", "0", "0", ""] - ,["HCAL:HcalEndcapPClusters:enableEtaBounds", "0", "0", ""] - ,["HCAL:HcalEndcapPClusters:energyWeight", "log", "log", ""] - ,["HCAL:HcalEndcapPClusters:input_protoclust_tag", "HcalEndcapPIslandProtoClusters", "HcalEndcapPIslandProtoClusters", ""] - ,["HCAL:HcalEndcapPClusters:input_simhit_tag", "HcalEndcapPHits", "HcalEndcapPHits", ""] - ,["HCAL:HcalEndcapPClusters:logWeightBase", "6.2", "6.2", ""] - ,["HCAL:HcalEndcapPClusters:moduleDimZName", "", "", ""] - ,["HCAL:HcalEndcapPClusters:samplingFraction", "0.025", "1", ""] - ,["HCAL:HcalEndcapPInsertClusters:depthCorrection", "0", "0", ""] - ,["HCAL:HcalEndcapPInsertClusters:enableEtaBounds", "0", "0", ""] - ,["HCAL:HcalEndcapPInsertClusters:energyWeight", "log", "log", ""] - ,["HCAL:HcalEndcapPInsertClusters:input_protoclust_tag", "HcalEndcapPInsertIslandProtoClusters", "HcalEndcapPInsertIslandProtoClusters", ""] - ,["HCAL:HcalEndcapPInsertClusters:input_simhit_tag", "HcalEndcapPInsertHits", "HcalEndcapPInsertHits", ""] - ,["HCAL:HcalEndcapPInsertClusters:logWeightBase", "6.2", "6.2", ""] - ,["HCAL:HcalEndcapPInsertClusters:moduleDimZName", "", "", ""] - ,["HCAL:HcalEndcapPInsertClusters:samplingFraction", "1", "1", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:dimScaledLocalDistXY", "1.5,1.5", "", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:globalDistEtaPhi", "", "", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:globalDistRPhi", "", "", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:localDistXY", "", "", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:localDistXZ", "", "", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:localDistYZ", "", "", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:minClusterCenterEdep", "0.03", "", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:minClusterHitEdep", "0", "", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:sectorDist", "5", "", ""] - ,["HCAL:HcalEndcapPInsertIslandProtoClusters:splitCluster", "1", "", ""] - ,["HCAL:HcalEndcapPInsertRawHits:capacityADC", "32768", "32768", ""] - ,["HCAL:HcalEndcapPInsertRawHits:dynamicRangeADC", "200.0", "0.2", ""] - ,["HCAL:HcalEndcapPInsertRawHits:energyResolutions", "", "", ""] - ,["HCAL:HcalEndcapPInsertRawHits:fieldRefNumbers", "", "", ""] - ,["HCAL:HcalEndcapPInsertRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["HCAL:HcalEndcapPInsertRawHits:pedestalMean", "400", "400", ""] - ,["HCAL:HcalEndcapPInsertRawHits:pedestalSigma", "10", "10", ""] - ,["HCAL:HcalEndcapPInsertRawHits:readoutClass", "", "", ""] - ,["HCAL:HcalEndcapPInsertRawHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["HCAL:HcalEndcapPInsertRawHits:scaleResponse", "1", "1", ""] - ,["HCAL:HcalEndcapPInsertRawHits:signalSumFields", "", "", ""] - ,["HCAL:HcalEndcapPInsertRawHits:timeResolution", "0", "0", ""] - ,["HCAL:HcalEndcapPInsertRecHits:capacityADC", "32768", "32768", ""] - ,["HCAL:HcalEndcapPInsertRecHits:dynamicRangeADC", "200.0", "0.2", ""] - ,["HCAL:HcalEndcapPInsertRecHits:geoServiceName", "geoServiceName", "geoServiceName", ""] - ,["HCAL:HcalEndcapPInsertRecHits:layerField", "", "", ""] - ,["HCAL:HcalEndcapPInsertRecHits:localDetElement", "", "", ""] - ,["HCAL:HcalEndcapPInsertRecHits:localDetFields", "", "", ""] - ,["HCAL:HcalEndcapPInsertRecHits:pedestalMean", "400", "400", ""] - ,["HCAL:HcalEndcapPInsertRecHits:pedestalSigma", "10", "10", ""] - ,["HCAL:HcalEndcapPInsertRecHits:readout", "HcalEndcapPInsertHits", "HcalEndcapPInsertHits", ""] - ,["HCAL:HcalEndcapPInsertRecHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["HCAL:HcalEndcapPInsertRecHits:samplingFraction", "0.998", "1", ""] - ,["HCAL:HcalEndcapPInsertRecHits:sectorField", "", "", ""] - ,["HCAL:HcalEndcapPInsertRecHits:thresholdFactor", "4", "4", ""] - ,["HCAL:HcalEndcapPInsertRecHits:thresholdValue", "0", "0", ""] - ,["HCAL:HcalEndcapPInsertTruthClusters:depthCorrection", "0", "", ""] - ,["HCAL:HcalEndcapPInsertTruthClusters:enableEtaBounds", "0", "", ""] - ,["HCAL:HcalEndcapPInsertTruthClusters:energyWeight", "log", "", ""] - ,["HCAL:HcalEndcapPInsertTruthClusters:input_protoclust_tag", "HcalEndcapPInsertTruthProtoClusters", "", ""] - ,["HCAL:HcalEndcapPInsertTruthClusters:input_simhit_tag", "HcalEndcapPInsertHits", "", ""] - ,["HCAL:HcalEndcapPInsertTruthClusters:logWeightBase", "6.2", "", ""] - ,["HCAL:HcalEndcapPInsertTruthClusters:moduleDimZName", "", "", ""] - ,["HCAL:HcalEndcapPInsertTruthClusters:samplingFraction", "1", "", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:dimScaledLocalDistXY", "1.5,1.5", "1.5,1.5", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:globalDistEtaPhi", "", "", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:globalDistRPhi", "", "", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:localDistXY", "150,150", "", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:localDistXZ", "", "", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:localDistYZ", "", "", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:minClusterCenterEdep", "30.0", "0.03", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:minClusterHitEdep", "0", "0", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:sectorDist", "5", "5", ""] - ,["HCAL:HcalEndcapPIslandProtoClusters:splitCluster", "1", "1", ""] - ,["HCAL:HcalEndcapPMergedHits:fields", "layer,slice", "layer,slice", ""] - ,["HCAL:HcalEndcapPMergedHits:input_tag", "HcalEndcapPRecHits", "HcalEndcapPRecHits", ""] - ,["HCAL:HcalEndcapPMergedHits:readout", "HcalEndcapPHits", "HcalEndcapPHits", ""] - ,["HCAL:HcalEndcapPMergedHits:refs", "1,0", "1,0", ""] - ,["HCAL:HcalEndcapPRawHits:capacityADC", "1024", "1024", ""] - ,["HCAL:HcalEndcapPRawHits:dynamicRangeADC", "3600.0", "3.6", ""] - ,["HCAL:HcalEndcapPRawHits:energyResolutions", "", "", ""] - ,["HCAL:HcalEndcapPRawHits:fieldRefNumbers", "", "", ""] - ,["HCAL:HcalEndcapPRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["HCAL:HcalEndcapPRawHits:pedestalMean", "20", "20", ""] - ,["HCAL:HcalEndcapPRawHits:pedestalSigma", "0.8", "0.8", ""] - ,["HCAL:HcalEndcapPRawHits:readoutClass", "", "", ""] - ,["HCAL:HcalEndcapPRawHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["HCAL:HcalEndcapPRawHits:scaleResponse", "1", "1", ""] - ,["HCAL:HcalEndcapPRawHits:signalSumFields", "", "", ""] - ,["HCAL:HcalEndcapPRawHits:timeResolution", "0", "0", ""] - ,["HCAL:HcalEndcapPRecHits:capacityADC", "1024", "8096", ""] - ,["HCAL:HcalEndcapPRecHits:dynamicRangeADC", "3600.0", "0.1", ""] - ,["HCAL:HcalEndcapPRecHits:geoServiceName", "geoServiceName", "geoServiceName", ""] - ,["HCAL:HcalEndcapPRecHits:layerField", "", "", ""] - ,["HCAL:HcalEndcapPRecHits:localDetElement", "", "", ""] - ,["HCAL:HcalEndcapPRecHits:localDetFields", "", "", ""] - ,["HCAL:HcalEndcapPRecHits:pedestalMean", "20", "400", ""] - ,["HCAL:HcalEndcapPRecHits:pedestalSigma", "0.8", "3.2", ""] - ,["HCAL:HcalEndcapPRecHits:readout", "HcalEndcapPHits", "HcalEndcapPHits", ""] - ,["HCAL:HcalEndcapPRecHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["HCAL:HcalEndcapPRecHits:samplingFraction", "0.025", "0.998", ""] - ,["HCAL:HcalEndcapPRecHits:sectorField", "", "", ""] - ,["HCAL:HcalEndcapPRecHits:thresholdFactor", "5", "4", ""] - ,["HCAL:HcalEndcapPRecHits:thresholdValue", "3", "0", ""] - ,["HCAL:HcalEndcapPTruthClusters:depthCorrection", "0", "", ""] - ,["HCAL:HcalEndcapPTruthClusters:enableEtaBounds", "0", "", ""] - ,["HCAL:HcalEndcapPTruthClusters:energyWeight", "log", "", ""] - ,["HCAL:HcalEndcapPTruthClusters:input_protoclust_tag", "HcalEndcapPTruthProtoClusters", "", ""] - ,["HCAL:HcalEndcapPTruthClusters:input_simhit_tag", "HcalEndcapPHits", "", ""] - ,["HCAL:HcalEndcapPTruthClusters:logWeightBase", "6.2", "", ""] - ,["HCAL:HcalEndcapPTruthClusters:moduleDimZName", "", "", ""] - ,["HCAL:HcalEndcapPTruthClusters:samplingFraction", "0.025", "", ""] - ,["HcalBarrelClusters:LogLevel", "info", "info", "log_level for HcalBarrelClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalBarrelIslandProtoClusters:LogLevel", "info", "info", "log_level for HcalBarrelIslandProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalBarrelMergedHits:LogLevel", "info", "info", "log_level for HcalBarrelMergedHits: trace, debug, info, warn, error, critical, off"] - ,["HcalBarrelRawHits:LogLevel", "info", "info", "log_level for HcalBarrelRawHits: trace, debug, info, warn, error, critical, off"] - ,["HcalBarrelRecHits:LogLevel", "info", "info", "log_level for HcalBarrelRecHits: trace, debug, info, warn, error, critical, off"] - ,["HcalBarrelTruthClusters:LogLevel", "info", "info", "log_level for HcalBarrelTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalBarrelTruthProtoClusters:LogLevel", "info", "info", "log_level for HcalBarrelTruthProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapNClusters:LogLevel", "info", "info", "log_level for HcalEndcapNClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapNIslandProtoClusters:LogLevel", "info", "info", "log_level for HcalEndcapNIslandProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapNMergedHits:LogLevel", "info", "info", "log_level for HcalEndcapNMergedHits: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapNRawHits:LogLevel", "info", "info", "log_level for HcalEndcapNRawHits: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapNRecHits:LogLevel", "info", "info", "log_level for HcalEndcapNRecHits: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapNTruthClusters:LogLevel", "info", "info", "log_level for HcalEndcapNTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapNTruthProtoClusters:LogLevel", "info", "info", "log_level for HcalEndcapNTruthProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPClusters:LogLevel", "info", "info", "log_level for HcalEndcapPClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPInsertClusters:LogLevel", "info", "info", "log_level for HcalEndcapPInsertClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPInsertIslandProtoClusters:LogLevel", "info", "info", "log_level for HcalEndcapPInsertIslandProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPInsertMergedHits:LogLevel", "info", "info", "log_level for HcalEndcapPInsertMergedHits: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPInsertRawHits:LogLevel", "info", "info", "log_level for HcalEndcapPInsertRawHits: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPInsertRecHits:LogLevel", "info", "info", "log_level for HcalEndcapPInsertRecHits: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPInsertTruthClusters:LogLevel", "info", "info", "log_level for HcalEndcapPInsertTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPInsertTruthProtoClusters:LogLevel", "info", "info", "log_level for HcalEndcapPInsertTruthProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPIslandProtoClusters:LogLevel", "info", "info", "log_level for HcalEndcapPIslandProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPMergedHits:LogLevel", "info", "info", "log_level for HcalEndcapPMergedHits: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPRawHits:LogLevel", "info", "info", "log_level for HcalEndcapPRawHits: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPRecHits:LogLevel", "info", "info", "log_level for HcalEndcapPRecHits: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPTruthClusters:LogLevel", "info", "info", "log_level for HcalEndcapPTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["HcalEndcapPTruthProtoClusters:LogLevel", "info", "info", "log_level for HcalEndcapPTruthProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["histsfile", "rec_pi_1GeV_20GeV_arches.ana.root", "", ""] - ,["jana:affinity", "2", "2", ""] - ,["jana:debug_plugin_loading", "1", "0", ""] - ,["jana:enable_stealing", "0", "0", ""] - ,["jana:engine", "0", "0", "0: Arrow engine, 1: Debug engine"] - ,["jana:event_pool_size", "1", "1", ""] - ,["jana:event_processor_chunksize", "1", "1", ""] - ,["jana:event_queue_threshold", "80", "80", ""] - ,["jana:event_source_chunksize", "40", "40", ""] - ,["jana:extended_report", "0", "0", ""] - ,["jana:limit_total_events_in_flight", "1", "1", ""] - ,["jana:locality", "0", "0", ""] - ,["jana:nevents", "0", "0", ""] - ,["jana:nskip", "0", "0", "Number of events that sources should skip before starting emitting"] - ,["jana:plugin_path", "", "", "Colon-separated paths to search for plugins"] - ,["JANA:STATUS_FNAME", "/tmp/jana_status", "/tmp/jana_status", "Filename of named pipe for retrieving instantaneous status info"] - ,["jana:timeout", "180", "8", ""] - ,["jana:warmup_timeout", "180", "30", ""] - ,["JEventProcessorPODIO:LogLevel", "info", "info", "log_level for JEventProcessorPODIO: trace, debug, info, warn, error, critical, off"] - ,["log:debug", "", "", ""] - ,["log:error", "", "", ""] - ,["log:fatal", "", "", ""] - ,["log:info", "", "", ""] - ,["log:off", "", "", ""] - ,["log:trace", "", "", ""] - ,["log:warn", "", "", ""] - ,["MPGD:MPGDTrackerHit:InputTags", "", "", "Input data tag name"] - ,["MPGD:MPGDTrackerHit:LogLevel", "info", "info", "log_level for MPGD:MPGDTrackerHit: trace, debug, info, warn, error, critical, off"] - ,["MPGD:MPGDTrackerHit:TimeResolution", "8", "10", ""] - ,["MPGD:MPGDTrackerRawHit:InputTags", "", "", "Input data tag name"] - ,["MPGD:MPGDTrackerRawHit:LogLevel", "info", "info", "log_level for MPGD:MPGDTrackerRawHit: trace, debug, info, warn, error, critical, off"] - ,["MPGD:MPGDTrackerRawHit:Threshold", "0", "0", ""] - ,["MPGD:MPGDTrackerRawHit:TimeResolution", "8", "8", ""] - ,["nthreads", "1", "1", "The total number of worker threads"] - ,["plugins", "log,dd4hep,acts,rootfile,algorithms_calorimetry,algorithms_tracking,algorithms_digi,digi,reco,tracking,BEMC,HCAL,B0ECAL,ZDC,BTRK,BVTX,ECTRK,EEMC,MPGD,RPOTS,BTOF,ECTOF,podio,dump_flags", "", ""] - ,["plugins_to_ignore", "", "", ""] - ,["podio:background_filename", "", "", "Name of file containing background events to merge in (default is not to merge any background)"] - ,["podio:num_background_events", "1", "1", "Number of background events to add to every primary event."] - ,["podio:output_exclude_collections", "", "", "Comma separated list of collection names to not write out."] - ,["podio:output_file", "rec_pi_1GeV_20GeV_arches.tree.edm4eic.root", "podio_output.root", ""] - ,["podio:output_file_copy_dir", "", "", "Directory name to make an additional copy of the output file to. Copy will be done at end of processing. Default is empty string which means do not make a copy. No check is made on path existing."] - ,["podio:output_include_collections", "MCParticles,GeneratedParticles,ReconstructedParticles,ReconstructedChargedParticles,ReconstructedChargedParticlesAssociations,trackerHits,BarrelTrackerHit,EndcapTrackerHit,TOFBarrelTrackerHit,BarrelVertexHit,TOFEndcapTrackerHit,ForwardOffMTrackerRecHits,MPGDTrackerHit,ForwardRomanPotRecHits,CentralTrackSegments,EcalEndcapNRawHits,EcalEndcapNRecHits,EcalEndcapNTruthClusters,EcalEndcapNClusters,EcalEndcapNMergedClusters,EcalEndcapNTruthClusterAssociations,EcalEndcapNClustersAssociations,EcalEndcapNMergedClustersAssociations,EcalEndcapPRawHits,EcalEndcapPRecHits,EcalEndcapPTruthClusters,EcalEndcapPClusters,EcalEndcapPMergedClusters,EcalEndcapPTruthClustersAssociations,EcalEndcapPClustersAssociations,EcalEndcapPMergedClustersAssociations,EcalEndcapPInsertRawHits,EcalEndcapPInsertRecHits,EcalEndcapPInsertTruthClusters,EcalEndcapPInsertClusters,EcalEndcapPInsertMergedClusters,EcalEndcapPInsertTruthClustersAssociations,EcalEndcapPInsertClustersAssociations,EcalEndcapPInsertMergedClustersAssociations,EcalBarrelSciGlassRawHits,EcalBarrelSciGlassRecHits,EcalBarrelSciGlassClusters,EcalBarrelSciGlassMergedClusters,EcalBarrelSciGlassTruthClusters,EcalBarrelSciGlassMergedTruthClusters,EcalBarrelImagingRawHits,EcalBarrelImagingRecHits,EcalBarrelImagingClusters,EcalBarrelImagingMergedClusters,EcalBarrelScFiRawHits,EcalBarrelScFiRecHits,EcalBarrelScFiMergedHits,EcalBarrelScFiClusters,HcalEndcapNRawHits,HcalEndcapNRecHits,HcalEndcapNMergedHits,HcalEndcapNClusters,HcalEndcapPRawHits,HcalEndcapPRecHits,HcalEndcapPMergedHits,HcalEndcapPClusters,HcalEndcapPInsertRawHits,HcalEndcapPInsertRecHits,HcalEndcapPInsertMergedHits,HcalEndcapPInsertClusters,HcalBarrelRawHits,HcalBarrelRecHits,HcalBarrelClusters,B0ECalRawHits,B0ECalRecHits,B0ECalClusters,ZDCEcalRawHits,ZDCEcalRecHits,ZDCEcalClusters,ZDCEcalMergedClusters,HcalEndcapNTruthClusters,HcalBarrelTruthClusters,B0ECalRecHits,B0ECalClusters,ZDCEcalTruthClusters,ForwardRomanPotRawHits,ForwardRomanPotRecHits,ForwardRomanPotParticles,SmearedFarForwardParticles", "MCParticles,GeneratedParticles,ReconstructedParticles,ReconstructedChargedParticles,ReconstructedChargedParticlesAssociations,trackerHits,BarrelTrackerHit,EndcapTrackerHit,TOFBarrelTrackerHit,BarrelVertexHit,TOFEndcapTrackerHit,ForwardOffMTrackerRecHits,MPGDTrackerHit,ForwardRomanPotRecHits,CentralTrackSegments,EcalEndcapNRawHits,EcalEndcapNRecHits,EcalEndcapNTruthClusters,EcalEndcapNClusters,EcalEndcapNMergedClusters,EcalEndcapNTruthClustersAssociations,EcalEndcapNClustersAssociations,EcalEndcapNMergedClustersAssociations,EcalEndcapPRawHits,EcalEndcapPRecHits,EcalEndcapPTruthClusters,EcalEndcapPClusters,EcalEndcapPMergedClusters,EcalEndcapPTruthClustersAssociations,EcalEndcapPClustersAssociations,EcalEndcapPMergedClustersAssociations,EcalEndcapPInsertRawHits,EcalEndcapPInsertRecHits,EcalEndcapPInsertTruthClusters,EcalEndcapPInsertClusters,EcalEndcapPInsertMergedClusters,EcalEndcapPInsertTruthClustersAssociations,EcalEndcapPInsertClustersAssociations,EcalEndcapPInsertMergedClustersAssociations,EcalBarrelSciGlassRawHits,EcalBarrelSciGlassRecHits,EcalBarrelSciGlassClusters,EcalBarrelSciGlassMergedClusters,EcalBarrelSciGlassTruthClusters,EcalBarrelSciGlassMergedTruthClusters,EcalBarrelImagingRawHits,EcalBarrelImagingRecHits,EcalBarrelImagingClusters,EcalBarrelImagingMergedClusters,EcalBarrelScFiRawHits,EcalBarrelScFiRecHits,EcalBarrelScFiMergedHits,EcalBarrelScFiClusters,HcalEndcapNRawHits,HcalEndcapNRecHits,HcalEndcapNMergedHits,HcalEndcapNClusters,HcalEndcapPRawHits,HcalEndcapPRecHits,HcalEndcapPMergedHits,HcalEndcapPClusters,HcalEndcapPInsertRawHits,HcalEndcapPInsertRecHits,HcalEndcapPInsertMergedHits,HcalEndcapPInsertClusters,HcalBarrelRawHits,HcalBarrelRecHits,HcalBarrelClusters,B0ECalRawHits,B0ECalRecHits,B0ECalClusters,ZDCEcalRawHits,ZDCEcalRecHits,ZDCEcalClusters,ZDCEcalMergedClusters,HcalEndcapNTruthClusters,HcalBarrelTruthClusters,B0ECalRecHits,B0ECalClusters,ZDCEcalTruthClusters,ForwardRomanPotRawHits,ForwardRomanPotRecHits,ForwardRomanPotParticles,SmearedFarForwardParticles", "Comma separated list of collection names to write out. If not set, all collections will be written (including ones from input file). Don't set this and use PODIO:OUTPUT_EXCLUDE_COLLECTIONS to write everything except a selection."] - ,["podio:print_type_table", "0", "0", "Print list of collection names and their types"] - ,["podio:run_forever", "0", "0", "set to true to recycle through events continuously"] - ,["Reco:GeneratedParticles:InputTags", "", "", "Input data tag name"] - ,["Reco:GeneratedParticles:LogLevel", "info", "info", "log_level for Reco:GeneratedParticles: trace, debug, info, warn, error, critical, off"] - ,["Reco:GeneratedParticles:MomentumSmearing", "0", "0", ""] - ,["reco:ReconstructedParticlesWithAssoc:InputTags", "", "", "Input data tag name"] - ,["reco:ReconstructedParticlesWithAssoc:LogLevel", "info", "info", "log_level for reco:ReconstructedParticlesWithAssoc: trace, debug, info, warn, error, critical, off"] - ,["RECORD_CALL_STACK", "0", "0", ""] - ,["RPOTS:ForwardRomanPotParticles:crossingAngle", "-0.025", "-0.025", ""] - ,["RPOTS:ForwardRomanPotParticles:local_x_offset_station_1", "-833.3878326", "-833.388", ""] - ,["RPOTS:ForwardRomanPotParticles:local_x_offset_station_2", "-924.342804", "-924.343", ""] - ,["RPOTS:ForwardRomanPotParticles:local_x_slope_offset", "-0.00622147", "-0.00622147", ""] - ,["RPOTS:ForwardRomanPotParticles:local_y_slope_offset", "-0.0451035", "-0.0451035", ""] - ,["RPOTS:ForwardRomanPotParticles:m_layerField", "", "", ""] - ,["RPOTS:ForwardRomanPotParticles:m_localDetElement", "", "", ""] - ,["RPOTS:ForwardRomanPotParticles:m_readout", "", "", ""] - ,["RPOTS:ForwardRomanPotParticles:m_sectorField", "", "", ""] - ,["RPOTS:ForwardRomanPotParticles:nomMomentum", "275.0", "275", ""] - ,["RPOTS:ForwardRomanPotParticles:u_localDetFields", "", "", ""] - ,["RPOTS:ForwardRomanPotRawHits:threshold", "0.0", "0", ""] - ,["RPOTS:ForwardRomanPotRawHits:timeResolution", "8.0", "8", ""] - ,["RPOTS:ForwardRomanPotRecHits:time_resolution", "0.0", "0", ""] - ,["tracking:CentralCKFTrajectories:Chi2CutOff", "15", "50", ""] - ,["tracking:CentralCKFTrajectories:EtaBins", "", "", ""] - ,["tracking:CentralCKFTrajectories:InputTags", "", "", "Input data tag name"] - ,["tracking:CentralCKFTrajectories:LogLevel", "info", "info", "log_level for tracking:CentralCKFTrajectories: trace, debug, info, warn, error, critical, off"] - ,["tracking:CentralCKFTrajectories:NumMeasurementsCutOff", "10", "10", ""] - ,["tracking:CentralTrackerSourceLinker:InputTags", "", "", "Input data tag name"] - ,["tracking:CentralTrackerSourceLinker:LogLevel", "info", "info", "log_level for tracking:CentralTrackerSourceLinker: trace, debug, info, warn, error, critical, off"] - ,["tracking:CentralTrackingParticles:InputTags", "", "", "Input data tag name"] - ,["tracking:CentralTrackingParticles:LogLevel", "info", "info", "log_level for tracking:CentralTrackingParticles: trace, debug, info, warn, error, critical, off"] - ,["tracking:CentralTrackSegments:InputTags", "", "", "Input data tag name"] - ,["tracking:CentralTrackSegments:LogLevel", "info", "info", "log_level for tracking:CentralTrackSegments: trace, debug, info, warn, error, critical, off"] - ,["tracking:ChargedParticlesWithAssociations:InputTags", "", "", "Input data tag name"] - ,["tracking:ChargedParticlesWithAssociations:LogLevel", "info", "info", "log_level for tracking:ChargedParticlesWithAssociations: trace, debug, info, warn, error, critical, off"] - ,["tracking:InitTrackParams:InputTags", "", "", "Input data tag name"] - ,["tracking:InitTrackParams:LogLevel", "info", "info", "log_level for tracking:InitTrackParams: trace, debug, info, warn, error, critical, off"] - ,["tracking:outputTrackParameters:InputTags", "", "", "Input data tag name"] - ,["tracking:outputTrackParameters:LogLevel", "info", "info", "log_level for tracking:outputTrackParameters: trace, debug, info, warn, error, critical, off"] - ,["Tracking:ReconstructedChargedParticles:InputTags", "", "", "Input data tag name"] - ,["Tracking:ReconstructedChargedParticles:LogLevel", "info", "info", "log_level for Tracking:ReconstructedChargedParticles: trace, debug, info, warn, error, critical, off"] - ,["Tracking:ReconstructedChargedParticlesAssociations:InputTags", "", "", "Input data tag name"] - ,["Tracking:ReconstructedChargedParticlesAssociations:LogLevel", "info", "info", "log_level for Tracking:ReconstructedChargedParticlesAssociations: trace, debug, info, warn, error, critical, off"] - ,["Tracking:ReconstructedParticles:InputTags", "", "", "Input data tag name"] - ,["Tracking:ReconstructedParticles:LogLevel", "info", "info", "log_level for Tracking:ReconstructedParticles: trace, debug, info, warn, error, critical, off"] - ,["tracking:trackerHits:InputTags", "", "", "Input data tag name"] - ,["tracking:trackerHits:LogLevel", "info", "info", "log_level for tracking:trackerHits: trace, debug, info, warn, error, critical, off"] - ,["ZDC:ZDCEcalClusters:depthCorrection", "0", "0", ""] - ,["ZDC:ZDCEcalClusters:enableEtaBounds", "0", "0", ""] - ,["ZDC:ZDCEcalClusters:energyWeight", "log", "log", ""] - ,["ZDC:ZDCEcalClusters:input_protoclust_tag", "ZDCEcalIslandProtoClusters", "ZDCEcalIslandProtoClusters", ""] - ,["ZDC:ZDCEcalClusters:input_simhit_tag", "ZDCEcalHits", "ZDCEcalHits", ""] - ,["ZDC:ZDCEcalClusters:logWeightBase", "6.2", "3.6", ""] - ,["ZDC:ZDCEcalClusters:moduleDimZName", "", "", ""] - ,["ZDC:ZDCEcalClusters:samplingFraction", "1", "1", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:dimScaledLocalDistXY", "5,5", "5,5", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:globalDistEtaPhi", "", "", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:globalDistRPhi", "", "", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:localDistXY", "50,50", "", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:localDistXZ", "", "", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:localDistYZ", "", "", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:minClusterCenterEdep", "3.0", "0.003", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:minClusterHitEdep", "0.1", "0.0001", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:sectorDist", "5", "5", ""] - ,["ZDC:ZDCEcalIslandProtoClusters:splitCluster", "1", "1", ""] - ,["ZDC:ZDCEcalRawHits:capacityADC", "8096", "8096", ""] - ,["ZDC:ZDCEcalRawHits:dynamicRangeADC", "0.1", "0.1", ""] - ,["ZDC:ZDCEcalRawHits:energyResolutions", "", "", ""] - ,["ZDC:ZDCEcalRawHits:fieldRefNumbers", "", "", ""] - ,["ZDC:ZDCEcalRawHits:geoServiceName", "ActsGeometryProvider", "ActsGeometryProvider", ""] - ,["ZDC:ZDCEcalRawHits:pedestalMean", "400", "400", ""] - ,["ZDC:ZDCEcalRawHits:pedestalSigma", "3.2", "3.2", ""] - ,["ZDC:ZDCEcalRawHits:readoutClass", "", "", ""] - ,["ZDC:ZDCEcalRawHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["ZDC:ZDCEcalRawHits:scaleResponse", "1", "1", ""] - ,["ZDC:ZDCEcalRawHits:signalSumFields", "", "", ""] - ,["ZDC:ZDCEcalRawHits:timeResolution", "0", "0", ""] - ,["ZDC:ZDCEcalRecHits:capacityADC", "8096", "8096", ""] - ,["ZDC:ZDCEcalRecHits:dynamicRangeADC", "0.1", "0.1", ""] - ,["ZDC:ZDCEcalRecHits:geoServiceName", "geoServiceName", "geoServiceName", ""] - ,["ZDC:ZDCEcalRecHits:layerField", "", "", ""] - ,["ZDC:ZDCEcalRecHits:localDetElement", "", "", ""] - ,["ZDC:ZDCEcalRecHits:localDetFields", "", "", ""] - ,["ZDC:ZDCEcalRecHits:pedestalMean", "400", "400", ""] - ,["ZDC:ZDCEcalRecHits:pedestalSigma", "3.2", "3.2", ""] - ,["ZDC:ZDCEcalRecHits:readout", "ZDCEcalHits", "ZDCEcalHits", ""] - ,["ZDC:ZDCEcalRecHits:resolutionTDC", "1e-11", "1e-11", ""] - ,["ZDC:ZDCEcalRecHits:samplingFraction", "1", "0.998", ""] - ,["ZDC:ZDCEcalRecHits:sectorField", "", "", ""] - ,["ZDC:ZDCEcalRecHits:thresholdFactor", "4", "4", ""] - ,["ZDC:ZDCEcalRecHits:thresholdValue", "0", "0", ""] - ,["ZDC:ZDCEcalTruthClusters:depthCorrection", "0", "0", ""] - ,["ZDC:ZDCEcalTruthClusters:enableEtaBounds", "0", "0", ""] - ,["ZDC:ZDCEcalTruthClusters:energyWeight", "log", "log", ""] - ,["ZDC:ZDCEcalTruthClusters:input_protoclust_tag", "ZDCEcalTruthProtoClusters", "ZDCEcalTruthProtoClusters", ""] - ,["ZDC:ZDCEcalTruthClusters:input_simhit_tag", "ZDCEcalHits", "ZDCEcalHits", ""] - ,["ZDC:ZDCEcalTruthClusters:logWeightBase", "3.6", "3.6", ""] - ,["ZDC:ZDCEcalTruthClusters:moduleDimZName", "", "", ""] - ,["ZDC:ZDCEcalTruthClusters:samplingFraction", "1", "1", ""] - ,["ZDCEcalClusters:LogLevel", "info", "info", "log_level for ZDCEcalClusters: trace, debug, info, warn, error, critical, off"] - ,["ZDCEcalIslandProtoClusters:LogLevel", "info", "info", "log_level for ZDCEcalIslandProtoClusters: trace, debug, info, warn, error, critical, off"] - ,["ZDCEcalMergedClusters:LogLevel", "info", "info", "log_level for ZDCEcalMergedClusters: trace, debug, info, warn, error, critical, off"] - ,["ZDCEcalMergedTruthClusters:LogLevel", "info", "info", "log_level for ZDCEcalMergedTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["ZDCEcalRawHits:LogLevel", "info", "info", "log_level for ZDCEcalRawHits: trace, debug, info, warn, error, critical, off"] - ,["ZDCEcalRecHits:LogLevel", "info", "info", "log_level for ZDCEcalRecHits: trace, debug, info, warn, error, critical, off"] - ,["ZDCEcalTruthClusters:LogLevel", "info", "info", "log_level for ZDCEcalTruthClusters: trace, debug, info, warn, error, critical, off"] - ,["ZDCEcalTruthProtoClusters:LogLevel", "info", "info", "log_level for ZDCEcalTruthProtoClusters: trace, debug, info, warn, error, critical, off"] + [ + "acts:InitLogLevel", + "info", + "info", + "log_level: trace, debug, info, warn, error, critical, off" + ], + [ + "acts:LogLevel", + "info", + "info", + "log_level for acts: trace, debug, info, warn, error, critical, off" + ], + [ + "acts:MaterialMap", + "calibrations/materials-map.cbor", + "calibrations/materials-map.cbor", + "" + ], + [ + "acts_init:LogLevel", + "info", + "info", + "log_level for acts_init: trace, debug, info, warn, error, critical, off" + ], + [ + "B0ECAL:B0ECalClusters:depthCorrection", + "0", + "", + "" + ], + [ + "B0ECAL:B0ECalClusters:enableEtaBounds", + "0", + "", + "" + ], + [ + "B0ECAL:B0ECalClusters:energyWeight", + "log", + "", + "" + ], + [ + "B0ECAL:B0ECalClusters:input_protoclust_tag", + "B0ECalIslandProtoClusters", + "", + "" + ], + [ + "B0ECAL:B0ECalClusters:logWeightBase", + "3.6", + "", + "" + ], + [ + "B0ECAL:B0ECalClusters:moduleDimZName", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalClusters:samplingFraction", + "1", + "", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:dimScaledLocalDistXY", + "1.8,1.8", + "1.8,1.8", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:input_tag", + "B0ECalRecHits", + "B0ECalRecHits", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:localDistXY", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:minClusterCenterEdep", + "1.0", + "0.001", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:minClusterHitEdep", + "30.0", + "0.03", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:sectorDist", + "50.0", + "5", + "" + ], + [ + "B0ECAL:B0ECalIslandProtoClusters:splitCluster", + "0", + "0", + "" + ], + [ + "B0ECAL:B0ECalRawHits:capacityADC", + "16384", + "16384", + "" + ], + [ + "B0ECAL:B0ECalRawHits:dynamicRangeADC", + "20000.0", + "1", + "" + ], + [ + "B0ECAL:B0ECalRawHits:energyResolutions", + "0.0,0.02,0.0", + "0,0.02,0", + "" + ], + [ + "B0ECAL:B0ECalRawHits:fieldRefNumbers", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalRawHits:geoServiceName", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalRawHits:input_tag", + "B0ECalHits", + "B0ECalHits", + "Name of input collection to use" + ], + [ + "B0ECAL:B0ECalRawHits:pedestalMean", + "100", + "100", + "" + ], + [ + "B0ECAL:B0ECalRawHits:pedestalSigma", + "1", + "1", + "" + ], + [ + "B0ECAL:B0ECalRawHits:readoutClass", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalRawHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "B0ECAL:B0ECalRawHits:scaleResponse", + "1", + "1", + "" + ], + [ + "B0ECAL:B0ECalRawHits:signalSumFields", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "B0ECAL:B0ECalRecHits:capacityADC", + "16384", + "16384", + "" + ], + [ + "B0ECAL:B0ECalRecHits:dynamicRangeADC", + "20000.0", + "20", + "" + ], + [ + "B0ECAL:B0ECalRecHits:geoServiceName", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalRecHits:input_tag", + "B0ECalRawHits", + "B0ECalRawHits", + "Name of input collection to use" + ], + [ + "B0ECAL:B0ECalRecHits:layerField", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalRecHits:localDetElement", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalRecHits:localDetFields", + "", + "", + "" + ], + [ + "B0ECAL:B0ECalRecHits:pedestalMean", + "100", + "100", + "" + ], + [ + "B0ECAL:B0ECalRecHits:pedestalSigma", + "1", + "1", + "" + ], + [ + "B0ECAL:B0ECalRecHits:readout", + "B0ECalHits", + "B0ECalHits", + "" + ], + [ + "B0ECAL:B0ECalRecHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "B0ECAL:B0ECalRecHits:samplingFraction", + "0.998", + "0.998", + "" + ], + [ + "B0ECAL:B0ECalRecHits:sectorField", + "sector", + "sector", + "" + ], + [ + "B0ECAL:B0ECalRecHits:thresholdFactor", + "4", + "4", + "" + ], + [ + "B0ECAL:B0ECalRecHits:thresholdValue", + "3", + "3", + "" + ], + [ + "B0ECalClusters:LogLevel", + "info", + "info", + "log_level for B0ECalClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "B0ECalIslandProtoClusters:LogLevel", + "info", + "info", + "log_level for B0ECalIslandProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "B0ECalMergedClusters:LogLevel", + "info", + "info", + "log_level for B0ECalMergedClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "B0ECalRawHits:LogLevel", + "info", + "info", + "log_level for B0ECalRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "B0ECalRecHits:LogLevel", + "info", + "info", + "log_level for B0ECalRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "B0ECalTruthProtoClusters:LogLevel", + "info", + "info", + "log_level for B0ECalTruthProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "BEMC:EcalBarrelImagingClusters:input_protoclust_tag", + "EcalBarrelImagingProtoClusters", + "EcalBarrelImagingProtoClusters", + "" + ], + [ + "BEMC:EcalBarrelImagingClusters:trackStopLayer", + "6", + "6", + "" + ], + [ + "BEMC:EcalBarrelImagingMergedClusters:energyAssociation_tag", + "EcalBarrelScFiClusterAssociations", + "EcalBarrelScFiClusterAssociations", + "" + ], + [ + "BEMC:EcalBarrelImagingMergedClusters:energyClusters_tag", + "EcalBarrelScFiClusters", + "EcalBarrelScFiClusters", + "" + ], + [ + "BEMC:EcalBarrelImagingMergedClusters:inputMCParticles_tag", + "MCParticles", + "MCParticles", + "" + ], + [ + "BEMC:EcalBarrelImagingMergedClusters:positionAssociations_tag", + "EcalBarrelImagingClusterAssociations", + "EcalBarrelImagingClusterAssociations", + "" + ], + [ + "BEMC:EcalBarrelImagingMergedClusters:positionClusters_tag", + "EcalBarrelImagingClusters", + "EcalBarrelImagingClusters", + "" + ], + [ + "BEMC:EcalBarrelImagingProtoClusters::layerDistEtaPhi", + "0.01,0.01", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingProtoClusters::localDistXY", + "2.0,2.0", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingProtoClusters::minClusterCenterEdep", + "0.", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingProtoClusters::minClusterEdep", + "0.5", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingProtoClusters::minClusterHitEdep", + "0.", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingProtoClusters::minClusterNhits", + "5", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingProtoClusters::neighbourLayersRange", + "2.0", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingProtoClusters::sectorDist", + "30.0", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingProtoClusters:input_tag", + "EcalBarrelImagingRecHits", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:capacityADC", + "8192", + "8192", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:dynamicRangeADC", + "3.0", + "0.1", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:energyResolutions", + "0.0,0.02,0.0", + "0,0.02,0", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:fieldRefNumbers", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:input_tag", + "EcalBarrelImagingHits", + "EcalBarrelImagingHits", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:pedestalMean", + "100", + "100", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:pedestalSigma", + "14", + "3.2", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:readoutClass", + "pixel", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:resolutionTDC", + "10*picosecond", + "1e-11", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:scaleResponse", + "1.0", + "1", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:signalSumFields", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelImagingRawHits:timeResolution", + "0.0*ns", + "0", + "" + ], + [ + "BEMC:EcalBarrelImagingRecHits:capacityADC", + "8192", + "8096", + "" + ], + [ + "BEMC:EcalBarrelImagingRecHits:dynamicRangeADC", + "3.0", + "0.1", + "" + ], + [ + "BEMC:EcalBarrelImagingRecHits:input_tag", + "EcalBarrelImagingRawHits", + "EcalBarrelImagingRawHits", + "" + ], + [ + "BEMC:EcalBarrelImagingRecHits:layerField", + "layer", + "layer", + "" + ], + [ + "BEMC:EcalBarrelImagingRecHits:pedestalMean", + "100", + "400", + "" + ], + [ + "BEMC:EcalBarrelImagingRecHits:pedSigmaADC", + "14", + "14", + "" + ], + [ + "BEMC:EcalBarrelImagingRecHits:samplingFraction", + "0.005", + "0.005", + "" + ], + [ + "BEMC:EcalBarrelImagingRecHits:sectorField", + "module", + "module", + "" + ], + [ + "BEMC:EcalBarrelImagingRecHits:thresholdFactor", + "3.0", + "3", + "" + ], + [ + "BEMC:EcalBarrelMergedSciGlassTruthClusters:input_tag", + "EcalBarrelSciGlassTruthClusters", + "EcalBarrelSciGlassTruthClusters", + "Name of input collection to use" + ], + [ + "BEMC:EcalBarrelMergedSciGlassTruthClusters:inputAssociations_tag", + "EcalBarrelSciGlassTruthClusterAssociations", + "EcalBarrelSciGlassTruthClusterAssociations", + "" + ], + [ + "BEMC:EcalBarrelScFiClusters:depthCorrection", + "0.0", + "0", + "" + ], + [ + "BEMC:EcalBarrelScFiClusters:enableEtaBounds", + "false", + "0", + "" + ], + [ + "BEMC:EcalBarrelScFiClusters:energyWeight", + "log", + "log", + "" + ], + [ + "BEMC:EcalBarrelScFiClusters:input_protoclust_tag", + "EcalBarrelScFiProtoClusters", + "EcalBarrelScFiProtoClusters", + "" + ], + [ + "BEMC:EcalBarrelScFiClusters:input_simhit_tag", + "EcalBarrelScFiHits", + "EcalBarrelScFiHits", + "" + ], + [ + "BEMC:EcalBarrelScFiClusters:logWeightBase", + "6.2", + "6.2", + "" + ], + [ + "BEMC:EcalBarrelScFiClusters:moduleDimZName", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiClusters:samplingFraction", + "1.0", + "1", + "" + ], + [ + "BEMC:EcalBarrelscFiMergedHits:fields", + "fiber,z", + "fiber,z", + "" + ], + [ + "BEMC:EcalBarrelscFiMergedHits:input_tag", + "EcalBarrelScFiRecHits", + "EcalBarrelScFiRecHits", + "" + ], + [ + "BEMC:EcalBarrelscFiMergedHits:refs", + "1,1", + "1,1", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:dimScaledLocalDistXY", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:input_tag", + "EcalBarrelScFiMergedHits", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:localDistXY", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:localDistXZ", + "30.0,30.0", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:minClusterCenterEdep", + "10.0", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:minClusterHitEdep", + "1.0", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:sectorDist", + "50.0", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiProtoClusters:splitCluster", + "false", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:capacityADC", + "16384", + "8096", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:dynamicRangeADC", + "750.0", + "0.1", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:energyResolutions", + "", + "0", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:fieldRefNumbers", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:input_tag", + "EcalBarrelScFiHits", + "EcalBarrelScFiHits", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:pedestalMean", + "20", + "400", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:pedestalSigma", + "0.3", + "3.2", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:readoutClass", + "light_guide", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:resolutionTDC", + "10*picosecond", + "1e-11", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:scaleResponse", + "1.0", + "1", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:signalSumFields", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelScFiRawHits:timeResolution", + "0*ns", + "0", + "" + ], + [ + "BEMC:EcalBarrelScFiRecHits:capacityADC", + "16384", + "16384", + "" + ], + [ + "BEMC:EcalBarrelScFiRecHits:dynamicRangeADC", + "750.0", + "0.75", + "" + ], + [ + "BEMC:EcalBarrelScFiRecHits:input_tag", + "EcalBarrelScFiRawHits", + "EcalBarrelScFiRawHits", + "" + ], + [ + "BEMC:EcalBarrelScFiRecHits:pedestalMean", + "20", + "20", + "" + ], + [ + "BEMC:EcalBarrelScFiRecHits:pedestalSigma", + "0.3", + "0.3", + "" + ], + [ + "BEMC:EcalBarrelScFiRecHits:resolutionTDC", + "10*picosecond", + "1e-11", + "" + ], + [ + "BEMC:EcalBarrelScFiRecHits:samplingFraction", + "0.125", + "0.125", + "" + ], + [ + "BEMC:EcalBarrelScFiRecHits:thresholdFactor", + "5.0", + "5", + "" + ], + [ + "BEMC:EcalBarrelScFiRecHits:thresholdValue", + "0.0", + "0", + "" + ], + [ + "BEMC:EcalBarrelSciGlassClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "BEMC:EcalBarrelSciGlassClusters:enableEtaBounds", + "1", + "0", + "" + ], + [ + "BEMC:EcalBarrelSciGlassClusters:energyWeight", + "log", + "log", + "" + ], + [ + "BEMC:EcalBarrelSciGlassClusters:input_protoclust_tag", + "EcalBarrelSciGlassProtoClusters", + "EcalBarrelSciGlassProtoClusters", + "" + ], + [ + "BEMC:EcalBarrelSciGlassClusters:input_simhit_tag", + "EcalBarrelSciGlassHits", + "EcalBarrelSciGlassHits", + "" + ], + [ + "BEMC:EcalBarrelSciGlassClusters:logWeightBase", + "6.2", + "3.6", + "" + ], + [ + "BEMC:EcalBarrelSciGlassClusters:moduleDimZName", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "BEMC:EcalBarrelSciGlassMergedClusters:input_tag", + "EcalBarrelSciGlassClusters", + "EcalBarrelSciGlassClusters", + "Name of input collection to use" + ], + [ + "BEMC:EcalBarrelSciGlassMergedClusters:inputAssociations_tag", + "EcalBarrelSciGlassClusterAssociations", + "EcalBarrelSciGlassClusterAssociations", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:dimScaledLocalDistXY", + "1.8,1.8", + "1.8,1.8", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:input_tag", + "EcalBarrelSciGlassRecHits", + "EcalBarrelSciGlassRecHits", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:localDistXY", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:minClusterCenterEdep", + "30.0", + "0.03", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:minClusterHitEdep", + "1.0", + "0.001", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:sectorDist", + "50.0", + "5", + "" + ], + [ + "BEMC:EcalBarrelSciGlassProtoClusters:splitCluster", + "0", + "0", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:capacityADC", + "16384", + "8096", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:dynamicRangeADC", + "20000.0", + "0.1", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:energyResolutions", + "0.0,0.02,0.0", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:fieldRefNumbers", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:input_tag", + "EcalBarrelSciGlassHits", + "EcalBarrelSciGlassHits", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:pedestalMean", + "100", + "400", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:pedestalSigma", + "1", + "3.2", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:readoutClass", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:scaleResponse", + "1", + "1", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:signalSumFields", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRecHits:capacityADC", + "16384", + "8096", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRecHits:dynamicRangeADC", + "20000.0", + "0.1", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRecHits:input_tag", + "EcalBarrelSciGlassRawHits", + "EcalBarrelSciGlassRawHits", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRecHits:pedestalMean", + "100", + "400", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRecHits:pedestalSigma", + "1", + "3.2", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRecHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRecHits:samplingFraction", + "0.98", + "0.998", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRecHits:thresholdFactor", + "3", + "4", + "" + ], + [ + "BEMC:EcalBarrelSciGlassRecHits:thresholdValue", + "3", + "0", + "" + ], + [ + "BEMC:EcalBarrelSciGlassTruthClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "BEMC:EcalBarrelSciGlassTruthClusters:enableEtaBounds", + "1", + "0", + "" + ], + [ + "BEMC:EcalBarrelSciGlassTruthClusters:energyWeight", + "log", + "log", + "" + ], + [ + "BEMC:EcalBarrelSciGlassTruthClusters:input_protoclust_tag", + "EcalBarrelSciGlassTruthProtoClusters", + "EcalBarrelSciGlassTruthProtoClusters", + "" + ], + [ + "BEMC:EcalBarrelSciGlassTruthClusters:input_simhit_tag", + "EcalBarrelSciGlassHits", + "EcalBarrelSciGlassHits", + "" + ], + [ + "BEMC:EcalBarrelSciGlassTruthClusters:logWeightBase", + "6.2", + "3.6", + "" + ], + [ + "BEMC:EcalBarrelSciGlassTruthClusters:moduleDimZName", + "", + "", + "" + ], + [ + "BEMC:EcalBarrelSciGlassTruthClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "BTOF:TOFBarrelRawHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "BTOF:TOFBarrelRawHit:LogLevel", + "info", + "info", + "log_level for BTOF:TOFBarrelRawHit: trace, debug, info, warn, error, critical, off" + ], + [ + "BTOF:TOFBarrelRawHit:Threshold", + "0", + "0", + "" + ], + [ + "BTOF:TOFBarrelRawHit:TimeResolution", + "0.025", + "0.025", + "" + ], + [ + "BTOF:TOFBarrelTrackerHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "BTOF:TOFBarrelTrackerHit:LogLevel", + "info", + "info", + "log_level for BTOF:TOFBarrelTrackerHit: trace, debug, info, warn, error, critical, off" + ], + [ + "BTOF:TOFBarrelTrackerHit:TimeResolution", + "0.025", + "10", + "" + ], + [ + "BTRK:BarrelTrackerHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "BTRK:BarrelTrackerHit:LogLevel", + "info", + "info", + "log_level for BTRK:BarrelTrackerHit: trace, debug, info, warn, error, critical, off" + ], + [ + "BTRK:BarrelTrackerHit:TimeResolution", + "8", + "10", + "" + ], + [ + "BTRK:BarrelTrackerRawHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "BTRK:BarrelTrackerRawHit:LogLevel", + "info", + "info", + "log_level for BTRK:BarrelTrackerRawHit: trace, debug, info, warn, error, critical, off" + ], + [ + "BTRK:BarrelTrackerRawHit:Threshold", + "0", + "0", + "" + ], + [ + "BTRK:BarrelTrackerRawHit:TimeResolution", + "8", + "8", + "" + ], + [ + "BVTX:BarrelVertexHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "BVTX:BarrelVertexHit:LogLevel", + "info", + "info", + "log_level for BVTX:BarrelVertexHit: trace, debug, info, warn, error, critical, off" + ], + [ + "BVTX:BarrelVertexHit:TimeResolution", + "8", + "10", + "" + ], + [ + "BVTX:BarrelVertexRawHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "BVTX:BarrelVertexRawHit:LogLevel", + "info", + "info", + "log_level for BVTX:BarrelVertexRawHit: trace, debug, info, warn, error, critical, off" + ], + [ + "BVTX:BarrelVertexRawHit:Threshold", + "0", + "0", + "" + ], + [ + "BVTX:BarrelVertexRawHit:TimeResolution", + "8", + "8", + "" + ], + [ + "dd4hep:print_level", + "4", + "4", + "Set DD4hep print level (see DD4hep/Printout.h)" + ], + [ + "dd4hep:xml_files", + "/opt/detector/epic-nightly/share/epic/epic_arches.xml", + "/opt/detector/epic-nightly/share/epic/epic_arches.xml", + "Comma separated list of XML files describing the DD4hep geometry. (Defaults to ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml using envars.)" + ], + [ + "Digi:SmearedFarForwardParticles:LogLevel", + "info", + "info", + "log_level for Digi:SmearedFarForwardParticles: trace, debug, info, warn, error, critical, off" + ], + [ + "dump_flags:json", + "arches_right_flags.json", + "", + "" + ], + [ + "dump_flags:LogLevel", + "info", + "info", + "log_level for dump_flags: trace, debug, info, warn, error, critical, off" + ], + [ + "dump_flags:markdown", + "", + "", + "If not empty, a markdown file to generate" + ], + [ + "dump_flags:python", + "all_flags_dump_from_run.py", + "", + "" + ], + [ + "dump_flags:screen", + "1", + "1", + "If not empty, print summary to screen at end of job" + ], + [ + "EcalBarrelImagingClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelImagingClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelImagingMergedClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelImagingMergedClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelImagingProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelImagingProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelImagingRawHits:LogLevel", + "info", + "info", + "log_level for EcalBarrelImagingRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelImagingRecHits:LogLevel", + "info", + "info", + "log_level for EcalBarrelImagingRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelScFiClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelScFiClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelScFiMergedHits:LogLevel", + "info", + "info", + "log_level for EcalBarrelScFiMergedHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelScFiProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelScFiProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelScFiRawHits:LogLevel", + "info", + "info", + "log_level for EcalBarrelScFiRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelScFiRecHits:LogLevel", + "info", + "info", + "log_level for EcalBarrelScFiRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelSciGlassClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelSciGlassClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelSciGlassMergedClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelSciGlassMergedClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelSciGlassMergedTruthClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelSciGlassMergedTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelSciGlassProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelSciGlassProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelSciGlassRawHits:LogLevel", + "info", + "info", + "log_level for EcalBarrelSciGlassRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelSciGlassRecHits:LogLevel", + "info", + "info", + "log_level for EcalBarrelSciGlassRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelSciGlassTruthClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelSciGlassTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalBarrelTruthSciGlassProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalBarrelTruthSciGlassProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapNClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapNClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapNIslandProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapNIslandProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapNMergedClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapNMergedClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapNRawHits:LogLevel", + "info", + "info", + "log_level for EcalEndcapNRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapNRecHits:LogLevel", + "info", + "info", + "log_level for EcalEndcapNRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapNTruthClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapNTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapNTruthProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapNTruthProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPInsertClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPInsertClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPInsertIslandProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPInsertIslandProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPInsertMergedClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPInsertMergedClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPInsertRawHits:LogLevel", + "info", + "info", + "log_level for EcalEndcapPInsertRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPInsertRecHits:LogLevel", + "info", + "info", + "log_level for EcalEndcapPInsertRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPInsertTruthClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPInsertTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPInsertTruthProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPInsertTruthProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPIslandProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPIslandProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPMergedClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPMergedClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPRawHits:LogLevel", + "info", + "info", + "log_level for EcalEndcapPRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPRecHits:LogLevel", + "info", + "info", + "log_level for EcalEndcapPRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPTruthClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "EcalEndcapPTruthProtoClusters:LogLevel", + "info", + "info", + "log_level for EcalEndcapPTruthProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "ECTOF:TOFEndcapRawHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "ECTOF:TOFEndcapRawHit:LogLevel", + "info", + "info", + "log_level for ECTOF:TOFEndcapRawHit: trace, debug, info, warn, error, critical, off" + ], + [ + "ECTOF:TOFEndcapRawHit:Threshold", + "0", + "0", + "" + ], + [ + "ECTOF:TOFEndcapRawHit:TimeResolution", + "0.025", + "0.025", + "" + ], + [ + "ECTOF:TOFEndcapTrackerHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "ECTOF:TOFEndcapTrackerHit:LogLevel", + "info", + "info", + "log_level for ECTOF:TOFEndcapTrackerHit: trace, debug, info, warn, error, critical, off" + ], + [ + "ECTOF:TOFEndcapTrackerHit:TimeResolution", + "0.025", + "10", + "" + ], + [ + "ECTRK:EndcapTrackerHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "ECTRK:EndcapTrackerHit:LogLevel", + "info", + "info", + "log_level for ECTRK:EndcapTrackerHit: trace, debug, info, warn, error, critical, off" + ], + [ + "ECTRK:EndcapTrackerHit:TimeResolution", + "8", + "10", + "" + ], + [ + "ECTRK:EndcapTrackerRawHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "ECTRK:EndcapTrackerRawHit:LogLevel", + "info", + "info", + "log_level for ECTRK:EndcapTrackerRawHit: trace, debug, info, warn, error, critical, off" + ], + [ + "ECTRK:EndcapTrackerRawHit:Threshold", + "0", + "0", + "" + ], + [ + "ECTRK:EndcapTrackerRawHit:TimeResolution", + "8", + "8", + "" + ], + [ + "EEMC:B0ECalClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "EEMC:B0ECalClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "EEMC:B0ECalClusters:energyWeight", + "log", + "log", + "" + ], + [ + "EEMC:B0ECalClusters:input_protoclust_tag", + "B0ECalIslandProtoClusters", + "B0ECalIslandProtoClusters", + "Name of input collection to use" + ], + [ + "EEMC:B0ECalClusters:logWeightBase", + "3.6", + "3.6", + "" + ], + [ + "EEMC:B0ECalClusters:moduleDimZName", + "", + "", + "" + ], + [ + "EEMC:B0ECalClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "EEMC:EcalEndcapNClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapNClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapNClusters:energyWeight", + "log", + "log", + "" + ], + [ + "EEMC:EcalEndcapNClusters:input_protoclust_tag", + "EcalEndcapNIslandProtoClusters", + "EcalEndcapNIslandProtoClusters", + "" + ], + [ + "EEMC:EcalEndcapNClusters:logWeightBase", + "3.6", + "3.6", + "" + ], + [ + "EEMC:EcalEndcapNClusters:moduleDimZName", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:dimScaledLocalDistXY", + "1.8,1.8", + "1.8,1.8", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:input_tag", + "EcalEndcapNRecHits", + "EcalEndcapNRecHits", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:localDistXY", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:minClusterCenterEdep", + "1.0", + "0.03", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:minClusterHitEdep", + "30.0", + "0.001", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:sectorDist", + "50.0", + "5", + "" + ], + [ + "EEMC:EcalEndcapNIslandProtoClusters:splitCluster", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapNMergedClusters:input_tag", + "EcalEndcapNClusters", + "EcalEndcapNClusters", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapNMergedClusters:inputAssociations_tag", + "EcalEndcapNClusterAssociations", + "EcalEndcapNClustersAssociations", + "Name of input associations collection to use" + ], + [ + "EEMC:EcalEndcapNRawHits:capacityADC", + "16384", + "8096", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:dynamicRangeADC", + "20000.0", + "0.1", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:energyResolutions", + "0.0,0.02,0.0", + "", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:fieldRefNumbers", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:input_tag", + "EcalEndcapNHits", + "EcalEndcapNHits", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapNRawHits:pedestalMean", + "100", + "400", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:pedestalSigma", + "1", + "3.2", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:readoutClass", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:scaleResponse", + "1", + "1", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:signalSumFields", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:capacityADC", + "16384", + "8096", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:dynamicRangeADC", + "20000.0", + "0.1", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:geoServiceName", + "geoServiceName", + "geoServiceName", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:input_tag", + "EcalEndcapNRawHits", + "EcalEndcapNRawHits", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapNRecHits:layerField", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:localDetElement", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:localDetFields", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:pedestalMean", + "100", + "400", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:pedestalSigma", + "1", + "3.2", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:readout", + "EcalEndcapNHits", + "EcalEndcapNHits", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:samplingFraction", + "0.998", + "0.998", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:sectorField", + "sector", + "sector", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:thresholdFactor", + "4", + "4", + "" + ], + [ + "EEMC:EcalEndcapNRecHits:thresholdValue", + "3", + "0", + "" + ], + [ + "EEMC:EcalEndcapNTruthClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapNTruthClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapNTruthClusters:energyWeight", + "log", + "log", + "" + ], + [ + "EEMC:EcalEndcapNTruthClusters:input_protoclust_tag", + "EcalEndcapNTruthProtoClusters", + "EcalEndcapNTruthProtoClusters", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapNTruthClusters:logWeightBase", + "4.6", + "3.6", + "" + ], + [ + "EEMC:EcalEndcapNTruthClusters:moduleDimZName", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapNTruthClusters:samplingFraction", + "0.03", + "1", + "" + ], + [ + "EEMC:EcalEndcapNTruthProtoClusters:inputHit_tag", + "EcalEndcapNRecHits", + "EcalEndcapNRecHits", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapPClusters:dimScaledLocalDistXY", + "1.8,1.8", + "1.8,1.8", + "" + ], + [ + "EEMC:EcalEndcapPClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapPClusters:energyWeight", + "log", + "log", + "" + ], + [ + "EEMC:EcalEndcapPClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPClusters:input_protoclust_tag", + "EcalEndcapPIslandProtoClusters", + "EcalEndcapPIslandProtoClusters", + "" + ], + [ + "EEMC:EcalEndcapPClusters:input_tag", + "EcalEndcapPRecHits", + "EcalEndcapPRecHits", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPClusters:localDistXY", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPClusters:localDistXZ", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPClusters:localDistYZ", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPClusters:logWeightBase", + "3.6", + "3.6", + "" + ], + [ + "EEMC:EcalEndcapPClusters:minClusterCenterEdep", + "0.03", + "0.03", + "" + ], + [ + "EEMC:EcalEndcapPClusters:minClusterHitEdep", + "0.001", + "0.001", + "" + ], + [ + "EEMC:EcalEndcapPClusters:moduleDimZName", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "EEMC:EcalEndcapPClusters:sectorDist", + "5", + "5", + "" + ], + [ + "EEMC:EcalEndcapPClusters:splitCluster", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapPInsertClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapPInsertClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapPInsertClusters:energyWeight", + "log", + "log", + "" + ], + [ + "EEMC:EcalEndcapPInsertClusters:input_protoclust_tag", + "EcalEndcapPInsertIslandProtoClusters", + "EcalEndcapPInsertIslandProtoClusters", + "" + ], + [ + "EEMC:EcalEndcapPInsertClusters:logWeightBase", + "3.6", + "3.6", + "" + ], + [ + "EEMC:EcalEndcapPInsertClusters:moduleDimZName", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:dimScaledLocalDistXY", + "1.5,1.5", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:localDistXY", + "10,10", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:minClusterCenterEdep", + "10.0", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:minClusterHitEdep", + "0", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:sectorDist", + "5", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertIslandProtoClusters:splitCluster", + "0", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertMergedClusters:input_tag", + "EcalEndcapPInsertClusters", + "EcalEndcapPInsertClusters", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPInsertMergedClusters:inputAssociations_tag", + "EcalEndcapPInsertClusterAssociations", + "EcalEndcapPInsertClustersAssociations", + "Name of input associations collection to use" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:capacityADC", + "16384", + "8096", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:dynamicRangeADC", + "3000.0", + "0.1", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:energyResolutions", + "0.00316,0.0015,0.0", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:fieldRefNumbers", + "1,1", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:input_tag", + "EcalEndcapPInsertHits", + "EcalEndcapPInsertHits", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:pedestalMean", + "100", + "400", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:pedestalSigma", + "0.7", + "3.2", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:readoutClass", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:scaleResponse", + "0.03", + "1", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:signalSumFields", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:capacityADC", + "16384", + "8096", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:dynamicRangeADC", + "3000.0", + "0.1", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:geoServiceName", + "geoServiceName", + "geoServiceName", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:input_tag", + "EcalEndcapPInsertRawHits", + "EcalEndcapPInsertRawHits", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:layerField", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:localDetElement", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:localDetFields", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:pedestalMean", + "100", + "400", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:pedestalSigma", + "0.7", + "3.2", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:readout", + "EcalEndcapPInsertHits", + "EcalEndcapPInsertHits", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:samplingFraction", + "0.03", + "0.998", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:sectorField", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:thresholdFactor", + "5.0", + "4", + "" + ], + [ + "EEMC:EcalEndcapPInsertRecHits:thresholdValue", + "2", + "0", + "" + ], + [ + "EEMC:EcalEndcapPInsertTruthClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapPInsertTruthClusters:enableEtaBounds", + "1", + "0", + "" + ], + [ + "EEMC:EcalEndcapPInsertTruthClusters:energyWeight", + "log", + "log", + "" + ], + [ + "EEMC:EcalEndcapPInsertTruthClusters:input_protoclust_tag", + "EcalEndcapPInsertTruthProtoClusters", + "EcalEndcapPInsertTruthProtoClusters", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPInsertTruthClusters:logWeightBase", + "6.2", + "3.6", + "" + ], + [ + "EEMC:EcalEndcapPInsertTruthClusters:moduleDimZName", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPInsertTruthClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:dimScaledLocalDistXY", + "1.5,1.5", + "", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:localDistXY", + "10,10", + "", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:minClusterCenterEdep", + "10.0", + "", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:minClusterHitEdep", + "0", + "", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:sectorDist", + "5", + "", + "" + ], + [ + "EEMC:EcalEndcapPIslandProtoClusters:splitCluster", + "0", + "", + "" + ], + [ + "EEMC:EcalEndcapPMergedClusters:input_tag", + "EcalEndcapPClusters", + "EcalEndcapPClusters", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPMergedClusters:inputAssociations_tag", + "EcalEndcapPClusterAssociations", + "EcalEndcapPClustersAssociations", + "Name of input associations collection to use" + ], + [ + "EEMC:EcalEndcapPRawHits:capacityADC", + "16384", + "8096", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:dynamicRangeADC", + "3000.0", + "0.1", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:energyResolutions", + "0.00316,0.0015,0.0", + "", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:fieldRefNumbers", + "1,1", + "", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:input_tag", + "EcalEndcapPHits", + "EcalEndcapPHits", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPRawHits:pedestalMean", + "100", + "400", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:pedestalSigma", + "0.7", + "3.2", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:readoutClass", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:scaleResponse", + "0.03", + "1", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:signalSumFields", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:capacityADC", + "16384", + "8096", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:dynamicRangeADC", + "3000.0", + "0.1", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:geoServiceName", + "geoServiceName", + "geoServiceName", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:input_tag", + "EcalEndcapPRawHits", + "EcalEndcapPRawHits", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPRecHits:layerField", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:localDetElement", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:localDetFields", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:pedestalMean", + "100", + "400", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:pedestalSigma", + "0.7", + "3.2", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:readout", + "EcalEndcapPHits", + "EcalEndcapPHits", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:samplingFraction", + "0.03", + "0.998", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:sectorField", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:thresholdFactor", + "5.0", + "4", + "" + ], + [ + "EEMC:EcalEndcapPRecHits:thresholdValue", + "2", + "0", + "" + ], + [ + "EEMC:EcalEndcapPTruthClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "EEMC:EcalEndcapPTruthClusters:enableEtaBounds", + "1", + "0", + "" + ], + [ + "EEMC:EcalEndcapPTruthClusters:energyWeight", + "log", + "log", + "" + ], + [ + "EEMC:EcalEndcapPTruthClusters:input_protoclust_tag", + "EcalEndcapPTruthProtoClusters", + "EcalEndcapPTruthProtoClusters", + "Name of input collection to use" + ], + [ + "EEMC:EcalEndcapPTruthClusters:logWeightBase", + "6.2", + "3.6", + "" + ], + [ + "EEMC:EcalEndcapPTruthClusters:moduleDimZName", + "", + "", + "" + ], + [ + "EEMC:EcalEndcapPTruthClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "EEMC:EcalEndcapPTruthProtoClusters:inputHit_tag", + "EcalEndcapPRecHits", + "EcalEndcapPRecHits", + "Name of input collection to use" + ], + [ + "eicrecon:LogLevel", + "info", + "info", + "log_level: trace, debug, info, warn, error, critical, off" + ], + [ + "event_source_type", + "", + "", + "" + ], + [ + "ForwardRomanPotParticles:LogLevel", + "info", + "info", + "log_level for ForwardRomanPotParticles: trace, debug, info, warn, error, critical, off" + ], + [ + "ForwardRomanPotRawHits:LogLevel", + "info", + "info", + "log_level for ForwardRomanPotRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "ForwardRomanPotRecHits:LogLevel", + "info", + "info", + "log_level for ForwardRomanPotRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HCAL:HcalBarrelClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "HCAL:HcalBarrelClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "HCAL:HcalBarrelClusters:energyWeight", + "log", + "log", + "" + ], + [ + "HCAL:HcalBarrelClusters:input_protoclust_tag", + "HcalBarrelIslandProtoClusters", + "HcalBarrelIslandProtoClusters", + "" + ], + [ + "HCAL:HcalBarrelClusters:input_simhit_tag", + "HcalBarrelHits", + "HcalBarrelHits", + "" + ], + [ + "HCAL:HcalBarrelClusters:logWeightBase", + "6.2", + "3.6", + "" + ], + [ + "HCAL:HcalBarrelClusters:moduleDimZName", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:dimScaledLocalDistXY", + "5,5", + "5,5", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:localDistXY", + "150,150", + "", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:minClusterCenterEdep", + "0.003", + "0.003", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:minClusterHitEdep", + "30.0", + "0.0001", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:sectorDist", + "5", + "5", + "" + ], + [ + "HCAL:HcalBarrelIslandProtoClusters:splitCluster", + "0", + "1", + "" + ], + [ + "HCAL:HcalBarrelMergedHits:fields", + "tower,tile", + "layer,slice", + "" + ], + [ + "HCAL:HcalBarrelMergedHits:input_tag", + "HcalBarrelRecHits", + "HcalBarrelRecHits", + "" + ], + [ + "HCAL:HcalBarrelMergedHits:refs", + "1,0", + "1,0", + "" + ], + [ + "HCAL:HcalBarrelRawHits:capacityADC", + "256", + "8096", + "" + ], + [ + "HCAL:HcalBarrelRawHits:dynamicRangeADC", + "50.0", + "50", + "" + ], + [ + "HCAL:HcalBarrelRawHits:energyResolutions", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelRawHits:fieldRefNumbers", + "1,0", + "", + "" + ], + [ + "HCAL:HcalBarrelRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "HCAL:HcalBarrelRawHits:pedestalMean", + "10", + "10", + "" + ], + [ + "HCAL:HcalBarrelRawHits:pedestalSigma", + "2", + "2", + "" + ], + [ + "HCAL:HcalBarrelRawHits:readoutClass", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelRawHits:resolutionTDC", + "1e-9", + "1e-09", + "" + ], + [ + "HCAL:HcalBarrelRawHits:scaleResponse", + "1", + "1", + "" + ], + [ + "HCAL:HcalBarrelRawHits:signalSumFields", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "HCAL:HcalBarrelRecHits:capacityADC", + "256", + "8096", + "" + ], + [ + "HCAL:HcalBarrelRecHits:dynamicRangeADC", + "20.0", + "50", + "" + ], + [ + "HCAL:HcalBarrelRecHits:geoServiceName", + "geoServiceName", + "geoServiceName", + "" + ], + [ + "HCAL:HcalBarrelRecHits:layerField", + "tower", + "tower", + "" + ], + [ + "HCAL:HcalBarrelRecHits:localDetElement", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelRecHits:localDetFields", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelRecHits:pedestalMean", + "20", + "10", + "" + ], + [ + "HCAL:HcalBarrelRecHits:pedestalSigma", + "0.3", + "2", + "" + ], + [ + "HCAL:HcalBarrelRecHits:readout", + "HcalBarrelHits", + "HcalBarrelHits", + "" + ], + [ + "HCAL:HcalBarrelRecHits:resolutionTDC", + "1e-11", + "1e-09", + "" + ], + [ + "HCAL:HcalBarrelRecHits:samplingFraction", + "0.033", + "0.033", + "" + ], + [ + "HCAL:HcalBarrelRecHits:sectorField", + "sector", + "sector", + "" + ], + [ + "HCAL:HcalBarrelRecHits:thresholdFactor", + "5", + "5", + "" + ], + [ + "HCAL:HcalBarrelRecHits:thresholdValue", + "1", + "0", + "" + ], + [ + "HCAL:HcalBarrelTruthClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "HCAL:HcalBarrelTruthClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "HCAL:HcalBarrelTruthClusters:energyWeight", + "log", + "log", + "" + ], + [ + "HCAL:HcalBarrelTruthClusters:input_protoclust_tag", + "HcalBarrelTruthProtoClusters", + "HcalBarrelTruthProtoClusters", + "" + ], + [ + "HCAL:HcalBarrelTruthClusters:input_simhit_tag", + "HcalBarrelHits", + "HcalBarrelHits", + "" + ], + [ + "HCAL:HcalBarrelTruthClusters:logWeightBase", + "6.2", + "3.6", + "" + ], + [ + "HCAL:HcalBarrelTruthClusters:moduleDimZName", + "", + "", + "" + ], + [ + "HCAL:HcalBarrelTruthClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "HCAL:HcalEndcapNClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapNClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapNClusters:energyWeight", + "log", + "log", + "" + ], + [ + "HCAL:HcalEndcapNClusters:input_protoclust_tag", + "HcalEndcapNIslandProtoClusters", + "HcalEndcapNIslandProtoClusters", + "" + ], + [ + "HCAL:HcalEndcapNClusters:input_simhit_tag", + "HcalEndcapNHits", + "HcalEndcapNHits", + "" + ], + [ + "HCAL:HcalEndcapNClusters:logWeightBase", + "6.2", + "6.2", + "" + ], + [ + "HCAL:HcalEndcapNClusters:moduleDimZName", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:dimScaledLocalDistXY", + "1.5,1.5", + "1.5,1.5", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:localDistXY", + "150,150", + "", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:minClusterCenterEdep", + "30.0", + "0.03", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:minClusterHitEdep", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:sectorDist", + "5", + "5", + "" + ], + [ + "HCAL:HcalEndcapNIslandProtoClusters:splitCluster", + "1", + "1", + "" + ], + [ + "HCAL:HcalEndcapNMergedHits:fields", + "layer,slice", + "layer,slice", + "" + ], + [ + "HCAL:HcalEndcapNMergedHits:input_tag", + "HcalEndcapNRecHits", + "HcalEndcapNRecHits", + "" + ], + [ + "HCAL:HcalEndcapNMergedHits:readout", + "HcalEndcapNHits", + "HcalEndcapNHits", + "" + ], + [ + "HCAL:HcalEndcapNMergedHits:refs", + "1,0", + "1,0", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:capacityADC", + "1024", + "1024", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:dynamicRangeADC", + "3.6", + "0.0036", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:energyResolutions", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:fieldRefNumbers", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:pedestalMean", + "20", + "400", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:pedestalSigma", + "0.3", + "3.2", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:readoutClass", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:scaleResponse", + "1", + "1", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:signalSumFields", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:capacityADC", + "1024", + "1024", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:dynamicRangeADC", + "3.6", + "0.0036", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:geoServiceName", + "geoServiceName", + "geoServiceName", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:layerField", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:localDetElement", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:localDetFields", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:pedestalMean", + "20", + "400", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:pedestalSigma", + "0.3", + "3.2", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:readout", + "HcalEndcapNHits", + "HcalEndcapNHits", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:samplingFraction", + "0.998", + "0.998", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:sectorField", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:thresholdFactor", + "4", + "4", + "" + ], + [ + "HCAL:HcalEndcapNRecHits:thresholdValue", + "1", + "0", + "" + ], + [ + "HCAL:HcalEndcapNTruthClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapNTruthClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapNTruthClusters:energyWeight", + "log", + "log", + "" + ], + [ + "HCAL:HcalEndcapNTruthClusters:input_protoclust_tag", + "HcalEndcapNTruthProtoClusters", + "HcalEndcapNTruthProtoClusters", + "" + ], + [ + "HCAL:HcalEndcapNTruthClusters:input_simhit_tag", + "HcalEndcapNHits", + "HcalEndcapNHits", + "" + ], + [ + "HCAL:HcalEndcapNTruthClusters:logWeightBase", + "6.2", + "3.6", + "" + ], + [ + "HCAL:HcalEndcapNTruthClusters:moduleDimZName", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapNTruthClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "HCAL:HcalEndcapPClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapPClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapPClusters:energyWeight", + "log", + "log", + "" + ], + [ + "HCAL:HcalEndcapPClusters:input_protoclust_tag", + "HcalEndcapPIslandProtoClusters", + "HcalEndcapPIslandProtoClusters", + "" + ], + [ + "HCAL:HcalEndcapPClusters:input_simhit_tag", + "HcalEndcapPHits", + "HcalEndcapPHits", + "" + ], + [ + "HCAL:HcalEndcapPClusters:logWeightBase", + "6.2", + "6.2", + "" + ], + [ + "HCAL:HcalEndcapPClusters:moduleDimZName", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPClusters:samplingFraction", + "0.025", + "1", + "" + ], + [ + "HCAL:HcalEndcapPInsertClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapPInsertClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapPInsertClusters:energyWeight", + "log", + "log", + "" + ], + [ + "HCAL:HcalEndcapPInsertClusters:input_protoclust_tag", + "HcalEndcapPInsertIslandProtoClusters", + "HcalEndcapPInsertIslandProtoClusters", + "" + ], + [ + "HCAL:HcalEndcapPInsertClusters:input_simhit_tag", + "HcalEndcapPInsertHits", + "HcalEndcapPInsertHits", + "" + ], + [ + "HCAL:HcalEndcapPInsertClusters:logWeightBase", + "6.2", + "6.2", + "" + ], + [ + "HCAL:HcalEndcapPInsertClusters:moduleDimZName", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:dimScaledLocalDistXY", + "1.5,1.5", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:localDistXY", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:minClusterCenterEdep", + "0.03", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:minClusterHitEdep", + "0", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:sectorDist", + "5", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertIslandProtoClusters:splitCluster", + "1", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:capacityADC", + "32768", + "32768", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:dynamicRangeADC", + "200.0", + "0.2", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:energyResolutions", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:fieldRefNumbers", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:pedestalMean", + "400", + "400", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:pedestalSigma", + "10", + "10", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:readoutClass", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:scaleResponse", + "1", + "1", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:signalSumFields", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:capacityADC", + "32768", + "32768", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:dynamicRangeADC", + "200.0", + "0.2", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:geoServiceName", + "geoServiceName", + "geoServiceName", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:layerField", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:localDetElement", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:localDetFields", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:pedestalMean", + "400", + "400", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:pedestalSigma", + "10", + "10", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:readout", + "HcalEndcapPInsertHits", + "HcalEndcapPInsertHits", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:samplingFraction", + "0.998", + "1", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:sectorField", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:thresholdFactor", + "4", + "4", + "" + ], + [ + "HCAL:HcalEndcapPInsertRecHits:thresholdValue", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapPInsertTruthClusters:depthCorrection", + "0", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertTruthClusters:enableEtaBounds", + "0", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertTruthClusters:energyWeight", + "log", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertTruthClusters:input_protoclust_tag", + "HcalEndcapPInsertTruthProtoClusters", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertTruthClusters:input_simhit_tag", + "HcalEndcapPInsertHits", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertTruthClusters:logWeightBase", + "6.2", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertTruthClusters:moduleDimZName", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPInsertTruthClusters:samplingFraction", + "1", + "", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:dimScaledLocalDistXY", + "1.5,1.5", + "1.5,1.5", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:localDistXY", + "150,150", + "", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:minClusterCenterEdep", + "30.0", + "0.03", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:minClusterHitEdep", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:sectorDist", + "5", + "5", + "" + ], + [ + "HCAL:HcalEndcapPIslandProtoClusters:splitCluster", + "1", + "1", + "" + ], + [ + "HCAL:HcalEndcapPMergedHits:fields", + "layer,slice", + "layer,slice", + "" + ], + [ + "HCAL:HcalEndcapPMergedHits:input_tag", + "HcalEndcapPRecHits", + "HcalEndcapPRecHits", + "" + ], + [ + "HCAL:HcalEndcapPMergedHits:readout", + "HcalEndcapPHits", + "HcalEndcapPHits", + "" + ], + [ + "HCAL:HcalEndcapPMergedHits:refs", + "1,0", + "1,0", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:capacityADC", + "1024", + "1024", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:dynamicRangeADC", + "3600.0", + "3.6", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:energyResolutions", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:fieldRefNumbers", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:pedestalMean", + "20", + "20", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:pedestalSigma", + "0.8", + "0.8", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:readoutClass", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:scaleResponse", + "1", + "1", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:signalSumFields", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:capacityADC", + "1024", + "8096", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:dynamicRangeADC", + "3600.0", + "0.1", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:geoServiceName", + "geoServiceName", + "geoServiceName", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:layerField", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:localDetElement", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:localDetFields", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:pedestalMean", + "20", + "400", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:pedestalSigma", + "0.8", + "3.2", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:readout", + "HcalEndcapPHits", + "HcalEndcapPHits", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:samplingFraction", + "0.025", + "0.998", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:sectorField", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:thresholdFactor", + "5", + "4", + "" + ], + [ + "HCAL:HcalEndcapPRecHits:thresholdValue", + "3", + "0", + "" + ], + [ + "HCAL:HcalEndcapPTruthClusters:depthCorrection", + "0", + "", + "" + ], + [ + "HCAL:HcalEndcapPTruthClusters:enableEtaBounds", + "0", + "", + "" + ], + [ + "HCAL:HcalEndcapPTruthClusters:energyWeight", + "log", + "", + "" + ], + [ + "HCAL:HcalEndcapPTruthClusters:input_protoclust_tag", + "HcalEndcapPTruthProtoClusters", + "", + "" + ], + [ + "HCAL:HcalEndcapPTruthClusters:input_simhit_tag", + "HcalEndcapPHits", + "", + "" + ], + [ + "HCAL:HcalEndcapPTruthClusters:logWeightBase", + "6.2", + "", + "" + ], + [ + "HCAL:HcalEndcapPTruthClusters:moduleDimZName", + "", + "", + "" + ], + [ + "HCAL:HcalEndcapPTruthClusters:samplingFraction", + "0.025", + "", + "" + ], + [ + "HcalBarrelClusters:LogLevel", + "info", + "info", + "log_level for HcalBarrelClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalBarrelIslandProtoClusters:LogLevel", + "info", + "info", + "log_level for HcalBarrelIslandProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalBarrelMergedHits:LogLevel", + "info", + "info", + "log_level for HcalBarrelMergedHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalBarrelRawHits:LogLevel", + "info", + "info", + "log_level for HcalBarrelRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalBarrelRecHits:LogLevel", + "info", + "info", + "log_level for HcalBarrelRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalBarrelTruthClusters:LogLevel", + "info", + "info", + "log_level for HcalBarrelTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalBarrelTruthProtoClusters:LogLevel", + "info", + "info", + "log_level for HcalBarrelTruthProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapNClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapNClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapNIslandProtoClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapNIslandProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapNMergedHits:LogLevel", + "info", + "info", + "log_level for HcalEndcapNMergedHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapNRawHits:LogLevel", + "info", + "info", + "log_level for HcalEndcapNRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapNRecHits:LogLevel", + "info", + "info", + "log_level for HcalEndcapNRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapNTruthClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapNTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapNTruthProtoClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapNTruthProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapPClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPInsertClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapPInsertClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPInsertIslandProtoClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapPInsertIslandProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPInsertMergedHits:LogLevel", + "info", + "info", + "log_level for HcalEndcapPInsertMergedHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPInsertRawHits:LogLevel", + "info", + "info", + "log_level for HcalEndcapPInsertRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPInsertRecHits:LogLevel", + "info", + "info", + "log_level for HcalEndcapPInsertRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPInsertTruthClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapPInsertTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPInsertTruthProtoClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapPInsertTruthProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPIslandProtoClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapPIslandProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPMergedHits:LogLevel", + "info", + "info", + "log_level for HcalEndcapPMergedHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPRawHits:LogLevel", + "info", + "info", + "log_level for HcalEndcapPRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPRecHits:LogLevel", + "info", + "info", + "log_level for HcalEndcapPRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPTruthClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapPTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "HcalEndcapPTruthProtoClusters:LogLevel", + "info", + "info", + "log_level for HcalEndcapPTruthProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "histsfile", + "rec_pi_1GeV_20GeV_arches.ana.root", + "", + "" + ], + [ + "jana:affinity", + "2", + "2", + "" + ], + [ + "jana:debug_plugin_loading", + "1", + "0", + "" + ], + [ + "jana:enable_stealing", + "0", + "0", + "" + ], + [ + "jana:engine", + "0", + "0", + "0: Arrow engine, 1: Debug engine" + ], + [ + "jana:event_pool_size", + "1", + "1", + "" + ], + [ + "jana:event_processor_chunksize", + "1", + "1", + "" + ], + [ + "jana:event_queue_threshold", + "80", + "80", + "" + ], + [ + "jana:event_source_chunksize", + "40", + "40", + "" + ], + [ + "jana:extended_report", + "0", + "0", + "" + ], + [ + "jana:limit_total_events_in_flight", + "1", + "1", + "" + ], + [ + "jana:locality", + "0", + "0", + "" + ], + [ + "jana:nevents", + "0", + "0", + "" + ], + [ + "jana:nskip", + "0", + "0", + "Number of events that sources should skip before starting emitting" + ], + [ + "jana:plugin_path", + "", + "", + "Colon-separated paths to search for plugins" + ], + [ + "JANA:STATUS_FNAME", + "/tmp/jana_status", + "/tmp/jana_status", + "Filename of named pipe for retrieving instantaneous status info" + ], + [ + "jana:timeout", + "180", + "8", + "" + ], + [ + "jana:warmup_timeout", + "180", + "30", + "" + ], + [ + "JEventProcessorPODIO:LogLevel", + "info", + "info", + "log_level for JEventProcessorPODIO: trace, debug, info, warn, error, critical, off" + ], + [ + "log:debug", + "", + "", + "" + ], + [ + "log:error", + "", + "", + "" + ], + [ + "log:fatal", + "", + "", + "" + ], + [ + "log:info", + "", + "", + "" + ], + [ + "log:off", + "", + "", + "" + ], + [ + "log:trace", + "", + "", + "" + ], + [ + "log:warn", + "", + "", + "" + ], + [ + "MPGD:MPGDTrackerHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "MPGD:MPGDTrackerHit:LogLevel", + "info", + "info", + "log_level for MPGD:MPGDTrackerHit: trace, debug, info, warn, error, critical, off" + ], + [ + "MPGD:MPGDTrackerHit:TimeResolution", + "8", + "10", + "" + ], + [ + "MPGD:MPGDTrackerRawHit:InputTags", + "", + "", + "Input data tag name" + ], + [ + "MPGD:MPGDTrackerRawHit:LogLevel", + "info", + "info", + "log_level for MPGD:MPGDTrackerRawHit: trace, debug, info, warn, error, critical, off" + ], + [ + "MPGD:MPGDTrackerRawHit:Threshold", + "0", + "0", + "" + ], + [ + "MPGD:MPGDTrackerRawHit:TimeResolution", + "8", + "8", + "" + ], + [ + "nthreads", + "1", + "1", + "The total number of worker threads" + ], + [ + "plugins", + "log,dd4hep,acts,rootfile,algorithms_calorimetry,algorithms_tracking,algorithms_digi,digi,reco,tracking,BEMC,HCAL,B0ECAL,ZDC,BTRK,BVTX,ECTRK,EEMC,MPGD,RPOTS,BTOF,ECTOF,podio,dump_flags", + "", + "" + ], + [ + "plugins_to_ignore", + "", + "", + "" + ], + [ + "podio:background_filename", + "", + "", + "Name of file containing background events to merge in (default is not to merge any background)" + ], + [ + "podio:num_background_events", + "1", + "1", + "Number of background events to add to every primary event." + ], + [ + "podio:output_exclude_collections", + "", + "", + "Comma separated list of collection names to not write out." + ], + [ + "podio:output_file", + "rec_pi_1GeV_20GeV_arches.tree.edm4eic.root", + "podio_output.root", + "" + ], + [ + "podio:output_file_copy_dir", + "", + "", + "Directory name to make an additional copy of the output file to. Copy will be done at end of processing. Default is empty string which means do not make a copy. No check is made on path existing." + ], + [ + "podio:output_include_collections", + "MCParticles,GeneratedParticles,ReconstructedParticles,ReconstructedChargedParticles,ReconstructedChargedParticlesAssociations,trackerHits,BarrelTrackerHit,EndcapTrackerHit,TOFBarrelTrackerHit,BarrelVertexHit,TOFEndcapTrackerHit,ForwardOffMTrackerRecHits,MPGDTrackerHit,ForwardRomanPotRecHits,CentralTrackSegments,EcalEndcapNRawHits,EcalEndcapNRecHits,EcalEndcapNTruthClusters,EcalEndcapNClusters,EcalEndcapNMergedClusters,EcalEndcapNTruthClusterAssociations,EcalEndcapNClustersAssociations,EcalEndcapNMergedClustersAssociations,EcalEndcapPRawHits,EcalEndcapPRecHits,EcalEndcapPTruthClusters,EcalEndcapPClusters,EcalEndcapPMergedClusters,EcalEndcapPTruthClustersAssociations,EcalEndcapPClustersAssociations,EcalEndcapPMergedClustersAssociations,EcalEndcapPInsertRawHits,EcalEndcapPInsertRecHits,EcalEndcapPInsertTruthClusters,EcalEndcapPInsertClusters,EcalEndcapPInsertMergedClusters,EcalEndcapPInsertTruthClustersAssociations,EcalEndcapPInsertClustersAssociations,EcalEndcapPInsertMergedClustersAssociations,EcalBarrelSciGlassRawHits,EcalBarrelSciGlassRecHits,EcalBarrelSciGlassClusters,EcalBarrelSciGlassMergedClusters,EcalBarrelSciGlassTruthClusters,EcalBarrelSciGlassMergedTruthClusters,EcalBarrelImagingRawHits,EcalBarrelImagingRecHits,EcalBarrelImagingClusters,EcalBarrelImagingMergedClusters,EcalBarrelScFiRawHits,EcalBarrelScFiRecHits,EcalBarrelScFiMergedHits,EcalBarrelScFiClusters,HcalEndcapNRawHits,HcalEndcapNRecHits,HcalEndcapNMergedHits,HcalEndcapNClusters,HcalEndcapPRawHits,HcalEndcapPRecHits,HcalEndcapPMergedHits,HcalEndcapPClusters,HcalEndcapPInsertRawHits,HcalEndcapPInsertRecHits,HcalEndcapPInsertMergedHits,HcalEndcapPInsertClusters,HcalBarrelRawHits,HcalBarrelRecHits,HcalBarrelClusters,B0ECalRawHits,B0ECalRecHits,B0ECalClusters,ZDCEcalRawHits,ZDCEcalRecHits,ZDCEcalClusters,ZDCEcalMergedClusters,HcalEndcapNTruthClusters,HcalBarrelTruthClusters,B0ECalRecHits,B0ECalClusters,ZDCEcalTruthClusters,ForwardRomanPotRawHits,ForwardRomanPotRecHits,ForwardRomanPotParticles,SmearedFarForwardParticles", + "MCParticles,GeneratedParticles,ReconstructedParticles,ReconstructedChargedParticles,ReconstructedChargedParticlesAssociations,trackerHits,BarrelTrackerHit,EndcapTrackerHit,TOFBarrelTrackerHit,BarrelVertexHit,TOFEndcapTrackerHit,ForwardOffMTrackerRecHits,MPGDTrackerHit,ForwardRomanPotRecHits,CentralTrackSegments,EcalEndcapNRawHits,EcalEndcapNRecHits,EcalEndcapNTruthClusters,EcalEndcapNClusters,EcalEndcapNMergedClusters,EcalEndcapNTruthClustersAssociations,EcalEndcapNClustersAssociations,EcalEndcapNMergedClustersAssociations,EcalEndcapPRawHits,EcalEndcapPRecHits,EcalEndcapPTruthClusters,EcalEndcapPClusters,EcalEndcapPMergedClusters,EcalEndcapPTruthClustersAssociations,EcalEndcapPClustersAssociations,EcalEndcapPMergedClustersAssociations,EcalEndcapPInsertRawHits,EcalEndcapPInsertRecHits,EcalEndcapPInsertTruthClusters,EcalEndcapPInsertClusters,EcalEndcapPInsertMergedClusters,EcalEndcapPInsertTruthClustersAssociations,EcalEndcapPInsertClustersAssociations,EcalEndcapPInsertMergedClustersAssociations,EcalBarrelSciGlassRawHits,EcalBarrelSciGlassRecHits,EcalBarrelSciGlassClusters,EcalBarrelSciGlassMergedClusters,EcalBarrelSciGlassTruthClusters,EcalBarrelSciGlassMergedTruthClusters,EcalBarrelImagingRawHits,EcalBarrelImagingRecHits,EcalBarrelImagingClusters,EcalBarrelImagingMergedClusters,EcalBarrelScFiRawHits,EcalBarrelScFiRecHits,EcalBarrelScFiMergedHits,EcalBarrelScFiClusters,HcalEndcapNRawHits,HcalEndcapNRecHits,HcalEndcapNMergedHits,HcalEndcapNClusters,HcalEndcapPRawHits,HcalEndcapPRecHits,HcalEndcapPMergedHits,HcalEndcapPClusters,HcalEndcapPInsertRawHits,HcalEndcapPInsertRecHits,HcalEndcapPInsertMergedHits,HcalEndcapPInsertClusters,HcalBarrelRawHits,HcalBarrelRecHits,HcalBarrelClusters,B0ECalRawHits,B0ECalRecHits,B0ECalClusters,ZDCEcalRawHits,ZDCEcalRecHits,ZDCEcalClusters,ZDCEcalMergedClusters,HcalEndcapNTruthClusters,HcalBarrelTruthClusters,B0ECalRecHits,B0ECalClusters,ZDCEcalTruthClusters,ForwardRomanPotRawHits,ForwardRomanPotRecHits,ForwardRomanPotParticles,SmearedFarForwardParticles", + "Comma separated list of collection names to write out. If not set, all collections will be written (including ones from input file). Don't set this and use PODIO:OUTPUT_EXCLUDE_COLLECTIONS to write everything except a selection." + ], + [ + "podio:print_type_table", + "0", + "0", + "Print list of collection names and their types" + ], + [ + "podio:run_forever", + "0", + "0", + "set to true to recycle through events continuously" + ], + [ + "Reco:GeneratedParticles:InputTags", + "", + "", + "Input data tag name" + ], + [ + "Reco:GeneratedParticles:LogLevel", + "info", + "info", + "log_level for Reco:GeneratedParticles: trace, debug, info, warn, error, critical, off" + ], + [ + "Reco:GeneratedParticles:MomentumSmearing", + "0", + "0", + "" + ], + [ + "reco:ReconstructedParticlesWithAssoc:InputTags", + "", + "", + "Input data tag name" + ], + [ + "reco:ReconstructedParticlesWithAssoc:LogLevel", + "info", + "info", + "log_level for reco:ReconstructedParticlesWithAssoc: trace, debug, info, warn, error, critical, off" + ], + [ + "RECORD_CALL_STACK", + "0", + "0", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:crossingAngle", + "-0.025", + "-0.025", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:local_x_offset_station_1", + "-833.3878326", + "-833.388", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:local_x_offset_station_2", + "-924.342804", + "-924.343", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:local_x_slope_offset", + "-0.00622147", + "-0.00622147", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:local_y_slope_offset", + "-0.0451035", + "-0.0451035", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:m_layerField", + "", + "", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:m_localDetElement", + "", + "", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:m_readout", + "", + "", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:m_sectorField", + "", + "", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:nomMomentum", + "275.0", + "275", + "" + ], + [ + "RPOTS:ForwardRomanPotParticles:u_localDetFields", + "", + "", + "" + ], + [ + "RPOTS:ForwardRomanPotRawHits:threshold", + "0.0", + "0", + "" + ], + [ + "RPOTS:ForwardRomanPotRawHits:timeResolution", + "8.0", + "8", + "" + ], + [ + "RPOTS:ForwardRomanPotRecHits:time_resolution", + "0.0", + "0", + "" + ], + [ + "tracking:CentralCKFTrajectories:Chi2CutOff", + "15", + "50", + "" + ], + [ + "tracking:CentralCKFTrajectories:EtaBins", + "", + "", + "" + ], + [ + "tracking:CentralCKFTrajectories:InputTags", + "", + "", + "Input data tag name" + ], + [ + "tracking:CentralCKFTrajectories:LogLevel", + "info", + "info", + "log_level for tracking:CentralCKFTrajectories: trace, debug, info, warn, error, critical, off" + ], + [ + "tracking:CentralCKFTrajectories:NumMeasurementsCutOff", + "10", + "10", + "" + ], + [ + "tracking:CentralTrackerSourceLinker:InputTags", + "", + "", + "Input data tag name" + ], + [ + "tracking:CentralTrackerSourceLinker:LogLevel", + "info", + "info", + "log_level for tracking:CentralTrackerSourceLinker: trace, debug, info, warn, error, critical, off" + ], + [ + "tracking:CentralTrackingParticles:InputTags", + "", + "", + "Input data tag name" + ], + [ + "tracking:CentralTrackingParticles:LogLevel", + "info", + "info", + "log_level for tracking:CentralTrackingParticles: trace, debug, info, warn, error, critical, off" + ], + [ + "tracking:CentralTrackSegments:InputTags", + "", + "", + "Input data tag name" + ], + [ + "tracking:CentralTrackSegments:LogLevel", + "info", + "info", + "log_level for tracking:CentralTrackSegments: trace, debug, info, warn, error, critical, off" + ], + [ + "tracking:ChargedParticlesWithAssociations:InputTags", + "", + "", + "Input data tag name" + ], + [ + "tracking:ChargedParticlesWithAssociations:LogLevel", + "info", + "info", + "log_level for tracking:ChargedParticlesWithAssociations: trace, debug, info, warn, error, critical, off" + ], + [ + "tracking:InitTrackParams:InputTags", + "", + "", + "Input data tag name" + ], + [ + "tracking:InitTrackParams:LogLevel", + "info", + "info", + "log_level for tracking:InitTrackParams: trace, debug, info, warn, error, critical, off" + ], + [ + "tracking:outputTrackParameters:InputTags", + "", + "", + "Input data tag name" + ], + [ + "tracking:outputTrackParameters:LogLevel", + "info", + "info", + "log_level for tracking:outputTrackParameters: trace, debug, info, warn, error, critical, off" + ], + [ + "Tracking:ReconstructedChargedParticles:InputTags", + "", + "", + "Input data tag name" + ], + [ + "Tracking:ReconstructedChargedParticles:LogLevel", + "info", + "info", + "log_level for Tracking:ReconstructedChargedParticles: trace, debug, info, warn, error, critical, off" + ], + [ + "Tracking:ReconstructedChargedParticlesAssociations:InputTags", + "", + "", + "Input data tag name" + ], + [ + "Tracking:ReconstructedChargedParticlesAssociations:LogLevel", + "info", + "info", + "log_level for Tracking:ReconstructedChargedParticlesAssociations: trace, debug, info, warn, error, critical, off" + ], + [ + "Tracking:ReconstructedParticles:InputTags", + "", + "", + "Input data tag name" + ], + [ + "Tracking:ReconstructedParticles:LogLevel", + "info", + "info", + "log_level for Tracking:ReconstructedParticles: trace, debug, info, warn, error, critical, off" + ], + [ + "tracking:trackerHits:InputTags", + "", + "", + "Input data tag name" + ], + [ + "tracking:trackerHits:LogLevel", + "info", + "info", + "log_level for tracking:trackerHits: trace, debug, info, warn, error, critical, off" + ], + [ + "ZDC:ZDCEcalClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "ZDC:ZDCEcalClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "ZDC:ZDCEcalClusters:energyWeight", + "log", + "log", + "" + ], + [ + "ZDC:ZDCEcalClusters:input_protoclust_tag", + "ZDCEcalIslandProtoClusters", + "ZDCEcalIslandProtoClusters", + "" + ], + [ + "ZDC:ZDCEcalClusters:input_simhit_tag", + "ZDCEcalHits", + "ZDCEcalHits", + "" + ], + [ + "ZDC:ZDCEcalClusters:logWeightBase", + "6.2", + "3.6", + "" + ], + [ + "ZDC:ZDCEcalClusters:moduleDimZName", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:dimScaledLocalDistXY", + "5,5", + "5,5", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:globalDistEtaPhi", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:globalDistRPhi", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:localDistXY", + "50,50", + "", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:localDistXZ", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:localDistYZ", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:minClusterCenterEdep", + "3.0", + "0.003", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:minClusterHitEdep", + "0.1", + "0.0001", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:sectorDist", + "5", + "5", + "" + ], + [ + "ZDC:ZDCEcalIslandProtoClusters:splitCluster", + "1", + "1", + "" + ], + [ + "ZDC:ZDCEcalRawHits:capacityADC", + "8096", + "8096", + "" + ], + [ + "ZDC:ZDCEcalRawHits:dynamicRangeADC", + "0.1", + "0.1", + "" + ], + [ + "ZDC:ZDCEcalRawHits:energyResolutions", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalRawHits:fieldRefNumbers", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalRawHits:geoServiceName", + "ActsGeometryProvider", + "ActsGeometryProvider", + "" + ], + [ + "ZDC:ZDCEcalRawHits:pedestalMean", + "400", + "400", + "" + ], + [ + "ZDC:ZDCEcalRawHits:pedestalSigma", + "3.2", + "3.2", + "" + ], + [ + "ZDC:ZDCEcalRawHits:readoutClass", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalRawHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "ZDC:ZDCEcalRawHits:scaleResponse", + "1", + "1", + "" + ], + [ + "ZDC:ZDCEcalRawHits:signalSumFields", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalRawHits:timeResolution", + "0", + "0", + "" + ], + [ + "ZDC:ZDCEcalRecHits:capacityADC", + "8096", + "8096", + "" + ], + [ + "ZDC:ZDCEcalRecHits:dynamicRangeADC", + "0.1", + "0.1", + "" + ], + [ + "ZDC:ZDCEcalRecHits:geoServiceName", + "geoServiceName", + "geoServiceName", + "" + ], + [ + "ZDC:ZDCEcalRecHits:layerField", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalRecHits:localDetElement", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalRecHits:localDetFields", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalRecHits:pedestalMean", + "400", + "400", + "" + ], + [ + "ZDC:ZDCEcalRecHits:pedestalSigma", + "3.2", + "3.2", + "" + ], + [ + "ZDC:ZDCEcalRecHits:readout", + "ZDCEcalHits", + "ZDCEcalHits", + "" + ], + [ + "ZDC:ZDCEcalRecHits:resolutionTDC", + "1e-11", + "1e-11", + "" + ], + [ + "ZDC:ZDCEcalRecHits:samplingFraction", + "1", + "0.998", + "" + ], + [ + "ZDC:ZDCEcalRecHits:sectorField", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalRecHits:thresholdFactor", + "4", + "4", + "" + ], + [ + "ZDC:ZDCEcalRecHits:thresholdValue", + "0", + "0", + "" + ], + [ + "ZDC:ZDCEcalTruthClusters:depthCorrection", + "0", + "0", + "" + ], + [ + "ZDC:ZDCEcalTruthClusters:enableEtaBounds", + "0", + "0", + "" + ], + [ + "ZDC:ZDCEcalTruthClusters:energyWeight", + "log", + "log", + "" + ], + [ + "ZDC:ZDCEcalTruthClusters:input_protoclust_tag", + "ZDCEcalTruthProtoClusters", + "ZDCEcalTruthProtoClusters", + "" + ], + [ + "ZDC:ZDCEcalTruthClusters:input_simhit_tag", + "ZDCEcalHits", + "ZDCEcalHits", + "" + ], + [ + "ZDC:ZDCEcalTruthClusters:logWeightBase", + "3.6", + "3.6", + "" + ], + [ + "ZDC:ZDCEcalTruthClusters:moduleDimZName", + "", + "", + "" + ], + [ + "ZDC:ZDCEcalTruthClusters:samplingFraction", + "1", + "1", + "" + ], + [ + "ZDCEcalClusters:LogLevel", + "info", + "info", + "log_level for ZDCEcalClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "ZDCEcalIslandProtoClusters:LogLevel", + "info", + "info", + "log_level for ZDCEcalIslandProtoClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "ZDCEcalMergedClusters:LogLevel", + "info", + "info", + "log_level for ZDCEcalMergedClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "ZDCEcalMergedTruthClusters:LogLevel", + "info", + "info", + "log_level for ZDCEcalMergedTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "ZDCEcalRawHits:LogLevel", + "info", + "info", + "log_level for ZDCEcalRawHits: trace, debug, info, warn, error, critical, off" + ], + [ + "ZDCEcalRecHits:LogLevel", + "info", + "info", + "log_level for ZDCEcalRecHits: trace, debug, info, warn, error, critical, off" + ], + [ + "ZDCEcalTruthClusters:LogLevel", + "info", + "info", + "log_level for ZDCEcalTruthClusters: trace, debug, info, warn, error, critical, off" + ], + [ + "ZDCEcalTruthProtoClusters:LogLevel", + "info", + "info", + "log_level for ZDCEcalTruthProtoClusters: trace, debug, info, warn, error, critical, off" + ] ] diff --git a/src/algorithms/calorimetry/CalorimeterClusterRecoCoG.cc b/src/algorithms/calorimetry/CalorimeterClusterRecoCoG.cc index bc890923ff..ba19764700 100644 --- a/src/algorithms/calorimetry/CalorimeterClusterRecoCoG.cc +++ b/src/algorithms/calorimetry/CalorimeterClusterRecoCoG.cc @@ -38,66 +38,71 @@ namespace eicrecon { - using namespace dd4hep; - - void CalorimeterClusterRecoCoG::init() { - // select weighting method - std::string ew = m_cfg.energyWeight; - // make it case-insensitive - std::transform(ew.begin(), ew.end(), ew.begin(), [](char s) { return std::tolower(s); }); - auto it = weightMethods.find(ew); - if (it == weightMethods.end()) { - error("Cannot find energy weighting method {}, choose one from [{}]", m_cfg.energyWeight, boost::algorithm::join(weightMethods | boost::adaptors::map_keys, ", ")); - return; - } - weightFunc = it->second; +using namespace dd4hep; + +void CalorimeterClusterRecoCoG::init() { + // select weighting method + std::string ew = m_cfg.energyWeight; + // make it case-insensitive + std::transform(ew.begin(), ew.end(), ew.begin(), [](char s) { return std::tolower(s); }); + auto it = weightMethods.find(ew); + if (it == weightMethods.end()) { + error("Cannot find energy weighting method {}, choose one from [{}]", m_cfg.energyWeight, + boost::algorithm::join(weightMethods | boost::adaptors::map_keys, ", ")); + return; } + weightFunc = it->second; +} - void CalorimeterClusterRecoCoG::process( - const CalorimeterClusterRecoCoG::Input& input, - const CalorimeterClusterRecoCoG::Output& output) const { +void CalorimeterClusterRecoCoG::process(const CalorimeterClusterRecoCoG::Input& input, + const CalorimeterClusterRecoCoG::Output& output) const { #if EDM4EIC_VERSION_MAJOR >= 7 - const auto [proto, mchitassociations] = input; + const auto [proto, mchitassociations] = input; #else - const auto [proto, mchits] = input; + const auto [proto, mchits] = input; #endif - auto [clusters, associations] = output; + auto [clusters, associations] = output; - for (const auto& pcl : *proto) { - // skip protoclusters with no hits - if (pcl.hits_size() == 0) { - continue; - } + for (const auto& pcl : *proto) { + // skip protoclusters with no hits + if (pcl.hits_size() == 0) { + continue; + } - auto cl_opt = reconstruct(pcl); - if (! cl_opt.has_value()) { - continue; - } - auto cl = *std::move(cl_opt); + auto cl_opt = reconstruct(pcl); + if (!cl_opt.has_value()) { + continue; + } + auto cl = *std::move(cl_opt); - debug("{} hits: {} GeV, ({}, {}, {})", cl.getNhits(), cl.getEnergy() / dd4hep::GeV, cl.getPosition().x / dd4hep::mm, cl.getPosition().y / dd4hep::mm, cl.getPosition().z / dd4hep::mm); - clusters->push_back(cl); + debug("{} hits: {} GeV, ({}, {}, {})", cl.getNhits(), cl.getEnergy() / dd4hep::GeV, + cl.getPosition().x / dd4hep::mm, cl.getPosition().y / dd4hep::mm, + cl.getPosition().z / dd4hep::mm); + clusters->push_back(cl); - // If sim hits are available, associate cluster with MCParticle + // If sim hits are available, associate cluster with MCParticle #if EDM4EIC_VERSION_MAJOR >= 7 - if (mchitassociations->size() == 0) { - debug("Provided MCRecoCalorimeterHitAssociation collection is empty. No truth associations will be performed."); - continue; - } else { - associate(cl, mchitassociations, associations); - } + if (mchitassociations->size() == 0) { + debug("Provided MCRecoCalorimeterHitAssociation collection is empty. No truth associations " + "will be performed."); + continue; + } else { + associate(cl, mchitassociations, associations); + } #else - if (mchits->size() == 0) { - debug("Provided SimCalorimeterHitCollection is empty. No truth association will be performed."); - continue; - } else { - associate(cl, mchits, associations); - } -#endif + if (mchits->size() == 0) { + debug( + "Provided SimCalorimeterHitCollection is empty. No truth association will be performed."); + continue; + } else { + associate(cl, mchits, associations); } +#endif + } } -std::optional CalorimeterClusterRecoCoG::reconstruct(const edm4eic::ProtoCluster& pcl) const { +std::optional +CalorimeterClusterRecoCoG::reconstruct(const edm4eic::ProtoCluster& pcl) const { edm4eic::MutableCluster cl; cl.setNhits(pcl.hits_size()); @@ -113,8 +118,8 @@ std::optional CalorimeterClusterRecoCoG::reconstruct(co // Used to optionally constrain the cluster eta to those of the contributing hits float minHitEta = std::numeric_limits::max(); float maxHitEta = std::numeric_limits::min(); - auto time = 0; - auto timeError = 0; + auto time = 0; + auto timeError = 0; for (unsigned i = 0; i < pcl.getHits().size(); ++i) { const auto& hit = pcl.getHits()[i]; const auto weight = pcl.getWeights()[i]; @@ -141,12 +146,12 @@ std::optional CalorimeterClusterRecoCoG::reconstruct(co float tw = 0.; auto v = cl.getPosition(); - double logWeightBase=m_cfg.logWeightBase; - if (m_cfg.logWeightBaseCoeffs.size() != 0){ - double l=log(cl.getEnergy()/m_cfg.logWeightBase_Eref); - logWeightBase=0; - for(std::size_t i =0; i CalorimeterClusterRecoCoG::reconstruct(co const auto& hit = pcl.getHits()[i]; const auto weight = pcl.getWeights()[i]; // _DBG_<<" -- weight = " << weight << " E=" << hit.getEnergy() << " totalE=" < CalorimeterClusterRecoCoG::reconstruct(co // x-y-z cluster widths (3D) float radius = 0, dispersion = 0, w_sum = 0; - Eigen::Matrix2f sum2_2D = Eigen::Matrix2f::Zero(); - Eigen::Matrix3f sum2_3D = Eigen::Matrix3f::Zero(); - Eigen::Vector2f sum1_2D = Eigen::Vector2f::Zero(); - Eigen::Vector3f sum1_3D = Eigen::Vector3f::Zero(); + Eigen::Matrix2f sum2_2D = Eigen::Matrix2f::Zero(); + Eigen::Matrix3f sum2_3D = Eigen::Matrix3f::Zero(); + Eigen::Vector2f sum1_2D = Eigen::Vector2f::Zero(); + Eigen::Vector3f sum1_3D = Eigen::Vector3f::Zero(); Eigen::Vector2cf eigenValues_2D = Eigen::Vector2cf::Zero(); Eigen::Vector3cf eigenValues_3D = Eigen::Vector3cf::Zero(); // the axis is the direction of the eigenvalue corresponding to the largest eigenvalue. @@ -203,13 +209,14 @@ std::optional CalorimeterClusterRecoCoG::reconstruct(co float w = weightFunc(hit.getEnergy(), totalE, logWeightBase, 0); // theta, phi - Eigen::Vector2f pos2D( edm4hep::utils::anglePolar( hit.getPosition() ), edm4hep::utils::angleAzimuthal( hit.getPosition() ) ); + Eigen::Vector2f pos2D(edm4hep::utils::anglePolar(hit.getPosition()), + edm4hep::utils::angleAzimuthal(hit.getPosition())); // x, y, z - Eigen::Vector3f pos3D( hit.getPosition().x, hit.getPosition().y, hit.getPosition().z ); + Eigen::Vector3f pos3D(hit.getPosition().x, hit.getPosition().y, hit.getPosition().z); const auto delta = cl.getPosition() - hit.getPosition(); - radius += delta * delta; - dispersion += delta * delta * w; + radius += delta * delta; + dispersion += delta * delta * w; // Weighted Sum x*x, x*y, x*z, y*y, etc. sum2_2D += w * pos2D * pos2D.transpose(); @@ -222,9 +229,9 @@ std::optional CalorimeterClusterRecoCoG::reconstruct(co w_sum += w; } - radius = sqrt((1. / (cl.getNhits() - 1.)) * radius); - if( w_sum > 0 ) { - dispersion = sqrt( dispersion / w_sum ); + radius = sqrt((1. / (cl.getNhits() - 1.)) * radius); + if (w_sum > 0) { + dispersion = sqrt(dispersion / w_sum); // normalize matrices sum2_2D /= w_sum; @@ -237,41 +244,35 @@ std::optional CalorimeterClusterRecoCoG::reconstruct(co Eigen::Matrix3f cov3 = sum2_3D - sum1_3D * sum1_3D.transpose(); // Solve for eigenvalues. Corresponds to cluster's 2nd moments (widths) - Eigen::EigenSolver es_2D(cov2, false); // set to true for eigenvector calculation - Eigen::EigenSolver es_3D(cov3, true); // set to true for eigenvector calculation + Eigen::EigenSolver es_2D(cov2, + false); // set to true for eigenvector calculation + Eigen::EigenSolver es_3D(cov3, + true); // set to true for eigenvector calculation // eigenvalues of symmetric real matrix are always real eigenValues_2D = es_2D.eigenvalues(); eigenValues_3D = es_3D.eigenvalues(); //find the eigenvector corresponding to the largest eigenvalue - auto eigenvectors= es_3D.eigenvectors(); - auto max_eigenvalue_it = std::max_element( - eigenValues_3D.begin(), - eigenValues_3D.end(), - [](auto a, auto b) { - return std::real(a) < std::real(b); - } - ); - auto axis_eigen = eigenvectors.col(std::distance( - eigenValues_3D.begin(), - max_eigenvalue_it - )); - axis = { - axis_eigen(0,0).real(), - axis_eigen(1,0).real(), - axis_eigen(2,0).real(), + auto eigenvectors = es_3D.eigenvectors(); + auto max_eigenvalue_it = + std::max_element(eigenValues_3D.begin(), eigenValues_3D.end(), + [](auto a, auto b) { return std::real(a) < std::real(b); }); + auto axis_eigen = eigenvectors.col(std::distance(eigenValues_3D.begin(), max_eigenvalue_it)); + axis = { + axis_eigen(0, 0).real(), + axis_eigen(1, 0).real(), + axis_eigen(2, 0).real(), }; } } - cl.addToShapeParameters( radius ); - cl.addToShapeParameters( dispersion ); - cl.addToShapeParameters( eigenValues_2D[0].real() ); // 2D theta-phi cluster width 1 - cl.addToShapeParameters( eigenValues_2D[1].real() ); // 2D theta-phi cluster width 2 - cl.addToShapeParameters( eigenValues_3D[0].real() ); // 3D x-y-z cluster width 1 - cl.addToShapeParameters( eigenValues_3D[1].real() ); // 3D x-y-z cluster width 2 - cl.addToShapeParameters( eigenValues_3D[2].real() ); // 3D x-y-z cluster width 3 - + cl.addToShapeParameters(radius); + cl.addToShapeParameters(dispersion); + cl.addToShapeParameters(eigenValues_2D[0].real()); // 2D theta-phi cluster width 1 + cl.addToShapeParameters(eigenValues_2D[1].real()); // 2D theta-phi cluster width 2 + cl.addToShapeParameters(eigenValues_3D[0].real()); // 3D x-y-z cluster width 1 + cl.addToShapeParameters(eigenValues_3D[1].real()); // 3D x-y-z cluster width 2 + cl.addToShapeParameters(eigenValues_3D[2].real()); // 3D x-y-z cluster width 3 double dot_product = cl.getPosition() * axis; if (dot_product < 0) { @@ -291,14 +292,13 @@ std::optional CalorimeterClusterRecoCoG::reconstruct(co } void CalorimeterClusterRecoCoG::associate( - const edm4eic::Cluster& cl, + const edm4eic::Cluster& cl, #if EDM4EIC_VERSION_MAJOR >= 7 - const edm4eic::MCRecoCalorimeterHitAssociationCollection* mchitassociations, + const edm4eic::MCRecoCalorimeterHitAssociationCollection* mchitassociations, #else - const edm4hep::SimCalorimeterHitCollection* mchits, + const edm4hep::SimCalorimeterHitCollection* mchits, #endif - edm4eic::MCRecoClusterParticleAssociationCollection* assocs -) const { + edm4eic::MCRecoClusterParticleAssociationCollection* assocs) const { // -------------------------------------------------------------------------- // Association Logic // -------------------------------------------------------------------------- @@ -340,12 +340,11 @@ void CalorimeterClusterRecoCoG::associate( vecAssocSimHits.push_back(hitAssoc.getSimHit()); eSimHitSum += vecAssocSimHits.back().getEnergy(); } - } #else for (const auto& mchit : *mchits) { if (mchit.getCellID() == clhit.getCellID()) { - vecAssocSimHits.push_back(mchit); + vecAssocSimHits.push_back(mchit); break; } } @@ -359,7 +358,8 @@ void CalorimeterClusterRecoCoG::associate( eSimHitSum += vecAssocSimHits.back().getEnergy(); } #endif - debug("{} associated sim hits found for reco hit (cell ID = {})", vecAssocSimHits.size(), clhit.getCellID()); + debug("{} associated sim hits found for reco hit (cell ID = {})", vecAssocSimHits.size(), + clhit.getCellID()); // ------------------------------------------------------------------------ // 2. loop through associated sim hits @@ -373,11 +373,8 @@ void CalorimeterClusterRecoCoG::associate( mapMCParToContrib[primary] += contrib.getEnergy(); trace("Identified primary: id = {}, pid = {}, total energy = {}, contributed = {}", - primary.getObjectID().index, - primary.getPDG(), - primary.getEnergy(), - mapMCParToContrib[primary] - ); + primary.getObjectID().index, primary.getPDG(), primary.getEnergy(), + mapMCParToContrib[primary]); } } } @@ -397,18 +394,15 @@ void CalorimeterClusterRecoCoG::associate( assoc.setWeight(weight); assoc.setRec(cl); assoc.setSim(part); - debug("Associated cluster #{} to MC Particle #{} (pid = {}, status = {}, energy = {}) with weight ({})", - cl.getObjectID().index, - part.getObjectID().index, - part.getPDG(), - part.getGeneratorStatus(), - part.getEnergy(), - weight - ); + debug("Associated cluster #{} to MC Particle #{} (pid = {}, status = {}, energy = {}) with " + "weight ({})", + cl.getObjectID().index, part.getObjectID().index, part.getPDG(), + part.getGeneratorStatus(), part.getEnergy(), weight); } } -edm4hep::MCParticle CalorimeterClusterRecoCoG::get_primary(const edm4hep::CaloHitContribution& contrib) const { +edm4hep::MCParticle +CalorimeterClusterRecoCoG::get_primary(const edm4hep::CaloHitContribution& contrib) const { // get contributing particle const auto contributor = contrib.getParticle(); @@ -417,10 +411,11 @@ edm4hep::MCParticle CalorimeterClusterRecoCoG::get_primary(const edm4hep::CaloHi // can be improved!! edm4hep::MCParticle primary = contributor; while (primary.parents_size() > 0) { - if (primary.getGeneratorStatus() != 0) break; + if (primary.getGeneratorStatus() != 0) + break; primary = primary.getParents(0); } return primary; } -} +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterClusterRecoCoG.h b/src/algorithms/calorimetry/CalorimeterClusterRecoCoG.h index 5a1ae4acbc..845996f053 100644 --- a/src/algorithms/calorimetry/CalorimeterClusterRecoCoG.h +++ b/src/algorithms/calorimetry/CalorimeterClusterRecoCoG.h @@ -38,71 +38,70 @@ static double constWeight(double /*E*/, double /*tE*/, double /*p*/, int /*type*/) { return 1.0; } static double linearWeight(double E, double /*tE*/, double /*p*/, int /*type*/) { return E; } static double logWeight(double E, double tE, double base, int /*type*/) { - return std::max(0., base + std::log(E / tE)); + return std::max(0., base + std::log(E / tE)); } -static const std::map> weightMethods={ - {"none", constWeight}, - {"linear", linearWeight}, - {"log", logWeight}, +static const std::map> + weightMethods = { + {"none", constWeight}, + {"linear", linearWeight}, + {"log", logWeight}, }; namespace eicrecon { - using ClustersWithAssociations = std::pair< - std::unique_ptr, - std::unique_ptr - >; +using ClustersWithAssociations = + std::pair, + std::unique_ptr>; - using CalorimeterClusterRecoCoGAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::ProtoClusterCollection, +using CalorimeterClusterRecoCoGAlgorithm = algorithms::Algorithm< + algorithms::Input= 7 - std::optional + std::optional #else - std::optional + std::optional #endif - >, - algorithms::Output< - edm4eic::ClusterCollection, - std::optional - > - >; - - class CalorimeterClusterRecoCoG - : public CalorimeterClusterRecoCoGAlgorithm, - public WithPodConfig { - - public: - CalorimeterClusterRecoCoG(std::string_view name) - : CalorimeterClusterRecoCoGAlgorithm{name, + >, + algorithms::Output>>; + +class CalorimeterClusterRecoCoG : public CalorimeterClusterRecoCoGAlgorithm, + public WithPodConfig { + +public: + CalorimeterClusterRecoCoG(std::string_view name) + : CalorimeterClusterRecoCoGAlgorithm{ + name, #if EDM4EIC_VERSION_MAJOR >= 7 - {"inputProtoClusterCollection", "mcRawHitAssocations"}, + {"inputProtoClusterCollection", "mcRawHitAssocations"}, #else - {"inputProtoClusterCollection", "mcHits"}, + {"inputProtoClusterCollection", "mcHits"}, #endif - {"outputClusterCollection", "outputAssociations"}, - "Reconstruct a cluster with the Center of Gravity method. For " - "simulation results it optionally creates a Cluster <-> MCParticle " - "association provided both optional arguments are provided."} {} + {"outputClusterCollection", "outputAssociations"}, + "Reconstruct a cluster with the Center of Gravity method. For " + "simulation results it optionally creates a Cluster <-> MCParticle " + "association provided both optional arguments are provided."} { + } - public: - void init() final; +public: + void init() final; - void process(const Input&, const Output&) const final; + void process(const Input&, const Output&) const final; - private: - std::function weightFunc; +private: + std::function weightFunc; - private: - std::optional reconstruct(const edm4eic::ProtoCluster& pcl) const; +private: + std::optional reconstruct(const edm4eic::ProtoCluster& pcl) const; #if EDM4EIC_VERSION_MAJOR >= 7 - void associate(const edm4eic::Cluster& cl, const edm4eic::MCRecoCalorimeterHitAssociationCollection* mchitassociations, edm4eic::MCRecoClusterParticleAssociationCollection* assocs) const; + void associate(const edm4eic::Cluster& cl, + const edm4eic::MCRecoCalorimeterHitAssociationCollection* mchitassociations, + edm4eic::MCRecoClusterParticleAssociationCollection* assocs) const; #else - void associate(const edm4eic::Cluster& cl, const edm4hep::SimCalorimeterHitCollection* mchits, edm4eic::MCRecoClusterParticleAssociationCollection* assocs) const; + void associate(const edm4eic::Cluster& cl, const edm4hep::SimCalorimeterHitCollection* mchits, + edm4eic::MCRecoClusterParticleAssociationCollection* assocs) const; #endif - edm4hep::MCParticle get_primary(const edm4hep::CaloHitContribution& contrib) const; - - }; + edm4hep::MCParticle get_primary(const edm4hep::CaloHitContribution& contrib) const; +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterClusterRecoCoGConfig.h b/src/algorithms/calorimetry/CalorimeterClusterRecoCoGConfig.h index 1b0624462e..e97874d412 100644 --- a/src/algorithms/calorimetry/CalorimeterClusterRecoCoGConfig.h +++ b/src/algorithms/calorimetry/CalorimeterClusterRecoCoGConfig.h @@ -9,27 +9,26 @@ namespace eicrecon { - struct CalorimeterClusterRecoCoGConfig { +struct CalorimeterClusterRecoCoGConfig { - std::string energyWeight; + std::string energyWeight; - double sampFrac = 1.; - double logWeightBase = 3.6; + double sampFrac = 1.; + double logWeightBase = 3.6; - //optional: have the log weight base depend on the energy - // logWeightBaseCoeffs[0]+logWeightBaseCoeffs[1]*l+logWeightBaseCoeffs[2]*l*l + ... - // where l = log(cl.getEnergy()/logWeightBase_Eref) - // If this is empty, use the logWeightBase parameter for backwards compatibility. - std::vector logWeightBaseCoeffs{}; - double logWeightBase_Eref = 50 * dd4hep::MeV; + //optional: have the log weight base depend on the energy + // logWeightBaseCoeffs[0]+logWeightBaseCoeffs[1]*l+logWeightBaseCoeffs[2]*l*l + ... + // where l = log(cl.getEnergy()/logWeightBase_Eref) + // If this is empty, use the logWeightBase parameter for backwards compatibility. + std::vector logWeightBaseCoeffs{}; + double logWeightBase_Eref = 50 * dd4hep::MeV; - bool longitudinalShowerInfoAvailable = false; + bool longitudinalShowerInfoAvailable = false; - // Constrain the cluster position eta to be within - // the eta of the contributing hits. This is useful to avoid edge effects - // for endcaps. - bool enableEtaBounds = false; + // Constrain the cluster position eta to be within + // the eta of the contributing hits. This is useful to avoid edge effects + // for endcaps. + bool enableEtaBounds = false; +}; - }; - -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterHitDigi.cc b/src/algorithms/calorimetry/CalorimeterHitDigi.cc index 95457082e9..ff33cb88a3 100644 --- a/src/algorithms/calorimetry/CalorimeterHitDigi.cc +++ b/src/algorithms/calorimetry/CalorimeterHitDigi.cc @@ -10,7 +10,6 @@ // Author: Chao Peng // Date: 06/02/2021 - #include "CalorimeterHitDigi.h" #include @@ -53,180 +52,184 @@ namespace eicrecon { // being set in the config. If that is the case, they should be moved into the default // values here. This needs to be confirmed. - void CalorimeterHitDigi::init() { - // Gaudi implements a random number generator service. It is not clear to me how this - // can work. There are multiple race conditions that occur in parallel event processing: - // 1. The exact same events processed by a given thread in one invocation will not - // necessarily be the combination of events any thread sees in a subsequent - // invocation. Thus, you can't rely on thread_local storage. - // 2. Its possible for the factory execution order to be modified by the presence of - // a processor (e.g. monitoring plugin). This is not as serious since changing the - // command line should cause one not to expect reproducibility. Still, one may - // expect the inclusion of an "observer" plugin not to have such side affects. - // - // More information will be needed. In the meantime, we implement a local random number - // generator. Ideally, this would be seeded with the run number+event number, but for - // now, just use default values defined in header file. - - // set energy resolution numbers - if (m_cfg.eRes.empty()) { - m_cfg.eRes.resize(3); - } else if (m_cfg.eRes.size() != 3) { - error("Invalid m_cfg.eRes.size()"); - throw std::runtime_error("Invalid m_cfg.eRes.size()"); + // Gaudi implements a random number generator service. It is not clear to me how this + // can work. There are multiple race conditions that occur in parallel event processing: + // 1. The exact same events processed by a given thread in one invocation will not + // necessarily be the combination of events any thread sees in a subsequent + // invocation. Thus, you can't rely on thread_local storage. + // 2. Its possible for the factory execution order to be modified by the presence of + // a processor (e.g. monitoring plugin). This is not as serious since changing the + // command line should cause one not to expect reproducibility. Still, one may + // expect the inclusion of an "observer" plugin not to have such side affects. + // + // More information will be needed. In the meantime, we implement a local random number + // generator. Ideally, this would be seeded with the run number+event number, but for + // now, just use default values defined in header file. + + // set energy resolution numbers + if (m_cfg.eRes.empty()) { + m_cfg.eRes.resize(3); + } else if (m_cfg.eRes.size() != 3) { + error("Invalid m_cfg.eRes.size()"); + throw std::runtime_error("Invalid m_cfg.eRes.size()"); + } + + // using juggler internal units (GeV, mm, radian, ns) + tRes = m_cfg.tRes / dd4hep::ns; + stepTDC = dd4hep::ns / m_cfg.resolutionTDC; + + // sanity checks + if (m_cfg.readout.empty()) { + error("readoutClass is not provided, it is needed to know the fields in readout ids"); + throw std::runtime_error("readoutClass is not provided"); + } + + // get decoders + try { + id_spec = m_geo.detector()->readout(m_cfg.readout).idSpec(); + } catch (...) { + // Can not be more verbose. In JANA2, this will be attempted at each event, which + // pollutes output for geometries that are less than complete. + // We could save an exception and throw it from process. + debug("Failed to load ID decoder for {}", m_cfg.readout); + throw std::runtime_error(fmt::format("Failed to load ID decoder for {}", m_cfg.readout)); + } + + decltype(id_mask) id_inverse_mask = 0; + // all these are for signal sum at digitization level + if (!m_cfg.fields.empty()) { + for (auto& field : m_cfg.fields) { + id_inverse_mask |= id_spec.field(field)->mask(); } - - // using juggler internal units (GeV, mm, radian, ns) - tRes = m_cfg.tRes / dd4hep::ns; - stepTDC = dd4hep::ns / m_cfg.resolutionTDC; - - // sanity checks - if (m_cfg.readout.empty()) { - error("readoutClass is not provided, it is needed to know the fields in readout ids"); - throw std::runtime_error("readoutClass is not provided"); + debug("ID mask in {:s}: {:#064b}", m_cfg.readout, id_mask); + } + id_mask = ~id_inverse_mask; + + std::function hit_to_map = [this](const edm4hep::SimCalorimeterHit& h) { + std::unordered_map params; + for (const auto& p : id_spec.fields()) { + const std::string& name = p.first; + const dd4hep::IDDescriptor::Field* field = p.second; + params.emplace(name, field->value(h.getCellID())); + trace("{} = {}", name, field->value(h.getCellID())); } + return params; + }; - // get decoders - try { - id_spec = m_geo.detector()->readout(m_cfg.readout).idSpec(); - } catch (...) { - // Can not be more verbose. In JANA2, this will be attempted at each event, which - // pollutes output for geometries that are less than complete. - // We could save an exception and throw it from process. - debug("Failed to load ID decoder for {}", m_cfg.readout); - throw std::runtime_error(fmt::format("Failed to load ID decoder for {}", m_cfg.readout)); - } - - decltype(id_mask) id_inverse_mask = 0; - // all these are for signal sum at digitization level - if (!m_cfg.fields.empty()) { - for (auto & field : m_cfg.fields) { - id_inverse_mask |= id_spec.field(field)->mask(); - } - debug("ID mask in {:s}: {:#064b}", m_cfg.readout, id_mask); - } - id_mask = ~id_inverse_mask; - - std::function hit_to_map = [this](const edm4hep::SimCalorimeterHit &h) { - std::unordered_map params; - for(const auto &p : id_spec.fields()) { - const std::string &name = p.first; - const dd4hep::IDDescriptor::Field* field = p.second; - params.emplace(name, field->value(h.getCellID())); - trace("{} = {}", name, field->value(h.getCellID())); - } - return params; - }; - - auto& serviceSvc = algorithms::ServiceSvc::instance(); - corrMeanScale = serviceSvc.service("EvaluatorSvc")->compile(m_cfg.corrMeanScale, hit_to_map); + auto& serviceSvc = algorithms::ServiceSvc::instance(); + corrMeanScale = + serviceSvc.service("EvaluatorSvc")->compile(m_cfg.corrMeanScale, hit_to_map); } +void CalorimeterHitDigi::process(const CalorimeterHitDigi::Input& input, + const CalorimeterHitDigi::Output& output) const { -void CalorimeterHitDigi::process( - const CalorimeterHitDigi::Input& input, - const CalorimeterHitDigi::Output& output) const { - - const auto [simhits] = input; + const auto [simhits] = input; #if EDM4EIC_VERSION_MAJOR >= 7 - auto [rawhits, rawassocs] = output; + auto [rawhits, rawassocs] = output; #else - auto [rawhits] = output; + auto [rawhits] = output; #endif - // find the hits that belong to the same group (for merging) - std::unordered_map> merge_map; - std::size_t ix = 0; - for (const auto &ahit : *simhits) { - uint64_t hid = ahit.getCellID() & id_mask; + // find the hits that belong to the same group (for merging) + std::unordered_map> merge_map; + std::size_t ix = 0; + for (const auto& ahit : *simhits) { + uint64_t hid = ahit.getCellID() & id_mask; - trace("org cell ID in {:s}: {:#064b}", m_cfg.readout, ahit.getCellID()); - trace("new cell ID in {:s}: {:#064b}", m_cfg.readout, hid); + trace("org cell ID in {:s}: {:#064b}", m_cfg.readout, ahit.getCellID()); + trace("new cell ID in {:s}: {:#064b}", m_cfg.readout, hid); - merge_map[hid].push_back(ix); + merge_map[hid].push_back(ix); - ix++; - } + ix++; + } - // signal sum - // NOTE: we take the cellID of the most energetic hit in this group so it is a real cellID from an MC hit - for (const auto &[id, ixs] : merge_map) { + // signal sum + // NOTE: we take the cellID of the most energetic hit in this group so it is a real cellID from an MC hit + for (const auto& [id, ixs] : merge_map) { - // create hit and association in advance - edm4hep::MutableRawCalorimeterHit rawhit; + // create hit and association in advance + edm4hep::MutableRawCalorimeterHit rawhit; #if EDM4EIC_VERSION_MAJOR >= 7 - std::vector rawassocs_staging; + std::vector rawassocs_staging; #endif - double edep = 0; - double time = std::numeric_limits::max(); - double max_edep = 0; - auto leading_hit = (*simhits)[ixs[0]]; - // sum energy, take time from the most energetic hit - for (size_t i = 0; i < ixs.size(); ++i) { - auto hit = (*simhits)[ixs[i]]; - - double timeC = std::numeric_limits::max(); - for (const auto& c : hit.getContributions()) { - if (c.getTime() <= timeC) { - timeC = c.getTime(); - } - } - if (timeC > m_cfg.capTime) continue; - edep += hit.getEnergy(); - trace("adding {} \t total: {}", hit.getEnergy(), edep); - - // change maximum hit energy & time if necessary - if (hit.getEnergy() > max_edep) { - max_edep = hit.getEnergy(); - leading_hit = hit; - if (timeC <= time) { - time = timeC; - } - } + double edep = 0; + double time = std::numeric_limits::max(); + double max_edep = 0; + auto leading_hit = (*simhits)[ixs[0]]; + // sum energy, take time from the most energetic hit + for (size_t i = 0; i < ixs.size(); ++i) { + auto hit = (*simhits)[ixs[i]]; + + double timeC = std::numeric_limits::max(); + for (const auto& c : hit.getContributions()) { + if (c.getTime() <= timeC) { + timeC = c.getTime(); + } + } + if (timeC > m_cfg.capTime) + continue; + edep += hit.getEnergy(); + trace("adding {} \t total: {}", hit.getEnergy(), edep); + + // change maximum hit energy & time if necessary + if (hit.getEnergy() > max_edep) { + max_edep = hit.getEnergy(); + leading_hit = hit; + if (timeC <= time) { + time = timeC; + } + } #if EDM4EIC_VERSION_MAJOR >= 7 - edm4eic::MutableMCRecoCalorimeterHitAssociation assoc; - assoc.setRawHit(rawhit); - assoc.setSimHit(hit); - assoc.setWeight(hit.getEnergy()); - rawassocs_staging.push_back(assoc); + edm4eic::MutableMCRecoCalorimeterHitAssociation assoc; + assoc.setRawHit(rawhit); + assoc.setSimHit(hit); + assoc.setWeight(hit.getEnergy()); + rawassocs_staging.push_back(assoc); #endif - } - if (time > m_cfg.capTime) continue; - - // safety check - const double eResRel = (edep > m_cfg.threshold) - ? m_gaussian(m_generator) * std::sqrt( - std::pow(m_cfg.eRes[0] / std::sqrt(edep), 2) + - std::pow(m_cfg.eRes[1], 2) + - std::pow(m_cfg.eRes[2] / (edep), 2) - ) - : 0; - double corrMeanScale_value = corrMeanScale(leading_hit); - - double ped = m_cfg.pedMeanADC + m_gaussian(m_generator) * m_cfg.pedSigmaADC; - - // Note: both adc and tdc values must be positive numbers to avoid integer wraparound - unsigned long long adc = std::max(std::llround(ped + edep * corrMeanScale_value * (1.0 + eResRel) / m_cfg.dyRangeADC * m_cfg.capADC), 0LL); - unsigned long long tdc = std::llround((time + m_gaussian(m_generator) * tRes) * stepTDC); - - if (edep> 1.e-3) trace("E sim {} \t adc: {} \t time: {}\t maxtime: {} \t tdc: {} \t corrMeanScale: {}", edep, adc, time, m_cfg.capTime, tdc, corrMeanScale_value); - - rawhit.setCellID(leading_hit.getCellID()); - rawhit.setAmplitude(adc > m_cfg.capADC ? m_cfg.capADC : adc); - rawhit.setTimeStamp(tdc); - rawhits->push_back(rawhit); + } + if (time > m_cfg.capTime) + continue; + + // safety check + const double eResRel = + (edep > m_cfg.threshold) + ? m_gaussian(m_generator) * + std::sqrt(std::pow(m_cfg.eRes[0] / std::sqrt(edep), 2) + + std::pow(m_cfg.eRes[1], 2) + std::pow(m_cfg.eRes[2] / (edep), 2)) + : 0; + double corrMeanScale_value = corrMeanScale(leading_hit); + + double ped = m_cfg.pedMeanADC + m_gaussian(m_generator) * m_cfg.pedSigmaADC; + + // Note: both adc and tdc values must be positive numbers to avoid integer wraparound + unsigned long long adc = + std::max(std::llround(ped + edep * corrMeanScale_value * (1.0 + eResRel) / + m_cfg.dyRangeADC * m_cfg.capADC), + 0LL); + unsigned long long tdc = std::llround((time + m_gaussian(m_generator) * tRes) * stepTDC); + + if (edep > 1.e-3) + trace("E sim {} \t adc: {} \t time: {}\t maxtime: {} \t tdc: {} \t corrMeanScale: {}", edep, + adc, time, m_cfg.capTime, tdc, corrMeanScale_value); + + rawhit.setCellID(leading_hit.getCellID()); + rawhit.setAmplitude(adc > m_cfg.capADC ? m_cfg.capADC : adc); + rawhit.setTimeStamp(tdc); + rawhits->push_back(rawhit); #if EDM4EIC_VERSION_MAJOR >= 7 - for (auto& assoc : rawassocs_staging) { - assoc.setWeight(assoc.getWeight() / edep); - rawassocs->push_back(assoc); - } -#endif + for (auto& assoc : rawassocs_staging) { + assoc.setWeight(assoc.getWeight() / edep); + rawassocs->push_back(assoc); } +#endif + } } } // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterHitDigi.h b/src/algorithms/calorimetry/CalorimeterHitDigi.h index b2d919a55f..c0c541cf37 100644 --- a/src/algorithms/calorimetry/CalorimeterHitDigi.h +++ b/src/algorithms/calorimetry/CalorimeterHitDigi.h @@ -10,7 +10,6 @@ // Author: Chao Peng // Date: 06/02/2021 - #pragma once #include @@ -33,56 +32,51 @@ namespace eicrecon { - using CalorimeterHitDigiAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4hep::SimCalorimeterHitCollection - >, +using CalorimeterHitDigiAlgorithm = algorithms::Algorithm< + algorithms::Input, algorithms::Output< #if EDM4EIC_VERSION_MAJOR >= 7 - edm4hep::RawCalorimeterHitCollection, - edm4eic::MCRecoCalorimeterHitAssociationCollection + edm4hep::RawCalorimeterHitCollection, edm4eic::MCRecoCalorimeterHitAssociationCollection #else - edm4hep::RawCalorimeterHitCollection + edm4hep::RawCalorimeterHitCollection #endif - > - >; + >>; - class CalorimeterHitDigi - : public CalorimeterHitDigiAlgorithm, - public WithPodConfig { +class CalorimeterHitDigi : public CalorimeterHitDigiAlgorithm, + public WithPodConfig { - public: - CalorimeterHitDigi(std::string_view name) - : CalorimeterHitDigiAlgorithm{name, - {"inputHitCollection"}, +public: + CalorimeterHitDigi(std::string_view name) + : CalorimeterHitDigiAlgorithm{ + name, + {"inputHitCollection"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"outputRawHitCollection", "outputRawHitAssociationCollection"}, + {"outputRawHitCollection", "outputRawHitAssociationCollection"}, #else - {"outputRawHitCollection"}, + {"outputRawHitCollection"}, #endif - "Smear energy deposit, digitize within ADC range, add pedestal, " - "convert time with smearing resolution, and sum signals."} {} - - void init() final; - void process(const Input&, const Output&) const final; - - private: + "Smear energy deposit, digitize within ADC range, add pedestal, " + "convert time with smearing resolution, and sum signals."} { + } - // unitless counterparts of inputs - double dyRangeADC{0}, stepTDC{0}, tRes{0}; + void init() final; + void process(const Input&, const Output&) const final; - uint64_t id_mask{0}; +private: + // unitless counterparts of inputs + double dyRangeADC{0}, stepTDC{0}, tRes{0}; - std::function corrMeanScale; + uint64_t id_mask{0}; - dd4hep::IDDescriptor id_spec; + std::function corrMeanScale; - private: - const algorithms::GeoSvc& m_geo = algorithms::GeoSvc::instance(); + dd4hep::IDDescriptor id_spec; - mutable std::default_random_engine m_generator; - mutable std::normal_distribution m_gaussian; +private: + const algorithms::GeoSvc& m_geo = algorithms::GeoSvc::instance(); - }; + mutable std::default_random_engine m_generator; + mutable std::normal_distribution m_gaussian; +}; } // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterHitDigiConfig.h b/src/algorithms/calorimetry/CalorimeterHitDigiConfig.h index 2b25d55c46..b55cb98f45 100644 --- a/src/algorithms/calorimetry/CalorimeterHitDigiConfig.h +++ b/src/algorithms/calorimetry/CalorimeterHitDigiConfig.h @@ -8,27 +8,26 @@ namespace eicrecon { - struct CalorimeterHitDigiConfig { +struct CalorimeterHitDigiConfig { - std::vector eRes; - double tRes; + std::vector eRes; + double tRes; - // single hit energy deposition threshold - double threshold{1.0*dd4hep::keV}; + // single hit energy deposition threshold + double threshold{1.0 * dd4hep::keV}; - // digitization settings - unsigned int capADC{1}; - double capTime{1000}; // dynamic range in ns - double dyRangeADC{1}; - unsigned int pedMeanADC{0}; - double pedSigmaADC{0}; - double resolutionTDC{1}; - std::string corrMeanScale{"1.0"}; + // digitization settings + unsigned int capADC{1}; + double capTime{1000}; // dynamic range in ns + double dyRangeADC{1}; + unsigned int pedMeanADC{0}; + double pedSigmaADC{0}; + double resolutionTDC{1}; + std::string corrMeanScale{"1.0"}; - // signal sums - std::string readout{""}; - std::vector fields{}; + // signal sums + std::string readout{""}; + std::vector fields{}; +}; - }; - -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterHitReco.cc b/src/algorithms/calorimetry/CalorimeterHitReco.cc index b461b790c8..645c651b37 100644 --- a/src/algorithms/calorimetry/CalorimeterHitReco.cc +++ b/src/algorithms/calorimetry/CalorimeterHitReco.cc @@ -47,263 +47,267 @@ namespace eicrecon { void CalorimeterHitReco::init() { - // threshold for firing - // Should set either m_cfg.thresholdFactor or m_cfg.thresholdValue, not both - if ( m_cfg.thresholdFactor * m_cfg.thresholdValue != 0 ){ - error("thresholdFactor = {}, thresholdValue = {}. Only one of these should be non-zero.", - m_cfg.thresholdFactor, m_cfg.thresholdValue); - throw; // throw with an argument doesn't trigger abort + // threshold for firing + // Should set either m_cfg.thresholdFactor or m_cfg.thresholdValue, not both + if (m_cfg.thresholdFactor * m_cfg.thresholdValue != 0) { + error("thresholdFactor = {}, thresholdValue = {}. Only one of these should be non-zero.", + m_cfg.thresholdFactor, m_cfg.thresholdValue); + throw; // throw with an argument doesn't trigger abort + } + thresholdADC = m_cfg.thresholdFactor * m_cfg.pedSigmaADC + m_cfg.thresholdValue; + // TDC channels to timing conversion + stepTDC = dd4hep::ns / m_cfg.resolutionTDC; + + // do not get the layer/sector ID if no readout class provided + if (m_cfg.readout.empty()) { + return; + } + + // First, try and get the IDDescriptor. This will throw an exception if it fails. + try { + id_spec = m_detector->readout(m_cfg.readout).idSpec(); + } catch (...) { + warning("Failed to get idSpec for {}", m_cfg.readout); + return; + } + // Next, try and get the readout fields. This will throw a different exception. + try { + id_dec = id_spec.decoder(); + if (!m_cfg.sectorField.empty()) { + sector_idx = id_dec->index(m_cfg.sectorField); + debug("Find sector field {}, index = {}", m_cfg.sectorField, sector_idx); } - thresholdADC = m_cfg.thresholdFactor * m_cfg.pedSigmaADC + m_cfg.thresholdValue; - // TDC channels to timing conversion - stepTDC = dd4hep::ns / m_cfg.resolutionTDC; - - // do not get the layer/sector ID if no readout class provided - if (m_cfg.readout.empty()) { - return; + if (!m_cfg.layerField.empty()) { + layer_idx = id_dec->index(m_cfg.layerField); + debug("Find layer field {}, index = {}", m_cfg.layerField, sector_idx); } - - // First, try and get the IDDescriptor. This will throw an exception if it fails. - try { - id_spec = m_detector->readout(m_cfg.readout).idSpec(); - } catch(...) { - warning("Failed to get idSpec for {}", m_cfg.readout); - return; + if (!m_cfg.maskPosFields.empty()) { + size_t tmp_mask = 0; + for (auto& field : m_cfg.maskPosFields) { + tmp_mask |= id_spec.field(field)->mask(); + } + // assign this mask if all fields succeed + gpos_mask = tmp_mask; } - // Next, try and get the readout fields. This will throw a different exception. - try { - id_dec = id_spec.decoder(); - if (!m_cfg.sectorField.empty()) { - sector_idx = id_dec->index(m_cfg.sectorField); - debug("Find sector field {}, index = {}", m_cfg.sectorField, sector_idx); - } - if (!m_cfg.layerField.empty()) { - layer_idx = id_dec->index(m_cfg.layerField); - debug("Find layer field {}, index = {}", m_cfg.layerField, sector_idx); - } - if (!m_cfg.maskPosFields.empty()) { - size_t tmp_mask = 0; - for (auto &field : m_cfg.maskPosFields) { - tmp_mask |= id_spec.field(field)->mask(); - } - // assign this mask if all fields succeed - gpos_mask = tmp_mask; - } - } catch (...) { - if (!id_dec) { - warning("Failed to load ID decoder for {}", m_cfg.readout); - std::stringstream readouts; - for (auto r: m_detector->readouts()) readouts << "\"" << r.first << "\", "; - warning("Available readouts: {}", readouts.str() ); - } else { - warning("Failed to find field index for {}.", m_cfg.readout); - if (!m_cfg.sectorField.empty()) { warning(" -- looking for sector field \"{}\".", m_cfg.sectorField); } - if (!m_cfg.layerField.empty()) { warning(" -- looking for layer field \"{}\".", m_cfg.layerField); } - if (!m_cfg.maskPosFields.empty()) { - warning(" -- looking for masking fields \"{}\".", fmt::join(m_cfg.maskPosFields, ", ")); - } - std::stringstream fields; - for (auto field: id_spec.decoder()->fields()) fields << "\"" << field.name() << "\", "; - warning("Available fields: {}", fields.str() ); - warning("n.b. The local position, sector id and layer id will not be correct for this."); - warning("Position masking may not be applied."); - warning("however, the position, energy, and time values should still be good."); - } - - return; + } catch (...) { + if (!id_dec) { + warning("Failed to load ID decoder for {}", m_cfg.readout); + std::stringstream readouts; + for (auto r : m_detector->readouts()) + readouts << "\"" << r.first << "\", "; + warning("Available readouts: {}", readouts.str()); + } else { + warning("Failed to find field index for {}.", m_cfg.readout); + if (!m_cfg.sectorField.empty()) { + warning(" -- looking for sector field \"{}\".", m_cfg.sectorField); + } + if (!m_cfg.layerField.empty()) { + warning(" -- looking for layer field \"{}\".", m_cfg.layerField); + } + if (!m_cfg.maskPosFields.empty()) { + warning(" -- looking for masking fields \"{}\".", fmt::join(m_cfg.maskPosFields, ", ")); + } + std::stringstream fields; + for (auto field : id_spec.decoder()->fields()) + fields << "\"" << field.name() << "\", "; + warning("Available fields: {}", fields.str()); + warning("n.b. The local position, sector id and layer id will not be correct for this."); + warning("Position masking may not be applied."); + warning("however, the position, energy, and time values should still be good."); } - id_spec = m_detector->readout(m_cfg.readout).idSpec(); + return; + } - std::function hit_to_map = [this](const edm4hep::RawCalorimeterHit &h) { - std::unordered_map params; - for(const auto &p : id_spec.fields()) { - const std::string &name = p.first; - const dd4hep::IDDescriptor::Field* field = p.second; - params.emplace(name, field->value(h.getCellID())); - trace("{} = {}", name, field->value(h.getCellID())); - } - return params; - }; - - auto& serviceSvc = algorithms::ServiceSvc::instance(); - sampFrac = serviceSvc.service("EvaluatorSvc")->compile(m_cfg.sampFrac, hit_to_map); - - // local detector name has higher priority - if (!m_cfg.localDetElement.empty()) { - try { - m_local = m_detector->detector(m_cfg.localDetElement); - info("local coordinate system from DetElement {}", m_cfg.localDetElement); - } catch (...) { - error("failed to load local coordinate system from DetElement {}", m_cfg.localDetElement); - return; - } - } else { - std::vector > fields; - for (auto f : m_cfg.localDetFields) { - fields.emplace_back(f, 0); - } - local_mask = id_spec.get_mask(fields); - // use all fields if nothing provided - if (fields.empty()) { - local_mask = ~static_cast(0); - } - } -} + id_spec = m_detector->readout(m_cfg.readout).idSpec(); + std::function hit_to_map = [this](const edm4hep::RawCalorimeterHit& h) { + std::unordered_map params; + for (const auto& p : id_spec.fields()) { + const std::string& name = p.first; + const dd4hep::IDDescriptor::Field* field = p.second; + params.emplace(name, field->value(h.getCellID())); + trace("{} = {}", name, field->value(h.getCellID())); + } + return params; + }; -void CalorimeterHitReco::process( - const CalorimeterHitReco::Input& input, - const CalorimeterHitReco::Output& output) const { + auto& serviceSvc = algorithms::ServiceSvc::instance(); + sampFrac = serviceSvc.service("EvaluatorSvc")->compile(m_cfg.sampFrac, hit_to_map); - const auto [rawhits] = input; - auto [recohits] = output; + // local detector name has higher priority + if (!m_cfg.localDetElement.empty()) { + try { + m_local = m_detector->detector(m_cfg.localDetElement); + info("local coordinate system from DetElement {}", m_cfg.localDetElement); + } catch (...) { + error("failed to load local coordinate system from DetElement {}", m_cfg.localDetElement); + return; + } + } else { + std::vector> fields; + for (auto f : m_cfg.localDetFields) { + fields.emplace_back(f, 0); + } + local_mask = id_spec.get_mask(fields); + // use all fields if nothing provided + if (fields.empty()) { + local_mask = ~static_cast(0); + } + } +} - // For some detectors, the cellID in the raw hits may be broken - // (currently this is the HcalBarrel). In this case, dd4hep - // prints an error message and throws an exception. We catch - // the exception and handle it, but the screen gets flooded - // with these messages. Keep a count of these and if a max - // number is encountered disable this algorithm. A useful message - // indicating what is going on is printed below where the - // error is detector. - if (NcellIDerrors >= MaxCellIDerrors) return; +void CalorimeterHitReco::process(const CalorimeterHitReco::Input& input, + const CalorimeterHitReco::Output& output) const { + + const auto [rawhits] = input; + auto [recohits] = output; + + // For some detectors, the cellID in the raw hits may be broken + // (currently this is the HcalBarrel). In this case, dd4hep + // prints an error message and throws an exception. We catch + // the exception and handle it, but the screen gets flooded + // with these messages. Keep a count of these and if a max + // number is encountered disable this algorithm. A useful message + // indicating what is going on is printed below where the + // error is detector. + if (NcellIDerrors >= MaxCellIDerrors) + return; + + for (const auto& rh : *rawhits) { + + //did not pass the zero-suppresion threshold + const auto cellID = rh.getCellID(); + if (rh.getAmplitude() < m_cfg.pedMeanADC + thresholdADC) { + continue; + } - for (const auto &rh: *rawhits) { + if (rh.getAmplitude() > m_cfg.capADC) { + error("Encountered hit with amplitude {} outside of ADC capacity {}", rh.getAmplitude(), + m_cfg.capADC); + continue; + } - //did not pass the zero-suppresion threshold - const auto cellID = rh.getCellID(); - if (rh.getAmplitude() < m_cfg.pedMeanADC + thresholdADC) { - continue; + // get layer and sector ID + const int lid = id_dec != nullptr && !m_cfg.layerField.empty() + ? static_cast(id_dec->get(cellID, layer_idx)) + : -1; + const int sid = id_dec != nullptr && !m_cfg.sectorField.empty() + ? static_cast(id_dec->get(cellID, sector_idx)) + : -1; + + // convert ADC to energy + float sampFrac_value = sampFrac(rh); + float energy = (((signed)rh.getAmplitude() - (signed)m_cfg.pedMeanADC)) / + static_cast(m_cfg.capADC) * m_cfg.dyRangeADC / sampFrac_value; + + const float time = rh.getTimeStamp() / stepTDC; + trace("cellID {}, \t energy: {}, TDC: {}, time: {}, sampFrac: {}", cellID, energy, + rh.getTimeStamp(), time, sampFrac_value); + + dd4hep::DetElement local; + dd4hep::Position gpos; + try { + // global positions + gpos = m_converter->position(cellID); + + // masked position (look for a mother volume) + if (gpos_mask != 0) { + auto mpos = m_converter->position(cellID & ~gpos_mask); + // replace corresponding coords + for (const char& c : m_cfg.maskPos) { + switch (std::tolower(c)) { + case 'x': + gpos.SetX(mpos.X()); + break; + case 'y': + gpos.SetY(mpos.Y()); + break; + case 'z': + gpos.SetZ(mpos.Z()); + break; + default: + break; + } } + } - if (rh.getAmplitude() > m_cfg.capADC) { - error("Encountered hit with amplitude {} outside of ADC capacity {}", rh.getAmplitude(), m_cfg.capADC); - continue; - } + // local positions + if (m_cfg.localDetElement.empty()) { + auto volman = m_detector->volumeManager(); + local = volman.lookupDetElement(cellID & local_mask); + } else { + local = m_local; + } + } catch (...) { + // Error looking up cellID. Messages should already have been printed. + // Also, see comment at top of this method. + if (++NcellIDerrors >= MaxCellIDerrors) { + error("Maximum number of errors reached: {}", MaxCellIDerrors); + error("This is likely an issue with the cellID being unknown."); + error("Note: local_mask={:X} example cellID={:x}", local_mask, cellID); + error("Disabling this algorithm since it requires a valid cellID."); + error("(See {}:{})", __FILE__, __LINE__); + } + continue; + } - // get layer and sector ID - const int lid = - id_dec != nullptr && !m_cfg.layerField.empty() ? static_cast(id_dec->get(cellID, layer_idx)) : -1; - const int sid = - id_dec != nullptr && !m_cfg.sectorField.empty() ? static_cast(id_dec->get(cellID, sector_idx)) : -1; - - // convert ADC to energy - float sampFrac_value = sampFrac(rh); - float energy = (((signed) rh.getAmplitude() - (signed) m_cfg.pedMeanADC)) / static_cast(m_cfg.capADC) * m_cfg.dyRangeADC / - sampFrac_value; - - const float time = rh.getTimeStamp() / stepTDC; - trace("cellID {}, \t energy: {}, TDC: {}, time: {}, sampFrac: {}", cellID, energy, rh.getTimeStamp(), time, sampFrac_value); - - dd4hep::DetElement local; - dd4hep::Position gpos; - try { - // global positions - gpos = m_converter->position(cellID); - - // masked position (look for a mother volume) - if (gpos_mask != 0) { - auto mpos = m_converter->position(cellID & ~gpos_mask); - // replace corresponding coords - for (const char &c : m_cfg.maskPos) { - switch (std::tolower(c)) { - case 'x': - gpos.SetX(mpos.X()); - break; - case 'y': - gpos.SetY(mpos.Y()); - break; - case 'z': - gpos.SetZ(mpos.Z()); - break; - default: - break; - } - } - } - - // local positions - if (m_cfg.localDetElement.empty()) { - auto volman = m_detector->volumeManager(); - local = volman.lookupDetElement(cellID & local_mask); - } else { - local = m_local; - } - } catch (...) { - // Error looking up cellID. Messages should already have been printed. - // Also, see comment at top of this method. - if (++NcellIDerrors >= MaxCellIDerrors) { - error("Maximum number of errors reached: {}", MaxCellIDerrors); - error("This is likely an issue with the cellID being unknown."); - error("Note: local_mask={:X} example cellID={:x}", local_mask, cellID); - error("Disabling this algorithm since it requires a valid cellID."); - error("(See {}:{})", __FILE__,__LINE__); - } - continue; - } + const auto pos = local.nominal().worldToLocal(gpos); + std::vector cdim; + // get segmentation dimensions - const auto pos = local.nominal().worldToLocal(gpos); - std::vector cdim; - // get segmentation dimensions + const dd4hep::DDSegmentation::Segmentation* segmentation = + m_converter->findReadout(local).segmentation()->segmentation; + auto segmentation_type = segmentation->type(); - const dd4hep::DDSegmentation::Segmentation* segmentation = m_converter->findReadout(local).segmentation()->segmentation; - auto segmentation_type = segmentation->type(); + while (segmentation_type == "MultiSegmentation") { + const auto* multi_segmentation = + dynamic_cast(segmentation); + const dd4hep::DDSegmentation::Segmentation& sub_segmentation = + multi_segmentation->subsegmentation(cellID); - while (segmentation_type == "MultiSegmentation"){ - const auto* multi_segmentation = dynamic_cast(segmentation); - const dd4hep::DDSegmentation::Segmentation& sub_segmentation = multi_segmentation->subsegmentation(cellID); + segmentation = &sub_segmentation; + segmentation_type = segmentation->type(); + } - segmentation = &sub_segmentation; - segmentation_type = segmentation->type(); - } + if (segmentation_type == "CartesianGridXY" || segmentation_type == "HexGridXY") { + auto cell_dim = m_converter->cellDimensions(cellID); + cdim.resize(3); + cdim[0] = cell_dim[0]; + cdim[1] = cell_dim[1]; + debug("Using segmentation for cell dimensions: {}", fmt::join(cdim, ", ")); + } else { + if ((segmentation_type != "NoSegmentation") && (!warned_unsupported_segmentation)) { + warning("Unsupported segmentation type \"{}\"", segmentation_type); + warned_unsupported_segmentation = true; + } - if (segmentation_type == "CartesianGridXY" || segmentation_type == "HexGridXY") { - auto cell_dim = m_converter->cellDimensions(cellID); - cdim.resize(3); - cdim[0] = cell_dim[0]; - cdim[1] = cell_dim[1]; - debug("Using segmentation for cell dimensions: {}", fmt::join(cdim, ", ")); - } else { - if ((segmentation_type != "NoSegmentation") && (!warned_unsupported_segmentation)) { - warning("Unsupported segmentation type \"{}\"", segmentation_type); - warned_unsupported_segmentation = true; - } - - // Using bounding box instead of actual solid so the dimensions are always in dim_x, dim_y, dim_z - cdim = m_converter->findContext(cellID)->volumePlacement().volume().boundingBox().dimensions(); - std::transform(cdim.begin(), cdim.end(), cdim.begin(), - std::bind(std::multiplies(), std::placeholders::_1, 2)); - debug("Using bounding box for cell dimensions: {}", fmt::join(cdim, ", ")); - } + // Using bounding box instead of actual solid so the dimensions are always in dim_x, dim_y, dim_z + cdim = + m_converter->findContext(cellID)->volumePlacement().volume().boundingBox().dimensions(); + std::transform(cdim.begin(), cdim.end(), cdim.begin(), + std::bind(std::multiplies(), std::placeholders::_1, 2)); + debug("Using bounding box for cell dimensions: {}", fmt::join(cdim, ", ")); + } - //create constant vectors for passing to hit initializer list - //FIXME: needs to come from the geometry service/converter - const decltype(edm4eic::CalorimeterHitData::position) position(gpos.x() / dd4hep::mm, gpos.y() / dd4hep::mm, - gpos.z() / dd4hep::mm); - const decltype(edm4eic::CalorimeterHitData::dimension) dimension(cdim.at(0) / dd4hep::mm, cdim.at(1) / dd4hep::mm, - cdim.at(2) / dd4hep::mm); - const decltype(edm4eic::CalorimeterHitData::local) local_position(pos.x() / dd4hep::mm, pos.y() / dd4hep::mm, - pos.z() / dd4hep::mm); + //create constant vectors for passing to hit initializer list + //FIXME: needs to come from the geometry service/converter + const decltype(edm4eic::CalorimeterHitData::position) position( + gpos.x() / dd4hep::mm, gpos.y() / dd4hep::mm, gpos.z() / dd4hep::mm); + const decltype(edm4eic::CalorimeterHitData::dimension) dimension( + cdim.at(0) / dd4hep::mm, cdim.at(1) / dd4hep::mm, cdim.at(2) / dd4hep::mm); + const decltype(edm4eic::CalorimeterHitData::local) local_position( + pos.x() / dd4hep::mm, pos.y() / dd4hep::mm, pos.z() / dd4hep::mm); #if EDM4EIC_VERSION_MAJOR >= 7 - auto recohit = + auto recohit = #endif - recohits->create( - rh.getCellID(), - energy, - 0, - time, - 0, - position, - dimension, - sid, - lid, - local_position); + recohits->create(rh.getCellID(), energy, 0, time, 0, position, dimension, sid, lid, + local_position); #if EDM4EIC_VERSION_MAJOR >= 7 - recohit.setRawHit(rh); + recohit.setRawHit(rh); #endif - } + } } } // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterHitReco.h b/src/algorithms/calorimetry/CalorimeterHitReco.h index 44d37a9dd0..650f3e4415 100644 --- a/src/algorithms/calorimetry/CalorimeterHitReco.h +++ b/src/algorithms/calorimetry/CalorimeterHitReco.h @@ -29,54 +29,47 @@ namespace eicrecon { - using CalorimeterHitRecoAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4hep::RawCalorimeterHitCollection - >, - algorithms::Output< - edm4eic::CalorimeterHitCollection - > - >; - - class CalorimeterHitReco - : public CalorimeterHitRecoAlgorithm, - public WithPodConfig { - - public: - CalorimeterHitReco(std::string_view name) - : CalorimeterHitRecoAlgorithm{name, - {"inputRawHitCollection"}, - {"outputRecHitCollection"}, - "Reconstruct hit from digitized input."} {} +using CalorimeterHitRecoAlgorithm = + algorithms::Algorithm, + algorithms::Output>; - void init() final; - void process(const Input&, const Output&) const final; +class CalorimeterHitReco : public CalorimeterHitRecoAlgorithm, + public WithPodConfig { - private: +public: + CalorimeterHitReco(std::string_view name) + : CalorimeterHitRecoAlgorithm{name, + {"inputRawHitCollection"}, + {"outputRecHitCollection"}, + "Reconstruct hit from digitized input."} {} - // unitless counterparts of the input parameters - double thresholdADC{0}; - double stepTDC{0}; + void init() final; + void process(const Input&, const Output&) const final; - std::function sampFrac; +private: + // unitless counterparts of the input parameters + double thresholdADC{0}; + double stepTDC{0}; - dd4hep::IDDescriptor id_spec; - dd4hep::BitFieldCoder* id_dec = nullptr; + std::function sampFrac; - mutable uint32_t NcellIDerrors = 0; - uint32_t MaxCellIDerrors = 100; + dd4hep::IDDescriptor id_spec; + dd4hep::BitFieldCoder* id_dec = nullptr; - size_t sector_idx{0}, layer_idx{0}; + mutable uint32_t NcellIDerrors = 0; + uint32_t MaxCellIDerrors = 100; - mutable bool warned_unsupported_segmentation = false; + size_t sector_idx{0}, layer_idx{0}; - dd4hep::DetElement m_local; - size_t local_mask = ~static_cast(0), gpos_mask = static_cast(0); + mutable bool warned_unsupported_segmentation = false; - private: - const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; - const dd4hep::rec::CellIDPositionConverter* m_converter{algorithms::GeoSvc::instance().cellIDPositionConverter()}; + dd4hep::DetElement m_local; + size_t local_mask = ~static_cast(0), gpos_mask = static_cast(0); - }; +private: + const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; + const dd4hep::rec::CellIDPositionConverter* m_converter{ + algorithms::GeoSvc::instance().cellIDPositionConverter()}; +}; } // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterHitRecoConfig.h b/src/algorithms/calorimetry/CalorimeterHitRecoConfig.h index e9c2a0c729..55d7b8c806 100644 --- a/src/algorithms/calorimetry/CalorimeterHitRecoConfig.h +++ b/src/algorithms/calorimetry/CalorimeterHitRecoConfig.h @@ -8,34 +8,34 @@ namespace eicrecon { - struct CalorimeterHitRecoConfig { - - // digitization settings - unsigned int capADC{1}; - double dyRangeADC{1}; - unsigned int pedMeanADC{0}; - double pedSigmaADC{0}; - double resolutionTDC{1}; - double corrMeanScale{1}; - - // zero suppression - double thresholdFactor{0}; - double thresholdValue{0}; - - // sampling fraction - std::string sampFrac{"1.0"}; - - // readout fields - std::string readout{""}; - std::string layerField{""}; - std::string sectorField{""}; - - // name of detelment or fields to find the local detector (for global->local transform) - // if nothing is provided, the lowest level DetElement (from cellID) will be used - std::string localDetElement{""}; - std::vector localDetFields{}; - std::string maskPos{""}; - std::vector maskPosFields{}; - }; - -} // eicrecon +struct CalorimeterHitRecoConfig { + + // digitization settings + unsigned int capADC{1}; + double dyRangeADC{1}; + unsigned int pedMeanADC{0}; + double pedSigmaADC{0}; + double resolutionTDC{1}; + double corrMeanScale{1}; + + // zero suppression + double thresholdFactor{0}; + double thresholdValue{0}; + + // sampling fraction + std::string sampFrac{"1.0"}; + + // readout fields + std::string readout{""}; + std::string layerField{""}; + std::string sectorField{""}; + + // name of detelment or fields to find the local detector (for global->local transform) + // if nothing is provided, the lowest level DetElement (from cellID) will be used + std::string localDetElement{""}; + std::vector localDetFields{}; + std::string maskPos{""}; + std::vector maskPosFields{}; +}; + +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterHitsMerger.cc b/src/algorithms/calorimetry/CalorimeterHitsMerger.cc index f43b75cce4..d08526354c 100644 --- a/src/algorithms/calorimetry/CalorimeterHitsMerger.cc +++ b/src/algorithms/calorimetry/CalorimeterHitsMerger.cc @@ -37,148 +37,130 @@ namespace eicrecon { void CalorimeterHitsMerger::init() { - if (m_cfg.readout.empty()) { - error("readoutClass is not provided, it is needed to know the fields in readout ids"); - return; + if (m_cfg.readout.empty()) { + error("readoutClass is not provided, it is needed to know the fields in readout ids"); + return; + } + + // split parameters into vectors of fields + // and of transformations + std::vector fields; + std::vector transforms; + for (const std::string& field_transform : m_cfg.fieldTransformations) { + + const std::size_t isplit = field_transform.find_first_of(':'); + if (isplit == std::string::npos) { + warning("transform '{}' ill-formatted. Format is :.", field_transform); } - // split parameters into vectors of fields - // and of transformations - std::vector fields; - std::vector transforms; - for (const std::string& field_transform : m_cfg.fieldTransformations) { + fields.emplace_back(field_transform.substr(0, isplit)); + transforms.emplace_back(field_transform.substr(isplit + 1)); + } - const std::size_t isplit = field_transform.find_first_of(':'); - if (isplit == std::string::npos) { - warning("transform '{}' ill-formatted. Format is :.", field_transform); - } - - - fields.emplace_back( - field_transform.substr(0, isplit) - ); - transforms.emplace_back( - field_transform.substr(isplit + 1) - ); + // initialize descriptor + decoders + try { + id_desc = m_detector->readout(m_cfg.readout).idSpec(); + id_decoder = id_desc.decoder(); + for (const std::string& field : fields) { + const short index = id_decoder->index(field); } - - - // initialize descriptor + decoders - try { - id_desc = m_detector->readout(m_cfg.readout).idSpec(); - id_decoder = id_desc.decoder(); - for (const std::string& field : fields) { - const short index = id_decoder->index(field); - } - } catch (...) { - auto mess = fmt::format("Failed to load ID decoder for {}", m_cfg.readout); - warning(mess); -// throw std::runtime_error(mess); + } catch (...) { + auto mess = fmt::format("Failed to load ID decoder for {}", m_cfg.readout); + warning(mess); + // throw std::runtime_error(mess); + } + + // lambda to translate IDDescriptor fields into function parameters + std::function hit_transform = [this](const edm4eic::CalorimeterHit& hit) { + std::unordered_map params; + for (const auto& name_field : id_desc.fields()) { + params.emplace(name_field.first, name_field.second->value(hit.getCellID())); + trace("{} = {}", name_field.first, name_field.second->value(hit.getCellID())); } - - // lambda to translate IDDescriptor fields into function parameters - std::function hit_transform = [this](const edm4eic::CalorimeterHit& hit) { - std::unordered_map params; - for (const auto& name_field : id_desc.fields()) { - params.emplace(name_field.first, name_field.second->value(hit.getCellID())); - trace("{} = {}", name_field.first, name_field.second->value(hit.getCellID())); - } - return params; - }; - - // loop through provided readout fields - auto& svc = algorithms::ServiceSvc::instance(); - for (std::size_t iField = 0; std::string& field : fields) { - - // grab provided transformation and field - const std::string field_transform = transforms.at(iField); - auto name_field = id_desc.field(field); - - // set transformation for each field - ref_maps[field] = svc.service("EvaluatorSvc")->compile(field_transform, hit_transform); - trace("{}: using transformation '{}'", field, field_transform); - ++iField; - } // end field loop - + return params; + }; + + // loop through provided readout fields + auto& svc = algorithms::ServiceSvc::instance(); + for (std::size_t iField = 0; std::string & field : fields) { + + // grab provided transformation and field + const std::string field_transform = transforms.at(iField); + auto name_field = id_desc.field(field); + + // set transformation for each field + ref_maps[field] = + svc.service("EvaluatorSvc")->compile(field_transform, hit_transform); + trace("{}: using transformation '{}'", field, field_transform); + ++iField; + } // end field loop } -void CalorimeterHitsMerger::process( - const CalorimeterHitsMerger::Input& input, - const CalorimeterHitsMerger::Output& output) const { - - const auto [in_hits] = input; - auto [out_hits] = output; +void CalorimeterHitsMerger::process(const CalorimeterHitsMerger::Input& input, + const CalorimeterHitsMerger::Output& output) const { + + const auto [in_hits] = input; + auto [out_hits] = output; + + // find the hits that belong to the same group (for merging) + MergeMap merge_map; + build_merge_map(in_hits, merge_map); + debug("Merge map built: merging {} hits into {} merged hits", in_hits->size(), merge_map.size()); + + // sort hits by energy from large to small + for (auto& it : merge_map) { + std::sort(it.second.begin(), it.second.end(), [&](std::size_t ix1, std::size_t ix2) { + return (*in_hits)[ix1].getEnergy() > (*in_hits)[ix2].getEnergy(); + }); + } + + // reconstruct info for merged hits + // dd4hep decoders + auto volman = m_detector->volumeManager(); + + for (const auto& [id, ixs] : merge_map) { + // reference fields id + const uint64_t ref_id = id | ref_mask; + // global positions + const auto gpos = m_converter->position(ref_id); + // local positions + auto alignment = volman.lookupDetElement(ref_id).nominal(); + const auto pos = alignment.worldToLocal(dd4hep::Position(gpos.x(), gpos.y(), gpos.z())); + debug("{}, {}", volman.lookupDetElement(ref_id).path(), volman.lookupDetector(ref_id).path()); + // sum energy + float energy = 0.; + float energyError = 0.; + float time = 0; + float timeError = 0; + for (auto ix : ixs) { + auto hit = (*in_hits)[ix]; + energy += hit.getEnergy(); + energyError += hit.getEnergyError() * hit.getEnergyError(); + time += hit.getTime(); + timeError += hit.getTimeError() * hit.getTimeError(); + } + energyError = sqrt(energyError); + time /= ixs.size(); + timeError = sqrt(timeError) / ixs.size(); - // find the hits that belong to the same group (for merging) - MergeMap merge_map; - build_merge_map(in_hits, merge_map); - debug("Merge map built: merging {} hits into {} merged hits", in_hits->size(), merge_map.size()); + const auto href = (*in_hits)[ixs.front()]; - // sort hits by energy from large to small - for (auto &it : merge_map) { - std::sort(it.second.begin(), it.second.end(), [&](std::size_t ix1, std::size_t ix2) { - return (*in_hits)[ix1].getEnergy() > (*in_hits)[ix2].getEnergy(); - }); - } + // create const vectors for passing to hit initializer list + const decltype(edm4eic::CalorimeterHitData::position) position( + gpos.x() / dd4hep::mm, gpos.y() / dd4hep::mm, gpos.z() / dd4hep::mm); + const decltype(edm4eic::CalorimeterHitData::local) local( + pos.x() / dd4hep::mm, pos.y() / dd4hep::mm, pos.z() / dd4hep::mm); - // reconstruct info for merged hits - // dd4hep decoders - auto volman = m_detector->volumeManager(); - - for (const auto &[id, ixs] : merge_map) { - // reference fields id - const uint64_t ref_id = id | ref_mask; - // global positions - const auto gpos = m_converter->position(ref_id); - // local positions - auto alignment = volman.lookupDetElement(ref_id).nominal(); - const auto pos = alignment.worldToLocal(dd4hep::Position(gpos.x(), gpos.y(), gpos.z())); - debug("{}, {}", volman.lookupDetElement(ref_id).path(), volman.lookupDetector(ref_id).path()); - // sum energy - float energy = 0.; - float energyError = 0.; - float time = 0; - float timeError = 0; - for (auto ix : ixs) { - auto hit = (*in_hits)[ix]; - energy += hit.getEnergy(); - energyError += hit.getEnergyError() * hit.getEnergyError(); - time += hit.getTime(); - timeError += hit.getTimeError() * hit.getTimeError(); - } - energyError = sqrt(energyError); - time /= ixs.size(); - timeError = sqrt(timeError) / ixs.size(); - - const auto href = (*in_hits)[ixs.front()]; - - // create const vectors for passing to hit initializer list - const decltype(edm4eic::CalorimeterHitData::position) position( - gpos.x() / dd4hep::mm, gpos.y() / dd4hep::mm, gpos.z() / dd4hep::mm - ); - const decltype(edm4eic::CalorimeterHitData::local) local( - pos.x() / dd4hep::mm, pos.y() / dd4hep::mm, pos.z() / dd4hep::mm - ); - - out_hits->create( - href.getCellID(), - energy, - energyError, - time, - timeError, - position, - href.getDimension(), - href.getSector(), - href.getLayer(), - local); // Can do better here? Right now position is mapped on the central hit - } + out_hits->create(href.getCellID(), energy, energyError, time, timeError, position, + href.getDimension(), href.getSector(), href.getLayer(), + local); // Can do better here? Right now position is mapped on the central hit + } - debug("Size before = {}, after = {}", in_hits->size(), out_hits->size()); + debug("Size before = {}, after = {}", in_hits->size(), out_hits->size()); } -void CalorimeterHitsMerger::build_merge_map( - const edm4eic::CalorimeterHitCollection* in_hits, - MergeMap& merge_map) const { +void CalorimeterHitsMerger::build_merge_map(const edm4eic::CalorimeterHitCollection* in_hits, + MergeMap& merge_map) const { std::vector ref_fields; for (std::size_t iHit = 0; const auto& hit : *in_hits) { @@ -189,13 +171,10 @@ void CalorimeterHitsMerger::build_merge_map( // apply mapping to field if provided, // otherwise copy value of field if (ref_maps.count(name_field.first) > 0) { - ref_fields.push_back( - {name_field.first, ref_maps[name_field.first](hit)} - ); + ref_fields.push_back({name_field.first, ref_maps[name_field.first](hit)}); } else { ref_fields.push_back( - {name_field.first, id_decoder->get(hit.getCellID(), name_field.first)} - ); + {name_field.first, id_decoder->get(hit.getCellID(), name_field.first)}); } ++iField; } @@ -205,8 +184,8 @@ void CalorimeterHitsMerger::build_merge_map( merge_map[ref_id].push_back(iHit); ++iHit; - } // end hit loop + } // end hit loop -} // end 'build_merge_map(edm4eic::CalorimeterHitsCollection*, MergeMap&)' +} // end 'build_merge_map(edm4eic::CalorimeterHitsCollection*, MergeMap&)' } // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterHitsMerger.h b/src/algorithms/calorimetry/CalorimeterHitsMerger.h index 4de553e4a8..65c84bd2ef 100644 --- a/src/algorithms/calorimetry/CalorimeterHitsMerger.h +++ b/src/algorithms/calorimetry/CalorimeterHitsMerger.h @@ -33,49 +33,43 @@ namespace eicrecon { - // aliases for convenience - using MergeMap = std::unordered_map>; - using RefField = std::pair; - using MapFunc = std::function; +// aliases for convenience +using MergeMap = std::unordered_map>; +using RefField = std::pair; +using MapFunc = std::function; - using CalorimeterHitsMergerAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::CalorimeterHitCollection - >, - algorithms::Output< - edm4eic::CalorimeterHitCollection - > - >; +using CalorimeterHitsMergerAlgorithm = + algorithms::Algorithm, + algorithms::Output>; - class CalorimeterHitsMerger - : public CalorimeterHitsMergerAlgorithm, - public WithPodConfig { +class CalorimeterHitsMerger : public CalorimeterHitsMergerAlgorithm, + public WithPodConfig { - public: - CalorimeterHitsMerger(std::string_view name) +public: + CalorimeterHitsMerger(std::string_view name) : CalorimeterHitsMergerAlgorithm{name, - {"inputHitCollection"}, - {"outputHitCollection"}, - "Group readout hits from a calorimeter."} {} + {"inputHitCollection"}, + {"outputHitCollection"}, + "Group readout hits from a calorimeter."} {} - void init() final; - void process(const Input&, const Output&) const final; + void init() final; + void process(const Input&, const Output&) const final; - private: - uint64_t ref_mask{0}; +private: + uint64_t ref_mask{0}; - private: - mutable std::map ref_maps; - dd4hep::IDDescriptor id_desc; - dd4hep::BitFieldCoder* id_decoder; +private: + mutable std::map ref_maps; + dd4hep::IDDescriptor id_desc; + dd4hep::BitFieldCoder* id_decoder; - private: - const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; - const dd4hep::rec::CellIDPositionConverter* m_converter{algorithms::GeoSvc::instance().cellIDPositionConverter()}; +private: + const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; + const dd4hep::rec::CellIDPositionConverter* m_converter{ + algorithms::GeoSvc::instance().cellIDPositionConverter()}; - private: - void build_merge_map(const edm4eic::CalorimeterHitCollection* in_hits, MergeMap& merge_map) const; - - }; +private: + void build_merge_map(const edm4eic::CalorimeterHitCollection* in_hits, MergeMap& merge_map) const; +}; } // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterHitsMergerConfig.h b/src/algorithms/calorimetry/CalorimeterHitsMergerConfig.h index bb644b6eac..ae9a80adb8 100644 --- a/src/algorithms/calorimetry/CalorimeterHitsMergerConfig.h +++ b/src/algorithms/calorimetry/CalorimeterHitsMergerConfig.h @@ -8,11 +8,10 @@ namespace eicrecon { - struct CalorimeterHitsMergerConfig { +struct CalorimeterHitsMergerConfig { - std::string readout{""}; - std::vector fieldTransformations{}; + std::string readout{""}; + std::vector fieldTransformations{}; +}; - }; - -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterIslandCluster.cc b/src/algorithms/calorimetry/CalorimeterIslandCluster.cc index 06aa4b811c..dddc2d7226 100644 --- a/src/algorithms/calorimetry/CalorimeterIslandCluster.cc +++ b/src/algorithms/calorimetry/CalorimeterIslandCluster.cc @@ -30,50 +30,40 @@ using namespace edm4eic; namespace eicrecon { -static double Phi_mpi_pi(double phi) { - return std::remainder(phi, 2 * M_PI); -} +static double Phi_mpi_pi(double phi) { return std::remainder(phi, 2 * M_PI); } -static edm4hep::Vector2f localDistXY(const CaloHit &h1, const CaloHit &h2) { - const auto delta =h1.getLocal() - h2.getLocal(); +static edm4hep::Vector2f localDistXY(const CaloHit& h1, const CaloHit& h2) { + const auto delta = h1.getLocal() - h2.getLocal(); return {delta.x, delta.y}; } -static edm4hep::Vector2f localDistXZ(const CaloHit &h1, const CaloHit &h2) { +static edm4hep::Vector2f localDistXZ(const CaloHit& h1, const CaloHit& h2) { const auto delta = h1.getLocal() - h2.getLocal(); return {delta.x, delta.z}; } -static edm4hep::Vector2f localDistYZ(const CaloHit &h1, const CaloHit &h2) { +static edm4hep::Vector2f localDistYZ(const CaloHit& h1, const CaloHit& h2) { const auto delta = h1.getLocal() - h2.getLocal(); return {delta.y, delta.z}; } -static edm4hep::Vector2f dimScaledLocalDistXY(const CaloHit &h1, const CaloHit &h2) { +static edm4hep::Vector2f dimScaledLocalDistXY(const CaloHit& h1, const CaloHit& h2) { const auto delta = h1.getLocal() - h2.getLocal(); const auto dimsum = h1.getDimension() + h2.getDimension(); return {2 * delta.x / dimsum.x, 2 * delta.y / dimsum.y}; } -static edm4hep::Vector2f globalDistRPhi(const CaloHit &h1, const CaloHit &h2) { +static edm4hep::Vector2f globalDistRPhi(const CaloHit& h1, const CaloHit& h2) { using vector_type = decltype(edm4hep::Vector2f::a); - return { - static_cast( - edm4hep::utils::magnitude(h1.getPosition()) - edm4hep::utils::magnitude(h2.getPosition()) - ), - static_cast( - Phi_mpi_pi(edm4hep::utils::angleAzimuthal(h1.getPosition()) - edm4hep::utils::angleAzimuthal(h2.getPosition())) - ) - }; + return {static_cast(edm4hep::utils::magnitude(h1.getPosition()) - + edm4hep::utils::magnitude(h2.getPosition())), + static_cast(Phi_mpi_pi(edm4hep::utils::angleAzimuthal(h1.getPosition()) - + edm4hep::utils::angleAzimuthal(h2.getPosition())))}; } -static edm4hep::Vector2f globalDistEtaPhi(const CaloHit &h1, const CaloHit &h2) { +static edm4hep::Vector2f globalDistEtaPhi(const CaloHit& h1, const CaloHit& h2) { using vector_type = decltype(edm4hep::Vector2f::a); - return { - static_cast( - edm4hep::utils::eta(h1.getPosition()) - edm4hep::utils::eta(h2.getPosition()) - ), - static_cast( - Phi_mpi_pi(edm4hep::utils::angleAzimuthal(h1.getPosition()) - edm4hep::utils::angleAzimuthal(h2.getPosition())) - ) - }; + return {static_cast(edm4hep::utils::eta(h1.getPosition()) - + edm4hep::utils::eta(h2.getPosition())), + static_cast(Phi_mpi_pi(edm4hep::utils::angleAzimuthal(h1.getPosition()) - + edm4hep::utils::angleAzimuthal(h2.getPosition())))}; } //------------------------ @@ -81,163 +71,175 @@ static edm4hep::Vector2f globalDistEtaPhi(const CaloHit &h1, const CaloHit &h2) //------------------------ void CalorimeterIslandCluster::init() { - static std::map, std::vector>> - distMethods{ - {"localDistXY", {localDistXY, {dd4hep::mm, dd4hep::mm}}}, {"localDistXZ", {localDistXZ, {dd4hep::mm, dd4hep::mm}}}, - {"localDistYZ", {localDistYZ, {dd4hep::mm, dd4hep::mm}}}, {"dimScaledLocalDistXY", {dimScaledLocalDistXY, {1., 1.}}}, - {"globalDistRPhi", {globalDistRPhi, {dd4hep::mm, dd4hep::rad}}}, {"globalDistEtaPhi", {globalDistEtaPhi, {1., dd4hep::rad}}} - }; - - - // set coordinate system - auto set_dist_method = [this](std::pair> uprop) { - if (uprop.second.size() == 0) { - return false; - } - auto& [method, units] = distMethods[uprop.first]; - if (uprop.second.size() != units.size()) { - warning("Expect {} values from {}, received {}. ignored it.", units.size(), uprop.first, uprop.second.size()); - return false; - } else { - for (size_t i = 0; i < units.size(); ++i) { - neighbourDist[i] = uprop.second[i] / units[i]; - } - hitsDist = method; - info("Clustering uses {} with distances <= [{}]", uprop.first, fmt::join(neighbourDist, ",")); - } - return true; - }; - - std::vector>> uprops{ - {"localDistXY", m_cfg.localDistXY}, - {"localDistXZ", m_cfg.localDistXZ}, - {"localDistYZ", m_cfg.localDistYZ}, - {"globalDistRPhi", m_cfg.globalDistRPhi}, - {"globalDistEtaPhi", m_cfg.globalDistEtaPhi}, - // default one should be the last one - {"dimScaledLocalDistXY", m_cfg.dimScaledLocalDistXY} - }; - - auto& serviceSvc = algorithms::ServiceSvc::instance(); - - std::function hit_pair_to_map = [this](const edm4eic::CalorimeterHit &h1, const edm4eic::CalorimeterHit &h2) { - std::unordered_map params; - for(const auto &p : m_idSpec.fields()) { - const std::string &name = p.first; - const dd4hep::IDDescriptor::Field* field = p.second; - params.emplace(name + "_1", field->value(h1.getCellID())); - params.emplace(name + "_2", field->value(h2.getCellID())); - trace("{}_1 = {}", name, field->value(h1.getCellID())); - trace("{}_2 = {}", name, field->value(h2.getCellID())); - } - return params; - }; - - if (m_cfg.readout.empty()) { - if ((!m_cfg.adjacencyMatrix.empty()) || (!m_cfg.peakNeighbourhoodMatrix.empty())) { - throw std::runtime_error("'readout' is not provided, it is needed to know the fields in readout ids"); - } + static std::map, + std::vector>> + distMethods{{"localDistXY", {localDistXY, {dd4hep::mm, dd4hep::mm}}}, + {"localDistXZ", {localDistXZ, {dd4hep::mm, dd4hep::mm}}}, + {"localDistYZ", {localDistYZ, {dd4hep::mm, dd4hep::mm}}}, + {"dimScaledLocalDistXY", {dimScaledLocalDistXY, {1., 1.}}}, + {"globalDistRPhi", {globalDistRPhi, {dd4hep::mm, dd4hep::rad}}}, + {"globalDistEtaPhi", {globalDistEtaPhi, {1., dd4hep::rad}}}}; + + // set coordinate system + auto set_dist_method = [this](std::pair> uprop) { + if (uprop.second.size() == 0) { + return false; + } + auto& [method, units] = distMethods[uprop.first]; + if (uprop.second.size() != units.size()) { + warning("Expect {} values from {}, received {}. ignored it.", units.size(), uprop.first, + uprop.second.size()); + return false; } else { - m_idSpec = m_detector->readout(m_cfg.readout).idSpec(); + for (size_t i = 0; i < units.size(); ++i) { + neighbourDist[i] = uprop.second[i] / units[i]; + } + hitsDist = method; + info("Clustering uses {} with distances <= [{}]", uprop.first, fmt::join(neighbourDist, ",")); } + return true; + }; - bool method_found = false; - - // Adjacency matrix methods - if (!m_cfg.adjacencyMatrix.empty()) { - is_neighbour = serviceSvc.service("EvaluatorSvc")->compile(m_cfg.adjacencyMatrix, hit_pair_to_map); - method_found = true; + std::vector>> uprops{ + {"localDistXY", m_cfg.localDistXY}, + {"localDistXZ", m_cfg.localDistXZ}, + {"localDistYZ", m_cfg.localDistYZ}, + {"globalDistRPhi", m_cfg.globalDistRPhi}, + {"globalDistEtaPhi", m_cfg.globalDistEtaPhi}, + // default one should be the last one + {"dimScaledLocalDistXY", m_cfg.dimScaledLocalDistXY}}; + + auto& serviceSvc = algorithms::ServiceSvc::instance(); + + std::function hit_pair_to_map = [this](const edm4eic::CalorimeterHit& h1, + const edm4eic::CalorimeterHit& h2) { + std::unordered_map params; + for (const auto& p : m_idSpec.fields()) { + const std::string& name = p.first; + const dd4hep::IDDescriptor::Field* field = p.second; + params.emplace(name + "_1", field->value(h1.getCellID())); + params.emplace(name + "_2", field->value(h2.getCellID())); + trace("{}_1 = {}", name, field->value(h1.getCellID())); + trace("{}_2 = {}", name, field->value(h2.getCellID())); } + return params; + }; - // Coordinate distance methods - if (not method_found) { - for (auto& uprop : uprops) { - if (set_dist_method(uprop)) { - method_found = true; - - is_neighbour = [this](const CaloHit &h1, const CaloHit &h2) { - // in the same sector - if (h1.getSector() == h2.getSector()) { - auto dist = hitsDist(h1, h2); - return (fabs(dist.a) <= neighbourDist[0]) && (fabs(dist.b) <= neighbourDist[1]); - // different sector, local coordinates do not work, using global coordinates - } else { - // sector may have rotation (barrel), so z is included - // (EDM4hep units are mm, so convert sectorDist to mm) - return (edm4hep::utils::magnitude(h1.getPosition() - h2.getPosition()) <= m_cfg.sectorDist / dd4hep::mm); - } - }; - - break; - } + if (m_cfg.readout.empty()) { + if ((!m_cfg.adjacencyMatrix.empty()) || (!m_cfg.peakNeighbourhoodMatrix.empty())) { + throw std::runtime_error( + "'readout' is not provided, it is needed to know the fields in readout ids"); + } + } else { + m_idSpec = m_detector->readout(m_cfg.readout).idSpec(); + } + + bool method_found = false; + + // Adjacency matrix methods + if (!m_cfg.adjacencyMatrix.empty()) { + is_neighbour = serviceSvc.service("EvaluatorSvc") + ->compile(m_cfg.adjacencyMatrix, hit_pair_to_map); + method_found = true; + } + + // Coordinate distance methods + if (not method_found) { + for (auto& uprop : uprops) { + if (set_dist_method(uprop)) { + method_found = true; + + is_neighbour = [this](const CaloHit& h1, const CaloHit& h2) { + // in the same sector + if (h1.getSector() == h2.getSector()) { + auto dist = hitsDist(h1, h2); + return (fabs(dist.a) <= neighbourDist[0]) && (fabs(dist.b) <= neighbourDist[1]); + // different sector, local coordinates do not work, using global coordinates + } else { + // sector may have rotation (barrel), so z is included + // (EDM4hep units are mm, so convert sectorDist to mm) + return (edm4hep::utils::magnitude(h1.getPosition() - h2.getPosition()) <= + m_cfg.sectorDist / dd4hep::mm); + } + }; + + break; } } + } - if (not method_found) { - throw std::runtime_error("Cannot determine the clustering coordinates"); - } + if (not method_found) { + throw std::runtime_error("Cannot determine the clustering coordinates"); + } - if (m_cfg.splitCluster) { - if (!m_cfg.peakNeighbourhoodMatrix.empty()) { - is_maximum_neighbourhood = serviceSvc.service("EvaluatorSvc")->compile(m_cfg.peakNeighbourhoodMatrix, hit_pair_to_map); - } else { - is_maximum_neighbourhood = is_neighbour; - } + if (m_cfg.splitCluster) { + if (!m_cfg.peakNeighbourhoodMatrix.empty()) { + is_maximum_neighbourhood = serviceSvc.service("EvaluatorSvc") + ->compile(m_cfg.peakNeighbourhoodMatrix, hit_pair_to_map); + } else { + is_maximum_neighbourhood = is_neighbour; + } - auto transverseEnergyProfileMetric_it = std::find_if(distMethods.begin(), distMethods.end(), [&](auto &p) { return m_cfg.transverseEnergyProfileMetric == p.first; }); - if (transverseEnergyProfileMetric_it == distMethods.end()) { - throw std::runtime_error(fmt::format("Unsupported value \"{}\" for \"transverseEnergyProfileMetric\"", m_cfg.transverseEnergyProfileMetric)); - } - transverseEnergyProfileMetric = std::get<0>(transverseEnergyProfileMetric_it->second); - std::vector &units = std::get<1>(transverseEnergyProfileMetric_it->second); - for (auto unit : units) { - if (unit != units[0]) { - throw std::runtime_error(fmt::format("Metric {} has incompatible dimension units", m_cfg.transverseEnergyProfileMetric)); - } + auto transverseEnergyProfileMetric_it = + std::find_if(distMethods.begin(), distMethods.end(), + [&](auto& p) { return m_cfg.transverseEnergyProfileMetric == p.first; }); + if (transverseEnergyProfileMetric_it == distMethods.end()) { + throw std::runtime_error( + fmt::format("Unsupported value \"{}\" for \"transverseEnergyProfileMetric\"", + m_cfg.transverseEnergyProfileMetric)); + } + transverseEnergyProfileMetric = std::get<0>(transverseEnergyProfileMetric_it->second); + std::vector& units = std::get<1>(transverseEnergyProfileMetric_it->second); + for (auto unit : units) { + if (unit != units[0]) { + throw std::runtime_error(fmt::format("Metric {} has incompatible dimension units", + m_cfg.transverseEnergyProfileMetric)); } - transverseEnergyProfileScaleUnits = units[0]; } + transverseEnergyProfileScaleUnits = units[0]; + } - return; + return; } +void CalorimeterIslandCluster::process(const CalorimeterIslandCluster::Input& input, + const CalorimeterIslandCluster::Output& output) const { -void CalorimeterIslandCluster::process( - const CalorimeterIslandCluster::Input& input, - const CalorimeterIslandCluster::Output& output) const { - - const auto [hits] = input; - auto [proto_clusters] = output; + const auto [hits] = input; + auto [proto_clusters] = output; - // group neighboring hits - std::vector> groups; + // group neighboring hits + std::vector> groups; - std::vector visits(hits->size(), false); - for (size_t i = 0; i < hits->size(); ++i) { + std::vector visits(hits->size(), false); + for (size_t i = 0; i < hits->size(); ++i) { - { - const auto& hit = (*hits)[i]; - debug("hit {:d}: energy = {:.4f} MeV, local = ({:.4f}, {:.4f}) mm, global=({:.4f}, {:.4f}, {:.4f}) mm", i, hit.getEnergy() * 1000., hit.getLocal().x, hit.getLocal().y, hit.getPosition().x, hit.getPosition().y, hit.getPosition().z); - } - // already in a group - if (visits[i]) { - continue; - } - groups.emplace_back(); - // create a new group, and group all the neighboring hits - bfs_group(*hits, groups.back(), i, visits); + { + const auto& hit = (*hits)[i]; + debug("hit {:d}: energy = {:.4f} MeV, local = ({:.4f}, {:.4f}) mm, global=({:.4f}, {:.4f}, " + "{:.4f}) mm", + i, hit.getEnergy() * 1000., hit.getLocal().x, hit.getLocal().y, hit.getPosition().x, + hit.getPosition().y, hit.getPosition().z); } - - for (auto& group : groups) { - if (group.empty()) { - continue; - } - auto maxima = find_maxima(*hits, group, !m_cfg.splitCluster); - split_group(*hits, group, maxima, proto_clusters); - - debug("hits in a group: {}, local maxima: {}", group.size(), maxima.size()); + // already in a group + if (visits[i]) { + continue; + } + groups.emplace_back(); + // create a new group, and group all the neighboring hits + bfs_group(*hits, groups.back(), i, visits); + } + + for (auto& group : groups) { + if (group.empty()) { + continue; } + auto maxima = find_maxima(*hits, group, !m_cfg.splitCluster); + split_group(*hits, group, maxima, proto_clusters); + + debug("hits in a group: {}, local maxima: {}", group.size(), maxima.size()); + } } } // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterIslandCluster.h b/src/algorithms/calorimetry/CalorimeterIslandCluster.h index f70d469f0a..3e844797cb 100644 --- a/src/algorithms/calorimetry/CalorimeterIslandCluster.h +++ b/src/algorithms/calorimetry/CalorimeterIslandCluster.h @@ -27,90 +27,85 @@ namespace eicrecon { - using CaloHit = edm4eic::CalorimeterHit; - - using CalorimeterIslandClusterAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::CalorimeterHitCollection - >, - algorithms::Output< - edm4eic::ProtoClusterCollection - > - >; - - class CalorimeterIslandCluster - : public CalorimeterIslandClusterAlgorithm, - public WithPodConfig { - - public: - CalorimeterIslandCluster(std::string_view name) - : CalorimeterIslandClusterAlgorithm{name, - {"inputProtoClusterCollection"}, - {"outputClusterCollection"}, - "Island clustering."} {} +using CaloHit = edm4eic::CalorimeterHit; - void init() final; - void process(const Input&, const Output&) const final; +using CalorimeterIslandClusterAlgorithm = + algorithms::Algorithm, + algorithms::Output>; - private: - const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; +class CalorimeterIslandCluster : public CalorimeterIslandClusterAlgorithm, + public WithPodConfig { - public: +public: + CalorimeterIslandCluster(std::string_view name) + : CalorimeterIslandClusterAlgorithm{name, + {"inputProtoClusterCollection"}, + {"outputClusterCollection"}, + "Island clustering."} {} - // neighbor checking function - std::function hitsDist; + void init() final; + void process(const Input&, const Output&) const final; - std::function transverseEnergyProfileMetric; - double u_transverseEnergyProfileScale; - double transverseEnergyProfileScaleUnits; +private: + const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; - // helper function to group hits - std::function is_neighbour; +public: + // neighbor checking function + std::function hitsDist; - // helper function to define hit maximum - std::function is_maximum_neighbourhood; + std::function + transverseEnergyProfileMetric; + double u_transverseEnergyProfileScale; + double transverseEnergyProfileScaleUnits; - // unitless counterparts of the input parameters - std::array neighbourDist; + // helper function to group hits + std::function is_neighbour; - // Pointer to the geometry service - dd4hep::IDDescriptor m_idSpec; + // helper function to define hit maximum + std::function is_maximum_neighbourhood; - private: + // unitless counterparts of the input parameters + std::array neighbourDist; - // grouping function with Breadth-First Search - void bfs_group(const edm4eic::CalorimeterHitCollection &hits, std::set &group, std::size_t idx, std::vector &visits) const { - visits[idx] = true; + // Pointer to the geometry service + dd4hep::IDDescriptor m_idSpec; - // not a qualified hit to participate clustering, stop here - if (hits[idx].getEnergy() < m_cfg.minClusterHitEdep) { - return; - } +private: + // grouping function with Breadth-First Search + void bfs_group(const edm4eic::CalorimeterHitCollection& hits, std::set& group, + std::size_t idx, std::vector& visits) const { + visits[idx] = true; + + // not a qualified hit to participate clustering, stop here + if (hits[idx].getEnergy() < m_cfg.minClusterHitEdep) { + return; + } - group.insert(idx); - size_t prev_size = 0; - - while (prev_size != group.size()) { - prev_size = group.size(); - for (std::size_t idx1 : group) { - // check neighbours - for (std::size_t idx2 = 0; idx2 < hits.size(); ++idx2) { - // not a qualified hit to participate clustering, skip - if (hits[idx2].getEnergy() < m_cfg.minClusterHitEdep) { - continue; - } - if ((!visits[idx2]) - && is_neighbour(hits[idx1], hits[idx2])) { - group.insert(idx2); - visits[idx2] = true; - } + group.insert(idx); + size_t prev_size = 0; + + while (prev_size != group.size()) { + prev_size = group.size(); + for (std::size_t idx1 : group) { + // check neighbours + for (std::size_t idx2 = 0; idx2 < hits.size(); ++idx2) { + // not a qualified hit to participate clustering, skip + if (hits[idx2].getEnergy() < m_cfg.minClusterHitEdep) { + continue; + } + if ((!visits[idx2]) && is_neighbour(hits[idx1], hits[idx2])) { + group.insert(idx2); + visits[idx2] = true; } } } } + } - // find local maxima that above a certain threshold - std::vector find_maxima(const edm4eic::CalorimeterHitCollection &hits, const std::set &group, bool global = false) const { + // find local maxima that above a certain threshold + std::vector find_maxima(const edm4eic::CalorimeterHitCollection& hits, + const std::set& group, + bool global = false) const { std::vector maxima; if (group.empty()) { return maxima; @@ -141,7 +136,8 @@ namespace eicrecon { continue; } - if (is_maximum_neighbourhood(hits[idx1], hits[idx2]) && (hits[idx2].getEnergy() > hits[idx1].getEnergy())) { + if (is_maximum_neighbourhood(hits[idx1], hits[idx2]) && + (hits[idx2].getEnergy() > hits[idx1].getEnergy())) { maximum = false; break; } @@ -154,20 +150,22 @@ namespace eicrecon { return maxima; } - // helper function - inline static void vec_normalize(std::vector& vals) { - double total = 0.; - for (auto& val : vals) { - total += val; - } - for (auto& val : vals) { - val /= total; - } + // helper function + inline static void vec_normalize(std::vector& vals) { + double total = 0.; + for (auto& val : vals) { + total += val; + } + for (auto& val : vals) { + val /= total; } + } - // split a group of hits according to the local maxima - //TODO: confirm protoclustering without protoclustercollection - void split_group(const edm4eic::CalorimeterHitCollection &hits, std::set& group, const std::vector& maxima, edm4eic::ProtoClusterCollection *protoClusters) const { + // split a group of hits according to the local maxima + //TODO: confirm protoclustering without protoclustercollection + void split_group(const edm4eic::CalorimeterHitCollection& hits, std::set& group, + const std::vector& maxima, + edm4eic::ProtoClusterCollection* protoClusters) const { // special cases if (maxima.empty()) { debug("No maxima found, not building any clusters"); @@ -196,9 +194,12 @@ namespace eicrecon { size_t j = 0; // calculate weights for local maxima for (std::size_t cidx : maxima) { - double energy = hits[cidx].getEnergy(); - double dist = edm4hep::utils::magnitude(transverseEnergyProfileMetric(hits[cidx], hits[idx])); - weights[j] = std::exp(-dist * transverseEnergyProfileScaleUnits / m_cfg.transverseEnergyProfileScale) * energy; + double energy = hits[cidx].getEnergy(); + double dist = + edm4hep::utils::magnitude(transverseEnergyProfileMetric(hits[cidx], hits[idx])); + weights[j] = std::exp(-dist * transverseEnergyProfileScaleUnits / + m_cfg.transverseEnergyProfileScale) * + energy; j += 1; } diff --git a/src/algorithms/calorimetry/CalorimeterIslandClusterConfig.h b/src/algorithms/calorimetry/CalorimeterIslandClusterConfig.h index eae2433769..734d9ee531 100644 --- a/src/algorithms/calorimetry/CalorimeterIslandClusterConfig.h +++ b/src/algorithms/calorimetry/CalorimeterIslandClusterConfig.h @@ -7,29 +7,28 @@ namespace eicrecon { - struct CalorimeterIslandClusterConfig { - - std::string adjacencyMatrix; - std::string peakNeighbourhoodMatrix; - std::string readout; - - // neighbour checking distances - double sectorDist; - std::vector localDistXY; - std::vector localDistXZ; - std::vector localDistYZ; - std::vector globalDistRPhi; - std::vector globalDistEtaPhi; - std::vector dimScaledLocalDistXY; - - bool splitCluster{false}; - double minClusterHitEdep; - double minClusterCenterEdep; - - std::string transverseEnergyProfileMetric; - double transverseEnergyProfileScale; - double transverseEnergyProfileScaleUnits; - - }; - -} // eicrecon +struct CalorimeterIslandClusterConfig { + + std::string adjacencyMatrix; + std::string peakNeighbourhoodMatrix; + std::string readout; + + // neighbour checking distances + double sectorDist; + std::vector localDistXY; + std::vector localDistXZ; + std::vector localDistYZ; + std::vector globalDistRPhi; + std::vector globalDistEtaPhi; + std::vector dimScaledLocalDistXY; + + bool splitCluster{false}; + double minClusterHitEdep; + double minClusterCenterEdep; + + std::string transverseEnergyProfileMetric; + double transverseEnergyProfileScale; + double transverseEnergyProfileScaleUnits; +}; + +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterTruthClustering.cc b/src/algorithms/calorimetry/CalorimeterTruthClustering.cc index c02b54243b..915791222b 100644 --- a/src/algorithms/calorimetry/CalorimeterTruthClustering.cc +++ b/src/algorithms/calorimetry/CalorimeterTruthClustering.cc @@ -16,67 +16,64 @@ using namespace dd4hep; namespace eicrecon { - void CalorimeterTruthClustering::init() { } +void CalorimeterTruthClustering::init() {} +void CalorimeterTruthClustering::process(const CalorimeterTruthClustering::Input& input, + const CalorimeterTruthClustering::Output& output) const { + const auto [hits, mc] = input; + auto [clusters] = output; - void CalorimeterTruthClustering::process( - const CalorimeterTruthClustering::Input& input, - const CalorimeterTruthClustering::Output& output) const { - const auto [hits, mc] = input; - auto [clusters] = output; + // Map mc track ID to protoCluster index + std::map protoIndex; - // Map mc track ID to protoCluster index - std::map protoIndex; - - // Loop over all calorimeter hits and sort per mcparticle - for (const auto& hit : *hits) { - // The original algorithm used the following to get the mcHit: - // - // const auto& mcHit = mc[hit->getObjectID().index]; - // - // This assumes there is a one-to-one relation between the truth hit - // (hits) and the reconstructed hit (mc). At least insofar as the - // index in "hits" is being used to index the "mc" container. - // - // If the objects in "hits" have not been added to a collection, - // then they will have getObjectID().index = "untracked" = -1 - // - // The way we handle this is here is to check if getObjectID().index - // is within the size limits of mc which includes >=0. If so, then - // assume the old code is valid. If not, then we need to search - // for the right hit. - // FIXME: This is clearly not the right way to do this! Podio needs - // FIXME: to be fixed so proper object tracking can be done without - // FIXME: requiring Collection classes be used to manage all objects. - std::size_t mcIndex; - if ((hit.getObjectID().index >= 0) && (hit.getObjectID().index < mc->size())) { - mcIndex = hit.getObjectID().index; - } else { - mcIndex = 0; - bool success = false; - for (auto tmpmc : *mc) { - if (tmpmc.getCellID() == hit.getCellID()) { - success = true; - break; - } - mcIndex++; - } - if (not success) { - continue; // ignore hit if we couldn't match it to truth hit - } - } - - const auto &trackID = (*mc)[mcIndex].getContributions(0).getParticle().getObjectID().index; - // Create a new protocluster if we don't have one for this trackID - if (protoIndex.count(trackID) == 0) { - clusters->create(); - protoIndex[trackID] = clusters->size() - 1; + // Loop over all calorimeter hits and sort per mcparticle + for (const auto& hit : *hits) { + // The original algorithm used the following to get the mcHit: + // + // const auto& mcHit = mc[hit->getObjectID().index]; + // + // This assumes there is a one-to-one relation between the truth hit + // (hits) and the reconstructed hit (mc). At least insofar as the + // index in "hits" is being used to index the "mc" container. + // + // If the objects in "hits" have not been added to a collection, + // then they will have getObjectID().index = "untracked" = -1 + // + // The way we handle this is here is to check if getObjectID().index + // is within the size limits of mc which includes >=0. If so, then + // assume the old code is valid. If not, then we need to search + // for the right hit. + // FIXME: This is clearly not the right way to do this! Podio needs + // FIXME: to be fixed so proper object tracking can be done without + // FIXME: requiring Collection classes be used to manage all objects. + std::size_t mcIndex; + if ((hit.getObjectID().index >= 0) && (hit.getObjectID().index < mc->size())) { + mcIndex = hit.getObjectID().index; + } else { + mcIndex = 0; + bool success = false; + for (auto tmpmc : *mc) { + if (tmpmc.getCellID() == hit.getCellID()) { + success = true; + break; } - // Add hit to the appropriate protocluster - (*clusters)[protoIndex[trackID]].addToHits(hit); - (*clusters)[protoIndex[trackID]].addToWeights(1); + mcIndex++; + } + if (not success) { + continue; // ignore hit if we couldn't match it to truth hit + } } + const auto& trackID = (*mc)[mcIndex].getContributions(0).getParticle().getObjectID().index; + // Create a new protocluster if we don't have one for this trackID + if (protoIndex.count(trackID) == 0) { + clusters->create(); + protoIndex[trackID] = clusters->size() - 1; + } + // Add hit to the appropriate protocluster + (*clusters)[protoIndex[trackID]].addToHits(hit); + (*clusters)[protoIndex[trackID]].addToWeights(1); } +} } // namespace eicrecon diff --git a/src/algorithms/calorimetry/CalorimeterTruthClustering.h b/src/algorithms/calorimetry/CalorimeterTruthClustering.h index 845d97985d..9b61e6266b 100644 --- a/src/algorithms/calorimetry/CalorimeterTruthClustering.h +++ b/src/algorithms/calorimetry/CalorimeterTruthClustering.h @@ -13,30 +13,22 @@ namespace eicrecon { - using CalorimeterTruthClusteringAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::CalorimeterHitCollection, - edm4hep::SimCalorimeterHitCollection - >, - algorithms::Output< - edm4eic::ProtoClusterCollection - > - >; - - class CalorimeterTruthClustering - : public CalorimeterTruthClusteringAlgorithm { - - public: - CalorimeterTruthClustering(std::string_view name) - : CalorimeterTruthClusteringAlgorithm{name, - {"inputHitCollection", "inputSimHitCollection"}, - {"outputProtoClusterCollection"}, - "Use truth information for clustering."} {} +using CalorimeterTruthClusteringAlgorithm = algorithms::Algorithm< + algorithms::Input, + algorithms::Output>; - public: - void init() final; - void process(const Input&, const Output&) const final; +class CalorimeterTruthClustering : public CalorimeterTruthClusteringAlgorithm { - }; +public: + CalorimeterTruthClustering(std::string_view name) + : CalorimeterTruthClusteringAlgorithm{name, + {"inputHitCollection", "inputSimHitCollection"}, + {"outputProtoClusterCollection"}, + "Use truth information for clustering."} {} + +public: + void init() final; + void process(const Input&, const Output&) const final; +}; } // namespace eicrecon diff --git a/src/algorithms/calorimetry/EnergyPositionClusterMerger.h b/src/algorithms/calorimetry/EnergyPositionClusterMerger.h index a7eb1565a1..771de5c692 100644 --- a/src/algorithms/calorimetry/EnergyPositionClusterMerger.h +++ b/src/algorithms/calorimetry/EnergyPositionClusterMerger.h @@ -17,20 +17,14 @@ namespace eicrecon { - using EnergyPositionClusterMergerAlgorithm = algorithms::Algorithm< +using EnergyPositionClusterMergerAlgorithm = algorithms::Algorithm< algorithms::Input< - edm4eic::ClusterCollection, - edm4eic::MCRecoClusterParticleAssociationCollection, - edm4eic::ClusterCollection, - edm4eic::MCRecoClusterParticleAssociationCollection - >, - algorithms::Output< - edm4eic::ClusterCollection, - edm4eic::MCRecoClusterParticleAssociationCollection - > - >; - - /** Simple algorithm to merge the energy measurement from cluster1 with the position + edm4eic::ClusterCollection, edm4eic::MCRecoClusterParticleAssociationCollection, + edm4eic::ClusterCollection, edm4eic::MCRecoClusterParticleAssociationCollection>, + algorithms::Output>; + +/** Simple algorithm to merge the energy measurement from cluster1 with the position * measurement of cluster2 (in case matching clusters are found). If not, it will * propagate the raw cluster from cluster1 or cluster2 * @@ -42,180 +36,181 @@ namespace eicrecon { * * \ingroup reco */ - class EnergyPositionClusterMerger - : public EnergyPositionClusterMergerAlgorithm, - public WithPodConfig { +class EnergyPositionClusterMerger : public EnergyPositionClusterMergerAlgorithm, + public WithPodConfig { - public: - EnergyPositionClusterMerger(std::string_view name) - : EnergyPositionClusterMergerAlgorithm{name, - {"energyClusterCollection", "energyClusterAssociations", - "positionClusterCollection", "positionClusterAssociations"}, - {"outputClusterCollection", "outputClusterAssociations"}, - "Merge energy and position clusters if matching."} {} +public: + EnergyPositionClusterMerger(std::string_view name) + : EnergyPositionClusterMergerAlgorithm{ + name, + {"energyClusterCollection", "energyClusterAssociations", "positionClusterCollection", + "positionClusterAssociations"}, + {"outputClusterCollection", "outputClusterAssociations"}, + "Merge energy and position clusters if matching."} {} - public: +public: + void init() {} - void init() { } + void process(const Input& input, const Output& output) const final { - void process(const Input& input, const Output& output) const final { + const auto [energy_clus, energy_assoc, pos_clus, pos_assoc] = input; + auto [merged_clus, merged_assoc] = output; - const auto [energy_clus, energy_assoc, pos_clus, pos_assoc] = input; - auto [merged_clus, merged_assoc] = output; + debug("Merging energy and position clusters for new event"); - debug( "Merging energy and position clusters for new event" ); + if (energy_clus->size() == 0 && pos_clus->size() == 0) { + debug("Nothing to do for this event, returning..."); + return; + } - if (energy_clus->size() == 0 && pos_clus->size() == 0) { - debug( "Nothing to do for this event, returning..." ); - return; - } + std::vector consumed(energy_clus->size(), false); - std::vector consumed(energy_clus->size(), false); - - // use position clusters as starting point - for (const auto& pc : *pos_clus) { - - trace(" --> Processing position cluster {}, energy: {}", pc.getObjectID().index, pc.getEnergy()); - - // check if we find a good match - int best_match = -1; - double best_delta = std::numeric_limits::max(); - for (size_t ie = 0; ie < energy_clus->size(); ++ie) { - if (consumed[ie]) { - continue; - } - - const auto& ec = (*energy_clus)[ie]; - - trace(" --> Evaluating energy cluster {}, energy: {}", ec.getObjectID().index, ec.getEnergy()); - - // 1. stop if not within tolerance - // (make sure to handle rollover of phi properly) - const double de_rel = std::abs((pc.getEnergy() - ec.getEnergy()) / ec.getEnergy()); - const double deta = std::abs(edm4hep::utils::eta(pc.getPosition()) - - edm4hep::utils::eta(ec.getPosition())); - // check the tolerance for sin(dphi/2) to avoid the hemisphere problem and allow - // for phi rollovers - const double dphi = edm4hep::utils::angleAzimuthal(pc.getPosition()) - - edm4hep::utils::angleAzimuthal(ec.getPosition()); - const double dsphi = std::abs(sin(0.5 * dphi)); - if ((m_cfg.energyRelTolerance > 0 && de_rel > m_cfg.energyRelTolerance) || - (m_cfg.etaTolerance > 0 && deta > m_cfg.etaTolerance) || - (m_cfg.phiTolerance > 0 && dsphi > sin(0.5 * m_cfg.phiTolerance))) { - continue; - } - // --> if we get here, we have a match within tolerance. Now treat the case - // where we have multiple matches. In this case take the one with the closest - // energies. - // 2. best match? - const double delta = fabs(pc.getEnergy() - ec.getEnergy()); - if (delta < best_delta) { - best_delta = delta; - best_match = ie; - } - } + // use position clusters as starting point + for (const auto& pc : *pos_clus) { - // Create a merged cluster if we find a good match - if (best_match >= 0) { - - const auto& ec = (*energy_clus)[best_match]; - - auto new_clus = merged_clus->create(); - new_clus.setEnergy(ec.getEnergy()); - new_clus.setEnergyError(ec.getEnergyError()); - new_clus.setTime(pc.getTime()); - new_clus.setNhits(pc.getNhits() + ec.getNhits()); - new_clus.setPosition(pc.getPosition()); - new_clus.setPositionError(pc.getPositionError()); - new_clus.addToClusters(pc); - new_clus.addToClusters(ec); - - trace(" --> Found matching energy cluster {}, energy: {}", ec.getObjectID().index, ec.getEnergy() ); - trace(" --> Created a new combined cluster {}, energy: {}", new_clus.getObjectID().index, new_clus.getEnergy() ); - - // find association from energy cluster - auto ea = energy_assoc->begin(); - for (; ea != energy_assoc->end(); ++ea) { - if (ea->getRec() == ec) { - break; - } - } - // find association from position cluster if different - auto pa = pos_assoc->begin(); - for (; pa != pos_assoc->end(); ++pa) { - if (pa->getRec() == pc) { - break; - } - } - if (ea != energy_assoc->end() || pa != pos_assoc->end()) { - // we must write an association - if (ea != energy_assoc->end() && pa != pos_assoc->end()) { - // we have two associations - if (pa->getSimID() == ea->getSimID()) { - // both associations agree on the MCParticles entry - auto clusterassoc = merged_assoc->create(); - clusterassoc.setRecID(new_clus.getObjectID().index); - clusterassoc.setSimID(ea->getSimID()); - clusterassoc.setWeight(1.0); - clusterassoc.setRec(new_clus); - clusterassoc.setSim(ea->getSim()); - } else { - // both associations disagree on the MCParticles entry - debug(" --> Two associations added to {} and {}", ea->getSimID(), pa->getSimID()); - auto clusterassoc1 = merged_assoc->create(); - clusterassoc1.setRecID(new_clus.getObjectID().index); - clusterassoc1.setSimID(ea->getSimID()); - clusterassoc1.setWeight(0.5); - clusterassoc1.setRec(new_clus); - clusterassoc1.setSim(ea->getSim()); - auto clusterassoc2 = merged_assoc->create(); - clusterassoc2.setRecID(new_clus.getObjectID().index); - clusterassoc2.setSimID(pa->getSimID()); - clusterassoc2.setWeight(0.5); - clusterassoc2.setRec(new_clus); - clusterassoc2.setSim(pa->getSim()); - } - } else if (ea != energy_assoc->end()) { - // no position association - debug(" --> Only added energy cluster association to {}", ea->getSimID()); - auto clusterassoc = merged_assoc->create(); - clusterassoc.setRecID(new_clus.getObjectID().index); - clusterassoc.setSimID(ea->getSimID()); - clusterassoc.setWeight(1.0); - clusterassoc.setRec(new_clus); - clusterassoc.setSim(ea->getSim()); - } else if (pa != pos_assoc->end()) { - // no energy association - debug(" --> Only added position cluster association to {}", pa->getSimID()); - auto clusterassoc = merged_assoc->create(); - clusterassoc.setRecID(new_clus.getObjectID().index); - clusterassoc.setSimID(pa->getSimID()); - clusterassoc.setWeight(1.0); - clusterassoc.setRec(new_clus); - clusterassoc.setSim(pa->getSim()); - } - } - - // label our energy cluster as consumed - consumed[best_match] = true; - - debug(" Matched position cluster {} with energy cluster {}", pc.getObjectID().index, ec.getObjectID().index); - debug(" - Position cluster: (E: {}, phi: {}, z: {})", pc.getEnergy(), - edm4hep::utils::angleAzimuthal(pc.getPosition()), pc.getPosition().z); - debug(" - Energy cluster: (E: {}, phi: {}, z: {})", ec.getEnergy(), - edm4hep::utils::angleAzimuthal(ec.getPosition()), ec.getPosition().z); - debug(" ---> Merged cluster: (E: {}, phi: {}, z: {})", new_clus.getEnergy(), - edm4hep::utils::angleAzimuthal(new_clus.getPosition()), new_clus.getPosition().z); + trace(" --> Processing position cluster {}, energy: {}", pc.getObjectID().index, + pc.getEnergy()); + // check if we find a good match + int best_match = -1; + double best_delta = std::numeric_limits::max(); + for (size_t ie = 0; ie < energy_clus->size(); ++ie) { + if (consumed[ie]) { + continue; + } + const auto& ec = (*energy_clus)[ie]; + + trace(" --> Evaluating energy cluster {}, energy: {}", ec.getObjectID().index, + ec.getEnergy()); + + // 1. stop if not within tolerance + // (make sure to handle rollover of phi properly) + const double de_rel = std::abs((pc.getEnergy() - ec.getEnergy()) / ec.getEnergy()); + const double deta = + std::abs(edm4hep::utils::eta(pc.getPosition()) - edm4hep::utils::eta(ec.getPosition())); + // check the tolerance for sin(dphi/2) to avoid the hemisphere problem and allow + // for phi rollovers + const double dphi = edm4hep::utils::angleAzimuthal(pc.getPosition()) - + edm4hep::utils::angleAzimuthal(ec.getPosition()); + const double dsphi = std::abs(sin(0.5 * dphi)); + if ((m_cfg.energyRelTolerance > 0 && de_rel > m_cfg.energyRelTolerance) || + (m_cfg.etaTolerance > 0 && deta > m_cfg.etaTolerance) || + (m_cfg.phiTolerance > 0 && dsphi > sin(0.5 * m_cfg.phiTolerance))) { + continue; + } + // --> if we get here, we have a match within tolerance. Now treat the case + // where we have multiple matches. In this case take the one with the closest + // energies. + // 2. best match? + const double delta = fabs(pc.getEnergy() - ec.getEnergy()); + if (delta < best_delta) { + best_delta = delta; + best_match = ie; + } + } + + // Create a merged cluster if we find a good match + if (best_match >= 0) { + + const auto& ec = (*energy_clus)[best_match]; + + auto new_clus = merged_clus->create(); + new_clus.setEnergy(ec.getEnergy()); + new_clus.setEnergyError(ec.getEnergyError()); + new_clus.setTime(pc.getTime()); + new_clus.setNhits(pc.getNhits() + ec.getNhits()); + new_clus.setPosition(pc.getPosition()); + new_clus.setPositionError(pc.getPositionError()); + new_clus.addToClusters(pc); + new_clus.addToClusters(ec); + + trace(" --> Found matching energy cluster {}, energy: {}", ec.getObjectID().index, + ec.getEnergy()); + trace(" --> Created a new combined cluster {}, energy: {}", new_clus.getObjectID().index, + new_clus.getEnergy()); + + // find association from energy cluster + auto ea = energy_assoc->begin(); + for (; ea != energy_assoc->end(); ++ea) { + if (ea->getRec() == ec) { + break; + } + } + // find association from position cluster if different + auto pa = pos_assoc->begin(); + for (; pa != pos_assoc->end(); ++pa) { + if (pa->getRec() == pc) { + break; + } + } + if (ea != energy_assoc->end() || pa != pos_assoc->end()) { + // we must write an association + if (ea != energy_assoc->end() && pa != pos_assoc->end()) { + // we have two associations + if (pa->getSimID() == ea->getSimID()) { + // both associations agree on the MCParticles entry + auto clusterassoc = merged_assoc->create(); + clusterassoc.setRecID(new_clus.getObjectID().index); + clusterassoc.setSimID(ea->getSimID()); + clusterassoc.setWeight(1.0); + clusterassoc.setRec(new_clus); + clusterassoc.setSim(ea->getSim()); } else { + // both associations disagree on the MCParticles entry + debug(" --> Two associations added to {} and {}", ea->getSimID(), pa->getSimID()); + auto clusterassoc1 = merged_assoc->create(); + clusterassoc1.setRecID(new_clus.getObjectID().index); + clusterassoc1.setSimID(ea->getSimID()); + clusterassoc1.setWeight(0.5); + clusterassoc1.setRec(new_clus); + clusterassoc1.setSim(ea->getSim()); + auto clusterassoc2 = merged_assoc->create(); + clusterassoc2.setRecID(new_clus.getObjectID().index); + clusterassoc2.setSimID(pa->getSimID()); + clusterassoc2.setWeight(0.5); + clusterassoc2.setRec(new_clus); + clusterassoc2.setSim(pa->getSim()); + } + } else if (ea != energy_assoc->end()) { + // no position association + debug(" --> Only added energy cluster association to {}", ea->getSimID()); + auto clusterassoc = merged_assoc->create(); + clusterassoc.setRecID(new_clus.getObjectID().index); + clusterassoc.setSimID(ea->getSimID()); + clusterassoc.setWeight(1.0); + clusterassoc.setRec(new_clus); + clusterassoc.setSim(ea->getSim()); + } else if (pa != pos_assoc->end()) { + // no energy association + debug(" --> Only added position cluster association to {}", pa->getSimID()); + auto clusterassoc = merged_assoc->create(); + clusterassoc.setRecID(new_clus.getObjectID().index); + clusterassoc.setSimID(pa->getSimID()); + clusterassoc.setWeight(1.0); + clusterassoc.setRec(new_clus); + clusterassoc.setSim(pa->getSim()); + } + } - debug(" Unmatched position cluster {}", pc.getObjectID().index); + // label our energy cluster as consumed + consumed[best_match] = true; - } + debug(" Matched position cluster {} with energy cluster {}", pc.getObjectID().index, + ec.getObjectID().index); + debug(" - Position cluster: (E: {}, phi: {}, z: {})", pc.getEnergy(), + edm4hep::utils::angleAzimuthal(pc.getPosition()), pc.getPosition().z); + debug(" - Energy cluster: (E: {}, phi: {}, z: {})", ec.getEnergy(), + edm4hep::utils::angleAzimuthal(ec.getPosition()), ec.getPosition().z); + debug(" ---> Merged cluster: (E: {}, phi: {}, z: {})", new_clus.getEnergy(), + edm4hep::utils::angleAzimuthal(new_clus.getPosition()), new_clus.getPosition().z); - } + } else { + + debug(" Unmatched position cluster {}", pc.getObjectID().index); + } } - }; + } +}; } // namespace eicrecon diff --git a/src/algorithms/calorimetry/EnergyPositionClusterMergerConfig.h b/src/algorithms/calorimetry/EnergyPositionClusterMergerConfig.h index 95a3d75703..32a8464d5a 100644 --- a/src/algorithms/calorimetry/EnergyPositionClusterMergerConfig.h +++ b/src/algorithms/calorimetry/EnergyPositionClusterMergerConfig.h @@ -5,12 +5,11 @@ namespace eicrecon { - struct EnergyPositionClusterMergerConfig { +struct EnergyPositionClusterMergerConfig { - double energyRelTolerance{0.5}; - double phiTolerance{0.1}; - double etaTolerance{0.2}; + double energyRelTolerance{0.5}; + double phiTolerance{0.1}; + double etaTolerance{0.2}; +}; - }; - -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/HEXPLIT.cc b/src/algorithms/calorimetry/HEXPLIT.cc index 498af96847..6752252402 100644 --- a/src/algorithms/calorimetry/HEXPLIT.cc +++ b/src/algorithms/calorimetry/HEXPLIT.cc @@ -15,7 +15,7 @@ #include #include #include -#include // for not_null +#include // for not_null #include #include "HEXPLIT.h" @@ -24,124 +24,127 @@ namespace eicrecon { //positions where the overlapping cells are relative to a given cell (in units of hexagon side length) -const std::vector HEXPLIT::neighbor_offsets_x =[]() { +const std::vector HEXPLIT::neighbor_offsets_x = []() { std::vector x; - double rs[2] ={1.5, sqrt(3)/2.}; - double offsets[2]={0, M_PI/2}; - for (int i = 0; i<2; i++){ + double rs[2] = {1.5, sqrt(3) / 2.}; + double offsets[2] = {0, M_PI / 2}; + for (int i = 0; i < 2; i++) { for (int j = 0; j < 6; j += 1) - x.push_back(rs[i]*cos(j*M_PI/3+offsets[i])); + x.push_back(rs[i] * cos(j * M_PI / 3 + offsets[i])); } return x; }(); -const std::vector HEXPLIT::neighbor_offsets_y =[]() { +const std::vector HEXPLIT::neighbor_offsets_y = []() { std::vector y; - double rs[2] ={1.5, sqrt(3)/2.}; - double offsets[2]={0, M_PI/2}; - for (int i = 0; i<2; i++){ + double rs[2] = {1.5, sqrt(3) / 2.}; + double offsets[2] = {0, M_PI / 2}; + for (int i = 0; i < 2; i++) { for (int j = 0; j < 6; j += 1) - y.push_back(rs[i]*sin(j*M_PI/3+offsets[i])); + y.push_back(rs[i] * sin(j * M_PI / 3 + offsets[i])); } return y; }(); //indices of the neighboring cells which overlap to produce a given subcell -const int HEXPLIT::neighbor_indices[SUBCELLS][OVERLAP]={{0, 11,10}, {1, 6, 11},{2, 7, 6}, {3,8,7}, {4,9,8}, {5,10,9}, - {6, 11, 7}, {7, 6, 8}, {8, 7, 9}, {9,8,10},{10,9,11},{11,10,6}}; +const int HEXPLIT::neighbor_indices[SUBCELLS][OVERLAP] = { + {0, 11, 10}, {1, 6, 11}, {2, 7, 6}, {3, 8, 7}, {4, 9, 8}, {5, 10, 9}, + {6, 11, 7}, {7, 6, 8}, {8, 7, 9}, {9, 8, 10}, {10, 9, 11}, {11, 10, 6}}; //positions of the centers of subcells -const std::vector HEXPLIT::subcell_offsets_x =[]() { +const std::vector HEXPLIT::subcell_offsets_x = []() { std::vector x; - double rs[2] ={0.75, sqrt(3)/4.}; - double offsets[2]={0, M_PI/2}; - for (int i = 0; i<2; i++){ - for (int j = 0; j < 6; j += 1) - x.push_back(rs[i]*cos(j*M_PI/3+offsets[i])); + double rs[2] = {0.75, sqrt(3) / 4.}; + double offsets[2] = {0, M_PI / 2}; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 6; j += 1) + x.push_back(rs[i] * cos(j * M_PI / 3 + offsets[i])); } return x; }(); -const std::vector HEXPLIT::subcell_offsets_y =[]() { +const std::vector HEXPLIT::subcell_offsets_y = []() { std::vector y; - double rs[2] ={0.75, sqrt(3)/4.}; - double offsets[2]={0, M_PI/2}; - for (int i = 0; i<2; i++){ + double rs[2] = {0.75, sqrt(3) / 4.}; + double offsets[2] = {0, M_PI / 2}; + for (int i = 0; i < 2; i++) { for (int j = 0; j < 6; j += 1) - y.push_back(rs[i]*sin(j*M_PI/3+offsets[i])); + y.push_back(rs[i] * sin(j * M_PI / 3 + offsets[i])); } return y; }(); -void HEXPLIT::init() { } +void HEXPLIT::init() {} -void HEXPLIT::process(const HEXPLIT::Input& input, - const HEXPLIT::Output& output) const { +void HEXPLIT::process(const HEXPLIT::Input& input, const HEXPLIT::Output& output) const { - const auto [hits] = input; + const auto [hits] = input; auto [subcellHits] = output; - double MIP=m_cfg.MIP/dd4hep::GeV; - double Emin=m_cfg.Emin_in_MIPs*MIP; - double tmax=m_cfg.tmax/dd4hep::ns; + double MIP = m_cfg.MIP / dd4hep::GeV; + double Emin = m_cfg.Emin_in_MIPs * MIP; + double tmax = m_cfg.tmax / dd4hep::ns; auto volman = m_detector->volumeManager(); - for(const auto& hit : *hits){ + for (const auto& hit : *hits) { //skip hits that do not pass E and t cuts - if (hit.getEnergy()tmax) + if (hit.getEnergy() < Emin || hit.getTime() > tmax) continue; //keep track of the energy in each neighboring cell std::vector Eneighbors(NEIGHBORS, 0.0); - double sl = hit.getDimension().x/2.; - for (const auto& other_hit : *hits){ + double sl = hit.getDimension().x / 2.; + for (const auto& other_hit : *hits) { // maximum distance between where the neighboring cell is and where it should be // based on an ideal geometry using the staggered tessellation pattern. // Deviations could arise from rounding errors or from detector misalignment. - double tol=0.1; // in units of side lengths. + double tol = 0.1; // in units of side lengths. //only look at hits nearby within two layers of the current layer - int dz=abs(hit.getLayer()-other_hit.getLayer()); - if (dz>2 || dz==0) + int dz = abs(hit.getLayer() - other_hit.getLayer()); + if (dz > 2 || dz == 0) continue; - if (other_hit.getEnergy()tmax) + if (other_hit.getEnergy() < Emin || other_hit.getTime() > tmax) continue; //difference in transverse position (in units of side lengths) - double dx=(other_hit.getLocal().x-hit.getLocal().x)/sl; - double dy=(other_hit.getLocal().y-hit.getLocal().y)/sl; - if (abs(dx)>2 || abs(dy)>sqrt(3)) + double dx = (other_hit.getLocal().x - hit.getLocal().x) / sl; + double dy = (other_hit.getLocal().y - hit.getLocal().y) / sl; + if (abs(dx) > 2 || abs(dy) > sqrt(3)) continue; //loop over locations of the neighboring cells //and check if the jth hit matches this location - for(int k=0;k(global_position.X()/dd4hep::mm), static_cast(global_position.Y()/dd4hep::mm), static_cast(global_position.Z()/dd4hep::mm)}; + const decltype(edm4eic::CalorimeterHitData::position) position = { + static_cast(global_position.X() / dd4hep::mm), + static_cast(global_position.Y() / dd4hep::mm), + static_cast(global_position.Z() / dd4hep::mm)}; //bounding box dimensions depend on the orientation of the rhombus - int orientation = k%3==0; - const decltype(edm4eic::CalorimeterHitData::dimension) dimension(sl*(orientation?1:1.5), sl*sqrt(3)/2.*(orientation?2:1), - hit.getDimension()[2]); - - subcellHits->create( - hit.getCellID(), - hit.getEnergy()*weights[k]/sum_weights, - 0, - hit.getTime(), - 0, - position, - dimension, - hit.getSector(), - hit.getLayer(), - local); + int orientation = k % 3 == 0; + const decltype(edm4eic::CalorimeterHitData::dimension) dimension( + sl * (orientation ? 1 : 1.5), sl * sqrt(3) / 2. * (orientation ? 2 : 1), + hit.getDimension()[2]); + + subcellHits->create(hit.getCellID(), hit.getEnergy() * weights[k] / sum_weights, 0, + hit.getTime(), 0, position, dimension, hit.getSector(), hit.getLayer(), + local); } } } - } // namespace eicrecon diff --git a/src/algorithms/calorimetry/HEXPLIT.h b/src/algorithms/calorimetry/HEXPLIT.h index 04910c897e..56392811e6 100644 --- a/src/algorithms/calorimetry/HEXPLIT.h +++ b/src/algorithms/calorimetry/HEXPLIT.h @@ -14,8 +14,8 @@ #include #include #include -#include // for basic_string -#include // for string_view +#include // for basic_string +#include // for string_view #include #include "HEXPLITConfig.h" @@ -23,48 +23,38 @@ namespace eicrecon { -using HEXPLITAlgorithm = algorithms::Algorithm< - algorithms::Input< - const edm4eic::CalorimeterHitCollection - >, - algorithms::Output< - edm4eic::CalorimeterHitCollection - > - >; +using HEXPLITAlgorithm = + algorithms::Algorithm, + algorithms::Output>; - class HEXPLIT - : public HEXPLITAlgorithm, - public WithPodConfig { +class HEXPLIT : public HEXPLITAlgorithm, public WithPodConfig { - public: - HEXPLIT(std::string_view name) - : HEXPLITAlgorithm{name, - {"inputHits"}, - {"outputSubcellHits"}, - "Split hits into subcell hits"} {} +public: + HEXPLIT(std::string_view name) + : HEXPLITAlgorithm{ + name, {"inputHits"}, {"outputSubcellHits"}, "Split hits into subcell hits"} {} - void init() final; - void process(const Input&, const Output&) const final; + void init() final; + void process(const Input&, const Output&) const final; - private: - // number of subcells that a single cell is divided into - static const int SUBCELLS=12; - // number of neighboring positions whose overlap define the subcells - static const int NEIGHBORS=12; - // number of neighboring cells that overlap to obtain a subcell - static const int OVERLAP=3; +private: + // number of subcells that a single cell is divided into + static const int SUBCELLS = 12; + // number of neighboring positions whose overlap define the subcells + static const int NEIGHBORS = 12; + // number of neighboring cells that overlap to obtain a subcell + static const int OVERLAP = 3; //positions where the overlapping cells are relative to a given cell (in units of hexagon side length) - static const std::vector neighbor_offsets_x; - static const std::vector neighbor_offsets_y; - //indices of the neighboring cells which overlap to produce a given subcell - static const int neighbor_indices[SUBCELLS][OVERLAP]; + static const std::vector neighbor_offsets_x; + static const std::vector neighbor_offsets_y; + //indices of the neighboring cells which overlap to produce a given subcell + static const int neighbor_indices[SUBCELLS][OVERLAP]; //positions of the centers of subcells - static const std::vector subcell_offsets_x; - static const std::vector subcell_offsets_y; + static const std::vector subcell_offsets_x; + static const std::vector subcell_offsets_y; - private: - const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; - - }; +private: + const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; +}; } // namespace eicrecon diff --git a/src/algorithms/calorimetry/HEXPLITConfig.h b/src/algorithms/calorimetry/HEXPLITConfig.h index 1e2d0d1c72..c783e46691 100644 --- a/src/algorithms/calorimetry/HEXPLITConfig.h +++ b/src/algorithms/calorimetry/HEXPLITConfig.h @@ -5,10 +5,10 @@ namespace eicrecon { - struct HEXPLITConfig { - double MIP{472.*dd4hep::keV}; - double Emin_in_MIPs{0.1}; - double tmax{325*dd4hep::ns}; - }; +struct HEXPLITConfig { + double MIP{472. * dd4hep::keV}; + double Emin_in_MIPs{0.1}; + double tmax{325 * dd4hep::ns}; +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/ImagingClusterReco.h b/src/algorithms/calorimetry/ImagingClusterReco.h index 28baf24447..a7a96ef310 100644 --- a/src/algorithms/calorimetry/ImagingClusterReco.h +++ b/src/algorithms/calorimetry/ImagingClusterReco.h @@ -38,278 +38,275 @@ namespace eicrecon { - using ImagingClusterRecoAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::ProtoClusterCollection, +using ImagingClusterRecoAlgorithm = + algorithms::Algorithm= 7 - edm4eic::MCRecoCalorimeterHitAssociationCollection + edm4eic::MCRecoCalorimeterHitAssociationCollection #else - edm4hep::SimCalorimeterHitCollection + edm4hep::SimCalorimeterHitCollection #endif - >, - algorithms::Output< - edm4eic::ClusterCollection, - edm4eic::MCRecoClusterParticleAssociationCollection, - edm4eic::ClusterCollection - > - >; - - /** Imaging cluster reconstruction. + >, + algorithms::Output>; + +/** Imaging cluster reconstruction. * * Reconstruct the cluster/layer info for imaging calorimeter * Logarithmic weighting is used to describe energy deposit in transverse direction * * \ingroup reco */ - class ImagingClusterReco - : public ImagingClusterRecoAlgorithm, - public WithPodConfig { +class ImagingClusterReco : public ImagingClusterRecoAlgorithm, + public WithPodConfig { - public: - ImagingClusterReco(std::string_view name) - : ImagingClusterRecoAlgorithm{name, +public: + ImagingClusterReco(std::string_view name) + : ImagingClusterRecoAlgorithm{ + name, #if EDM4EIC_VERSION_MAJOR >= 7 - {"inputProtoClusterCollection", "mcRawHitAssocations"}, + {"inputProtoClusterCollection", "mcRawHitAssocations"}, #else - {"inputProtoClusterCollection", "mcHits"}, + {"inputProtoClusterCollection", "mcHits"}, #endif - {"outputClusterCollection", "outputClusterAssociations", "outputLayerCollection"}, - "Reconstruct the cluster/layer info for imaging calorimeter."} {} - - public: + {"outputClusterCollection", "outputClusterAssociations", "outputLayerCollection"}, + "Reconstruct the cluster/layer info for imaging calorimeter."} { + } - void init() { } +public: + void init() {} - void process(const Input& input, const Output& output) const final { + void process(const Input& input, const Output& output) const final { #if EDM4EIC_VERSION_MAJOR >= 7 - const auto [proto, mchitassociations] = input; + const auto [proto, mchitassociations] = input; #else - const auto [proto, mchits] = input; + const auto [proto, mchits] = input; #endif - auto [clusters, associations, layers] = output; - - for (const auto& pcl: *proto) { - if (!pcl.getHits().empty() && !pcl.getHits(0).isAvailable()) { - warning("Protocluster hit relation is invalid, skipping protocluster"); - continue; - } - // get cluster and associated layers - auto cl = reconstruct_cluster(pcl); - auto cl_layers = reconstruct_cluster_layers(pcl); - - // Get cluster direction from the layer profile - auto [theta, phi] = fit_track(cl_layers); - cl.setIntrinsicTheta(theta); - cl.setIntrinsicPhi(phi); - // no error on the intrinsic direction TODO - - // store layer and clusters on the datastore - for (const auto& layer: cl_layers) { - layers->push_back(layer); - cl.addToClusters(layer); - } - clusters->push_back(cl); - - // If sim hits are available, associate cluster with MCParticle + auto [clusters, associations, layers] = output; + + for (const auto& pcl : *proto) { + if (!pcl.getHits().empty() && !pcl.getHits(0).isAvailable()) { + warning("Protocluster hit relation is invalid, skipping protocluster"); + continue; + } + // get cluster and associated layers + auto cl = reconstruct_cluster(pcl); + auto cl_layers = reconstruct_cluster_layers(pcl); + + // Get cluster direction from the layer profile + auto [theta, phi] = fit_track(cl_layers); + cl.setIntrinsicTheta(theta); + cl.setIntrinsicPhi(phi); + // no error on the intrinsic direction TODO + + // store layer and clusters on the datastore + for (const auto& layer : cl_layers) { + layers->push_back(layer); + cl.addToClusters(layer); + } + clusters->push_back(cl); + + // If sim hits are available, associate cluster with MCParticle #if EDM4EIC_VERSION_MAJOR >= 7 - if (mchitassociations->size() == 0) { - debug("Provided MCRecoCalorimeterHitAssociation collection is empty. No truth associations will be performed."); - continue; - } else { - associate_mc_particles(cl, mchitassociations, associations); - } + if (mchitassociations->size() == 0) { + debug("Provided MCRecoCalorimeterHitAssociation collection is empty. No truth associations " + "will be performed."); + continue; + } else { + associate_mc_particles(cl, mchitassociations, associations); + } #else - if (mchits->size() == 0) { - debug("Provided SimCalorimeterHitCollection is empty. No truth association will be performed."); - continue; - } else { - associate_mc_particles(cl, mchits, associations); - } + if (mchits->size() == 0) { + debug("Provided SimCalorimeterHitCollection is empty. No truth association will be " + "performed."); + continue; + } else { + associate_mc_particles(cl, mchits, associations); + } #endif - } - - // debug output - for (const auto& cl: *clusters) { - debug("Cluster {:d}: Edep = {:.3f} MeV, Dir = ({:.3f}, {:.3f}) deg", cl.getObjectID().index, - cl.getEnergy() * 1000., cl.getIntrinsicTheta() / M_PI * 180., - cl.getIntrinsicPhi() / M_PI * 180. - ); - } } - private: - - static std::vector reconstruct_cluster_layers(const edm4eic::ProtoCluster& pcl) { - const auto& hits = pcl.getHits(); - const auto& weights = pcl.getWeights(); - // using map to have hits sorted by layer - std::map>> layer_map; - for (unsigned i = 0; i < hits.size(); ++i) { - const auto hit = hits[i]; - auto lid = hit.getLayer(); -// if (layer_map.count(lid) == 0) { -// std::vector> v; -// layer_map[lid] = {}; -// } - layer_map[lid].push_back({hit, weights[i]}); - } - - // create layers - std::vector cl_layers; - for (const auto &[lid, layer_hits]: layer_map) { - auto layer = reconstruct_layer(layer_hits); - cl_layers.push_back(layer); - } - return cl_layers; + // debug output + for (const auto& cl : *clusters) { + debug("Cluster {:d}: Edep = {:.3f} MeV, Dir = ({:.3f}, {:.3f}) deg", cl.getObjectID().index, + cl.getEnergy() * 1000., cl.getIntrinsicTheta() / M_PI * 180., + cl.getIntrinsicPhi() / M_PI * 180.); } - - static edm4eic::MutableCluster reconstruct_layer(const std::vector>& hits) { - edm4eic::MutableCluster layer; - layer.setType(Jug::Reco::ClusterType::kClusterSlice); - // Calculate averages - double energy{0}; - double energyError{0}; - double time{0}; - double timeError{0}; - double sumOfWeights{0}; - auto pos = layer.getPosition(); - for (const auto &[hit, weight]: hits) { - energy += hit.getEnergy() * weight; - energyError += std::pow(hit.getEnergyError() * weight, 2); - time += hit.getTime() * weight; - timeError += std::pow(hit.getTimeError() * weight, 2); - pos = pos + hit.getPosition() * weight; - sumOfWeights += weight; - layer.addToHits(hit); - } - layer.setEnergy(energy); - layer.setEnergyError(std::sqrt(energyError)); - layer.setTime(time / sumOfWeights); - layer.setTimeError(std::sqrt(timeError) / sumOfWeights); - layer.setNhits(hits.size()); - layer.setPosition(pos / sumOfWeights); - // positionError not set - // Intrinsic direction meaningless in a cluster layer --> not set - - // Calculate radius as the standard deviation of the hits versus the cluster center - double radius = 0.; - for (const auto &[hit, weight]: hits) { - radius += std::pow(edm4hep::utils::magnitude(hit.getPosition() - layer.getPosition()), 2); - } - layer.addToShapeParameters(std::sqrt(radius / layer.getNhits())); - // TODO Skewedness - - return layer; + } + +private: + static std::vector + reconstruct_cluster_layers(const edm4eic::ProtoCluster& pcl) { + const auto& hits = pcl.getHits(); + const auto& weights = pcl.getWeights(); + // using map to have hits sorted by layer + std::map>> layer_map; + for (unsigned i = 0; i < hits.size(); ++i) { + const auto hit = hits[i]; + auto lid = hit.getLayer(); + // if (layer_map.count(lid) == 0) { + // std::vector> v; + // layer_map[lid] = {}; + // } + layer_map[lid].push_back({hit, weights[i]}); } - static edm4eic::MutableCluster reconstruct_cluster(const edm4eic::ProtoCluster& pcl) { - edm4eic::MutableCluster cluster; - - const auto& hits = pcl.getHits(); - const auto& weights = pcl.getWeights(); - - cluster.setType(Jug::Reco::ClusterType::kCluster3D); - double energy = 0.; - double energyError = 0.; - double time = 0.; - double timeError = 0.; - double meta = 0.; - double mphi = 0.; - double r = 9999 * dd4hep::cm; - for (unsigned i = 0; i < hits.size(); ++i) { - const auto &hit = hits[i]; - const auto &weight = weights[i]; - energy += hit.getEnergy() * weight; - energyError += std::pow(hit.getEnergyError() * weight, 2); - // energy weighting for the other variables - const double energyWeight = hit.getEnergy() * weight; - time += hit.getTime() * energyWeight; - timeError += std::pow(hit.getTimeError() * energyWeight, 2); - meta += edm4hep::utils::eta(hit.getPosition()) * energyWeight; - mphi += edm4hep::utils::angleAzimuthal(hit.getPosition()) * energyWeight; - r = std::min(edm4hep::utils::magnitude(hit.getPosition()), r); - cluster.addToHits(hit); - } - cluster.setEnergy(energy); - cluster.setEnergyError(std::sqrt(energyError)); - cluster.setTime(time / energy); - cluster.setTimeError(std::sqrt(timeError) / energy); - cluster.setNhits(hits.size()); - cluster.setPosition(edm4hep::utils::sphericalToVector(r, edm4hep::utils::etaToAngle(meta / energy), mphi / energy)); - - // shower radius estimate (eta-phi plane) - double radius = 0.; - for (const auto &hit: hits) { - radius += std::pow( - std::hypot( - (edm4hep::utils::eta(hit.getPosition()) - edm4hep::utils::eta(cluster.getPosition())), - (edm4hep::utils::angleAzimuthal(hit.getPosition()) - edm4hep::utils::angleAzimuthal(cluster.getPosition())) - ), - 2.0 - ); - } - cluster.addToShapeParameters(std::sqrt(radius / cluster.getNhits())); - // Skewedness not calculated TODO - - // Optionally store the MC truth associated with the first hit in this cluster - // FIXME no connection between cluster and truth in edm4hep - // if (mcHits) { - // const auto& mc_hit = (*mcHits)[pcl.getHits(0).ID.value]; - // cluster.mcID({mc_hit.truth().trackID, m_kMonteCarloSource}); - //} - - return cluster; + // create layers + std::vector cl_layers; + for (const auto& [lid, layer_hits] : layer_map) { + auto layer = reconstruct_layer(layer_hits); + cl_layers.push_back(layer); + } + return cl_layers; + } + + static edm4eic::MutableCluster + reconstruct_layer(const std::vector>& hits) { + edm4eic::MutableCluster layer; + layer.setType(Jug::Reco::ClusterType::kClusterSlice); + // Calculate averages + double energy{0}; + double energyError{0}; + double time{0}; + double timeError{0}; + double sumOfWeights{0}; + auto pos = layer.getPosition(); + for (const auto& [hit, weight] : hits) { + energy += hit.getEnergy() * weight; + energyError += std::pow(hit.getEnergyError() * weight, 2); + time += hit.getTime() * weight; + timeError += std::pow(hit.getTimeError() * weight, 2); + pos = pos + hit.getPosition() * weight; + sumOfWeights += weight; + layer.addToHits(hit); + } + layer.setEnergy(energy); + layer.setEnergyError(std::sqrt(energyError)); + layer.setTime(time / sumOfWeights); + layer.setTimeError(std::sqrt(timeError) / sumOfWeights); + layer.setNhits(hits.size()); + layer.setPosition(pos / sumOfWeights); + // positionError not set + // Intrinsic direction meaningless in a cluster layer --> not set + + // Calculate radius as the standard deviation of the hits versus the cluster center + double radius = 0.; + for (const auto& [hit, weight] : hits) { + radius += std::pow(edm4hep::utils::magnitude(hit.getPosition() - layer.getPosition()), 2); + } + layer.addToShapeParameters(std::sqrt(radius / layer.getNhits())); + // TODO Skewedness + + return layer; + } + + static edm4eic::MutableCluster reconstruct_cluster(const edm4eic::ProtoCluster& pcl) { + edm4eic::MutableCluster cluster; + + const auto& hits = pcl.getHits(); + const auto& weights = pcl.getWeights(); + + cluster.setType(Jug::Reco::ClusterType::kCluster3D); + double energy = 0.; + double energyError = 0.; + double time = 0.; + double timeError = 0.; + double meta = 0.; + double mphi = 0.; + double r = 9999 * dd4hep::cm; + for (unsigned i = 0; i < hits.size(); ++i) { + const auto& hit = hits[i]; + const auto& weight = weights[i]; + energy += hit.getEnergy() * weight; + energyError += std::pow(hit.getEnergyError() * weight, 2); + // energy weighting for the other variables + const double energyWeight = hit.getEnergy() * weight; + time += hit.getTime() * energyWeight; + timeError += std::pow(hit.getTimeError() * energyWeight, 2); + meta += edm4hep::utils::eta(hit.getPosition()) * energyWeight; + mphi += edm4hep::utils::angleAzimuthal(hit.getPosition()) * energyWeight; + r = std::min(edm4hep::utils::magnitude(hit.getPosition()), r); + cluster.addToHits(hit); + } + cluster.setEnergy(energy); + cluster.setEnergyError(std::sqrt(energyError)); + cluster.setTime(time / energy); + cluster.setTimeError(std::sqrt(timeError) / energy); + cluster.setNhits(hits.size()); + cluster.setPosition(edm4hep::utils::sphericalToVector( + r, edm4hep::utils::etaToAngle(meta / energy), mphi / energy)); + + // shower radius estimate (eta-phi plane) + double radius = 0.; + for (const auto& hit : hits) { + radius += std::pow(std::hypot((edm4hep::utils::eta(hit.getPosition()) - + edm4hep::utils::eta(cluster.getPosition())), + (edm4hep::utils::angleAzimuthal(hit.getPosition()) - + edm4hep::utils::angleAzimuthal(cluster.getPosition()))), + 2.0); + } + cluster.addToShapeParameters(std::sqrt(radius / cluster.getNhits())); + // Skewedness not calculated TODO + + // Optionally store the MC truth associated with the first hit in this cluster + // FIXME no connection between cluster and truth in edm4hep + // if (mcHits) { + // const auto& mc_hit = (*mcHits)[pcl.getHits(0).ID.value]; + // cluster.mcID({mc_hit.truth().trackID, m_kMonteCarloSource}); + //} + + return cluster; + } + + std::pair + fit_track(const std::vector& layers) const { + int nrows = 0; + decltype(edm4eic::ClusterData::position) mean_pos{0, 0, 0}; + for (const auto& layer : layers) { + if ((layer.getNhits() > 0) && (layer.getHits(0).getLayer() <= m_cfg.trackStopLayer)) { + mean_pos = mean_pos + layer.getPosition(); + nrows += 1; + } } - std::pair fit_track(const std::vector &layers) const { - int nrows = 0; - decltype(edm4eic::ClusterData::position) mean_pos{0, 0, 0}; - for (const auto &layer: layers) { - if ((layer.getNhits() > 0) && (layer.getHits(0).getLayer() <= m_cfg.trackStopLayer)) { - mean_pos = mean_pos + layer.getPosition(); - nrows += 1; - } - } - - // cannot fit - if (nrows < 2) { - return {}; - } - - mean_pos = mean_pos / nrows; - // fill position data - Eigen::MatrixXd pos(nrows, 3); - int ir = 0; - for (const auto &layer: layers) { - if ((layer.getNhits() > 0) && (layer.getHits(0).getLayer() <= m_cfg.trackStopLayer)) { - auto delta = layer.getPosition() - mean_pos; - pos(ir, 0) = delta.x; - pos(ir, 1) = delta.y; - pos(ir, 2) = delta.z; - ir += 1; - } - } + // cannot fit + if (nrows < 2) { + return {}; + } - Eigen::JacobiSVD svd(pos, Eigen::ComputeThinU | Eigen::ComputeThinV); - const auto dir = svd.matrixV().col(0); - // theta and phi - return {std::acos(dir(2)), std::atan2(dir(1), dir(0))}; + mean_pos = mean_pos / nrows; + // fill position data + Eigen::MatrixXd pos(nrows, 3); + int ir = 0; + for (const auto& layer : layers) { + if ((layer.getNhits() > 0) && (layer.getHits(0).getLayer() <= m_cfg.trackStopLayer)) { + auto delta = layer.getPosition() - mean_pos; + pos(ir, 0) = delta.x; + pos(ir, 1) = delta.y; + pos(ir, 2) = delta.z; + ir += 1; + } } - void associate_mc_particles( - const edm4eic::Cluster& cl, + Eigen::JacobiSVD svd(pos, Eigen::ComputeThinU | Eigen::ComputeThinV); + const auto dir = svd.matrixV().col(0); + // theta and phi + return {std::acos(dir(2)), std::atan2(dir(1), dir(0))}; + } + + void associate_mc_particles( + const edm4eic::Cluster& cl, #if EDM4EIC_VERSION_MAJOR >= 7 - const edm4eic::MCRecoCalorimeterHitAssociationCollection* mchitassociations, + const edm4eic::MCRecoCalorimeterHitAssociationCollection* mchitassociations, #else - const edm4hep::SimCalorimeterHitCollection* mchits, + const edm4hep::SimCalorimeterHitCollection* mchits, #endif - edm4eic::MCRecoClusterParticleAssociationCollection* assocs - ) const { - // -------------------------------------------------------------------------- - // Association Logic - // -------------------------------------------------------------------------- - /* 1. identify all sim hits associated with a given protocluster, and sum + edm4eic::MCRecoClusterParticleAssociationCollection* assocs) const { + // -------------------------------------------------------------------------- + // Association Logic + // -------------------------------------------------------------------------- + /* 1. identify all sim hits associated with a given protocluster, and sum * the energy of the sim hits. * 2. for each sim hit * - identify parents of each contributing particles; and @@ -319,116 +316,110 @@ namespace eicrecon { * of contributed energy over total sim hit energy. */ - // lambda to compare MCParticles - auto compare = [](const edm4hep::MCParticle& lhs, const edm4hep::MCParticle& rhs) { - if (lhs.getObjectID().collectionID == rhs.getObjectID().collectionID) { - return (lhs.getObjectID().index < rhs.getObjectID().index); - } else { - return (lhs.getObjectID().collectionID < rhs.getObjectID().collectionID); - } - }; - - // bookkeeping maps for associated primaries - std::map mapMCParToContrib(compare); - - // -------------------------------------------------------------------------- - // 1. get associated sim hits and sum energy - // -------------------------------------------------------------------------- - double eSimHitSum = 0.; - for (auto clhit : cl.getHits()) { - // vector to hold associated sim hits - std::vector vecAssocSimHits; + // lambda to compare MCParticles + auto compare = [](const edm4hep::MCParticle& lhs, const edm4hep::MCParticle& rhs) { + if (lhs.getObjectID().collectionID == rhs.getObjectID().collectionID) { + return (lhs.getObjectID().index < rhs.getObjectID().index); + } else { + return (lhs.getObjectID().collectionID < rhs.getObjectID().collectionID); + } + }; + + // bookkeeping maps for associated primaries + std::map mapMCParToContrib(compare); + + // -------------------------------------------------------------------------- + // 1. get associated sim hits and sum energy + // -------------------------------------------------------------------------- + double eSimHitSum = 0.; + for (auto clhit : cl.getHits()) { + // vector to hold associated sim hits + std::vector vecAssocSimHits; #if EDM4EIC_VERSION_MAJOR >= 7 - for (const auto& hitAssoc : *mchitassociations) { - // if found corresponding raw hit, add sim hit to vector - // and increment energy sum - if (clhit.getRawHit() == hitAssoc.getRawHit()) { - vecAssocSimHits.push_back(hitAssoc.getSimHit()); - eSimHitSum += vecAssocSimHits.back().getEnergy(); - } - - } + for (const auto& hitAssoc : *mchitassociations) { + // if found corresponding raw hit, add sim hit to vector + // and increment energy sum + if (clhit.getRawHit() == hitAssoc.getRawHit()) { + vecAssocSimHits.push_back(hitAssoc.getSimHit()); + eSimHitSum += vecAssocSimHits.back().getEnergy(); + } + } #else - for (const auto& mchit : *mchits) { - if (mchit.getCellID() == clhit.getCellID()) { - vecAssocSimHits.push_back(mchit); - eSimHitSum += vecAssocSimHits.back().getEnergy(); - break; - } - } - - // if no matching cell ID found, continue - // otherwise increment sum - if (vecAssocSimHits.empty()) { - debug("No matching SimHit for hit {}", clhit.getCellID()); - continue; - } -#endif - debug("{} associated sim hits found for reco hit (cell ID = {})", vecAssocSimHits.size(), clhit.getCellID()); - - // ------------------------------------------------------------------------ - // 2. loop through associated sim hits - // ------------------------------------------------------------------------ - for (const auto& simHit : vecAssocSimHits) { - for (const auto& contrib : simHit.getContributions()) { - // -------------------------------------------------------------------- - // grab primary responsible for contribution & increment relevant sum - // -------------------------------------------------------------------- - edm4hep::MCParticle primary = get_primary(contrib); - mapMCParToContrib[primary] += contrib.getEnergy(); - - trace("Identified primary: id = {}, pid = {}, total energy = {}, contributed = {}", - primary.getObjectID().index, - primary.getPDG(), - primary.getEnergy(), - mapMCParToContrib[primary] - ); - } - } + for (const auto& mchit : *mchits) { + if (mchit.getCellID() == clhit.getCellID()) { + vecAssocSimHits.push_back(mchit); + eSimHitSum += vecAssocSimHits.back().getEnergy(); + break; } - debug("Found {} primaries contributing a total of {} GeV", mapMCParToContrib.size(), eSimHitSum); - - // -------------------------------------------------------------------------- - // 3. create association for each contributing primary - // -------------------------------------------------------------------------- - for (auto [part, contribution] : mapMCParToContrib) { - // calculate weight - const double weight = contribution / eSimHitSum; - - // set association - auto assoc = assocs->create(); - assoc.setRecID(cl.getObjectID().index); // if not using collection, this is always set to -1 - assoc.setSimID(part.getObjectID().index); - assoc.setWeight(weight); - assoc.setRec(cl); - assoc.setSim(part); - debug("Associated cluster #{} to MC Particle #{} (pid = {}, status = {}, energy = {}) with weight ({})", - cl.getObjectID().index, - part.getObjectID().index, - part.getPDG(), - part.getGeneratorStatus(), - part.getEnergy(), - weight - ); + } + + // if no matching cell ID found, continue + // otherwise increment sum + if (vecAssocSimHits.empty()) { + debug("No matching SimHit for hit {}", clhit.getCellID()); + continue; + } +#endif + debug("{} associated sim hits found for reco hit (cell ID = {})", vecAssocSimHits.size(), + clhit.getCellID()); + + // ------------------------------------------------------------------------ + // 2. loop through associated sim hits + // ------------------------------------------------------------------------ + for (const auto& simHit : vecAssocSimHits) { + for (const auto& contrib : simHit.getContributions()) { + // -------------------------------------------------------------------- + // grab primary responsible for contribution & increment relevant sum + // -------------------------------------------------------------------- + edm4hep::MCParticle primary = get_primary(contrib); + mapMCParToContrib[primary] += contrib.getEnergy(); + + trace("Identified primary: id = {}, pid = {}, total energy = {}, contributed = {}", + primary.getObjectID().index, primary.getPDG(), primary.getEnergy(), + mapMCParToContrib[primary]); } + } } - - edm4hep::MCParticle get_primary(const edm4hep::CaloHitContribution& contrib) const { - // get contributing particle - const auto contributor = contrib.getParticle(); - - // walk back through parents to find primary - // - TODO finalize primary selection. This - // can be improved!! - edm4hep::MCParticle primary = contributor; - while (primary.parents_size() > 0) { - if (primary.getGeneratorStatus() != 0) break; - primary = primary.getParents(0); - } - return primary; + debug("Found {} primaries contributing a total of {} GeV", mapMCParToContrib.size(), + eSimHitSum); + + // -------------------------------------------------------------------------- + // 3. create association for each contributing primary + // -------------------------------------------------------------------------- + for (auto [part, contribution] : mapMCParToContrib) { + // calculate weight + const double weight = contribution / eSimHitSum; + + // set association + auto assoc = assocs->create(); + assoc.setRecID(cl.getObjectID().index); // if not using collection, this is always set to -1 + assoc.setSimID(part.getObjectID().index); + assoc.setWeight(weight); + assoc.setRec(cl); + assoc.setSim(part); + debug("Associated cluster #{} to MC Particle #{} (pid = {}, status = {}, energy = {}) with " + "weight ({})", + cl.getObjectID().index, part.getObjectID().index, part.getPDG(), + part.getGeneratorStatus(), part.getEnergy(), weight); } - + } + + edm4hep::MCParticle get_primary(const edm4hep::CaloHitContribution& contrib) const { + // get contributing particle + const auto contributor = contrib.getParticle(); + + // walk back through parents to find primary + // - TODO finalize primary selection. This + // can be improved!! + edm4hep::MCParticle primary = contributor; + while (primary.parents_size() > 0) { + if (primary.getGeneratorStatus() != 0) + break; + primary = primary.getParents(0); + } + return primary; + } }; } // namespace eicrecon diff --git a/src/algorithms/calorimetry/ImagingClusterRecoConfig.h b/src/algorithms/calorimetry/ImagingClusterRecoConfig.h index 8ae57def32..9ed22791f6 100644 --- a/src/algorithms/calorimetry/ImagingClusterRecoConfig.h +++ b/src/algorithms/calorimetry/ImagingClusterRecoConfig.h @@ -5,10 +5,9 @@ namespace eicrecon { - struct ImagingClusterRecoConfig { +struct ImagingClusterRecoConfig { - int trackStopLayer = 9; + int trackStopLayer = 9; +}; - }; - -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/ImagingTopoCluster.h b/src/algorithms/calorimetry/ImagingTopoCluster.h index f5a7263697..5364c45d7c 100644 --- a/src/algorithms/calorimetry/ImagingTopoCluster.h +++ b/src/algorithms/calorimetry/ImagingTopoCluster.h @@ -41,244 +41,236 @@ namespace eicrecon { - using ImagingTopoClusterAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::CalorimeterHitCollection - >, - algorithms::Output< - edm4eic::ProtoClusterCollection - > - >; - - class ImagingTopoCluster - : public ImagingTopoClusterAlgorithm, - public WithPodConfig { - - public: - ImagingTopoCluster(std::string_view name) - : ImagingTopoClusterAlgorithm{name, - {"inputHitCollection"}, - {"outputProtoClusterCollection"}, - "Topological cell clustering algorithm for imaging calorimetry."} {} - - private: - - // unitless counterparts of the input parameters - std::array localDistXY{0, 0}; - std::array layerDistEtaPhi{0, 0}; - std::array layerDistXY{0, 0}; - double sectorDist{0}; - double minClusterHitEdep{0}; - double minClusterCenterEdep{0}; - double minClusterEdep{0}; - - public: - void init() { - // unitless conversion - // sanity checks - if (m_cfg.localDistXY.size() != 2) { - error( "Expected 2 values (x_dist, y_dist) for localDistXY"); - return; - } - if (m_cfg.layerDistEtaPhi.size() != 2) { - error( "Expected 2 values (eta_dist, phi_dist) for layerDistEtaPhi" ); - return; - } - if (m_cfg.minClusterCenterEdep < m_cfg.minClusterHitEdep) { - error( "minClusterCenterEdep must be greater than or equal to minClusterHitEdep" ); - return; - } +using ImagingTopoClusterAlgorithm = + algorithms::Algorithm, + algorithms::Output>; + +class ImagingTopoCluster : public ImagingTopoClusterAlgorithm, + public WithPodConfig { + +public: + ImagingTopoCluster(std::string_view name) + : ImagingTopoClusterAlgorithm{ + name, + {"inputHitCollection"}, + {"outputProtoClusterCollection"}, + "Topological cell clustering algorithm for imaging calorimetry."} {} + +private: + // unitless counterparts of the input parameters + std::array localDistXY{0, 0}; + std::array layerDistEtaPhi{0, 0}; + std::array layerDistXY{0, 0}; + double sectorDist{0}; + double minClusterHitEdep{0}; + double minClusterCenterEdep{0}; + double minClusterEdep{0}; + +public: + void init() { + // unitless conversion + // sanity checks + if (m_cfg.localDistXY.size() != 2) { + error("Expected 2 values (x_dist, y_dist) for localDistXY"); + return; + } + if (m_cfg.layerDistEtaPhi.size() != 2) { + error("Expected 2 values (eta_dist, phi_dist) for layerDistEtaPhi"); + return; + } + if (m_cfg.minClusterCenterEdep < m_cfg.minClusterHitEdep) { + error("minClusterCenterEdep must be greater than or equal to minClusterHitEdep"); + return; + } - // using juggler internal units (GeV, dd4hep::mm, dd4hep::ns, dd4hep::rad) - localDistXY[0] = m_cfg.localDistXY[0] / dd4hep::mm; - localDistXY[1] = m_cfg.localDistXY[1] / dd4hep::mm; - layerDistXY[0] = m_cfg.layerDistXY[0] / dd4hep::mm; - layerDistXY[1] = m_cfg.layerDistXY[1] / dd4hep::mm; - layerDistEtaPhi[0] = m_cfg.layerDistEtaPhi[0]; - layerDistEtaPhi[1] = m_cfg.layerDistEtaPhi[1] / dd4hep::rad; - sectorDist = m_cfg.sectorDist / dd4hep::mm; - minClusterHitEdep = m_cfg.minClusterHitEdep / dd4hep::GeV; - minClusterCenterEdep = m_cfg.minClusterCenterEdep / dd4hep::GeV; - minClusterEdep = m_cfg.minClusterEdep / dd4hep::GeV; - - // summarize the clustering parameters - info("Local clustering (same sector and same layer): " - "Local [x, y] distance between hits <= [{:.4f} mm, {:.4f} mm].", - localDistXY[0], localDistXY[1] - ); - switch (m_cfg.layerMode) { - case ImagingTopoClusterConfig::ELayerMode::etaphi: - info("Neighbour layers clustering (same sector and layer id within +- {:d}: " - "Global [eta, phi] distance between hits <= [{:.4f}, {:.4f} rad].", - m_cfg.neighbourLayersRange, layerDistEtaPhi[0], layerDistEtaPhi[1] - ); - break; - case ImagingTopoClusterConfig::ELayerMode::xy: - info("Neighbour layers clustering (same sector and layer id within +- {:d}: " - "Local [x, y] distance between hits <= [{:.4f} mm, {:.4f} mm].", - m_cfg.neighbourLayersRange, layerDistXY[0], layerDistXY[1] - ); - break; - default: - error("Unknown layer mode."); - } - info("Neighbour sectors clustering (different sector): " - "Global distance between hits <= {:.4f} mm.", - sectorDist - ); + // using juggler internal units (GeV, dd4hep::mm, dd4hep::ns, dd4hep::rad) + localDistXY[0] = m_cfg.localDistXY[0] / dd4hep::mm; + localDistXY[1] = m_cfg.localDistXY[1] / dd4hep::mm; + layerDistXY[0] = m_cfg.layerDistXY[0] / dd4hep::mm; + layerDistXY[1] = m_cfg.layerDistXY[1] / dd4hep::mm; + layerDistEtaPhi[0] = m_cfg.layerDistEtaPhi[0]; + layerDistEtaPhi[1] = m_cfg.layerDistEtaPhi[1] / dd4hep::rad; + sectorDist = m_cfg.sectorDist / dd4hep::mm; + minClusterHitEdep = m_cfg.minClusterHitEdep / dd4hep::GeV; + minClusterCenterEdep = m_cfg.minClusterCenterEdep / dd4hep::GeV; + minClusterEdep = m_cfg.minClusterEdep / dd4hep::GeV; + + // summarize the clustering parameters + info("Local clustering (same sector and same layer): " + "Local [x, y] distance between hits <= [{:.4f} mm, {:.4f} mm].", + localDistXY[0], localDistXY[1]); + switch (m_cfg.layerMode) { + case ImagingTopoClusterConfig::ELayerMode::etaphi: + info("Neighbour layers clustering (same sector and layer id within +- {:d}: " + "Global [eta, phi] distance between hits <= [{:.4f}, {:.4f} rad].", + m_cfg.neighbourLayersRange, layerDistEtaPhi[0], layerDistEtaPhi[1]); + break; + case ImagingTopoClusterConfig::ELayerMode::xy: + info("Neighbour layers clustering (same sector and layer id within +- {:d}: " + "Local [x, y] distance between hits <= [{:.4f} mm, {:.4f} mm].", + m_cfg.neighbourLayersRange, layerDistXY[0], layerDistXY[1]); + break; + default: + error("Unknown layer mode."); + } + info("Neighbour sectors clustering (different sector): " + "Global distance between hits <= {:.4f} mm.", + sectorDist); + } + + void process(const Input& input, const Output& output) const final { + + const auto [hits] = input; + auto [proto] = output; + + // Sort hit indices (podio collections do not support std::sort) + auto compare = [&hits](const auto& a, const auto& b) { + // if !(a < b) and !(b < a), then a and b are equivalent + // and only one of them will be allowed in a set + if ((*hits)[a].getLayer() == (*hits)[b].getLayer()) { + return (*hits)[a].getObjectID().index < (*hits)[b].getObjectID().index; + } + return (*hits)[a].getLayer() < (*hits)[b].getLayer(); + }; + // indices contains the remaining hit indices that have not + // been assigned to a group yet + std::set indices(compare); + // set does not have a size yet, so cannot fill with iota + for (std::size_t i = 0; i < hits->size(); ++i) { + indices.insert(i); + } + // ensure no hits were dropped due to equivalency in set + if (hits->size() != indices.size()) { + error("equivalent hits were dropped: #hits {:d}, #indices {:d}", hits->size(), + indices.size()); } - void process(const Input& input, const Output& output) const final { - - const auto [hits] = input; - auto [proto] = output; - - // Sort hit indices (podio collections do not support std::sort) - auto compare = [&hits](const auto& a, const auto& b) { - // if !(a < b) and !(b < a), then a and b are equivalent - // and only one of them will be allowed in a set - if ((*hits)[a].getLayer() == (*hits)[b].getLayer()) { - return (*hits)[a].getObjectID().index < (*hits)[b].getObjectID().index; - } - return (*hits)[a].getLayer() < (*hits)[b].getLayer(); - }; - // indices contains the remaining hit indices that have not - // been assigned to a group yet - std::set indices(compare); - // set does not have a size yet, so cannot fill with iota - for (std::size_t i = 0; i < hits->size(); ++i) { - indices.insert(i); - } - // ensure no hits were dropped due to equivalency in set - if (hits->size() != indices.size()) { - error("equivalent hits were dropped: #hits {:d}, #indices {:d}", hits->size(), indices.size()); - } + // Group neighbouring hits + std::vector> groups; + // because indices changes, the loop over indices requires some care: + // - we must use iterators instead of range-for + // - erase returns an incremented iterator and therefore acts as idx++ + // - when the set becomes empty on erase, idx is invalid and idx++ will be too + // (also applies to loop in bfs_group below) + for (auto idx = indices.begin(); idx != indices.end(); + indices.empty() ? idx = indices.end() : idx) { + + debug("hit {:d}: local position = ({}, {}, {}), global position = ({}, {}, {}), energy = {}", + *idx, (*hits)[*idx].getLocal().x, (*hits)[*idx].getLocal().y, + (*hits)[*idx].getPosition().z, (*hits)[*idx].getPosition().x, + (*hits)[*idx].getPosition().y, (*hits)[*idx].getPosition().z, + (*hits)[*idx].getEnergy()); + + // not energetic enough for cluster center, but could still be cluster hit + if ((*hits)[*idx].getEnergy() < minClusterCenterEdep) { + idx++; + continue; + } - // Group neighbouring hits - std::vector> groups; - // because indices changes, the loop over indices requires some care: - // - we must use iterators instead of range-for - // - erase returns an incremented iterator and therefore acts as idx++ - // - when the set becomes empty on erase, idx is invalid and idx++ will be too - // (also applies to loop in bfs_group below) - for (auto idx = indices.begin(); idx != indices.end(); - indices.empty() ? idx = indices.end() : idx) { - - debug("hit {:d}: local position = ({}, {}, {}), global position = ({}, {}, {}), energy = {}", *idx, - (*hits)[*idx].getLocal().x, (*hits)[*idx].getLocal().y, (*hits)[*idx].getPosition().z, - (*hits)[*idx].getPosition().x, (*hits)[*idx].getPosition().y, (*hits)[*idx].getPosition().z, - (*hits)[*idx].getEnergy() - ); - - // not energetic enough for cluster center, but could still be cluster hit - if ((*hits)[*idx].getEnergy() < minClusterCenterEdep) { - idx++; - continue; - } - - // create a new group, and group all the neighbouring hits - groups.emplace_back(std::list{*idx}); - bfs_group(*hits, indices, groups.back(), *idx); - - // wait with erasing until after bfs_group to ensure iterator is not invalidated in bfs_group - idx = indices.erase(idx); // takes role of idx++ - } - debug("found {} potential clusters (groups of hits)", groups.size()); - for (size_t i = 0; i < groups.size(); ++i) { - debug("group {}: {} hits", i, groups[i].size()); - } + // create a new group, and group all the neighbouring hits + groups.emplace_back(std::list{*idx}); + bfs_group(*hits, indices, groups.back(), *idx); - // form clusters - for (const auto &group : groups) { - if (group.size() < m_cfg.minClusterNhits) { - continue; - } - double energy = 0.; - for (std::size_t idx : group) { - energy += (*hits)[idx].getEnergy(); - } - if (energy < minClusterEdep) { - continue; - } - auto pcl = proto->create(); - for (std::size_t idx : group) { - pcl.addToHits((*hits)[idx]); - pcl.addToWeights(1); - } - } + // wait with erasing until after bfs_group to ensure iterator is not invalidated in bfs_group + idx = indices.erase(idx); // takes role of idx++ + } + debug("found {} potential clusters (groups of hits)", groups.size()); + for (size_t i = 0; i < groups.size(); ++i) { + debug("group {}: {} hits", i, groups[i].size()); } - private: + // form clusters + for (const auto& group : groups) { + if (group.size() < m_cfg.minClusterNhits) { + continue; + } + double energy = 0.; + for (std::size_t idx : group) { + energy += (*hits)[idx].getEnergy(); + } + if (energy < minClusterEdep) { + continue; + } + auto pcl = proto->create(); + for (std::size_t idx : group) { + pcl.addToHits((*hits)[idx]); + pcl.addToWeights(1); + } + } + } + +private: + // helper function to group hits + bool is_neighbour(const edm4eic::CalorimeterHit& h1, const edm4eic::CalorimeterHit& h2) const { + // different sectors, simple distance check + if (h1.getSector() != h2.getSector()) { + return std::hypot((h1.getPosition().x - h2.getPosition().x), + (h1.getPosition().y - h2.getPosition().y), + (h1.getPosition().z - h2.getPosition().z)) <= sectorDist; + } - // helper function to group hits - bool is_neighbour(const edm4eic::CalorimeterHit& h1, const edm4eic::CalorimeterHit& h2) const { - // different sectors, simple distance check - if (h1.getSector() != h2.getSector()) { - return std::hypot((h1.getPosition().x - h2.getPosition().x), - (h1.getPosition().y - h2.getPosition().y), - (h1.getPosition().z - h2.getPosition().z)) <= sectorDist; + // layer check + int ldiff = std::abs(h1.getLayer() - h2.getLayer()); + // same layer, check local positions + if (ldiff == 0) { + return (std::abs(h1.getLocal().x - h2.getLocal().x) <= localDistXY[0]) && + (std::abs(h1.getLocal().y - h2.getLocal().y) <= localDistXY[1]); + } else if (ldiff <= m_cfg.neighbourLayersRange) { + switch (m_cfg.layerMode) { + case eicrecon::ImagingTopoClusterConfig::ELayerMode::etaphi: + return (std::abs(edm4hep::utils::eta(h1.getPosition()) - + edm4hep::utils::eta(h2.getPosition())) <= layerDistEtaPhi[0]) && + (std::abs(edm4hep::utils::angleAzimuthal(h1.getPosition()) - + edm4hep::utils::angleAzimuthal(h2.getPosition())) <= layerDistEtaPhi[1]); + case eicrecon::ImagingTopoClusterConfig::ELayerMode::xy: + return (std::abs(h1.getPosition().x - h2.getPosition().x) <= layerDistXY[0]) && + (std::abs(h1.getPosition().y - h2.getPosition().y) <= layerDistXY[1]); + } + } + // not in adjacent layers + return false; + } + + // grouping function with Breadth-First Search + // note: template to allow Compare only known in local scope of caller + template + void bfs_group(const edm4eic::CalorimeterHitCollection& hits, + std::set& indices, std::list& group, + const std::size_t idx) const { + + // loop over group as it grows, until the end is stable and we reach it + for (auto idx1 = group.begin(); idx1 != group.end(); ++idx1) { + // check neighbours (note comments on loop over set above) + for (auto idx2 = indices.begin(); idx2 != indices.end(); + indices.empty() ? idx2 = indices.end() : idx2) { + + // skip idx1 and original idx + // (we cannot erase idx since it would invalidate iterator in calling scope) + if (*idx2 == *idx1 || *idx2 == idx) { + idx2++; + continue; } - // layer check - int ldiff = std::abs(h1.getLayer() - h2.getLayer()); - // same layer, check local positions - if (ldiff == 0) { - return (std::abs(h1.getLocal().x - h2.getLocal().x) <= localDistXY[0]) && - (std::abs(h1.getLocal().y - h2.getLocal().y) <= localDistXY[1]); - } else if (ldiff <= m_cfg.neighbourLayersRange) { - switch(m_cfg.layerMode){ - case eicrecon::ImagingTopoClusterConfig::ELayerMode::etaphi: - return (std::abs(edm4hep::utils::eta(h1.getPosition()) - edm4hep::utils::eta(h2.getPosition())) <= layerDistEtaPhi[0]) && - (std::abs(edm4hep::utils::angleAzimuthal(h1.getPosition()) - edm4hep::utils::angleAzimuthal(h2.getPosition())) <= - layerDistEtaPhi[1]); - case eicrecon::ImagingTopoClusterConfig::ELayerMode::xy: - return (std::abs(h1.getPosition().x - h2.getPosition().x) <= layerDistXY[0]) && - (std::abs(h1.getPosition().y - h2.getPosition().y) <= layerDistXY[1]); - } + // skip rest of list of hits when we're past relevant layers + //if (hits[*idx2].getLayer() - hits[*idx1].getLayer() > m_cfg.neighbourLayersRange) { + // break; + //} + + // not energetic enough for cluster hit + if (hits[*idx2].getEnergy() < m_cfg.minClusterHitEdep) { + idx2 = indices.erase(idx2); + continue; } - // not in adjacent layers - return false; - } - // grouping function with Breadth-First Search - // note: template to allow Compare only known in local scope of caller - template - void bfs_group(const edm4eic::CalorimeterHitCollection &hits, std::set& indices, std::list &group, const std::size_t idx) const { - - // loop over group as it grows, until the end is stable and we reach it - for (auto idx1 = group.begin(); idx1 != group.end(); ++idx1) { - // check neighbours (note comments on loop over set above) - for (auto idx2 = indices.begin(); idx2 != indices.end(); - indices.empty() ? idx2 = indices.end() : idx2) { - - // skip idx1 and original idx - // (we cannot erase idx since it would invalidate iterator in calling scope) - if (*idx2 == *idx1 || *idx2 == idx) { - idx2++; - continue; - } - - // skip rest of list of hits when we're past relevant layers - //if (hits[*idx2].getLayer() - hits[*idx1].getLayer() > m_cfg.neighbourLayersRange) { - // break; - //} - - // not energetic enough for cluster hit - if (hits[*idx2].getEnergy() < m_cfg.minClusterHitEdep) { - idx2 = indices.erase(idx2); - continue; - } - - if (is_neighbour(hits[*idx1], hits[*idx2])) { - group.push_back(*idx2); - idx2 = indices.erase(idx2); // takes role of idx2++ - } else { - idx2++; - } + if (is_neighbour(hits[*idx1], hits[*idx2])) { + group.push_back(*idx2); + idx2 = indices.erase(idx2); // takes role of idx2++ + } else { + idx2++; } } } - - }; + } +}; } // namespace eicrecon diff --git a/src/algorithms/calorimetry/ImagingTopoClusterConfig.h b/src/algorithms/calorimetry/ImagingTopoClusterConfig.h index 651a0f4619..8eb85d5206 100644 --- a/src/algorithms/calorimetry/ImagingTopoClusterConfig.h +++ b/src/algorithms/calorimetry/ImagingTopoClusterConfig.h @@ -8,58 +8,57 @@ namespace eicrecon { - struct ImagingTopoClusterConfig { +struct ImagingTopoClusterConfig { - // maximum difference in layer numbers that can be considered as neighbours - int neighbourLayersRange = 1; - // maximum distance of local (x, y) to be considered as neighbors at the same layer - std::vector localDistXY = {1.0 * dd4hep::mm, 1.0 * dd4hep::mm}; - // maximum distance of global (eta, phi) to be considered as neighbors at different layers (if layerMode==etaphi) - std::vector layerDistEtaPhi = {0.01, 0.01}; - // maximum distance of global (x, y) to be considered as neighbors at different layers (if layerMode==xy) - std::vector layerDistXY = {1.0 * dd4hep::mm, 1.0 * dd4hep::mm}; - // determines how neighbors are determined for hits in different layers (using either eta and phi, or x and y) - enum ELayerMode {etaphi=0, xy=1} layerMode = etaphi; + // maximum difference in layer numbers that can be considered as neighbours + int neighbourLayersRange = 1; + // maximum distance of local (x, y) to be considered as neighbors at the same layer + std::vector localDistXY = {1.0 * dd4hep::mm, 1.0 * dd4hep::mm}; + // maximum distance of global (eta, phi) to be considered as neighbors at different layers (if layerMode==etaphi) + std::vector layerDistEtaPhi = {0.01, 0.01}; + // maximum distance of global (x, y) to be considered as neighbors at different layers (if layerMode==xy) + std::vector layerDistXY = {1.0 * dd4hep::mm, 1.0 * dd4hep::mm}; + // determines how neighbors are determined for hits in different layers (using either eta and phi, or x and y) + enum ELayerMode { etaphi = 0, xy = 1 } layerMode = etaphi; - // maximum global distance to be considered as neighbors in different sectors - double sectorDist = 1.0 * dd4hep::cm; + // maximum global distance to be considered as neighbors in different sectors + double sectorDist = 1.0 * dd4hep::cm; - // minimum hit energy to participate clustering - double minClusterHitEdep = 0.; - // minimum cluster center energy (to be considered as a seed for cluster) - double minClusterCenterEdep = 0.; - // minimum cluster energy (to save this cluster) - double minClusterEdep = 0.5 * dd4hep::MeV; - // minimum number of hits (to save this cluster) - std::size_t minClusterNhits = 10; + // minimum hit energy to participate clustering + double minClusterHitEdep = 0.; + // minimum cluster center energy (to be considered as a seed for cluster) + double minClusterCenterEdep = 0.; + // minimum cluster energy (to save this cluster) + double minClusterEdep = 0.5 * dd4hep::MeV; + // minimum number of hits (to save this cluster) + std::size_t minClusterNhits = 10; +}; - }; - - std::istream& operator>>(std::istream& in, ImagingTopoClusterConfig::ELayerMode& layerMode) { - std::string s; - in >> s; - // stringifying the enums causes them to be converted to integers before conversion to strings - if (s == "etaphi" or s=="0") { - layerMode = ImagingTopoClusterConfig::ELayerMode::etaphi; - } else if (s == "xy" or s=="1") { - layerMode = ImagingTopoClusterConfig::ELayerMode::xy; - } else { - in.setstate(std::ios::failbit); // Set the fail bit if the input is not valid - } - - return in; +std::istream& operator>>(std::istream& in, ImagingTopoClusterConfig::ELayerMode& layerMode) { + std::string s; + in >> s; + // stringifying the enums causes them to be converted to integers before conversion to strings + if (s == "etaphi" or s == "0") { + layerMode = ImagingTopoClusterConfig::ELayerMode::etaphi; + } else if (s == "xy" or s == "1") { + layerMode = ImagingTopoClusterConfig::ELayerMode::xy; + } else { + in.setstate(std::ios::failbit); // Set the fail bit if the input is not valid } - std::ostream& operator<<(std::ostream& out, ImagingTopoClusterConfig::ELayerMode& layerMode) { - switch(layerMode) { - case ImagingTopoClusterConfig::ELayerMode::etaphi: - out << "etaphi"; - break; - case ImagingTopoClusterConfig::ELayerMode::xy: - out << "xy"; - break; - default: - out.setstate(std::ios::failbit); - } - return out; + + return in; +} +std::ostream& operator<<(std::ostream& out, ImagingTopoClusterConfig::ELayerMode& layerMode) { + switch (layerMode) { + case ImagingTopoClusterConfig::ELayerMode::etaphi: + out << "etaphi"; + break; + case ImagingTopoClusterConfig::ELayerMode::xy: + out << "xy"; + break; + default: + out.setstate(std::ios::failbit); } + return out; +} } // namespace eicrecon diff --git a/src/algorithms/calorimetry/TrackClusterMergeSplitter.cc b/src/algorithms/calorimetry/TrackClusterMergeSplitter.cc index 4fdd643599..7768f1a15e 100644 --- a/src/algorithms/calorimetry/TrackClusterMergeSplitter.cc +++ b/src/algorithms/calorimetry/TrackClusterMergeSplitter.cc @@ -16,27 +16,23 @@ #include "TrackClusterMergeSplitter.h" #include "algorithms/calorimetry/TrackClusterMergeSplitterConfig.h" - - namespace eicrecon { - // -------------------------------------------------------------------------- - //! Initialize algorithm - // -------------------------------------------------------------------------- - void TrackClusterMergeSplitter::init(const dd4hep::Detector* detector) { - - // grab detector id - m_idCalo = detector -> constant(m_cfg.idCalo); - debug("Collecting projections to detector with system id {}", m_idCalo); +// -------------------------------------------------------------------------- +//! Initialize algorithm +// -------------------------------------------------------------------------- +void TrackClusterMergeSplitter::init(const dd4hep::Detector* detector) { - } // end 'init(dd4hep::Detector*)' + // grab detector id + m_idCalo = detector->constant(m_cfg.idCalo); + debug("Collecting projections to detector with system id {}", m_idCalo); +} // end 'init(dd4hep::Detector*)' - - // -------------------------------------------------------------------------- - //! Process inputs - // -------------------------------------------------------------------------- - /*! Primary algorithm call: algorithm ingests a collection +// -------------------------------------------------------------------------- +//! Process inputs +// -------------------------------------------------------------------------- +/*! Primary algorithm call: algorithm ingests a collection * protoclusters and a collection of track projections. * It then decides to merge or split protoclusters according * to the following algorithm: @@ -59,151 +55,83 @@ namespace eicrecon { * projection with hit weighted relative to * the track momentum. */ - void TrackClusterMergeSplitter::process( - const TrackClusterMergeSplitter::Input& input, - const TrackClusterMergeSplitter::Output& output - ) const { - - // grab inputs/outputs - const auto [in_protoclusters, in_projections] = input; - auto [out_protoclusters] = output; - - // exit if no clusters in collection - if (in_protoclusters->size() == 0) { - debug("No proto-clusters in input collection."); - return; +void TrackClusterMergeSplitter::process(const TrackClusterMergeSplitter::Input& input, + const TrackClusterMergeSplitter::Output& output) const { + + // grab inputs/outputs + const auto [in_protoclusters, in_projections] = input; + auto [out_protoclusters] = output; + + // exit if no clusters in collection + if (in_protoclusters->size() == 0) { + debug("No proto-clusters in input collection."); + return; + } + + // ------------------------------------------------------------------------ + // 1. Identify projections to calorimeter + // ------------------------------------------------------------------------ + VecProj vecProject; + get_projections(in_projections, vecProject); + + // ------------------------------------------------------------------------ + // 2. Match relevant projections to clusters + // ------------------------------------------------------------------------ + MapToVecProj mapProjToSplit; + if (vecProject.size() == 0) { + debug("No projections to match clusters to."); + return; + } else { + match_clusters_to_tracks(in_protoclusters, vecProject, mapProjToSplit); + } + + // ------------------------------------------------------------------------ + // 3. Loop over projection-cluster pairs to check if merging is needed + // ------------------------------------------------------------------------ + SetClust setUsedClust; + MapToVecClust mapClustToMerge; + for (auto& [clustSeed, vecMatchProj] : mapProjToSplit) { + + // at this point, track-cluster matches are 1-to-1 + // so grab matched track + auto projSeed = vecMatchProj.front(); + + // skip if cluster is already used + if (setUsedClust.count(clustSeed)) { + continue; } - // ------------------------------------------------------------------------ - // 1. Identify projections to calorimeter - // ------------------------------------------------------------------------ - VecProj vecProject; - get_projections(in_projections, vecProject); - - // ------------------------------------------------------------------------ - // 2. Match relevant projections to clusters - // ------------------------------------------------------------------------ - MapToVecProj mapProjToSplit; - if (vecProject.size() == 0) { - debug("No projections to match clusters to."); - return; - } else { - match_clusters_to_tracks(in_protoclusters, vecProject, mapProjToSplit); + // add cluster to list and flag as used + mapClustToMerge[clustSeed].push_back(clustSeed); + setUsedClust.insert(clustSeed); + + // grab cluster energy and projection momentum + const float eClustSeed = get_cluster_energy(clustSeed); + const float eProjSeed = m_cfg.avgEP * edm4hep::utils::magnitude(projSeed.momentum); + + // ---------------------------------------------------------------------- + // 3.i. Calculate significance + // ---------------------------------------------------------------------- + const float sigSeed = (eClustSeed - eProjSeed) / m_cfg.sigEP; + trace("Seed energy = {}, expected energy = {}, significance = {}", eClustSeed, eProjSeed, + sigSeed); + + // ---------------------------------------------------------------------- + // 3.ii. If significance is above threshold, do nothing. + // Otherwise identify clusters to merge. + // ---------------------------------------------------------------------- + if (sigSeed > m_cfg.minSigCut) { + continue; } - // ------------------------------------------------------------------------ - // 3. Loop over projection-cluster pairs to check if merging is needed - // ------------------------------------------------------------------------ - SetClust setUsedClust; - MapToVecClust mapClustToMerge; - for (auto& [clustSeed, vecMatchProj] : mapProjToSplit) { - - // at this point, track-cluster matches are 1-to-1 - // so grab matched track - auto projSeed = vecMatchProj.front(); - - // skip if cluster is already used - if (setUsedClust.count(clustSeed)) { - continue; - } - - // add cluster to list and flag as used - mapClustToMerge[clustSeed].push_back( clustSeed ); - setUsedClust.insert( clustSeed ); - - // grab cluster energy and projection momentum - const float eClustSeed = get_cluster_energy(clustSeed); - const float eProjSeed = m_cfg.avgEP * edm4hep::utils::magnitude(projSeed.momentum); - - // ---------------------------------------------------------------------- - // 3.i. Calculate significance - // ---------------------------------------------------------------------- - const float sigSeed = (eClustSeed - eProjSeed) / m_cfg.sigEP; - trace("Seed energy = {}, expected energy = {}, significance = {}", eClustSeed, eProjSeed, sigSeed); - - // ---------------------------------------------------------------------- - // 3.ii. If significance is above threshold, do nothing. - // Otherwise identify clusters to merge. - // ---------------------------------------------------------------------- - if (sigSeed > m_cfg.minSigCut) { - continue; - } + // get eta, phi of seed + const auto posSeed = get_cluster_position(clustSeed); + const float etaSeed = edm4hep::utils::eta(posSeed); + const float phiSeed = edm4hep::utils::angleAzimuthal(posSeed); - // get eta, phi of seed - const auto posSeed = get_cluster_position(clustSeed); - const float etaSeed = edm4hep::utils::eta(posSeed); - const float phiSeed = edm4hep::utils::angleAzimuthal(posSeed); - - // loop over other clusters - float eClustSum = eClustSeed; - float sigSum = sigSeed; - for (auto in_cluster : *in_protoclusters) { - - // ignore used clusters - if (setUsedClust.count(in_cluster)) { - continue; - } - - // get eta, phi of cluster - const auto posClust = get_cluster_position(in_cluster); - const float etaClust = edm4hep::utils::eta(posClust); - const float phiClust = edm4hep::utils::angleAzimuthal(posClust); - - // get distance to seed - const float drToSeed = std::hypot( - etaSeed - etaClust, - std::remainder(phiSeed - phiClust, 2. * M_PI) - ); - - // -------------------------------------------------------------------- - // If inside merging-window, add to list of clusters to merge - // -------------------------------------------------------------------- - if (drToSeed > m_cfg.drAdd) { - continue; - } else { - mapClustToMerge[clustSeed].push_back( in_cluster ); - setUsedClust.insert( in_cluster ); - } - - // -------------------------------------------------------------------- - // if picked up cluster w/ matched track, add projection to list - // -------------------------------------------------------------------- - if (mapProjToSplit.count(in_cluster)) { - vecMatchProj.insert( - vecMatchProj.end(), - mapProjToSplit[in_cluster].begin(), - mapProjToSplit[in_cluster].end() - ); - } - - // increment sums and output debugging - eClustSum += get_cluster_energy(in_cluster); - sigSum = (eClustSum - eProjSeed) / m_cfg.sigEP; - trace( - "{} clusters to merge: current sum = {}, current significance = {}, {} track(s) pointing to merged cluster", - mapClustToMerge[clustSeed].size(), - eClustSum, - sigSum, - vecMatchProj.size() - ); - } // end cluster loop - } // end matched cluster-projection loop - - // ------------------------------------------------------------------------ - // 4. Create an output protocluster for each merged cluster and for - // each track pointing to merged cluster - // ------------------------------------------------------------------------ - for (auto& [clustSeed, vecClustToMerge] : mapClustToMerge) { - merge_and_split_clusters( - vecClustToMerge, - mapProjToSplit[clustSeed], - out_protoclusters - ); - } // end clusters to merge loop - - // ------------------------------------------------------------------------ - // copy unused clusters to output - // ------------------------------------------------------------------------ + // loop over other clusters + float eClustSum = eClustSeed; + float sigSum = sigSeed; for (auto in_cluster : *in_protoclusters) { // ignore used clusters @@ -211,239 +139,269 @@ namespace eicrecon { continue; } - // copy cluster and add to output collection - edm4eic::MutableProtoCluster out_cluster = in_cluster.clone(); - out_protoclusters->push_back(out_cluster); - trace("Copied input cluster {} onto output cluster {}", - in_cluster.getObjectID().index, - out_cluster.getObjectID().index - ); - - } // end cluster loop - - } // end 'process(Input&, Output&)' + // get eta, phi of cluster + const auto posClust = get_cluster_position(in_cluster); + const float etaClust = edm4hep::utils::eta(posClust); + const float phiClust = edm4hep::utils::angleAzimuthal(posClust); + // get distance to seed + const float drToSeed = + std::hypot(etaSeed - etaClust, std::remainder(phiSeed - phiClust, 2. * M_PI)); + // -------------------------------------------------------------------- + // If inside merging-window, add to list of clusters to merge + // -------------------------------------------------------------------- + if (drToSeed > m_cfg.drAdd) { + continue; + } else { + mapClustToMerge[clustSeed].push_back(in_cluster); + setUsedClust.insert(in_cluster); + } - // -------------------------------------------------------------------------- - //! Collect projections pointing to calorimeter - // -------------------------------------------------------------------------- - void TrackClusterMergeSplitter::get_projections( - const edm4eic::TrackSegmentCollection* projections, - VecProj& relevant_projects - ) const { + // -------------------------------------------------------------------- + // if picked up cluster w/ matched track, add projection to list + // -------------------------------------------------------------------- + if (mapProjToSplit.count(in_cluster)) { + vecMatchProj.insert(vecMatchProj.end(), mapProjToSplit[in_cluster].begin(), + mapProjToSplit[in_cluster].end()); + } - // return if projections are empty - if (projections->size() == 0) { - debug("No projections in input collection."); - return; + // increment sums and output debugging + eClustSum += get_cluster_energy(in_cluster); + sigSum = (eClustSum - eProjSeed) / m_cfg.sigEP; + trace("{} clusters to merge: current sum = {}, current significance = {}, {} track(s) " + "pointing to merged cluster", + mapClustToMerge[clustSeed].size(), eClustSum, sigSum, vecMatchProj.size()); + } // end cluster loop + } // end matched cluster-projection loop + + // ------------------------------------------------------------------------ + // 4. Create an output protocluster for each merged cluster and for + // each track pointing to merged cluster + // ------------------------------------------------------------------------ + for (auto& [clustSeed, vecClustToMerge] : mapClustToMerge) { + merge_and_split_clusters(vecClustToMerge, mapProjToSplit[clustSeed], out_protoclusters); + } // end clusters to merge loop + + // ------------------------------------------------------------------------ + // copy unused clusters to output + // ------------------------------------------------------------------------ + for (auto in_cluster : *in_protoclusters) { + + // ignore used clusters + if (setUsedClust.count(in_cluster)) { + continue; } - // collect projections - for (auto project : *projections) { - for (auto point : project.getPoints()) { - if ( - (point.system == m_idCalo) && - (point.surface == 1) - ) { - relevant_projects.push_back(point); - } - } // end point loop - } // end projection loop - debug("Collected relevant projections: {} to process", relevant_projects.size()); - - } // end 'get_projections(edm4eic::CalorimeterHit&, edm4eic::TrackSegmentCollection&, VecTrkPoint&)' - + // copy cluster and add to output collection + edm4eic::MutableProtoCluster out_cluster = in_cluster.clone(); + out_protoclusters->push_back(out_cluster); + trace("Copied input cluster {} onto output cluster {}", in_cluster.getObjectID().index, + out_cluster.getObjectID().index); + + } // end cluster loop + +} // end 'process(Input&, Output&)' + +// -------------------------------------------------------------------------- +//! Collect projections pointing to calorimeter +// -------------------------------------------------------------------------- +void TrackClusterMergeSplitter::get_projections(const edm4eic::TrackSegmentCollection* projections, + VecProj& relevant_projects) const { + + // return if projections are empty + if (projections->size() == 0) { + debug("No projections in input collection."); + return; + } + + // collect projections + for (auto project : *projections) { + for (auto point : project.getPoints()) { + if ((point.system == m_idCalo) && (point.surface == 1)) { + relevant_projects.push_back(point); + } + } // end point loop + } // end projection loop + debug("Collected relevant projections: {} to process", relevant_projects.size()); +} // end 'get_projections(edm4eic::CalorimeterHit&, edm4eic::TrackSegmentCollection&, VecTrkPoint&)' - // -------------------------------------------------------------------------- - //! Match clusters to track projections - // -------------------------------------------------------------------------- - /*! FIXME remove this once cluster-track matching has been centralized +// -------------------------------------------------------------------------- +//! Match clusters to track projections +// -------------------------------------------------------------------------- +/*! FIXME remove this once cluster-track matching has been centralized */ - void TrackClusterMergeSplitter::match_clusters_to_tracks( - const edm4eic::ProtoClusterCollection* clusters, - const VecProj& projections, - MapToVecProj& matches - ) const { - - - // loop over relevant projections - for (uint32_t iProject = 0; iProject < projections.size(); ++iProject) { - - // grab projection - auto project = projections[iProject]; - - // get eta, phi of projection - const float etaProj = edm4hep::utils::eta(project.position); - const float phiProj = edm4hep::utils::angleAzimuthal(project.position); - - // to store matched cluster - edm4eic::ProtoCluster match; - - // find closest cluster - bool foundMatch = false; - float dMatch = m_cfg.drAdd; - for (auto cluster : *clusters) { - - // get eta, phi of cluster - const auto posClust = get_cluster_position(cluster); - const float etaClust = edm4hep::utils::eta(posClust); - const float phiClust = edm4hep::utils::angleAzimuthal(posClust); - - // calculate distance to centroid - const float dist = std::hypot( - etaProj - etaClust, - std::remainder(phiProj - phiClust, 2. * M_PI) - ); - - // if closer, set match to current projection - if (dist <= dMatch) { - foundMatch = true; - dMatch = dist; - match = cluster; - } - } // end cluster loop - - // record match if found - if (foundMatch) { - matches[match].push_back(project); - trace("Matched cluster to track projection: eta-phi distance = {}", dMatch); +void TrackClusterMergeSplitter::match_clusters_to_tracks( + const edm4eic::ProtoClusterCollection* clusters, const VecProj& projections, + MapToVecProj& matches) const { + + // loop over relevant projections + for (uint32_t iProject = 0; iProject < projections.size(); ++iProject) { + + // grab projection + auto project = projections[iProject]; + + // get eta, phi of projection + const float etaProj = edm4hep::utils::eta(project.position); + const float phiProj = edm4hep::utils::angleAzimuthal(project.position); + + // to store matched cluster + edm4eic::ProtoCluster match; + + // find closest cluster + bool foundMatch = false; + float dMatch = m_cfg.drAdd; + for (auto cluster : *clusters) { + + // get eta, phi of cluster + const auto posClust = get_cluster_position(cluster); + const float etaClust = edm4hep::utils::eta(posClust); + const float phiClust = edm4hep::utils::angleAzimuthal(posClust); + + // calculate distance to centroid + const float dist = + std::hypot(etaProj - etaClust, std::remainder(phiProj - phiClust, 2. * M_PI)); + + // if closer, set match to current projection + if (dist <= dMatch) { + foundMatch = true; + dMatch = dist; + match = cluster; } - } // end cluster loop - debug("Finished matching clusters to track projections: {} matches", matches.size()); - - } // end 'match_clusters_to_tracks(edm4eic::ClusterCollection*, VecTrkPoint&, MapToVecProj&)' + } // end cluster loop + // record match if found + if (foundMatch) { + matches[match].push_back(project); + trace("Matched cluster to track projection: eta-phi distance = {}", dMatch); + } + } // end cluster loop + debug("Finished matching clusters to track projections: {} matches", matches.size()); +} // end 'match_clusters_to_tracks(edm4eic::ClusterCollection*, VecTrkPoint&, MapToVecProj&)' - // -------------------------------------------------------------------------- - //! Merge identified clusters and split if needed - // -------------------------------------------------------------------------- - /*! If multiple tracks are pointing to merged cluster, a new protocluster +// -------------------------------------------------------------------------- +//! Merge identified clusters and split if needed +// -------------------------------------------------------------------------- +/*! If multiple tracks are pointing to merged cluster, a new protocluster * is created for each track w/ hits weighted by its distance to the track * and the track's momentum. */ - void TrackClusterMergeSplitter::merge_and_split_clusters( - const VecClust& to_merge, - const VecProj& to_split, - edm4eic::ProtoClusterCollection* out_protoclusters - ) const { - - // if only 1 matched track, no need to split - if (to_split.size() == 1) { - edm4eic::MutableProtoCluster new_clust = out_protoclusters->create(); - for (const auto& old_clust : to_merge) { - for (const auto& hit : old_clust.getHits()) { - new_clust.addToHits( hit ); - new_clust.addToWeights( 1. ); - } - trace("Merged input cluster {} into output cluster {}", old_clust.getObjectID().index, new_clust.getObjectID().index); - } - return; - } - - // otherwise split merged cluster for each matched track - std::vector new_clusters; - for (const auto& proj : to_split) { - new_clusters.push_back( out_protoclusters->create() ); - } - trace("Splitting merged cluster across {} tracks", to_split.size()); +void TrackClusterMergeSplitter::merge_and_split_clusters( + const VecClust& to_merge, const VecProj& to_split, + edm4eic::ProtoClusterCollection* out_protoclusters) const { - // loop over all hits from all clusters to merge - std::vector weights( to_split.size(), 1. ); + // if only 1 matched track, no need to split + if (to_split.size() == 1) { + edm4eic::MutableProtoCluster new_clust = out_protoclusters->create(); for (const auto& old_clust : to_merge) { for (const auto& hit : old_clust.getHits()) { + new_clust.addToHits(hit); + new_clust.addToWeights(1.); + } + trace("Merged input cluster {} into output cluster {}", old_clust.getObjectID().index, + new_clust.getObjectID().index); + } + return; + } + + // otherwise split merged cluster for each matched track + std::vector new_clusters; + for (const auto& proj : to_split) { + new_clusters.push_back(out_protoclusters->create()); + } + trace("Splitting merged cluster across {} tracks", to_split.size()); + + // loop over all hits from all clusters to merge + std::vector weights(to_split.size(), 1.); + for (const auto& old_clust : to_merge) { + for (const auto& hit : old_clust.getHits()) { + + // calculate hit's weight for each track + for (std::size_t iProj = 0; const auto& proj : to_split) { + + // get track eta, phi + const float etaProj = edm4hep::utils::eta(proj.position); + const float phiProj = edm4hep::utils::angleAzimuthal(proj.position); + + // get hit eta, phi + const float etaHit = edm4hep::utils::eta(hit.getPosition()); + const float phiHit = edm4hep::utils::angleAzimuthal(hit.getPosition()); + + // get track momentum, distance to hit + const float mom = edm4hep::utils::magnitude(proj.momentum); + const float dist = + std::hypot(etaHit - etaProj, std::remainder(phiHit - phiProj, 2. * M_PI)); + + // set weight + weights[iProj] = std::exp(-1. * dist / m_cfg.transverseEnergyProfileScale) * mom; + ++iProj; + } - // calculate hit's weight for each track - for (std::size_t iProj = 0; const auto& proj : to_split) { - - // get track eta, phi - const float etaProj = edm4hep::utils::eta(proj.position); - const float phiProj = edm4hep::utils::angleAzimuthal(proj.position); - - // get hit eta, phi - const float etaHit = edm4hep::utils::eta(hit.getPosition()); - const float phiHit = edm4hep::utils::angleAzimuthal(hit.getPosition()); - - // get track momentum, distance to hit - const float mom = edm4hep::utils::magnitude(proj.momentum); - const float dist = std::hypot( - etaHit - etaProj, - std::remainder(phiHit - phiProj, 2. * M_PI) - ); - - // set weight - weights[iProj] = std::exp(-1. * dist / m_cfg.transverseEnergyProfileScale) * mom; - ++iProj; - } - - // normalize weights - float wTotal = 0.; - for (const float weight : weights) { - wTotal += weight; - } - for (float& weight : weights) { - weight /= wTotal; - } - - // add hit to each split merged cluster w/ relevant weight - for (std::size_t iProj = 0; auto& new_clust : new_clusters) { - new_clust.addToHits( hit ); - new_clust.addToWeights( weights[iProj] ); - } - - } // end hits to merge loop - } // end clusters to merge loop - - } // end 'merge_and_split_clusters(VecClust&, VecProj&, edm4eic::MutableCluster&)' - + // normalize weights + float wTotal = 0.; + for (const float weight : weights) { + wTotal += weight; + } + for (float& weight : weights) { + weight /= wTotal; + } + // add hit to each split merged cluster w/ relevant weight + for (std::size_t iProj = 0; auto& new_clust : new_clusters) { + new_clust.addToHits(hit); + new_clust.addToWeights(weights[iProj]); + } - // -------------------------------------------------------------------------- - //! Grab current energy of protocluster - // -------------------------------------------------------------------------- - float TrackClusterMergeSplitter::get_cluster_energy(const edm4eic::ProtoCluster& clust) const { + } // end hits to merge loop + } // end clusters to merge loop - float eClust = 0.; - for (auto hit : clust.getHits()) { - eClust += hit.getEnergy(); - } - return eClust / m_cfg.sampFrac; +} // end 'merge_and_split_clusters(VecClust&, VecProj&, edm4eic::MutableCluster&)' - } // end 'get_cluster_energy(edm4eic::ProtoCluster&)' +// -------------------------------------------------------------------------- +//! Grab current energy of protocluster +// -------------------------------------------------------------------------- +float TrackClusterMergeSplitter::get_cluster_energy(const edm4eic::ProtoCluster& clust) const { + float eClust = 0.; + for (auto hit : clust.getHits()) { + eClust += hit.getEnergy(); + } + return eClust / m_cfg.sampFrac; +} // end 'get_cluster_energy(edm4eic::ProtoCluster&)' - // -------------------------------------------------------------------------- - //! Get current center of protocluster - // -------------------------------------------------------------------------- - edm4hep::Vector3f TrackClusterMergeSplitter::get_cluster_position(const edm4eic::ProtoCluster& clust) const { +// -------------------------------------------------------------------------- +//! Get current center of protocluster +// -------------------------------------------------------------------------- +edm4hep::Vector3f +TrackClusterMergeSplitter::get_cluster_position(const edm4eic::ProtoCluster& clust) const { - // grab total energy - const float eClust = get_cluster_energy(clust) * m_cfg.sampFrac; + // grab total energy + const float eClust = get_cluster_energy(clust) * m_cfg.sampFrac; - // calculate energy-weighted center - float wTotal = 0.; - edm4hep::Vector3f position(0., 0., 0.); - for (auto hit : clust.getHits()) { + // calculate energy-weighted center + float wTotal = 0.; + edm4hep::Vector3f position(0., 0., 0.); + for (auto hit : clust.getHits()) { - // calculate weight - float weight = hit.getEnergy() / eClust; - wTotal += weight; + // calculate weight + float weight = hit.getEnergy() / eClust; + wTotal += weight; - // update cluster position - position = position + (hit.getPosition() * weight); - } + // update cluster position + position = position + (hit.getPosition() * weight); + } - float norm = 1.; - if (wTotal == 0.) { - warning("Total weight of 0 in position calculation!"); - } else { - norm = wTotal; - } - return position / norm; + float norm = 1.; + if (wTotal == 0.) { + warning("Total weight of 0 in position calculation!"); + } else { + norm = wTotal; + } + return position / norm; - } // end 'get_cluster_position(edm4eic::ProtoCluster&)' +} // end 'get_cluster_position(edm4eic::ProtoCluster&)' -} // end eicrecon namespace +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/TrackClusterMergeSplitter.h b/src/algorithms/calorimetry/TrackClusterMergeSplitter.h index e38e7e608e..a5bda213a1 100644 --- a/src/algorithms/calorimetry/TrackClusterMergeSplitter.h +++ b/src/algorithms/calorimetry/TrackClusterMergeSplitter.h @@ -21,97 +21,81 @@ // for algorithm configuration #include "algorithms/interfaces/WithPodConfig.h" - - namespace eicrecon { - // -------------------------------------------------------------------------- - //! Comparator struct for protoclusters - // -------------------------------------------------------------------------- - /*! Organizes protoclusters by their ObjectID's in decreasing collection +// -------------------------------------------------------------------------- +//! Comparator struct for protoclusters +// -------------------------------------------------------------------------- +/*! Organizes protoclusters by their ObjectID's in decreasing collection * ID first, and second by decreasing index second. */ - struct CompareProto { - - bool operator() (const edm4eic::ProtoCluster& lhs, const edm4eic::ProtoCluster& rhs) const { - if (lhs.getObjectID().collectionID == rhs.getObjectID().collectionID) { - return (lhs.getObjectID().index < rhs.getObjectID().index); - } else { - return (lhs.getObjectID().collectionID < rhs.getObjectID().collectionID); - } - } - - }; // end CompareObjectID - - - - // -------------------------------------------------------------------------- - //! Convenience types - // -------------------------------------------------------------------------- - using VecProj = std::vector; - using VecClust = std::vector; - using SetClust = std::set; - using MapToVecProj = std::map; - using MapToVecClust = std::map; - - - - // -------------------------------------------------------------------------- - //! Algorithm input/output - // -------------------------------------------------------------------------- - using TrackClusterMergeSplitterAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::ProtoClusterCollection, - edm4eic::TrackSegmentCollection - >, - algorithms::Output< - edm4eic::ProtoClusterCollection - > - >; - +struct CompareProto { - - // -------------------------------------------------------------------------- - //! Track-Based Cluster Merger/Splitter - // -------------------------------------------------------------------------- - /*! An algorithm which takes a collection of proto-clusters, matches + bool operator()(const edm4eic::ProtoCluster& lhs, const edm4eic::ProtoCluster& rhs) const { + if (lhs.getObjectID().collectionID == rhs.getObjectID().collectionID) { + return (lhs.getObjectID().index < rhs.getObjectID().index); + } else { + return (lhs.getObjectID().collectionID < rhs.getObjectID().collectionID); + } + } + +}; // end CompareObjectID + +// -------------------------------------------------------------------------- +//! Convenience types +// -------------------------------------------------------------------------- +using VecProj = std::vector; +using VecClust = std::vector; +using SetClust = std::set; +using MapToVecProj = std::map; +using MapToVecClust = std::map; + +// -------------------------------------------------------------------------- +//! Algorithm input/output +// -------------------------------------------------------------------------- +using TrackClusterMergeSplitterAlgorithm = algorithms::Algorithm< + algorithms::Input, + algorithms::Output>; + +// -------------------------------------------------------------------------- +//! Track-Based Cluster Merger/Splitter +// -------------------------------------------------------------------------- +/*! An algorithm which takes a collection of proto-clusters, matches * track projections, and then decides to merge or split those proto- * clusters based on average E/p from simulations. * * Heavily inspired by Eur. Phys. J. C (2017) 77:466 */ - class TrackClusterMergeSplitter : - public TrackClusterMergeSplitterAlgorithm, - public WithPodConfig - { - - public: - - // ctor - TrackClusterMergeSplitter(std::string_view name) : - TrackClusterMergeSplitterAlgorithm { - name, - {"InputProtoClusterCollection", "InputTrackProjections"}, - {"OutputProtoClusterCollection"}, - "Merges or splits clusters based on tracks projected to them." - } {} - - // public methods - void init(const dd4hep::Detector* detector); - void process (const Input&, const Output&) const final; - - private: - - // private methods - void get_projections(const edm4eic::TrackSegmentCollection* projections, VecProj& relevant_projects) const; - void match_clusters_to_tracks(const edm4eic::ProtoClusterCollection* clusters, const VecProj& projections, MapToVecProj& matches) const; - void merge_and_split_clusters(const VecClust& to_merge, const VecProj& to_split, edm4eic::ProtoClusterCollection* out_protoclusters) const; - float get_cluster_energy(const edm4eic::ProtoCluster& clust) const; - edm4hep::Vector3f get_cluster_position(const edm4eic::ProtoCluster& clust) const; - - // calorimeter id - int m_idCalo {0}; - - }; // end TrackClusterMergeSplitter - -} // end eicrecon namespace +class TrackClusterMergeSplitter : public TrackClusterMergeSplitterAlgorithm, + public WithPodConfig { + +public: + // ctor + TrackClusterMergeSplitter(std::string_view name) + : TrackClusterMergeSplitterAlgorithm{ + name, + {"InputProtoClusterCollection", "InputTrackProjections"}, + {"OutputProtoClusterCollection"}, + "Merges or splits clusters based on tracks projected to them."} {} + + // public methods + void init(const dd4hep::Detector* detector); + void process(const Input&, const Output&) const final; + +private: + // private methods + void get_projections(const edm4eic::TrackSegmentCollection* projections, + VecProj& relevant_projects) const; + void match_clusters_to_tracks(const edm4eic::ProtoClusterCollection* clusters, + const VecProj& projections, MapToVecProj& matches) const; + void merge_and_split_clusters(const VecClust& to_merge, const VecProj& to_split, + edm4eic::ProtoClusterCollection* out_protoclusters) const; + float get_cluster_energy(const edm4eic::ProtoCluster& clust) const; + edm4hep::Vector3f get_cluster_position(const edm4eic::ProtoCluster& clust) const; + + // calorimeter id + int m_idCalo{0}; + +}; // end TrackClusterMergeSplitter + +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/TrackClusterMergeSplitterConfig.h b/src/algorithms/calorimetry/TrackClusterMergeSplitterConfig.h index 13f37c6f54..6a1f0b0b20 100644 --- a/src/algorithms/calorimetry/TrackClusterMergeSplitterConfig.h +++ b/src/algorithms/calorimetry/TrackClusterMergeSplitterConfig.h @@ -7,19 +7,19 @@ namespace eicrecon { - struct TrackClusterMergeSplitterConfig { +struct TrackClusterMergeSplitterConfig { - std::string idCalo = "HcalBarrel_ID"; // id of calorimeter to match projections to + std::string idCalo = "HcalBarrel_ID"; // id of calorimeter to match projections to - double minSigCut = -1.; // min significance - double avgEP = 1.0; // mean E/p - double sigEP = 1.0; // rms of E/p - double drAdd = 0.4; // window to add clusters - double sampFrac = 1.0; // allows for sampling fraction correction + double minSigCut = -1.; // min significance + double avgEP = 1.0; // mean E/p + double sigEP = 1.0; // rms of E/p + double drAdd = 0.4; // window to add clusters + double sampFrac = 1.0; // allows for sampling fraction correction - // scale for hit-track distance - double transverseEnergyProfileScale = 1.0; + // scale for hit-track distance + double transverseEnergyProfileScale = 1.0; - }; // end TrackClusterMergeSplitterConfig +}; // end TrackClusterMergeSplitterConfig -} // end eicrecon namespace +} // namespace eicrecon diff --git a/src/algorithms/calorimetry/TruthEnergyPositionClusterMerger.h b/src/algorithms/calorimetry/TruthEnergyPositionClusterMerger.h index d41293d27c..5ed3709f26 100644 --- a/src/algorithms/calorimetry/TruthEnergyPositionClusterMerger.h +++ b/src/algorithms/calorimetry/TruthEnergyPositionClusterMerger.h @@ -18,21 +18,15 @@ namespace eicrecon { - using TruthEnergyPositionClusterMergerAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4hep::MCParticleCollection, - edm4eic::ClusterCollection, - edm4eic::MCRecoClusterParticleAssociationCollection, - edm4eic::ClusterCollection, - edm4eic::MCRecoClusterParticleAssociationCollection - >, - algorithms::Output< - edm4eic::ClusterCollection, - edm4eic::MCRecoClusterParticleAssociationCollection - > - >; - - /** Simple algorithm to merge the energy measurement from cluster1 with the position +using TruthEnergyPositionClusterMergerAlgorithm = algorithms::Algorithm< + algorithms::Input, + algorithms::Output>; + +/** Simple algorithm to merge the energy measurement from cluster1 with the position * measurement of cluster2 (in case matching clusters are found). If not, it will * propagate the raw cluster from cluster1 or cluster2 * @@ -40,176 +34,183 @@ namespace eicrecon { * * \ingroup reco */ - class TruthEnergyPositionClusterMerger - : public TruthEnergyPositionClusterMergerAlgorithm { +class TruthEnergyPositionClusterMerger : public TruthEnergyPositionClusterMergerAlgorithm { - public: - TruthEnergyPositionClusterMerger(std::string_view name) - : TruthEnergyPositionClusterMergerAlgorithm{name, - {"mcParticles", - "energyClusterCollection", "energyClusterAssociations", - "positionClusterCollection", "positionClusterAssociations"}, - {"outputClusterCollection", "outputClusterAssociations"}, - "Merge energy and position clusters based on truth."} {} +public: + TruthEnergyPositionClusterMerger(std::string_view name) + : TruthEnergyPositionClusterMergerAlgorithm{ + name, + {"mcParticles", "energyClusterCollection", "energyClusterAssociations", + "positionClusterCollection", "positionClusterAssociations"}, + {"outputClusterCollection", "outputClusterAssociations"}, + "Merge energy and position clusters based on truth."} {} - public: - void init() { } +public: + void init() {} - void process(const Input& input, const Output& output) const final { + void process(const Input& input, const Output& output) const final { - const auto [mcparticles, energy_clus, energy_assoc, pos_clus, pos_assoc] = input; - auto [merged_clus, merged_assoc] = output; + const auto [mcparticles, energy_clus, energy_assoc, pos_clus, pos_assoc] = input; + auto [merged_clus, merged_assoc] = output; - debug( "Merging energy and position clusters for new event" ); + debug("Merging energy and position clusters for new event"); - if (energy_clus->size() == 0 && pos_clus->size() == 0) { - debug( "Nothing to do for this event, returning..." ); - return; - } + if (energy_clus->size() == 0 && pos_clus->size() == 0) { + debug("Nothing to do for this event, returning..."); + return; + } - debug( "Step 0/2: Getting indexed list of clusters..." ); + debug("Step 0/2: Getting indexed list of clusters..."); - // get an indexed map of all clusters - debug(" --> Indexing energy clusters"); - auto energyMap = indexedClusters(*energy_clus, *energy_assoc); - trace(" --> Found these energy clusters:"); - for (const auto &[mcID, eclus]: energyMap) { - trace(" --> energy cluster {}, mcID: {}, energy: {}", eclus.getObjectID().index, mcID, eclus.getEnergy()); - } - debug(" --> Indexing position clusters"); - auto posMap = indexedClusters(*pos_clus, *pos_assoc); - trace(" --> Found these position clusters:"); - for (const auto &[mcID, pclus]: posMap) { - trace(" --> position cluster {}, mcID: {}, energy: {}", pclus.getObjectID().index, mcID, pclus.getEnergy()); - } + // get an indexed map of all clusters + debug(" --> Indexing energy clusters"); + auto energyMap = indexedClusters(*energy_clus, *energy_assoc); + trace(" --> Found these energy clusters:"); + for (const auto& [mcID, eclus] : energyMap) { + trace(" --> energy cluster {}, mcID: {}, energy: {}", eclus.getObjectID().index, mcID, + eclus.getEnergy()); + } + debug(" --> Indexing position clusters"); + auto posMap = indexedClusters(*pos_clus, *pos_assoc); + trace(" --> Found these position clusters:"); + for (const auto& [mcID, pclus] : posMap) { + trace(" --> position cluster {}, mcID: {}, energy: {}", pclus.getObjectID().index, mcID, + pclus.getEnergy()); + } - // loop over all position clusters and match with energy clusters - debug( "Step 1/2: Matching all position clusters to the available energy clusters..." ); - for (const auto &[mcID, pclus]: posMap) { - - debug(" --> Processing position cluster {}, mcID: {}, energy: {}", pclus.getObjectID().index, mcID, pclus.getEnergy()); - if (energyMap.count(mcID)) { - - const auto &eclus = energyMap[mcID]; - - auto new_clus = merged_clus->create(); - new_clus.setEnergy(eclus.getEnergy()); - new_clus.setEnergyError(eclus.getEnergyError()); - new_clus.setTime(pclus.getTime()); - new_clus.setNhits(pclus.getNhits() + eclus.getNhits()); - new_clus.setPosition(pclus.getPosition()); - new_clus.setPositionError(pclus.getPositionError()); - new_clus.addToClusters(pclus); - new_clus.addToClusters(eclus); - for (const auto &cl: {pclus, eclus}) { - for (const auto &hit: cl.getHits()) { - new_clus.addToHits(hit); - } - new_clus.addToSubdetectorEnergies(cl.getEnergy()); - } - for (const auto ¶m: pclus.getShapeParameters()) { - new_clus.addToShapeParameters(param); - } - debug(" --> Found matching energy cluster {}, energy: {}", eclus.getObjectID().index, eclus.getEnergy() ); - debug(" --> Created new combined cluster {}, energy: {}", new_clus.getObjectID().index, new_clus.getEnergy() ); - - // set association - auto clusterassoc = merged_assoc->create(); - clusterassoc.setRecID(new_clus.getObjectID().index); - clusterassoc.setSimID(mcID); - clusterassoc.setWeight(1.0); - clusterassoc.setRec(new_clus); - clusterassoc.setSim((*mcparticles)[mcID]); - - // erase the energy cluster from the map, so we can in the end account for all - // remaining clusters - energyMap.erase(mcID); - } else { - debug(" --> No matching energy cluster found, copying over position cluster" ); - auto new_clus = pclus.clone(); - new_clus.addToClusters(pclus); - merged_clus->push_back(new_clus); - - // set association - auto clusterassoc = merged_assoc->create(); - clusterassoc.setRecID(new_clus.getObjectID().index); - clusterassoc.setSimID(mcID); - clusterassoc.setWeight(1.0); - clusterassoc.setRec(new_clus); - clusterassoc.setSim((*mcparticles)[mcID]); - } + // loop over all position clusters and match with energy clusters + debug("Step 1/2: Matching all position clusters to the available energy clusters..."); + for (const auto& [mcID, pclus] : posMap) { + + debug(" --> Processing position cluster {}, mcID: {}, energy: {}", pclus.getObjectID().index, + mcID, pclus.getEnergy()); + if (energyMap.count(mcID)) { + + const auto& eclus = energyMap[mcID]; + + auto new_clus = merged_clus->create(); + new_clus.setEnergy(eclus.getEnergy()); + new_clus.setEnergyError(eclus.getEnergyError()); + new_clus.setTime(pclus.getTime()); + new_clus.setNhits(pclus.getNhits() + eclus.getNhits()); + new_clus.setPosition(pclus.getPosition()); + new_clus.setPositionError(pclus.getPositionError()); + new_clus.addToClusters(pclus); + new_clus.addToClusters(eclus); + for (const auto& cl : {pclus, eclus}) { + for (const auto& hit : cl.getHits()) { + new_clus.addToHits(hit); + } + new_clus.addToSubdetectorEnergies(cl.getEnergy()); } - // Collect remaining energy clusters. Use mc truth position for these clusters, as - // they should really have a match in the position clusters (and if they don't it due - // to a clustering error). - debug( "Step 2/2: Collecting remaining energy clusters..." ); - for (const auto &[mcID, eclus]: energyMap) { - const auto &mc = (*mcparticles)[mcID]; - const auto &p = mc.getMomentum(); - const auto phi = std::atan2(p.y, p.x); - const auto theta = std::atan2(std::hypot(p.x, p.y), p.z); - - auto new_clus = merged_clus->create(); - new_clus.setEnergy(eclus.getEnergy()); - new_clus.setEnergyError(eclus.getEnergyError()); - new_clus.setTime(eclus.getTime()); - new_clus.setNhits(eclus.getNhits()); - // FIXME use nominal dd4hep::radius of 110cm, and use start vertex theta and phi - new_clus.setPosition(edm4hep::utils::sphericalToVector(78.5 * dd4hep::cm / dd4hep::mm, theta, phi)); - new_clus.addToClusters(eclus); - - debug(" --> Processing energy cluster {}, mcID: {}, energy: {}", eclus.getObjectID().index, mcID, eclus.getEnergy() ); - debug(" --> Created new 'combined' cluster {}, energy: {}", new_clus.getObjectID().index, new_clus.getEnergy() ); - - // set association - auto clusterassoc = merged_assoc->create(); - clusterassoc.setRecID(new_clus.getObjectID().index); - clusterassoc.setSimID(mcID); - clusterassoc.setWeight(1.0); - clusterassoc.setRec(new_clus); - clusterassoc.setSim(mc); + for (const auto& param : pclus.getShapeParameters()) { + new_clus.addToShapeParameters(param); } + debug(" --> Found matching energy cluster {}, energy: {}", eclus.getObjectID().index, + eclus.getEnergy()); + debug(" --> Created new combined cluster {}, energy: {}", new_clus.getObjectID().index, + new_clus.getEnergy()); + + // set association + auto clusterassoc = merged_assoc->create(); + clusterassoc.setRecID(new_clus.getObjectID().index); + clusterassoc.setSimID(mcID); + clusterassoc.setWeight(1.0); + clusterassoc.setRec(new_clus); + clusterassoc.setSim((*mcparticles)[mcID]); + + // erase the energy cluster from the map, so we can in the end account for all + // remaining clusters + energyMap.erase(mcID); + } else { + debug(" --> No matching energy cluster found, copying over position cluster"); + auto new_clus = pclus.clone(); + new_clus.addToClusters(pclus); + merged_clus->push_back(new_clus); + + // set association + auto clusterassoc = merged_assoc->create(); + clusterassoc.setRecID(new_clus.getObjectID().index); + clusterassoc.setSimID(mcID); + clusterassoc.setWeight(1.0); + clusterassoc.setRec(new_clus); + clusterassoc.setSim((*mcparticles)[mcID]); + } } + // Collect remaining energy clusters. Use mc truth position for these clusters, as + // they should really have a match in the position clusters (and if they don't it due + // to a clustering error). + debug("Step 2/2: Collecting remaining energy clusters..."); + for (const auto& [mcID, eclus] : energyMap) { + const auto& mc = (*mcparticles)[mcID]; + const auto& p = mc.getMomentum(); + const auto phi = std::atan2(p.y, p.x); + const auto theta = std::atan2(std::hypot(p.x, p.y), p.z); + + auto new_clus = merged_clus->create(); + new_clus.setEnergy(eclus.getEnergy()); + new_clus.setEnergyError(eclus.getEnergyError()); + new_clus.setTime(eclus.getTime()); + new_clus.setNhits(eclus.getNhits()); + // FIXME use nominal dd4hep::radius of 110cm, and use start vertex theta and phi + new_clus.setPosition( + edm4hep::utils::sphericalToVector(78.5 * dd4hep::cm / dd4hep::mm, theta, phi)); + new_clus.addToClusters(eclus); + + debug(" --> Processing energy cluster {}, mcID: {}, energy: {}", eclus.getObjectID().index, + mcID, eclus.getEnergy()); + debug(" --> Created new 'combined' cluster {}, energy: {}", new_clus.getObjectID().index, + new_clus.getEnergy()); + + // set association + auto clusterassoc = merged_assoc->create(); + clusterassoc.setRecID(new_clus.getObjectID().index); + clusterassoc.setSimID(mcID); + clusterassoc.setWeight(1.0); + clusterassoc.setRec(new_clus); + clusterassoc.setSim(mc); + } + } + + // get a map of MCParticle index --> cluster + // input: cluster_collections --> list of handles to all cluster collections + std::map + indexedClusters(const edm4eic::ClusterCollection& clusters, + const edm4eic::MCRecoClusterParticleAssociationCollection& associations) const { - // get a map of MCParticle index --> cluster - // input: cluster_collections --> list of handles to all cluster collections - std::map indexedClusters( - const edm4eic::ClusterCollection& clusters, - const edm4eic::MCRecoClusterParticleAssociationCollection& associations - ) const { - - std::map matched = {}; - - for (const auto &cluster: clusters) { - int mcID = -1; - - // find associated particle - for (const auto &assoc: associations) { - if (assoc.getRec() == cluster) { - mcID = assoc.getSimID(); - break; - } - } - - trace(" --> Found cluster: {} with mcID {} and energy {}", cluster.getObjectID().index, mcID, cluster.getEnergy()); - - if (mcID < 0) { - trace( " --> WARNING: no valid MC truth link found, skipping cluster..." ); - continue; - } - - const bool duplicate = matched.count(mcID); - if (duplicate) { - trace( " --> WARNING: this is a duplicate mcID, keeping the higher energy cluster"); - if (cluster.getEnergy() < matched[mcID].getEnergy()) { - continue; - } - } - - matched[mcID] = cluster; + std::map matched = {}; + + for (const auto& cluster : clusters) { + int mcID = -1; + + // find associated particle + for (const auto& assoc : associations) { + if (assoc.getRec() == cluster) { + mcID = assoc.getSimID(); + break; } - return matched; + } + + trace(" --> Found cluster: {} with mcID {} and energy {}", cluster.getObjectID().index, mcID, + cluster.getEnergy()); + + if (mcID < 0) { + trace(" --> WARNING: no valid MC truth link found, skipping cluster..."); + continue; + } + + const bool duplicate = matched.count(mcID); + if (duplicate) { + trace(" --> WARNING: this is a duplicate mcID, keeping the higher energy cluster"); + if (cluster.getEnergy() < matched[mcID].getEnergy()) { + continue; + } + } + + matched[mcID] = cluster; } + return matched; + } }; } // namespace eicrecon diff --git a/src/algorithms/digi/PhotoMultiplierHitDigi.cc b/src/algorithms/digi/PhotoMultiplierHitDigi.cc index 99cfe1f62d..05cc1f73b4 100644 --- a/src/algorithms/digi/PhotoMultiplierHitDigi.cc +++ b/src/algorithms/digi/PhotoMultiplierHitDigi.cc @@ -12,7 +12,6 @@ * Ported from Juggler by Thomas Britton (JLab) */ - #include "PhotoMultiplierHitDigi.h" #include @@ -33,253 +32,235 @@ namespace eicrecon { //------------------------ // init //------------------------ -void PhotoMultiplierHitDigi::init() -{ - // print the configuration parameters - debug() << m_cfg << endmsg; +void PhotoMultiplierHitDigi::init() { + // print the configuration parameters + debug() << m_cfg << endmsg; - /* warn if using potentially thread-unsafe seed + /* warn if using potentially thread-unsafe seed * FIXME: remove this warning when this issue is resolved: * https://github.com/eic/EICrecon/issues/539 */ - if(m_cfg.seed==0) warning("using seed=0 may cause thread-unsafe behavior of TRandom (EICrecon issue 539)"); - - // random number generators - m_random.SetSeed(m_cfg.seed); - m_rngNorm = [&](){ - return m_random.Gaus(0., 1.0); - }; - m_rngUni = [&](){ - return m_random.Uniform(0., 1.0); - }; - //auto randSvc = svc("RndmGenSvc", true); - auto sc1 = m_rngUni;//m_rngUni.initialize(randSvc, Rndm::Flat(0., 1.)); - auto sc2 = m_rngNorm;//m_rngNorm.initialize(randSvc, Rndm::Gauss(0., 1.)); - //if (!sc1.isSuccess() || !sc2.isSuccess()) { - if (!sc1 || !sc2) { - throw std::runtime_error("Cannot initialize random generator!"); - } + if (m_cfg.seed == 0) + warning("using seed=0 may cause thread-unsafe behavior of TRandom (EICrecon issue 539)"); + + // random number generators + m_random.SetSeed(m_cfg.seed); + m_rngNorm = [&]() { return m_random.Gaus(0., 1.0); }; + m_rngUni = [&]() { return m_random.Uniform(0., 1.0); }; + //auto randSvc = svc("RndmGenSvc", true); + auto sc1 = m_rngUni; //m_rngUni.initialize(randSvc, Rndm::Flat(0., 1.)); + auto sc2 = m_rngNorm; //m_rngNorm.initialize(randSvc, Rndm::Gauss(0., 1.)); + //if (!sc1.isSuccess() || !sc2.isSuccess()) { + if (!sc1 || !sc2) { + throw std::runtime_error("Cannot initialize random generator!"); + } - // initialize quantum efficiency table - qe_init(); + // initialize quantum efficiency table + qe_init(); } - //------------------------ // process //------------------------ -void PhotoMultiplierHitDigi::process( - const PhotoMultiplierHitDigi::Input& input, - const PhotoMultiplierHitDigi::Output& output) const -{ - const auto [sim_hits] = input; - auto [raw_hits, hit_assocs] = output; - - trace("{:=^70}"," call PhotoMultiplierHitDigi::process "); - std::unordered_map> hit_groups; - // collect the photon hit in the same cell - // calculate signal - trace("{:-<70}","Loop over simulated hits "); - for(std::size_t sim_hit_index = 0; sim_hit_index < sim_hits->size(); sim_hit_index++) { - const auto& sim_hit = sim_hits->at(sim_hit_index); - auto edep_eV = sim_hit.getEDep() * 1e9; // [GeV] -> [eV] // FIXME: use common unit converters, when available - auto id = sim_hit.getCellID(); - trace("hit: pixel id={:#018X} edep = {} eV", id, edep_eV); - - // overall safety factor - if (m_rngUni() > m_cfg.safetyFactor) continue; - - // quantum efficiency - if (m_cfg.enableQuantumEfficiency and !qe_pass(edep_eV, m_rngUni())) continue; - - // pixel gap cuts - if(m_cfg.enablePixelGaps) { - auto pos = sim_hit.getPosition(); - if( ! m_PixelGapMask(id, dd4hep::Position(pos.x*dd4hep::mm, pos.y*dd4hep::mm, pos.z*dd4hep::mm)) ) - continue; - } - - // cell time, signal amplitude, truth photon - trace(" -> hit accepted"); - trace(" -> MC hit id={}", sim_hit.getObjectID().index); - auto time = sim_hit.getTime(); - double amp = m_cfg.speMean + m_rngNorm() * m_cfg.speError; - - // insert hit to `hit_groups` - InsertHit( - hit_groups, - id, - amp, - time, - sim_hit_index - ); - } +void PhotoMultiplierHitDigi::process(const PhotoMultiplierHitDigi::Input& input, + const PhotoMultiplierHitDigi::Output& output) const { + const auto [sim_hits] = input; + auto [raw_hits, hit_assocs] = output; + + trace("{:=^70}", " call PhotoMultiplierHitDigi::process "); + std::unordered_map> hit_groups; + // collect the photon hit in the same cell + // calculate signal + trace("{:-<70}", "Loop over simulated hits "); + for (std::size_t sim_hit_index = 0; sim_hit_index < sim_hits->size(); sim_hit_index++) { + const auto& sim_hit = sim_hits->at(sim_hit_index); + auto edep_eV = sim_hit.getEDep() * + 1e9; // [GeV] -> [eV] // FIXME: use common unit converters, when available + auto id = sim_hit.getCellID(); + trace("hit: pixel id={:#018X} edep = {} eV", id, edep_eV); + + // overall safety factor + if (m_rngUni() > m_cfg.safetyFactor) + continue; + + // quantum efficiency + if (m_cfg.enableQuantumEfficiency and !qe_pass(edep_eV, m_rngUni())) + continue; + + // pixel gap cuts + if (m_cfg.enablePixelGaps) { + auto pos = sim_hit.getPosition(); + if (!m_PixelGapMask( + id, dd4hep::Position(pos.x * dd4hep::mm, pos.y * dd4hep::mm, pos.z * dd4hep::mm))) + continue; + } - // print `hit_groups` - if(level() <= algorithms::LogLevel::kTrace) { - trace("{:-<70}","Accepted hit groups "); - for(auto &[id,hitVec] : hit_groups) - for(auto &hit : hitVec) { - trace("hit_group: pixel id={:#018X} -> npe={} signal={} time={}", id, hit.npe, hit.signal, hit.time); - for(auto i : hit.sim_hit_indices) - trace(" - MC hit: EDep={}, id={}", sim_hits->at(i).getEDep(), sim_hits->at(i).getObjectID().index); - } - } + // cell time, signal amplitude, truth photon + trace(" -> hit accepted"); + trace(" -> MC hit id={}", sim_hit.getObjectID().index); + auto time = sim_hit.getTime(); + double amp = m_cfg.speMean + m_rngNorm() * m_cfg.speError; - //build noise raw hits - if (m_cfg.enableNoise) { - trace("{:=^70}"," BEGIN NOISE INJECTION "); - float p = m_cfg.noiseRate*m_cfg.noiseTimeWindow; - auto cellID_action = [this,&hit_groups] (auto id) { - - // cell time, signal amplitude - double amp = m_cfg.speMean + m_rngNorm()*m_cfg.speError; - TimeType time = m_cfg.noiseTimeWindow*m_rngUni() / dd4hep::ns; - dd4hep::Position pos_hit_global = m_converter->position(id); - - // insert in `hit_groups`, or if the pixel already has a hit, update `npe` and `signal` - this->InsertHit( - hit_groups, - id, - amp, - time, - 0, // not used - true - ); - - }; - m_VisitRngCellIDs(cellID_action, p); - } + // insert hit to `hit_groups` + InsertHit(hit_groups, id, amp, time, sim_hit_index); + } + + // print `hit_groups` + if (level() <= algorithms::LogLevel::kTrace) { + trace("{:-<70}", "Accepted hit groups "); + for (auto& [id, hitVec] : hit_groups) + for (auto& hit : hitVec) { + trace("hit_group: pixel id={:#018X} -> npe={} signal={} time={}", id, hit.npe, hit.signal, + hit.time); + for (auto i : hit.sim_hit_indices) + trace(" - MC hit: EDep={}, id={}", sim_hits->at(i).getEDep(), + sim_hits->at(i).getObjectID().index); + } + } + + //build noise raw hits + if (m_cfg.enableNoise) { + trace("{:=^70}", " BEGIN NOISE INJECTION "); + float p = m_cfg.noiseRate * m_cfg.noiseTimeWindow; + auto cellID_action = [this, &hit_groups](auto id) { + // cell time, signal amplitude + double amp = m_cfg.speMean + m_rngNorm() * m_cfg.speError; + TimeType time = m_cfg.noiseTimeWindow * m_rngUni() / dd4hep::ns; + dd4hep::Position pos_hit_global = m_converter->position(id); + + // insert in `hit_groups`, or if the pixel already has a hit, update `npe` and `signal` + this->InsertHit(hit_groups, id, amp, time, + 0, // not used + true); + }; + m_VisitRngCellIDs(cellID_action, p); + } - // build output `RawTrackerHit` and `MCRecoTrackerHitAssociation` collections - trace("{:-<70}","Digitized raw hits "); - for (auto &it : hit_groups) { - for (auto &data : it.second) { - - // build `RawTrackerHit` - auto raw_hit = raw_hits->create(); - raw_hit.setCellID(it.first); - raw_hit.setCharge( static_cast (data.signal) ); - raw_hit.setTimeStamp( static_cast (data.time/m_cfg.timeResolution) ); - trace("raw_hit: cellID={:#018X} -> charge={} timeStamp={}", - raw_hit.getCellID(), - raw_hit.getCharge(), - raw_hit.getTimeStamp() - ); - - // build `MCRecoTrackerHitAssociation` (for non-noise hits only) - if(!data.sim_hit_indices.empty()) { - for(auto i : data.sim_hit_indices) { - auto hit_assoc = hit_assocs->create(); - hit_assoc.setWeight(1.0 / data.sim_hit_indices.size()); // not used - hit_assoc.setRawHit(raw_hit); + // build output `RawTrackerHit` and `MCRecoTrackerHitAssociation` collections + trace("{:-<70}", "Digitized raw hits "); + for (auto& it : hit_groups) { + for (auto& data : it.second) { + + // build `RawTrackerHit` + auto raw_hit = raw_hits->create(); + raw_hit.setCellID(it.first); + raw_hit.setCharge(static_cast(data.signal)); + raw_hit.setTimeStamp(static_cast( + data.time / m_cfg.timeResolution)); + trace("raw_hit: cellID={:#018X} -> charge={} timeStamp={}", raw_hit.getCellID(), + raw_hit.getCharge(), raw_hit.getTimeStamp()); + + // build `MCRecoTrackerHitAssociation` (for non-noise hits only) + if (!data.sim_hit_indices.empty()) { + for (auto i : data.sim_hit_indices) { + auto hit_assoc = hit_assocs->create(); + hit_assoc.setWeight(1.0 / data.sim_hit_indices.size()); // not used + hit_assoc.setRawHit(raw_hit); #if EDM4EIC_VERSION_MAJOR >= 6 - hit_assoc.setSimHit(sim_hits->at(i)); + hit_assoc.setSimHit(sim_hits->at(i)); #else - hit_assoc.addToSimHits(sim_hits->at(i)); + hit_assoc.addToSimHits(sim_hits->at(i)); #endif - } - } - } } + } + } + } } -void PhotoMultiplierHitDigi::qe_init() -{ - // get quantum efficiency table - qeff.clear(); - auto hc = dd4hep::h_Planck * dd4hep::c_light / (dd4hep::eV * dd4hep::nm); // [eV*nm] - for(const auto &[wl,qe] : m_cfg.quantumEfficiency) { - qeff.emplace_back( hc / wl, qe ); // convert wavelength [nm] -> energy [eV] - } +void PhotoMultiplierHitDigi::qe_init() { + // get quantum efficiency table + qeff.clear(); + auto hc = dd4hep::h_Planck * dd4hep::c_light / (dd4hep::eV * dd4hep::nm); // [eV*nm] + for (const auto& [wl, qe] : m_cfg.quantumEfficiency) { + qeff.emplace_back(hc / wl, qe); // convert wavelength [nm] -> energy [eV] + } - // sort quantum efficiency data first - std::sort(qeff.begin(), qeff.end(), - [] (const std::pair &v1, const std::pair &v2) { - return v1.first < v2.first; + // sort quantum efficiency data first + std::sort(qeff.begin(), qeff.end(), + [](const std::pair& v1, const std::pair& v2) { + return v1.first < v2.first; }); - // print the table - debug("{:-^60}"," Quantum Efficiency vs. Energy "); - for(auto& [en,qe] : qeff) - debug(" {:>10.4} {:<}",en,qe); - trace("{:=^60}",""); - - if (m_cfg.enableQuantumEfficiency) { - // sanity checks - if (qeff.empty()) { - qeff = {{2.6, 0.3}, {7.0, 0.3}}; - warning("Invalid quantum efficiency data provided, using default values {} {:.2f} {} {:.2f} {} {:.2f} {} {:.2f} {}","{{", qeff.front().first, ",", qeff.front().second, "},{",qeff.back().first,",",qeff.back().second,"}}"); - } - if (qeff.front().first > 3.0) { - warning("Quantum efficiency data start from {:.2f} {}", qeff.front().first, " eV, maybe you are using wrong units?"); - } - if (qeff.back().first < 3.0) { - warning("Quantum efficiency data end at {:.2f} {}", qeff.back().first, " eV, maybe you are using wrong units?"); - } - } + // print the table + debug("{:-^60}", " Quantum Efficiency vs. Energy "); + for (auto& [en, qe] : qeff) + debug(" {:>10.4} {:<}", en, qe); + trace("{:=^60}", ""); + + if (m_cfg.enableQuantumEfficiency) { + // sanity checks + if (qeff.empty()) { + qeff = {{2.6, 0.3}, {7.0, 0.3}}; + warning("Invalid quantum efficiency data provided, using default values {} {:.2f} {} {:.2f} " + "{} {:.2f} {} {:.2f} {}", + "{{", qeff.front().first, ",", qeff.front().second, "},{", qeff.back().first, ",", + qeff.back().second, "}}"); + } + if (qeff.front().first > 3.0) { + warning("Quantum efficiency data start from {:.2f} {}", qeff.front().first, + " eV, maybe you are using wrong units?"); + } + if (qeff.back().first < 3.0) { + warning("Quantum efficiency data end at {:.2f} {}", qeff.back().first, + " eV, maybe you are using wrong units?"); + } + } } +template +RndmIter PhotoMultiplierHitDigi::interval_search(RndmIter beg, RndmIter end, const T& val, + Compare comp) const { + // special cases + auto dist = std::distance(beg, end); + if ((dist < 2) || (comp(*beg, val) > 0) || (comp(*std::prev(end), val) < 0)) { + return end; + } + auto mid = std::next(beg, dist / 2); + + while (mid != end) { + if (comp(*mid, val) == 0) { + return mid; + } else if (comp(*mid, val) > 0) { + end = mid; + } else { + beg = std::next(mid); + } + mid = std::next(beg, std::distance(beg, end) / 2); + } -template RndmIter PhotoMultiplierHitDigi::interval_search(RndmIter beg, RndmIter end, const T &val, Compare comp) const -{ - // special cases - auto dist = std::distance(beg, end); - if ((dist < 2) || (comp(*beg, val) > 0) || (comp(*std::prev(end), val) < 0)) { - return end; - } - auto mid = std::next(beg, dist / 2); - - while (mid != end) { - if (comp(*mid, val) == 0) { - return mid; - } else if (comp(*mid, val) > 0) { - end = mid; - } else { - beg = std::next(mid); - } - mid = std::next(beg, std::distance(beg, end)/2); - } - - if (mid == end || comp(*mid, val) > 0) { - return std::prev(mid); - } - return mid; + if (mid == end || comp(*mid, val) > 0) { + return std::prev(mid); + } + return mid; } -bool PhotoMultiplierHitDigi::qe_pass(double ev, double rand) const -{ - auto it = interval_search(qeff.begin(), qeff.end(), ev, - [] (const std::pair &vals, double val) { - return vals.first - val; - }); - - if (it == qeff.end()) { - // warning("{} eV is out of QE data range, assuming 0\% efficiency",ev); - return false; - } +bool PhotoMultiplierHitDigi::qe_pass(double ev, double rand) const { + auto it = interval_search( + qeff.begin(), qeff.end(), ev, + [](const std::pair& vals, double val) { return vals.first - val; }); - double prob = it->second; - auto itn = std::next(it); - if (itn != qeff.end() && (itn->first - it->first != 0)) { - prob = (it->second*(itn->first - ev) + itn->second*(ev - it->first)) / (itn->first - it->first); - } + if (it == qeff.end()) { + // warning("{} eV is out of QE data range, assuming 0\% efficiency",ev); + return false; + } - // trace("{} eV, QE: {}\%",ev,prob*100.); - return rand <= prob; -} + double prob = it->second; + auto itn = std::next(it); + if (itn != qeff.end() && (itn->first - it->first != 0)) { + prob = (it->second * (itn->first - ev) + itn->second * (ev - it->first)) / + (itn->first - it->first); + } + // trace("{} eV, QE: {}\%",ev,prob*100.); + return rand <= prob; +} // add a hit to local `hit_groups` data structure // NOLINTBEGIN(bugprone-easily-swappable-parameters) void PhotoMultiplierHitDigi::InsertHit( - std::unordered_map> &hit_groups, - CellIDType id, - double amp, - TimeType time, - std::size_t sim_hit_index, - bool is_noise_hit - ) const // NOLINTEND(bugprone-easily-swappable-parameters) + std::unordered_map>& hit_groups, CellIDType id, double amp, + TimeType time, std::size_t sim_hit_index, + bool is_noise_hit) const // NOLINTEND(bugprone-easily-swappable-parameters) { auto it = hit_groups.find(id); if (it != hit_groups.end()) { @@ -289,7 +270,8 @@ void PhotoMultiplierHitDigi::InsertHit( // hit group found, update npe, signal, and list of MC hits ghit->npe += 1; ghit->signal += amp; - if(!is_noise_hit) ghit->sim_hit_indices.push_back(sim_hit_index); + if (!is_noise_hit) + ghit->sim_hit_indices.push_back(sim_hit_index); trace(" -> add to group @ {:#018X}: signal={}", id, ghit->signal); break; } @@ -298,16 +280,18 @@ void PhotoMultiplierHitDigi::InsertHit( if (i >= it->second.size()) { auto sig = amp + m_cfg.pedMean + m_cfg.pedError * m_rngNorm(); decltype(HitData::sim_hit_indices) indices; - if(!is_noise_hit) indices.push_back(sim_hit_index); - hit_groups.insert({ id, {HitData{1, sig, time, indices}} }); + if (!is_noise_hit) + indices.push_back(sim_hit_index); + hit_groups.insert({id, {HitData{1, sig, time, indices}}}); trace(" -> no group found,"); trace(" so new group @ {:#018X}: signal={}", id, sig); } } else { auto sig = amp + m_cfg.pedMean + m_cfg.pedError * m_rngNorm(); decltype(HitData::sim_hit_indices) indices; - if(!is_noise_hit) indices.push_back(sim_hit_index); - hit_groups.insert({ id, {HitData{1, sig, time, indices}} }); + if (!is_noise_hit) + indices.push_back(sim_hit_index); + hit_groups.insert({id, {HitData{1, sig, time, indices}}}); trace(" -> new group @ {:#018X}: signal={}", id, sig); } } diff --git a/src/algorithms/digi/PhotoMultiplierHitDigi.h b/src/algorithms/digi/PhotoMultiplierHitDigi.h index 62c4ad2e1f..1f17c2dfad 100644 --- a/src/algorithms/digi/PhotoMultiplierHitDigi.h +++ b/src/algorithms/digi/PhotoMultiplierHitDigi.h @@ -12,7 +12,6 @@ * Ported from Juggler by Thomas Britton (JLab) */ - #pragma once #include @@ -42,99 +41,86 @@ namespace eicrecon { - using PhotoMultiplierHitDigiAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4hep::SimTrackerHitCollection - >, - algorithms::Output< - edm4eic::RawTrackerHitCollection, - edm4eic::MCRecoTrackerHitAssociationCollection - > - >; - - class PhotoMultiplierHitDigi - : public PhotoMultiplierHitDigiAlgorithm, - public WithPodConfig { - - public: - PhotoMultiplierHitDigi(std::string_view name) +using PhotoMultiplierHitDigiAlgorithm = + algorithms::Algorithm, + algorithms::Output>; + +class PhotoMultiplierHitDigi : public PhotoMultiplierHitDigiAlgorithm, + public WithPodConfig { + +public: + PhotoMultiplierHitDigi(std::string_view name) : PhotoMultiplierHitDigiAlgorithm{name, - {"inputHitCollection"}, - {"outputRawHitCollection", "outputRawHitAssociations"}, - "Digitize within ADC range, add pedestal, convert time " - "with smearing resolution."} {} - - void init() final; - void process(const Input&, const Output&) const final; - - // EDM datatype member types - using CellIDType = decltype(edm4hep::SimTrackerHitData::cellID); - using TimeType = decltype(edm4hep::SimTrackerHitData::time); - - // local structure to hold data for a hit - struct HitData { - uint32_t npe; - double signal; - TimeType time; - std::vector sim_hit_indices; - }; - - // random number generators - TRandomMixMax m_random; - std::function m_rngNorm; - std::function m_rngUni; - //Rndm::Numbers m_rngUni, m_rngNorm; - - // set `m_VisitAllRngPixels`, a visitor to run an action (type - // `function`) on a selection of random CellIDs; must be - // defined externally, since this would be detector-specific - void SetVisitRngCellIDs( - std::function< void(std::function, float) > visitor - ) - { m_VisitRngCellIDs = visitor; } - - // set `m_PixelGapMask`, which takes `cellID` and MC hit position, returning - // true if the hit position is on a pixel, or false if on a pixel gap; must be - // defined externally, since this would be detector-specific - void SetPixelGapMask( - std::function< bool(CellIDType, dd4hep::Position) > mask - ) - { m_PixelGapMask = mask; } + {"inputHitCollection"}, + {"outputRawHitCollection", "outputRawHitAssociations"}, + "Digitize within ADC range, add pedestal, convert time " + "with smearing resolution."} {} + + void init() final; + void process(const Input&, const Output&) const final; + + // EDM datatype member types + using CellIDType = decltype(edm4hep::SimTrackerHitData::cellID); + using TimeType = decltype(edm4hep::SimTrackerHitData::time); + + // local structure to hold data for a hit + struct HitData { + uint32_t npe; + double signal; + TimeType time; + std::vector sim_hit_indices; + }; + + // random number generators + TRandomMixMax m_random; + std::function m_rngNorm; + std::function m_rngUni; + //Rndm::Numbers m_rngUni, m_rngNorm; + + // set `m_VisitAllRngPixels`, a visitor to run an action (type + // `function`) on a selection of random CellIDs; must be + // defined externally, since this would be detector-specific + void SetVisitRngCellIDs(std::function, float)> visitor) { + m_VisitRngCellIDs = visitor; + } + + // set `m_PixelGapMask`, which takes `cellID` and MC hit position, returning + // true if the hit position is on a pixel, or false if on a pixel gap; must be + // defined externally, since this would be detector-specific + void SetPixelGapMask(std::function mask) { + m_PixelGapMask = mask; + } protected: + // visitor of all possible CellIDs (set with SetVisitRngCellIDs) + std::function, float)> m_VisitRngCellIDs = + [](std::function visitor_action, float p) { /* default no-op */ }; - // visitor of all possible CellIDs (set with SetVisitRngCellIDs) - std::function< void(std::function, float) > m_VisitRngCellIDs = - [] ( std::function visitor_action, float p ) { /* default no-op */ }; - - // pixel gap mask - std::function< bool(CellIDType, dd4hep::Position) > m_PixelGapMask = - [] (CellIDType cellID, dd4hep::Position pos_hit_global) { + // pixel gap mask + std::function m_PixelGapMask = + [](CellIDType cellID, dd4hep::Position pos_hit_global) { throw std::runtime_error("pixel gap cuts enabled, but none defined"); return false; }; private: - - // add a hit to local `hit_groups` data structure - void InsertHit( - std::unordered_map> &hit_groups, - CellIDType id, - double amp, - TimeType time, - std::size_t sim_hit_index, - bool is_noise_hit = false - ) const; - - const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; - const dd4hep::rec::CellIDPositionConverter* m_converter{algorithms::GeoSvc::instance().cellIDPositionConverter()}; - - // std::default_random_engine generator; // TODO: need something more appropriate here - // std::normal_distribution m_normDist; // defaults to mean=0, sigma=1 - - std::vector> qeff; - void qe_init(); - template RndmIter interval_search(RndmIter beg, RndmIter end, const T &val, Compare comp) const; - bool qe_pass(double ev, double rand) const; + // add a hit to local `hit_groups` data structure + void InsertHit(std::unordered_map>& hit_groups, CellIDType id, + double amp, TimeType time, std::size_t sim_hit_index, + bool is_noise_hit = false) const; + + const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; + const dd4hep::rec::CellIDPositionConverter* m_converter{ + algorithms::GeoSvc::instance().cellIDPositionConverter()}; + + // std::default_random_engine generator; // TODO: need something more appropriate here + // std::normal_distribution m_normDist; // defaults to mean=0, sigma=1 + + std::vector> qeff; + void qe_init(); + template + RndmIter interval_search(RndmIter beg, RndmIter end, const T& val, Compare comp) const; + bool qe_pass(double ev, double rand) const; }; -} +} // namespace eicrecon diff --git a/src/algorithms/digi/PhotoMultiplierHitDigiConfig.h b/src/algorithms/digi/PhotoMultiplierHitDigiConfig.h index e4ece07c3e..4d719529f7 100644 --- a/src/algorithms/digi/PhotoMultiplierHitDigiConfig.h +++ b/src/algorithms/digi/PhotoMultiplierHitDigiConfig.h @@ -6,96 +6,80 @@ #include namespace eicrecon { - class PhotoMultiplierHitDigiConfig { - public: - - // random number generator seed - /* FIXME: don't use 0 if `TRandomMixMax` is the RNG, it can get "stuck" +class PhotoMultiplierHitDigiConfig { +public: + // random number generator seed + /* FIXME: don't use 0 if `TRandomMixMax` is the RNG, it can get "stuck" * FIXME: remove this warning when this issue is resolved: * https://github.com/eic/EICrecon/issues/539 */ - unsigned long seed = 1; // seed for RNG (note: `0` might mean "unique" seed) + unsigned long seed = 1; // seed for RNG (note: `0` might mean "unique" seed) - // triggering - double hitTimeWindow = 20.0; // time gate in which 2 input hits will be grouped to 1 output hit // [ns] - double timeResolution = 1/16.0; // time resolution (= 1 / TDC counts per unit time) // [ns] - double speMean = 80.0; // mean ADC counts for a single photon - double speError = 16.0; // sigma of ADC counts for a single photon - double pedMean = 200.0; // mean ADC counts for the pedestal - double pedError = 3.0; // sigma of ADC counts for the pedestal + // triggering + double hitTimeWindow = + 20.0; // time gate in which 2 input hits will be grouped to 1 output hit // [ns] + double timeResolution = 1 / 16.0; // time resolution (= 1 / TDC counts per unit time) // [ns] + double speMean = 80.0; // mean ADC counts for a single photon + double speError = 16.0; // sigma of ADC counts for a single photon + double pedMean = 200.0; // mean ADC counts for the pedestal + double pedError = 3.0; // sigma of ADC counts for the pedestal - // noise - bool enableNoise = false; - double noiseRate = 20000; // [Hz] - double noiseTimeWindow = 20.0; // [ns] + // noise + bool enableNoise = false; + double noiseRate = 20000; // [Hz] + double noiseTimeWindow = 20.0; // [ns] - // SiPM pixels - bool enablePixelGaps = false; // enable/disable removal of hits in gaps between pixels + // SiPM pixels + bool enablePixelGaps = false; // enable/disable removal of hits in gaps between pixels - // overall safety factor - /* simulations assume the detector is ideal and perfect, but reality is + // overall safety factor + /* simulations assume the detector is ideal and perfect, but reality is * often neither; use this safety factor to reduce the number of initial * photon hits for a more conservative estimate of the number of * photoelectrons, or set to 1 to apply no such factor */ - double safetyFactor = 1.0; // allowed range: (0,1] + double safetyFactor = 1.0; // allowed range: (0,1] - // quantum efficiency - bool enableQuantumEfficiency = true; - // - wavelength units are [nm] - // FIXME: figure out how users can override this, maybe an external `yaml` file - std::vector > quantumEfficiency = { - {315, 0.00}, - {325, 0.04}, - {340, 0.10}, - {350, 0.20}, - {370, 0.30}, - {400, 0.35}, - {450, 0.40}, - {500, 0.38}, - {550, 0.35}, - {600, 0.27}, - {650, 0.20}, - {700, 0.15}, - {750, 0.12}, - {800, 0.08}, - {850, 0.06}, - {900, 0.04}, - {1000, 0.00} - }; + // quantum efficiency + bool enableQuantumEfficiency = true; + // - wavelength units are [nm] + // FIXME: figure out how users can override this, maybe an external `yaml` file + std::vector> quantumEfficiency = { + {315, 0.00}, {325, 0.04}, {340, 0.10}, {350, 0.20}, {370, 0.30}, {400, 0.35}, + {450, 0.40}, {500, 0.38}, {550, 0.35}, {600, 0.27}, {650, 0.20}, {700, 0.15}, + {750, 0.12}, {800, 0.08}, {850, 0.06}, {900, 0.04}, {1000, 0.00}}; - /* + /* std::vector > quantumEfficiency = { // test unit QE {325, 1.00}, {900, 1.00} }; */ - friend std::ostream& operator<<(std::ostream& os, const PhotoMultiplierHitDigiConfig& cfg); + friend std::ostream& operator<<(std::ostream& os, const PhotoMultiplierHitDigiConfig& cfg); +}; +std::ostream& operator<<(std::ostream& os, const PhotoMultiplierHitDigiConfig& cfg) { + os << fmt::format("{:=^60}", " PhotoMultiplierHitDigiConfig Settings ") << std::endl; + auto print_param = [&os](auto name, auto val) { + os << fmt::format(" {:>20} = {:<}", name, val) << std::endl; }; - - std::ostream& operator<<(std::ostream& os, const PhotoMultiplierHitDigiConfig& cfg) { - os << fmt::format("{:=^60}", " PhotoMultiplierHitDigiConfig Settings ") << std::endl; - auto print_param = [&os] (auto name, auto val) { - os << fmt::format(" {:>20} = {:<}", name, val) << std::endl; - }; - print_param("seed", cfg.seed); - print_param("hitTimeWindow", cfg.hitTimeWindow); - print_param("timeResolution", cfg.timeResolution); - print_param("speMean", cfg.speMean); - print_param("speError", cfg.speError); - print_param("pedMean", cfg.pedMean); - print_param("pedError", cfg.pedError); - print_param("enablePixelGaps", cfg.enablePixelGaps); - print_param("safetyFactor", cfg.safetyFactor); - print_param("enableNoise", cfg.enableNoise); - print_param("noiseRate", cfg.noiseRate); - print_param("noiseTimeWindow", cfg.noiseTimeWindow); - os << fmt::format("{:-^60}", " Quantum Efficiency vs. Wavelength ") << std::endl; - for(auto& [wl,qe] : cfg.quantumEfficiency) - os << fmt::format(" {:>10} {:<}", wl, qe) << std::endl; - return os; - } - + print_param("seed", cfg.seed); + print_param("hitTimeWindow", cfg.hitTimeWindow); + print_param("timeResolution", cfg.timeResolution); + print_param("speMean", cfg.speMean); + print_param("speError", cfg.speError); + print_param("pedMean", cfg.pedMean); + print_param("pedError", cfg.pedError); + print_param("enablePixelGaps", cfg.enablePixelGaps); + print_param("safetyFactor", cfg.safetyFactor); + print_param("enableNoise", cfg.enableNoise); + print_param("noiseRate", cfg.noiseRate); + print_param("noiseTimeWindow", cfg.noiseTimeWindow); + os << fmt::format("{:-^60}", " Quantum Efficiency vs. Wavelength ") << std::endl; + for (auto& [wl, qe] : cfg.quantumEfficiency) + os << fmt::format(" {:>10} {:<}", wl, qe) << std::endl; + return os; } + +} // namespace eicrecon diff --git a/src/algorithms/digi/SiliconTrackerDigi.cc b/src/algorithms/digi/SiliconTrackerDigi.cc index b5f21216eb..821ecad1fc 100644 --- a/src/algorithms/digi/SiliconTrackerDigi.cc +++ b/src/algorithms/digi/SiliconTrackerDigi.cc @@ -21,89 +21,86 @@ namespace eicrecon { void SiliconTrackerDigi::init() { - // Create random gauss function - m_gauss = [&](){ - return m_random.Gaus(0, m_cfg.timeResolution); - //return m_rng.gaussian(0., m_cfg.timeResolution); - }; + // Create random gauss function + m_gauss = [&]() { + return m_random.Gaus(0, m_cfg.timeResolution); + //return m_rng.gaussian(0., m_cfg.timeResolution); + }; } +void SiliconTrackerDigi::process(const SiliconTrackerDigi::Input& input, + const SiliconTrackerDigi::Output& output) const { + + const auto [sim_hits] = input; + auto [raw_hits, associations] = output; + + // A map of unique cellIDs with temporary structure RawHit + std::unordered_map cell_hit_map; + + for (const auto& sim_hit : *sim_hits) { + + // time smearing + double time_smearing = m_gauss(); + double result_time = sim_hit.getTime() + time_smearing; + auto hit_time_stamp = (std::int32_t)(result_time * 1e3); + + debug("--------------------"); + debug("Hit cellID = {}", sim_hit.getCellID()); + debug(" position = ({:.2f}, {:.2f}, {:.2f})", sim_hit.getPosition().x, + sim_hit.getPosition().y, sim_hit.getPosition().z); + debug(" xy_radius = {:.2f}", std::hypot(sim_hit.getPosition().x, sim_hit.getPosition().y)); + debug(" momentum = ({:.2f}, {:.2f}, {:.2f})", sim_hit.getMomentum().x, + sim_hit.getMomentum().y, sim_hit.getMomentum().z); + debug(" edep = {:.2f}", sim_hit.getEDep()); + debug(" time = {:.4f}[ns]", sim_hit.getTime()); + debug(" particle time = {}[ns]", sim_hit.getMCParticle().getTime()); + debug(" time smearing: {:.4f}, resulting time = {:.4f} [ns]", time_smearing, result_time); + debug(" hit_time_stamp: {} [~ps]", hit_time_stamp); + + if (sim_hit.getEDep() < m_cfg.threshold) { + debug(" edep is below threshold of {:.2f} [keV]", m_cfg.threshold / dd4hep::keV); + continue; + } -void SiliconTrackerDigi::process( - const SiliconTrackerDigi::Input& input, - const SiliconTrackerDigi::Output& output) const { - - const auto [sim_hits] = input; - auto [raw_hits,associations] = output; - - // A map of unique cellIDs with temporary structure RawHit - std::unordered_map cell_hit_map; - - - for (const auto& sim_hit : *sim_hits) { - - // time smearing - double time_smearing = m_gauss(); - double result_time = sim_hit.getTime() + time_smearing; - auto hit_time_stamp = (std::int32_t) (result_time * 1e3); - - debug("--------------------"); - debug("Hit cellID = {}", sim_hit.getCellID()); - debug(" position = ({:.2f}, {:.2f}, {:.2f})", sim_hit.getPosition().x, sim_hit.getPosition().y, sim_hit.getPosition().z); - debug(" xy_radius = {:.2f}", std::hypot(sim_hit.getPosition().x, sim_hit.getPosition().y)); - debug(" momentum = ({:.2f}, {:.2f}, {:.2f})", sim_hit.getMomentum().x, sim_hit.getMomentum().y, sim_hit.getMomentum().z); - debug(" edep = {:.2f}", sim_hit.getEDep()); - debug(" time = {:.4f}[ns]", sim_hit.getTime()); - debug(" particle time = {}[ns]", sim_hit.getMCParticle().getTime()); - debug(" time smearing: {:.4f}, resulting time = {:.4f} [ns]", time_smearing, result_time); - debug(" hit_time_stamp: {} [~ps]", hit_time_stamp); - - - if (sim_hit.getEDep() < m_cfg.threshold) { - debug(" edep is below threshold of {:.2f} [keV]", m_cfg.threshold / dd4hep::keV); - continue; - } - - if (cell_hit_map.count(sim_hit.getCellID()) == 0) { - // This cell doesn't have hits - cell_hit_map[sim_hit.getCellID()] = { - sim_hit.getCellID(), - (std::int32_t) std::llround(sim_hit.getEDep() * 1e6), - hit_time_stamp // ns->ps - }; - } else { - // There is previous values in the cell - auto& hit = cell_hit_map[sim_hit.getCellID()]; - debug(" Hit already exists in cell ID={}, prev. hit time: {}", sim_hit.getCellID(), hit.getTimeStamp()); - - // keep earliest time for hit - auto time_stamp = hit.getTimeStamp(); - hit.setTimeStamp(std::min(hit_time_stamp, hit.getTimeStamp())); - - // sum deposited energy - auto charge = hit.getCharge(); - hit.setCharge(charge + (std::int32_t) std::llround(sim_hit.getEDep() * 1e6)); - } + if (cell_hit_map.count(sim_hit.getCellID()) == 0) { + // This cell doesn't have hits + cell_hit_map[sim_hit.getCellID()] = { + sim_hit.getCellID(), (std::int32_t)std::llround(sim_hit.getEDep() * 1e6), + hit_time_stamp // ns->ps + }; + } else { + // There is previous values in the cell + auto& hit = cell_hit_map[sim_hit.getCellID()]; + debug(" Hit already exists in cell ID={}, prev. hit time: {}", sim_hit.getCellID(), + hit.getTimeStamp()); + + // keep earliest time for hit + auto time_stamp = hit.getTimeStamp(); + hit.setTimeStamp(std::min(hit_time_stamp, hit.getTimeStamp())); + + // sum deposited energy + auto charge = hit.getCharge(); + hit.setCharge(charge + (std::int32_t)std::llround(sim_hit.getEDep() * 1e6)); } + } - for (auto item : cell_hit_map) { - raw_hits->push_back(item.second); + for (auto item : cell_hit_map) { + raw_hits->push_back(item.second); - for (const auto& sim_hit : *sim_hits) { - if (item.first == sim_hit.getCellID()) { - // set association - auto hitassoc = associations->create(); - hitassoc.setWeight(1.0); - hitassoc.setRawHit(item.second); + for (const auto& sim_hit : *sim_hits) { + if (item.first == sim_hit.getCellID()) { + // set association + auto hitassoc = associations->create(); + hitassoc.setWeight(1.0); + hitassoc.setRawHit(item.second); #if EDM4EIC_VERSION_MAJOR >= 6 - hitassoc.setSimHit(sim_hit); + hitassoc.setSimHit(sim_hit); #else - hitassoc.addToSimHits(sim_hit); + hitassoc.addToSimHits(sim_hit); #endif - } - } - + } } + } } } // namespace eicrecon diff --git a/src/algorithms/digi/SiliconTrackerDigiConfig.h b/src/algorithms/digi/SiliconTrackerDigiConfig.h index fb66db252b..e8c4964440 100644 --- a/src/algorithms/digi/SiliconTrackerDigiConfig.h +++ b/src/algorithms/digi/SiliconTrackerDigiConfig.h @@ -7,11 +7,11 @@ namespace eicrecon { - struct SiliconTrackerDigiConfig { - // sub-systems should overwrite their own - // NB: be aware of thresholds in npsim! E.g. https://github.com/eic/npsim/pull/9/files - double threshold = 0 * dd4hep::keV; - double timeResolution = 8; /// TODO 8 of what units??? Same TODO in juggler. Probably [ns] - }; +struct SiliconTrackerDigiConfig { + // sub-systems should overwrite their own + // NB: be aware of thresholds in npsim! E.g. https://github.com/eic/npsim/pull/9/files + double threshold = 0 * dd4hep::keV; + double timeResolution = 8; /// TODO 8 of what units??? Same TODO in juggler. Probably [ns] +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/FarDetectorLinearProjection.cc b/src/algorithms/fardetectors/FarDetectorLinearProjection.cc index 6fe421020e..02deaf58ba 100644 --- a/src/algorithms/fardetectors/FarDetectorLinearProjection.cc +++ b/src/algorithms/fardetectors/FarDetectorLinearProjection.cc @@ -16,66 +16,60 @@ #include "algorithms/fardetectors/FarDetectorLinearProjection.h" #include "algorithms/fardetectors/FarDetectorLinearProjectionConfig.h" - - namespace eicrecon { +void FarDetectorLinearProjection::init() { - void FarDetectorLinearProjection::init() { - - // plane position - m_plane_position << m_cfg.plane_position[0], m_cfg.plane_position[1], m_cfg.plane_position[2]; - m_directions.block<3,1>(0,0) << m_cfg.plane_a[0], m_cfg.plane_a[1], m_cfg.plane_a[2]; - m_directions.block<3,1>(0,1) << m_cfg.plane_b[0], m_cfg.plane_b[1], m_cfg.plane_b[2]; - - } - - void FarDetectorLinearProjection::process(const FarDetectorLinearProjection::Input& input, - const FarDetectorLinearProjection::Output& output) const { - - const auto [inputSegments] = input; - auto [outputTracks] = output; - - Eigen::Matrix3d directions = m_directions; - - for(const auto& segment: *inputSegments ) { + // plane position + m_plane_position << m_cfg.plane_position[0], m_cfg.plane_position[1], m_cfg.plane_position[2]; + m_directions.block<3, 1>(0, 0) << m_cfg.plane_a[0], m_cfg.plane_a[1], m_cfg.plane_a[2]; + m_directions.block<3, 1>(0, 1) << m_cfg.plane_b[0], m_cfg.plane_b[1], m_cfg.plane_b[2]; +} - auto inputPoint = segment.getPoints()[0]; +void FarDetectorLinearProjection::process(const FarDetectorLinearProjection::Input& input, + const FarDetectorLinearProjection::Output& output) const { - Eigen::Vector3d point_position(inputPoint.position.x,inputPoint.position.y,inputPoint.position.z); - Eigen::Vector3d positionDiff = point_position - m_plane_position; + const auto [inputSegments] = input; + auto [outputTracks] = output; - // Convert spherical coordinates to Cartesian - double x = std::sin(inputPoint.theta) * std::cos(inputPoint.phi); - double y = std::sin(inputPoint.theta) * std::sin(inputPoint.phi); - double z = std::cos(inputPoint.theta); - directions.block<3,1>(0,2) << x,y,z; + Eigen::Matrix3d directions = m_directions; - auto projectedPoint = directions.inverse()*positionDiff; + for (const auto& segment : *inputSegments) { - // Create track parameters edm4eic structure - // TODO - populate more of the fields correctly - std::int32_t type = 0; - // Surface ID not used in this context - std::uint64_t surface = 0; - // Plane Point - edm4hep::Vector2f loc(projectedPoint[0],projectedPoint[1]); //Temp unit transform - float theta = inputPoint.theta;//edm4eic::anglePolar(outVec); - float phi = inputPoint.phi ;//edm4eic::angleAzimuthal(outVec); - float qOverP = 0.; - float time = 0; - int32_t pdgCode = 11; - // Point Error - edm4eic::Cov6f error; + auto inputPoint = segment.getPoints()[0]; - debug("Position: a={}, b={}",loc.a,loc.b); - debug("Direction: theta={}, phi={}",theta,phi); + Eigen::Vector3d point_position(inputPoint.position.x, inputPoint.position.y, + inputPoint.position.z); + Eigen::Vector3d positionDiff = point_position - m_plane_position; - outputTracks->create(type,surface,loc,theta,phi,qOverP,time,pdgCode,error); + // Convert spherical coordinates to Cartesian + double x = std::sin(inputPoint.theta) * std::cos(inputPoint.phi); + double y = std::sin(inputPoint.theta) * std::sin(inputPoint.phi); + double z = std::cos(inputPoint.theta); + directions.block<3, 1>(0, 2) << x, y, z; - } + auto projectedPoint = directions.inverse() * positionDiff; - } + // Create track parameters edm4eic structure + // TODO - populate more of the fields correctly + std::int32_t type = 0; + // Surface ID not used in this context + std::uint64_t surface = 0; + // Plane Point + edm4hep::Vector2f loc(projectedPoint[0], projectedPoint[1]); //Temp unit transform + float theta = inputPoint.theta; //edm4eic::anglePolar(outVec); + float phi = inputPoint.phi; //edm4eic::angleAzimuthal(outVec); + float qOverP = 0.; + float time = 0; + int32_t pdgCode = 11; + // Point Error + edm4eic::Cov6f error; + debug("Position: a={}, b={}", loc.a, loc.b); + debug("Direction: theta={}, phi={}", theta, phi); + outputTracks->create(type, surface, loc, theta, phi, qOverP, time, pdgCode, error); + } } + +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/FarDetectorLinearProjection.h b/src/algorithms/fardetectors/FarDetectorLinearProjection.h index 61c8a1f5d7..8e3c3e9576 100644 --- a/src/algorithms/fardetectors/FarDetectorLinearProjection.h +++ b/src/algorithms/fardetectors/FarDetectorLinearProjection.h @@ -16,39 +16,31 @@ namespace eicrecon { - using FarDetectorLinearProjectionAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::TrackSegmentCollection - >, - algorithms::Output< - edm4eic::TrackParametersCollection - > - >; - - class FarDetectorLinearProjection - : public FarDetectorLinearProjectionAlgorithm, - public WithPodConfig { - - public: - FarDetectorLinearProjection(std::string_view name) - : FarDetectorLinearProjectionAlgorithm{name, - {"inputTrackSegments"}, - {"outputTrackParameters"}, - "Project track segments to a plane"} {} - - /** One time initialization **/ - void init() final; - - /** Event by event processing **/ - void process(const Input&, const Output&) const final; - - - private: - Eigen::Vector3d m_plane_position; - Eigen::Vector3d m_plane_a; - Eigen::Vector3d m_plane_b; - Eigen::Matrix3d m_directions; - - }; - -} // eicrecon +using FarDetectorLinearProjectionAlgorithm = + algorithms::Algorithm, + algorithms::Output>; + +class FarDetectorLinearProjection : public FarDetectorLinearProjectionAlgorithm, + public WithPodConfig { + +public: + FarDetectorLinearProjection(std::string_view name) + : FarDetectorLinearProjectionAlgorithm{name, + {"inputTrackSegments"}, + {"outputTrackParameters"}, + "Project track segments to a plane"} {} + + /** One time initialization **/ + void init() final; + + /** Event by event processing **/ + void process(const Input&, const Output&) const final; + +private: + Eigen::Vector3d m_plane_position; + Eigen::Vector3d m_plane_a; + Eigen::Vector3d m_plane_b; + Eigen::Matrix3d m_directions; +}; + +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/FarDetectorLinearProjectionConfig.h b/src/algorithms/fardetectors/FarDetectorLinearProjectionConfig.h index 0eedb7b659..0316143a00 100644 --- a/src/algorithms/fardetectors/FarDetectorLinearProjectionConfig.h +++ b/src/algorithms/fardetectors/FarDetectorLinearProjectionConfig.h @@ -4,11 +4,10 @@ #pragma once namespace eicrecon { - struct FarDetectorLinearProjectionConfig { +struct FarDetectorLinearProjectionConfig { - std::vector plane_position = {0.0, 0.0, 0.0}; - std::vector plane_a = {0.0, 1.0, 0.0}; - std::vector plane_b = {0.0, 0.0, 1.0}; - - }; -} + std::vector plane_position = {0.0, 0.0, 0.0}; + std::vector plane_a = {0.0, 1.0, 0.0}; + std::vector plane_b = {0.0, 0.0, 1.0}; +}; +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/FarDetectorLinearTracking.cc b/src/algorithms/fardetectors/FarDetectorLinearTracking.cc index 5d93d42bce..b71ea639d4 100644 --- a/src/algorithms/fardetectors/FarDetectorLinearTracking.cc +++ b/src/algorithms/fardetectors/FarDetectorLinearTracking.cc @@ -25,147 +25,145 @@ namespace eicrecon { - void FarDetectorLinearTracking::init() { +void FarDetectorLinearTracking::init() { - // For changing how strongly each layer hit is in contributing to the fit - m_layerWeights = Eigen::VectorXd::Constant(m_cfg.n_layer,1); + // For changing how strongly each layer hit is in contributing to the fit + m_layerWeights = Eigen::VectorXd::Constant(m_cfg.n_layer, 1); - // For checking the direction of the track from theta and phi angles - m_optimumDirection = Eigen::Vector3d::UnitZ(); - m_optimumDirection = Eigen::AngleAxisd(m_cfg.optimum_theta,Eigen::Vector3d::UnitY())*m_optimumDirection; - m_optimumDirection = Eigen::AngleAxisd(m_cfg.optimum_phi,Eigen::Vector3d::UnitZ())*m_optimumDirection; + // For checking the direction of the track from theta and phi angles + m_optimumDirection = Eigen::Vector3d::UnitZ(); + m_optimumDirection = + Eigen::AngleAxisd(m_cfg.optimum_theta, Eigen::Vector3d::UnitY()) * m_optimumDirection; + m_optimumDirection = + Eigen::AngleAxisd(m_cfg.optimum_phi, Eigen::Vector3d::UnitZ()) * m_optimumDirection; +} +void FarDetectorLinearTracking::process(const FarDetectorLinearTracking::Input& input, + const FarDetectorLinearTracking::Output& output) const { + + const auto [inputhits] = input; + auto [outputTracks] = output; + + // Check the number of input collections is correct + int nCollections = inputhits.size(); + if (nCollections != m_cfg.n_layer) { + error("Wrong number of input collections passed to algorithm"); + return; + } + + // Check there aren't too many hits in any layer to handle + // Temporary limit of number of hits per layer before Kalman filtering/GNN implemented + // TODO - Implement more sensible solution + for (const auto& layerHits : inputhits) { + if ((*layerHits).size() > m_cfg.layer_hits_max) { + info("Too many hits in layer"); + return; } + } - void FarDetectorLinearTracking::process( - const FarDetectorLinearTracking::Input& input, - const FarDetectorLinearTracking::Output& output) const { - - const auto [inputhits] = input; - auto [outputTracks] = output; - - // Check the number of input collections is correct - int nCollections = inputhits.size(); - if(nCollections!=m_cfg.n_layer){ - error("Wrong number of input collections passed to algorithm"); - return; - } - - // Check there aren't too many hits in any layer to handle - // Temporary limit of number of hits per layer before Kalman filtering/GNN implemented - // TODO - Implement more sensible solution - for(const auto& layerHits: inputhits){ - if((*layerHits).size()>m_cfg.layer_hits_max){ - info("Too many hits in layer"); - return; - } - } - - // Create a matrix to store the hit positions - Eigen::MatrixXd hitMatrix(3,m_cfg.n_layer); - // Loop over all combinations of hits fitting a track to all layers - buildMatrixRecursive(m_cfg.n_layer-1,&hitMatrix,inputhits,outputTracks); + // Create a matrix to store the hit positions + Eigen::MatrixXd hitMatrix(3, m_cfg.n_layer); + // Loop over all combinations of hits fitting a track to all layers + buildMatrixRecursive(m_cfg.n_layer - 1, &hitMatrix, inputhits, outputTracks); +} - } +void FarDetectorLinearTracking::buildMatrixRecursive( + int level, Eigen::MatrixXd* hitMatrix, + const std::vector>& hits, + gsl::not_null outputTracks) const { + // Iterate over hits in this layer + for (auto hit : (*hits[level])) { + auto pos = hit.getPosition(); + hitMatrix->col(level) << pos.x, pos.y, pos.z; - void FarDetectorLinearTracking::buildMatrixRecursive(int level, - Eigen::MatrixXd* hitMatrix, - const std::vector>& hits, - gsl::not_null outputTracks ) const { - - // Iterate over hits in this layer - for(auto hit : (*hits[level])){ - auto pos = hit.getPosition(); - hitMatrix->col(level) << pos.x, pos.y, pos.z; - - // Check the last two hits are within a certain angle of the optimum direction - if(m_cfg.restrict_direction && levelcol(level),hitMatrix->col(level+1))){ - continue; - } - } - - if(level>0){ - buildMatrixRecursive(level-1, - hitMatrix, - hits, - outputTracks); - } - else{ - checkHitCombination(hitMatrix,outputTracks); - } + // Check the last two hits are within a certain angle of the optimum direction + if (m_cfg.restrict_direction && level < m_cfg.n_layer - 1) { + if (!checkHitPair(hitMatrix->col(level), hitMatrix->col(level + 1))) { + continue; } - } + if (level > 0) { + buildMatrixRecursive(level - 1, hitMatrix, hits, outputTracks); + } else { + checkHitCombination(hitMatrix, outputTracks); + } + } +} - void FarDetectorLinearTracking::checkHitCombination(Eigen::MatrixXd* hitMatrix, - gsl::not_null outputTracks ) const { - - Eigen::Vector3d weightedAnchor = (*hitMatrix)*m_layerWeights/(m_layerWeights.sum()); - - auto localMatrix = (*hitMatrix).colwise()-weightedAnchor; - - Eigen::BDCSVD svd(localMatrix.transpose(), Eigen::ComputeThinU | Eigen::ComputeThinV); - - auto V = svd.matrixV(); +void FarDetectorLinearTracking::checkHitCombination( + Eigen::MatrixXd* hitMatrix, + gsl::not_null outputTracks) const { - // Rotate into principle components and calculate chi2/ndf - auto rotatedMatrix = localMatrix.transpose()*V; - auto residuals = rotatedMatrix.rightCols(2); - double chi2 = (residuals.array()*residuals.array()).sum()/(2*m_cfg.n_layer); + Eigen::Vector3d weightedAnchor = (*hitMatrix) * m_layerWeights / (m_layerWeights.sum()); - if(chi2>m_cfg.chi2_max) return; + auto localMatrix = (*hitMatrix).colwise() - weightedAnchor; - edm4hep::Vector3d outPos = weightedAnchor.data(); - edm4hep::Vector3d outVec = V.col(0).data(); + Eigen::BDCSVD svd(localMatrix.transpose(), + Eigen::ComputeThinU | Eigen::ComputeThinV); - // Make sure fit was pointing in the right direction - if(outVec.z>0) outVec = outVec*-1; + auto V = svd.matrixV(); - uint64_t surface{0}; // Surface track was propagated to (possibly multiple per detector) - uint32_t system{0}; // Detector system track was propagated to - edm4hep::Vector3f position(outPos.x,outPos.y,outPos.z); // Position of the trajectory point [mm] - edm4eic::Cov3f positionError; // Error on the position - edm4hep::Vector3f momentum; // 3-momentum at the point [GeV] - edm4eic::Cov3f momentumError; // Error on the 3-momentum - float time{0}; // Time at this point [ns] - float timeError{0}; // Error on the time at this point - float theta = edm4eic::anglePolar(outVec); // global polar direction of the fitted vector [rad] - float phi = edm4eic::angleAzimuthal(outVec); // global azimuthal direction of the fitted vector [rad] - edm4eic::Cov2f directionError; // Error on the polar and azimuthal angles - float pathlength{0}; // Pathlength from the origin to this point - float pathlengthError{0}; // Error on the pathlength + // Rotate into principle components and calculate chi2/ndf + auto rotatedMatrix = localMatrix.transpose() * V; + auto residuals = rotatedMatrix.rightCols(2); + double chi2 = (residuals.array() * residuals.array()).sum() / (2 * m_cfg.n_layer); - edm4eic::TrackPoint point({surface,system,position,positionError,momentum,momentumError,time,timeError,theta,phi,directionError,pathlength,pathlengthError}); + if (chi2 > m_cfg.chi2_max) + return; - float length = 0; - float lengthError = 0; - auto segment = (*outputTracks)->create(length,lengthError); + edm4hep::Vector3d outPos = weightedAnchor.data(); + edm4hep::Vector3d outVec = V.col(0).data(); - segment.addToPoints(point); + // Make sure fit was pointing in the right direction + if (outVec.z > 0) + outVec = outVec * -1; + uint64_t surface{0}; // Surface track was propagated to (possibly multiple per detector) + uint32_t system{0}; // Detector system track was propagated to + edm4hep::Vector3f position(outPos.x, outPos.y, outPos.z); // Position of the trajectory point [mm] + edm4eic::Cov3f positionError; // Error on the position + edm4hep::Vector3f momentum; // 3-momentum at the point [GeV] + edm4eic::Cov3f momentumError; // Error on the 3-momentum + float time{0}; // Time at this point [ns] + float timeError{0}; // Error on the time at this point + float theta = edm4eic::anglePolar(outVec); // global polar direction of the fitted vector [rad] + float phi = + edm4eic::angleAzimuthal(outVec); // global azimuthal direction of the fitted vector [rad] + edm4eic::Cov2f directionError; // Error on the polar and azimuthal angles + float pathlength{0}; // Pathlength from the origin to this point + float pathlengthError{0}; // Error on the pathlength - } + edm4eic::TrackPoint point({surface, system, position, positionError, momentum, momentumError, + time, timeError, theta, phi, directionError, pathlength, + pathlengthError}); - // Check if a pair of hits lies close to the optimum direction - bool FarDetectorLinearTracking::checkHitPair(const Eigen::Vector3d& hit1, - const Eigen::Vector3d& hit2) const { + float length = 0; + float lengthError = 0; + auto segment = (*outputTracks)->create(length, lengthError); - Eigen::Vector3d hitDiff = hit2-hit1; - hitDiff.normalize(); + segment.addToPoints(point); +} - double angle = std::acos(hitDiff.dot(m_optimumDirection)); +// Check if a pair of hits lies close to the optimum direction +bool FarDetectorLinearTracking::checkHitPair(const Eigen::Vector3d& hit1, + const Eigen::Vector3d& hit2) const { - debug("Vector: x={}, y={}, z={}",hitDiff.x(),hitDiff.y(),hitDiff.z()); - debug("Optimum: x={}, y={}, z={}",m_optimumDirection.x(),m_optimumDirection.y(),m_optimumDirection.z()); - debug("Angle: {}, Tolerance {}",angle,m_cfg.step_angle_tolerance); + Eigen::Vector3d hitDiff = hit2 - hit1; + hitDiff.normalize(); - if(angle>m_cfg.step_angle_tolerance) return false; + double angle = std::acos(hitDiff.dot(m_optimumDirection)); - return true; + debug("Vector: x={}, y={}, z={}", hitDiff.x(), hitDiff.y(), hitDiff.z()); + debug("Optimum: x={}, y={}, z={}", m_optimumDirection.x(), m_optimumDirection.y(), + m_optimumDirection.z()); + debug("Angle: {}, Tolerance {}", angle, m_cfg.step_angle_tolerance); - } + if (angle > m_cfg.step_angle_tolerance) + return false; + return true; } + +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/FarDetectorLinearTrackingConfig.h b/src/algorithms/fardetectors/FarDetectorLinearTrackingConfig.h index f8ee0e526b..f02b36516c 100644 --- a/src/algorithms/fardetectors/FarDetectorLinearTrackingConfig.h +++ b/src/algorithms/fardetectors/FarDetectorLinearTrackingConfig.h @@ -4,17 +4,16 @@ #pragma once namespace eicrecon { - struct FarDetectorLinearTrackingConfig { +struct FarDetectorLinearTrackingConfig { - int layer_hits_max{10}; - float chi2_max{0.001}; - int n_layer{4}; + int layer_hits_max{10}; + float chi2_max{0.001}; + int n_layer{4}; - // Restrict hit direction - bool restrict_direction{true}; - float optimum_theta{0.026}; - float optimum_phi{0}; - float step_angle_tolerance{0.05}; - - }; -} + // Restrict hit direction + bool restrict_direction{true}; + float optimum_theta{0.026}; + float optimum_phi{0}; + float step_angle_tolerance{0.05}; +}; +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/FarDetectorMLReconstruction.cc b/src/algorithms/fardetectors/FarDetectorMLReconstruction.cc index d92b382714..bb1e982925 100644 --- a/src/algorithms/fardetectors/FarDetectorMLReconstruction.cc +++ b/src/algorithms/fardetectors/FarDetectorMLReconstruction.cc @@ -19,112 +19,115 @@ namespace eicrecon { - - void FarDetectorMLReconstruction::init() { - - m_reader = new TMVA::Reader( "!Color:!Silent" ); - // Create a set of variables and declare them to the reader - // - the variable names MUST corresponds in name and type to those given in the weight file(s) used - m_reader->AddVariable( "LowQ2Tracks[0].loc.a", &nnInput[FarDetectorMLNNIndexIn::PosY] ); - m_reader->AddVariable( "LowQ2Tracks[0].loc.b", &nnInput[FarDetectorMLNNIndexIn::PosZ] ); - m_reader->AddVariable( "sin(LowQ2Tracks[0].phi)*sin(LowQ2Tracks[0].theta)", &nnInput[FarDetectorMLNNIndexIn::DirX] ); - m_reader->AddVariable( "cos(LowQ2Tracks[0].phi)*sin(LowQ2Tracks[0].theta)", &nnInput[FarDetectorMLNNIndexIn::DirY] ); - - // Locate and load the weight file - // TODO - Add functionality to select passed by configuration - bool methodFound = false; - if(!m_cfg.modelPath.empty()){ - try{ - m_method = dynamic_cast(m_reader->BookMVA( m_cfg.methodName, m_cfg.modelPath )); - } - catch(std::exception &e){ - error(fmt::format("Failed to load method {} from file {}: {}", m_cfg.methodName, m_cfg.modelPath, e.what())); - } - - } else { - error("No model path provided for FarDetectorMLReconstruction"); +void FarDetectorMLReconstruction::init() { + + m_reader = new TMVA::Reader("!Color:!Silent"); + // Create a set of variables and declare them to the reader + // - the variable names MUST corresponds in name and type to those given in the weight file(s) used + m_reader->AddVariable("LowQ2Tracks[0].loc.a", &nnInput[FarDetectorMLNNIndexIn::PosY]); + m_reader->AddVariable("LowQ2Tracks[0].loc.b", &nnInput[FarDetectorMLNNIndexIn::PosZ]); + m_reader->AddVariable("sin(LowQ2Tracks[0].phi)*sin(LowQ2Tracks[0].theta)", + &nnInput[FarDetectorMLNNIndexIn::DirX]); + m_reader->AddVariable("cos(LowQ2Tracks[0].phi)*sin(LowQ2Tracks[0].theta)", + &nnInput[FarDetectorMLNNIndexIn::DirY]); + + // Locate and load the weight file + // TODO - Add functionality to select passed by configuration + bool methodFound = false; + if (!m_cfg.modelPath.empty()) { + try { + m_method = + dynamic_cast(m_reader->BookMVA(m_cfg.methodName, m_cfg.modelPath)); + } catch (std::exception& e) { + error(fmt::format("Failed to load method {} from file {}: {}", m_cfg.methodName, + m_cfg.modelPath, e.what())); } - } - - - - void FarDetectorMLReconstruction::process( - const FarDetectorMLReconstruction::Input& input, - const FarDetectorMLReconstruction::Output& output) { - - const auto [inputTracks,beamElectrons] = input; - auto [outputFarDetectorMLTrajectories, outputFarDetectorMLTrackParameters, outputFarDetectorMLTracks] = output; - - //Set beam energy from first MCBeamElectron, using std::call_once - std::call_once(m_initBeamE,[&](){ - // Check if beam electrons are present - if(beamElectrons->size() == 0){ - error("No beam electrons found keeping default 10GeV beam energy."); - return; - } - m_beamE = beamElectrons->at(0).getEnergy(); - //Round beam energy to nearest GeV - Should be 5, 10 or 18GeV - m_beamE = round(m_beamE); - }); - - // Reconstructed particle members which don't change - std::int32_t type = 0; // Check? - float charge = -1; - - for(const auto& track: *inputTracks){ - - auto pos = track.getLoc(); - auto trackphi = track.getPhi(); - auto tracktheta = track.getTheta(); - - nnInput[FarDetectorMLNNIndexIn::PosY] = pos.a; - nnInput[FarDetectorMLNNIndexIn::PosZ] = pos.b; - nnInput[FarDetectorMLNNIndexIn::DirX] = sin(trackphi)*sin(tracktheta); - nnInput[FarDetectorMLNNIndexIn::DirY] = cos(trackphi)*sin(tracktheta); - auto values = m_method->GetRegressionValues(); - - edm4hep::Vector3f momentum = {values[FarDetectorMLNNIndexOut::MomX],values[FarDetectorMLNNIndexOut::MomY],values[FarDetectorMLNNIndexOut::MomZ]}; - - // log out the momentum components and magnitude - trace("Prescaled Output Momentum: x {}, y {}, z {}",values[FarDetectorMLNNIndexOut::MomX],values[FarDetectorMLNNIndexOut::MomY],values[FarDetectorMLNNIndexOut::MomZ]); - trace("Prescaled Momentum: {}",edm4eic::magnitude(momentum)); - - // Scale momentum magnitude - momentum = momentum*m_beamE; - trace("Scaled Momentum: {}",edm4eic::magnitude(momentum)); - - // Track parameter variables - // TODO: Add time and momentum errors - // Plane Point - edm4hep::Vector2f loc(0,0); // Vertex estimate - uint64_t surface = 0; //Not used in this context - float theta = edm4eic::anglePolar(momentum); - float phi = edm4eic::angleAzimuthal(momentum); - float qOverP = charge/edm4eic::magnitude(momentum); - float time; - // PDG - int32_t pdg = 11; - // Point Error - edm4eic::Cov6f error; - - edm4eic::TrackParameters params = outputFarDetectorMLTrackParameters->create(type,surface,loc,theta,phi,qOverP,time,pdg,error); - - auto trajectory = outputFarDetectorMLTrajectories->create(); - trajectory.addToTrackParameters(params); + } else { + error("No model path provided for FarDetectorMLReconstruction"); + } +} - int32_t trackType = 0; - edm4hep::Vector3f position = {0,0,0}; - float timeError; - float charge = -1; - float chi2 = 0; - uint32_t ndf = 0; +void FarDetectorMLReconstruction::process(const FarDetectorMLReconstruction::Input& input, + const FarDetectorMLReconstruction::Output& output) { - auto outTrack = outputFarDetectorMLTracks->create(trackType,position,momentum,error,time,timeError,charge,chi2,ndf); - outTrack.setTrajectory(trajectory); + const auto [inputTracks, beamElectrons] = input; + auto [outputFarDetectorMLTrajectories, outputFarDetectorMLTrackParameters, + outputFarDetectorMLTracks] = output; + //Set beam energy from first MCBeamElectron, using std::call_once + std::call_once(m_initBeamE, [&]() { + // Check if beam electrons are present + if (beamElectrons->size() == 0) { + error("No beam electrons found keeping default 10GeV beam energy."); + return; } - + m_beamE = beamElectrons->at(0).getEnergy(); + //Round beam energy to nearest GeV - Should be 5, 10 or 18GeV + m_beamE = round(m_beamE); + }); + + // Reconstructed particle members which don't change + std::int32_t type = 0; // Check? + float charge = -1; + + for (const auto& track : *inputTracks) { + + auto pos = track.getLoc(); + auto trackphi = track.getPhi(); + auto tracktheta = track.getTheta(); + + nnInput[FarDetectorMLNNIndexIn::PosY] = pos.a; + nnInput[FarDetectorMLNNIndexIn::PosZ] = pos.b; + nnInput[FarDetectorMLNNIndexIn::DirX] = sin(trackphi) * sin(tracktheta); + nnInput[FarDetectorMLNNIndexIn::DirY] = cos(trackphi) * sin(tracktheta); + + auto values = m_method->GetRegressionValues(); + + edm4hep::Vector3f momentum = {values[FarDetectorMLNNIndexOut::MomX], + values[FarDetectorMLNNIndexOut::MomY], + values[FarDetectorMLNNIndexOut::MomZ]}; + + // log out the momentum components and magnitude + trace("Prescaled Output Momentum: x {}, y {}, z {}", values[FarDetectorMLNNIndexOut::MomX], + values[FarDetectorMLNNIndexOut::MomY], values[FarDetectorMLNNIndexOut::MomZ]); + trace("Prescaled Momentum: {}", edm4eic::magnitude(momentum)); + + // Scale momentum magnitude + momentum = momentum * m_beamE; + trace("Scaled Momentum: {}", edm4eic::magnitude(momentum)); + + // Track parameter variables + // TODO: Add time and momentum errors + // Plane Point + edm4hep::Vector2f loc(0, 0); // Vertex estimate + uint64_t surface = 0; //Not used in this context + float theta = edm4eic::anglePolar(momentum); + float phi = edm4eic::angleAzimuthal(momentum); + float qOverP = charge / edm4eic::magnitude(momentum); + float time; + // PDG + int32_t pdg = 11; + // Point Error + edm4eic::Cov6f error; + + edm4eic::TrackParameters params = outputFarDetectorMLTrackParameters->create( + type, surface, loc, theta, phi, qOverP, time, pdg, error); + + auto trajectory = outputFarDetectorMLTrajectories->create(); + trajectory.addToTrackParameters(params); + + int32_t trackType = 0; + edm4hep::Vector3f position = {0, 0, 0}; + float timeError; + float charge = -1; + float chi2 = 0; + uint32_t ndf = 0; + + auto outTrack = outputFarDetectorMLTracks->create(trackType, position, momentum, error, time, + timeError, charge, chi2, ndf); + outTrack.setTrajectory(trajectory); } - } + +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/FarDetectorMLReconstruction.h b/src/algorithms/fardetectors/FarDetectorMLReconstruction.h index a0f72141a7..4482d05e15 100644 --- a/src/algorithms/fardetectors/FarDetectorMLReconstruction.h +++ b/src/algorithms/fardetectors/FarDetectorMLReconstruction.h @@ -20,48 +20,38 @@ namespace eicrecon { - enum FarDetectorMLNNIndexIn{PosY,PosZ,DirX,DirY}; - enum FarDetectorMLNNIndexOut{MomX,MomY,MomZ}; +enum FarDetectorMLNNIndexIn { PosY, PosZ, DirX, DirY }; +enum FarDetectorMLNNIndexOut { MomX, MomY, MomZ }; - using FarDetectorMLReconstructionAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::TrackParametersCollection, - edm4hep::MCParticleCollection - >, - algorithms::Output< - edm4eic::TrajectoryCollection, - edm4eic::TrackParametersCollection, - edm4eic::TrackCollection - > - >; +using FarDetectorMLReconstructionAlgorithm = algorithms::Algorithm< + algorithms::Input, + algorithms::Output>; - class FarDetectorMLReconstruction - : public FarDetectorMLReconstructionAlgorithm, - public WithPodConfig { +class FarDetectorMLReconstruction : public FarDetectorMLReconstructionAlgorithm, + public WithPodConfig { - public: - FarDetectorMLReconstruction(std::string_view name) - : FarDetectorMLReconstructionAlgorithm{name, - {"TrackParameters","BeamElectrons"}, - {"Trajectory","TrackParameters","Track"}, - "Reconstruct track parameters using ML method."} {} +public: + FarDetectorMLReconstruction(std::string_view name) + : FarDetectorMLReconstructionAlgorithm{name, + {"TrackParameters", "BeamElectrons"}, + {"Trajectory", "TrackParameters", "Track"}, + "Reconstruct track parameters using ML method."} {} + /** One time initialization **/ + void init(); - /** One time initialization **/ - void init(); + /** Event by event processing **/ + void process(const Input&, const Output&); - /** Event by event processing **/ - void process(const Input&, const Output&); + //----- Define constants here ------ - //----- Define constants here ------ +private: + TMVA::Reader* m_reader{nullptr}; + TMVA::MethodBase* m_method{nullptr}; + float m_beamE{10.0}; + std::once_flag m_initBeamE; + float nnInput[4] = {0.0, 0.0, 0.0, 0.0}; +}; - private: - TMVA::Reader* m_reader{nullptr}; - TMVA::MethodBase* m_method{nullptr}; - float m_beamE{10.0}; - std::once_flag m_initBeamE; - float nnInput[4] = {0.0,0.0,0.0,0.0}; - - }; - -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/FarDetectorMLReconstructionConfig.h b/src/algorithms/fardetectors/FarDetectorMLReconstructionConfig.h index 29276a8bbe..2ce227b293 100644 --- a/src/algorithms/fardetectors/FarDetectorMLReconstructionConfig.h +++ b/src/algorithms/fardetectors/FarDetectorMLReconstructionConfig.h @@ -6,10 +6,9 @@ #include namespace eicrecon { - struct FarDetectorMLReconstructionConfig { +struct FarDetectorMLReconstructionConfig { - std::string modelPath; - std::string methodName; - - }; -} + std::string modelPath; + std::string methodName; +}; +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/FarDetectorTrackerClusterConfig.h b/src/algorithms/fardetectors/FarDetectorTrackerClusterConfig.h index 17975c5579..d9eccfb168 100644 --- a/src/algorithms/fardetectors/FarDetectorTrackerClusterConfig.h +++ b/src/algorithms/fardetectors/FarDetectorTrackerClusterConfig.h @@ -6,15 +6,14 @@ #include namespace eicrecon { - struct FarDetectorTrackerClusterConfig { +struct FarDetectorTrackerClusterConfig { - // Readout identifiers for dividing detector - std::string readout{""}; - std::string x_field{"x"}; - std::string y_field{"y"}; + // Readout identifiers for dividing detector + std::string readout{""}; + std::string x_field{"x"}; + std::string y_field{"y"}; - // Timing limit to add a hit to a cluster - double hit_time_limit{10*edm4eic::unit::ns}; - - }; -} + // Timing limit to add a hit to a cluster + double hit_time_limit{10 * edm4eic::unit::ns}; +}; +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/MatrixTransferStatic.cc b/src/algorithms/fardetectors/MatrixTransferStatic.cc index 01b933806a..a16e9f9db9 100644 --- a/src/algorithms/fardetectors/MatrixTransferStatic.cc +++ b/src/algorithms/fardetectors/MatrixTransferStatic.cc @@ -20,128 +20,123 @@ #include "algorithms/fardetectors/MatrixTransferStaticConfig.h" -void eicrecon::MatrixTransferStatic::init() { +void eicrecon::MatrixTransferStatic::init() {} -} - -void eicrecon::MatrixTransferStatic::process( - const MatrixTransferStatic::Input& input, - const MatrixTransferStatic::Output& output) const { +void eicrecon::MatrixTransferStatic::process(const MatrixTransferStatic::Input& input, + const MatrixTransferStatic::Output& output) const { const auto [mcparts, rechits] = input; - auto [outputParticles] = output; + auto [outputParticles] = output; std::vector> aX(m_cfg.aX); std::vector> aY(m_cfg.aY); //----- Define constants here ------ - double aXinv[2][2] = {{0.0, 0.0}, - {0.0, 0.0}}; - double aYinv[2][2] = {{0.0, 0.0}, - {0.0, 0.0}}; - - double nomMomentum = m_cfg.nomMomentum; //extract the nominal value first -- will be overwritten by MCParticle - double local_x_offset = m_cfg.local_x_offset; - double local_y_offset = m_cfg.local_y_offset; - double local_x_slope_offset = m_cfg.local_x_slope_offset; - double local_y_slope_offset = m_cfg.local_y_slope_offset; - - double numBeamProtons = 0; + double aXinv[2][2] = {{0.0, 0.0}, {0.0, 0.0}}; + double aYinv[2][2] = {{0.0, 0.0}, {0.0, 0.0}}; + + double nomMomentum = + m_cfg.nomMomentum; //extract the nominal value first -- will be overwritten by MCParticle + double local_x_offset = m_cfg.local_x_offset; + double local_y_offset = m_cfg.local_y_offset; + double local_x_slope_offset = m_cfg.local_x_slope_offset; + double local_y_slope_offset = m_cfg.local_y_slope_offset; + + double numBeamProtons = 0; double runningMomentum = 0.0; - for (const auto& p: *mcparts) { - if(mcparts->size() == 1 && p.getPDG() == 2212){ - runningMomentum = p.getMomentum().z; - numBeamProtons++; - } - if (p.getGeneratorStatus() == 4 && p.getPDG() == 2212) { //look for "beam" proton - runningMomentum += p.getMomentum().z; - numBeamProtons++; - } + for (const auto& p : *mcparts) { + if (mcparts->size() == 1 && p.getPDG() == 2212) { + runningMomentum = p.getMomentum().z; + numBeamProtons++; + } + if (p.getGeneratorStatus() == 4 && p.getPDG() == 2212) { //look for "beam" proton + runningMomentum += p.getMomentum().z; + numBeamProtons++; + } } - if(numBeamProtons == 0) {error("No beam protons to choose matrix!! Skipping!!"); return;} + if (numBeamProtons == 0) { + error("No beam protons to choose matrix!! Skipping!!"); + return; + } - nomMomentum = runningMomentum/numBeamProtons; + nomMomentum = runningMomentum / numBeamProtons; double nomMomentumError = 0.05; //This is a temporary solution to get the beam energy information //needed to select the correct matrix - if(abs(275.0 - nomMomentum)/275.0 < nomMomentumError){ + if (abs(275.0 - nomMomentum) / 275.0 < nomMomentumError) { - aX[0][0] = 3.251116; //a - aX[0][1] = 30.285734; //b - aX[1][0] = 0.186036375; //c - aX[1][1] = 0.196439472; //d + aX[0][0] = 3.251116; //a + aX[0][1] = 30.285734; //b + aX[1][0] = 0.186036375; //c + aX[1][1] = 0.196439472; //d - aY[0][0] = 0.4730500000; //a - aY[0][1] = 3.062999454; //b - aY[1][0] = 0.0204108951; //c - aY[1][1] = -0.139318692; //d + aY[0][0] = 0.4730500000; //a + aY[0][1] = 3.062999454; //b + aY[1][0] = 0.0204108951; //c + aY[1][1] = -0.139318692; //d - local_x_offset = -1209.29;//-0.339334; these are the local coordinate values - local_y_offset = 0.00132511;//-0.000299454; - local_x_slope_offset = -45.4772;//-0.219603248; - local_y_slope_offset = 0.000745498;//-0.000176128; + local_x_offset = -1209.29; //-0.339334; these are the local coordinate values + local_y_offset = 0.00132511; //-0.000299454; + local_x_slope_offset = -45.4772; //-0.219603248; + local_y_slope_offset = 0.000745498; //-0.000176128; - } - else if(abs(100.0 - nomMomentum)/100.0 < nomMomentumError){ + } else if (abs(100.0 - nomMomentum) / 100.0 < nomMomentumError) { - aX[0][0] = 3.152158; //a - aX[0][1] = 20.852072; //b - aX[1][0] = 0.181649517; //c - aX[1][1] = -0.303998487; //d + aX[0][0] = 3.152158; //a + aX[0][1] = 20.852072; //b + aX[1][0] = 0.181649517; //c + aX[1][1] = -0.303998487; //d - aY[0][0] = 0.5306100000; //a - aY[0][1] = 3.19623343; //b - aY[1][0] = 0.0226283320; //c - aY[1][1] = -0.082666019; //d + aY[0][0] = 0.5306100000; //a + aY[0][1] = 3.19623343; //b + aY[1][0] = 0.0226283320; //c + aY[1][1] = -0.082666019; //d - local_x_offset = -1209.27;//-0.329072; - local_y_offset = 0.00355218;//-0.00028343; - local_x_slope_offset = -45.4737;//-0.218525084; - local_y_slope_offset = 0.00204394;//-0.00015321; + local_x_offset = -1209.27; //-0.329072; + local_y_offset = 0.00355218; //-0.00028343; + local_x_slope_offset = -45.4737; //-0.218525084; + local_y_slope_offset = 0.00204394; //-0.00015321; - } - else if(abs(41.0 - nomMomentum)/41.0 < nomMomentumError){ + } else if (abs(41.0 - nomMomentum) / 41.0 < nomMomentumError) { - aX[0][0] = 3.135997; //a - aX[0][1] = 18.482273; //b - aX[1][0] = 0.176479921; //c - aX[1][1] = -0.497839483; //d + aX[0][0] = 3.135997; //a + aX[0][1] = 18.482273; //b + aX[1][0] = 0.176479921; //c + aX[1][1] = -0.497839483; //d - aY[0][0] = 0.4914400000; //a - aY[0][1] = 4.53857451; //b - aY[1][0] = 0.0179664765; //c - aY[1][1] = 0.004160679; //d + aY[0][0] = 0.4914400000; //a + aY[0][1] = 4.53857451; //b + aY[1][0] = 0.0179664765; //c + aY[1][1] = 0.004160679; //d - local_x_offset = -1209.22;//-0.283273; - local_y_offset = 0.00868737;//-0.00552451; - local_x_slope_offset = -45.4641;//-0.21174031; - local_y_slope_offset = 0.00498786;//-0.003212011; + local_x_offset = -1209.22; //-0.283273; + local_y_offset = 0.00868737; //-0.00552451; + local_x_slope_offset = -45.4641; //-0.21174031; + local_y_slope_offset = 0.00498786; //-0.003212011; - } - else if(abs(135.0 - nomMomentum)/135.0 < nomMomentumError){ //135 GeV deuterons + } else if (abs(135.0 - nomMomentum) / 135.0 < nomMomentumError) { //135 GeV deuterons - aX[0][0] = 1.6248; - aX[0][1] = 12.966293; - aX[1][0] = 0.1832; - aX[1][1] = -2.8636535; + aX[0][0] = 1.6248; + aX[0][1] = 12.966293; + aX[1][0] = 0.1832; + aX[1][1] = -2.8636535; - aY[0][0] = 0.0001674; //a - aY[0][1] = -28.6003; //b - aY[1][0] = 0.0000837; //c - aY[1][1] = -2.87985; //d + aY[0][0] = 0.0001674; //a + aY[0][1] = -28.6003; //b + aY[1][0] = 0.0000837; //c + aY[1][1] = -2.87985; //d - local_x_offset = -11.9872; - local_y_offset = -0.0146; - local_x_slope_offset = -14.75315; - local_y_slope_offset = -0.0073; + local_x_offset = -11.9872; + local_y_offset = -0.0146; + local_x_slope_offset = -14.75315; + local_y_slope_offset = -0.0073; - } - else { + } else { error("MatrixTransferStatic:: No valid matrix found to match beam momentum!! Skipping!!"); return; } @@ -153,11 +148,10 @@ void eicrecon::MatrixTransferStatic::process( return; } - aXinv[0][0] = aX[1][1] / determinant; + aXinv[0][0] = aX[1][1] / determinant; aXinv[0][1] = -aX[0][1] / determinant; aXinv[1][0] = -aX[1][0] / determinant; - aXinv[1][1] = aX[0][0] / determinant; - + aXinv[1][1] = aX[0][0] / determinant; determinant = aY[0][0] * aY[1][1] - aY[0][1] * aY[1][0]; @@ -166,14 +160,14 @@ void eicrecon::MatrixTransferStatic::process( return; } - aYinv[0][0] = aY[1][1] / determinant; + aYinv[0][0] = aY[1][1] / determinant; aYinv[0][1] = -aY[0][1] / determinant; aYinv[1][0] = -aY[1][0] / determinant; - aYinv[1][1] = aY[0][0] / determinant; + aYinv[1][1] = aY[0][0] / determinant; //---- begin Reconstruction code ---- - edm4hep::Vector3f goodHit[2] = {{0.0,0.0,0.0},{0.0,0.0,0.0}}; + edm4hep::Vector3f goodHit[2] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; double goodHitX[2] = {0.0, 0.0}; double goodHitY[2] = {0.0, 0.0}; @@ -182,41 +176,40 @@ void eicrecon::MatrixTransferStatic::process( bool goodHit1 = false; bool goodHit2 = false; - for (const auto &h: *rechits) { + for (const auto& h : *rechits) { auto cellID = h.getCellID(); // The actual hit position in Global Coordinates auto gpos = m_converter->position(cellID); // local positions auto volman = m_detector->volumeManager(); - auto local = volman.lookupDetElement(cellID); + auto local = volman.lookupDetElement(cellID); - auto pos0 = local.nominal().worldToLocal(dd4hep::Position(gpos.x(), gpos.y(), gpos.z())); // hit position in local coordinates + auto pos0 = local.nominal().worldToLocal( + dd4hep::Position(gpos.x(), gpos.y(), gpos.z())); // hit position in local coordinates // convert into mm - gpos = gpos/dd4hep::mm; - pos0 = pos0/dd4hep::mm; + gpos = gpos / dd4hep::mm; + pos0 = pos0 / dd4hep::mm; //std::cout << "gpos.z() = " << gpos.z() << " pos0.z() = " << pos0.z() << std::endl; //std::cout << "[gpos.x(), gpos.y()] = " << gpos.x() <<", "<< gpos.y() << " and [pos0.x(), pos0.y()] = "<< pos0.x()<< ", " << pos0.y() << std::endl; - if(!goodHit2 && gpos.z() > m_cfg.hit2minZ && gpos.z() < m_cfg.hit2maxZ){ + if (!goodHit2 && gpos.z() > m_cfg.hit2minZ && gpos.z() < m_cfg.hit2maxZ) { goodHit[1].x = gpos.x(); //pos0.x() - pos0 is local coordinates, gpos is global - goodHit[1].y = gpos.y(); //pos0.y() - temporarily changing to global to solve the local coordinate issue + goodHit[1].y = + gpos.y(); //pos0.y() - temporarily changing to global to solve the local coordinate issue goodHit[1].z = gpos.z(); // - which is unique to the Roman pots situation - goodHit2 = true; - + goodHit2 = true; } - if(!goodHit1 && gpos.z() > m_cfg.hit1minZ && gpos.z() < m_cfg.hit1maxZ){ + if (!goodHit1 && gpos.z() > m_cfg.hit1minZ && gpos.z() < m_cfg.hit1maxZ) { goodHit[0].x = gpos.x(); //pos0.x() goodHit[0].y = gpos.y(); //pos0.y() goodHit[0].z = gpos.z(); - goodHit1 = true; - + goodHit1 = true; } - } // NB: @@ -234,13 +227,12 @@ void eicrecon::MatrixTransferStatic::process( if (base == 0) { info("Detector separation = 0! Cannot calculate slope!"); - } - else{ + } else { double Xip[2] = {0.0, 0.0}; - double Xrp[2] = {XL[1], ((XL[1] - XL[0]) / (base))/dd4hep::mrad - local_x_slope_offset}; + double Xrp[2] = {XL[1], ((XL[1] - XL[0]) / (base)) / dd4hep::mrad - local_x_slope_offset}; double Yip[2] = {0.0, 0.0}; - double Yrp[2] = {YL[1], ((YL[1] - YL[0]) / (base))/dd4hep::mrad - local_y_slope_offset}; + double Yrp[2] = {YL[1], ((YL[1] - YL[0]) / (base)) / dd4hep::mrad - local_y_slope_offset}; // use the hit information and calculated slope at the RP + the transfer matrix inverse to calculate the // Polar Angle and deltaP at the IP @@ -252,26 +244,27 @@ void eicrecon::MatrixTransferStatic::process( } } - Yip[1] = Yrp[0]/aY[0][1]; + Yip[1] = Yrp[0] / aY[0][1]; // convert polar angles to radians double rsx = Xip[1] * dd4hep::mrad; double rsy = Yip[1] * dd4hep::mrad; // calculate momentum magnitude from measured deltaP – using thin lens optics. - double p = nomMomentum * (1 + 0.01 * Xip[0]); + double p = nomMomentum * (1 + 0.01 * Xip[0]); double norm = std::sqrt(1.0 + rsx * rsx + rsy * rsy); - edm4hep::Vector3f prec = {static_cast(p * rsx / norm), static_cast(p * rsy / norm), - static_cast(p / norm)}; - auto refPoint = goodHit[0]; + edm4hep::Vector3f prec = {static_cast(p * rsx / norm), + static_cast(p * rsy / norm), static_cast(p / norm)}; + auto refPoint = goodHit[0]; //----- end reconstruction code ------ edm4eic::MutableReconstructedParticle reconTrack; reconTrack.setType(0); reconTrack.setMomentum(prec); - reconTrack.setEnergy(std::hypot(edm4hep::utils::magnitude(reconTrack.getMomentum()), m_cfg.partMass)); + reconTrack.setEnergy( + std::hypot(edm4hep::utils::magnitude(reconTrack.getMomentum()), m_cfg.partMass)); reconTrack.setReferencePoint(refPoint); reconTrack.setCharge(m_cfg.partCharge); reconTrack.setMass(m_cfg.partMass); @@ -281,5 +274,4 @@ void eicrecon::MatrixTransferStatic::process( outputParticles->push_back(reconTrack); } } // end enough hits for matrix reco - } diff --git a/src/algorithms/fardetectors/MatrixTransferStatic.h b/src/algorithms/fardetectors/MatrixTransferStatic.h index b823e37e51..8f9b4e4f53 100644 --- a/src/algorithms/fardetectors/MatrixTransferStatic.h +++ b/src/algorithms/fardetectors/MatrixTransferStatic.h @@ -19,33 +19,26 @@ namespace eicrecon { - using MatrixTransferStaticAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4hep::MCParticleCollection, - edm4eic::TrackerHitCollection - >, - algorithms::Output< - edm4eic::ReconstructedParticleCollection - > - >; - - class MatrixTransferStatic - : public MatrixTransferStaticAlgorithm, - public WithPodConfig { - - public: - MatrixTransferStatic(std::string_view name) - : MatrixTransferStaticAlgorithm{name, - {"mcParticles", "inputHitCollection"}, - {"outputParticleCollection"}, - "Apply matrix method reconstruction to hits."} {} - - void init() final; - void process(const Input&, const Output&) const final; +using MatrixTransferStaticAlgorithm = algorithms::Algorithm< + algorithms::Input, + algorithms::Output>; - private: - const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; - const dd4hep::rec::CellIDPositionConverter* m_converter{algorithms::GeoSvc::instance().cellIDPositionConverter()}; +class MatrixTransferStatic : public MatrixTransferStaticAlgorithm, + public WithPodConfig { - }; -} +public: + MatrixTransferStatic(std::string_view name) + : MatrixTransferStaticAlgorithm{name, + {"mcParticles", "inputHitCollection"}, + {"outputParticleCollection"}, + "Apply matrix method reconstruction to hits."} {} + + void init() final; + void process(const Input&, const Output&) const final; + +private: + const dd4hep::Detector* m_detector{algorithms::GeoSvc::instance().detector()}; + const dd4hep::rec::CellIDPositionConverter* m_converter{ + algorithms::GeoSvc::instance().cellIDPositionConverter()}; +}; +} // namespace eicrecon diff --git a/src/algorithms/fardetectors/MatrixTransferStaticConfig.h b/src/algorithms/fardetectors/MatrixTransferStaticConfig.h index a559e1dc6a..2cb6956a70 100644 --- a/src/algorithms/fardetectors/MatrixTransferStaticConfig.h +++ b/src/algorithms/fardetectors/MatrixTransferStaticConfig.h @@ -5,43 +5,39 @@ namespace eicrecon { - struct MatrixTransferStaticConfig { - - float partMass {0.938272}; - float partCharge{1}; - long long partPDG {2212}; - - // Defaults here are for RPOTS - double local_x_offset {0.0}; - double local_y_offset {0.0}; - double local_x_slope_offset{-0.00622147}; - double local_y_slope_offset{-0.0451035}; - double crossingAngle {0.025}; - double nomMomentum {100.0}; - - //std::vector> aX = {{2.102403743, 29.11067626}, - // {0.186640381, 0.192604619}}; - //std::vector> aY = {{0.0000159900, 3.94082098}, - // {0.0000079946, -0.1402995}}; - - - //x_offset = 0.00979216; - //y_offset = -0.00778646; - //x_slope_offset = 0.004526961; - //y_slope_offset = -0.003907849; - - std::vector> aX = {{2.03459216, 22.85780784}, - {0.179641961, -0.306626961}}; - std::vector> aY = {{0.38879, 3.71612646}, - {0.022685, -0.003907849}}; - - double hit1minZ{0}; - double hit1maxZ{0}; - double hit2minZ{0}; - double hit2maxZ{0}; - - std::string readout{""}; - - }; - -} +struct MatrixTransferStaticConfig { + + float partMass{0.938272}; + float partCharge{1}; + long long partPDG{2212}; + + // Defaults here are for RPOTS + double local_x_offset{0.0}; + double local_y_offset{0.0}; + double local_x_slope_offset{-0.00622147}; + double local_y_slope_offset{-0.0451035}; + double crossingAngle{0.025}; + double nomMomentum{100.0}; + + //std::vector> aX = {{2.102403743, 29.11067626}, + // {0.186640381, 0.192604619}}; + //std::vector> aY = {{0.0000159900, 3.94082098}, + // {0.0000079946, -0.1402995}}; + + //x_offset = 0.00979216; + //y_offset = -0.00778646; + //x_slope_offset = 0.004526961; + //y_slope_offset = -0.003907849; + + std::vector> aX = {{2.03459216, 22.85780784}, {0.179641961, -0.306626961}}; + std::vector> aY = {{0.38879, 3.71612646}, {0.022685, -0.003907849}}; + + double hit1minZ{0}; + double hit1maxZ{0}; + double hit2minZ{0}; + double hit2maxZ{0}; + + std::string readout{""}; +}; + +} // namespace eicrecon diff --git a/src/algorithms/interfaces/ParticleSvc.cc b/src/algorithms/interfaces/ParticleSvc.cc index c23128ded3..251d389ae6 100644 --- a/src/algorithms/interfaces/ParticleSvc.cc +++ b/src/algorithms/interfaces/ParticleSvc.cc @@ -8,6 +8,7 @@ namespace algorithms { const std::shared_ptr ParticleSvc::kParticleMap = + // clang-format off std::make_shared(ParticleSvc::ParticleMap{ { 0, { 0, 0, 0.0 , "unknown" }}, { 11, { 11, -1, 0.000510998928, "e-" }}, @@ -248,5 +249,6 @@ const std::shared_ptr ParticleSvc::kParticleMap = { 1000020030, { 1000020030, 2, 2.80923 , "He-3" }}, { 1000020040, { 1000020040, 2, 3.72742 , "Alpha" }}, }); +// clang-format on } // namespace algorithms diff --git a/src/algorithms/interfaces/ParticleSvc.h b/src/algorithms/interfaces/ParticleSvc.h index 5f3db7311c..d502819d12 100644 --- a/src/algorithms/interfaces/ParticleSvc.h +++ b/src/algorithms/interfaces/ParticleSvc.h @@ -13,9 +13,9 @@ namespace algorithms { class ParticleSvc : public Service { public: struct ParticleData { - int pdgCode; - int charge; - double mass; + int pdgCode; + int charge; + double mass; std::string name; }; using Particle = ParticleData; @@ -31,9 +31,7 @@ class ParticleSvc : public Service { } } - virtual std::shared_ptr particleMap() const { - return m_particleMap; - }; + virtual std::shared_ptr particleMap() const { return m_particleMap; }; virtual Particle& particle(int pdg) const { if (m_particleMap->count(pdg) == 0) { diff --git a/src/algorithms/interfaces/WithPodConfig.h b/src/algorithms/interfaces/WithPodConfig.h index ac5a113ceb..dc253f863f 100644 --- a/src/algorithms/interfaces/WithPodConfig.h +++ b/src/algorithms/interfaces/WithPodConfig.h @@ -5,34 +5,35 @@ #pragma once namespace eicrecon { - /** +/** * This struct might be used for factories that has no underlying config class, * for example: * WithPodConfig */ - struct NoConfig { - }; +struct NoConfig {}; - /** +/** * Small helper class that brings common functions interface for classes that have POD type config * @tparam ConfigT * * @example: * */ - template - class WithPodConfig { - public: - using ConfigType = ConfigT; +template class WithPodConfig { +public: + using ConfigType = ConfigT; - /// Get a configuration to be changed - ConfigT& getConfig() {return m_cfg;} + /// Get a configuration to be changed + ConfigT& getConfig() { return m_cfg; } - /// Sets a configuration (config is properly copyible) - ConfigT& applyConfig(ConfigT cfg) { m_cfg = cfg; return m_cfg;} + /// Sets a configuration (config is properly copyible) + ConfigT& applyConfig(ConfigT cfg) { + m_cfg = cfg; + return m_cfg; + } - protected: - /** configuration parameters **/ - ConfigT m_cfg; - }; -} +protected: + /** configuration parameters **/ + ConfigT m_cfg; +}; +} // namespace eicrecon diff --git a/src/algorithms/meta/CollectionCollector.h b/src/algorithms/meta/CollectionCollector.h index ccafe3fc36..9f478d3e32 100644 --- a/src/algorithms/meta/CollectionCollector.h +++ b/src/algorithms/meta/CollectionCollector.h @@ -11,40 +11,39 @@ namespace eicrecon { - template - using CollectionCollectorAlgorithm = algorithms::Algorithm< - typename algorithms::Input>, - typename algorithms::Output - >; +template +using CollectionCollectorAlgorithm = + algorithms::Algorithm>, + typename algorithms::Output>; - template - class CollectionCollector : public CollectionCollectorAlgorithm { +template class CollectionCollector : public CollectionCollectorAlgorithm { - public: - CollectionCollector(std::string_view name) +public: + CollectionCollector(std::string_view name) : CollectionCollectorAlgorithm{name, - {"inputCollections"}, - {"outputCollection"}, - "Merge content of collections into one subset collection" - }{} + {"inputCollections"}, + {"outputCollection"}, + "Merge content of collections into one subset collection"} { + } - void init() final { }; + void init() final {}; - void process(const typename CollectionCollector::Input& input, const typename CollectionCollector::Output& output) const final{ + void process(const typename CollectionCollector::Input& input, + const typename CollectionCollector::Output& output) const final { - const auto [in_collections] = input; - auto [out_collection] = output; + const auto [in_collections] = input; + auto [out_collection] = output; - out_collection->setSubsetCollection(); + out_collection->setSubsetCollection(); - for (const auto& collection : in_collections) { - for (const auto& hit : *collection) { - out_collection->push_back(hit); - } + for (const auto& collection : in_collections) { + for (const auto& hit : *collection) { + out_collection->push_back(hit); } - //Log how many hits were collected from N input collections - this->debug("Collected {} hits from {} input collections", out_collection->size(), in_collections.size()); } - - }; -} // eicrecon + //Log how many hits were collected from N input collections + this->debug("Collected {} hits from {} input collections", out_collection->size(), + in_collections.size()); + } +}; +} // namespace eicrecon diff --git a/src/algorithms/meta/FilterMatching.h b/src/algorithms/meta/FilterMatching.h index 106ad64441..a30502a9e6 100644 --- a/src/algorithms/meta/FilterMatching.h +++ b/src/algorithms/meta/FilterMatching.h @@ -13,70 +13,64 @@ namespace eicrecon { - template - using FilterMatchingAlgorithm = algorithms::Algorithm< - typename algorithms::Input< - typename ToFilterObjectT::collection_type, - typename FilterByObjectT::collection_type - >, - typename algorithms::Output< - typename ToFilterObjectT::collection_type, - typename ToFilterObjectT::collection_type - > - >; - - /// Filters a collection by the members of another collection - /// The first collection is divided up into two collections where its elements either passed the filter or not - /// The second collection provides a filter - /// Functions need to be provided along with the collections to form the link between the data types - /// These functions are envisioned to link the objectIDs of the collection/associations but could be anything - template - class FilterMatching : public FilterMatchingAlgorithm { - - public: - FilterMatching(std::string_view name) - : FilterMatchingAlgorithm{name, - {"inputCollection","inputMatchedCollection"}, - {"outputMatchedAssociations","outputUnmatchedAssociations"}, - "Filter by matching to a collection" - } { - }; - - void init() final { }; - - void process(const typename FilterMatchingAlgorithm::Input& input, - const typename FilterMatchingAlgorithm::Output& output) const final{ - - const auto [toFilterEntries,filterByEntries] = input; - auto [is_matched,is_not_matched] = output; - - is_matched->setSubsetCollection(); - is_not_matched->setSubsetCollection(); - - for (const auto& matchedEntry : *toFilterEntries){ - - auto ref_value = ToFilterFunction(&matchedEntry); - - bool found_match = false; - - // Tries to find the association in the entries - for(const auto& entry : *filterByEntries){ - auto other_value = FilterByFunction(&entry); - if(other_value == ref_value){ - is_matched->push_back(matchedEntry); - found_match = true; - break; - } - } - - if(!found_match){ - is_not_matched->push_back(matchedEntry); - } - - } - - }; - +template +using FilterMatchingAlgorithm = + algorithms::Algorithm, + typename algorithms::Output>; + +/// Filters a collection by the members of another collection +/// The first collection is divided up into two collections where its elements either passed the filter or not +/// The second collection provides a filter +/// Functions need to be provided along with the collections to form the link between the data types +/// These functions are envisioned to link the objectIDs of the collection/associations but could be anything +template +class FilterMatching : public FilterMatchingAlgorithm { + +public: + FilterMatching(std::string_view name) + : FilterMatchingAlgorithm{ + name, + {"inputCollection", "inputMatchedCollection"}, + {"outputMatchedAssociations", "outputUnmatchedAssociations"}, + "Filter by matching to a collection"} {}; + + void init() final {}; + + void + process(const typename FilterMatchingAlgorithm::Input& input, + const typename FilterMatchingAlgorithm::Output& output) + const final { + + const auto [toFilterEntries, filterByEntries] = input; + auto [is_matched, is_not_matched] = output; + + is_matched->setSubsetCollection(); + is_not_matched->setSubsetCollection(); + + for (const auto& matchedEntry : *toFilterEntries) { + + auto ref_value = ToFilterFunction(&matchedEntry); + + bool found_match = false; + + // Tries to find the association in the entries + for (const auto& entry : *filterByEntries) { + auto other_value = FilterByFunction(&entry); + if (other_value == ref_value) { + is_matched->push_back(matchedEntry); + found_match = true; + break; + } + } + + if (!found_match) { + is_not_matched->push_back(matchedEntry); + } + } }; +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/meta/SubDivideCollection.h b/src/algorithms/meta/SubDivideCollection.h index 8329b930d1..f76ff6761c 100644 --- a/src/algorithms/meta/SubDivideCollection.h +++ b/src/algorithms/meta/SubDivideCollection.h @@ -15,56 +15,52 @@ namespace eicrecon { - template - using SubDivideCollectionAlgorithm = algorithms::Algorithm< - typename algorithms::Input, - typename algorithms::Output> - >; +template +using SubDivideCollectionAlgorithm = + algorithms::Algorithm, + typename algorithms::Output>>; +template +class SubDivideCollection : public SubDivideCollectionAlgorithm, + public WithPodConfig> { - template - class SubDivideCollection : public SubDivideCollectionAlgorithm, public WithPodConfig> { - - public: - SubDivideCollection(std::string_view name) +public: + SubDivideCollection(std::string_view name) : SubDivideCollectionAlgorithm{name, - {"inputCollection"}, - {"outputCollection"}, - "Sub-Divide collection" - }, - WithPodConfig>() { - }; - - void init() final { }; - - void process(const typename SubDivideCollectionAlgorithm::Input& input, const typename SubDivideCollectionAlgorithm::Output& output) const final{ - - const auto [entries] = input; - auto [subdivided_entries] = output; + {"inputCollection"}, + {"outputCollection"}, + "Sub-Divide collection"} + , WithPodConfig>() {}; - for( auto out : subdivided_entries){ - out->setSubsetCollection(); - } + void init() final {}; - for (const auto& entry : *entries) { + void process(const typename SubDivideCollectionAlgorithm::Input& input, + const typename SubDivideCollectionAlgorithm::Output& output) const final { - auto div_indices = this->m_cfg.function(entry); + const auto [entries] = input; + auto [subdivided_entries] = output; - for (auto index : div_indices){ - subdivided_entries[index]->push_back(entry); - } + for (auto out : subdivided_entries) { + out->setSubsetCollection(); + } - } + for (const auto& entry : *entries) { - //Log how the hits were divided between the collection names - this->debug("Divided {} hits between {} collections", entries->size(), subdivided_entries.size()); - //How many hits in each output collection - for (size_t i = 0; i < subdivided_entries.size(); i++) { - this->debug("Collection {} takes {} hits", i, subdivided_entries[i]->size()); - } + auto div_indices = this->m_cfg.function(entry); - }; + for (auto index : div_indices) { + subdivided_entries[index]->push_back(entry); + } + } + //Log how the hits were divided between the collection names + this->debug("Divided {} hits between {} collections", entries->size(), + subdivided_entries.size()); + //How many hits in each output collection + for (size_t i = 0; i < subdivided_entries.size(); i++) { + this->debug("Collection {} takes {} hits", i, subdivided_entries[i]->size()); + } }; +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/meta/SubDivideCollectionConfig.h b/src/algorithms/meta/SubDivideCollectionConfig.h index 47ef9f66f1..d10721a2a8 100644 --- a/src/algorithms/meta/SubDivideCollectionConfig.h +++ b/src/algorithms/meta/SubDivideCollectionConfig.h @@ -5,9 +5,8 @@ namespace eicrecon { - template - struct SubDivideCollectionConfig { - std::function(const T&)> function; - }; +template struct SubDivideCollectionConfig { + std::function(const T&)> function; +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/meta/SubDivideFunctors.h b/src/algorithms/meta/SubDivideFunctors.h index a6bb89167d..c26de86917 100644 --- a/src/algorithms/meta/SubDivideFunctors.h +++ b/src/algorithms/meta/SubDivideFunctors.h @@ -10,27 +10,24 @@ namespace eicrecon { // ---------------------------------------------------------------------------- // Functor to split collection based on a range of values // ---------------------------------------------------------------------------- -template -class RangeSplit { +template class RangeSplit { public: - - RangeSplit(std::vector> ranges) : m_ranges(ranges) {}; - - template - std::vector operator()(T& instance) const { - std::vector ids; - //Check if requested value is within the ranges - for(size_t i = 0; i < m_ranges.size(); i++){ - if((instance.*MemberFunctionPtr)() > m_ranges[i].first && (instance.*MemberFunctionPtr)() < m_ranges[i].second){ - ids.push_back(i); - } - } - return ids; + RangeSplit(std::vector> ranges) : m_ranges(ranges) {}; + + template std::vector operator()(T& instance) const { + std::vector ids; + //Check if requested value is within the ranges + for (size_t i = 0; i < m_ranges.size(); i++) { + if ((instance.*MemberFunctionPtr)() > m_ranges[i].first && + (instance.*MemberFunctionPtr)() < m_ranges[i].second) { + ids.push_back(i); + } } + return ids; + } private: - std::vector> m_ranges; - + std::vector> m_ranges; }; // ---------------------------------------------------------------------------- @@ -38,80 +35,74 @@ class RangeSplit { // ---------------------------------------------------------------------------- class GeometrySplit { public: + GeometrySplit(std::vector> ids, std::string readout, + std::vector divisions) + : m_ids(ids) + , m_readout(readout) + , m_divisions(divisions) + , is_init(std::make_shared()) + , m_id_dec(std::make_shared()) + , m_div_ids(std::make_shared>()) {}; + + template std::vector operator()(T& instance) const { + + // Initialize the decoder and division ids on the first function call + std::call_once(*is_init, &GeometrySplit::init, this); + + //Check which detector division to put the hit into + auto cellID = instance.getCellID(); + std::vector det_ids; + for (auto d : *m_div_ids) { + det_ids.push_back((*m_id_dec)->get(cellID, d)); + } - GeometrySplit(std::vector> ids, std::string readout, std::vector divisions) - : m_ids(ids), m_readout(readout), m_divisions(divisions), - is_init(std::make_shared()), - m_id_dec(std::make_shared()), - m_div_ids(std::make_shared>()) {}; - - template - std::vector operator()(T& instance) const { - - // Initialize the decoder and division ids on the first function call - std::call_once(*is_init, &GeometrySplit::init, this); - - //Check which detector division to put the hit into - auto cellID = instance.getCellID(); - std::vector det_ids; - for(auto d : *m_div_ids){ - det_ids.push_back((*m_id_dec)->get(cellID, d)); - } - - auto index = std::find(m_ids.begin(),m_ids.end(),det_ids); + auto index = std::find(m_ids.begin(), m_ids.end(), det_ids); - std::vector ids; - if(index != m_ids.end()){ - ids.push_back(std::distance(m_ids.begin(),index)); - } - return ids; + std::vector ids; + if (index != m_ids.end()) { + ids.push_back(std::distance(m_ids.begin(), index)); } + return ids; + } private: - - void init() const { - *m_id_dec = algorithms::GeoSvc::instance().detector()->readout(m_readout).idSpec().decoder(); - for (auto d : m_divisions){ - m_div_ids->push_back((*m_id_dec)->index(d)); - } + void init() const { + *m_id_dec = algorithms::GeoSvc::instance().detector()->readout(m_readout).idSpec().decoder(); + for (auto d : m_divisions) { + m_div_ids->push_back((*m_id_dec)->index(d)); } + } - std::vector> m_ids; - std::vector m_divisions; - std::string m_readout; - - std::shared_ptr is_init; - std::shared_ptr m_id_dec; - std::shared_ptr> m_div_ids; + std::vector> m_ids; + std::vector m_divisions; + std::string m_readout; + std::shared_ptr is_init; + std::shared_ptr m_id_dec; + std::shared_ptr> m_div_ids; }; - // ---------------------------------------------------------------------------- // Functor to split collection based on any number of collection values // ---------------------------------------------------------------------------- -template -class ValueSplit { +template class ValueSplit { public: - - ValueSplit(std::vector> ids) : m_ids(ids) {}; - - template - std::vector operator()(T& instance) const { - std::vector ids; - // Check if requested value matches any configuration combinations - std::vector values; - (values.push_back((instance.*MemberFunctionPtrs)()), ...); - auto index = std::find(m_ids.begin(),m_ids.end(),values); - if(index != m_ids.end()){ - ids.push_back(std::distance(m_ids.begin(),index)); - } - return ids; + ValueSplit(std::vector> ids) : m_ids(ids) {}; + + template std::vector operator()(T& instance) const { + std::vector ids; + // Check if requested value matches any configuration combinations + std::vector values; + (values.push_back((instance.*MemberFunctionPtrs)()), ...); + auto index = std::find(m_ids.begin(), m_ids.end(), values); + if (index != m_ids.end()) { + ids.push_back(std::distance(m_ids.begin(), index)); } + return ids; + } private: - std::vector> m_ids; - + std::vector> m_ids; }; -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/onnx/CalorimeterParticleIDPostML.cc b/src/algorithms/onnx/CalorimeterParticleIDPostML.cc index 7c2b2199ab..20217e6a32 100644 --- a/src/algorithms/onnx/CalorimeterParticleIDPostML.cc +++ b/src/algorithms/onnx/CalorimeterParticleIDPostML.cc @@ -13,74 +13,82 @@ namespace eicrecon { - void CalorimeterParticleIDPostML::init() { - // Nothing - } +void CalorimeterParticleIDPostML::init() { + // Nothing +} - void CalorimeterParticleIDPostML::process( - const CalorimeterParticleIDPostML::Input& input, - const CalorimeterParticleIDPostML::Output& output) const { +void CalorimeterParticleIDPostML::process(const CalorimeterParticleIDPostML::Input& input, + const CalorimeterParticleIDPostML::Output& output) const { - const auto [in_clusters, in_assocs, prediction_tensors] = input; - auto [out_clusters, out_assocs, out_particle_ids] = output; + const auto [in_clusters, in_assocs, prediction_tensors] = input; + auto [out_clusters, out_assocs, out_particle_ids] = output; - if (prediction_tensors->size() != 1) { - error("Expected to find a single tensor, found {}", prediction_tensors->size()); - throw std::runtime_error(""); - } - edm4eic::Tensor prediction_tensor = (*prediction_tensors)[0]; + if (prediction_tensors->size() != 1) { + error("Expected to find a single tensor, found {}", prediction_tensors->size()); + throw std::runtime_error(""); + } + edm4eic::Tensor prediction_tensor = (*prediction_tensors)[0]; - if (prediction_tensor.shape_size() != 2) { - error("Expected tensor rank to be 2, but it is {}", prediction_tensor.shape_size()); - throw std::runtime_error(fmt::format("Expected tensor rank to be 2, but it is {}", prediction_tensor.shape_size())); - } + if (prediction_tensor.shape_size() != 2) { + error("Expected tensor rank to be 2, but it is {}", prediction_tensor.shape_size()); + throw std::runtime_error( + fmt::format("Expected tensor rank to be 2, but it is {}", prediction_tensor.shape_size())); + } - if (prediction_tensor.getShape(0) != in_clusters->size()) { - error("Length mismatch between tensor's 0th axis and number of clusters: {} != {}", prediction_tensor.getShape(0), in_clusters->size()); - throw std::runtime_error(fmt::format("Length mismatch between tensor's 0th axis and number of clusters: {} != {}", prediction_tensor.getShape(0), in_clusters->size())); - } + if (prediction_tensor.getShape(0) != in_clusters->size()) { + error("Length mismatch between tensor's 0th axis and number of clusters: {} != {}", + prediction_tensor.getShape(0), in_clusters->size()); + throw std::runtime_error( + fmt::format("Length mismatch between tensor's 0th axis and number of clusters: {} != {}", + prediction_tensor.getShape(0), in_clusters->size())); + } - if (prediction_tensor.getShape(1) != 2) { - error("Expected 2 values per cluster in the output tensor, got {}", prediction_tensor.getShape(0)); - throw std::runtime_error(fmt::format("Expected 2 values per cluster in the output tensor, got {}", prediction_tensor.getShape(0))); - } + if (prediction_tensor.getShape(1) != 2) { + error("Expected 2 values per cluster in the output tensor, got {}", + prediction_tensor.getShape(0)); + throw std::runtime_error( + fmt::format("Expected 2 values per cluster in the output tensor, got {}", + prediction_tensor.getShape(0))); + } - if (prediction_tensor.getElementType() != 1) { // 1 - float - error("Expected a tensor of floats, but element type is {}", prediction_tensor.getElementType()); - throw std::runtime_error(fmt::format("Expected a tensor of floats, but element type is {}", prediction_tensor.getElementType())); - } + if (prediction_tensor.getElementType() != 1) { // 1 - float + error("Expected a tensor of floats, but element type is {}", + prediction_tensor.getElementType()); + throw std::runtime_error(fmt::format("Expected a tensor of floats, but element type is {}", + prediction_tensor.getElementType())); + } - for (size_t cluster_ix = 0; cluster_ix < in_clusters->size(); cluster_ix++) { - edm4eic::Cluster in_cluster = (*in_clusters)[cluster_ix]; - edm4eic::MutableCluster out_cluster = in_cluster.clone(); - out_clusters->push_back(out_cluster); - - float prob_pion = prediction_tensor.getFloatData(cluster_ix * prediction_tensor.getShape(1) + 0); - float prob_electron = prediction_tensor.getFloatData(cluster_ix * prediction_tensor.getShape(1) + 1); - - out_cluster.addToParticleIDs(out_particle_ids->create( - 0, // std::int32_t type - 211, // std::int32_t PDG - 0, // std::int32_t algorithmType - prob_pion // float likelihood - )); - out_cluster.addToParticleIDs(out_particle_ids->create( - 0, // std::int32_t type - 11, // std::int32_t PDG - 0, // std::int32_t algorithmType - prob_electron // float likelihood - )); - - // propagate associations - for (auto in_assoc : *in_assocs) { - if (in_assoc.getRec() == in_cluster) { - auto out_assoc = in_assoc.clone(); - out_assoc.setRec(out_cluster); - out_assocs->push_back(out_assoc); - } + for (size_t cluster_ix = 0; cluster_ix < in_clusters->size(); cluster_ix++) { + edm4eic::Cluster in_cluster = (*in_clusters)[cluster_ix]; + edm4eic::MutableCluster out_cluster = in_cluster.clone(); + out_clusters->push_back(out_cluster); + + float prob_pion = + prediction_tensor.getFloatData(cluster_ix * prediction_tensor.getShape(1) + 0); + float prob_electron = + prediction_tensor.getFloatData(cluster_ix * prediction_tensor.getShape(1) + 1); + + out_cluster.addToParticleIDs(out_particle_ids->create(0, // std::int32_t type + 211, // std::int32_t PDG + 0, // std::int32_t algorithmType + prob_pion // float likelihood + )); + out_cluster.addToParticleIDs(out_particle_ids->create(0, // std::int32_t type + 11, // std::int32_t PDG + 0, // std::int32_t algorithmType + prob_electron // float likelihood + )); + + // propagate associations + for (auto in_assoc : *in_assocs) { + if (in_assoc.getRec() == in_cluster) { + auto out_assoc = in_assoc.clone(); + out_assoc.setRec(out_cluster); + out_assocs->push_back(out_assoc); } } } +} } // namespace eicrecon #endif diff --git a/src/algorithms/onnx/CalorimeterParticleIDPostML.h b/src/algorithms/onnx/CalorimeterParticleIDPostML.h index dbc2cb93e8..3dd3c68c3c 100644 --- a/src/algorithms/onnx/CalorimeterParticleIDPostML.h +++ b/src/algorithms/onnx/CalorimeterParticleIDPostML.h @@ -16,26 +16,24 @@ namespace eicrecon { -using CalorimeterParticleIDPostMLAlgorithm = - algorithms::Algorithm< +using CalorimeterParticleIDPostMLAlgorithm = algorithms::Algorithm< algorithms::Input, - edm4eic::TensorCollection>, - algorithms::Output, - edm4hep::ParticleIDCollection> - >; + edm4eic::TensorCollection>, + algorithms::Output, + edm4hep::ParticleIDCollection>>; class CalorimeterParticleIDPostML : public CalorimeterParticleIDPostMLAlgorithm, - public WithPodConfig { + public WithPodConfig { public: CalorimeterParticleIDPostML(std::string_view name) - : CalorimeterParticleIDPostMLAlgorithm{name, - {"inputClusters", "inputClusterAssociations", "inputPredictionsTensor"}, - {"outputClusters", "outputClusterAssociations", "outputParticleIDs"}, - ""} { - } + : CalorimeterParticleIDPostMLAlgorithm{ + name, + {"inputClusters", "inputClusterAssociations", "inputPredictionsTensor"}, + {"outputClusters", "outputClusterAssociations", "outputParticleIDs"}, + ""} {} void init() final; void process(const Input&, const Output&) const final; diff --git a/src/algorithms/onnx/CalorimeterParticleIDPreML.cc b/src/algorithms/onnx/CalorimeterParticleIDPreML.cc index 89d2175d7c..01ebc64a64 100644 --- a/src/algorithms/onnx/CalorimeterParticleIDPreML.cc +++ b/src/algorithms/onnx/CalorimeterParticleIDPreML.cc @@ -17,84 +17,86 @@ namespace eicrecon { - void CalorimeterParticleIDPreML::init() { - // Nothing - } +void CalorimeterParticleIDPreML::init() { + // Nothing +} - void CalorimeterParticleIDPreML::process( - const CalorimeterParticleIDPreML::Input& input, - const CalorimeterParticleIDPreML::Output& output) const { +void CalorimeterParticleIDPreML::process(const CalorimeterParticleIDPreML::Input& input, + const CalorimeterParticleIDPreML::Output& output) const { - const auto [clusters, cluster_assocs] = input; - auto [feature_tensors, target_tensors] = output; + const auto [clusters, cluster_assocs] = input; + auto [feature_tensors, target_tensors] = output; - edm4eic::MutableTensor feature_tensor = feature_tensors->create(); - feature_tensor.addToShape(clusters->size()); - feature_tensor.addToShape(11); // p, E/p, azimuthal, polar, 7 shape parameters - feature_tensor.setElementType(1); // 1 - float + edm4eic::MutableTensor feature_tensor = feature_tensors->create(); + feature_tensor.addToShape(clusters->size()); + feature_tensor.addToShape(11); // p, E/p, azimuthal, polar, 7 shape parameters + feature_tensor.setElementType(1); // 1 - float - edm4eic::MutableTensor target_tensor; - if (cluster_assocs) { - target_tensor = target_tensors->create(); - target_tensor.addToShape(clusters->size()); - target_tensor.addToShape(2); // is electron, is hadron - target_tensor.setElementType(7); // 7 - int64 - } + edm4eic::MutableTensor target_tensor; + if (cluster_assocs) { + target_tensor = target_tensors->create(); + target_tensor.addToShape(clusters->size()); + target_tensor.addToShape(2); // is electron, is hadron + target_tensor.setElementType(7); // 7 - int64 + } - for (edm4eic::Cluster cluster : *clusters) { - double momentum; - { - // FIXME: use track momentum once matching to tracks becomes available - edm4eic::MCRecoClusterParticleAssociation best_assoc; - for (auto assoc : *cluster_assocs) { - if (assoc.getRec() == cluster) { - if ((not best_assoc.isAvailable()) || (assoc.getWeight() > best_assoc.getWeight())) { - best_assoc = assoc; - } + for (edm4eic::Cluster cluster : *clusters) { + double momentum; + { + // FIXME: use track momentum once matching to tracks becomes available + edm4eic::MCRecoClusterParticleAssociation best_assoc; + for (auto assoc : *cluster_assocs) { + if (assoc.getRec() == cluster) { + if ((not best_assoc.isAvailable()) || (assoc.getWeight() > best_assoc.getWeight())) { + best_assoc = assoc; } } - if (best_assoc.isAvailable()) { - momentum = edm4hep::utils::magnitude(best_assoc.getSim().getMomentum()); - } else { - warning("Can't find association for cluster. Skipping..."); - continue; - } } - - feature_tensor.addToFloatData(momentum); - feature_tensor.addToFloatData(cluster.getEnergy() / momentum); - auto pos = cluster.getPosition(); - feature_tensor.addToFloatData(edm4hep::utils::anglePolar(pos)); - feature_tensor.addToFloatData(edm4hep::utils::angleAzimuthal(pos)); - for (int par_ix = 0; par_ix < cluster.shapeParameters_size(); par_ix++) { - feature_tensor.addToFloatData(cluster.getShapeParameters(par_ix)); + if (best_assoc.isAvailable()) { + momentum = edm4hep::utils::magnitude(best_assoc.getSim().getMomentum()); + } else { + warning("Can't find association for cluster. Skipping..."); + continue; } + } - if (cluster_assocs) { - edm4eic::MCRecoClusterParticleAssociation best_assoc; - for (auto assoc : *cluster_assocs) { - if (assoc.getRec() == cluster) { - if ((not best_assoc.isAvailable()) || (assoc.getWeight() > best_assoc.getWeight())) { - best_assoc = assoc; - } + feature_tensor.addToFloatData(momentum); + feature_tensor.addToFloatData(cluster.getEnergy() / momentum); + auto pos = cluster.getPosition(); + feature_tensor.addToFloatData(edm4hep::utils::anglePolar(pos)); + feature_tensor.addToFloatData(edm4hep::utils::angleAzimuthal(pos)); + for (int par_ix = 0; par_ix < cluster.shapeParameters_size(); par_ix++) { + feature_tensor.addToFloatData(cluster.getShapeParameters(par_ix)); + } + + if (cluster_assocs) { + edm4eic::MCRecoClusterParticleAssociation best_assoc; + for (auto assoc : *cluster_assocs) { + if (assoc.getRec() == cluster) { + if ((not best_assoc.isAvailable()) || (assoc.getWeight() > best_assoc.getWeight())) { + best_assoc = assoc; } } - int64_t is_electron = 0, is_pion = 0; - if (best_assoc.isAvailable()) { - is_electron = best_assoc.getSim().getPDG() == 11; - is_pion = best_assoc.getSim().getPDG() != 11; - } - target_tensor.addToInt64Data(is_pion); - target_tensor.addToInt64Data(is_electron); } + int64_t is_electron = 0, is_pion = 0; + if (best_assoc.isAvailable()) { + is_electron = best_assoc.getSim().getPDG() == 11; + is_pion = best_assoc.getSim().getPDG() != 11; + } + target_tensor.addToInt64Data(is_pion); + target_tensor.addToInt64Data(is_electron); } + } - size_t expected_num_entries = feature_tensor.getShape(0) * feature_tensor.getShape(1); - if (feature_tensor.floatData_size() != expected_num_entries) { - error("Inconsistent output tensor shape and element count: {} != {}", feature_tensor.floatData_size(), expected_num_entries); - throw std::runtime_error(fmt::format("Inconsistent output tensor shape and element count: {} != {}", feature_tensor.floatData_size(), expected_num_entries)); - } + size_t expected_num_entries = feature_tensor.getShape(0) * feature_tensor.getShape(1); + if (feature_tensor.floatData_size() != expected_num_entries) { + error("Inconsistent output tensor shape and element count: {} != {}", + feature_tensor.floatData_size(), expected_num_entries); + throw std::runtime_error( + fmt::format("Inconsistent output tensor shape and element count: {} != {}", + feature_tensor.floatData_size(), expected_num_entries)); } +} } // namespace eicrecon #endif diff --git a/src/algorithms/onnx/CalorimeterParticleIDPreML.h b/src/algorithms/onnx/CalorimeterParticleIDPreML.h index bc4b757eb4..9ae4858d66 100644 --- a/src/algorithms/onnx/CalorimeterParticleIDPreML.h +++ b/src/algorithms/onnx/CalorimeterParticleIDPreML.h @@ -15,22 +15,18 @@ namespace eicrecon { -using CalorimeterParticleIDPreMLAlgorithm = - algorithms::Algorithm>, - algorithms::Output>>; +using CalorimeterParticleIDPreMLAlgorithm = algorithms::Algorithm< + algorithms::Input>, + algorithms::Output>>; class CalorimeterParticleIDPreML : public CalorimeterParticleIDPreMLAlgorithm, - public WithPodConfig { + public WithPodConfig { public: CalorimeterParticleIDPreML(std::string_view name) - : CalorimeterParticleIDPreMLAlgorithm{name, - {"inputClusters"}, - {"outputFeatureTensor", "outputTargetTensor"}, - ""} { - } + : CalorimeterParticleIDPreMLAlgorithm{ + name, {"inputClusters"}, {"outputFeatureTensor", "outputTargetTensor"}, ""} {} void init() final; void process(const Input&, const Output&) const final; diff --git a/src/algorithms/onnx/InclusiveKinematicsML.cc b/src/algorithms/onnx/InclusiveKinematicsML.cc index 091e637eff..076681f330 100644 --- a/src/algorithms/onnx/InclusiveKinematicsML.cc +++ b/src/algorithms/onnx/InclusiveKinematicsML.cc @@ -15,123 +15,130 @@ namespace eicrecon { - static std::string print_shape(const std::vector& v) { - std::stringstream ss(""); - for (std::size_t i = 0; i < v.size() - 1; i++) ss << v[i] << "x"; - ss << v[v.size() - 1]; - return ss.str(); - } - - template - Ort::Value vec_to_tensor(std::vector& data, const std::vector& shape) { - Ort::MemoryInfo mem_info = - Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault); - auto tensor = Ort::Value::CreateTensor(mem_info, data.data(), data.size(), shape.data(), shape.size()); - return tensor; - } - - void InclusiveKinematicsML::init() { - // onnxruntime setup - m_env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, "inclusive-kinematics-ml"); - Ort::SessionOptions session_options; - session_options.SetInterOpNumThreads(1); - session_options.SetIntraOpNumThreads(1); - try { - m_session = Ort::Session(m_env, m_cfg.modelPath.c_str(), session_options); - - // print name/shape of inputs - Ort::AllocatorWithDefaultOptions allocator; - debug("Input Node Name/Shape:"); - for (std::size_t i = 0; i < m_session.GetInputCount(); i++) { - m_input_names.emplace_back(m_session.GetInputNameAllocated(i, allocator).get()); - if (m_session.GetInputTypeInfo(i).GetONNXType() == ONNX_TYPE_TENSOR) { - m_input_shapes.emplace_back(m_session.GetInputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); - debug("\t{} : {}", m_input_names.at(i), print_shape(m_input_shapes.at(i))); - } else { - m_input_shapes.emplace_back(); - debug("\t{} : not a tensor", m_input_names.at(i)); - } +static std::string print_shape(const std::vector& v) { + std::stringstream ss(""); + for (std::size_t i = 0; i < v.size() - 1; i++) + ss << v[i] << "x"; + ss << v[v.size() - 1]; + return ss.str(); +} + +template +Ort::Value vec_to_tensor(std::vector& data, const std::vector& shape) { + Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, + OrtMemType::OrtMemTypeDefault); + auto tensor = + Ort::Value::CreateTensor(mem_info, data.data(), data.size(), shape.data(), shape.size()); + return tensor; +} + +void InclusiveKinematicsML::init() { + // onnxruntime setup + m_env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, "inclusive-kinematics-ml"); + Ort::SessionOptions session_options; + session_options.SetInterOpNumThreads(1); + session_options.SetIntraOpNumThreads(1); + try { + m_session = Ort::Session(m_env, m_cfg.modelPath.c_str(), session_options); + + // print name/shape of inputs + Ort::AllocatorWithDefaultOptions allocator; + debug("Input Node Name/Shape:"); + for (std::size_t i = 0; i < m_session.GetInputCount(); i++) { + m_input_names.emplace_back(m_session.GetInputNameAllocated(i, allocator).get()); + if (m_session.GetInputTypeInfo(i).GetONNXType() == ONNX_TYPE_TENSOR) { + m_input_shapes.emplace_back( + m_session.GetInputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); + debug("\t{} : {}", m_input_names.at(i), print_shape(m_input_shapes.at(i))); + } else { + m_input_shapes.emplace_back(); + debug("\t{} : not a tensor", m_input_names.at(i)); } + } - // print name/shape of outputs - debug("Output Node Name/Shape:"); - for (std::size_t i = 0; i < m_session.GetOutputCount(); i++) { - m_output_names.emplace_back(m_session.GetOutputNameAllocated(i, allocator).get()); - if (m_session.GetOutputTypeInfo(i).GetONNXType() == ONNX_TYPE_TENSOR) { - m_output_shapes.emplace_back(m_session.GetOutputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); - debug("\t{} : {}", m_output_names.at(i), print_shape(m_output_shapes.at(i))); - } else { - m_output_shapes.emplace_back(); - debug("\t{} : not a tensor", m_output_names.at(i)); - } + // print name/shape of outputs + debug("Output Node Name/Shape:"); + for (std::size_t i = 0; i < m_session.GetOutputCount(); i++) { + m_output_names.emplace_back(m_session.GetOutputNameAllocated(i, allocator).get()); + if (m_session.GetOutputTypeInfo(i).GetONNXType() == ONNX_TYPE_TENSOR) { + m_output_shapes.emplace_back( + m_session.GetOutputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); + debug("\t{} : {}", m_output_names.at(i), print_shape(m_output_shapes.at(i))); + } else { + m_output_shapes.emplace_back(); + debug("\t{} : not a tensor", m_output_names.at(i)); } - - // convert names to char* - m_input_names_char.resize(m_input_names.size(), nullptr); - std::transform(std::begin(m_input_names), std::end(m_input_names), std::begin(m_input_names_char), - [&](const std::string& str) { return str.c_str(); }); - m_output_names_char.resize(m_output_names.size(), nullptr); - std::transform(std::begin(m_output_names), std::end(m_output_names), std::begin(m_output_names_char), - [&](const std::string& str) { return str.c_str(); }); - - } catch(std::exception& e) { - error(e.what()); } + + // convert names to char* + m_input_names_char.resize(m_input_names.size(), nullptr); + std::transform(std::begin(m_input_names), std::end(m_input_names), + std::begin(m_input_names_char), + [&](const std::string& str) { return str.c_str(); }); + m_output_names_char.resize(m_output_names.size(), nullptr); + std::transform(std::begin(m_output_names), std::end(m_output_names), + std::begin(m_output_names_char), + [&](const std::string& str) { return str.c_str(); }); + + } catch (std::exception& e) { + error(e.what()); } +} - void InclusiveKinematicsML::process( - const InclusiveKinematicsML::Input& input, - const InclusiveKinematicsML::Output& output) const { +void InclusiveKinematicsML::process(const InclusiveKinematicsML::Input& input, + const InclusiveKinematicsML::Output& output) const { - const auto [electron, da] = input; - auto [ml] = output; + const auto [electron, da] = input; + auto [ml] = output; - // Require valid inputs - if (electron->size() == 0 || da->size() == 0) { - debug("skipping because input collections have no entries"); - return; - } + // Require valid inputs + if (electron->size() == 0 || da->size() == 0) { + debug("skipping because input collections have no entries"); + return; + } - // Assume model has 1 input nodes and 1 output node. - if (m_input_names.size() != 1 || m_output_names.size() != 1) { - debug("skipping because model has incorrect input and output size"); - return; - } + // Assume model has 1 input nodes and 1 output node. + if (m_input_names.size() != 1 || m_output_names.size() != 1) { + debug("skipping because model has incorrect input and output size"); + return; + } - // Prepare input tensor - std::vector input_tensor_values; - std::vector input_tensors; - for (std::size_t i = 0; i < electron->size(); i++) { - input_tensor_values.push_back(electron->at(i).getX()); - } - input_tensors.emplace_back(vec_to_tensor(input_tensor_values, m_input_shapes.front())); + // Prepare input tensor + std::vector input_tensor_values; + std::vector input_tensors; + for (std::size_t i = 0; i < electron->size(); i++) { + input_tensor_values.push_back(electron->at(i).getX()); + } + input_tensors.emplace_back(vec_to_tensor(input_tensor_values, m_input_shapes.front())); - // Double-check the dimensions of the input tensor - if (! input_tensors[0].IsTensor() || input_tensors[0].GetTensorTypeAndShapeInfo().GetShape() != m_input_shapes.front()) { - debug("skipping because input tensor shape incorrect"); - return; - } + // Double-check the dimensions of the input tensor + if (!input_tensors[0].IsTensor() || + input_tensors[0].GetTensorTypeAndShapeInfo().GetShape() != m_input_shapes.front()) { + debug("skipping because input tensor shape incorrect"); + return; + } - // Attempt inference - try { - auto output_tensors = m_session.Run(Ort::RunOptions{nullptr}, m_input_names_char.data(), input_tensors.data(), - m_input_names_char.size(), m_output_names_char.data(), m_output_names_char.size()); + // Attempt inference + try { + auto output_tensors = m_session.Run(Ort::RunOptions{nullptr}, m_input_names_char.data(), + input_tensors.data(), m_input_names_char.size(), + m_output_names_char.data(), m_output_names_char.size()); - // Double-check the dimensions of the output tensors - if (!output_tensors[0].IsTensor() || output_tensors.size() != m_output_names.size()) { - debug("skipping because output tensor shape incorrect"); - return; - } + // Double-check the dimensions of the output tensors + if (!output_tensors[0].IsTensor() || output_tensors.size() != m_output_names.size()) { + debug("skipping because output tensor shape incorrect"); + return; + } - // Convert output tensor - float* output_tensor_data = output_tensors[0].GetTensorMutableData(); - auto x = output_tensor_data[0]; - auto kin = ml->create(); - kin.setX(x); + // Convert output tensor + float* output_tensor_data = output_tensors[0].GetTensorMutableData(); + auto x = output_tensor_data[0]; + auto kin = ml->create(); + kin.setX(x); - } catch (const Ort::Exception& exception) { - error("error running model inference: {}", exception.what()); - } + } catch (const Ort::Exception& exception) { + error("error running model inference: {}", exception.what()); } +} } // namespace eicrecon diff --git a/src/algorithms/onnx/InclusiveKinematicsMLConfig.h b/src/algorithms/onnx/InclusiveKinematicsMLConfig.h index dd7bd37d1a..c1f2430bd5 100644 --- a/src/algorithms/onnx/InclusiveKinematicsMLConfig.h +++ b/src/algorithms/onnx/InclusiveKinematicsMLConfig.h @@ -7,10 +7,9 @@ namespace eicrecon { - struct InclusiveKinematicsMLConfig { +struct InclusiveKinematicsMLConfig { - std::string modelPath{"calibrations/onnx/identity_gemm_w1x1_b1.onnx"}; + std::string modelPath{"calibrations/onnx/identity_gemm_w1x1_b1.onnx"}; +}; - }; - -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/onnx/ONNXInference.cc b/src/algorithms/onnx/ONNXInference.cc index 00665cd852..5b23336d83 100644 --- a/src/algorithms/onnx/ONNXInference.cc +++ b/src/algorithms/onnx/ONNXInference.cc @@ -18,173 +18,179 @@ namespace eicrecon { - static std::string print_shape(const std::vector& v) { - std::stringstream ss(""); - for (std::size_t i = 0; i < v.size() - 1; i++) ss << v[i] << " x "; - ss << v[v.size() - 1]; - return ss.str(); +static std::string print_shape(const std::vector& v) { + std::stringstream ss(""); + for (std::size_t i = 0; i < v.size() - 1; i++) + ss << v[i] << " x "; + ss << v[v.size() - 1]; + return ss.str(); +} + +static bool check_shape_consistency(const std::vector& shape1, + const std::vector& shape2) { + if (shape2.size() != shape1.size()) { + return false; } - - static bool check_shape_consistency(const std::vector& shape1, const std::vector& shape2) { - if (shape2.size() != shape1.size()) { + for (size_t ix = 0; ix < shape1.size(); ix++) { + if ((shape1[ix] != -1) && (shape2[ix] != -1) && (shape1[ix] != shape2[ix])) { return false; } - for (size_t ix = 0; ix < shape1.size(); ix++) { - if ((shape1[ix] != -1) && (shape2[ix] != -1) && (shape1[ix] != shape2[ix])) { - return false; + } + return true; +} + +template +static Ort::Value iters_to_tensor(typename std::vector::const_iterator data_begin, + typename std::vector::const_iterator data_end, + std::vector::const_iterator shape_begin, + std::vector::const_iterator shape_end) { + Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, + OrtMemType::OrtMemTypeDefault); + auto tensor = + Ort::Value::CreateTensor(mem_info, const_cast(&*data_begin), data_end - data_begin, + &*shape_begin, shape_end - shape_begin); + return tensor; +} + +void ONNXInference::init() { + // onnxruntime setup + m_env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, name().data()); + Ort::SessionOptions session_options; + session_options.SetInterOpNumThreads(1); + session_options.SetIntraOpNumThreads(1); + try { + m_session = Ort::Session(m_env, m_cfg.modelPath.c_str(), session_options); + Ort::AllocatorWithDefaultOptions allocator; + + // print name/shape of inputs + debug("Input Node Name/Shape:"); + for (std::size_t i = 0; i < m_session.GetInputCount(); i++) { + m_input_names.emplace_back(m_session.GetInputNameAllocated(i, allocator).get()); + m_input_shapes.emplace_back( + m_session.GetInputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); + debug("\t{} : {}", m_input_names.at(i), print_shape(m_input_shapes.at(i))); + } + + // print name/shape of outputs + debug("Output Node Name/Shape: {}", m_session.GetOutputCount()); + for (std::size_t i = 0; i < m_session.GetOutputCount(); i++) { + m_output_names.emplace_back(m_session.GetOutputNameAllocated(i, allocator).get()); + + if (m_session.GetOutputTypeInfo(i).GetONNXType() != ONNX_TYPE_TENSOR) { + m_output_shapes.emplace_back(); + debug("\t{} : not a tensor", m_output_names.at(i)); + } else { + m_output_shapes.emplace_back( + m_session.GetOutputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); + debug("\t{} : {}", m_output_names.at(i), print_shape(m_output_shapes.at(i))); } } - return true; - } - template - static Ort::Value iters_to_tensor( - typename std::vector::const_iterator data_begin, - typename std::vector::const_iterator data_end, - std::vector::const_iterator shape_begin, - std::vector::const_iterator shape_end - ) { - Ort::MemoryInfo mem_info = - Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault); - auto tensor = Ort::Value::CreateTensor(mem_info, const_cast(&*data_begin), data_end - data_begin, &*shape_begin, shape_end - shape_begin); - return tensor; + // convert names to char* + m_input_names_char.resize(m_input_names.size(), nullptr); + std::transform(std::begin(m_input_names), std::end(m_input_names), + std::begin(m_input_names_char), + [&](const std::string& str) { return str.c_str(); }); + m_output_names_char.resize(m_output_names.size(), nullptr); + std::transform(std::begin(m_output_names), std::end(m_output_names), + std::begin(m_output_names_char), + [&](const std::string& str) { return str.c_str(); }); + + } catch (const Ort::Exception& exception) { + error("ONNX error {}", exception.what()); + throw; } +} - void ONNXInference::init() { - // onnxruntime setup - m_env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, name().data()); - Ort::SessionOptions session_options; - session_options.SetInterOpNumThreads(1); - session_options.SetIntraOpNumThreads(1); - try { - m_session = Ort::Session(m_env, m_cfg.modelPath.c_str(), session_options); - Ort::AllocatorWithDefaultOptions allocator; - - // print name/shape of inputs - debug("Input Node Name/Shape:"); - for (std::size_t i = 0; i < m_session.GetInputCount(); i++) { - m_input_names.emplace_back(m_session.GetInputNameAllocated(i, allocator).get()); - m_input_shapes.emplace_back(m_session.GetInputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); - debug("\t{} : {}", m_input_names.at(i), print_shape(m_input_shapes.at(i))); - } +void ONNXInference::process(const ONNXInference::Input& input, + const ONNXInference::Output& output) const { - // print name/shape of outputs - debug("Output Node Name/Shape: {}", m_session.GetOutputCount()); - for (std::size_t i = 0; i < m_session.GetOutputCount(); i++) { - m_output_names.emplace_back(m_session.GetOutputNameAllocated(i, allocator).get()); - - if (m_session.GetOutputTypeInfo(i).GetONNXType() != ONNX_TYPE_TENSOR) { - m_output_shapes.emplace_back(); - debug("\t{} : not a tensor", m_output_names.at(i)); - } else { - m_output_shapes.emplace_back(m_session.GetOutputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape()); - debug("\t{} : {}", m_output_names.at(i), print_shape(m_output_shapes.at(i))); - } - } + const auto [in_tensors] = input; + auto [out_tensors] = output; - // convert names to char* - m_input_names_char.resize(m_input_names.size(), nullptr); - std::transform(std::begin(m_input_names), std::end(m_input_names), std::begin(m_input_names_char), - [&](const std::string& str) { return str.c_str(); }); - m_output_names_char.resize(m_output_names.size(), nullptr); - std::transform(std::begin(m_output_names), std::end(m_output_names), std::begin(m_output_names_char), - [&](const std::string& str) { return str.c_str(); }); - - } catch(const Ort::Exception& exception) { - error("ONNX error {}", exception.what()); - throw; - } + // Require valid inputs + if (in_tensors.size() != m_input_names.size()) { + error("The ONNX model requires {} tensors, whereas {} were provided", m_input_names.size(), + in_tensors.size()); + throw std::runtime_error( + fmt::format("The ONNX model requires {} tensors, whereas {} were provided", + m_input_names.size(), in_tensors.size())); } - void ONNXInference::process( - const ONNXInference::Input& input, - const ONNXInference::Output& output) const { - - const auto [in_tensors] = input; - auto [out_tensors] = output; - - // Require valid inputs - if (in_tensors.size() != m_input_names.size()) { - error("The ONNX model requires {} tensors, whereas {} were provided", m_input_names.size(), in_tensors.size()); - throw std::runtime_error(fmt::format("The ONNX model requires {} tensors, whereas {} were provided", m_input_names.size(), in_tensors.size())); + // Prepare input tensor + std::vector input_tensor_values; + std::vector input_tensors; + + for (int ix = 0; ix < m_input_names.size(); ix++) { + edm4eic::Tensor in_tensor = in_tensors[ix]->at(0); + if (in_tensor.getElementType() == ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT) { + input_tensors.emplace_back( + iters_to_tensor(in_tensor.floatData_begin(), in_tensor.floatData_end(), + in_tensor.shape_begin(), in_tensor.shape_end())); + } else if (in_tensor.getElementType() == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64) { + input_tensors.emplace_back( + iters_to_tensor(in_tensor.int64Data_begin(), in_tensor.int64Data_end(), + in_tensor.shape_begin(), in_tensor.shape_end())); } - // Prepare input tensor - std::vector input_tensor_values; - std::vector input_tensors; - - for (int ix = 0; ix < m_input_names.size(); ix++) { - edm4eic::Tensor in_tensor = in_tensors[ix]->at(0); - if (in_tensor.getElementType() == ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT) { - input_tensors.emplace_back(iters_to_tensor( - in_tensor.floatData_begin(), - in_tensor.floatData_end(), - in_tensor.shape_begin(), - in_tensor.shape_end() - )); - } else if (in_tensor.getElementType() == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64) { - input_tensors.emplace_back(iters_to_tensor( - in_tensor.int64Data_begin(), - in_tensor.int64Data_end(), - in_tensor.shape_begin(), - in_tensor.shape_end() - )); - } - - auto input_shape = input_tensors[ix].GetTensorTypeAndShapeInfo().GetShape(); - std::vector input_expected_shape = m_input_shapes[ix]; - if (!check_shape_consistency(input_shape, input_expected_shape)) { - error("Input tensor shape incorrect {} != {}", print_shape(input_shape), print_shape(input_expected_shape)); - throw std::runtime_error(fmt::format("Input tensor shape incorrect {} != {}", print_shape(input_shape), print_shape(input_expected_shape))); - } + auto input_shape = input_tensors[ix].GetTensorTypeAndShapeInfo().GetShape(); + std::vector input_expected_shape = m_input_shapes[ix]; + if (!check_shape_consistency(input_shape, input_expected_shape)) { + error("Input tensor shape incorrect {} != {}", print_shape(input_shape), + print_shape(input_expected_shape)); + throw std::runtime_error(fmt::format("Input tensor shape incorrect {} != {}", + print_shape(input_shape), + print_shape(input_expected_shape))); } + } - // Attempt inference - std::vector onnx_values; - try { - onnx_values = m_session.Run(Ort::RunOptions{nullptr}, m_input_names_char.data(), input_tensors.data(), - m_input_names_char.size(), m_output_names_char.data(), m_output_names_char.size()); - } catch (const Ort::Exception& exception) { - error("Error running model inference: {}", exception.what()); - throw; - } + // Attempt inference + std::vector onnx_values; + try { + onnx_values = m_session.Run(Ort::RunOptions{nullptr}, m_input_names_char.data(), + input_tensors.data(), m_input_names_char.size(), + m_output_names_char.data(), m_output_names_char.size()); + } catch (const Ort::Exception& exception) { + error("Error running model inference: {}", exception.what()); + throw; + } - try { - for (size_t ix = 0; ix < onnx_values.size(); ix++) { - Ort::Value &onnx_tensor = onnx_values[ix]; - if (!onnx_tensor.IsTensor()) { - error("The output \"{}\" is not a tensor. ONNXType {} is not yet supported. Skipping...", - m_output_names_char[ix], - static_cast(onnx_tensor.GetTypeInfo().GetONNXType())); - continue; - } - auto onnx_tensor_type = onnx_tensor.GetTensorTypeAndShapeInfo(); - edm4eic::MutableTensor out_tensor = out_tensors[ix]->create(); - out_tensor.setElementType(static_cast(onnx_tensor_type.GetElementType())); - size_t num_values = 1; - for (int64_t dim_size : onnx_tensor_type.GetShape()) { - out_tensor.addToShape(dim_size); - num_values *= dim_size; + try { + for (size_t ix = 0; ix < onnx_values.size(); ix++) { + Ort::Value& onnx_tensor = onnx_values[ix]; + if (!onnx_tensor.IsTensor()) { + error("The output \"{}\" is not a tensor. ONNXType {} is not yet supported. Skipping...", + m_output_names_char[ix], static_cast(onnx_tensor.GetTypeInfo().GetONNXType())); + continue; + } + auto onnx_tensor_type = onnx_tensor.GetTensorTypeAndShapeInfo(); + edm4eic::MutableTensor out_tensor = out_tensors[ix]->create(); + out_tensor.setElementType(static_cast(onnx_tensor_type.GetElementType())); + size_t num_values = 1; + for (int64_t dim_size : onnx_tensor_type.GetShape()) { + out_tensor.addToShape(dim_size); + num_values *= dim_size; + } + if (onnx_tensor_type.GetElementType() == ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT) { + auto* data = onnx_tensor.GetTensorMutableData(); + for (size_t value_ix = 0; value_ix < num_values; value_ix++) { + out_tensor.addToFloatData(data[value_ix]); } - if (onnx_tensor_type.GetElementType() == ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT) { - auto *data = onnx_tensor.GetTensorMutableData(); - for (size_t value_ix = 0; value_ix < num_values; value_ix++) { - out_tensor.addToFloatData(data[value_ix]); - } - } else if (onnx_tensor_type.GetElementType() == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64) { - auto *data = onnx_tensor.GetTensorMutableData(); - for (size_t value_ix = 0; value_ix < num_values; value_ix++) { - out_tensor.addToInt64Data(data[value_ix]); - } - } else { - error("Unsupported ONNXTensorElementDataType {}", static_cast(onnx_tensor_type.GetElementType())); + } else if (onnx_tensor_type.GetElementType() == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64) { + auto* data = onnx_tensor.GetTensorMutableData(); + for (size_t value_ix = 0; value_ix < num_values; value_ix++) { + out_tensor.addToInt64Data(data[value_ix]); } + } else { + error("Unsupported ONNXTensorElementDataType {}", + static_cast(onnx_tensor_type.GetElementType())); } - } catch (const Ort::Exception& exception) { - error("Error running model inference: {}", exception.what()); - throw; } + } catch (const Ort::Exception& exception) { + error("Error running model inference: {}", exception.what()); + throw; } +} } // namespace eicrecon #endif diff --git a/src/algorithms/onnx/ONNXInference.h b/src/algorithms/onnx/ONNXInference.h index 8cc8e91232..8e3a78dd9a 100644 --- a/src/algorithms/onnx/ONNXInference.h +++ b/src/algorithms/onnx/ONNXInference.h @@ -20,16 +20,11 @@ using ONNXInferenceAlgorithm = algorithms::Algorithm>, algorithms::Output>>; -class ONNXInference : public ONNXInferenceAlgorithm, - public WithPodConfig { +class ONNXInference : public ONNXInferenceAlgorithm, public WithPodConfig { public: ONNXInference(std::string_view name) - : ONNXInferenceAlgorithm{name, - {"inputTensors"}, - {"outputTensors"}, - ""} { - } + : ONNXInferenceAlgorithm{name, {"inputTensors"}, {"outputTensors"}, ""} {} void init() final; void process(const Input&, const Output&) const final; diff --git a/src/algorithms/onnx/ONNXInferenceConfig.h b/src/algorithms/onnx/ONNXInferenceConfig.h index a6e98204a1..7103b1f7ba 100644 --- a/src/algorithms/onnx/ONNXInferenceConfig.h +++ b/src/algorithms/onnx/ONNXInferenceConfig.h @@ -7,10 +7,9 @@ namespace eicrecon { - struct ONNXInferenceConfig { +struct ONNXInferenceConfig { - std::string modelPath; + std::string modelPath; +}; - }; - -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/pid/ConvertParticleID.h b/src/algorithms/pid/ConvertParticleID.h index 6ee30965c6..a92fb4694e 100644 --- a/src/algorithms/pid/ConvertParticleID.h +++ b/src/algorithms/pid/ConvertParticleID.h @@ -16,69 +16,62 @@ namespace eicrecon { - class ConvertParticleID { - public: - - // index map, used for external access to the converted objects - using IndexMap = std::map; // - - // convert edm4eic::CherenkovParticleID hypotheses to list of edm4hep::ParticleID objects - // - requires input `CherenkovParticleID` object `in_pid` - // - adds output `ParticleID` objects to collection `out_pids` - // - sorted by likelihood, if `sort_by_likelihood==true` - // - returns a map of the new `out_pid` indices to new `ParticleID` IDs, so the caller can - // access the newly created `ParticleID` objects - static IndexMap ConvertToParticleIDs( - const edm4eic::CherenkovParticleID& in_pid, - edm4hep::ParticleIDCollection& out_pids, - bool sort_by_likelihood = false - ) - { - - // output vector of collection indices - IndexMap out_indices; - - // build list of (hypothesis index, hypothesis weight) - using HypIndex = std::pair; - std::vector hyp_indices; - for(std::size_t hyp_index=0; hyp_index b.second; } - ); - - // create and fill output objects - for(const auto& [hyp_index, hyp_weight] : hyp_indices) { - - // get the input hypothesis - auto in_hyp = in_pid.getHypotheses(hyp_index); - - // create output `ParticleID` object - auto out_index = out_pids.size(); - auto out_pid = out_pids.create(); - out_indices.insert({out_index, out_pid.getObjectID().index}); - - // fill scalars - out_pid.setPDG( static_cast (in_hyp.PDG) ); - out_pid.setLikelihood( static_cast (in_hyp.weight) ); - out_pid.setType( static_cast (0) ); // FIXME: not used yet - out_pid.setAlgorithmType( static_cast (0) ); // FIXME: not used yet - - // fill parameters vector - out_pid.addToParameters( static_cast (in_hyp.npe) ); // NPE for this hypothesis - - } - - return out_indices; - } - - }; // class ConvertParticleID +class ConvertParticleID { +public: + // index map, used for external access to the converted objects + using IndexMap = std::map; // + + // convert edm4eic::CherenkovParticleID hypotheses to list of edm4hep::ParticleID objects + // - requires input `CherenkovParticleID` object `in_pid` + // - adds output `ParticleID` objects to collection `out_pids` + // - sorted by likelihood, if `sort_by_likelihood==true` + // - returns a map of the new `out_pid` indices to new `ParticleID` IDs, so the caller can + // access the newly created `ParticleID` objects + static IndexMap ConvertToParticleIDs(const edm4eic::CherenkovParticleID& in_pid, + edm4hep::ParticleIDCollection& out_pids, + bool sort_by_likelihood = false) { + + // output vector of collection indices + IndexMap out_indices; + + // build list of (hypothesis index, hypothesis weight) + using HypIndex = + std::pair; + std::vector hyp_indices; + for (std::size_t hyp_index = 0; hyp_index < in_pid.hypotheses_size(); hyp_index++) + hyp_indices.push_back(HypIndex{hyp_index, in_pid.getHypotheses(hyp_index).weight}); + + // sort it by likelihood, if needed + if (sort_by_likelihood) + std::sort(hyp_indices.begin(), hyp_indices.end(), + [](HypIndex& a, HypIndex& b) { return a.second > b.second; }); + + // create and fill output objects + for (const auto& [hyp_index, hyp_weight] : hyp_indices) { + + // get the input hypothesis + auto in_hyp = in_pid.getHypotheses(hyp_index); + + // create output `ParticleID` object + auto out_index = out_pids.size(); + auto out_pid = out_pids.create(); + out_indices.insert({out_index, out_pid.getObjectID().index}); + + // fill scalars + out_pid.setPDG(static_cast(in_hyp.PDG)); + out_pid.setLikelihood( + static_cast(in_hyp.weight)); + out_pid.setType( + static_cast(0)); // FIXME: not used yet + out_pid.setAlgorithmType( + static_cast(0)); // FIXME: not used yet + + // fill parameters vector + out_pid.addToParameters(static_cast(in_hyp.npe)); // NPE for this hypothesis + } + + return out_indices; + } + +}; // class ConvertParticleID } // namespace eicrecon diff --git a/src/algorithms/pid/IrtCherenkovParticleID.cc b/src/algorithms/pid/IrtCherenkovParticleID.cc index 960a43ebea..3e2c5edbfc 100644 --- a/src/algorithms/pid/IrtCherenkovParticleID.cc +++ b/src/algorithms/pid/IrtCherenkovParticleID.cc @@ -36,11 +36,8 @@ namespace eicrecon { -void IrtCherenkovParticleID::init( - CherenkovDetectorCollection* irt_det_coll, - std::shared_ptr& logger - ) -{ +void IrtCherenkovParticleID::init(CherenkovDetectorCollection* irt_det_coll, + std::shared_ptr& logger) { // members m_irt_det_coll = irt_det_coll; m_log = logger; @@ -53,134 +50,135 @@ void IrtCherenkovParticleID::init( // extract the the relevant `CherenkovDetector`, set to `m_irt_det` auto& detectors = m_irt_det_coll->GetDetectors(); - if(detectors.size() == 0) + if (detectors.size() == 0) throw std::runtime_error("No CherenkovDetectors found in input collection `irt_det_coll`"); - if(detectors.size() > 1) - m_log->warn("IrtCherenkovParticleID currently only supports 1 CherenkovDetector at a time; taking the first"); + if (detectors.size() > 1) + m_log->warn("IrtCherenkovParticleID currently only supports 1 CherenkovDetector at a time; " + "taking the first"); auto this_detector = *detectors.begin(); m_det_name = this_detector.first; m_irt_det = this_detector.second; - m_log->debug("Initializing IrtCherenkovParticleID algorithm for CherenkovDetector '{}'", m_det_name); + m_log->debug("Initializing IrtCherenkovParticleID algorithm for CherenkovDetector '{}'", + m_det_name); // readout decoding m_cell_mask = m_irt_det->GetReadoutCellMask(); m_log->debug("readout cellMask = {:#X}", m_cell_mask); // rebin refractive index tables to have `m_cfg.numRIndexBins` bins - m_log->trace("Rebinning refractive index tables to have {} bins",m_cfg.numRIndexBins); - for(auto [rad_name,irt_rad] : m_irt_det->Radiators()) { + m_log->trace("Rebinning refractive index tables to have {} bins", m_cfg.numRIndexBins); + for (auto [rad_name, irt_rad] : m_irt_det->Radiators()) { auto ri_lookup_table_orig = irt_rad->m_ri_lookup_table; irt_rad->m_ri_lookup_table.clear(); - irt_rad->m_ri_lookup_table = Tools::ApplyFineBinning( ri_lookup_table_orig, m_cfg.numRIndexBins ); + irt_rad->m_ri_lookup_table = Tools::ApplyFineBinning(ri_lookup_table_orig, m_cfg.numRIndexBins); // m_log->trace("- {}", rad_name); // for(auto [energy,rindex] : irt_rad->m_ri_lookup_table) m_log->trace(" {:>5} eV {:<}", energy, rindex); } // build `m_pid_radiators`, the list of radiators to use for PID m_log->debug("Obtain List of Radiators:"); - for(auto [rad_name,irt_rad] : m_irt_det->Radiators()) { - if(rad_name!="Filter") { - m_pid_radiators.insert({ std::string(rad_name), irt_rad }); + for (auto [rad_name, irt_rad] : m_irt_det->Radiators()) { + if (rad_name != "Filter") { + m_pid_radiators.insert({std::string(rad_name), irt_rad}); m_log->debug("- {}", rad_name.Data()); } } // check radiators' configuration, and pass it to `m_irt_det`'s radiators - for(auto [rad_name,irt_rad] : m_pid_radiators) { + for (auto [rad_name, irt_rad] : m_pid_radiators) { // find `cfg_rad`, the associated `IrtCherenkovParticleIDConfig` radiator auto cfg_rad_it = m_cfg.radiators.find(rad_name); - if(cfg_rad_it != m_cfg.radiators.end()) { + if (cfg_rad_it != m_cfg.radiators.end()) { auto cfg_rad = cfg_rad_it->second; // pass `cfg_rad` params to `irt_rad`, the IRT radiator - irt_rad->m_ID = Tools::GetRadiatorID(std::string(rad_name)); + irt_rad->m_ID = Tools::GetRadiatorID(std::string(rad_name)); irt_rad->m_AverageRefractiveIndex = cfg_rad.referenceRIndex; irt_rad->SetReferenceRefractiveIndex(cfg_rad.referenceRIndex); - if(cfg_rad.attenuation>0) + if (cfg_rad.attenuation > 0) irt_rad->SetReferenceAttenuationLength(cfg_rad.attenuation); - if(cfg_rad.smearing>0) { - if(cfg_rad.smearingMode=="uniform") + if (cfg_rad.smearing > 0) { + if (cfg_rad.smearingMode == "uniform") irt_rad->SetUniformSmearing(cfg_rad.smearing); - else if(cfg_rad.smearingMode=="gaussian") + else if (cfg_rad.smearingMode == "gaussian") irt_rad->SetGaussianSmearing(cfg_rad.smearing); else - m_log->error("Unknown smearing mode '{}' for {} radiator", cfg_rad.smearingMode, rad_name); + m_log->error("Unknown smearing mode '{}' for {} radiator", cfg_rad.smearingMode, + rad_name); } - } - else + } else m_log->error("Cannot find radiator '{}' in IrtCherenkovParticleIDConfig instance", rad_name); } // get PDG info for the particles we want to identify in PID m_log->debug("List of particles for PID:"); - for(auto pdg : m_cfg.pdgList) { + for (auto pdg : m_cfg.pdgList) { auto mass = m_particleSvc.particle(pdg).mass; - m_pdg_mass.insert({ pdg, mass }); + m_pdg_mass.insert({pdg, mass}); m_log->debug(" {:>8} M={} GeV", pdg, mass); } - } -void IrtCherenkovParticleID::process( - const IrtCherenkovParticleID::Input& input, - const IrtCherenkovParticleID::Output& output) const -{ - const auto [in_aerogel_tracks, in_gas_tracks, in_merged_tracks, in_raw_hits, in_hit_assocs] = input; +void IrtCherenkovParticleID::process(const IrtCherenkovParticleID::Input& input, + const IrtCherenkovParticleID::Output& output) const { + const auto [in_aerogel_tracks, in_gas_tracks, in_merged_tracks, in_raw_hits, in_hit_assocs] = + input; auto [out_aerogel_particleIDs, out_gas_particleIDs] = output; // logging - m_log->trace("{:=^70}"," call IrtCherenkovParticleID::AlgorithmProcess "); + m_log->trace("{:=^70}", " call IrtCherenkovParticleID::AlgorithmProcess "); m_log->trace("number of raw sensor hits: {}", in_raw_hits->size()); m_log->trace("number of raw sensor hit with associated photons: {}", in_hit_assocs->size()); std::map in_charged_particles{ - {"Aerogel", in_aerogel_tracks}, - {"Gas", in_gas_tracks}, - {"Merged", in_merged_tracks}, + {"Aerogel", in_aerogel_tracks}, + {"Gas", in_gas_tracks}, + {"Merged", in_merged_tracks}, }; // start output collections std::map out_cherenkov_pids{ - {"Aerogel", out_aerogel_particleIDs}, - {"Gas", out_gas_particleIDs} - }; + {"Aerogel", out_aerogel_particleIDs}, {"Gas", out_gas_particleIDs}}; // check `in_charged_particles`: each radiator should have the same number of TrackSegments std::unordered_map in_charged_particle_size_distribution; - for(const auto& [rad_name, in_charged_particle] : in_charged_particles) { + for (const auto& [rad_name, in_charged_particle] : in_charged_particles) { ++in_charged_particle_size_distribution[in_charged_particle->size()]; } if (in_charged_particle_size_distribution.size() != 1) { std::vector in_charged_particle_sizes; - std::transform(in_charged_particles.begin(), in_charged_particles.end(), - std::back_inserter(in_charged_particle_sizes), - [](const auto& in_charged_particle) { return in_charged_particle.second->size(); }); - m_log->error("radiators have differing numbers of TrackSegments {}", fmt::join(in_charged_particle_sizes, ", ")); + std::transform( + in_charged_particles.begin(), in_charged_particles.end(), + std::back_inserter(in_charged_particle_sizes), + [](const auto& in_charged_particle) { return in_charged_particle.second->size(); }); + m_log->error("radiators have differing numbers of TrackSegments {}", + fmt::join(in_charged_particle_sizes, ", ")); return; } // loop over charged particles ******************************************** - m_log->trace("{:#<70}","### CHARGED PARTICLES "); + m_log->trace("{:#<70}", "### CHARGED PARTICLES "); std::size_t num_charged_particles = in_charged_particle_size_distribution.begin()->first; - for(long i_charged_particle=0; i_charged_particletrace("{:-<70}", fmt::format("--- charged particle #{} ", i_charged_particle)); // start an `irt_particle`, for `IRT` auto irt_particle = std::make_unique(); // loop over radiators - for(auto [rad_name,irt_rad] : m_pid_radiators) { + for (auto [rad_name, irt_rad] : m_pid_radiators) { // get the `charged_particle` for this radiator auto charged_particle_list_it = in_charged_particles.find(rad_name); - if(charged_particle_list_it == in_charged_particles.end()) { + if (charged_particle_list_it == in_charged_particles.end()) { m_log->error("Cannot find radiator '{}' in `in_charged_particles`", rad_name); continue; } - const auto *charged_particle_list = charged_particle_list_it->second; - auto charged_particle = charged_particle_list->at(i_charged_particle); + const auto* charged_particle_list = charged_particle_list_it->second; + auto charged_particle = charged_particle_list->at(i_charged_particle); // set number of bins for this radiator and charged particle - if(charged_particle.points_size()==0) { + if (charged_particle.points_size() == 0) { m_log->trace("No propagated track points in radiator '{}'", rad_name); continue; } @@ -189,13 +187,13 @@ void IrtCherenkovParticleID::process( // start a new IRT `RadiatorHistory` // - must be a raw pointer for `irt` compatibility // - it will be destroyed when `irt_particle` is destroyed - auto *irt_rad_history = new RadiatorHistory(); - irt_particle->StartRadiatorHistory({ irt_rad, irt_rad_history }); + auto* irt_rad_history = new RadiatorHistory(); + irt_particle->StartRadiatorHistory({irt_rad, irt_rad_history}); // loop over `TrackPoint`s of this `charged_particle`, adding each to the IRT radiator irt_rad->ResetLocations(); m_log->trace("TrackPoints in '{}' radiator:", rad_name); - for(const auto& point : charged_particle.getPoints()) { + for (const auto& point : charged_particle.getPoints()) { TVector3 position = Tools::PodioVector3_to_TVector3(point.position); TVector3 momentum = Tools::PodioVector3_to_TVector3(point.momentum); irt_rad->AddLocation(position, momentum); @@ -203,34 +201,32 @@ void IrtCherenkovParticleID::process( Tools::PrintTVector3(m_log, " p", momentum); } - // loop over raw hits *************************************************** - m_log->trace("{:#<70}","### SENSOR HITS "); - for(const auto& raw_hit : *in_raw_hits) { + m_log->trace("{:#<70}", "### SENSOR HITS "); + for (const auto& raw_hit : *in_raw_hits) { // get MC photon(s), typically only used by cheat modes or trace logging // - loop over `in_hit_assocs`, searching for the matching hit association // - will not exist for noise hits edm4hep::MCParticle mc_photon; bool mc_photon_found = false; - if(m_cfg.cheatPhotonVertex || m_cfg.cheatTrueRadiator) { - for(const auto& hit_assoc : *in_hit_assocs) { - if(hit_assoc.getRawHit().isAvailable()) { - if(hit_assoc.getRawHit().id() == raw_hit.id()) { + if (m_cfg.cheatPhotonVertex || m_cfg.cheatTrueRadiator) { + for (const auto& hit_assoc : *in_hit_assocs) { + if (hit_assoc.getRawHit().isAvailable()) { + if (hit_assoc.getRawHit().id() == raw_hit.id()) { #if EDM4EIC_VERSION_MAJOR >= 6 mc_photon = hit_assoc.getSimHit().getMCParticle(); #else // hit association found, get the MC photon and break the loop - if(hit_assoc.simHits_size() > 0) { + if (hit_assoc.simHits_size() > 0) { mc_photon = hit_assoc.getSimHits(0).getMCParticle(); #endif - mc_photon_found = true; - if(mc_photon.getPDG() != -22) - m_log->warn("non-opticalphoton hit: PDG = {}",mc_photon.getPDG()); + mc_photon_found = true; + if (mc_photon.getPDG() != -22) + m_log->warn("non-opticalphoton hit: PDG = {}", mc_photon.getPDG()); #if EDM4EIC_VERSION_MAJOR >= 6 #else - } - else if(m_cfg.CheatModeEnabled()) + } else if (m_cfg.CheatModeEnabled()) m_log->error("cheat mode enabled, but no MC photons provided"); #endif break; @@ -240,57 +236,62 @@ void IrtCherenkovParticleID::process( } // cheat mode, for testing only: use MC photon to get the actual radiator - if(m_cfg.cheatTrueRadiator && mc_photon_found) { + if (m_cfg.cheatTrueRadiator && mc_photon_found) { auto vtx = Tools::PodioVector3_to_TVector3(mc_photon.getVertex()); auto mc_rad = m_irt_det->GuessRadiator(vtx, vtx); // assume IP is at (0,0,0) - if(mc_rad != irt_rad) continue; // skip this photon, if not from radiator `irt_rad` - Tools::PrintTVector3(m_log, fmt::format("cheat: radiator '{}' determined from photon vertex", rad_name), vtx); + if (mc_rad != irt_rad) + continue; // skip this photon, if not from radiator `irt_rad` + Tools::PrintTVector3( + m_log, fmt::format("cheat: radiator '{}' determined from photon vertex", rad_name), + vtx); } // get sensor and pixel info // FIXME: signal and timing cuts (ADC, TDC, ToT, ...) - auto cell_id = raw_hit.getCellID(); + auto cell_id = raw_hit.getCellID(); uint64_t sensor_id = cell_id & m_cell_mask; TVector3 pixel_pos = m_irt_det->m_ReadoutIDToPosition(cell_id); // trace logging - if(m_log->level() <= spdlog::level::trace) { + if (m_log->level() <= spdlog::level::trace) { m_log->trace("cell_id={:#X} sensor_id={:#X}", cell_id, sensor_id); Tools::PrintTVector3(m_log, "pixel position", pixel_pos); - if(mc_photon_found) { + if (mc_photon_found) { TVector3 mc_endpoint = Tools::PodioVector3_to_TVector3(mc_photon.getEndpoint()); Tools::PrintTVector3(m_log, "photon endpoint", mc_endpoint); - m_log->trace("{:>30} = {}", "dist( pixel, photon )", (pixel_pos - mc_endpoint).Mag()); - } - else m_log->trace(" no MC photon found; probably a noise hit"); + m_log->trace("{:>30} = {}", "dist( pixel, photon )", (pixel_pos - mc_endpoint).Mag()); + } else + m_log->trace(" no MC photon found; probably a noise hit"); } // start new IRT photon - auto *irt_sensor = m_irt_det->m_PhotonDetectors[0]; // NOTE: assumes one sensor type - auto *irt_photon = new OpticalPhoton(); // new raw pointer; it will also be destroyed when `irt_particle` is destroyed + auto* irt_sensor = m_irt_det->m_PhotonDetectors[0]; // NOTE: assumes one sensor type + auto* irt_photon = + new OpticalPhoton(); // new raw pointer; it will also be destroyed when `irt_particle` is destroyed irt_photon->SetVolumeCopy(sensor_id); irt_photon->SetDetectionPosition(pixel_pos); irt_photon->SetPhotonDetector(irt_sensor); irt_photon->SetDetected(true); // cheat mode: get photon vertex info from MC truth - if((m_cfg.cheatPhotonVertex || m_cfg.cheatTrueRadiator) && mc_photon_found) { + if ((m_cfg.cheatPhotonVertex || m_cfg.cheatTrueRadiator) && mc_photon_found) { irt_photon->SetVertexPosition(Tools::PodioVector3_to_TVector3(mc_photon.getVertex())); irt_photon->SetVertexMomentum(Tools::PodioVector3_to_TVector3(mc_photon.getMomentum())); } // cheat mode: retrieve a refractive index estimate; it is not exactly the one, which // was used in GEANT, but should be very close - if(m_cfg.cheatPhotonVertex) { + if (m_cfg.cheatPhotonVertex) { double ri; auto mom = 1e9 * irt_photon->GetVertexMomentum().Mag(); auto ri_set = Tools::GetFinelyBinnedTableEntry(irt_rad->m_ri_lookup_table, mom, &ri); - if(ri_set) { + if (ri_set) { irt_photon->SetVertexRefractiveIndex(ri); m_log->trace("{:>30} = {}", "refractive index", ri); - } - else - m_log->warn("Tools::GetFinelyBinnedTableEntry failed to lookup refractive index for momentum {} eV", mom); + } else + m_log->warn("Tools::GetFinelyBinnedTableEntry failed to lookup refractive index for " + "momentum {} eV", + mom); } // add each `irt_photon` to the radiator history @@ -307,58 +308,55 @@ void IrtCherenkovParticleID::process( } // end radiator loop - - // particle identification +++++++++++++++++++++++++++++++++++++++++++++++++++++ // define a mass hypothesis for each particle we want to check - m_log->trace("{:+^70}"," PARTICLE IDENTIFICATION "); + m_log->trace("{:+^70}", " PARTICLE IDENTIFICATION "); CherenkovPID irt_pid; - std::unordered_map pdg_to_hyp; // `pdg` -> hypothesis - for(auto [pdg,mass] : m_pdg_mass) { + std::unordered_map pdg_to_hyp; // `pdg` -> hypothesis + for (auto [pdg, mass] : m_pdg_mass) { irt_pid.AddMassHypothesis(mass); - pdg_to_hyp.insert({ pdg, irt_pid.GetHypothesis(irt_pid.GetHypothesesCount()-1) }); + pdg_to_hyp.insert({pdg, irt_pid.GetHypothesis(irt_pid.GetHypothesesCount() - 1)}); } // run IRT PID irt_particle->PIDReconstruction(irt_pid); - m_log->trace("{:-^70}"," IRT RESULTS "); + m_log->trace("{:-^70}", " IRT RESULTS "); // loop over radiators - for(auto [rad_name,irt_rad] : m_pid_radiators) { + for (auto [rad_name, irt_rad] : m_pid_radiators) { m_log->trace("-> {} Radiator (ID={}):", rad_name, irt_rad->m_ID); // Cherenkov angle (theta) estimate - unsigned npe = 0; - double rindex_ave = 0.0; - double energy_ave = 0.0; - std::vector> phot_theta_phi; + unsigned npe = 0; + double rindex_ave = 0.0; + double energy_ave = 0.0; + std::vector> phot_theta_phi; // loop over this radiator's photons, and decide which to include in the theta estimate - auto *irt_rad_history = irt_particle->FindRadiatorHistory(irt_rad); - if(irt_rad_history==nullptr) { + auto* irt_rad_history = irt_particle->FindRadiatorHistory(irt_rad); + if (irt_rad_history == nullptr) { m_log->trace(" No radiator history; skip"); continue; } m_log->trace(" Photoelectrons:"); - for(auto *irt_photon : irt_rad_history->Photons()) { + for (auto* irt_photon : irt_rad_history->Photons()) { // check whether this photon was selected by at least one mass hypothesis bool photon_selected = false; - for(auto irt_photon_sel : irt_photon->_m_Selected) { - if(irt_photon_sel.second == irt_rad) { + for (auto irt_photon_sel : irt_photon->_m_Selected) { + if (irt_photon_sel.second == irt_rad) { photon_selected = true; break; } } - if(!photon_selected) continue; + if (!photon_selected) + continue; // trace logging - Tools::PrintTVector3( - m_log, - fmt::format("- sensor_id={:#X}: hit",irt_photon->GetVolumeCopy()), - irt_photon->GetDetectionPosition() - ); + Tools::PrintTVector3(m_log, + fmt::format("- sensor_id={:#X}: hit", irt_photon->GetVolumeCopy()), + irt_photon->GetDetectionPosition()); Tools::PrintTVector3(m_log, "photon vertex", irt_photon->GetVertexPosition()); // get this photon's theta and phi estimates @@ -367,8 +365,8 @@ void IrtCherenkovParticleID::process( // add to the total npe++; - phot_theta_phi.emplace_back( phot_theta, phot_phi ); - if(m_cfg.cheatPhotonVertex) { + phot_theta_phi.emplace_back(phot_theta, phot_phi); + if (m_cfg.cheatPhotonVertex) { rindex_ave += irt_photon->GetVertexRefractiveIndex(); energy_ave += irt_photon->GetVertexMomentum().Mag(); } @@ -376,7 +374,7 @@ void IrtCherenkovParticleID::process( } // end loop over this radiator's photons // compute averages - if(npe>0) { + if (npe > 0) { rindex_ave /= npe; energy_ave /= npe; } @@ -384,27 +382,30 @@ void IrtCherenkovParticleID::process( // fill photon info auto out_cherenkov_pid = out_cherenkov_pids.at(rad_name)->create(); out_cherenkov_pid.setNpe(static_cast(npe)); - out_cherenkov_pid.setRefractiveIndex(static_cast(rindex_ave)); - out_cherenkov_pid.setPhotonEnergy(static_cast(energy_ave)); - for(auto [phot_theta,phot_phi] : phot_theta_phi) - out_cherenkov_pid.addToThetaPhiPhotons(edm4hep::Vector2f{ - static_cast(phot_theta), - static_cast(phot_phi) - }); + out_cherenkov_pid.setRefractiveIndex( + static_cast(rindex_ave)); + out_cherenkov_pid.setPhotonEnergy( + static_cast(energy_ave)); + for (auto [phot_theta, phot_phi] : phot_theta_phi) + out_cherenkov_pid.addToThetaPhiPhotons( + edm4hep::Vector2f{static_cast(phot_theta), static_cast(phot_phi)}); // relate mass hypotheses - for(auto [pdg,mass] : m_pdg_mass) { + for (auto [pdg, mass] : m_pdg_mass) { // get hypothesis results - auto *irt_hypothesis = pdg_to_hyp.at(pdg); - auto hyp_weight = irt_hypothesis->GetWeight(irt_rad); - auto hyp_npe = irt_hypothesis->GetNpe(irt_rad); + auto* irt_hypothesis = pdg_to_hyp.at(pdg); + auto hyp_weight = irt_hypothesis->GetWeight(irt_rad); + auto hyp_npe = irt_hypothesis->GetNpe(irt_rad); // fill `ParticleID` output collection edm4eic::CherenkovParticleIDHypothesis out_hypothesis; - out_hypothesis.PDG = static_cast(pdg); - out_hypothesis.weight = static_cast(hyp_weight); - out_hypothesis.npe = static_cast(hyp_npe); + out_hypothesis.PDG = + static_cast(pdg); + out_hypothesis.weight = + static_cast(hyp_weight); + out_hypothesis.npe = + static_cast(hyp_npe); // relate out_cherenkov_pid.addToHypotheses(out_hypothesis); @@ -416,16 +417,15 @@ void IrtCherenkovParticleID::process( // relate charged particle projection auto charged_particle_list_it = in_charged_particles.find("Merged"); - if(charged_particle_list_it != in_charged_particles.end()) { - const auto *charged_particle_list = charged_particle_list_it->second; - auto charged_particle = charged_particle_list->at(i_charged_particle); + if (charged_particle_list_it != in_charged_particles.end()) { + const auto* charged_particle_list = charged_particle_list_it->second; + auto charged_particle = charged_particle_list->at(i_charged_particle); out_cherenkov_pid.setChargedParticle(charged_particle); - } - else + } else m_log->error("Cannot find radiator 'Merged' in `in_charged_particles`"); // relate hit associations - for(const auto& hit_assoc : *in_hit_assocs) + for (const auto& hit_assoc : *in_hit_assocs) out_cherenkov_pid.addToRawHitAssociations(hit_assoc); } // end radiator loop diff --git a/src/algorithms/pid/IrtCherenkovParticleID.h b/src/algorithms/pid/IrtCherenkovParticleID.h index 0ddc648a9f..2a7ee2d5e9 100644 --- a/src/algorithms/pid/IrtCherenkovParticleID.h +++ b/src/algorithms/pid/IrtCherenkovParticleID.h @@ -26,56 +26,45 @@ namespace eicrecon { - // - `in_raw_hits` is a collection of digitized (raw) sensor hits, possibly including noise hits - // - `in_hit_assocs` is a collection of digitized (raw) sensor hits, associated with MC (simulated) hits; - // noise hits are not included since there is no associated simulated photon - // - `in_charged_particles` is a map of a radiator name to a collection of TrackSegments - // - each TrackSegment has a list of TrackPoints: the propagation of reconstructed track (trajectory) points - // - the output is a map: radiator name -> collection of particle ID objects - using IrtCherenkovParticleIDAlgorithm = algorithms::Algorithm< - algorithms::Input< - const edm4eic::TrackSegmentCollection, - const edm4eic::TrackSegmentCollection, - const edm4eic::TrackSegmentCollection, - const edm4eic::RawTrackerHitCollection, - const edm4eic::MCRecoTrackerHitAssociationCollection - >, - algorithms::Output< - edm4eic::CherenkovParticleIDCollection, - edm4eic::CherenkovParticleIDCollection - > - >; +// - `in_raw_hits` is a collection of digitized (raw) sensor hits, possibly including noise hits +// - `in_hit_assocs` is a collection of digitized (raw) sensor hits, associated with MC (simulated) hits; +// noise hits are not included since there is no associated simulated photon +// - `in_charged_particles` is a map of a radiator name to a collection of TrackSegments +// - each TrackSegment has a list of TrackPoints: the propagation of reconstructed track (trajectory) points +// - the output is a map: radiator name -> collection of particle ID objects +using IrtCherenkovParticleIDAlgorithm = algorithms::Algorithm< + algorithms::Input, + algorithms::Output>; - class IrtCherenkovParticleID - : public IrtCherenkovParticleIDAlgorithm, - public WithPodConfig { +class IrtCherenkovParticleID : public IrtCherenkovParticleIDAlgorithm, + public WithPodConfig { - public: - IrtCherenkovParticleID(std::string_view name) +public: + IrtCherenkovParticleID(std::string_view name) : IrtCherenkovParticleIDAlgorithm{name, - { - "inputAerogelTrackSegments", "inputGasTrackSegments", "inputMergedTrackSegments", - "inputRawHits", "inputRawHitAssociations" - }, - {"outputAerogelParticleIDs", "outputGasParticleIDs"}, - "Effectively 'zip' the input particle IDs"} {} + {"inputAerogelTrackSegments", "inputGasTrackSegments", + "inputMergedTrackSegments", "inputRawHits", + "inputRawHitAssociations"}, + {"outputAerogelParticleIDs", "outputGasParticleIDs"}, + "Effectively 'zip' the input particle IDs"} {} - void init(CherenkovDetectorCollection* irt_det_coll, std::shared_ptr& logger); + void init(CherenkovDetectorCollection* irt_det_coll, std::shared_ptr& logger); - void process(const Input&, const Output&) const; + void process(const Input&, const Output&) const; - private: +private: + std::shared_ptr m_log; + CherenkovDetectorCollection* m_irt_det_coll; + CherenkovDetector* m_irt_det; - std::shared_ptr m_log; - CherenkovDetectorCollection* m_irt_det_coll; - CherenkovDetector* m_irt_det; + const algorithms::ParticleSvc& m_particleSvc = algorithms::ParticleSvc::instance(); - const algorithms::ParticleSvc& m_particleSvc = algorithms::ParticleSvc::instance(); - - uint64_t m_cell_mask; - std::string m_det_name; - std::unordered_map m_pdg_mass; - std::map m_pid_radiators; - - }; -} + uint64_t m_cell_mask; + std::string m_det_name; + std::unordered_map m_pdg_mass; + std::map m_pid_radiators; +}; +} // namespace eicrecon diff --git a/src/algorithms/pid/IrtCherenkovParticleIDConfig.h b/src/algorithms/pid/IrtCherenkovParticleIDConfig.h index a015ec5ebf..0584d61fcd 100644 --- a/src/algorithms/pid/IrtCherenkovParticleIDConfig.h +++ b/src/algorithms/pid/IrtCherenkovParticleIDConfig.h @@ -8,87 +8,80 @@ namespace eicrecon { - // radiator config parameters - struct RadiatorConfig { - double referenceRIndex; // reference radiator refractive index - double attenuation; // reference radiator attenuation length [mm]; set to 0 to disable - std::string smearingMode; // smearing type: "gaussian", "uniform" - double smearing; // smearing amount [radians] - }; +// radiator config parameters +struct RadiatorConfig { + double referenceRIndex; // reference radiator refractive index + double attenuation; // reference radiator attenuation length [mm]; set to 0 to disable + std::string smearingMode; // smearing type: "gaussian", "uniform" + double smearing; // smearing amount [radians] +}; - // IRT algorithm config - class IrtCherenkovParticleIDConfig { - public: +// IRT algorithm config +class IrtCherenkovParticleIDConfig { +public: + ///////////////////////////////////////////////////// + // CONFIGURATION PARAMETERS + // NOTE: some defaults are hard-coded here; override externally - ///////////////////////////////////////////////////// - // CONFIGURATION PARAMETERS - // NOTE: some defaults are hard-coded here; override externally + unsigned numRIndexBins = 100; // number of bins to interpolate the refractive index vs. energy - unsigned numRIndexBins = 100; // number of bins to interpolate the refractive index vs. energy - - /* radiator-specific settings; handled by `RadiatorConfig` struct (see above) + /* radiator-specific settings; handled by `RadiatorConfig` struct (see above) * example: radiators.insert({ "Aerogel", RadiatorConfig{ ... }}); * radiators.insert({ "Gas", RadiatorConfig{ ... }}); */ - std::map radiators; + std::map radiators; - /* list of PDG codes to identify with this PID algorithm + /* list of PDG codes to identify with this PID algorithm * example: std::vector pdgList = { 11, 211, 321, 2212 }; */ - std::vector pdgList; + std::vector pdgList; - /* cheat modes: useful for test purposes, or idealizing; the real PID should run with all + /* cheat modes: useful for test purposes, or idealizing; the real PID should run with all * cheat modes off */ - bool cheatPhotonVertex = false; // if true, use MC photon vertex, wavelength, and refractive index - bool cheatTrueRadiator = false; // if true, use MC truth to obtain true radiator, for each hit - - // - ///////////////////////////////////////////////////// + bool cheatPhotonVertex = false; // if true, use MC photon vertex, wavelength, and refractive index + bool cheatTrueRadiator = false; // if true, use MC truth to obtain true radiator, for each hit - // print warnings about cheat modes - void PrintCheats( - std::shared_ptr m_log, - spdlog::level::level_enum lvl=spdlog::level::debug, - bool printAll=false - ) - { - auto print_param = [&m_log, &lvl, &printAll] (auto name, bool val, auto desc) { - if(printAll) m_log->log(lvl, " {:>20} = {:<}", name, val); - else if(val) m_log->warn("CHEAT MODE '{}' ENABLED: {}", name, desc); - }; - print_param("cheatPhotonVertex", cheatPhotonVertex, "use MC photon vertex, wavelength, refractive index"); - print_param("cheatTrueRadiator", cheatTrueRadiator, "use MC truth to obtain true radiator"); - } + // + ///////////////////////////////////////////////////// - // boolean: true if any cheat mode is enabled - bool CheatModeEnabled() const { - return cheatPhotonVertex || cheatTrueRadiator; - } + // print warnings about cheat modes + void PrintCheats(std::shared_ptr m_log, + spdlog::level::level_enum lvl = spdlog::level::debug, bool printAll = false) { + auto print_param = [&m_log, &lvl, &printAll](auto name, bool val, auto desc) { + if (printAll) + m_log->log(lvl, " {:>20} = {:<}", name, val); + else if (val) + m_log->warn("CHEAT MODE '{}' ENABLED: {}", name, desc); + }; + print_param("cheatPhotonVertex", cheatPhotonVertex, + "use MC photon vertex, wavelength, refractive index"); + print_param("cheatTrueRadiator", cheatTrueRadiator, "use MC truth to obtain true radiator"); + } - // print all parameters - void Print( - std::shared_ptr m_log, - spdlog::level::level_enum lvl=spdlog::level::debug - ) - { - m_log->log(lvl, "{:=^60}"," IrtCherenkovParticleIDConfig Settings "); - auto print_param = [&m_log, &lvl] (auto name, auto val) { - m_log->log(lvl, " {:>20} = {:<}", name, val); - }; - print_param("numRIndexBins",numRIndexBins); - PrintCheats(m_log, lvl, true); - m_log->log(lvl, "pdgList:"); - for(const auto& pdg : pdgList) m_log->log(lvl, " {}", pdg); - for(const auto& [name,rad] : radiators) { - m_log->log(lvl, "{:-<60}", fmt::format("--- {} config ",name)); - print_param("smearingMode", rad.smearingMode); - print_param("smearing", rad.smearing); - print_param("referenceRIndex", rad.referenceRIndex); - print_param("attenuation", rad.attenuation); - } - m_log->log(lvl, "{:=^60}",""); - } + // boolean: true if any cheat mode is enabled + bool CheatModeEnabled() const { return cheatPhotonVertex || cheatTrueRadiator; } - }; -} + // print all parameters + void Print(std::shared_ptr m_log, + spdlog::level::level_enum lvl = spdlog::level::debug) { + m_log->log(lvl, "{:=^60}", " IrtCherenkovParticleIDConfig Settings "); + auto print_param = [&m_log, &lvl](auto name, auto val) { + m_log->log(lvl, " {:>20} = {:<}", name, val); + }; + print_param("numRIndexBins", numRIndexBins); + PrintCheats(m_log, lvl, true); + m_log->log(lvl, "pdgList:"); + for (const auto& pdg : pdgList) + m_log->log(lvl, " {}", pdg); + for (const auto& [name, rad] : radiators) { + m_log->log(lvl, "{:-<60}", fmt::format("--- {} config ", name)); + print_param("smearingMode", rad.smearingMode); + print_param("smearing", rad.smearing); + print_param("referenceRIndex", rad.referenceRIndex); + print_param("attenuation", rad.attenuation); + } + m_log->log(lvl, "{:=^60}", ""); + } +}; +} // namespace eicrecon diff --git a/src/algorithms/pid/MatchToRICHPID.cc b/src/algorithms/pid/MatchToRICHPID.cc index 2aebd96ec3..397a8efa7e 100644 --- a/src/algorithms/pid/MatchToRICHPID.cc +++ b/src/algorithms/pid/MatchToRICHPID.cc @@ -20,167 +20,145 @@ #include "algorithms/pid/ConvertParticleID.h" #include "algorithms/pid/MatchToRICHPIDConfig.h" +namespace eicrecon { +void MatchToRICHPID::init() {} -namespace eicrecon { +void MatchToRICHPID::process(const MatchToRICHPID::Input& input, + const MatchToRICHPID::Output& output) const { + const auto [parts_in, assocs_in, drich_cherenkov_pid] = input; + auto [parts_out, assocs_out, pids] = output; + + for (auto part_in : *parts_in) { + auto part_out = part_in.clone(); + + // link Cherenkov PID objects + auto success = linkCherenkovPID(part_out, *drich_cherenkov_pid, *pids); + if (success) + trace("Previous PDG vs. CherenkovPID PDG: {:>10} vs. {:<10}", part_in.getPDG(), + part_out.getParticleIDUsed().isAvailable() ? part_out.getParticleIDUsed().getPDG() : 0); - void MatchToRICHPID::init() {} - - void MatchToRICHPID::process( - const MatchToRICHPID::Input& input, const MatchToRICHPID::Output& output - ) const { - const auto [parts_in, assocs_in, drich_cherenkov_pid] = input; - auto [parts_out, assocs_out, pids] = output; - - for (auto part_in : *parts_in) { - auto part_out = part_in.clone(); - - // link Cherenkov PID objects - auto success = linkCherenkovPID(part_out, *drich_cherenkov_pid, *pids); - if (success) - trace("Previous PDG vs. CherenkovPID PDG: {:>10} vs. {:<10}", - part_in.getPDG(), - part_out.getParticleIDUsed().isAvailable() ? part_out.getParticleIDUsed().getPDG() : 0 - ); - - for (auto assoc_in : *assocs_in) { - if (assoc_in.getRec() == part_in) { - auto assoc_out = assoc_in.clone(); - assoc_out.setRec(part_out); - assocs_out->push_back(assoc_out); - } - } - - parts_out->push_back(part_out); - } + for (auto assoc_in : *assocs_in) { + if (assoc_in.getRec() == part_in) { + auto assoc_out = assoc_in.clone(); + assoc_out.setRec(part_out); + assocs_out->push_back(assoc_out); + } } + parts_out->push_back(part_out); + } +} - /* link PID objects to input particle +/* link PID objects to input particle * - finds `CherenkovParticleID` object in `in_pids` associated to particle `in_part` * by proximity matching to the associated track * - converts this `CherenkovParticleID` object's PID hypotheses to `ParticleID` objects, * relates them to `in_part`, and adds them to the collection `out_pids` for persistency * - returns `true` iff PID objects were found and linked */ - bool MatchToRICHPID::linkCherenkovPID( - edm4eic::MutableReconstructedParticle& in_part, - const edm4eic::CherenkovParticleIDCollection& in_pids, - edm4hep::ParticleIDCollection& out_pids - ) const - { - - // skip this particle, if neutral - if (std::abs(in_part.getCharge()) < 0.001) - return false; - - // structure to store list of candidate matches - struct ProxMatch { - double match_dist; - std::size_t pid_idx; - }; - std::vector prox_match_list; - - // get input reconstructed particle momentum angles - auto in_part_p = in_part.getMomentum(); - auto in_part_eta = edm4hep::utils::eta(in_part_p); - auto in_part_phi = edm4hep::utils::angleAzimuthal(in_part_p); - trace("Input particle: (eta,phi) = ( {:>5.4}, {:>5.4} deg )", - in_part_eta, - in_part_phi * 180.0 / M_PI - ); - - // loop over input CherenkovParticleID objects - for (std::size_t in_pid_idx = 0; in_pid_idx < in_pids.size(); in_pid_idx++) { - auto in_pid = in_pids.at(in_pid_idx); - - // get charged particle track associated to this CherenkovParticleID object - auto in_track = in_pid.getChargedParticle(); - if (!in_track.isAvailable()) { - error("found CherenkovParticleID object with no chargedParticle"); - return false; - } - if (in_track.points_size() == 0) { - error("found chargedParticle for CherenkovParticleID, but it has no TrackPoints"); - return false; - } - - // get averge momentum direction of the track's TrackPoints - decltype(edm4eic::TrackPoint::momentum) in_track_p{0.0, 0.0, 0.0}; - for (const auto& in_track_point : in_track.getPoints()) - in_track_p = in_track_p + ( in_track_point.momentum / in_track.points_size() ); - auto in_track_eta = edm4hep::utils::eta(in_track_p); - auto in_track_phi = edm4hep::utils::angleAzimuthal(in_track_p); - - // calculate dist(eta,phi) - auto match_dist = std::hypot( - in_part_eta - in_track_eta, - in_part_phi - in_track_phi - ); - - // check if the match is close enough: within user-specified tolerances - auto match_is_close = - std::abs(in_part_eta - in_track_eta) < m_cfg.etaTolerance && - std::abs(in_part_phi - in_track_phi) < m_cfg.phiTolerance; - if (match_is_close) - prox_match_list.push_back(ProxMatch{match_dist, in_pid_idx}); - - // logging - trace(" - (eta,phi) = ( {:>5.4}, {:>5.4} deg ), match_dist = {:<5.4}{}", - in_track_eta, - in_track_phi * 180.0 / M_PI, - match_dist, - match_is_close ? " => CLOSE!" : "" - ); - - } // end loop over input CherenkovParticleID objects - - // check if at least one match was found - if (prox_match_list.size() == 0) { - trace(" => no matching CherenkovParticleID found for this particle"); - return false; - } - - // choose the closest matching CherenkovParticleID object corresponding to this input reconstructed particle - auto closest_prox_match = *std::min_element( - prox_match_list.begin(), - prox_match_list.end(), - [] (ProxMatch a, ProxMatch b) { return a.match_dist < b.match_dist; } - ); - auto in_pid_matched = in_pids.at(closest_prox_match.pid_idx); - trace(" => best match: match_dist = {:<5.4} at idx = {}", - closest_prox_match.match_dist, - closest_prox_match.pid_idx - ); - - // convert `CherenkovParticleID` object's hypotheses => set of `ParticleID` objects - auto out_pid_index_map = ConvertParticleID::ConvertToParticleIDs(in_pid_matched, out_pids, true); - if (out_pid_index_map.size() == 0) { - error("found CherenkovParticleID object with no hypotheses"); - return false; - } - - // relate matched ParticleID objects to output particle - for (const auto& [out_pids_index, out_pids_id] : out_pid_index_map) { - const auto& out_pid = out_pids->at(out_pids_index); - if (out_pid.getObjectID().index != out_pids_id) { // sanity check - error("indexing error in `edm4eic::ParticleID` collection"); - return false; - } - in_part.addToParticleIDs(out_pid); - } - in_part.setParticleIDUsed(in_part.getParticleIDs().at(0)); // highest likelihood is the first - in_part.setGoodnessOfPID(1); // FIXME: not used yet, aside from 0=noPID vs 1=hasPID - - // trace logging - trace(" {:.^50}"," PID results "); - trace(" Hypotheses (sorted):"); - for (auto hyp : in_part.getParticleIDs()) { - float npe = hyp.parameters_size() > 0 ? hyp.getParameters(0) : -1; // assume NPE is the first parameter - trace("{:{}}{:>6} {:>10.8} {:>10.8}", "", 8, hyp.getPDG(), hyp.getLikelihood(), npe); - } - trace(" {:'^50}",""); - - return true; +bool MatchToRICHPID::linkCherenkovPID(edm4eic::MutableReconstructedParticle& in_part, + const edm4eic::CherenkovParticleIDCollection& in_pids, + edm4hep::ParticleIDCollection& out_pids) const { + + // skip this particle, if neutral + if (std::abs(in_part.getCharge()) < 0.001) + return false; + + // structure to store list of candidate matches + struct ProxMatch { + double match_dist; + std::size_t pid_idx; + }; + std::vector prox_match_list; + + // get input reconstructed particle momentum angles + auto in_part_p = in_part.getMomentum(); + auto in_part_eta = edm4hep::utils::eta(in_part_p); + auto in_part_phi = edm4hep::utils::angleAzimuthal(in_part_p); + trace("Input particle: (eta,phi) = ( {:>5.4}, {:>5.4} deg )", in_part_eta, + in_part_phi * 180.0 / M_PI); + + // loop over input CherenkovParticleID objects + for (std::size_t in_pid_idx = 0; in_pid_idx < in_pids.size(); in_pid_idx++) { + auto in_pid = in_pids.at(in_pid_idx); + + // get charged particle track associated to this CherenkovParticleID object + auto in_track = in_pid.getChargedParticle(); + if (!in_track.isAvailable()) { + error("found CherenkovParticleID object with no chargedParticle"); + return false; + } + if (in_track.points_size() == 0) { + error("found chargedParticle for CherenkovParticleID, but it has no TrackPoints"); + return false; + } + + // get averge momentum direction of the track's TrackPoints + decltype(edm4eic::TrackPoint::momentum) in_track_p{0.0, 0.0, 0.0}; + for (const auto& in_track_point : in_track.getPoints()) + in_track_p = in_track_p + (in_track_point.momentum / in_track.points_size()); + auto in_track_eta = edm4hep::utils::eta(in_track_p); + auto in_track_phi = edm4hep::utils::angleAzimuthal(in_track_p); + + // calculate dist(eta,phi) + auto match_dist = std::hypot(in_part_eta - in_track_eta, in_part_phi - in_track_phi); + + // check if the match is close enough: within user-specified tolerances + auto match_is_close = std::abs(in_part_eta - in_track_eta) < m_cfg.etaTolerance && + std::abs(in_part_phi - in_track_phi) < m_cfg.phiTolerance; + if (match_is_close) + prox_match_list.push_back(ProxMatch{match_dist, in_pid_idx}); + + // logging + trace(" - (eta,phi) = ( {:>5.4}, {:>5.4} deg ), match_dist = {:<5.4}{}", in_track_eta, + in_track_phi * 180.0 / M_PI, match_dist, match_is_close ? " => CLOSE!" : ""); + + } // end loop over input CherenkovParticleID objects + + // check if at least one match was found + if (prox_match_list.size() == 0) { + trace(" => no matching CherenkovParticleID found for this particle"); + return false; + } + + // choose the closest matching CherenkovParticleID object corresponding to this input reconstructed particle + auto closest_prox_match = + *std::min_element(prox_match_list.begin(), prox_match_list.end(), + [](ProxMatch a, ProxMatch b) { return a.match_dist < b.match_dist; }); + auto in_pid_matched = in_pids.at(closest_prox_match.pid_idx); + trace(" => best match: match_dist = {:<5.4} at idx = {}", closest_prox_match.match_dist, + closest_prox_match.pid_idx); + + // convert `CherenkovParticleID` object's hypotheses => set of `ParticleID` objects + auto out_pid_index_map = ConvertParticleID::ConvertToParticleIDs(in_pid_matched, out_pids, true); + if (out_pid_index_map.size() == 0) { + error("found CherenkovParticleID object with no hypotheses"); + return false; + } + + // relate matched ParticleID objects to output particle + for (const auto& [out_pids_index, out_pids_id] : out_pid_index_map) { + const auto& out_pid = out_pids->at(out_pids_index); + if (out_pid.getObjectID().index != out_pids_id) { // sanity check + error("indexing error in `edm4eic::ParticleID` collection"); + return false; } + in_part.addToParticleIDs(out_pid); + } + in_part.setParticleIDUsed(in_part.getParticleIDs().at(0)); // highest likelihood is the first + in_part.setGoodnessOfPID(1); // FIXME: not used yet, aside from 0=noPID vs 1=hasPID + + // trace logging + trace(" {:.^50}", " PID results "); + trace(" Hypotheses (sorted):"); + for (auto hyp : in_part.getParticleIDs()) { + float npe = + hyp.parameters_size() > 0 ? hyp.getParameters(0) : -1; // assume NPE is the first parameter + trace("{:{}}{:>6} {:>10.8} {:>10.8}", "", 8, hyp.getPDG(), hyp.getLikelihood(), npe); + } + trace(" {:'^50}", ""); + + return true; } +} // namespace eicrecon diff --git a/src/algorithms/pid/MatchToRICHPID.h b/src/algorithms/pid/MatchToRICHPID.h index b767993a52..42c8d94113 100644 --- a/src/algorithms/pid/MatchToRICHPID.h +++ b/src/algorithms/pid/MatchToRICHPID.h @@ -1,7 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2022, 2023, Sylvester Joosten, Wouter Deconinck, Dmitry Romanov, Christopher Dilks - #pragma once #include @@ -15,30 +14,33 @@ #include "MatchToRICHPIDConfig.h" #include "algorithms/interfaces/WithPodConfig.h" - namespace eicrecon { using MatchToRICHPIDAlgorithm = - algorithms::Algorithm< - algorithms::Input, - algorithms::Output - >; + algorithms::Algorithm, + algorithms::Output>; class MatchToRICHPID : public MatchToRICHPIDAlgorithm, public WithPodConfig { public: + MatchToRICHPID(std::string_view name) + : MatchToRICHPIDAlgorithm{ + name, + {"inputReconstructedParticlesCollection", "inputAssociationsCollection", + "inputCherenkovParticleIDCollection"}, + {"outputReconstructedParticlesCollection", "outputAssociationsCollection"}, + "Matches tracks to Cherenkov PIDs"} {}; - MatchToRICHPID(std::string_view name) : MatchToRICHPIDAlgorithm{name, {"inputReconstructedParticlesCollection", "inputAssociationsCollection", "inputCherenkovParticleIDCollection"}, {"outputReconstructedParticlesCollection", "outputAssociationsCollection"}, "Matches tracks to Cherenkov PIDs"} {}; - - void init() final; - void process(const Input&, const Output&) const final; + void init() final; + void process(const Input&, const Output&) const final; private: - - bool linkCherenkovPID( - edm4eic::MutableReconstructedParticle& in_part, - const edm4eic::CherenkovParticleIDCollection& in_pids, - edm4hep::ParticleIDCollection& out_pids - ) const; + bool linkCherenkovPID(edm4eic::MutableReconstructedParticle& in_part, + const edm4eic::CherenkovParticleIDCollection& in_pids, + edm4hep::ParticleIDCollection& out_pids) const; }; -} +} // namespace eicrecon diff --git a/src/algorithms/pid/MatchToRICHPIDConfig.h b/src/algorithms/pid/MatchToRICHPIDConfig.h index e043c674e9..44588c3500 100644 --- a/src/algorithms/pid/MatchToRICHPIDConfig.h +++ b/src/algorithms/pid/MatchToRICHPIDConfig.h @@ -10,4 +10,4 @@ struct MatchToRICHPIDConfig { double phiTolerance{0.1}; }; -} +} // namespace eicrecon diff --git a/src/algorithms/pid/MergeParticleID.cc b/src/algorithms/pid/MergeParticleID.cc index 645edc85d8..b920377a90 100644 --- a/src/algorithms/pid/MergeParticleID.cc +++ b/src/algorithms/pid/MergeParticleID.cc @@ -20,18 +20,16 @@ namespace eicrecon { -void MergeParticleID::init(std::shared_ptr& logger) -{ +void MergeParticleID::init(std::shared_ptr& logger) { m_log = logger; m_cfg.Print(m_log, spdlog::level::debug); } -void MergeParticleID::process( - const MergeParticleID::Input& input, - const MergeParticleID::Output& output) const { +void MergeParticleID::process(const MergeParticleID::Input& input, + const MergeParticleID::Output& output) const { const auto [in_pid_collections_list] = input; - auto [out_pids] = output; + auto [out_pids] = output; /* match input `CherenkovParticleIDCollection` elements from each list of * collections in `in_pid_collections_list` @@ -66,20 +64,21 @@ void MergeParticleID::process( // fill `particle_pids` // ------------------------------------------------------------------------------- - std::unordered_map< decltype(podio::ObjectID::index), std::vector> > particle_pids; - m_log->trace("{:-<70}","Build `particle_pids` indexing data structure "); + std::unordered_map>> + particle_pids; + m_log->trace("{:-<70}", "Build `particle_pids` indexing data structure "); // loop over list of PID collections - for(size_t idx_coll = 0; idx_coll < in_pid_collections_list.size(); idx_coll++) { + for (size_t idx_coll = 0; idx_coll < in_pid_collections_list.size(); idx_coll++) { const auto& in_pid_collection = in_pid_collections_list.at(idx_coll); m_log->trace("idx_col={}", idx_coll); // loop over this PID collection - for(size_t idx_pid = 0; idx_pid < in_pid_collection->size(); idx_pid++) { + for (size_t idx_pid = 0; idx_pid < in_pid_collection->size(); idx_pid++) { // make the index pair - const auto& in_pid = in_pid_collection->at(idx_pid); + const auto& in_pid = in_pid_collection->at(idx_pid); auto& charged_particle_track_segment = in_pid.getChargedParticle(); - if(!charged_particle_track_segment.isAvailable()) { + if (!charged_particle_track_segment.isAvailable()) { m_log->error("PID object found with no charged particle"); continue; } @@ -89,7 +88,7 @@ void MergeParticleID::process( // insert in `particle_pids` auto it = particle_pids.find(id_particle); - if(it == particle_pids.end()) + if (it == particle_pids.end()) particle_pids.insert({id_particle, {idx_paired}}); else it->second.push_back(idx_paired); @@ -97,22 +96,21 @@ void MergeParticleID::process( } // trace logging - if(m_log->level() <= spdlog::level::trace) { - m_log->trace("{:-<70}","Resulting `particle_pids` "); - for(auto& [id_particle, idx_paired_list] : particle_pids) { + if (m_log->level() <= spdlog::level::trace) { + m_log->trace("{:-<70}", "Resulting `particle_pids` "); + for (auto& [id_particle, idx_paired_list] : particle_pids) { m_log->trace("id_particle={}", id_particle); - for(auto& [idx_coll, idx_pid] : idx_paired_list) + for (auto& [idx_coll, idx_pid] : idx_paired_list) m_log->trace(" (idx_coll, idx_pid) = ({}, {})", idx_coll, idx_pid); } } // -------------------------------------------------------------------------------- - // loop over charged particles, combine weights from the associated `CherenkovParticleID` objects // and create a merged output `CherenkovParticleID` object - m_log->trace("{:-<70}","Begin Merging PID Objects "); - for(auto& [id_particle, idx_paired_list] : particle_pids) { + m_log->trace("{:-<70}", "Begin Merging PID Objects "); + for (auto& [id_particle, idx_paired_list] : particle_pids) { // trace logging m_log->trace("Charged Particle:"); @@ -120,59 +118,62 @@ void MergeParticleID::process( m_log->trace(" PID Hypotheses:"); // create mutable output `CherenkovParticleID` object `out_pid` - auto out_pid = out_pids->create(); - decltype(edm4eic::CherenkovParticleIDData::npe) out_npe = 0.0; + auto out_pid = out_pids->create(); + decltype(edm4eic::CherenkovParticleIDData::npe) out_npe = 0.0; decltype(edm4eic::CherenkovParticleIDData::refractiveIndex) out_refractiveIndex = 0.0; - decltype(edm4eic::CherenkovParticleIDData::photonEnergy) out_photonEnergy = 0.0; + decltype(edm4eic::CherenkovParticleIDData::photonEnergy) out_photonEnergy = 0.0; // define `pdg_2_out_hyp`: map of PDG => merged output hypothesis - std::unordered_map< decltype(edm4eic::CherenkovParticleIDHypothesis::PDG), edm4eic::CherenkovParticleIDHypothesis > pdg_2_out_hyp; + std::unordered_map + pdg_2_out_hyp; // merge each input `CherenkovParticleID` objects associated with this charged particle - for(auto& [idx_coll, idx_pid] : idx_paired_list) { + for (auto& [idx_coll, idx_pid] : idx_paired_list) { const auto& in_pid = in_pid_collections_list.at(idx_coll)->at(idx_pid); // logging - m_log->trace(" Hypotheses for PID result (idx_coll, idx_pid) = ({}, {}):", idx_coll, idx_pid); - Tools::PrintHypothesisTableHead(m_log,6); + m_log->trace(" Hypotheses for PID result (idx_coll, idx_pid) = ({}, {}):", idx_coll, + idx_pid); + Tools::PrintHypothesisTableHead(m_log, 6); // merge scalar members - out_npe += in_pid.getNpe(); // sum + out_npe += in_pid.getNpe(); // sum out_refractiveIndex += in_pid.getNpe() * in_pid.getRefractiveIndex(); // NPE-weighted average - out_photonEnergy += in_pid.getNpe() * in_pid.getPhotonEnergy(); // NPE-weighted average + out_photonEnergy += in_pid.getNpe() * in_pid.getPhotonEnergy(); // NPE-weighted average // merge photon Cherenkov angles - for(auto in_photon_vec : in_pid.getThetaPhiPhotons()) + for (auto in_photon_vec : in_pid.getThetaPhiPhotons()) out_pid.addToThetaPhiPhotons(in_photon_vec); // relate the charged particle - if(!out_pid.getChargedParticle().isAvailable()) // only needs to be done once + if (!out_pid.getChargedParticle().isAvailable()) // only needs to be done once out_pid.setChargedParticle(in_pid.getChargedParticle()); // merge PDG hypotheses, combining their weights and other members - for(auto in_hyp : in_pid.getHypotheses()) { - Tools::PrintHypothesisTableLine(m_log,in_hyp,6); + for (auto in_hyp : in_pid.getHypotheses()) { + Tools::PrintHypothesisTableLine(m_log, in_hyp, 6); auto out_hyp_it = pdg_2_out_hyp.find(in_hyp.PDG); - if(out_hyp_it == pdg_2_out_hyp.end()) { + if (out_hyp_it == pdg_2_out_hyp.end()) { edm4eic::CherenkovParticleIDHypothesis out_hyp; out_hyp.PDG = in_hyp.PDG; // FIXME: no copy constructor? out_hyp.npe = in_hyp.npe; out_hyp.weight = in_hyp.weight; - pdg_2_out_hyp.insert({out_hyp.PDG,out_hyp}); - } - else { + pdg_2_out_hyp.insert({out_hyp.PDG, out_hyp}); + } else { auto& out_hyp = out_hyp_it->second; out_hyp.npe += in_hyp.npe; // combine hypotheses' weights - switch(m_cfg.mergeMode) { - case MergeParticleIDConfig::kAddWeights: - out_hyp.weight += in_hyp.weight; - break; - case MergeParticleIDConfig::kMultiplyWeights: - out_hyp.weight *= in_hyp.weight; - break; - default: - throw std::runtime_error("unknown MergeParticleIDConfig::mergeMode setting; weights not combined"); + switch (m_cfg.mergeMode) { + case MergeParticleIDConfig::kAddWeights: + out_hyp.weight += in_hyp.weight; + break; + case MergeParticleIDConfig::kMultiplyWeights: + out_hyp.weight *= in_hyp.weight; + break; + default: + throw std::runtime_error( + "unknown MergeParticleIDConfig::mergeMode setting; weights not combined"); } } } // end `in_pid.getHypotheses()` loop, for this charged particle @@ -181,20 +182,20 @@ void MergeParticleID::process( // finish computing averages of scalar members out_pid.setNpe(out_npe); - if(out_npe > 0) { - out_pid.setRefractiveIndex( out_refractiveIndex / out_npe ); - out_pid.setPhotonEnergy( out_photonEnergy / out_npe ); + if (out_npe > 0) { + out_pid.setRefractiveIndex(out_refractiveIndex / out_npe); + out_pid.setPhotonEnergy(out_photonEnergy / out_npe); } // append hypotheses - for(auto [pdg,out_hyp] : pdg_2_out_hyp) + for (auto [pdg, out_hyp] : pdg_2_out_hyp) out_pid.addToHypotheses(out_hyp); // logging: print merged hypothesis table m_log->trace(" => merged hypothesis weights:"); - Tools::PrintHypothesisTableHead(m_log,6); - for(auto out_hyp : out_pid.getHypotheses()) - Tools::PrintHypothesisTableLine(m_log,out_hyp,6); + Tools::PrintHypothesisTableHead(m_log, 6); + for (auto out_hyp : out_pid.getHypotheses()) + Tools::PrintHypothesisTableLine(m_log, out_hyp, 6); } // end `particle_pids` loop over charged particles } diff --git a/src/algorithms/pid/MergeParticleID.h b/src/algorithms/pid/MergeParticleID.h index 6e0ee715d4..d751e80283 100644 --- a/src/algorithms/pid/MergeParticleID.h +++ b/src/algorithms/pid/MergeParticleID.h @@ -18,35 +18,29 @@ namespace eicrecon { - using MergeParticleIDAlgorithm = algorithms::Algorithm< - algorithms::Input< - std::vector - >, - algorithms::Output< - edm4eic::CherenkovParticleIDCollection - > - >; - - class MergeParticleID - : public MergeParticleIDAlgorithm, - public WithPodConfig { - - public: - MergeParticleID(std::string_view name) +using MergeParticleIDAlgorithm = algorithms::Algorithm< + algorithms::Input>, + algorithms::Output>; + +class MergeParticleID : public MergeParticleIDAlgorithm, + public WithPodConfig { + +public: + MergeParticleID(std::string_view name) : MergeParticleIDAlgorithm{name, - {"inputTrackSegments"}, - {"outputTrackSegments"}, - "Effectively 'zip' the input particle IDs"} {} - - void init(std::shared_ptr& logger); - - // - input: a list of particle ID collections, which we want to merge together - // - output: the merged particle ID collection - // - overload this function to support different collections from other PID subsystems, or to support - // merging PID results from overlapping subsystems - void process(const Input&, const Output&) const final; - - private: - std::shared_ptr m_log; - }; -} + {"inputTrackSegments"}, + {"outputTrackSegments"}, + "Effectively 'zip' the input particle IDs"} {} + + void init(std::shared_ptr& logger); + + // - input: a list of particle ID collections, which we want to merge together + // - output: the merged particle ID collection + // - overload this function to support different collections from other PID subsystems, or to support + // merging PID results from overlapping subsystems + void process(const Input&, const Output&) const final; + +private: + std::shared_ptr m_log; +}; +} // namespace eicrecon diff --git a/src/algorithms/pid/MergeParticleIDConfig.h b/src/algorithms/pid/MergeParticleIDConfig.h index b70e2af8b1..08404f3331 100644 --- a/src/algorithms/pid/MergeParticleIDConfig.h +++ b/src/algorithms/pid/MergeParticleIDConfig.h @@ -7,33 +7,28 @@ namespace eicrecon { - class MergeParticleIDConfig { - public: - - ///////////////////////////////////////////////////// - // CONFIGURATION PARAMETERS - // NOTE: some defaults are hard-coded here; override externally - - // decide how to combine the weights - enum math_enum { kAddWeights, kMultiplyWeights }; - int mergeMode = kAddWeights; - - // - ///////////////////////////////////////////////////// - - // print all parameters - void Print( - std::shared_ptr m_log, - spdlog::level::level_enum lvl=spdlog::level::debug - ) - { - m_log->log(lvl, "{:=^60}"," MergeParticleIDConfig Settings "); - auto print_param = [&m_log, &lvl] (auto name, auto val) { - m_log->log(lvl, " {:>20} = {:<}", name, val); - }; - print_param("mergeMode",mergeMode); - m_log->log(lvl, "{:=^60}",""); - } - - }; -} +class MergeParticleIDConfig { +public: + ///////////////////////////////////////////////////// + // CONFIGURATION PARAMETERS + // NOTE: some defaults are hard-coded here; override externally + + // decide how to combine the weights + enum math_enum { kAddWeights, kMultiplyWeights }; + int mergeMode = kAddWeights; + + // + ///////////////////////////////////////////////////// + + // print all parameters + void Print(std::shared_ptr m_log, + spdlog::level::level_enum lvl = spdlog::level::debug) { + m_log->log(lvl, "{:=^60}", " MergeParticleIDConfig Settings "); + auto print_param = [&m_log, &lvl](auto name, auto val) { + m_log->log(lvl, " {:>20} = {:<}", name, val); + }; + print_param("mergeMode", mergeMode); + m_log->log(lvl, "{:=^60}", ""); + } +}; +} // namespace eicrecon diff --git a/src/algorithms/pid/MergeTracks.h b/src/algorithms/pid/MergeTracks.h index 853ec1eb1c..ce465482a0 100644 --- a/src/algorithms/pid/MergeTracks.h +++ b/src/algorithms/pid/MergeTracks.h @@ -31,7 +31,7 @@ class MergeTracks : public MergeTracksAlgorithm { {"outputTrackSegments"}, "Effectively 'zip' the input track segments."} {} - void init() final{}; + void init() final {}; void process(const Input&, const Output&) const final; }; } // namespace eicrecon diff --git a/src/algorithms/pid/Tools.h b/src/algorithms/pid/Tools.h index b99450b122..f6edddd501 100644 --- a/src/algorithms/pid/Tools.h +++ b/src/algorithms/pid/Tools.h @@ -22,200 +22,181 @@ #include #include - namespace eicrecon { - // Tools class, filled with miscellaneous helper functions - class Tools { - public: - - // ------------------------------------------------------------------------------------- - - // h*c constant, for wavelength <=> energy conversion [GeV*nm] - static constexpr double HC = dd4hep::h_Planck * dd4hep::c_light / (dd4hep::GeV * dd4hep::nm); - - - // ------------------------------------------------------------------------------------- - // Radiator IDs - - static std::unordered_map GetRadiatorIDs() { - return std::unordered_map{ - { 0, "Aerogel" }, - { 1, "Gas" } - }; - } - - static std::string GetRadiatorName(int id) { - std::string name; - try { name = GetRadiatorIDs().at(id); } - catch(const std::out_of_range& e) { - throw std::runtime_error(fmt::format("RUNTIME ERROR: unknown radiator ID={} in algorithms/pid/Tools::GetRadiatorName",id)); - } - return name; - } - - static int GetRadiatorID(std::string name) { - for(auto& [id,name_tmp] : GetRadiatorIDs()) - if(name==name_tmp) return id; - throw std::runtime_error(fmt::format("RUNTIME ERROR: unknown radiator '{}' in algorithms/pid/Tools::GetRadiatorID",name)); - return -1; - } - - - // ------------------------------------------------------------------------------------- - // Table rebinning and lookup - - // Rebin input table `input` to have `nbins+1` equidistant bins; returns the rebinned table - static std::vector> ApplyFineBinning( - const std::vector> &input, - unsigned nbins - ) - { - std::vector> ret; - - // Well, could have probably just reordered the initial vector; - std::map buffer; - - for(auto entry: input) - buffer[entry.first] = entry.second; - - // Sanity checks; return empty map in case do not pass them; - if (buffer.size() < 2 || nbins < 2) return ret; - - double from = (*buffer.begin()).first; - double to = (*buffer.rbegin()).first; - // Will be "nbins+1" equidistant entries; - double step = (to - from) / nbins; - - for(auto entry: buffer) { - double e1 = entry.first; - double qe1 = entry.second; - - if (!ret.size()) - ret.push_back(std::make_pair(e1, qe1)); - else { - const auto &prev = ret[ret.size()-1]; - - double e0 = prev.first; - double qe0 = prev.second; - double a = (qe1 - qe0) / (e1 - e0); - double b = qe0 - a*e0; - // FIXME: check floating point accuracy when moving to a next point; do we actually - // care whether the overall number of bins will be "nbins+1" or more?; - for(double e = e0+step; e> &table, - double argument, - double *entry - ) - { - // Get the tabulated table reference; perform sanity checks; - //const std::vector> &qe = u_quantumEfficiency.value(); - unsigned dim = table.size(); if (dim < 2) return false; - - // Find a proper bin; no tricks, they are all equidistant; - auto const &from = table[0]; - auto const &to = table[dim-1]; - double emin = from.first; - double emax = to.first; - double step = (emax - emin) / (dim - 1); - int ibin = (int)floor((argument - emin) / step); - - //printf("%f vs %f, %f -> %d\n", ev, from.first, to. first, ibin); - - // Out of range check; - if (ibin < 0 || ibin >= int(dim)) return false; - - *entry = table[ibin].second; - return true; - } - - // ------------------------------------------------------------------------------------- - // convert PODIO vector datatype to ROOT TVector3 - template - static TVector3 PodioVector3_to_TVector3(const PodioVector3 v) { - return TVector3(v.x, v.y, v.z); - } - // convert ROOT::Math::Vector to ROOT TVector3 - template - static TVector3 MathVector3_to_TVector3(MathVector3 v) { - return TVector3(v.x(), v.y(), v.z()); - } - - // ------------------------------------------------------------------------------------- - - // printing: vectors - static void PrintTVector3( - std::shared_ptr m_log, - std::string name, TVector3 vec, - int nameBuffer=30, spdlog::level::level_enum lvl=spdlog::level::trace - ) - { - m_log->log(lvl, "{:>{}} = ( {:>10.2f} {:>10.2f} {:>10.2f} )", name, nameBuffer, vec.x(), vec.y(), vec.z()); - } - - // printing: hypothesis tables - static void PrintHypothesisTableHead( - std::shared_ptr m_log, - int indent=4, spdlog::level::level_enum lvl=spdlog::level::trace - ) - { - m_log->log(lvl, "{:{}}{:>6} {:>10} {:>10}", "", indent, "PDG", "Weight", "NPE"); - } - static void PrintHypothesisTableLine( - std::shared_ptr m_log, - edm4eic::CherenkovParticleIDHypothesis hyp, - int indent=4, spdlog::level::level_enum lvl=spdlog::level::trace - ) - { - m_log->log(lvl, "{:{}}{:>6} {:>10.8} {:>10.8}", "", indent, hyp.PDG, hyp.weight, hyp.npe); - } - static void PrintHypothesisTableLine( - std::shared_ptr m_log, - edm4hep::ParticleID hyp, - int indent=4, spdlog::level::level_enum lvl=spdlog::level::trace - ) - { - float npe = hyp.parameters_size() > 0 ? hyp.getParameters(0) : -1; // assume NPE is the first parameter - m_log->log(lvl, "{:{}}{:>6} {:>10.8} {:>10.8}", "", indent, hyp.getPDG(), hyp.getLikelihood(), npe); +// Tools class, filled with miscellaneous helper functions +class Tools { +public: + // ------------------------------------------------------------------------------------- + + // h*c constant, for wavelength <=> energy conversion [GeV*nm] + static constexpr double HC = dd4hep::h_Planck * dd4hep::c_light / (dd4hep::GeV * dd4hep::nm); + + // ------------------------------------------------------------------------------------- + // Radiator IDs + + static std::unordered_map GetRadiatorIDs() { + return std::unordered_map{{0, "Aerogel"}, {1, "Gas"}}; + } + + static std::string GetRadiatorName(int id) { + std::string name; + try { + name = GetRadiatorIDs().at(id); + } catch (const std::out_of_range& e) { + throw std::runtime_error(fmt::format( + "RUNTIME ERROR: unknown radiator ID={} in algorithms/pid/Tools::GetRadiatorName", id)); + } + return name; + } + + static int GetRadiatorID(std::string name) { + for (auto& [id, name_tmp] : GetRadiatorIDs()) + if (name == name_tmp) + return id; + throw std::runtime_error(fmt::format( + "RUNTIME ERROR: unknown radiator '{}' in algorithms/pid/Tools::GetRadiatorID", name)); + return -1; + } + + // ------------------------------------------------------------------------------------- + // Table rebinning and lookup + + // Rebin input table `input` to have `nbins+1` equidistant bins; returns the rebinned table + static std::vector> + ApplyFineBinning(const std::vector>& input, unsigned nbins) { + std::vector> ret; + + // Well, could have probably just reordered the initial vector; + std::map buffer; + + for (auto entry : input) + buffer[entry.first] = entry.second; + + // Sanity checks; return empty map in case do not pass them; + if (buffer.size() < 2 || nbins < 2) + return ret; + + double from = (*buffer.begin()).first; + double to = (*buffer.rbegin()).first; + // Will be "nbins+1" equidistant entries; + double step = (to - from) / nbins; + + for (auto entry : buffer) { + double e1 = entry.first; + double qe1 = entry.second; + + if (!ret.size()) + ret.push_back(std::make_pair(e1, qe1)); + else { + const auto& prev = ret[ret.size() - 1]; + + double e0 = prev.first; + double qe0 = prev.second; + double a = (qe1 - qe0) / (e1 - e0); + double b = qe0 - a * e0; + // FIXME: check floating point accuracy when moving to a next point; do we actually + // care whether the overall number of bins will be "nbins+1" or more?; + for (double e = e0 + step; e < e1; e += step) + ret.push_back(std::make_pair(e, a * e + b)); + } //if + } //for entry + + return ret; + } + + // Find the bin in table `table` that contains entry `argument` in the first column and + // sets `entry` to the corresponding element of the second column; returns true if successful + static bool GetFinelyBinnedTableEntry(const std::vector>& table, + double argument, double* entry) { + // Get the tabulated table reference; perform sanity checks; + //const std::vector> &qe = u_quantumEfficiency.value(); + unsigned dim = table.size(); + if (dim < 2) + return false; + + // Find a proper bin; no tricks, they are all equidistant; + auto const& from = table[0]; + auto const& to = table[dim - 1]; + double emin = from.first; + double emax = to.first; + double step = (emax - emin) / (dim - 1); + int ibin = (int)floor((argument - emin) / step); + + //printf("%f vs %f, %f -> %d\n", ev, from.first, to. first, ibin); + + // Out of range check; + if (ibin < 0 || ibin >= int(dim)) + return false; + + *entry = table[ibin].second; + return true; + } + + // ------------------------------------------------------------------------------------- + // convert PODIO vector datatype to ROOT TVector3 + template static TVector3 PodioVector3_to_TVector3(const PodioVector3 v) { + return TVector3(v.x, v.y, v.z); + } + // convert ROOT::Math::Vector to ROOT TVector3 + template static TVector3 MathVector3_to_TVector3(MathVector3 v) { + return TVector3(v.x(), v.y(), v.z()); + } + + // ------------------------------------------------------------------------------------- + + // printing: vectors + static void PrintTVector3(std::shared_ptr m_log, std::string name, TVector3 vec, + int nameBuffer = 30, + spdlog::level::level_enum lvl = spdlog::level::trace) { + m_log->log(lvl, "{:>{}} = ( {:>10.2f} {:>10.2f} {:>10.2f} )", name, nameBuffer, vec.x(), + vec.y(), vec.z()); + } + + // printing: hypothesis tables + static void PrintHypothesisTableHead(std::shared_ptr m_log, int indent = 4, + spdlog::level::level_enum lvl = spdlog::level::trace) { + m_log->log(lvl, "{:{}}{:>6} {:>10} {:>10}", "", indent, "PDG", "Weight", "NPE"); + } + static void PrintHypothesisTableLine(std::shared_ptr m_log, + edm4eic::CherenkovParticleIDHypothesis hyp, int indent = 4, + spdlog::level::level_enum lvl = spdlog::level::trace) { + m_log->log(lvl, "{:{}}{:>6} {:>10.8} {:>10.8}", "", indent, hyp.PDG, hyp.weight, hyp.npe); + } + static void PrintHypothesisTableLine(std::shared_ptr m_log, + edm4hep::ParticleID hyp, int indent = 4, + spdlog::level::level_enum lvl = spdlog::level::trace) { + float npe = + hyp.parameters_size() > 0 ? hyp.getParameters(0) : -1; // assume NPE is the first parameter + m_log->log(lvl, "{:{}}{:>6} {:>10.8} {:>10.8}", "", indent, hyp.getPDG(), hyp.getLikelihood(), + npe); + } + + // printing: Cherenkov angle estimate + static void PrintCherenkovEstimate(std::shared_ptr m_log, + edm4eic::CherenkovParticleID pid, bool printHypotheses = true, + int indent = 2, + spdlog::level::level_enum lvl = spdlog::level::trace) { + if (m_log->level() <= lvl) { + double thetaAve = 0; + if (pid.getNpe() > 0) + for (const auto& [theta, phi] : pid.getThetaPhiPhotons()) + thetaAve += theta / pid.getNpe(); + m_log->log(lvl, "{:{}}Cherenkov Angle Estimate:", "", indent); + m_log->log(lvl, "{:{}} {:>16}: {:>10}", "", indent, "NPE", pid.getNpe()); + m_log->log(lvl, "{:{}} {:>16}: {:>10.8} mrad", "", indent, "", + thetaAve * 1e3); // [rad] -> [mrad] + m_log->log(lvl, "{:{}} {:>16}: {:>10.8}", "", indent, "", pid.getRefractiveIndex()); + m_log->log(lvl, "{:{}} {:>16}: {:>10.8} eV", "", indent, "", + pid.getPhotonEnergy() * 1e9); // [GeV] -> [eV] + if (printHypotheses) { + m_log->log(lvl, "{:{}}Mass Hypotheses:", "", indent); + Tools::PrintHypothesisTableHead(m_log, indent + 2); + for (const auto& hyp : pid.getHypotheses()) + Tools::PrintHypothesisTableLine(m_log, hyp, indent + 2); } + } + } - // printing: Cherenkov angle estimate - static void PrintCherenkovEstimate( - std::shared_ptr m_log, - edm4eic::CherenkovParticleID pid, - bool printHypotheses = true, - int indent=2, spdlog::level::level_enum lvl=spdlog::level::trace - ) - { - if(m_log->level() <= lvl) { - double thetaAve = 0; - if(pid.getNpe() > 0) - for(const auto& [theta,phi] : pid.getThetaPhiPhotons()) - thetaAve += theta / pid.getNpe(); - m_log->log(lvl, "{:{}}Cherenkov Angle Estimate:", "", indent); - m_log->log(lvl, "{:{}} {:>16}: {:>10}", "", indent, "NPE", pid.getNpe()); - m_log->log(lvl, "{:{}} {:>16}: {:>10.8} mrad", "", indent, "", thetaAve*1e3); // [rad] -> [mrad] - m_log->log(lvl, "{:{}} {:>16}: {:>10.8}", "", indent, "", pid.getRefractiveIndex()); - m_log->log(lvl, "{:{}} {:>16}: {:>10.8} eV", "", indent, "", pid.getPhotonEnergy()*1e9); // [GeV] -> [eV] - if(printHypotheses) { - m_log->log(lvl, "{:{}}Mass Hypotheses:", "", indent); - Tools::PrintHypothesisTableHead(m_log, indent+2); - for(const auto& hyp : pid.getHypotheses()) - Tools::PrintHypothesisTableLine(m_log, hyp, indent+2); - } - } - } - - - }; // class Tools +}; // class Tools } // namespace eicrecon diff --git a/src/algorithms/pid_lut/PIDLookup.cc b/src/algorithms/pid_lut/PIDLookup.cc index 47cb5b37d9..48d452abf9 100644 --- a/src/algorithms/pid_lut/PIDLookup.cc +++ b/src/algorithms/pid_lut/PIDLookup.cc @@ -20,20 +20,21 @@ namespace eicrecon { void PIDLookup::init() { auto& serviceSvc = algorithms::ServiceSvc::instance(); - auto lut_svc = serviceSvc.service("PIDLookupTableSvc"); - - m_lut = lut_svc->load(m_cfg.filename, { - .pdg_values=m_cfg.pdg_values, - .charge_values=m_cfg.charge_values, - .momentum_edges=m_cfg.momentum_edges, - .polar_edges=m_cfg.polar_edges, - .azimuthal_binning=m_cfg.azimuthal_binning, - .azimuthal_bin_centers_in_lut=m_cfg.azimuthal_bin_centers_in_lut, - .momentum_bin_centers_in_lut=m_cfg.momentum_bin_centers_in_lut, - .polar_bin_centers_in_lut=m_cfg.polar_bin_centers_in_lut, - .use_radians=m_cfg.use_radians, - .missing_electron_prob=m_cfg.missing_electron_prob, - }); + auto lut_svc = serviceSvc.service("PIDLookupTableSvc"); + + m_lut = lut_svc->load(m_cfg.filename, + { + .pdg_values = m_cfg.pdg_values, + .charge_values = m_cfg.charge_values, + .momentum_edges = m_cfg.momentum_edges, + .polar_edges = m_cfg.polar_edges, + .azimuthal_binning = m_cfg.azimuthal_binning, + .azimuthal_bin_centers_in_lut = m_cfg.azimuthal_bin_centers_in_lut, + .momentum_bin_centers_in_lut = m_cfg.momentum_bin_centers_in_lut, + .polar_bin_centers_in_lut = m_cfg.polar_bin_centers_in_lut, + .use_radians = m_cfg.use_radians, + .missing_electron_prob = m_cfg.missing_electron_prob, + }); if (m_lut == nullptr) { throw std::runtime_error("LUT not available"); } @@ -79,41 +80,44 @@ void PIDLookup::process(const Input& input, const Output& output) const { double theta = edm4hep::utils::anglePolar(recopart.getMomentum()) / M_PI * 180.; double phi = edm4hep::utils::angleAzimuthal(recopart.getMomentum()) / M_PI * 180.; - trace("lookup for true_pdg={}, true_charge={}, momentum={:.2f} GeV, polar={:.2f}, aziumthal={:.2f}", - true_pdg, true_charge, momentum, theta, phi); + trace("lookup for true_pdg={}, true_charge={}, momentum={:.2f} GeV, polar={:.2f}, " + "aziumthal={:.2f}", + true_pdg, true_charge, momentum, theta, phi); auto entry = m_lut->Lookup(true_pdg, true_charge, momentum, theta, phi); int identified_pdg = 0; // unknown - if ((entry != nullptr) && ((entry->prob_electron != 0.) || (entry->prob_pion != 0.) || (entry->prob_kaon != 0.) || (entry->prob_electron != 0.))) { + if ((entry != nullptr) && ((entry->prob_electron != 0.) || (entry->prob_pion != 0.) || + (entry->prob_kaon != 0.) || (entry->prob_electron != 0.))) { double random_unit_interval = m_dist(m_gen); - trace("entry with e:pi:K:P={}:{}:{}:{}", entry->prob_electron, entry->prob_pion, entry->prob_kaon, entry->prob_proton); - - recopart.addToParticleIDs(partids_out->create( - m_cfg.system, // std::int32_t type - std::copysign(11, -charge), // std::int32_t PDG - 0, // std::int32_t algorithmType - static_cast(entry->prob_electron) // float likelihood - )); - recopart.addToParticleIDs(partids_out->create( - m_cfg.system, // std::int32_t type - std::copysign(211, charge), // std::int32_t PDG - 0, // std::int32_t algorithmType - static_cast(entry->prob_pion) // float likelihood - )); - recopart.addToParticleIDs(partids_out->create( - m_cfg.system, // std::int32_t type - std::copysign(321, charge), // std::int32_t PDG - 0, // std::int32_t algorithmType - static_cast(entry->prob_kaon) // float likelihood - )); - recopart.addToParticleIDs(partids_out->create( - m_cfg.system, // std::int32_t type - std::copysign(2212, charge), // std::int32_t PDG - 0, // std::int32_t algorithmType - static_cast(entry->prob_proton) // float likelihood - )); + trace("entry with e:pi:K:P={}:{}:{}:{}", entry->prob_electron, entry->prob_pion, + entry->prob_kaon, entry->prob_proton); + + recopart.addToParticleIDs( + partids_out->create(m_cfg.system, // std::int32_t type + std::copysign(11, -charge), // std::int32_t PDG + 0, // std::int32_t algorithmType + static_cast(entry->prob_electron) // float likelihood + )); + recopart.addToParticleIDs( + partids_out->create(m_cfg.system, // std::int32_t type + std::copysign(211, charge), // std::int32_t PDG + 0, // std::int32_t algorithmType + static_cast(entry->prob_pion) // float likelihood + )); + recopart.addToParticleIDs( + partids_out->create(m_cfg.system, // std::int32_t type + std::copysign(321, charge), // std::int32_t PDG + 0, // std::int32_t algorithmType + static_cast(entry->prob_kaon) // float likelihood + )); + recopart.addToParticleIDs( + partids_out->create(m_cfg.system, // std::int32_t type + std::copysign(2212, charge), // std::int32_t PDG + 0, // std::int32_t algorithmType + static_cast(entry->prob_proton) // float likelihood + )); if (random_unit_interval < entry->prob_electron) { identified_pdg = 11; // electron diff --git a/src/algorithms/pid_lut/PIDLookupConfig.h b/src/algorithms/pid_lut/PIDLookupConfig.h index 2d8e93ddab..ec43509bbb 100644 --- a/src/algorithms/pid_lut/PIDLookupConfig.h +++ b/src/algorithms/pid_lut/PIDLookupConfig.h @@ -15,11 +15,11 @@ struct PIDLookupConfig { std::vector momentum_edges; std::vector polar_edges; std::vector azimuthal_binning; - bool azimuthal_bin_centers_in_lut {false}; - bool momentum_bin_centers_in_lut {false}; - bool polar_bin_centers_in_lut {false}; - bool use_radians {false}; - bool missing_electron_prob {false}; + bool azimuthal_bin_centers_in_lut{false}; + bool momentum_bin_centers_in_lut{false}; + bool polar_bin_centers_in_lut{false}; + bool use_radians{false}; + bool missing_electron_prob{false}; }; } // namespace eicrecon diff --git a/src/algorithms/reco/Beam.h b/src/algorithms/reco/Beam.h index b27bd3a2d3..d6da7eba17 100644 --- a/src/algorithms/reco/Beam.h +++ b/src/algorithms/reco/Beam.h @@ -12,72 +12,63 @@ using ROOT::Math::PxPyPzEVector; namespace eicrecon { - template - auto find_first_with_pdg( - const T* parts, - const std::set& pdg) { - T c; - c.setSubsetCollection(); - for (const auto& p: *parts) { - if (pdg.count(p.getPDG()) > 0) { - c.push_back(p); - break; - } +template auto find_first_with_pdg(const T* parts, const std::set& pdg) { + T c; + c.setSubsetCollection(); + for (const auto& p : *parts) { + if (pdg.count(p.getPDG()) > 0) { + c.push_back(p); + break; } - return c; } + return c; +} - template - auto find_first_with_status_pdg( - const T* parts, - const std::set& status, - const std::set& pdg) { - T c; - c.setSubsetCollection(); - for (const auto& p: *parts) { - if (status.count(p.getGeneratorStatus()) > 0 && - pdg.count(p.getPDG()) > 0) { - c.push_back(p); - break; - } +template +auto find_first_with_status_pdg(const T* parts, const std::set& status, + const std::set& pdg) { + T c; + c.setSubsetCollection(); + for (const auto& p : *parts) { + if (status.count(p.getGeneratorStatus()) > 0 && pdg.count(p.getPDG()) > 0) { + c.push_back(p); + break; } - return c; } + return c; +} - inline auto find_first_beam_electron(const edm4hep::MCParticleCollection* mcparts) { - return find_first_with_status_pdg(mcparts, {4}, {11}); - } +inline auto find_first_beam_electron(const edm4hep::MCParticleCollection* mcparts) { + return find_first_with_status_pdg(mcparts, {4}, {11}); +} - inline auto find_first_beam_hadron(const edm4hep::MCParticleCollection* mcparts) { - return find_first_with_status_pdg(mcparts, {4}, {2212, 2112}); - } +inline auto find_first_beam_hadron(const edm4hep::MCParticleCollection* mcparts) { + return find_first_with_status_pdg(mcparts, {4}, {2212, 2112}); +} - inline auto find_first_scattered_electron(const edm4hep::MCParticleCollection* mcparts) { - return find_first_with_status_pdg(mcparts, {1}, {11}); - } +inline auto find_first_scattered_electron(const edm4hep::MCParticleCollection* mcparts) { + return find_first_with_status_pdg(mcparts, {1}, {11}); +} - inline auto find_first_scattered_electron(const edm4eic::ReconstructedParticleCollection* rcparts) { - return find_first_with_pdg(rcparts, {11}); - } +inline auto find_first_scattered_electron(const edm4eic::ReconstructedParticleCollection* rcparts) { + return find_first_with_pdg(rcparts, {11}); +} - template - PxPyPzEVector - round_beam_four_momentum( - const Vector3& p_in, - const float mass, - const std::vector& pz_set, - const float crossing_angle = 0.0) { - PxPyPzEVector p_out; - for (const auto& pz : pz_set) { - if (fabs(p_in.z / pz - 1) < 0.1) { - p_out.SetPz(pz); - break; - } +template +PxPyPzEVector round_beam_four_momentum(const Vector3& p_in, const float mass, + const std::vector& pz_set, + const float crossing_angle = 0.0) { + PxPyPzEVector p_out; + for (const auto& pz : pz_set) { + if (fabs(p_in.z / pz - 1) < 0.1) { + p_out.SetPz(pz); + break; } - p_out.SetPx(p_out.Pz() * sin(crossing_angle)); - p_out.SetPz(p_out.Pz() * cos(crossing_angle)); - p_out.SetE(std::hypot(p_out.Px(), p_out.Pz(), mass)); - return p_out; } + p_out.SetPx(p_out.Pz() * sin(crossing_angle)); + p_out.SetPz(p_out.Pz() * cos(crossing_angle)); + p_out.SetE(std::hypot(p_out.Px(), p_out.Pz(), mass)); + return p_out; +} } // namespace eicrecon diff --git a/src/algorithms/reco/Boost.h b/src/algorithms/reco/Boost.h index 95c7b0e857..df4edf4b4a 100644 --- a/src/algorithms/reco/Boost.h +++ b/src/algorithms/reco/Boost.h @@ -14,50 +14,50 @@ using ROOT::Math::PxPyPzEVector; namespace eicrecon { - using ROOT::Math::LorentzRotation; +using ROOT::Math::LorentzRotation; - inline LorentzRotation determine_boost(PxPyPzEVector ei, PxPyPzEVector pi) { +inline LorentzRotation determine_boost(PxPyPzEVector ei, PxPyPzEVector pi) { - using ROOT::Math::RotationX; - using ROOT::Math::RotationY; - using ROOT::Math::Boost; + using ROOT::Math::Boost; + using ROOT::Math::RotationX; + using ROOT::Math::RotationY; - // Step 1: Find the needed boosts and rotations from the incoming lepton and hadron beams - // (note, this will give you a perfect boost, in principle you will not know the beam momenta exactly and should use an average) + // Step 1: Find the needed boosts and rotations from the incoming lepton and hadron beams + // (note, this will give you a perfect boost, in principle you will not know the beam momenta exactly and should use an average) - // Define the Boost to make beams back-to-back - const auto cmBoost = (ei + pi).BoostToCM(); + // Define the Boost to make beams back-to-back + const auto cmBoost = (ei + pi).BoostToCM(); - const Boost boost_to_cm(-cmBoost); + const Boost boost_to_cm(-cmBoost); - // This will boost beams from a center of momentum frame back to (nearly) their original energies - const Boost boost_to_headon(cmBoost); // FIXME + // This will boost beams from a center of momentum frame back to (nearly) their original energies + const Boost boost_to_headon(cmBoost); // FIXME - // Boost and rotate the incoming beams to find the proper rotations TLorentzVector + // Boost and rotate the incoming beams to find the proper rotations TLorentzVector - // Boost to COM frame - boost_to_cm(pi); - boost_to_cm(ei); - // Rotate to head-on - RotationY rotAboutY(-1.0*atan2(pi.Px(), pi.Pz())); // Rotate to remove x component of beams - RotationX rotAboutX(+1.0*atan2(pi.Py(), pi.Pz())); // Rotate to remove y component of beams + // Boost to COM frame + boost_to_cm(pi); + boost_to_cm(ei); + // Rotate to head-on + RotationY rotAboutY(-1.0 * atan2(pi.Px(), pi.Pz())); // Rotate to remove x component of beams + RotationX rotAboutX(+1.0 * atan2(pi.Py(), pi.Pz())); // Rotate to remove y component of beams - LorentzRotation tf; - tf *= boost_to_cm; - tf *= rotAboutY; - tf *= rotAboutX; - tf *= boost_to_headon; - return tf; - } + LorentzRotation tf; + tf *= boost_to_cm; + tf *= rotAboutY; + tf *= rotAboutX; + tf *= boost_to_headon; + return tf; +} - inline PxPyPzEVector apply_boost(const LorentzRotation& tf, PxPyPzEVector part) { +inline PxPyPzEVector apply_boost(const LorentzRotation& tf, PxPyPzEVector part) { - // Step 2: Apply boosts and rotations to any particle 4-vector - // (here too, choices will have to be made as to what the 4-vector is for reconstructed particles) + // Step 2: Apply boosts and rotations to any particle 4-vector + // (here too, choices will have to be made as to what the 4-vector is for reconstructed particles) - // Boost and rotate particle 4-momenta into the headon frame - tf(part); - return part; - } + // Boost and rotate particle 4-momenta into the headon frame + tf(part); + return part; +} } // namespace eicrecon diff --git a/src/algorithms/reco/ChargedMCParticleSelector.h b/src/algorithms/reco/ChargedMCParticleSelector.h index f004d83cef..704156a5fc 100644 --- a/src/algorithms/reco/ChargedMCParticleSelector.h +++ b/src/algorithms/reco/ChargedMCParticleSelector.h @@ -13,33 +13,29 @@ namespace eicrecon { - class ChargedMCParticleSelector : public WithPodConfig { +class ChargedMCParticleSelector : public WithPodConfig { - private: +private: + std::shared_ptr m_log; - std::shared_ptr m_log; +public: + // algorithm initialization + void init(std::shared_ptr& logger) { m_log = logger; } - public: + // primary algorithm call + std::unique_ptr + process(const edm4hep::MCParticleCollection* inputs) { + auto outputs = std::make_unique(); + outputs->setSubsetCollection(); - // algorithm initialization - void init(std::shared_ptr& logger) { - m_log = logger; - } - - // primary algorithm call - std::unique_ptr process(const edm4hep::MCParticleCollection* inputs) { - auto outputs = std::make_unique(); - outputs->setSubsetCollection(); - - for (const auto &particle : *inputs) { - if (particle.getCharge() != 0.) { - outputs->push_back(particle); - } + for (const auto& particle : *inputs) { + if (particle.getCharge() != 0.) { + outputs->push_back(particle); } - - return std::move(outputs); } - }; + return std::move(outputs); + } +}; -} +} // namespace eicrecon diff --git a/src/algorithms/reco/ChargedReconstructedParticleSelector.h b/src/algorithms/reco/ChargedReconstructedParticleSelector.h index 93381738e4..3cf26479f5 100644 --- a/src/algorithms/reco/ChargedReconstructedParticleSelector.h +++ b/src/algorithms/reco/ChargedReconstructedParticleSelector.h @@ -13,33 +13,29 @@ namespace eicrecon { - class ChargedReconstructedParticleSelector : public WithPodConfig { +class ChargedReconstructedParticleSelector : public WithPodConfig { - private: +private: + std::shared_ptr m_log; - std::shared_ptr m_log; +public: + // algorithm initialization + void init(std::shared_ptr& logger) { m_log = logger; } - public: + // primary algorithm call + std::unique_ptr + process(const edm4eic::ReconstructedParticleCollection* inputs) { + auto outputs = std::make_unique(); + outputs->setSubsetCollection(); - // algorithm initialization - void init(std::shared_ptr& logger) { - m_log = logger; - } - - // primary algorithm call - std::unique_ptr process(const edm4eic::ReconstructedParticleCollection* inputs) { - auto outputs = std::make_unique(); - outputs->setSubsetCollection(); - - for (const auto &particle : *inputs) { - if (particle.getCharge() != 0.) { - outputs->push_back(particle); - } + for (const auto& particle : *inputs) { + if (particle.getCharge() != 0.) { + outputs->push_back(particle); } - - return std::move(outputs); } - }; + return std::move(outputs); + } +}; -} +} // namespace eicrecon diff --git a/src/algorithms/reco/ElectronReconstruction.cc b/src/algorithms/reco/ElectronReconstruction.cc index 9bc57ba8f1..ffa8c1c092 100644 --- a/src/algorithms/reco/ElectronReconstruction.cc +++ b/src/algorithms/reco/ElectronReconstruction.cc @@ -12,43 +12,42 @@ namespace eicrecon { - void ElectronReconstruction::init(std::shared_ptr logger) { - m_log = logger; - } +void ElectronReconstruction::init(std::shared_ptr logger) { m_log = logger; } + +std::unique_ptr +ElectronReconstruction::execute(const edm4eic::ReconstructedParticleCollection* rcparts) { + + // Some obvious improvements: + // - E/p cut from real study optimized for electron finding and hadron rejection + // - use of any HCAL info? + // - check for duplicates? - std::unique_ptr ElectronReconstruction::execute( - const edm4eic::ReconstructedParticleCollection *rcparts - ) { - - // Some obvious improvements: - // - E/p cut from real study optimized for electron finding and hadron rejection - // - use of any HCAL info? - // - check for duplicates? - - // output container - auto out_electrons = std::make_unique(); - out_electrons->setSubsetCollection(); // out_electrons is a subset of the ReconstructedParticles collection - - for (const auto particle : *rcparts) { - // if we found a reco particle then test for electron compatibility - if (particle.getClusters().size() == 0) { - continue; - } - if (particle.getCharge() == 0) { // Skip over photons/other particles without a track - continue; - } - double E = particle.getClusters()[0].getEnergy(); - double p = edm4hep::utils::magnitude(particle.getMomentum()); - double EOverP = E / p; - - m_log->trace("ReconstructedElectron: Energy={} GeV, p={} GeV, E/p = {} for PDG (from truth): {}", E, p, EOverP, particle.getPDG()); - // Apply the E/p cut here to select electons - if (EOverP >= m_cfg.min_energy_over_momentum && EOverP <= m_cfg.max_energy_over_momentum) { - out_electrons->push_back(particle); - } - - } - m_log->debug("Found {} electron candidates", out_electrons->size()); - return out_electrons; + // output container + auto out_electrons = std::make_unique(); + out_electrons + ->setSubsetCollection(); // out_electrons is a subset of the ReconstructedParticles collection + + for (const auto particle : *rcparts) { + // if we found a reco particle then test for electron compatibility + if (particle.getClusters().size() == 0) { + continue; + } + if (particle.getCharge() == 0) { // Skip over photons/other particles without a track + continue; + } + double E = particle.getClusters()[0].getEnergy(); + double p = edm4hep::utils::magnitude(particle.getMomentum()); + double EOverP = E / p; + + m_log->trace( + "ReconstructedElectron: Energy={} GeV, p={} GeV, E/p = {} for PDG (from truth): {}", E, p, + EOverP, particle.getPDG()); + // Apply the E/p cut here to select electons + if (EOverP >= m_cfg.min_energy_over_momentum && EOverP <= m_cfg.max_energy_over_momentum) { + out_electrons->push_back(particle); } + } + m_log->debug("Found {} electron candidates", out_electrons->size()); + return out_electrons; } +} // namespace eicrecon diff --git a/src/algorithms/reco/ElectronReconstruction.h b/src/algorithms/reco/ElectronReconstruction.h index cb54b06a4a..521efedc80 100644 --- a/src/algorithms/reco/ElectronReconstruction.h +++ b/src/algorithms/reco/ElectronReconstruction.h @@ -10,23 +10,19 @@ #include "ElectronReconstructionConfig.h" #include "algorithms/interfaces/WithPodConfig.h" - namespace eicrecon { - class ElectronReconstruction : public WithPodConfig{ - - public: - - void init(std::shared_ptr logger); +class ElectronReconstruction : public WithPodConfig { - // idea will be to overload this with other version (e.g. reco mode) - std::unique_ptr execute( - const edm4eic::ReconstructedParticleCollection *rcparts - ); +public: + void init(std::shared_ptr logger); - private: - std::shared_ptr m_log; - double m_electron{0.000510998928}; + // idea will be to overload this with other version (e.g. reco mode) + std::unique_ptr + execute(const edm4eic::ReconstructedParticleCollection* rcparts); - }; +private: + std::shared_ptr m_log; + double m_electron{0.000510998928}; +}; } // namespace eicrecon diff --git a/src/algorithms/reco/ElectronReconstructionConfig.h b/src/algorithms/reco/ElectronReconstructionConfig.h index 4f025ad8d6..1ec9bc60bb 100644 --- a/src/algorithms/reco/ElectronReconstructionConfig.h +++ b/src/algorithms/reco/ElectronReconstructionConfig.h @@ -6,9 +6,8 @@ namespace eicrecon { struct ElectronReconstructionConfig { - double min_energy_over_momentum = 0.9; - double max_energy_over_momentum = 1.2; - + double min_energy_over_momentum = 0.9; + double max_energy_over_momentum = 1.2; }; } // namespace eicrecon diff --git a/src/algorithms/reco/FarForwardNeutronReconstruction.cc b/src/algorithms/reco/FarForwardNeutronReconstruction.cc index 14b63a504a..a769555c13 100644 --- a/src/algorithms/reco/FarForwardNeutronReconstruction.cc +++ b/src/algorithms/reco/FarForwardNeutronReconstruction.cc @@ -26,64 +26,67 @@ namespace eicrecon { - void FarForwardNeutronReconstruction::init() { - if (m_cfg.scale_corr_coeff_hcal.size() < 3) { - error("Invalid configuration. m_cfg.scale_corr_coeff_hcal should have at least 3 parameters"); - throw std::runtime_error("Invalid configuration. m_cfg.scale_corr_coeff_hcal should have at least 3 parameters"); - } - if (m_cfg.scale_corr_coeff_ecal.size() < 3) { - error("Invalid configuration. m_cfg.scale_corr_coeff_ecal should have at least 3 parameters"); - throw std::runtime_error("Invalid configuration. m_cfg.scale_corr_coeff_ecal should have at least 3 parameters"); - } +void FarForwardNeutronReconstruction::init() { + if (m_cfg.scale_corr_coeff_hcal.size() < 3) { + error("Invalid configuration. m_cfg.scale_corr_coeff_hcal should have at least 3 parameters"); + throw std::runtime_error( + "Invalid configuration. m_cfg.scale_corr_coeff_hcal should have at least 3 parameters"); + } + if (m_cfg.scale_corr_coeff_ecal.size() < 3) { + error("Invalid configuration. m_cfg.scale_corr_coeff_ecal should have at least 3 parameters"); + throw std::runtime_error( + "Invalid configuration. m_cfg.scale_corr_coeff_ecal should have at least 3 parameters"); + } +} +/** calculates the correction for a given uncorrected total energy and a set of coefficients*/ +double FarForwardNeutronReconstruction::calc_corr(double Etot, + const std::vector& coeffs) const { + return coeffs[0] + coeffs[1] / sqrt(Etot) + coeffs[2] / Etot; +} +void FarForwardNeutronReconstruction::process( + const FarForwardNeutronReconstruction::Input& input, + const FarForwardNeutronReconstruction::Output& output) const { + const auto [clustersHcal, clustersEcal] = input; + auto [out_neutrons] = output; + + double Etot_hcal = 0, Etot_ecal = 0; + double Emax = 0; + edm4hep::Vector3f position; + for (const auto& cluster : *clustersHcal) { + double E = cluster.getEnergy(); + Etot_hcal += E; + if (E > Emax) { + Emax = E; + position = cluster.getPosition(); } - /** calculates the correction for a given uncorrected total energy and a set of coefficients*/ - double FarForwardNeutronReconstruction::calc_corr(double Etot, const std::vector& coeffs) const{ - return coeffs[0]+coeffs[1]/sqrt(Etot)+coeffs[2]/Etot; + } + for (const auto& cluster : *clustersEcal) { + double E = cluster.getEnergy(); + Etot_ecal += E; + } + double Etot = Etot_hcal + Etot_ecal; + if (Etot > 0 && Emax > 0) { + auto rec_part = out_neutrons->create(); + double corr = calc_corr(Etot, m_cfg.scale_corr_coeff_hcal); + Etot_hcal = Etot_hcal / (1 + corr); + corr = calc_corr(Etot, m_cfg.scale_corr_coeff_ecal); + Etot_ecal = Etot_ecal / (1 + corr); + Etot = Etot_hcal + Etot_ecal; + rec_part.setEnergy(Etot); + rec_part.setPDG(2112); + double p = sqrt(Etot * Etot - m_neutron * m_neutron); + double r = edm4hep::utils::magnitude(position); + edm4hep::Vector3f momentum = position * (p / r); + rec_part.setMomentum(momentum); + rec_part.setCharge(0); + rec_part.setMass(m_neutron); + for (const auto& cluster : *clustersHcal) { + rec_part.addToClusters(cluster); } - void FarForwardNeutronReconstruction::process(const FarForwardNeutronReconstruction::Input& input, - const FarForwardNeutronReconstruction::Output& output) const { - const auto [clustersHcal,clustersEcal] = input; - auto [out_neutrons] = output; - - double Etot_hcal=0, Etot_ecal=0; - double Emax=0; - edm4hep::Vector3f position; - for (const auto& cluster : *clustersHcal) { - double E = cluster.getEnergy(); - Etot_hcal += E; - if (E > Emax){ - Emax = E; - position = cluster.getPosition(); - } - } - for (const auto& cluster : *clustersEcal) { - double E = cluster.getEnergy(); - Etot_ecal+=E; - } - double Etot=Etot_hcal+Etot_ecal; - if (Etot > 0 && Emax > 0){ - auto rec_part = out_neutrons->create(); - double corr=calc_corr(Etot,m_cfg.scale_corr_coeff_hcal); - Etot_hcal=Etot_hcal/(1+corr); - corr=calc_corr(Etot,m_cfg.scale_corr_coeff_ecal); - Etot_ecal=Etot_ecal/(1+corr); - Etot=Etot_hcal+Etot_ecal; - rec_part.setEnergy(Etot); - rec_part.setPDG(2112); - double p = sqrt(Etot*Etot-m_neutron*m_neutron); - double r = edm4hep::utils::magnitude(position); - edm4hep::Vector3f momentum = position * (p / r); - rec_part.setMomentum(momentum); - rec_part.setCharge(0); - rec_part.setMass(m_neutron); - for (const auto& cluster : *clustersHcal){ - rec_part.addToClusters(cluster); - } - for (const auto& cluster : *clustersEcal){ - rec_part.addToClusters(cluster); - } - } - //m_log->debug("Found {} neutron candidates", out_neutrons->size()); - + for (const auto& cluster : *clustersEcal) { + rec_part.addToClusters(cluster); } + } + //m_log->debug("Found {} neutron candidates", out_neutrons->size()); } +} // namespace eicrecon diff --git a/src/algorithms/reco/FarForwardNeutronReconstruction.h b/src/algorithms/reco/FarForwardNeutronReconstruction.h index 8767cbac3f..a3b237c028 100644 --- a/src/algorithms/reco/FarForwardNeutronReconstruction.h +++ b/src/algorithms/reco/FarForwardNeutronReconstruction.h @@ -9,8 +9,8 @@ #include #include #include -#include // for basic_string -#include // for string_view +#include // for basic_string +#include // for string_view #include #include "algorithms/interfaces/WithPodConfig.h" @@ -19,30 +19,26 @@ namespace eicrecon { using FarForwardNeutronReconstructionAlgorithm = algorithms::Algorithm< - algorithms::Input< - const edm4eic::ClusterCollection, - std::optional - >, - algorithms::Output< - edm4eic::ReconstructedParticleCollection - > - >; - class FarForwardNeutronReconstruction : - public FarForwardNeutronReconstructionAlgorithm, - public WithPodConfig { - public: - FarForwardNeutronReconstruction(std::string_view name) - : FarForwardNeutronReconstructionAlgorithm{name, - {"inputClustersHcal", "inputClustersEcal"}, - {"outputNeutrons"}, - "Merges all HCAL (and optionally also ECAL) clusters in a collection into a neutron candidate"} {} + algorithms::Input>, + algorithms::Output>; +class FarForwardNeutronReconstruction + : public FarForwardNeutronReconstructionAlgorithm, + public WithPodConfig { +public: + FarForwardNeutronReconstruction(std::string_view name) + : FarForwardNeutronReconstructionAlgorithm{ + name, + {"inputClustersHcal", "inputClustersEcal"}, + {"outputNeutrons"}, + "Merges all HCAL (and optionally also ECAL) clusters in a collection into a neutron " + "candidate"} {} - void init() final; - void process(const Input&, const Output&) const final; - double calc_corr(double Etot, const std::vector&) const; - private: - std::shared_ptr m_log; - double m_neutron{0.93956542052}; + void init() final; + void process(const Input&, const Output&) const final; + double calc_corr(double Etot, const std::vector&) const; - }; +private: + std::shared_ptr m_log; + double m_neutron{0.93956542052}; +}; } // namespace eicrecon diff --git a/src/algorithms/reco/FarForwardNeutronReconstructionConfig.h b/src/algorithms/reco/FarForwardNeutronReconstructionConfig.h index f236f722cf..51b6968420 100644 --- a/src/algorithms/reco/FarForwardNeutronReconstructionConfig.h +++ b/src/algorithms/reco/FarForwardNeutronReconstructionConfig.h @@ -5,11 +5,11 @@ namespace eicrecon { - struct FarForwardNeutronReconstructionConfig { - /** Correction factors for the Hcal */ - std::vector scale_corr_coeff_hcal={-0.0756, -1.91, 2.30}; - /** Correction factors for the (optional) Ecal */ - std::vector scale_corr_coeff_ecal={-0.352, -1.34, 1.61}; - }; - -} // eicrecon +struct FarForwardNeutronReconstructionConfig { + /** Correction factors for the Hcal */ + std::vector scale_corr_coeff_hcal = {-0.0756, -1.91, 2.30}; + /** Correction factors for the (optional) Ecal */ + std::vector scale_corr_coeff_ecal = {-0.352, -1.34, 1.61}; +}; + +} // namespace eicrecon diff --git a/src/algorithms/reco/HadronicFinalState.cc b/src/algorithms/reco/HadronicFinalState.cc index 60ebb5f5a5..fd2f3865d7 100644 --- a/src/algorithms/reco/HadronicFinalState.cc +++ b/src/algorithms/reco/HadronicFinalState.cc @@ -25,114 +25,104 @@ using ROOT::Math::PxPyPzEVector; namespace eicrecon { - void HadronicFinalState::init() { } +void HadronicFinalState::init() {} - void HadronicFinalState::process( - const HadronicFinalState::Input& input, - const HadronicFinalState::Output& output) const { +void HadronicFinalState::process(const HadronicFinalState::Input& input, + const HadronicFinalState::Output& output) const { - const auto [mcparts, rcparts, rcassoc] = input; - auto [hadronicfinalstate] = output; + const auto [mcparts, rcparts, rcassoc] = input; + auto [hadronicfinalstate] = output; - // Get incoming electron beam - const auto ei_coll = find_first_beam_electron(mcparts); - if (ei_coll.size() == 0) { - debug("No beam electron found"); - return; - } - const PxPyPzEVector ei( - round_beam_four_momentum( - ei_coll[0].getMomentum(), - m_particleSvc.particle(ei_coll[0].getPDG()).mass, - {-5.0, -10.0, -18.0}, - 0.0) - ); - - // Get incoming hadron beam - const auto pi_coll = find_first_beam_hadron(mcparts); - if (pi_coll.size() == 0) { - debug("No beam hadron found"); - return; - } - const PxPyPzEVector pi( - round_beam_four_momentum( - pi_coll[0].getMomentum(), - m_particleSvc.particle(pi_coll[0].getPDG()).mass, - {41.0, 100.0, 275.0}, - m_crossingAngle) - ); - - // Get first scattered electron - const auto ef_coll = find_first_scattered_electron(mcparts); - if (ef_coll.size() == 0) { - debug("No truth scattered electron found"); - return; - } - // Associate first scattered electron with reconstructed electrons - //const auto ef_assoc = std::find_if( - // rcassoc->begin(), - // rcassoc->end(), - // [&ef_coll](const auto& a){ return a.getSim().getObjectID() == ef_coll[0].getObjectID(); }); - auto ef_assoc = rcassoc->begin(); - for (; ef_assoc != rcassoc->end(); ++ef_assoc) { - if (ef_assoc->getSim().getObjectID() == ef_coll[0].getObjectID()) { - break; - } - } - if (!(ef_assoc != rcassoc->end())) { - debug("Truth scattered electron not in reconstructed particles"); - return; + // Get incoming electron beam + const auto ei_coll = find_first_beam_electron(mcparts); + if (ei_coll.size() == 0) { + debug("No beam electron found"); + return; + } + const PxPyPzEVector ei(round_beam_four_momentum(ei_coll[0].getMomentum(), + m_particleSvc.particle(ei_coll[0].getPDG()).mass, + {-5.0, -10.0, -18.0}, 0.0)); + + // Get incoming hadron beam + const auto pi_coll = find_first_beam_hadron(mcparts); + if (pi_coll.size() == 0) { + debug("No beam hadron found"); + return; + } + const PxPyPzEVector pi(round_beam_four_momentum(pi_coll[0].getMomentum(), + m_particleSvc.particle(pi_coll[0].getPDG()).mass, + {41.0, 100.0, 275.0}, m_crossingAngle)); + + // Get first scattered electron + const auto ef_coll = find_first_scattered_electron(mcparts); + if (ef_coll.size() == 0) { + debug("No truth scattered electron found"); + return; + } + // Associate first scattered electron with reconstructed electrons + //const auto ef_assoc = std::find_if( + // rcassoc->begin(), + // rcassoc->end(), + // [&ef_coll](const auto& a){ return a.getSim().getObjectID() == ef_coll[0].getObjectID(); }); + auto ef_assoc = rcassoc->begin(); + for (; ef_assoc != rcassoc->end(); ++ef_assoc) { + if (ef_assoc->getSim().getObjectID() == ef_coll[0].getObjectID()) { + break; } - const auto ef_rc{ef_assoc->getRec()}; - const auto ef_rc_id{ef_rc.getObjectID().index}; - - // Sums in colinear frame - double pxsum = 0; - double pysum = 0; - double pzsum = 0; - double Esum = 0; - - // Get boost to colinear frame - auto boost = determine_boost(ei, pi); - - auto hfs = hadronicfinalstate->create(0., 0., 0.); - - for (const auto& p: *rcparts) { - bool isHadron = true; - // Check if it's the scattered electron - if (p.getObjectID().index != ef_rc_id) { - // Lorentz vector in lab frame - PxPyPzEVector hf_lab(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, p.getEnergy()); - // Boost to colinear frame - PxPyPzEVector hf_boosted = apply_boost(boost, hf_lab); - - pxsum += hf_boosted.Px(); - pysum += hf_boosted.Py(); - pzsum += hf_boosted.Pz(); - Esum += hf_boosted.E(); - - hfs.addToHadrons(p); - } + } + if (!(ef_assoc != rcassoc->end())) { + debug("Truth scattered electron not in reconstructed particles"); + return; + } + const auto ef_rc{ef_assoc->getRec()}; + const auto ef_rc_id{ef_rc.getObjectID().index}; + + // Sums in colinear frame + double pxsum = 0; + double pysum = 0; + double pzsum = 0; + double Esum = 0; + + // Get boost to colinear frame + auto boost = determine_boost(ei, pi); + + auto hfs = hadronicfinalstate->create(0., 0., 0.); + + for (const auto& p : *rcparts) { + bool isHadron = true; + // Check if it's the scattered electron + if (p.getObjectID().index != ef_rc_id) { + // Lorentz vector in lab frame + PxPyPzEVector hf_lab(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, p.getEnergy()); + // Boost to colinear frame + PxPyPzEVector hf_boosted = apply_boost(boost, hf_lab); + + pxsum += hf_boosted.Px(); + pysum += hf_boosted.Py(); + pzsum += hf_boosted.Pz(); + Esum += hf_boosted.E(); + + hfs.addToHadrons(p); } + } - // Hadronic final state calculations - auto sigma = Esum - pzsum; - auto pT = sqrt(pxsum*pxsum + pysum*pysum); - auto gamma = acos((pT*pT - sigma*sigma)/(pT*pT + sigma*sigma)); - - hfs.setSigma(sigma); - hfs.setPT(pT); - hfs.setGamma(gamma); - - // Sigma zero or negative - if (sigma <= 0) { - debug("Sigma zero or negative"); - return; - } + // Hadronic final state calculations + auto sigma = Esum - pzsum; + auto pT = sqrt(pxsum * pxsum + pysum * pysum); + auto gamma = acos((pT * pT - sigma * sigma) / (pT * pT + sigma * sigma)); - debug("sigma_h, pT_h, gamma_h = {},{},{}", hfs.getSigma(), hfs.getPT(), hfs.getGamma()); + hfs.setSigma(sigma); + hfs.setPT(pT); + hfs.setGamma(gamma); + // Sigma zero or negative + if (sigma <= 0) { + debug("Sigma zero or negative"); + return; } -} // namespace Jug::Reco + debug("sigma_h, pT_h, gamma_h = {},{},{}", hfs.getSigma(), hfs.getPT(), hfs.getGamma()); +} + +} // namespace eicrecon #endif diff --git a/src/algorithms/reco/InclusiveKinematicsDA.cc b/src/algorithms/reco/InclusiveKinematicsDA.cc index b2260d268c..daf56c59f2 100644 --- a/src/algorithms/reco/InclusiveKinematicsDA.cc +++ b/src/algorithms/reco/InclusiveKinematicsDA.cc @@ -23,76 +23,68 @@ using ROOT::Math::PxPyPzEVector; namespace eicrecon { - void InclusiveKinematicsDA::init() { } - - void InclusiveKinematicsDA::process( - const InclusiveKinematicsDA::Input& input, - const InclusiveKinematicsDA::Output& output) const { - - const auto [mcparts, escat, hfs] = input; - auto [kinematics] = output; - - // Get incoming electron beam - const auto ei_coll = find_first_beam_electron(mcparts); - if (ei_coll.size() == 0) { - debug("No beam electron found"); - return; - } - const PxPyPzEVector ei( - round_beam_four_momentum( - ei_coll[0].getMomentum(), - m_particleSvc.particle(ei_coll[0].getPDG()).mass, - {-5.0, -10.0, -18.0}, - 0.0) - ); - - // Get incoming hadron beam - const auto pi_coll = find_first_beam_hadron(mcparts); - if (pi_coll.size() == 0) { - debug("No beam hadron found"); - return; - } - const PxPyPzEVector pi( - round_beam_four_momentum( - pi_coll[0].getMomentum(), - m_particleSvc.particle(pi_coll[0].getPDG()).mass, - {41.0, 100.0, 275.0}, - m_crossingAngle) - ); - - // Get boost to colinear frame - auto boost = determine_boost(ei, pi); - - // Get electron angle - auto kf = escat->at(0); - PxPyPzEVector e_lab(kf.getMomentum().x, kf.getMomentum().y, kf.getMomentum().z, kf.getEnergy()); - PxPyPzEVector e_boosted = apply_boost(boost, e_lab); - auto theta_e = e_boosted.Theta(); - - // Get hadronic final state variables - auto sigma_h = hfs->at(0).getSigma(); - auto ptsum = hfs->at(0).getPT(); - auto gamma_h = hfs->at(0).getGamma(); - - // Sigma zero or negative - if (sigma_h <= 0) { - debug("Sigma zero or negative"); - return; - } - - // Calculate kinematic variables - static const auto m_proton = m_particleSvc.particle(2212).mass; - const auto y_da = tan(gamma_h/2.) / ( tan(theta_e/2.) + tan(gamma_h/2.) ); - const auto Q2_da = 4.*ei.energy()*ei.energy() * ( 1. / tan(theta_e/2.) ) * ( 1. / (tan(theta_e/2.) + tan(gamma_h/2.)) ); - const auto x_da = Q2_da / (4.*ei.energy()*pi.energy()*y_da); - const auto nu_da = Q2_da / (2.*m_proton*x_da); - const auto W_da = sqrt(m_proton*m_proton + 2*m_proton*nu_da - Q2_da); - auto kin = kinematics->create(x_da, Q2_da, W_da, y_da, nu_da); - kin.setScat(kf); - - debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), - kin.getQ2(), kin.getW(), kin.getY(), kin.getNu()); +void InclusiveKinematicsDA::init() {} + +void InclusiveKinematicsDA::process(const InclusiveKinematicsDA::Input& input, + const InclusiveKinematicsDA::Output& output) const { + + const auto [mcparts, escat, hfs] = input; + auto [kinematics] = output; + + // Get incoming electron beam + const auto ei_coll = find_first_beam_electron(mcparts); + if (ei_coll.size() == 0) { + debug("No beam electron found"); + return; + } + const PxPyPzEVector ei(round_beam_four_momentum(ei_coll[0].getMomentum(), + m_particleSvc.particle(ei_coll[0].getPDG()).mass, + {-5.0, -10.0, -18.0}, 0.0)); + + // Get incoming hadron beam + const auto pi_coll = find_first_beam_hadron(mcparts); + if (pi_coll.size() == 0) { + debug("No beam hadron found"); + return; + } + const PxPyPzEVector pi(round_beam_four_momentum(pi_coll[0].getMomentum(), + m_particleSvc.particle(pi_coll[0].getPDG()).mass, + {41.0, 100.0, 275.0}, m_crossingAngle)); + + // Get boost to colinear frame + auto boost = determine_boost(ei, pi); + + // Get electron angle + auto kf = escat->at(0); + PxPyPzEVector e_lab(kf.getMomentum().x, kf.getMomentum().y, kf.getMomentum().z, kf.getEnergy()); + PxPyPzEVector e_boosted = apply_boost(boost, e_lab); + auto theta_e = e_boosted.Theta(); + + // Get hadronic final state variables + auto sigma_h = hfs->at(0).getSigma(); + auto ptsum = hfs->at(0).getPT(); + auto gamma_h = hfs->at(0).getGamma(); + + // Sigma zero or negative + if (sigma_h <= 0) { + debug("Sigma zero or negative"); + return; } + // Calculate kinematic variables + static const auto m_proton = m_particleSvc.particle(2212).mass; + const auto y_da = tan(gamma_h / 2.) / (tan(theta_e / 2.) + tan(gamma_h / 2.)); + const auto Q2_da = 4. * ei.energy() * ei.energy() * (1. / tan(theta_e / 2.)) * + (1. / (tan(theta_e / 2.) + tan(gamma_h / 2.))); + const auto x_da = Q2_da / (4. * ei.energy() * pi.energy() * y_da); + const auto nu_da = Q2_da / (2. * m_proton * x_da); + const auto W_da = sqrt(m_proton * m_proton + 2 * m_proton * nu_da - Q2_da); + auto kin = kinematics->create(x_da, Q2_da, W_da, y_da, nu_da); + kin.setScat(kf); + + debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), kin.getQ2(), kin.getW(), kin.getY(), + kin.getNu()); } + +} // namespace eicrecon #endif diff --git a/src/algorithms/reco/InclusiveKinematicsESigma.cc b/src/algorithms/reco/InclusiveKinematicsESigma.cc index e1249172dd..e3bc0bc783 100644 --- a/src/algorithms/reco/InclusiveKinematicsESigma.cc +++ b/src/algorithms/reco/InclusiveKinematicsESigma.cc @@ -23,86 +23,78 @@ using ROOT::Math::PxPyPzEVector; namespace eicrecon { - void InclusiveKinematicsESigma::init() { } - - void InclusiveKinematicsESigma::process( - const InclusiveKinematicsESigma::Input& input, - const InclusiveKinematicsESigma::Output& output) const { - - const auto [mcparts, escat, hfs] = input; - auto [kinematics] = output; - - // Get incoming electron beam - const auto ei_coll = find_first_beam_electron(mcparts); - if (ei_coll.size() == 0) { - debug("No beam electron found"); - return; - } - const PxPyPzEVector ei( - round_beam_four_momentum( - ei_coll[0].getMomentum(), - m_particleSvc.particle(ei_coll[0].getPDG()).mass, - {-5.0, -10.0, -18.0}, - 0.0) - ); - - // Get incoming hadron beam - const auto pi_coll = find_first_beam_hadron(mcparts); - if (pi_coll.size() == 0) { - debug("No beam hadron found"); - return; - } - const PxPyPzEVector pi( - round_beam_four_momentum( - pi_coll[0].getMomentum(), - m_particleSvc.particle(pi_coll[0].getPDG()).mass, - {41.0, 100.0, 275.0}, - m_crossingAngle) - ); - - // Get boost to colinear frame - auto boost = determine_boost(ei, pi); - - // Get electron variables - auto kf = escat->at(0); - PxPyPzEVector e_lab(kf.getMomentum().x, kf.getMomentum().y, kf.getMomentum().z, kf.getEnergy()); - PxPyPzEVector e_boosted = apply_boost(boost, e_lab); - auto pt_e = e_boosted.Pt(); - auto sigma_e = e_boosted.E() - e_boosted.Pz(); - - // Get hadronic final state variables - auto sigma_h = hfs->at(0).getSigma(); - auto ptsum = hfs->at(0).getPT(); - auto gamma_h = hfs->at(0).getGamma(); - - if (sigma_h <= 0) { - debug("No scattered electron found or sigma zero or negative"); - return; - } - - auto sigma_tot = sigma_e + sigma_h; - - // Calculate kinematic variables - const auto y_e = 1. - sigma_e / (2.*ei.energy()); - const auto Q2_e = (pt_e*pt_e) / (1. - y_e); - - const auto y_sig = sigma_h / sigma_tot; - const auto Q2_sig = (pt_e*pt_e) / (1. - y_sig); - const auto x_sig = Q2_sig / (4.*ei.energy()*pi.energy()*y_sig); - - static const auto m_proton = m_particleSvc.particle(2212).mass; - const auto Q2_esig = Q2_e; - const auto x_esig = x_sig; - const auto y_esig = Q2_esig / (4.*ei.energy()*pi.energy()*x_esig); //equivalent to (2*ei.energy() / sigma_tot)*y_sig - const auto nu_esig = Q2_esig / (2.*m_proton*x_esig); - const auto W_esig = sqrt(m_proton*m_proton + 2*m_proton*nu_esig - Q2_esig); - auto kin = kinematics->create(x_esig, Q2_esig, W_esig, y_esig, nu_esig); - kin.setScat(kf); - - // Debugging output - debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), - kin.getQ2(), kin.getW(), kin.getY(), kin.getNu()); +void InclusiveKinematicsESigma::init() {} + +void InclusiveKinematicsESigma::process(const InclusiveKinematicsESigma::Input& input, + const InclusiveKinematicsESigma::Output& output) const { + + const auto [mcparts, escat, hfs] = input; + auto [kinematics] = output; + + // Get incoming electron beam + const auto ei_coll = find_first_beam_electron(mcparts); + if (ei_coll.size() == 0) { + debug("No beam electron found"); + return; + } + const PxPyPzEVector ei(round_beam_four_momentum(ei_coll[0].getMomentum(), + m_particleSvc.particle(ei_coll[0].getPDG()).mass, + {-5.0, -10.0, -18.0}, 0.0)); + + // Get incoming hadron beam + const auto pi_coll = find_first_beam_hadron(mcparts); + if (pi_coll.size() == 0) { + debug("No beam hadron found"); + return; + } + const PxPyPzEVector pi(round_beam_four_momentum(pi_coll[0].getMomentum(), + m_particleSvc.particle(pi_coll[0].getPDG()).mass, + {41.0, 100.0, 275.0}, m_crossingAngle)); + + // Get boost to colinear frame + auto boost = determine_boost(ei, pi); + + // Get electron variables + auto kf = escat->at(0); + PxPyPzEVector e_lab(kf.getMomentum().x, kf.getMomentum().y, kf.getMomentum().z, kf.getEnergy()); + PxPyPzEVector e_boosted = apply_boost(boost, e_lab); + auto pt_e = e_boosted.Pt(); + auto sigma_e = e_boosted.E() - e_boosted.Pz(); + + // Get hadronic final state variables + auto sigma_h = hfs->at(0).getSigma(); + auto ptsum = hfs->at(0).getPT(); + auto gamma_h = hfs->at(0).getGamma(); + + if (sigma_h <= 0) { + debug("No scattered electron found or sigma zero or negative"); + return; } + auto sigma_tot = sigma_e + sigma_h; + + // Calculate kinematic variables + const auto y_e = 1. - sigma_e / (2. * ei.energy()); + const auto Q2_e = (pt_e * pt_e) / (1. - y_e); + + const auto y_sig = sigma_h / sigma_tot; + const auto Q2_sig = (pt_e * pt_e) / (1. - y_sig); + const auto x_sig = Q2_sig / (4. * ei.energy() * pi.energy() * y_sig); + + static const auto m_proton = m_particleSvc.particle(2212).mass; + const auto Q2_esig = Q2_e; + const auto x_esig = x_sig; + const auto y_esig = Q2_esig / (4. * ei.energy() * pi.energy() * + x_esig); //equivalent to (2*ei.energy() / sigma_tot)*y_sig + const auto nu_esig = Q2_esig / (2. * m_proton * x_esig); + const auto W_esig = sqrt(m_proton * m_proton + 2 * m_proton * nu_esig - Q2_esig); + auto kin = kinematics->create(x_esig, Q2_esig, W_esig, y_esig, nu_esig); + kin.setScat(kf); + + // Debugging output + debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), kin.getQ2(), kin.getW(), kin.getY(), + kin.getNu()); } + +} // namespace eicrecon #endif diff --git a/src/algorithms/reco/InclusiveKinematicsElectron.cc b/src/algorithms/reco/InclusiveKinematicsElectron.cc index 79fa7f07da..311d489773 100644 --- a/src/algorithms/reco/InclusiveKinematicsElectron.cc +++ b/src/algorithms/reco/InclusiveKinematicsElectron.cc @@ -23,120 +23,111 @@ using ROOT::Math::PxPyPzEVector; namespace eicrecon { - void InclusiveKinematicsElectron::init() { } - - void InclusiveKinematicsElectron::process( - const InclusiveKinematicsElectron::Input& input, - const InclusiveKinematicsElectron::Output& output) const { - - const auto [mcparts, escat, hfs] = input; - auto [kinematics] = output; - - // 1. find_if - //const auto mc_first_electron = std::find_if( - // mcparts.begin(), - // mcparts.end(), - // [](const auto& p){ return p.getPDG() == 11; }); - - // 2a. simple loop over iterator (post-increment) - //auto mc_first_electron = mcparts.end(); - //for (auto p = mcparts.begin(); p != mcparts.end(); p++) { - // if (p.getPDG() == 11) { - // mc_first_electron = p; - // break; - // } - //} - // 2b. simple loop over iterator (pre-increment) - //auto mc_first_electron = mcparts.end(); - //for (auto p = mcparts.begin(); p != mcparts.end(); ++p) { - // if (p.getPDG() == 11) { - // mc_first_electron = p; - // break; - // } - //} - - // 3. pre-initialized simple loop - //auto mc_first_electron = mcparts.begin(); - //for (; mc_first_electron != mcparts.end(); ++mc_first_electron) { - // if (mc_first_electron.getPDG() == 11) { - // break; - // } - //} - - // 4a. iterator equality - //if (mc_first_electron == mcparts.end()) { - // debug() << "No electron found" << endmsg; - // return StatusCode::FAILURE; - //} - // 4b. iterator inequality - //if (!(mc_first_electron != mcparts.end())) { - // debug() << "No electron found" << endmsg; - // return StatusCode::FAILURE; - //} - - // 5. ranges and views - //auto is_electron = [](const auto& p){ return p.getPDG() == 11; }; - //for (const auto& e: mcparts | std::views::filter(is_electron)) { - // break; - //} - - // Get incoming electron beam - const auto ei_coll = find_first_beam_electron(mcparts); - if (ei_coll.size() == 0) { - debug("No beam electron found"); - return; - } - const PxPyPzEVector ei( - round_beam_four_momentum( - ei_coll[0].getMomentum(), - m_particleSvc.particle(ei_coll[0].getPDG()).mass, - {-5.0, -10.0, -18.0}, - 0.0) - ); - - // Get incoming hadron beam - const auto pi_coll = find_first_beam_hadron(mcparts); - if (pi_coll.size() == 0) { - debug("No beam hadron found"); - return; - } - const PxPyPzEVector pi( - round_beam_four_momentum( - pi_coll[0].getMomentum(), - m_particleSvc.particle(pi_coll[0].getPDG()).mass, - {41.0, 100.0, 275.0}, - m_crossingAngle) - ); - - // Get scattered electron - std::vector electrons; - for (const auto& p: *escat) { - electrons.emplace_back(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, p.getEnergy()); - break; - } - - // If no scattered electron was found - if (electrons.size() == 0) { - debug("No scattered electron found"); - return; - } - - // DIS kinematics calculations - static const auto m_proton = m_particleSvc.particle(2212).mass; - const auto ef = electrons.front(); - const auto q = ei - ef; - const auto q_dot_pi = q.Dot(pi); - const auto Q2 = -q.Dot(q); - const auto y = q_dot_pi / ei.Dot(pi); - const auto nu = q_dot_pi / m_proton; - const auto x = Q2 / (2. * q_dot_pi); - const auto W = sqrt(m_proton*m_proton + 2.*q_dot_pi - Q2); - auto kin = kinematics->create(x, Q2, W, y, nu); - kin.setScat(escat->at(0)); - - debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), - kin.getQ2(), kin.getW(), kin.getY(), kin.getNu()); +void InclusiveKinematicsElectron::init() {} + +void InclusiveKinematicsElectron::process(const InclusiveKinematicsElectron::Input& input, + const InclusiveKinematicsElectron::Output& output) const { + + const auto [mcparts, escat, hfs] = input; + auto [kinematics] = output; + + // 1. find_if + //const auto mc_first_electron = std::find_if( + // mcparts.begin(), + // mcparts.end(), + // [](const auto& p){ return p.getPDG() == 11; }); + + // 2a. simple loop over iterator (post-increment) + //auto mc_first_electron = mcparts.end(); + //for (auto p = mcparts.begin(); p != mcparts.end(); p++) { + // if (p.getPDG() == 11) { + // mc_first_electron = p; + // break; + // } + //} + // 2b. simple loop over iterator (pre-increment) + //auto mc_first_electron = mcparts.end(); + //for (auto p = mcparts.begin(); p != mcparts.end(); ++p) { + // if (p.getPDG() == 11) { + // mc_first_electron = p; + // break; + // } + //} + + // 3. pre-initialized simple loop + //auto mc_first_electron = mcparts.begin(); + //for (; mc_first_electron != mcparts.end(); ++mc_first_electron) { + // if (mc_first_electron.getPDG() == 11) { + // break; + // } + //} + + // 4a. iterator equality + //if (mc_first_electron == mcparts.end()) { + // debug() << "No electron found" << endmsg; + // return StatusCode::FAILURE; + //} + // 4b. iterator inequality + //if (!(mc_first_electron != mcparts.end())) { + // debug() << "No electron found" << endmsg; + // return StatusCode::FAILURE; + //} + + // 5. ranges and views + //auto is_electron = [](const auto& p){ return p.getPDG() == 11; }; + //for (const auto& e: mcparts | std::views::filter(is_electron)) { + // break; + //} + + // Get incoming electron beam + const auto ei_coll = find_first_beam_electron(mcparts); + if (ei_coll.size() == 0) { + debug("No beam electron found"); + return; + } + const PxPyPzEVector ei(round_beam_four_momentum(ei_coll[0].getMomentum(), + m_particleSvc.particle(ei_coll[0].getPDG()).mass, + {-5.0, -10.0, -18.0}, 0.0)); + + // Get incoming hadron beam + const auto pi_coll = find_first_beam_hadron(mcparts); + if (pi_coll.size() == 0) { + debug("No beam hadron found"); + return; + } + const PxPyPzEVector pi(round_beam_four_momentum(pi_coll[0].getMomentum(), + m_particleSvc.particle(pi_coll[0].getPDG()).mass, + {41.0, 100.0, 275.0}, m_crossingAngle)); + + // Get scattered electron + std::vector electrons; + for (const auto& p : *escat) { + electrons.emplace_back(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, p.getEnergy()); + break; } + // If no scattered electron was found + if (electrons.size() == 0) { + debug("No scattered electron found"); + return; + } + + // DIS kinematics calculations + static const auto m_proton = m_particleSvc.particle(2212).mass; + const auto ef = electrons.front(); + const auto q = ei - ef; + const auto q_dot_pi = q.Dot(pi); + const auto Q2 = -q.Dot(q); + const auto y = q_dot_pi / ei.Dot(pi); + const auto nu = q_dot_pi / m_proton; + const auto x = Q2 / (2. * q_dot_pi); + const auto W = sqrt(m_proton * m_proton + 2. * q_dot_pi - Q2); + auto kin = kinematics->create(x, Q2, W, y, nu); + kin.setScat(escat->at(0)); + + debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), kin.getQ2(), kin.getW(), kin.getY(), + kin.getNu()); } + +} // namespace eicrecon #endif diff --git a/src/algorithms/reco/InclusiveKinematicsJB.cc b/src/algorithms/reco/InclusiveKinematicsJB.cc index 67b80af52c..de0ef72ca7 100644 --- a/src/algorithms/reco/InclusiveKinematicsJB.cc +++ b/src/algorithms/reco/InclusiveKinematicsJB.cc @@ -20,67 +20,58 @@ using ROOT::Math::PxPyPzEVector; namespace eicrecon { - void InclusiveKinematicsJB::init() { } +void InclusiveKinematicsJB::init() {} - void InclusiveKinematicsJB::process( - const InclusiveKinematicsJB::Input& input, - const InclusiveKinematicsJB::Output& output) const { +void InclusiveKinematicsJB::process(const InclusiveKinematicsJB::Input& input, + const InclusiveKinematicsJB::Output& output) const { - const auto [mcparts, escat, hfs] = input; - auto [kinematics] = output; + const auto [mcparts, escat, hfs] = input; + auto [kinematics] = output; - // Get incoming electron beam - const auto ei_coll = find_first_beam_electron(mcparts); - if (ei_coll.size() == 0) { - debug("No beam electron found"); - return; - } - const PxPyPzEVector ei( - round_beam_four_momentum( - ei_coll[0].getMomentum(), - m_particleSvc.particle(ei_coll[0].getPDG()).mass, - {-5.0, -10.0, -18.0}, - 0.0) - ); - - // Get incoming hadron beam - const auto pi_coll = find_first_beam_hadron(mcparts); - if (pi_coll.size() == 0) { - debug("No beam hadron found"); - return; - } - const PxPyPzEVector pi( - round_beam_four_momentum( - pi_coll[0].getMomentum(), - m_particleSvc.particle(pi_coll[0].getPDG()).mass, - {41.0, 100.0, 275.0}, - m_crossingAngle) - ); - - // Get hadronic final state variables - auto sigma_h = hfs->at(0).getSigma(); - auto ptsum = hfs->at(0).getPT(); - auto gamma_h = hfs->at(0).getGamma(); + // Get incoming electron beam + const auto ei_coll = find_first_beam_electron(mcparts); + if (ei_coll.size() == 0) { + debug("No beam electron found"); + return; + } + const PxPyPzEVector ei(round_beam_four_momentum(ei_coll[0].getMomentum(), + m_particleSvc.particle(ei_coll[0].getPDG()).mass, + {-5.0, -10.0, -18.0}, 0.0)); - // Sigma zero or negative - if (sigma_h <= 0) { - debug("Sigma zero or negative"); - return; - } + // Get incoming hadron beam + const auto pi_coll = find_first_beam_hadron(mcparts); + if (pi_coll.size() == 0) { + debug("No beam hadron found"); + return; + } + const PxPyPzEVector pi(round_beam_four_momentum(pi_coll[0].getMomentum(), + m_particleSvc.particle(pi_coll[0].getPDG()).mass, + {41.0, 100.0, 275.0}, m_crossingAngle)); - // Calculate kinematic variables - static const auto m_proton = m_particleSvc.particle(2212).mass; - const auto y_jb = sigma_h / (2.*ei.energy()); - const auto Q2_jb = ptsum*ptsum / (1. - y_jb); - const auto x_jb = Q2_jb / (4.*ei.energy()*pi.energy()*y_jb); - const auto nu_jb = Q2_jb / (2.*m_proton*x_jb); - const auto W_jb = sqrt(m_proton*m_proton + 2*m_proton*nu_jb - Q2_jb); - auto kin = kinematics->create(x_jb, Q2_jb, W_jb, y_jb, nu_jb); - kin.setScat(escat->at(0)); + // Get hadronic final state variables + auto sigma_h = hfs->at(0).getSigma(); + auto ptsum = hfs->at(0).getPT(); + auto gamma_h = hfs->at(0).getGamma(); - debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), - kin.getQ2(), kin.getW(), kin.getY(), kin.getNu()); + // Sigma zero or negative + if (sigma_h <= 0) { + debug("Sigma zero or negative"); + return; } + // Calculate kinematic variables + static const auto m_proton = m_particleSvc.particle(2212).mass; + const auto y_jb = sigma_h / (2. * ei.energy()); + const auto Q2_jb = ptsum * ptsum / (1. - y_jb); + const auto x_jb = Q2_jb / (4. * ei.energy() * pi.energy() * y_jb); + const auto nu_jb = Q2_jb / (2. * m_proton * x_jb); + const auto W_jb = sqrt(m_proton * m_proton + 2 * m_proton * nu_jb - Q2_jb); + auto kin = kinematics->create(x_jb, Q2_jb, W_jb, y_jb, nu_jb); + kin.setScat(escat->at(0)); + + debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), kin.getQ2(), kin.getW(), kin.getY(), + kin.getNu()); } + +} // namespace eicrecon #endif diff --git a/src/algorithms/reco/InclusiveKinematicsSigma.cc b/src/algorithms/reco/InclusiveKinematicsSigma.cc index d6789bf2b3..6541b221a8 100644 --- a/src/algorithms/reco/InclusiveKinematicsSigma.cc +++ b/src/algorithms/reco/InclusiveKinematicsSigma.cc @@ -22,78 +22,69 @@ using ROOT::Math::PxPyPzEVector; namespace eicrecon { - void InclusiveKinematicsSigma::init() { } - - void InclusiveKinematicsSigma::process( - const InclusiveKinematicsSigma::Input& input, - const InclusiveKinematicsSigma::Output& output) const { - - const auto [mcparts, escat, hfs] = input; - auto [kinematics] = output; - - // Get incoming electron beam - const auto ei_coll = find_first_beam_electron(mcparts); - if (ei_coll.size() == 0) { - debug("No beam electron found"); - return; - } - const PxPyPzEVector ei( - round_beam_four_momentum( - ei_coll[0].getMomentum(), - m_particleSvc.particle(ei_coll[0].getPDG()).mass, - {-5.0, -10.0, -18.0}, - 0.0) - ); - - // Get incoming hadron beam - const auto pi_coll = find_first_beam_hadron(mcparts); - if (pi_coll.size() == 0) { - debug("No beam hadron found"); - return; - } - const PxPyPzEVector pi( - round_beam_four_momentum( - pi_coll[0].getMomentum(), - m_particleSvc.particle(pi_coll[0].getPDG()).mass, - {41.0, 100.0, 275.0}, - m_crossingAngle) - ); - - // Get boost to colinear frame - auto boost = determine_boost(ei, pi); - - // Get electron variables - auto kf = escat->at(0); - PxPyPzEVector e_lab(kf.getMomentum().x, kf.getMomentum().y, kf.getMomentum().z, kf.getEnergy()); - PxPyPzEVector e_boosted = apply_boost(boost, e_lab); - auto pt_e = e_boosted.Pt(); - auto sigma_e = e_boosted.E() - e_boosted.Pz(); - - // Get hadronic final state variables - auto sigma_h = hfs->at(0).getSigma(); - auto ptsum = hfs->at(0).getPT(); - auto gamma_h = hfs->at(0).getGamma(); - - if (sigma_h <= 0) { - debug("No scattered electron found or sigma zero or negative"); - return; - } - - auto sigma_tot = sigma_e + sigma_h; - - // Calculate kinematic variables - static const auto m_proton = m_particleSvc.particle(2212).mass; - const auto y_sig = sigma_h / sigma_tot; - const auto Q2_sig = (pt_e*pt_e) / (1. - y_sig); - const auto x_sig = Q2_sig / (4.*ei.energy()*pi.energy()*y_sig); - const auto nu_sig = Q2_sig / (2.*m_proton*x_sig); - const auto W_sig = sqrt(m_proton*m_proton + 2*m_proton*nu_sig - Q2_sig); - auto kin = kinematics->create(x_sig, Q2_sig, W_sig, y_sig, nu_sig); - kin.setScat(kf); - - debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), - kin.getQ2(), kin.getW(), kin.getY(), kin.getNu()); +void InclusiveKinematicsSigma::init() {} + +void InclusiveKinematicsSigma::process(const InclusiveKinematicsSigma::Input& input, + const InclusiveKinematicsSigma::Output& output) const { + + const auto [mcparts, escat, hfs] = input; + auto [kinematics] = output; + + // Get incoming electron beam + const auto ei_coll = find_first_beam_electron(mcparts); + if (ei_coll.size() == 0) { + debug("No beam electron found"); + return; + } + const PxPyPzEVector ei(round_beam_four_momentum(ei_coll[0].getMomentum(), + m_particleSvc.particle(ei_coll[0].getPDG()).mass, + {-5.0, -10.0, -18.0}, 0.0)); + + // Get incoming hadron beam + const auto pi_coll = find_first_beam_hadron(mcparts); + if (pi_coll.size() == 0) { + debug("No beam hadron found"); + return; } + const PxPyPzEVector pi(round_beam_four_momentum(pi_coll[0].getMomentum(), + m_particleSvc.particle(pi_coll[0].getPDG()).mass, + {41.0, 100.0, 275.0}, m_crossingAngle)); + + // Get boost to colinear frame + auto boost = determine_boost(ei, pi); + + // Get electron variables + auto kf = escat->at(0); + PxPyPzEVector e_lab(kf.getMomentum().x, kf.getMomentum().y, kf.getMomentum().z, kf.getEnergy()); + PxPyPzEVector e_boosted = apply_boost(boost, e_lab); + auto pt_e = e_boosted.Pt(); + auto sigma_e = e_boosted.E() - e_boosted.Pz(); + + // Get hadronic final state variables + auto sigma_h = hfs->at(0).getSigma(); + auto ptsum = hfs->at(0).getPT(); + auto gamma_h = hfs->at(0).getGamma(); + + if (sigma_h <= 0) { + debug("No scattered electron found or sigma zero or negative"); + return; + } + + auto sigma_tot = sigma_e + sigma_h; + // Calculate kinematic variables + static const auto m_proton = m_particleSvc.particle(2212).mass; + const auto y_sig = sigma_h / sigma_tot; + const auto Q2_sig = (pt_e * pt_e) / (1. - y_sig); + const auto x_sig = Q2_sig / (4. * ei.energy() * pi.energy() * y_sig); + const auto nu_sig = Q2_sig / (2. * m_proton * x_sig); + const auto W_sig = sqrt(m_proton * m_proton + 2 * m_proton * nu_sig - Q2_sig); + auto kin = kinematics->create(x_sig, Q2_sig, W_sig, y_sig, nu_sig); + kin.setScat(kf); + + debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), kin.getQ2(), kin.getW(), kin.getY(), + kin.getNu()); } + +} // namespace eicrecon #endif diff --git a/src/algorithms/reco/InclusiveKinematicsTruth.cc b/src/algorithms/reco/InclusiveKinematicsTruth.cc index d05493e832..a6daf44943 100644 --- a/src/algorithms/reco/InclusiveKinematicsTruth.cc +++ b/src/algorithms/reco/InclusiveKinematicsTruth.cc @@ -19,70 +19,69 @@ using ROOT::Math::PxPyPzEVector; namespace eicrecon { - void InclusiveKinematicsTruth::init() { } +void InclusiveKinematicsTruth::init() {} - void InclusiveKinematicsTruth::process( - const InclusiveKinematicsTruth::Input& input, - const InclusiveKinematicsTruth::Output& output) const { +void InclusiveKinematicsTruth::process(const InclusiveKinematicsTruth::Input& input, + const InclusiveKinematicsTruth::Output& output) const { - const auto [mcparts] = input; - auto [kinematics] = output; + const auto [mcparts] = input; + auto [kinematics] = output; - // Loop over generated particles to get incoming electron and proton beams - // and the scattered electron. In the presence of QED radition on the incoming - // or outgoing electron line, the vertex kinematics will be different than the - // kinematics calculated using the scattered electron as done here. - // Also need to update for CC events. + // Loop over generated particles to get incoming electron and proton beams + // and the scattered electron. In the presence of QED radition on the incoming + // or outgoing electron line, the vertex kinematics will be different than the + // kinematics calculated using the scattered electron as done here. + // Also need to update for CC events. - // Get incoming electron beam - const auto ei_coll = find_first_beam_electron(mcparts); - if (ei_coll.size() == 0) { - debug("No beam electron found"); - return; - } - const auto ei_p = ei_coll[0].getMomentum(); - const auto ei_p_mag = edm4hep::utils::magnitude(ei_p); - static const auto ei_mass = m_particleSvc.particle(11).mass; - const PxPyPzEVector ei(ei_p.x, ei_p.y, ei_p.z, std::hypot(ei_p_mag, ei_mass)); + // Get incoming electron beam + const auto ei_coll = find_first_beam_electron(mcparts); + if (ei_coll.size() == 0) { + debug("No beam electron found"); + return; + } + const auto ei_p = ei_coll[0].getMomentum(); + const auto ei_p_mag = edm4hep::utils::magnitude(ei_p); + static const auto ei_mass = m_particleSvc.particle(11).mass; + const PxPyPzEVector ei(ei_p.x, ei_p.y, ei_p.z, std::hypot(ei_p_mag, ei_mass)); - // Get incoming hadron beam - const auto pi_coll = find_first_beam_hadron(mcparts); - if (pi_coll.size() == 0) { - debug("No beam hadron found"); - return; - } - const auto pi_p = pi_coll[0].getMomentum(); - const auto pi_p_mag = edm4hep::utils::magnitude(pi_p); - const auto pi_mass = m_particleSvc.particle(pi_coll[0].getPDG()).mass; - const PxPyPzEVector pi(pi_p.x, pi_p.y, pi_p.z, std::hypot(pi_p_mag, pi_mass)); + // Get incoming hadron beam + const auto pi_coll = find_first_beam_hadron(mcparts); + if (pi_coll.size() == 0) { + debug("No beam hadron found"); + return; + } + const auto pi_p = pi_coll[0].getMomentum(); + const auto pi_p_mag = edm4hep::utils::magnitude(pi_p); + const auto pi_mass = m_particleSvc.particle(pi_coll[0].getPDG()).mass; + const PxPyPzEVector pi(pi_p.x, pi_p.y, pi_p.z, std::hypot(pi_p_mag, pi_mass)); - // Get first scattered electron - // Scattered electron. Currently taken as first status==1 electron in HEPMC record, - // which seems to be correct based on a cursory glance at the Pythia8 output. In the future, - // it may be better to trace back each final-state electron and see which one originates from - // the beam. - const auto ef_coll = find_first_scattered_electron(mcparts); - if (ef_coll.size() == 0) { - debug("No truth scattered electron found"); - return; - } - const auto ef_p = ef_coll[0].getMomentum(); - const auto ef_p_mag = edm4hep::utils::magnitude(ef_p); - static const auto ef_mass = m_particleSvc.particle(11).mass; - const PxPyPzEVector ef(ef_p.x, ef_p.y, ef_p.z, std::hypot(ef_p_mag, ef_mass)); + // Get first scattered electron + // Scattered electron. Currently taken as first status==1 electron in HEPMC record, + // which seems to be correct based on a cursory glance at the Pythia8 output. In the future, + // it may be better to trace back each final-state electron and see which one originates from + // the beam. + const auto ef_coll = find_first_scattered_electron(mcparts); + if (ef_coll.size() == 0) { + debug("No truth scattered electron found"); + return; + } + const auto ef_p = ef_coll[0].getMomentum(); + const auto ef_p_mag = edm4hep::utils::magnitude(ef_p); + static const auto ef_mass = m_particleSvc.particle(11).mass; + const PxPyPzEVector ef(ef_p.x, ef_p.y, ef_p.z, std::hypot(ef_p_mag, ef_mass)); - // DIS kinematics calculations - const auto q = ei - ef; - const auto q_dot_pi = q.Dot(pi); - const auto Q2 = -q.Dot(q); - const auto y = q_dot_pi / ei.Dot(pi); - const auto nu = q_dot_pi / pi_mass; - const auto x = Q2 / (2.*q_dot_pi); - const auto W = sqrt(pi_mass*pi_mass + 2.*q_dot_pi - Q2); - auto kin = kinematics->create(x, Q2, W, y, nu); + // DIS kinematics calculations + const auto q = ei - ef; + const auto q_dot_pi = q.Dot(pi); + const auto Q2 = -q.Dot(q); + const auto y = q_dot_pi / ei.Dot(pi); + const auto nu = q_dot_pi / pi_mass; + const auto x = Q2 / (2. * q_dot_pi); + const auto W = sqrt(pi_mass * pi_mass + 2. * q_dot_pi - Q2); + auto kin = kinematics->create(x, Q2, W, y, nu); - debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), - kin.getQ2(), kin.getW(), kin.getY(), kin.getNu()); - } + debug("x,Q2,W,y,nu = {},{},{},{},{}", kin.getX(), kin.getQ2(), kin.getW(), kin.getY(), + kin.getNu()); +} -} // namespace Jug::Reco +} // namespace eicrecon diff --git a/src/algorithms/reco/JetReconstruction.cc b/src/algorithms/reco/JetReconstruction.cc index 09dad9e089..a90fa990bb 100644 --- a/src/algorithms/reco/JetReconstruction.cc +++ b/src/algorithms/reco/JetReconstruction.cc @@ -154,7 +154,7 @@ void JetReconstruction::process( for (unsigned j = 0; j < csts.size(); j++) { jet_output.addToParticles(input_collection->at(csts[j].user_index())); } // for constituent j - } // for jet i + } // for jet i // return the jets return; diff --git a/src/algorithms/reco/JetReconstructionConfig.h b/src/algorithms/reco/JetReconstructionConfig.h index 262465a42c..b9c282338b 100644 --- a/src/algorithms/reco/JetReconstructionConfig.h +++ b/src/algorithms/reco/JetReconstructionConfig.h @@ -8,21 +8,20 @@ namespace eicrecon { - struct JetReconstructionConfig { +struct JetReconstructionConfig { - float rJet = 1.0; // jet resolution parameter - float pJet = -1.0; // exponent for generalized kt algorithms - double minCstPt = 0.2 * dd4hep::GeV; // minimum pT of objects fed to cluster sequence - double maxCstPt = 100. * dd4hep::GeV; // maximum pT of objects fed to clsuter sequence - double minJetPt = 1.0 * dd4hep::GeV; // minimum jet pT - double ghostMaxRap = 3.5; // maximum rapidity of ghosts - double ghostArea = 0.01; // area per ghost - int numGhostRepeat = 1; // number of times a ghost is reused per grid site - std::string jetAlgo = "antikt_algorithm"; // jet finding algorithm - std::string recombScheme = "E_scheme"; // particle recombination scheme - std::string areaType = "active_area"; // type of area calculated - std::string jetContribAlgo = "Centauro"; // contributed algorithm name + float rJet = 1.0; // jet resolution parameter + float pJet = -1.0; // exponent for generalized kt algorithms + double minCstPt = 0.2 * dd4hep::GeV; // minimum pT of objects fed to cluster sequence + double maxCstPt = 100. * dd4hep::GeV; // maximum pT of objects fed to clsuter sequence + double minJetPt = 1.0 * dd4hep::GeV; // minimum jet pT + double ghostMaxRap = 3.5; // maximum rapidity of ghosts + double ghostArea = 0.01; // area per ghost + int numGhostRepeat = 1; // number of times a ghost is reused per grid site + std::string jetAlgo = "antikt_algorithm"; // jet finding algorithm + std::string recombScheme = "E_scheme"; // particle recombination scheme + std::string areaType = "active_area"; // type of area calculated + std::string jetContribAlgo = "Centauro"; // contributed algorithm name +}; - }; - -} // end eicrecon namespace +} // namespace eicrecon diff --git a/src/algorithms/reco/MC2SmearedParticle.cc b/src/algorithms/reco/MC2SmearedParticle.cc index 93c85d936a..9dccc7a884 100644 --- a/src/algorithms/reco/MC2SmearedParticle.cc +++ b/src/algorithms/reco/MC2SmearedParticle.cc @@ -9,41 +9,39 @@ #include #include +void eicrecon::MC2SmearedParticle::init(std::shared_ptr logger) { m_log = logger; } -void eicrecon::MC2SmearedParticle::init(std::shared_ptr logger) { - m_log = logger; -} +std::unique_ptr +eicrecon::MC2SmearedParticle::produce(const edm4hep::MCParticleCollection* mc_particles) { + auto rec_particles = std::make_unique(); + for (const auto& mc_particle : *mc_particles) { -std::unique_ptr eicrecon::MC2SmearedParticle::produce(const edm4hep::MCParticleCollection* mc_particles) { - auto rec_particles = std::make_unique(); - for (const auto& mc_particle: *mc_particles) { - - if (mc_particle.getGeneratorStatus() != 1) { - m_log->debug("ignoring particle with generatorStatus = {}", mc_particle.getGeneratorStatus()); - continue; - } - - // make sure we keep types consistent - using MomType = decltype(edm4eic::ReconstructedParticle().getMomentum().x); - - const MomType px = mc_particle.getMomentum().x; - const MomType py = mc_particle.getMomentum().y; - const MomType pz = mc_particle.getMomentum().z; - - const MomType vx = mc_particle.getVertex().x; - const MomType vy = mc_particle.getVertex().y; - const MomType vz = mc_particle.getVertex().z; - - auto rec_part = rec_particles->create(); - rec_part.setType(mc_particle.getGeneratorStatus()); // @TODO: determine type codes - rec_part.setEnergy(mc_particle.getEnergy()); - rec_part.setMomentum({px, py, pz}); - rec_part.setReferencePoint({vx, vy, vz}); // @FIXME: probably not what we want? - rec_part.setCharge(mc_particle.getCharge()); - rec_part.setMass(mc_particle.getMass()); - rec_part.setGoodnessOfPID(1); // Perfect PID - rec_part.setCovMatrix({0, 0, 0, 0}); - rec_part.setPDG(mc_particle.getPDG()); + if (mc_particle.getGeneratorStatus() != 1) { + m_log->debug("ignoring particle with generatorStatus = {}", mc_particle.getGeneratorStatus()); + continue; } - return std::move(rec_particles); + + // make sure we keep types consistent + using MomType = decltype(edm4eic::ReconstructedParticle().getMomentum().x); + + const MomType px = mc_particle.getMomentum().x; + const MomType py = mc_particle.getMomentum().y; + const MomType pz = mc_particle.getMomentum().z; + + const MomType vx = mc_particle.getVertex().x; + const MomType vy = mc_particle.getVertex().y; + const MomType vz = mc_particle.getVertex().z; + + auto rec_part = rec_particles->create(); + rec_part.setType(mc_particle.getGeneratorStatus()); // @TODO: determine type codes + rec_part.setEnergy(mc_particle.getEnergy()); + rec_part.setMomentum({px, py, pz}); + rec_part.setReferencePoint({vx, vy, vz}); // @FIXME: probably not what we want? + rec_part.setCharge(mc_particle.getCharge()); + rec_part.setMass(mc_particle.getMass()); + rec_part.setGoodnessOfPID(1); // Perfect PID + rec_part.setCovMatrix({0, 0, 0, 0}); + rec_part.setPDG(mc_particle.getPDG()); + } + return std::move(rec_particles); } diff --git a/src/algorithms/reco/MC2SmearedParticle.h b/src/algorithms/reco/MC2SmearedParticle.h index 6b81fe0c44..217996baec 100644 --- a/src/algorithms/reco/MC2SmearedParticle.h +++ b/src/algorithms/reco/MC2SmearedParticle.h @@ -8,23 +8,22 @@ #include #include - namespace eicrecon { - /** +/** * Converts edm4hep::MCParticle to edm4eic::ReconstructedParticle */ - class MC2SmearedParticle { - public: - - /** Initialized algorithms with required data. Init function is assumed to be called once **/ - void init(std::shared_ptr logger); - - /** process function convert one data type to another **/ - std::unique_ptr produce(const edm4hep::MCParticleCollection* mc_particles); - - private: - /** algorithm logger */ - std::shared_ptr m_log; - }; -} +class MC2SmearedParticle { +public: + /** Initialized algorithms with required data. Init function is assumed to be called once **/ + void init(std::shared_ptr logger); + + /** process function convert one data type to another **/ + std::unique_ptr + produce(const edm4hep::MCParticleCollection* mc_particles); + +private: + /** algorithm logger */ + std::shared_ptr m_log; +}; +} // namespace eicrecon diff --git a/src/algorithms/reco/MatchClusters.cc b/src/algorithms/reco/MatchClusters.cc index a91752e230..c16f146ab9 100644 --- a/src/algorithms/reco/MatchClusters.cc +++ b/src/algorithms/reco/MatchClusters.cc @@ -23,162 +23,161 @@ namespace eicrecon { -void MatchClusters::process( - const MatchClusters::Input& input, - const MatchClusters::Output& output) const { - - const auto [mcparticles, inparts, inpartsassoc, clusters, clustersassoc] = input; - auto [outparts, outpartsassoc] = output; - - debug("Processing cluster info for new event"); - - debug("Step 0/2: Getting indexed list of clusters..."); - - // get an indexed map of all clusters - auto clusterMap = indexedClusters(clusters, clustersassoc); - - // 1. Loop over all tracks and link matched clusters where applicable - // (removing matched clusters from the cluster maps) - debug("Step 1/2: Matching clusters to charged particles..."); - - for (const auto inpart: *inparts) { - debug(" --> Processing charged particle {}, PDG {}, energy {}", inpart.getObjectID().index, - inpart.getPDG(), inpart.getEnergy()); - - auto outpart = inpart.clone(); - outparts->push_back(outpart); - - int mcID = -1; - - // find associated particle - for (const auto &assoc: *inpartsassoc) { - if (assoc.getRec().getObjectID() == inpart.getObjectID()) { - mcID = assoc.getSim().getObjectID().index; - break; - } - } - - trace(" --> Found particle with mcID {}", mcID); - - if (mcID < 0) { - debug(" --> cannot match track without associated mcID"); - continue; - } - - if (clusterMap.count(mcID)) { - const auto &clus = clusterMap[mcID]; - debug(" --> found matching cluster with energy: {}", clus.getEnergy()); - debug(" --> adding cluster to reconstructed particle"); - outpart.addToClusters(clus); - clusterMap.erase(mcID); - } - - // create truth associations - auto assoc = outpartsassoc->create(); - assoc.setRecID(outpart.getObjectID().index); - assoc.setSimID(mcID); - assoc.setWeight(1.0); - assoc.setRec(outpart); - assoc.setSim((*mcparticles)[mcID]); +void MatchClusters::process(const MatchClusters::Input& input, + const MatchClusters::Output& output) const { + + const auto [mcparticles, inparts, inpartsassoc, clusters, clustersassoc] = input; + auto [outparts, outpartsassoc] = output; + + debug("Processing cluster info for new event"); + + debug("Step 0/2: Getting indexed list of clusters..."); + + // get an indexed map of all clusters + auto clusterMap = indexedClusters(clusters, clustersassoc); + + // 1. Loop over all tracks and link matched clusters where applicable + // (removing matched clusters from the cluster maps) + debug("Step 1/2: Matching clusters to charged particles..."); + + for (const auto inpart : *inparts) { + debug(" --> Processing charged particle {}, PDG {}, energy {}", inpart.getObjectID().index, + inpart.getPDG(), inpart.getEnergy()); + + auto outpart = inpart.clone(); + outparts->push_back(outpart); + + int mcID = -1; + + // find associated particle + for (const auto& assoc : *inpartsassoc) { + if (assoc.getRec().getObjectID() == inpart.getObjectID()) { + mcID = assoc.getSim().getObjectID().index; + break; + } } - // 2. Now loop over all remaining clusters and add neutrals. Also add in Hcal energy - // if a matching cluster is available - debug("Step 2/2: Creating neutrals for remaining clusters..."); - for (const auto &[mcID, clus]: clusterMap) { - debug(" --> Processing unmatched cluster with energy: {}", clus.getEnergy()); - - - // get mass/PDG from mcparticles, 0 (unidentified) in case the matched particle is charged. - const auto mc = (*mcparticles)[mcID]; - const double mass = (!mc.getCharge()) ? mc.getMass() : 0; - const int32_t pdg = (!mc.getCharge()) ? mc.getPDG() : 0; - if (level() <= algorithms::LogLevel::kDebug) { - if (mc.getCharge()) { - debug(" --> associated mcparticle is not a neutral (PDG: {}), " - "setting the reconstructed particle ID to 0 (unidentified)", mc.getPDG()); - } - debug(" --> found matching associated mcparticle with PDG: {}, energy: {}", pdg, - mc.getEnergy()); - } - - // Reconstruct our neutrals and add them to the list - const auto outpart = reconstruct_neutral(&clus, mass, pdg); - debug(" --> Reconstructed neutral particle with PDG: {}, energy: {}", outpart.getPDG(), - outpart.getEnergy()); - - outparts->push_back(outpart); - - // Create truth associations - auto assoc = outpartsassoc->create(); - assoc.setRecID(outpart.getObjectID().index); - assoc.setSimID(mcID); - assoc.setWeight(1.0); - assoc.setRec(outpart); - assoc.setSim((*mcparticles)[mcID]); + trace(" --> Found particle with mcID {}", mcID); + + if (mcID < 0) { + debug(" --> cannot match track without associated mcID"); + continue; + } + + if (clusterMap.count(mcID)) { + const auto& clus = clusterMap[mcID]; + debug(" --> found matching cluster with energy: {}", clus.getEnergy()); + debug(" --> adding cluster to reconstructed particle"); + outpart.addToClusters(clus); + clusterMap.erase(mcID); + } + + // create truth associations + auto assoc = outpartsassoc->create(); + assoc.setRecID(outpart.getObjectID().index); + assoc.setSimID(mcID); + assoc.setWeight(1.0); + assoc.setRec(outpart); + assoc.setSim((*mcparticles)[mcID]); + } + + // 2. Now loop over all remaining clusters and add neutrals. Also add in Hcal energy + // if a matching cluster is available + debug("Step 2/2: Creating neutrals for remaining clusters..."); + for (const auto& [mcID, clus] : clusterMap) { + debug(" --> Processing unmatched cluster with energy: {}", clus.getEnergy()); + + // get mass/PDG from mcparticles, 0 (unidentified) in case the matched particle is charged. + const auto mc = (*mcparticles)[mcID]; + const double mass = (!mc.getCharge()) ? mc.getMass() : 0; + const int32_t pdg = (!mc.getCharge()) ? mc.getPDG() : 0; + if (level() <= algorithms::LogLevel::kDebug) { + if (mc.getCharge()) { + debug(" --> associated mcparticle is not a neutral (PDG: {}), " + "setting the reconstructed particle ID to 0 (unidentified)", + mc.getPDG()); + } + debug(" --> found matching associated mcparticle with PDG: {}, energy: {}", pdg, + mc.getEnergy()); } + + // Reconstruct our neutrals and add them to the list + const auto outpart = reconstruct_neutral(&clus, mass, pdg); + debug(" --> Reconstructed neutral particle with PDG: {}, energy: {}", outpart.getPDG(), + outpart.getEnergy()); + + outparts->push_back(outpart); + + // Create truth associations + auto assoc = outpartsassoc->create(); + assoc.setRecID(outpart.getObjectID().index); + assoc.setSimID(mcID); + assoc.setWeight(1.0); + assoc.setRec(outpart); + assoc.setSim((*mcparticles)[mcID]); + } } // get a map of mcID --> cluster // input: clusters --> all clusters std::map MatchClusters::indexedClusters( - const edm4eic::ClusterCollection* clusters, - const edm4eic::MCRecoClusterParticleAssociationCollection* associations) const { + const edm4eic::ClusterCollection* clusters, + const edm4eic::MCRecoClusterParticleAssociationCollection* associations) const { - std::map matched = {}; + std::map matched = {}; - // loop over clusters - for (const auto cluster: *clusters) { + // loop over clusters + for (const auto cluster : *clusters) { - int mcID = -1; + int mcID = -1; - // find associated particle - for (const auto assoc: *associations) { - if (assoc.getRec() == cluster) { - mcID = assoc.getSim().getObjectID().index; - break; - } - } + // find associated particle + for (const auto assoc : *associations) { + if (assoc.getRec() == cluster) { + mcID = assoc.getSim().getObjectID().index; + break; + } + } - trace(" --> Found cluster with mcID {} and energy {}", mcID, cluster.getEnergy()); + trace(" --> Found cluster with mcID {} and energy {}", mcID, cluster.getEnergy()); - if (mcID < 0) { - trace(" --> WARNING: no valid MC truth link found, skipping cluster..."); - continue; - } + if (mcID < 0) { + trace(" --> WARNING: no valid MC truth link found, skipping cluster..."); + continue; + } - const bool duplicate = matched.count(mcID); - if (duplicate) { - trace(" --> WARNING: this is a duplicate mcID, keeping the higher energy cluster"); + const bool duplicate = matched.count(mcID); + if (duplicate) { + trace(" --> WARNING: this is a duplicate mcID, keeping the higher energy cluster"); - if (cluster.getEnergy() < matched[mcID].getEnergy()) { - continue; - } - } - matched[mcID] = cluster; + if (cluster.getEnergy() < matched[mcID].getEnergy()) { + continue; + } } - return matched; + matched[mcID] = cluster; + } + return matched; } - // reconstruct a neutral cluster // (for now assuming the vertex is at (0,0,0)) -edm4eic::MutableReconstructedParticle MatchClusters::reconstruct_neutral( - const edm4eic::Cluster *cluster, const double mass, const int32_t pdg) const { - - const float energy = cluster->getEnergy(); - const float p = energy < mass ? 0 : std::sqrt(energy * energy - mass * mass); - const auto position = cluster->getPosition(); - const auto momentum = p * (position / edm4hep::utils::magnitude(position)); - // setup our particle - edm4eic::MutableReconstructedParticle part; - part.setMomentum(momentum); - part.setPDG(pdg); - part.setCharge(0); - part.setEnergy(energy); - part.setMass(mass); - part.addToClusters(*cluster); - return part; +edm4eic::MutableReconstructedParticle +MatchClusters::reconstruct_neutral(const edm4eic::Cluster* cluster, const double mass, + const int32_t pdg) const { + + const float energy = cluster->getEnergy(); + const float p = energy < mass ? 0 : std::sqrt(energy * energy - mass * mass); + const auto position = cluster->getPosition(); + const auto momentum = p * (position / edm4hep::utils::magnitude(position)); + // setup our particle + edm4eic::MutableReconstructedParticle part; + part.setMomentum(momentum); + part.setPDG(pdg); + part.setCharge(0); + part.setEnergy(energy); + part.setMass(mass); + part.addToClusters(*cluster); + return part; } } // namespace eicrecon diff --git a/src/algorithms/reco/MatchClusters.h b/src/algorithms/reco/MatchClusters.h index de35742b9d..5fab3420b8 100644 --- a/src/algorithms/reco/MatchClusters.h +++ b/src/algorithms/reco/MatchClusters.h @@ -18,55 +18,39 @@ #include #include - namespace eicrecon { - using MatchClustersAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4hep::MCParticleCollection, - edm4eic::ReconstructedParticleCollection, - edm4eic::MCRecoParticleAssociationCollection, - edm4eic::ClusterCollection, - edm4eic::MCRecoClusterParticleAssociationCollection - >, - algorithms::Output< - edm4eic::ReconstructedParticleCollection, - edm4eic::MCRecoParticleAssociationCollection - > - >; +using MatchClustersAlgorithm = algorithms::Algorithm< + algorithms::Input, + algorithms::Output>; - class MatchClusters - : public MatchClustersAlgorithm { +class MatchClusters : public MatchClustersAlgorithm { - public: - MatchClusters(std::string_view name) +public: + MatchClusters(std::string_view name) : MatchClustersAlgorithm{name, - { - "MCParticles", - "CentralTracks", "CentralTrackAssociations", - "EcalClusters", "EcalClusterAssociations" - }, - { - "ReconstructedParticles", "ReconstructedParticleAssociations" - }, - "Match tracks with clusters, and assign associations."} {} - - void init() final { }; - void process(const Input&, const Output&) const final; - - private: - // get a map of mcID --> cluster - // input: clusters --> all clusters - std::map indexedClusters( - const edm4eic::ClusterCollection* clusters, - const edm4eic::MCRecoClusterParticleAssociationCollection* associations) const; - - // reconstruct a neutral cluster - // (for now assuming the vertex is at (0,0,0)) - edm4eic::MutableReconstructedParticle reconstruct_neutral( - const edm4eic::Cluster *cluster, - const double mass, const int32_t pdg) const; - - }; + {"MCParticles", "CentralTracks", "CentralTrackAssociations", + "EcalClusters", "EcalClusterAssociations"}, + {"ReconstructedParticles", "ReconstructedParticleAssociations"}, + "Match tracks with clusters, and assign associations."} {} + + void init() final {}; + void process(const Input&, const Output&) const final; + +private: + // get a map of mcID --> cluster + // input: clusters --> all clusters + std::map + indexedClusters(const edm4eic::ClusterCollection* clusters, + const edm4eic::MCRecoClusterParticleAssociationCollection* associations) const; + + // reconstruct a neutral cluster + // (for now assuming the vertex is at (0,0,0)) + edm4eic::MutableReconstructedParticle + reconstruct_neutral(const edm4eic::Cluster* cluster, const double mass, const int32_t pdg) const; +}; } // namespace eicrecon diff --git a/src/algorithms/reco/PrimaryVertices.cc b/src/algorithms/reco/PrimaryVertices.cc index 290f991ec8..8603d04ebf 100644 --- a/src/algorithms/reco/PrimaryVertices.cc +++ b/src/algorithms/reco/PrimaryVertices.cc @@ -17,69 +17,69 @@ namespace eicrecon { - /** +/** * @brief Initialize the PrimaryVertices Algorithm * */ - void PrimaryVertices::init() { - } +void PrimaryVertices::init() {} - /** +/** * @brief Produce a list of primary vertex candidates * * @param rcvtx - input collection of all vertex candidates * @return edm4eic::VertexCollection */ - void PrimaryVertices::process(const PrimaryVertices::Input& input, - const PrimaryVertices::Output& output) const { - const auto [rcvtx] = input; - auto [out_primary_vertices] = output; +void PrimaryVertices::process(const PrimaryVertices::Input& input, + const PrimaryVertices::Output& output) const { + const auto [rcvtx] = input; + auto [out_primary_vertices] = output; - // this multimap will store intermediate results - // so that we can sort them before filling output - // collection - std::multimap> primaryVertexMap; + // this multimap will store intermediate results + // so that we can sort them before filling output + // collection + std::multimap> primaryVertexMap; - // our output collection of primary vertex - // ordered by N_trk = associatedParticle array size - out_primary_vertices->setSubsetCollection(); + // our output collection of primary vertex + // ordered by N_trk = associatedParticle array size + out_primary_vertices->setSubsetCollection(); - trace("We have {} candidate vertices", rcvtx->size()); + trace("We have {} candidate vertices", rcvtx->size()); - for (const auto& vtx: *rcvtx) { - const auto &v = vtx.getPosition(); + for (const auto& vtx : *rcvtx) { + const auto& v = vtx.getPosition(); - // some basic vertex selection - if (sqrt( v.x*v.x + v.y*v.y ) / edm4eic::unit::mm > m_cfg.maxVr || - fabs( v.z ) / edm4eic::unit::mm > m_cfg.maxVz ) - continue; + // some basic vertex selection + if (sqrt(v.x * v.x + v.y * v.y) / edm4eic::unit::mm > m_cfg.maxVr || + fabs(v.z) / edm4eic::unit::mm > m_cfg.maxVz) + continue; - if (vtx.getChi2() > m_cfg.maxChi2) continue; + if (vtx.getChi2() > m_cfg.maxChi2) + continue; - int N_trk = vtx.getAssociatedParticles().size(); - trace( "\t N_trk = {}", N_trk ); - primaryVertexMap.insert({N_trk, vtx}); - } // vertex loop + int N_trk = vtx.getAssociatedParticles().size(); + trace("\t N_trk = {}", N_trk); + primaryVertexMap.insert({N_trk, vtx}); + } // vertex loop - bool first = true; - // map defined with std::greater<> will be iterated in descending order by the key - for (auto [N_trk, vertex] : primaryVertexMap) { - // Do not save primary candidates that - // are not within range - if ( N_trk > m_cfg.maxNtrk - || N_trk < m_cfg.minNtrk ){ - continue; - } + bool first = true; + // map defined with std::greater<> will be iterated in descending order by the key + for (auto [N_trk, vertex] : primaryVertexMap) { + // Do not save primary candidates that + // are not within range + if (N_trk > m_cfg.maxNtrk || N_trk < m_cfg.minNtrk) { + continue; + } - // For logging and development - // report the highest N_trk candidate chosen - if (first) { - trace("Max N_trk Candidate:"); - trace("\t N_trk = {}", N_trk); - trace("\t Primary vertex has xyz=( {}, {}, {} )", vertex.getPosition().x, vertex.getPosition().y, vertex.getPosition().z); - first = false; - } - out_primary_vertices->push_back(vertex); - } // loop on primaryVertexMap - } + // For logging and development + // report the highest N_trk candidate chosen + if (first) { + trace("Max N_trk Candidate:"); + trace("\t N_trk = {}", N_trk); + trace("\t Primary vertex has xyz=( {}, {}, {} )", vertex.getPosition().x, + vertex.getPosition().y, vertex.getPosition().z); + first = false; + } + out_primary_vertices->push_back(vertex); + } // loop on primaryVertexMap +} } // namespace eicrecon diff --git a/src/algorithms/reco/PrimaryVertices.h b/src/algorithms/reco/PrimaryVertices.h index a6d6a2785d..d43f91ba0b 100644 --- a/src/algorithms/reco/PrimaryVertices.h +++ b/src/algorithms/reco/PrimaryVertices.h @@ -5,34 +5,31 @@ #include #include -#include // for basic_string -#include // for string_view +#include // for basic_string +#include // for string_view #include "algorithms/interfaces/WithPodConfig.h" #include "algorithms/reco/PrimaryVerticesConfig.h" - namespace eicrecon { -using PrimaryVerticesAlgorithm = algorithms::Algorithm< - algorithms::Input, - algorithms::Output>; - - class PrimaryVertices : - public PrimaryVerticesAlgorithm, - public WithPodConfig{ +using PrimaryVerticesAlgorithm = + algorithms::Algorithm, + algorithms::Output>; - public: - PrimaryVertices(std::string_view name) - : PrimaryVerticesAlgorithm{name, - {"inputVertices"}, - {"outputPrimaryVertices"}, - "Sort reconstructed vertices in PrimaryVertices collection"} {} +class PrimaryVertices : public PrimaryVerticesAlgorithm, + public WithPodConfig { - void init() final; - void process(const Input&, const Output&) const final; +public: + PrimaryVertices(std::string_view name) + : PrimaryVerticesAlgorithm{name, + {"inputVertices"}, + {"outputPrimaryVertices"}, + "Sort reconstructed vertices in PrimaryVertices collection"} {} - private: + void init() final; + void process(const Input&, const Output&) const final; - }; +private: +}; } // namespace eicrecon diff --git a/src/algorithms/reco/PrimaryVerticesConfig.h b/src/algorithms/reco/PrimaryVerticesConfig.h index c732a1e906..c229049931 100644 --- a/src/algorithms/reco/PrimaryVerticesConfig.h +++ b/src/algorithms/reco/PrimaryVerticesConfig.h @@ -8,16 +8,16 @@ namespace eicrecon { - struct PrimaryVerticesConfig { +struct PrimaryVerticesConfig { - // For now these are wide open - // In the future the cut should depend - // on the generator settings - float maxVr = 50.0; // mm - float maxVz = 500.0; // mm - float maxChi2 = 10000.0; // - int minNtrk = 1; // >= - int maxNtrk = 1000000; // <= - }; + // For now these are wide open + // In the future the cut should depend + // on the generator settings + float maxVr = 50.0; // mm + float maxVz = 500.0; // mm + float maxChi2 = 10000.0; // + int minNtrk = 1; // >= + int maxNtrk = 1000000; // <= +}; -} // end eicrecon namespace +} // namespace eicrecon diff --git a/src/algorithms/reco/ScatteredElectronsEMinusPz.cc b/src/algorithms/reco/ScatteredElectronsEMinusPz.cc index 0e0ec2bd30..ce7dc5dd2a 100644 --- a/src/algorithms/reco/ScatteredElectronsEMinusPz.cc +++ b/src/algorithms/reco/ScatteredElectronsEMinusPz.cc @@ -21,116 +21,108 @@ using ROOT::Math::PxPyPzMVector; namespace eicrecon { - /** +/** * @brief Initialize the ScatteredElectronsEMinusPz Algorithm */ - void ScatteredElectronsEMinusPz::init() { } +void ScatteredElectronsEMinusPz::init() {} - /** +/** * @brief Produce a list of scattered electron candidates * * @param rcparts - input collection of all reconstructed particles * @param rcele - input collection of all electron candidates * @return std::unique_ptr */ - void ScatteredElectronsEMinusPz::process( - const ScatteredElectronsEMinusPz::Input& input, - const ScatteredElectronsEMinusPz::Output& output - ) const { - auto [rcparts, rcele] = input; - auto [out_electrons] = output; - - static const auto m_electron = m_particleSvc.particle(11).mass; - static const auto m_pion = m_particleSvc.particle(211).mass; - - // this map will store intermediate results - // so that we can sort them before filling output - // collection - std::map> scatteredElectronsMap; - - out_electrons->setSubsetCollection(); - - trace("We have {} candidate electrons", rcele->size()); - - // Lorentz Vector for the scattered electron, - // hadronic final state, and individual hadron - // We do it here to avoid creating objects inside the loops - PxPyPzMVector vScatteredElectron; - PxPyPzMVector vHadronicFinalState; - PxPyPzMVector vHadron; - - for ( const auto& e: *rcele ) { - // Do not cut on charge to account for charge-symmetric background - - // reset the HadronicFinalState - vHadronicFinalState.SetCoordinates(0, 0, 0, 0); - - // Set a vector for the electron we are considering now - vScatteredElectron.SetCoordinates( - e.getMomentum().x, - e.getMomentum().y, - e.getMomentum().z, - m_electron +void ScatteredElectronsEMinusPz::process(const ScatteredElectronsEMinusPz::Input& input, + const ScatteredElectronsEMinusPz::Output& output) const { + auto [rcparts, rcele] = input; + auto [out_electrons] = output; + + static const auto m_electron = m_particleSvc.particle(11).mass; + static const auto m_pion = m_particleSvc.particle(211).mass; + + // this map will store intermediate results + // so that we can sort them before filling output + // collection + std::map> scatteredElectronsMap; + + out_electrons->setSubsetCollection(); + + trace("We have {} candidate electrons", rcele->size()); + + // Lorentz Vector for the scattered electron, + // hadronic final state, and individual hadron + // We do it here to avoid creating objects inside the loops + PxPyPzMVector vScatteredElectron; + PxPyPzMVector vHadronicFinalState; + PxPyPzMVector vHadron; + + for (const auto& e : *rcele) { + // Do not cut on charge to account for charge-symmetric background + + // reset the HadronicFinalState + vHadronicFinalState.SetCoordinates(0, 0, 0, 0); + + // Set a vector for the electron we are considering now + vScatteredElectron.SetCoordinates(e.getMomentum().x, e.getMomentum().y, e.getMomentum().z, + m_electron); + + // Loop over reconstructed particles to + // sum hadronic final state + for (const auto& p : *rcparts) { + // What we want is to add all reconstructed particles + // except the one we are currently considering as the + // (scattered) electron candidate. + if (p.getObjectID() != e.getObjectID()) { + vHadron.SetCoordinates(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, + m_pion // Assume pion for hadronic state ); - // Loop over reconstructed particles to - // sum hadronic final state - for (const auto& p: *rcparts) { - // What we want is to add all reconstructed particles - // except the one we are currently considering as the - // (scattered) electron candidate. - if (p.getObjectID() != e.getObjectID()) { - vHadron.SetCoordinates( - p.getMomentum().x, - p.getMomentum().y, - p.getMomentum().z, - m_pion // Assume pion for hadronic state - ); - - // Sum hadronic final state - vHadronicFinalState += vHadron; - } else { - trace("Skipping electron in hadronic final state"); - } - } // hadron loop (reconstructed particles) - - // Calculate the E-Pz for this electron - // + hadron final state combination - // For now we keep all electron - // candidates but we will rank them by their E-Pz - double EPz=(vScatteredElectron+vHadronicFinalState).E() - - (vScatteredElectron+vHadronicFinalState).Pz(); - trace("\tE-Pz={}", EPz); - trace("\tScatteredElectron has Pxyz=( {}, {}, {} )", e.getMomentum().x, e.getMomentum().y, e.getMomentum().z); - - // Store the result of this calculation - scatteredElectronsMap[ EPz ] = e; - } // electron loop - - trace("Selecting candidates with {} < E-Pz < {}", m_cfg.minEMinusPz, m_cfg.maxEMinusPz); - - bool first = true; - // map defined with std::greater<> will be iterated in descending order by the key - for (auto kv : scatteredElectronsMap) { - - double EMinusPz = kv.first; - // Do not save electron candidates that - // are not within range - if ( EMinusPz > m_cfg.maxEMinusPz - || EMinusPz < m_cfg.minEMinusPz ){ - continue; + // Sum hadronic final state + vHadronicFinalState += vHadron; + } else { + trace("Skipping electron in hadronic final state"); } - - // For logging and development - // report the highest E-Pz candidate chosen - if ( first ){ - trace("Max E-Pz Candidate:"); - trace("\tE-Pz={}", EMinusPz); - trace("\tScatteredElectron has Pxyz=( {}, {}, {} )", kv.second.getMomentum().x, kv.second.getMomentum().y, kv.second.getMomentum().z); - first = false; - } - out_electrons->push_back( kv.second ); - } // reverse loop on scatteredElectronsMap - } + } // hadron loop (reconstructed particles) + + // Calculate the E-Pz for this electron + // + hadron final state combination + // For now we keep all electron + // candidates but we will rank them by their E-Pz + double EPz = (vScatteredElectron + vHadronicFinalState).E() - + (vScatteredElectron + vHadronicFinalState).Pz(); + trace("\tE-Pz={}", EPz); + trace("\tScatteredElectron has Pxyz=( {}, {}, {} )", e.getMomentum().x, e.getMomentum().y, + e.getMomentum().z); + + // Store the result of this calculation + scatteredElectronsMap[EPz] = e; + } // electron loop + + trace("Selecting candidates with {} < E-Pz < {}", m_cfg.minEMinusPz, m_cfg.maxEMinusPz); + + bool first = true; + // map defined with std::greater<> will be iterated in descending order by the key + for (auto kv : scatteredElectronsMap) { + + double EMinusPz = kv.first; + // Do not save electron candidates that + // are not within range + if (EMinusPz > m_cfg.maxEMinusPz || EMinusPz < m_cfg.minEMinusPz) { + continue; + } + + // For logging and development + // report the highest E-Pz candidate chosen + if (first) { + trace("Max E-Pz Candidate:"); + trace("\tE-Pz={}", EMinusPz); + trace("\tScatteredElectron has Pxyz=( {}, {}, {} )", kv.second.getMomentum().x, + kv.second.getMomentum().y, kv.second.getMomentum().z); + first = false; + } + out_electrons->push_back(kv.second); + } // reverse loop on scatteredElectronsMap +} } // namespace eicrecon diff --git a/src/algorithms/reco/ScatteredElectronsEMinusPz.h b/src/algorithms/reco/ScatteredElectronsEMinusPz.h index a7680b7d9f..f473f32ed9 100644 --- a/src/algorithms/reco/ScatteredElectronsEMinusPz.h +++ b/src/algorithms/reco/ScatteredElectronsEMinusPz.h @@ -12,34 +12,27 @@ #include "algorithms/interfaces/WithPodConfig.h" #include "algorithms/reco/ScatteredElectronsEMinusPzConfig.h" - namespace eicrecon { - using ScatteredElectronsEMinusPzAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4eic::ReconstructedParticleCollection, - edm4eic::ReconstructedParticleCollection - >, - algorithms::Output< - edm4eic::ReconstructedParticleCollection - > - >; - - class ScatteredElectronsEMinusPz : public ScatteredElectronsEMinusPzAlgorithm, WithPodConfig{ +using ScatteredElectronsEMinusPzAlgorithm = + algorithms::Algorithm, + algorithms::Output>; - public: +class ScatteredElectronsEMinusPz : public ScatteredElectronsEMinusPzAlgorithm, + WithPodConfig { - ScatteredElectronsEMinusPz(std::string_view name) +public: + ScatteredElectronsEMinusPz(std::string_view name) : ScatteredElectronsEMinusPzAlgorithm{name, - {"inputParticles", "inputElectronCandidates"}, - {"outputElectrons"}, - "Outputs DIS electrons ordered in decreasing E-pz"} {} - void init() final; - void process(const Input&, const Output&) const final; - - private: - const algorithms::ParticleSvc& m_particleSvc = algorithms::ParticleSvc::instance(); - - }; + {"inputParticles", "inputElectronCandidates"}, + {"outputElectrons"}, + "Outputs DIS electrons ordered in decreasing E-pz"} {} + void init() final; + void process(const Input&, const Output&) const final; + +private: + const algorithms::ParticleSvc& m_particleSvc = algorithms::ParticleSvc::instance(); +}; } // namespace eicrecon diff --git a/src/algorithms/reco/ScatteredElectronsEMinusPzConfig.h b/src/algorithms/reco/ScatteredElectronsEMinusPzConfig.h index 58f12d2ded..f8ef3bd5e9 100644 --- a/src/algorithms/reco/ScatteredElectronsEMinusPzConfig.h +++ b/src/algorithms/reco/ScatteredElectronsEMinusPzConfig.h @@ -8,14 +8,13 @@ namespace eicrecon { - struct ScatteredElectronsEMinusPzConfig { +struct ScatteredElectronsEMinusPzConfig { - // For now these are wide open - // In the future the cut should depend - // on the generator settings - float minEMinusPz = 0.0; // GeV - float maxEMinusPz = 1000000.0; // GeV + // For now these are wide open + // In the future the cut should depend + // on the generator settings + float minEMinusPz = 0.0; // GeV + float maxEMinusPz = 1000000.0; // GeV +}; - }; - -} // end eicrecon namespace +} // namespace eicrecon diff --git a/src/algorithms/reco/ScatteredElectronsTruth.cc b/src/algorithms/reco/ScatteredElectronsTruth.cc index 733fb311ae..12220c5642 100644 --- a/src/algorithms/reco/ScatteredElectronsTruth.cc +++ b/src/algorithms/reco/ScatteredElectronsTruth.cc @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later - // Copyright (C) 2024 Daniel Brandenburg +// Copyright (C) 2024 Daniel Brandenburg #include #include @@ -22,12 +22,12 @@ using ROOT::Math::PxPyPzMVector; namespace eicrecon { - /** +/** * @brief Initialize ScatteredElectronsTruth algorithm */ - void ScatteredElectronsTruth::init() { } +void ScatteredElectronsTruth::init() {} - /** +/** * @brief Selects the scattered electron based * on TRUTH information (Mc particle info). * Returns a collection of reconstructed particles @@ -38,91 +38,86 @@ namespace eicrecon { * MCRecoParticleAssociationCollection * @param output - ReconstructedParticleCollection */ - void ScatteredElectronsTruth::process( - const ScatteredElectronsTruth::Input& input, - const ScatteredElectronsTruth::Output& output) const { - - // get our input and outputs - const auto [mcparts, rcparts, rcassoc] = input; - auto [output_electrons] = output; - output_electrons->setSubsetCollection(); - - - // Get first scattered electron - const auto ef_coll = find_first_scattered_electron(mcparts); - if (ef_coll.size() == 0) { - trace("No truth scattered electron found"); - return; +void ScatteredElectronsTruth::process(const ScatteredElectronsTruth::Input& input, + const ScatteredElectronsTruth::Output& output) const { + + // get our input and outputs + const auto [mcparts, rcparts, rcassoc] = input; + auto [output_electrons] = output; + output_electrons->setSubsetCollection(); + + // Get first scattered electron + const auto ef_coll = find_first_scattered_electron(mcparts); + if (ef_coll.size() == 0) { + trace("No truth scattered electron found"); + return; + } + + // Associate first scattered electron + // with reconstructed electron + auto ef_assoc = rcassoc->begin(); + for (; ef_assoc != rcassoc->end(); ++ef_assoc) { + if (ef_assoc->getSim().getObjectID() == ef_coll[0].getObjectID()) { + break; } - - // Associate first scattered electron - // with reconstructed electron - auto ef_assoc = rcassoc->begin(); - for (; ef_assoc != rcassoc->end(); ++ef_assoc) { - if (ef_assoc->getSim().getObjectID() == ef_coll[0].getObjectID()) { - break; - } - } - - // Check to see if the associated reconstructed - // particle is available - if (!(ef_assoc != rcassoc->end())) { - trace("Truth scattered electron not in reconstructed particles"); - return; + } + + // Check to see if the associated reconstructed + // particle is available + if (!(ef_assoc != rcassoc->end())) { + trace("Truth scattered electron not in reconstructed particles"); + return; + } + + // Get the reconstructed electron object + const auto ef_rc{ef_assoc->getRec()}; + const auto ef_rc_id{ef_rc.getObjectID()}; + + // Use these to compute the E-Pz + // This is for development of the EMinusPz + // algorithm + PxPyPzMVector vScatteredElectron; + PxPyPzMVector vHadronicFinalState; + PxPyPzMVector vHadron; + + // Loop over reconstructed particles to + // get outgoing scattered electron. + // Use the true scattered electron from the + // MC information + std::vector electrons; + for (const auto& p : *rcparts) { + if (p.getObjectID() == ef_rc_id) { + + output_electrons->push_back(p); + static const auto m_electron = m_particleSvc.particle(11).mass; + vScatteredElectron.SetCoordinates(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, + m_electron); + electrons.emplace_back(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, + p.getEnergy()); + // break; NOTE: if we are not computing E-Pz + // we can safely break here and save precious CPUs + } else { + // Compute the sum hadronic final state + static const auto m_pion = m_particleSvc.particle(211).mass; + vHadron.SetCoordinates(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, m_pion); + vHadronicFinalState += vHadron; } - - // Get the reconstructed electron object - const auto ef_rc{ef_assoc->getRec()}; - const auto ef_rc_id{ef_rc.getObjectID()}; - - // Use these to compute the E-Pz - // This is for development of the EMinusPz - // algorithm - PxPyPzMVector vScatteredElectron; - PxPyPzMVector vHadronicFinalState; - PxPyPzMVector vHadron; - - // Loop over reconstructed particles to - // get outgoing scattered electron. - // Use the true scattered electron from the - // MC information - std::vector electrons; - for (const auto& p: *rcparts) { - if (p.getObjectID() == ef_rc_id) { - - output_electrons->push_back( p ); - static const auto m_electron = m_particleSvc.particle(11).mass; - vScatteredElectron.SetCoordinates( p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, m_electron ); - electrons.emplace_back(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, p.getEnergy()); - // break; NOTE: if we are not computing E-Pz - // we can safely break here and save precious CPUs - } else { - // Compute the sum hadronic final state - static const auto m_pion = m_particleSvc.particle(211).mass; - vHadron.SetCoordinates( p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, m_pion ); - vHadronicFinalState += vHadron; - } - } - - // If no scattered electron was found, too bad - if (electrons.size() == 0) { - trace("No Truth scattered electron found"); - return; - } - - // Just for debug/development - // report the computed E-Pz for the chosen electron - double EPz = (vScatteredElectron+vHadronicFinalState).E() - - (vScatteredElectron+vHadronicFinalState).Pz(); - trace("We found {} scattered electrons using Truth association", electrons.size()); - trace( "TRUTH scattered electron has E-Pz = {}", EPz ); - trace( - "TRUTH scattered electron has Pxyz=( {}, {}, {} ) and E/p = {}", - electrons[0].Px(), - electrons[0].Py(), - electrons[0].Pz(), - (electrons[0].E()/electrons[0].P()) - ); - } // process + } + + // If no scattered electron was found, too bad + if (electrons.size() == 0) { + trace("No Truth scattered electron found"); + return; + } + + // Just for debug/development + // report the computed E-Pz for the chosen electron + double EPz = (vScatteredElectron + vHadronicFinalState).E() - + (vScatteredElectron + vHadronicFinalState).Pz(); + trace("We found {} scattered electrons using Truth association", electrons.size()); + trace("TRUTH scattered electron has E-Pz = {}", EPz); + trace("TRUTH scattered electron has Pxyz=( {}, {}, {} ) and E/p = {}", electrons[0].Px(), + electrons[0].Py(), electrons[0].Pz(), (electrons[0].E() / electrons[0].P())); +} // process } // namespace eicrecon diff --git a/src/algorithms/reco/ScatteredElectronsTruth.h b/src/algorithms/reco/ScatteredElectronsTruth.h index 33410cc289..346d3df397 100644 --- a/src/algorithms/reco/ScatteredElectronsTruth.h +++ b/src/algorithms/reco/ScatteredElectronsTruth.h @@ -14,33 +14,26 @@ namespace eicrecon { - using ScatteredElectronsTruthAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4hep::MCParticleCollection, - edm4eic::ReconstructedParticleCollection, - edm4eic::MCRecoParticleAssociationCollection - >, - algorithms::Output< - edm4eic::ReconstructedParticleCollection - > - >; - - class ScatteredElectronsTruth - : public ScatteredElectronsTruthAlgorithm { - - public: - ScatteredElectronsTruth(std::string_view name) - : ScatteredElectronsTruthAlgorithm{name, - {"MCParticles", "inputParticles", "inputAssociations"}, - {"ReconstructedParticles"}, - "Output a list of possible scattered electrons using truth MC Particle associations."} {} +using ScatteredElectronsTruthAlgorithm = algorithms::Algorithm< + algorithms::Input, + algorithms::Output>; + +class ScatteredElectronsTruth : public ScatteredElectronsTruthAlgorithm { - void init() final; - void process(const Input&, const Output&) const final; +public: + ScatteredElectronsTruth(std::string_view name) + : ScatteredElectronsTruthAlgorithm{name, + {"MCParticles", "inputParticles", "inputAssociations"}, + {"ReconstructedParticles"}, + "Output a list of possible scattered electrons using " + "truth MC Particle associations."} {} - private: - const algorithms::ParticleSvc& m_particleSvc = algorithms::ParticleSvc::instance(); + void init() final; + void process(const Input&, const Output&) const final; - }; +private: + const algorithms::ParticleSvc& m_particleSvc = algorithms::ParticleSvc::instance(); +}; } // namespace eicrecon diff --git a/src/algorithms/reco/TransformBreitFrame.cc b/src/algorithms/reco/TransformBreitFrame.cc index 6cf37b46e1..c140711e9a 100644 --- a/src/algorithms/reco/TransformBreitFrame.cc +++ b/src/algorithms/reco/TransformBreitFrame.cc @@ -20,130 +20,122 @@ namespace eicrecon { - void TransformBreitFrame::process( - const TransformBreitFrame::Input& input, - const TransformBreitFrame::Output& output - ) const { - // Grab input collections - const auto [mcpart, kine, lab_collection] = input; - auto [breit_collection] = output; - - // Beam momenta extracted from MCParticle - // This is the only place truth information is used! - - // Get incoming electron beam - const auto ei_coll = find_first_beam_electron(mcpart); - if (ei_coll.size() == 0) { - debug("No beam electron found"); - return; - } - const PxPyPzEVector e_initial( - round_beam_four_momentum( - ei_coll[0].getMomentum(), - m_particleSvc.particle(ei_coll[0].getPDG()).mass, - {-5.0, -10.0, -18.0}, - 0.0) - ); - - // Get incoming hadron beam - const auto pi_coll = find_first_beam_hadron(mcpart); - if (pi_coll.size() == 0) { - debug("No beam hadron found"); - return; - } - const PxPyPzEVector p_initial( - round_beam_four_momentum( - pi_coll[0].getMomentum(), - m_particleSvc.particle(pi_coll[0].getPDG()).mass, - {41.0, 100.0, 275.0}, - m_crossingAngle) - ); - - debug("electron energy, proton energy = {},{}",e_initial.E(),p_initial.E()); - - // Get the event kinematics, set up transform - if (kine->size() == 0) { - debug("No kinematics found"); - return; - } - - const auto& evt_kin = kine->at(0); - - const auto meas_x = evt_kin.getX(); - const auto meas_Q2 = evt_kin.getQ2(); - - // Use relation to get reconstructed scattered electron - const PxPyPzEVector e_final = edm4hep::utils::detail::p4(evt_kin.getScat(),&edm4hep::utils::UseEnergy); - debug("scattered electron in lab frame px,py,pz,E = {},{},{},{}", - e_final.Px(),e_final.Py(),e_final.Pz(),e_final.E()); - - // Set up the transformation - const PxPyPzEVector virtual_photon = (e_initial - e_final); - debug("virtual photon in lab frame px,py,pz,E = {},{},{},{}", - virtual_photon.Px(),virtual_photon.Py(),virtual_photon.Pz(),virtual_photon.E()); - - debug("x, Q^2 = {},{}",meas_x,meas_Q2); - - // Set up the transformation (boost) to the Breit frame - const auto P3 = p_initial.Vect(); - const auto q3 = virtual_photon.Vect(); - const ROOT::Math::Boost breit(-(2.0*meas_x*P3 + q3)*(1.0/(2.0*meas_x*p_initial.E() + virtual_photon.E()))); - - PxPyPzEVector p_initial_breit = (breit * p_initial); - PxPyPzEVector e_initial_breit = (breit * e_initial); - PxPyPzEVector e_final_breit = (breit * e_final); - PxPyPzEVector virtual_photon_breit = (breit * virtual_photon); - - // Now rotate so the virtual photon momentum is all along the negative z-axis - const auto zhat = -virtual_photon_breit.Vect().Unit(); - const auto yhat = (e_initial_breit.Vect().Cross(e_final_breit.Vect())).Unit(); - const auto xhat = yhat.Cross(zhat); - - const ROOT::Math::Rotation3D breitRotInv(xhat,yhat,zhat); - const ROOT::Math::Rotation3D breitRot = breitRotInv.Inverse(); - - // Diagnostics - p_initial_breit = breitRot*p_initial_breit; - e_initial_breit = breitRot*e_initial_breit; - e_final_breit = breitRot*e_final_breit; - virtual_photon_breit = breitRot*virtual_photon_breit; - - debug("incoming hadron in Breit frame px,py,pz,E = {},{},{},{}", - p_initial_breit.Px(),p_initial_breit.Py(),p_initial_breit.Pz(),p_initial_breit.E()); - debug("virtual photon in Breit frame px,py,pz,E = {},{},{},{}", - virtual_photon_breit.Px(),virtual_photon_breit.Py(),virtual_photon_breit.Pz(),virtual_photon_breit.E()); - - // look over the input particles and transform - for (const auto& lab : *lab_collection) { - - // Transform to Breit frame - PxPyPzEVector lab_particle(lab.getMomentum().x,lab.getMomentum().y,lab.getMomentum().z,lab.getEnergy()); - PxPyPzEVector breit_particle = breitRot*(breit*lab_particle); - - // create particle to store in output collection - auto breit_out = breit_collection->create(); - breit_out.setMomentum(edm4hep::Vector3f(breit_particle.Px(), breit_particle.Py(), breit_particle.Pz())); - breit_out.setEnergy(breit_particle.E()); - - // Copy the rest of the particle information - breit_out.setType(lab.getType()); - breit_out.setReferencePoint(lab.getReferencePoint()); - breit_out.setCharge(lab.getCharge()); - breit_out.setMass(lab.getMass()); - breit_out.setGoodnessOfPID(lab.getGoodnessOfPID()); - breit_out.setCovMatrix(lab.getCovMatrix()); - breit_out.setPDG(lab.getPDG()); - breit_out.setStartVertex(lab.getStartVertex()); - breit_out.setParticleIDUsed(lab.getParticleIDUsed()); - - // set up a relation between the lab and Breit frame representations - breit_out.addToParticles( lab ); - - } - +void TransformBreitFrame::process(const TransformBreitFrame::Input& input, + const TransformBreitFrame::Output& output) const { + // Grab input collections + const auto [mcpart, kine, lab_collection] = input; + auto [breit_collection] = output; + + // Beam momenta extracted from MCParticle + // This is the only place truth information is used! + + // Get incoming electron beam + const auto ei_coll = find_first_beam_electron(mcpart); + if (ei_coll.size() == 0) { + debug("No beam electron found"); return; + } + const PxPyPzEVector e_initial(round_beam_four_momentum( + ei_coll[0].getMomentum(), m_particleSvc.particle(ei_coll[0].getPDG()).mass, + {-5.0, -10.0, -18.0}, 0.0)); + + // Get incoming hadron beam + const auto pi_coll = find_first_beam_hadron(mcpart); + if (pi_coll.size() == 0) { + debug("No beam hadron found"); + return; + } + const PxPyPzEVector p_initial(round_beam_four_momentum( + pi_coll[0].getMomentum(), m_particleSvc.particle(pi_coll[0].getPDG()).mass, + {41.0, 100.0, 275.0}, m_crossingAngle)); - } // end 'process' - + debug("electron energy, proton energy = {},{}", e_initial.E(), p_initial.E()); -} // end namespace eicrecon + // Get the event kinematics, set up transform + if (kine->size() == 0) { + debug("No kinematics found"); + return; + } + + const auto& evt_kin = kine->at(0); + + const auto meas_x = evt_kin.getX(); + const auto meas_Q2 = evt_kin.getQ2(); + + // Use relation to get reconstructed scattered electron + const PxPyPzEVector e_final = + edm4hep::utils::detail::p4(evt_kin.getScat(), &edm4hep::utils::UseEnergy); + debug("scattered electron in lab frame px,py,pz,E = {},{},{},{}", e_final.Px(), e_final.Py(), + e_final.Pz(), e_final.E()); + + // Set up the transformation + const PxPyPzEVector virtual_photon = (e_initial - e_final); + debug("virtual photon in lab frame px,py,pz,E = {},{},{},{}", virtual_photon.Px(), + virtual_photon.Py(), virtual_photon.Pz(), virtual_photon.E()); + + debug("x, Q^2 = {},{}", meas_x, meas_Q2); + + // Set up the transformation (boost) to the Breit frame + const auto P3 = p_initial.Vect(); + const auto q3 = virtual_photon.Vect(); + const ROOT::Math::Boost breit(-(2.0 * meas_x * P3 + q3) * + (1.0 / (2.0 * meas_x * p_initial.E() + virtual_photon.E()))); + + PxPyPzEVector p_initial_breit = (breit * p_initial); + PxPyPzEVector e_initial_breit = (breit * e_initial); + PxPyPzEVector e_final_breit = (breit * e_final); + PxPyPzEVector virtual_photon_breit = (breit * virtual_photon); + + // Now rotate so the virtual photon momentum is all along the negative z-axis + const auto zhat = -virtual_photon_breit.Vect().Unit(); + const auto yhat = (e_initial_breit.Vect().Cross(e_final_breit.Vect())).Unit(); + const auto xhat = yhat.Cross(zhat); + + const ROOT::Math::Rotation3D breitRotInv(xhat, yhat, zhat); + const ROOT::Math::Rotation3D breitRot = breitRotInv.Inverse(); + + // Diagnostics + p_initial_breit = breitRot * p_initial_breit; + e_initial_breit = breitRot * e_initial_breit; + e_final_breit = breitRot * e_final_breit; + virtual_photon_breit = breitRot * virtual_photon_breit; + + debug("incoming hadron in Breit frame px,py,pz,E = {},{},{},{}", p_initial_breit.Px(), + p_initial_breit.Py(), p_initial_breit.Pz(), p_initial_breit.E()); + debug("virtual photon in Breit frame px,py,pz,E = {},{},{},{}", virtual_photon_breit.Px(), + virtual_photon_breit.Py(), virtual_photon_breit.Pz(), virtual_photon_breit.E()); + + // look over the input particles and transform + for (const auto& lab : *lab_collection) { + + // Transform to Breit frame + PxPyPzEVector lab_particle(lab.getMomentum().x, lab.getMomentum().y, lab.getMomentum().z, + lab.getEnergy()); + PxPyPzEVector breit_particle = breitRot * (breit * lab_particle); + + // create particle to store in output collection + auto breit_out = breit_collection->create(); + breit_out.setMomentum( + edm4hep::Vector3f(breit_particle.Px(), breit_particle.Py(), breit_particle.Pz())); + breit_out.setEnergy(breit_particle.E()); + + // Copy the rest of the particle information + breit_out.setType(lab.getType()); + breit_out.setReferencePoint(lab.getReferencePoint()); + breit_out.setCharge(lab.getCharge()); + breit_out.setMass(lab.getMass()); + breit_out.setGoodnessOfPID(lab.getGoodnessOfPID()); + breit_out.setCovMatrix(lab.getCovMatrix()); + breit_out.setPDG(lab.getPDG()); + breit_out.setStartVertex(lab.getStartVertex()); + breit_out.setParticleIDUsed(lab.getParticleIDUsed()); + + // set up a relation between the lab and Breit frame representations + breit_out.addToParticles(lab); + } + + return; + +} // end 'process' + +} // end namespace eicrecon diff --git a/src/algorithms/reco/TransformBreitFrame.h b/src/algorithms/reco/TransformBreitFrame.h index 26ab2d06f7..ef627e7024 100644 --- a/src/algorithms/reco/TransformBreitFrame.h +++ b/src/algorithms/reco/TransformBreitFrame.h @@ -31,7 +31,7 @@ class TransformBreitFrame : public TransformBreitFrameAlgorithm, public WithPodC "Transforms a set of particles from the lab frame to the Breit frame"} {} // algorithm initialization - void init() final{}; + void init() final {}; // run algorithm void process(const Input&, const Output&) const final; diff --git a/src/algorithms/reco/UndoAfterBurner.cc b/src/algorithms/reco/UndoAfterBurner.cc index 1be31d0e22..61eb2ee547 100644 --- a/src/algorithms/reco/UndoAfterBurner.cc +++ b/src/algorithms/reco/UndoAfterBurner.cc @@ -18,128 +18,131 @@ #include "algorithms/reco/Beam.h" #include "algorithms/reco/UndoAfterBurnerConfig.h" -void eicrecon::UndoAfterBurner::init() { - -} - -void eicrecon::UndoAfterBurner::process( - const UndoAfterBurner::Input& input, - const UndoAfterBurner::Output& output) const { - - const auto [mcparts] = input; - auto [outputParticles] = output; - - bool pidAssumePionMass = m_cfg.m_pid_assume_pion_mass; - double crossingAngle = m_cfg.m_crossing_angle; - double pidPurity = m_cfg.m_pid_purity; - bool correctBeamFX = m_cfg.m_correct_beam_FX; - bool pidUseMCTruth = m_cfg.m_pid_use_MC_truth; - - bool hasBeamHadron = true; - bool hasBeamLepton = true; - - //read MCParticles information and "postburn" to remove the afterburner effects. - //The output is then the original MC input produced by the generator. - - ROOT::Math::PxPyPzEVector e_beam(0.,0.,0.,0.); - ROOT::Math::PxPyPzEVector h_beam(0.,0.,0.,0.); - - auto incoming_lepton = find_first_beam_electron(mcparts); - if (incoming_lepton.size() == 0) { - debug("No beam electron found -- particleGun input"); - hasBeamLepton = false; +void eicrecon::UndoAfterBurner::init() {} + +void eicrecon::UndoAfterBurner::process(const UndoAfterBurner::Input& input, + const UndoAfterBurner::Output& output) const { + + const auto [mcparts] = input; + auto [outputParticles] = output; + + bool pidAssumePionMass = m_cfg.m_pid_assume_pion_mass; + double crossingAngle = m_cfg.m_crossing_angle; + double pidPurity = m_cfg.m_pid_purity; + bool correctBeamFX = m_cfg.m_correct_beam_FX; + bool pidUseMCTruth = m_cfg.m_pid_use_MC_truth; + + bool hasBeamHadron = true; + bool hasBeamLepton = true; + + //read MCParticles information and "postburn" to remove the afterburner effects. + //The output is then the original MC input produced by the generator. + + ROOT::Math::PxPyPzEVector e_beam(0., 0., 0., 0.); + ROOT::Math::PxPyPzEVector h_beam(0., 0., 0., 0.); + + auto incoming_lepton = find_first_beam_electron(mcparts); + if (incoming_lepton.size() == 0) { + debug("No beam electron found -- particleGun input"); + hasBeamLepton = false; + } + + auto incoming_hadron = find_first_beam_hadron(mcparts); + if (incoming_hadron.size() == 0) { + debug("No beam hadron found -- particleGun input"); + hasBeamHadron = false; + } + + if ((hasBeamHadron && !hasBeamLepton) || (!hasBeamHadron && hasBeamLepton)) { + debug("Only one beam defined! Not a possible configuration!"); + return; + } + + // Handling for FF particle gun input!! + if (!hasBeamHadron || !hasBeamLepton) { + for (const auto& p : *mcparts) { + if ((p.getPDG() == 2212 || p.getPDG() == 2112)) { //look for "gun" proton/neutron + hasBeamHadron = true; + h_beam.SetPxPyPzE(crossingAngle * p.getEnergy(), 0.0, p.getEnergy(), p.getEnergy()); + if (p.getEnergy() > 270.0 && p.getEnergy() < 280.0) { + hasBeamLepton = true; + e_beam.SetPxPyPzE(0.0, 0.0, -18.0, 18.0); + } + } } - auto incoming_hadron = find_first_beam_hadron(mcparts); - if (incoming_hadron.size() == 0) { - debug("No beam hadron found -- particleGun input"); - hasBeamHadron = false; - } + } else { - if((hasBeamHadron && !hasBeamLepton) || (!hasBeamHadron && hasBeamLepton)){ - debug("Only one beam defined! Not a possible configuration!"); - return; - } + if (correctBeamFX) { - // Handling for FF particle gun input!! - if (!hasBeamHadron || !hasBeamLepton) { - for (const auto& p: *mcparts) { - if((p.getPDG() == 2212 || p.getPDG() == 2112)) { //look for "gun" proton/neutron - hasBeamHadron = true; - h_beam.SetPxPyPzE(crossingAngle*p.getEnergy(), 0.0, p.getEnergy(), p.getEnergy()); - if(p.getEnergy() > 270.0 && p.getEnergy() < 280.0){ - hasBeamLepton = true; - e_beam.SetPxPyPzE(0.0, 0.0, -18.0, 18.0); - } - } - } + h_beam.SetPxPyPzE(incoming_hadron[0].getMomentum().x, incoming_hadron[0].getMomentum().y, + incoming_hadron[0].getMomentum().z, incoming_hadron[0].getEnergy()); + e_beam.SetPxPyPzE(incoming_lepton[0].getMomentum().x, incoming_lepton[0].getMomentum().y, + incoming_lepton[0].getMomentum().z, incoming_lepton[0].getEnergy()); } else { - if (correctBeamFX) { - - h_beam.SetPxPyPzE(incoming_hadron[0].getMomentum().x, incoming_hadron[0].getMomentum().y, incoming_hadron[0].getMomentum().z, incoming_hadron[0].getEnergy()); - e_beam.SetPxPyPzE(incoming_lepton[0].getMomentum().x, incoming_lepton[0].getMomentum().y, incoming_lepton[0].getMomentum().z, incoming_lepton[0].getEnergy()); - - } else { - - h_beam.SetPxPyPzE(crossingAngle*incoming_hadron[0].getEnergy(), 0.0, incoming_hadron[0].getEnergy(), incoming_hadron[0].getEnergy()); - e_beam.SetPxPyPzE(0.0, 0.0, -incoming_lepton[0].getEnergy(), incoming_lepton[0].getEnergy()); - - } + h_beam.SetPxPyPzE(crossingAngle * incoming_hadron[0].getEnergy(), 0.0, + incoming_hadron[0].getEnergy(), incoming_hadron[0].getEnergy()); + e_beam.SetPxPyPzE(0.0, 0.0, -incoming_lepton[0].getEnergy(), incoming_lepton[0].getEnergy()); } - - // Bail out if still no beam particles, since this leads to division by zero - if (!hasBeamHadron && !hasBeamLepton) { - return; + } + + // Bail out if still no beam particles, since this leads to division by zero + if (!hasBeamHadron && !hasBeamLepton) { + return; + } + + // Calculate boost vectors and rotations here + ROOT::Math::PxPyPzEVector cm_frame_boost = e_beam + h_beam; + ROOT::Math::Cartesian3D beta(-cm_frame_boost.Px() / cm_frame_boost.E(), + -cm_frame_boost.Py() / cm_frame_boost.E(), + -cm_frame_boost.Pz() / cm_frame_boost.E()); + ROOT::Math::Boost boostVector(beta); + + // Boost to CM frame + e_beam = boostVector(e_beam); + h_beam = boostVector(h_beam); + + double rotationAngleY = -1.0 * TMath::ATan2(h_beam.Px(), h_beam.Pz()); + double rotationAngleX = 1.0 * TMath::ATan2(h_beam.Py(), h_beam.Pz()); + + ROOT::Math::RotationY rotationAboutY(rotationAngleY); + ROOT::Math::RotationX rotationAboutX(rotationAngleX); + + // Boost back to proper head-on frame + ROOT::Math::PxPyPzEVector head_on_frame_boost(0., 0., cm_frame_boost.Pz(), cm_frame_boost.E()); + ROOT::Math::Boost headOnBoostVector(head_on_frame_boost.Px() / head_on_frame_boost.E(), + head_on_frame_boost.Py() / head_on_frame_boost.E(), + head_on_frame_boost.Pz() / head_on_frame_boost.E()); + + // Now, loop through events and apply operations to the MCparticles + for (const auto& p : *mcparts) { + if (p.isCreatedInSimulation()) { + continue; } - // Calculate boost vectors and rotations here - ROOT::Math::PxPyPzEVector cm_frame_boost = e_beam + h_beam; - ROOT::Math::Cartesian3D beta(-cm_frame_boost.Px() / cm_frame_boost.E(), -cm_frame_boost.Py() / cm_frame_boost.E(), -cm_frame_boost.Pz() / cm_frame_boost.E()); - ROOT::Math::Boost boostVector(beta); + ROOT::Math::PxPyPzEVector mc(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, + p.getEnergy()); - // Boost to CM frame - e_beam = boostVector(e_beam); - h_beam = boostVector(h_beam); + mc = boostVector(mc); + mc = rotationAboutY(mc); + mc = rotationAboutX(mc); + mc = headOnBoostVector(mc); - double rotationAngleY = -1.0*TMath::ATan2(h_beam.Px(), h_beam.Pz()); - double rotationAngleX = 1.0*TMath::ATan2(h_beam.Py(), h_beam.Pz()); - - ROOT::Math::RotationY rotationAboutY(rotationAngleY); - ROOT::Math::RotationX rotationAboutX(rotationAngleX); - - // Boost back to proper head-on frame - ROOT::Math::PxPyPzEVector head_on_frame_boost(0., 0., cm_frame_boost.Pz(), cm_frame_boost.E()); - ROOT::Math::Boost headOnBoostVector(head_on_frame_boost.Px()/head_on_frame_boost.E(), head_on_frame_boost.Py()/head_on_frame_boost.E(), head_on_frame_boost.Pz()/head_on_frame_boost.E()); - - // Now, loop through events and apply operations to the MCparticles - for (const auto& p: *mcparts) { - if (p.isCreatedInSimulation()) { - continue; - } + decltype(edm4hep::MCParticleData::momentum) mcMom(mc.Px(), mc.Py(), mc.Pz()); + edm4hep::MutableMCParticle MCTrack(p.clone()); + MCTrack.setMomentum(mcMom); - ROOT::Math::PxPyPzEVector mc(p.getMomentum().x, p.getMomentum().y, p.getMomentum().z, p.getEnergy()); - - mc = boostVector(mc); - mc = rotationAboutY(mc); - mc = rotationAboutX(mc); - mc = headOnBoostVector(mc); - - decltype(edm4hep::MCParticleData::momentum) mcMom(mc.Px(), mc.Py(), mc.Pz()); - edm4hep::MutableMCParticle MCTrack(p.clone()); - MCTrack.setMomentum(mcMom); - - if(pidUseMCTruth){ - MCTrack.setPDG(p.getPDG()); - MCTrack.setMass(p.getMass()); - } - if(!pidUseMCTruth && pidAssumePionMass){ - MCTrack.setPDG(211); - MCTrack.setMass(0.13957); - } - - outputParticles->push_back(MCTrack); + if (pidUseMCTruth) { + MCTrack.setPDG(p.getPDG()); + MCTrack.setMass(p.getMass()); + } + if (!pidUseMCTruth && pidAssumePionMass) { + MCTrack.setPDG(211); + MCTrack.setMass(0.13957); } + outputParticles->push_back(MCTrack); + } } diff --git a/src/algorithms/reco/UndoAfterBurner.h b/src/algorithms/reco/UndoAfterBurner.h index 57866520f0..9b9105a62a 100644 --- a/src/algorithms/reco/UndoAfterBurner.h +++ b/src/algorithms/reco/UndoAfterBurner.h @@ -12,31 +12,24 @@ namespace eicrecon { - using UndoAfterBurnerAlgorithm = algorithms::Algorithm< - algorithms::Input< - edm4hep::MCParticleCollection - >, - algorithms::Output< - edm4hep::MCParticleCollection - > - >; - - class UndoAfterBurner - : public UndoAfterBurnerAlgorithm, - public WithPodConfig { - - public: - UndoAfterBurner(std::string_view name) - : UndoAfterBurnerAlgorithm{name, - {"inputMCParticles"}, - {"outputMCParticles"}, - "Apply boosts and rotations to remove crossing angle and beam effects."} {} - - void init(); - void process(const Input&, const Output&) const final; - - private: - - - }; -} +using UndoAfterBurnerAlgorithm = + algorithms::Algorithm, + algorithms::Output>; + +class UndoAfterBurner : public UndoAfterBurnerAlgorithm, + public WithPodConfig { + +public: + UndoAfterBurner(std::string_view name) + : UndoAfterBurnerAlgorithm{ + name, + {"inputMCParticles"}, + {"outputMCParticles"}, + "Apply boosts and rotations to remove crossing angle and beam effects."} {} + + void init(); + void process(const Input&, const Output&) const final; + +private: +}; +} // namespace eicrecon diff --git a/src/algorithms/reco/UndoAfterBurnerConfig.h b/src/algorithms/reco/UndoAfterBurnerConfig.h index 1c331a5a45..fbed4f4c5e 100644 --- a/src/algorithms/reco/UndoAfterBurnerConfig.h +++ b/src/algorithms/reco/UndoAfterBurnerConfig.h @@ -6,14 +6,13 @@ namespace eicrecon { - struct UndoAfterBurnerConfig { +struct UndoAfterBurnerConfig { - bool m_pid_assume_pion_mass = false; - double m_crossing_angle = -0.025; - double m_pid_purity = 0.51; - bool m_correct_beam_FX = true; - bool m_pid_use_MC_truth = true; + bool m_pid_assume_pion_mass = false; + double m_crossing_angle = -0.025; + double m_pid_purity = 0.51; + bool m_correct_beam_FX = true; + bool m_pid_use_MC_truth = true; +}; - }; - -} +} // namespace eicrecon diff --git a/src/algorithms/tracking/ActsGeometryProvider.cc b/src/algorithms/tracking/ActsGeometryProvider.cc index bc54725632..a1867fa3c7 100644 --- a/src/algorithms/tracking/ActsGeometryProvider.cc +++ b/src/algorithms/tracking/ActsGeometryProvider.cc @@ -36,162 +36,143 @@ #include template -struct fmt::formatter< - T, - std::enable_if_t< - std::is_base_of_v, T>, - char - > -> : fmt::ostream_formatter {}; +struct fmt::formatter, T>, char>> + : fmt::ostream_formatter {}; #endif // FMT_VERSION >= 90000 -void ActsGeometryProvider::initialize(const dd4hep::Detector* dd4hep_geo, - std::string material_file, +void ActsGeometryProvider::initialize(const dd4hep::Detector* dd4hep_geo, std::string material_file, std::shared_ptr log, std::shared_ptr init_log) { - // LOGGING - m_log = log; - m_init_log = init_log; - - m_init_log->debug("ActsGeometryProvider initializing..."); - - m_init_log->debug("Set TGeoManager and acts_init_log_level log levels"); - // Turn off TGeo printouts if appropriate for the msg level - if (m_log->level() >= (int) spdlog::level::info) { - TGeoManager::SetVerboseLevel(0); - } - - // Set ACTS logging level - auto acts_init_log_level = eicrecon::SpdlogToActsLevel(m_init_log->level()); - - m_dd4hepDetector = dd4hep_geo; - - // Load ACTS materials maps - std::shared_ptr materialDeco{nullptr}; - if (!material_file.empty()) { - m_init_log->info("loading materials map from file: '{}'", material_file); - // Set up the converter first - Acts::MaterialMapJsonConverter::Config jsonGeoConvConfig; - // Set up the json-based decorator - materialDeco = std::make_shared(jsonGeoConvConfig, material_file, acts_init_log_level); - } - - // Geometry identifier hook to write detector ID to extra field - class ConvertDD4hepDetectorGeometryIdentifierHook: public Acts::GeometryIdentifierHook { - Acts::GeometryIdentifier decorateIdentifier( - Acts::GeometryIdentifier identifier, const Acts::Surface& surface) const { - const auto* dd4hep_det_element = - dynamic_cast(surface.associatedDetectorElement()); - if (dd4hep_det_element == nullptr) { - return identifier; - } - // set 8-bit extra field to 8-bit DD4hep detector ID - return identifier.setExtra(0xff & dd4hep_det_element->identifier()); - }; + // LOGGING + m_log = log; + m_init_log = init_log; + + m_init_log->debug("ActsGeometryProvider initializing..."); + + m_init_log->debug("Set TGeoManager and acts_init_log_level log levels"); + // Turn off TGeo printouts if appropriate for the msg level + if (m_log->level() >= (int)spdlog::level::info) { + TGeoManager::SetVerboseLevel(0); + } + + // Set ACTS logging level + auto acts_init_log_level = eicrecon::SpdlogToActsLevel(m_init_log->level()); + + m_dd4hepDetector = dd4hep_geo; + + // Load ACTS materials maps + std::shared_ptr materialDeco{nullptr}; + if (!material_file.empty()) { + m_init_log->info("loading materials map from file: '{}'", material_file); + // Set up the converter first + Acts::MaterialMapJsonConverter::Config jsonGeoConvConfig; + // Set up the json-based decorator + materialDeco = std::make_shared( + jsonGeoConvConfig, material_file, acts_init_log_level); + } + + // Geometry identifier hook to write detector ID to extra field + class ConvertDD4hepDetectorGeometryIdentifierHook : public Acts::GeometryIdentifierHook { + Acts::GeometryIdentifier decorateIdentifier(Acts::GeometryIdentifier identifier, + const Acts::Surface& surface) const { + const auto* dd4hep_det_element = + dynamic_cast(surface.associatedDetectorElement()); + if (dd4hep_det_element == nullptr) { + return identifier; + } + // set 8-bit extra field to 8-bit DD4hep detector ID + return identifier.setExtra(0xff & dd4hep_det_element->identifier()); }; - auto geometryIdHook = std::make_shared(); - - // Convert DD4hep geometry to ACTS - m_init_log->info("Converting DD4Hep geometry to ACTS..."); - auto logger = eicrecon::getSpdlogLogger("CONV", m_log); - Acts::BinningType bTypePhi = Acts::equidistant; - Acts::BinningType bTypeR = Acts::equidistant; - Acts::BinningType bTypeZ = Acts::equidistant; - double layerEnvelopeR = Acts::UnitConstants::mm; - double layerEnvelopeZ = Acts::UnitConstants::mm; - double defaultLayerThickness = Acts::UnitConstants::fm; - using Acts::sortDetElementsByID; - - try { - m_trackingGeo = Acts::convertDD4hepDetector( - m_dd4hepDetector->world(), - *logger, - bTypePhi, - bTypeR, - bTypeZ, - layerEnvelopeR, - layerEnvelopeZ, - defaultLayerThickness, - sortDetElementsByID, - m_trackingGeoCtx, - materialDeco, - geometryIdHook); - } - catch(std::exception &ex) { - m_init_log->error("Error during DD4Hep -> ACTS geometry conversion: {}", ex.what()); - m_init_log->info ("Set parameter acts::InitLogLevel=trace to see conversion info and possibly identify failing geometry"); - throw JException(ex.what()); - } - - m_init_log->info("DD4Hep geometry converted!"); - - // Visit surfaces - m_init_log->info("Checking surfaces..."); - if (m_trackingGeo) { - // Write tracking geometry to collection of obj or ply files - const Acts::TrackingVolume* world = m_trackingGeo->highestTrackingVolume(); - if (m_objWriteIt) { - m_init_log->info("Writing obj files to {}...", m_outputDir); - Acts::ObjVisualization3D objVis; - Acts::GeometryView3D::drawTrackingVolume( - objVis, *world, m_trackingGeoCtx, - m_containerView, m_volumeView, m_passiveView, m_sensitiveView, m_gridView, - m_objWriteIt, m_outputTag, m_outputDir - ); - } - if (m_plyWriteIt) { - m_init_log->info("Writing ply files to {}...", m_outputDir); - Acts::PlyVisualization3D plyVis; - Acts::GeometryView3D::drawTrackingVolume( - plyVis, *world, m_trackingGeoCtx, - m_containerView, m_volumeView, m_passiveView, m_sensitiveView, m_gridView, - m_plyWriteIt, m_outputTag, m_outputDir - ); - } - - m_init_log->debug("visiting all the surfaces "); - m_trackingGeo->visitSurfaces([this](const Acts::Surface *surface) { - // for now we just require a valid surface - if (surface == nullptr) { - m_init_log->info("no surface??? "); - return; - } - const auto *det_element = - dynamic_cast(surface->associatedDetectorElement()); - - if (det_element == nullptr) { - m_init_log->error("invalid det_element!!! det_element == nullptr "); - return; - } - - // more verbose output is lower enum value - m_init_log->debug(" det_element->identifier() = {} ", det_element->identifier()); - auto volman = m_dd4hepDetector->volumeManager(); - auto *vol_ctx = volman.lookupContext(det_element->identifier()); - auto vol_id = vol_ctx->identifier; - - if (m_init_log->level() <= spdlog::level::debug) { - auto de = vol_ctx->element; - m_init_log->debug(" de.path = {}", de.path()); - m_init_log->debug(" de.placementPath = {}", de.placementPath()); - } - - this->m_surfaces.insert_or_assign(vol_id, surface); - }); - } - else { - m_init_log->error("m_trackingGeo==null why am I still alive???"); + }; + auto geometryIdHook = std::make_shared(); + + // Convert DD4hep geometry to ACTS + m_init_log->info("Converting DD4Hep geometry to ACTS..."); + auto logger = eicrecon::getSpdlogLogger("CONV", m_log); + Acts::BinningType bTypePhi = Acts::equidistant; + Acts::BinningType bTypeR = Acts::equidistant; + Acts::BinningType bTypeZ = Acts::equidistant; + double layerEnvelopeR = Acts::UnitConstants::mm; + double layerEnvelopeZ = Acts::UnitConstants::mm; + double defaultLayerThickness = Acts::UnitConstants::fm; + using Acts::sortDetElementsByID; + + try { + m_trackingGeo = Acts::convertDD4hepDetector(m_dd4hepDetector->world(), *logger, bTypePhi, + bTypeR, bTypeZ, layerEnvelopeR, layerEnvelopeZ, + defaultLayerThickness, sortDetElementsByID, + m_trackingGeoCtx, materialDeco, geometryIdHook); + } catch (std::exception& ex) { + m_init_log->error("Error during DD4Hep -> ACTS geometry conversion: {}", ex.what()); + m_init_log->info("Set parameter acts::InitLogLevel=trace to see conversion info and possibly " + "identify failing geometry"); + throw JException(ex.what()); + } + + m_init_log->info("DD4Hep geometry converted!"); + + // Visit surfaces + m_init_log->info("Checking surfaces..."); + if (m_trackingGeo) { + // Write tracking geometry to collection of obj or ply files + const Acts::TrackingVolume* world = m_trackingGeo->highestTrackingVolume(); + if (m_objWriteIt) { + m_init_log->info("Writing obj files to {}...", m_outputDir); + Acts::ObjVisualization3D objVis; + Acts::GeometryView3D::drawTrackingVolume(objVis, *world, m_trackingGeoCtx, m_containerView, + m_volumeView, m_passiveView, m_sensitiveView, + m_gridView, m_objWriteIt, m_outputTag, m_outputDir); } - - // Load ACTS magnetic field - m_init_log->info("Loading magnetic field..."); - m_magneticField = std::make_shared(m_dd4hepDetector); - Acts::MagneticFieldContext m_fieldctx{eicrecon::BField::BFieldVariant(m_magneticField)}; - auto bCache = m_magneticField->makeCache(m_fieldctx); - for (int z: {0, 500, 1000, 1500, 2000, 3000, 4000}) { - auto b = m_magneticField->getField({0.0, 0.0, double(z)}, bCache).value(); - m_init_log->debug("B(z = {:>5} [mm]) = {} T", z, b.transpose() / Acts::UnitConstants::T); + if (m_plyWriteIt) { + m_init_log->info("Writing ply files to {}...", m_outputDir); + Acts::PlyVisualization3D plyVis; + Acts::GeometryView3D::drawTrackingVolume(plyVis, *world, m_trackingGeoCtx, m_containerView, + m_volumeView, m_passiveView, m_sensitiveView, + m_gridView, m_plyWriteIt, m_outputTag, m_outputDir); } - m_init_log->info("ActsGeometryProvider initialization complete"); + m_init_log->debug("visiting all the surfaces "); + m_trackingGeo->visitSurfaces([this](const Acts::Surface* surface) { + // for now we just require a valid surface + if (surface == nullptr) { + m_init_log->info("no surface??? "); + return; + } + const auto* det_element = + dynamic_cast(surface->associatedDetectorElement()); + + if (det_element == nullptr) { + m_init_log->error("invalid det_element!!! det_element == nullptr "); + return; + } + + // more verbose output is lower enum value + m_init_log->debug(" det_element->identifier() = {} ", det_element->identifier()); + auto volman = m_dd4hepDetector->volumeManager(); + auto* vol_ctx = volman.lookupContext(det_element->identifier()); + auto vol_id = vol_ctx->identifier; + + if (m_init_log->level() <= spdlog::level::debug) { + auto de = vol_ctx->element; + m_init_log->debug(" de.path = {}", de.path()); + m_init_log->debug(" de.placementPath = {}", de.placementPath()); + } + + this->m_surfaces.insert_or_assign(vol_id, surface); + }); + } else { + m_init_log->error("m_trackingGeo==null why am I still alive???"); + } + + // Load ACTS magnetic field + m_init_log->info("Loading magnetic field..."); + m_magneticField = std::make_shared(m_dd4hepDetector); + Acts::MagneticFieldContext m_fieldctx{eicrecon::BField::BFieldVariant(m_magneticField)}; + auto bCache = m_magneticField->makeCache(m_fieldctx); + for (int z : {0, 500, 1000, 1500, 2000, 3000, 4000}) { + auto b = m_magneticField->getField({0.0, 0.0, double(z)}, bCache).value(); + m_init_log->debug("B(z = {:>5} [mm]) = {} T", z, b.transpose() / Acts::UnitConstants::T); + } + + m_init_log->info("ActsGeometryProvider initialization complete"); } diff --git a/src/algorithms/tracking/ActsGeometryProvider.h b/src/algorithms/tracking/ActsGeometryProvider.h index bfe3f6403f..75c77f7fad 100644 --- a/src/algorithms/tracking/ActsGeometryProvider.h +++ b/src/algorithms/tracking/ActsGeometryProvider.h @@ -27,117 +27,117 @@ #include "DD4hepBField.h" namespace dd4hep::rec { - class Surface; +class Surface; } /** Draw the surfaces and save to obj file. * This is useful for debugging the ACTS geometry. The obj file can * be loaded into various tools, such as FreeCAD, for inspection. */ -void draw_surfaces(std::shared_ptr trk_geo, std::shared_ptr init_log, const std::string &fname); +void draw_surfaces(std::shared_ptr trk_geo, + std::shared_ptr init_log, const std::string& fname); class ActsGeometryProvider { public: - ActsGeometryProvider() {} - using VolumeSurfaceMap = std::unordered_map; + ActsGeometryProvider() {} + using VolumeSurfaceMap = std::unordered_map; - virtual void initialize(const dd4hep::Detector* dd4hep_geo, - std::string material_file, - std::shared_ptr log, - std::shared_ptr init_log) final; + virtual void initialize(const dd4hep::Detector* dd4hep_geo, std::string material_file, + std::shared_ptr log, + std::shared_ptr init_log) final; - const dd4hep::Detector* dd4hepDetector() const { return m_dd4hepDetector; } + const dd4hep::Detector* dd4hepDetector() const { return m_dd4hepDetector; } - /** Gets the ACTS tracking geometry. + /** Gets the ACTS tracking geometry. */ - std::shared_ptr trackingGeometry() const { return m_trackingGeo;} + std::shared_ptr trackingGeometry() const { return m_trackingGeo; } - std::shared_ptr getFieldProvider() const { return m_magneticField; } + std::shared_ptr getFieldProvider() const { + return m_magneticField; + } - double centralMagneticField() const { - return m_dd4hepDetector->field().magneticField({0, 0, 0}).z() * (Acts::UnitConstants::T / dd4hep::tesla); - } + double centralMagneticField() const { + return m_dd4hepDetector->field().magneticField({0, 0, 0}).z() * + (Acts::UnitConstants::T / dd4hep::tesla); + } - const VolumeSurfaceMap &surfaceMap() const { return m_surfaces; } + const VolumeSurfaceMap& surfaceMap() const { return m_surfaces; } + std::map getDD4hepSurfaceMap() const { return m_surfaceMap; } - std::map getDD4hepSurfaceMap() const { return m_surfaceMap; } + const Acts::GeometryContext& getActsGeometryContext() const { return m_trackingGeoCtx; } - const Acts::GeometryContext& getActsGeometryContext() const {return m_trackingGeoCtx;} + /// ACTS general logger that is used for running ACTS + std::shared_ptr getActsRelatedLogger() const { return m_log; } - /// ACTS general logger that is used for running ACTS - std::shared_ptr getActsRelatedLogger() const { return m_log; } - - /// Logger that is used for geometry initialization - /// By default its level the same as ACTS general logger (m_log) - /// But it might be customized to solely printout geometry information - std::shared_ptr getActsInitRelatedLogger() const { return m_init_log; } + /// Logger that is used for geometry initialization + /// By default its level the same as ACTS general logger (m_log) + /// But it might be customized to solely printout geometry information + std::shared_ptr getActsInitRelatedLogger() const { return m_init_log; } private: - - /** DD4hep detector interface class. + /** DD4hep detector interface class. * This is the main dd4hep detector handle. * See DD4hep Detector documentation */ - const dd4hep::Detector* m_dd4hepDetector = nullptr; + const dd4hep::Detector* m_dd4hepDetector = nullptr; - /// DD4hep surface map - std::map m_surfaceMap; + /// DD4hep surface map + std::map m_surfaceMap; - /// ACTS Logging Level - Acts::Logging::Level acts_log_level = Acts::Logging::INFO; + /// ACTS Logging Level + Acts::Logging::Level acts_log_level = Acts::Logging::INFO; - /// ACTS Tracking Geometry Context - Acts::GeometryContext m_trackingGeoCtx; + /// ACTS Tracking Geometry Context + Acts::GeometryContext m_trackingGeoCtx; - /// ACTS Tracking Geometry - std::shared_ptr m_trackingGeo{nullptr}; + /// ACTS Tracking Geometry + std::shared_ptr m_trackingGeo{nullptr}; - /// ACTS surface lookup container for hit surfaces that generate smeared hits - VolumeSurfaceMap m_surfaces; + /// ACTS surface lookup container for hit surfaces that generate smeared hits + VolumeSurfaceMap m_surfaces; - /// Acts magnetic field - std::shared_ptr m_magneticField = nullptr; + /// Acts magnetic field + std::shared_ptr m_magneticField = nullptr; - /// ACTS general logger that is used for running ACTS - std::shared_ptr m_log; + /// ACTS general logger that is used for running ACTS + std::shared_ptr m_log; - /// Logger that is used for geometry initialization - /// By default its level the same as ACTS general logger (m_log) - /// But it might be customized to solely printout geometry information - std::shared_ptr m_init_log; + /// Logger that is used for geometry initialization + /// By default its level the same as ACTS general logger (m_log) + /// But it might be customized to solely printout geometry information + std::shared_ptr m_init_log; - /// Configuration for obj export - Acts::ViewConfig m_containerView{{220, 220, 220}}; - Acts::ViewConfig m_volumeView{{220, 220, 0}}; - Acts::ViewConfig m_sensitiveView{{0, 180, 240}}; - Acts::ViewConfig m_passiveView{{240, 280, 0}}; - Acts::ViewConfig m_gridView{{220, 0, 0}}; - bool m_objWriteIt{false}; - bool m_plyWriteIt{false}; - std::string m_outputTag{""}; - std::string m_outputDir{""}; + /// Configuration for obj export + Acts::ViewConfig m_containerView{{220, 220, 220}}; + Acts::ViewConfig m_volumeView{{220, 220, 0}}; + Acts::ViewConfig m_sensitiveView{{0, 180, 240}}; + Acts::ViewConfig m_passiveView{{240, 280, 0}}; + Acts::ViewConfig m_gridView{{220, 0, 0}}; + bool m_objWriteIt{false}; + bool m_plyWriteIt{false}; + std::string m_outputTag{""}; + std::string m_outputDir{""}; public: - void setObjWriteIt(bool writeit) { m_objWriteIt = writeit; } - bool getObjWriteIt() const { return m_objWriteIt; } - void setPlyWriteIt(bool writeit) { m_plyWriteIt = writeit; } - bool getPlyWriteIt() const { return m_plyWriteIt; } - - void setOutputTag(std::string tag) { m_outputTag = tag; } - std::string getOutputTag() const { return m_outputTag; } - void setOutputDir(std::string dir) { m_outputDir = dir; } - std::string getOutputDir() const { return m_outputDir; } - - void setContainerView(std::array view) { m_containerView = Acts::ViewConfig{view}; } - const Acts::ViewConfig& getContainerView() const { return m_containerView; } - void setVolumeView(std::array view) { m_volumeView = Acts::ViewConfig{view}; } - const Acts::ViewConfig& getVolumeView() const { return m_volumeView; } - void setSensitiveView(std::array view) { m_sensitiveView = Acts::ViewConfig{view}; } - const Acts::ViewConfig& getSensitiveView() const { return m_sensitiveView; } - void setPassiveView(std::array view) { m_passiveView = Acts::ViewConfig{view}; } - const Acts::ViewConfig& getPassiveView() const { return m_passiveView; } - void setGridView(std::array view) { m_gridView = Acts::ViewConfig{view}; } - const Acts::ViewConfig& getGridView() const { return m_gridView; } - + void setObjWriteIt(bool writeit) { m_objWriteIt = writeit; } + bool getObjWriteIt() const { return m_objWriteIt; } + void setPlyWriteIt(bool writeit) { m_plyWriteIt = writeit; } + bool getPlyWriteIt() const { return m_plyWriteIt; } + + void setOutputTag(std::string tag) { m_outputTag = tag; } + std::string getOutputTag() const { return m_outputTag; } + void setOutputDir(std::string dir) { m_outputDir = dir; } + std::string getOutputDir() const { return m_outputDir; } + + void setContainerView(std::array view) { m_containerView = Acts::ViewConfig{view}; } + const Acts::ViewConfig& getContainerView() const { return m_containerView; } + void setVolumeView(std::array view) { m_volumeView = Acts::ViewConfig{view}; } + const Acts::ViewConfig& getVolumeView() const { return m_volumeView; } + void setSensitiveView(std::array view) { m_sensitiveView = Acts::ViewConfig{view}; } + const Acts::ViewConfig& getSensitiveView() const { return m_sensitiveView; } + void setPassiveView(std::array view) { m_passiveView = Acts::ViewConfig{view}; } + const Acts::ViewConfig& getPassiveView() const { return m_passiveView; } + void setGridView(std::array view) { m_gridView = Acts::ViewConfig{view}; } + const Acts::ViewConfig& getGridView() const { return m_gridView; } }; diff --git a/src/algorithms/tracking/ActsToTracks.cc b/src/algorithms/tracking/ActsToTracks.cc index aa8c069449..f1c9832f37 100644 --- a/src/algorithms/tracking/ActsToTracks.cc +++ b/src/algorithms/tracking/ActsToTracks.cc @@ -38,27 +38,25 @@ namespace eicrecon { // Note: std::map is not constexpr, so we use a constexpr std::array // std::array initialization need double braces since arrays are aggregates // ref: https://en.cppreference.com/w/cpp/language/aggregate_initialization -static constexpr std::array, 6> edm4eic_indexed_units{{ - {Acts::eBoundLoc0, Acts::UnitConstants::mm}, - {Acts::eBoundLoc1, Acts::UnitConstants::mm}, - {Acts::eBoundPhi, 1.}, - {Acts::eBoundTheta, 1.}, - {Acts::eBoundQOverP, 1. / Acts::UnitConstants::GeV}, - {Acts::eBoundTime, Acts::UnitConstants::ns} -}}; - -void ActsToTracks::init() { -} +static constexpr std::array, 6> edm4eic_indexed_units{ + {{Acts::eBoundLoc0, Acts::UnitConstants::mm}, + {Acts::eBoundLoc1, Acts::UnitConstants::mm}, + {Acts::eBoundPhi, 1.}, + {Acts::eBoundTheta, 1.}, + {Acts::eBoundQOverP, 1. / Acts::UnitConstants::GeV}, + {Acts::eBoundTime, Acts::UnitConstants::ns}}}; + +void ActsToTracks::init() {} void ActsToTracks::process(const Input& input, const Output& output) const { - const auto [meas2Ds, acts_trajectories, raw_hit_assocs] = input; - auto [trajectories, track_parameters, tracks, tracks_assoc] = output; + const auto [meas2Ds, acts_trajectories, raw_hit_assocs] = input; + auto [trajectories, track_parameters, tracks, tracks_assoc] = output; // Loop over trajectories for (const auto traj : acts_trajectories) { // The trajectory entry indices and the multiTrajectory const auto& trackTips = traj->tips(); - const auto& mj = traj->multiTrajectory(); + const auto& mj = traj->multiTrajectory(); if (trackTips.empty()) { warning("Empty multiTrajectory."); continue; @@ -67,14 +65,11 @@ void ActsToTracks::process(const Input& input, const Output& output) const { // Loop over all trajectories in a multiTrajectory for (auto trackTip : trackTips) { // Collect the trajectory summary info - auto trajectoryState = - Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); + auto trajectoryState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); // Check if the reco track has fitted track parameters if (not traj->hasTrackParameters(trackTip)) { - warning( - "No fitted track parameters for trajectory with entry index = {}", - trackTip); + warning("No fitted track parameters for trajectory with entry index = {}", trackTip); continue; } @@ -86,18 +81,15 @@ void ActsToTracks::process(const Input& input, const Output& output) const { trajectory.setNHoles(trajectoryState.nHoles); trajectory.setNSharedHits(trajectoryState.nSharedHits); - debug("trajectory state, measurement, outlier, hole: {} {} {} {}", - trajectoryState.nStates, - trajectoryState.nMeasurements, - trajectoryState.nOutliers, - trajectoryState.nHoles); + debug("trajectory state, measurement, outlier, hole: {} {} {} {}", trajectoryState.nStates, + trajectoryState.nMeasurements, trajectoryState.nOutliers, trajectoryState.nHoles); for (const auto& measurementChi2 : trajectoryState.measurementChi2) { - trajectory.addToMeasurementChi2(measurementChi2); + trajectory.addToMeasurementChi2(measurementChi2); } for (const auto& outlierChi2 : trajectoryState.outlierChi2) { - trajectory.addToOutlierChi2(outlierChi2); + trajectory.addToOutlierChi2(outlierChi2); } // Get the fitted track parameter @@ -107,10 +99,8 @@ void ActsToTracks::process(const Input& input, const Output& output) const { auto pars = track_parameters->create(); pars.setType(0); // type: track head --> 0 - pars.setLoc({ - static_cast(parameter[Acts::eBoundLoc0]), - static_cast(parameter[Acts::eBoundLoc1]) - }); + pars.setLoc({static_cast(parameter[Acts::eBoundLoc0]), + static_cast(parameter[Acts::eBoundLoc1])}); pars.setTheta(static_cast(parameter[Acts::eBoundTheta])); pars.setPhi(static_cast(parameter[Acts::eBoundPhi])); pars.setQOverP(static_cast(parameter[Acts::eBoundQOverP])); @@ -119,7 +109,7 @@ void ActsToTracks::process(const Input& input, const Output& output) const { for (size_t i = 0; const auto& [a, x] : edm4eic_indexed_units) { for (size_t j = 0; const auto& [b, y] : edm4eic_indexed_units) { // FIXME why not pars.getCovariance()(i,j) = covariance(a,b) / x / y; - cov(i,j) = covariance(a,b) / x / y; + cov(i, j) = covariance(a, b) / x / y; ++j; } ++i; @@ -130,110 +120,100 @@ void ActsToTracks::process(const Input& input, const Output& output) const { // Fill tracks auto track = tracks->create(); - track.setType( // Flag that defines the type of track - pars.getType() - ); - track.setPosition( // Track 3-position at the vertex - edm4hep::Vector3f() - ); - track.setMomentum( // Track 3-momentum at the vertex [GeV] - edm4hep::Vector3f() - ); - track.setPositionMomentumCovariance( // Covariance matrix in basis [x,y,z,px,py,pz] - edm4eic::Cov6f() - ); - track.setTime( // Track time at the vertex [ns] - static_cast(parameter[Acts::eBoundTime]) - ); - track.setTimeError( // Error on the track vertex time - sqrt(static_cast(covariance(Acts::eBoundTime, Acts::eBoundTime))) - ); - track.setCharge( // Particle charge - std::copysign(1., parameter[Acts::eBoundQOverP]) - ); - track.setChi2(trajectoryState.chi2Sum); // Total chi2 - track.setNdf(trajectoryState.NDF); // Number of degrees of freedom - track.setPdg( // PDG particle ID hypothesis - boundParam.particleHypothesis().absolutePdg() - ); - track.setTrajectory(trajectory); // Trajectory of this track + track.setType( // Flag that defines the type of track + pars.getType()); + track.setPosition( // Track 3-position at the vertex + edm4hep::Vector3f()); + track.setMomentum( // Track 3-momentum at the vertex [GeV] + edm4hep::Vector3f()); + track.setPositionMomentumCovariance( // Covariance matrix in basis [x,y,z,px,py,pz] + edm4eic::Cov6f()); + track.setTime( // Track time at the vertex [ns] + static_cast(parameter[Acts::eBoundTime])); + track.setTimeError( // Error on the track vertex time + sqrt(static_cast(covariance(Acts::eBoundTime, Acts::eBoundTime)))); + track.setCharge( // Particle charge + std::copysign(1., parameter[Acts::eBoundQOverP])); + track.setChi2(trajectoryState.chi2Sum); // Total chi2 + track.setNdf(trajectoryState.NDF); // Number of degrees of freedom + track.setPdg( // PDG particle ID hypothesis + boundParam.particleHypothesis().absolutePdg()); + track.setTrajectory(trajectory); // Trajectory of this track // Determine track association with MCParticle, weighted by number of used measurements - std::map mcparticle_weight_by_hit_count; + std::map mcparticle_weight_by_hit_count; // save measurement2d to good measurements or outliers according to srclink index // fix me: ideally, this should be integrated into multitrajectoryhelper // fix me: should say "OutlierMeasurements" instead of "OutlierHits" etc mj.visitBackwards(trackTip, [&](const auto& state) { - - auto geoID = state.referenceSurface().geometryId().value(); - auto typeFlags = state.typeFlags(); - - // find the associated hit (2D measurement) with state sourcelink index - // fix me: calibrated or not? - if (state.hasUncalibratedSourceLink()) { - - std::size_t srclink_index = state.getUncalibratedSourceLink().template get().index(); - - // no hit on this state/surface, skip - if (typeFlags.test(Acts::TrackStateFlag::HoleFlag)) { - debug("No hit found on geo id={}", geoID); - - } else { - auto meas2D = (*meas2Ds) [srclink_index]; - if (typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) { - track.addToMeasurements(meas2D); - trajectory.addToMeasurements_deprecated(meas2D); - debug("Measurement on geo id={}, index={}, loc={},{}", - geoID, srclink_index, meas2D.getLoc().a, meas2D.getLoc().b); - - // Determine track associations if hit associations provided - // FIXME: not able to check whether optional inputs were provided - //if (raw_hit_assocs->has_value()) { - #if EDM4EIC_VERSION_MAJOR >= 7 - for (auto& hit : meas2D.getHits()) { - auto raw_hit = hit.getRawHit(); - for (const auto raw_hit_assoc : *raw_hit_assocs) { - if (raw_hit_assoc.getRawHit() == raw_hit) { - auto sim_hit = raw_hit_assoc.getSimHit(); - auto mc_particle = sim_hit.getMCParticle(); - mcparticle_weight_by_hit_count[mc_particle]++; - } - } - } - #endif - //} - - } - else if (typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) { - trajectory.addToOutliers_deprecated(meas2D); - debug("Outlier on geo id={}, index={}, loc={},{}", - geoID, srclink_index, meas2D.getLoc().a, meas2D.getLoc().b); - + auto geoID = state.referenceSurface().geometryId().value(); + auto typeFlags = state.typeFlags(); + + // find the associated hit (2D measurement) with state sourcelink index + // fix me: calibrated or not? + if (state.hasUncalibratedSourceLink()) { + + std::size_t srclink_index = state.getUncalibratedSourceLink() + .template get() + .index(); + + // no hit on this state/surface, skip + if (typeFlags.test(Acts::TrackStateFlag::HoleFlag)) { + debug("No hit found on geo id={}", geoID); + + } else { + auto meas2D = (*meas2Ds)[srclink_index]; + if (typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) { + track.addToMeasurements(meas2D); + trajectory.addToMeasurements_deprecated(meas2D); + debug("Measurement on geo id={}, index={}, loc={},{}", geoID, srclink_index, + meas2D.getLoc().a, meas2D.getLoc().b); + +// Determine track associations if hit associations provided +// FIXME: not able to check whether optional inputs were provided +//if (raw_hit_assocs->has_value()) { +#if EDM4EIC_VERSION_MAJOR >= 7 + for (auto& hit : meas2D.getHits()) { + auto raw_hit = hit.getRawHit(); + for (const auto raw_hit_assoc : *raw_hit_assocs) { + if (raw_hit_assoc.getRawHit() == raw_hit) { + auto sim_hit = raw_hit_assoc.getSimHit(); + auto mc_particle = sim_hit.getMCParticle(); + mcparticle_weight_by_hit_count[mc_particle]++; } + } } +#endif + //} + + } else if (typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) { + trajectory.addToOutliers_deprecated(meas2D); + debug("Outlier on geo id={}, index={}, loc={},{}", geoID, srclink_index, + meas2D.getLoc().a, meas2D.getLoc().b); + } } - + } }); // Store track associations if hit associations provided // FIXME: not able to check whether optional inputs were provided //if (raw_hit_assocs->has_value()) { - double total_weight = std::accumulate( - mcparticle_weight_by_hit_count.begin(), mcparticle_weight_by_hit_count.end(), - 0, [](const double sum, const auto& i) { return sum + i.second; }); - for (const auto& [mcparticle, weight] : mcparticle_weight_by_hit_count) { - auto track_assoc = tracks_assoc->create(); - track_assoc.setRec(track); - track_assoc.setSim(mcparticle); - double normalized_weight = weight / total_weight; - track_assoc.setWeight(normalized_weight); - debug("track {}: mcparticle {} weight {}", track.id().index, mcparticle.id().index, normalized_weight); - } + double total_weight = std::accumulate( + mcparticle_weight_by_hit_count.begin(), mcparticle_weight_by_hit_count.end(), 0, + [](const double sum, const auto& i) { return sum + i.second; }); + for (const auto& [mcparticle, weight] : mcparticle_weight_by_hit_count) { + auto track_assoc = tracks_assoc->create(); + track_assoc.setRec(track); + track_assoc.setSim(mcparticle); + double normalized_weight = weight / total_weight; + track_assoc.setWeight(normalized_weight); + debug("track {}: mcparticle {} weight {}", track.id().index, mcparticle.id().index, + normalized_weight); + } //} - } } } -} +} // namespace eicrecon diff --git a/src/algorithms/tracking/ActsToTracks.h b/src/algorithms/tracking/ActsToTracks.h index 884ab25198..10937b4f0b 100644 --- a/src/algorithms/tracking/ActsToTracks.h +++ b/src/algorithms/tracking/ActsToTracks.h @@ -18,41 +18,32 @@ namespace eicrecon { -using ActsToTracksAlgorithm = - algorithms::Algorithm< - algorithms::Input< - edm4eic::Measurement2DCollection, - std::vector, - std::optional - >, - algorithms::Output< - edm4eic::TrajectoryCollection, - edm4eic::TrackParametersCollection, - edm4eic::TrackCollection, - std::optional - > - >; +using ActsToTracksAlgorithm = algorithms::Algorithm< + algorithms::Input, + std::optional>, + algorithms::Output>>; class ActsToTracks : public ActsToTracksAlgorithm { public: - ActsToTracks(std::string_view name) - : ActsToTracksAlgorithm{ - name, - { - "inputMeasurements", - "inputActsTrajectories", - "inputRawTrackerHitAssociations", - }, - { - "outputTrajectories", - "outputTrackParameters", - "outputTracks", - "outputTrackAssociations", - }, - "Converts ACTS trajectories to EDM4eic"} {}; + ActsToTracks(std::string_view name) + : ActsToTracksAlgorithm{name, + { + "inputMeasurements", + "inputActsTrajectories", + "inputRawTrackerHitAssociations", + }, + { + "outputTrajectories", + "outputTrackParameters", + "outputTracks", + "outputTrackAssociations", + }, + "Converts ACTS trajectories to EDM4eic"} {}; - void init() final; - void process(const Input&, const Output&) const final; + void init() final; + void process(const Input&, const Output&) const final; }; -} +} // namespace eicrecon diff --git a/src/algorithms/tracking/AmbiguitySolver.cc b/src/algorithms/tracking/AmbiguitySolver.cc index 4be8faa411..a61dbb6639 100644 --- a/src/algorithms/tracking/AmbiguitySolver.cc +++ b/src/algorithms/tracking/AmbiguitySolver.cc @@ -49,10 +49,8 @@ static bool sourceLinkEquality(const Acts::SourceLink& a, const Acts::SourceLink b.get().index(); } - AmbiguitySolver::AmbiguitySolver() {} - void AmbiguitySolver::init(std::shared_ptr log) { m_log = log; @@ -61,8 +59,8 @@ void AmbiguitySolver::init(std::shared_ptr log) { m_core = std::make_unique(m_acts_cfg, logger().clone()); } - -std::tuple, std::vector> +std::tuple, + std::vector> AmbiguitySolver::process(std::vector input_container, const edm4eic::Measurement2DCollection& meas2Ds) { @@ -82,38 +80,34 @@ AmbiguitySolver::process(std::vector i for (auto iTrack : state.selectedTracks) { - auto destProxy = solvedTracks.getTrack(solvedTracks.addTrack()); - auto srcProxy = input_trks->getTrack(state.trackTips.at(iTrack)); - destProxy.copyFrom(srcProxy, false); - destProxy.tipIndex() = srcProxy.tipIndex(); - - } - - output_tracks.push_back(new ActsExamples::ConstTrackContainer( - std::make_shared(std::move(solvedTracks.container())), - input_trks->trackStateContainerHolder())); + auto destProxy = solvedTracks.getTrack(solvedTracks.addTrack()); + auto srcProxy = input_trks->getTrack(state.trackTips.at(iTrack)); + destProxy.copyFrom(srcProxy, false); + destProxy.tipIndex() = srcProxy.tipIndex(); + } - //Make output trajectories - ActsExamples::Trajectories::IndexedParameters parameters; - std::vector tips; + output_tracks.push_back(new ActsExamples::ConstTrackContainer( + std::make_shared(std::move(solvedTracks.container())), + input_trks->trackStateContainerHolder())); - for (const auto& track : *(output_tracks.front())) { + //Make output trajectories + ActsExamples::Trajectories::IndexedParameters parameters; + std::vector tips; - tips.clear(); - parameters.clear(); + for (const auto& track : *(output_tracks.front())) { - tips.push_back(track.tipIndex()); - parameters.emplace( - std::pair{track.tipIndex(), - ActsExamples::TrackParameters{track.referenceSurface().getSharedPtr(), - track.parameters(), track.covariance(), - track.particleHypothesis()}}); + tips.clear(); + parameters.clear(); - output_trajectories.push_back(new ActsExamples::Trajectories( - ((*output_tracks.front())).trackStateContainer(), - tips, parameters)); + tips.push_back(track.tipIndex()); + parameters.emplace(std::pair{ + track.tipIndex(), + ActsExamples::TrackParameters{track.referenceSurface().getSharedPtr(), track.parameters(), + track.covariance(), track.particleHypothesis()}}); - } + output_trajectories.push_back(new ActsExamples::Trajectories( + ((*output_tracks.front())).trackStateContainer(), tips, parameters)); + } return std::make_tuple(std::move(output_tracks), std::move(output_trajectories)); } diff --git a/src/algorithms/tracking/AmbiguitySolver.h b/src/algorithms/tracking/AmbiguitySolver.h index 6244626500..bca17669b8 100644 --- a/src/algorithms/tracking/AmbiguitySolver.h +++ b/src/algorithms/tracking/AmbiguitySolver.h @@ -24,11 +24,10 @@ class AmbiguitySolver : public WithPodConfig { void init(std::shared_ptr log); -std::tuple< - std::vector, - std::vector - > - process(std::vector input_container,const edm4eic::Measurement2DCollection& meas2Ds); + std::tuple, + std::vector> + process(std::vector input_container, + const edm4eic::Measurement2DCollection& meas2Ds); private: std::shared_ptr m_log; diff --git a/src/algorithms/tracking/CKFTracking.cc b/src/algorithms/tracking/CKFTracking.cc index ba07f93561..c9165c2ce3 100644 --- a/src/algorithms/tracking/CKFTracking.cc +++ b/src/algorithms/tracking/CKFTracking.cc @@ -70,325 +70,307 @@ namespace eicrecon { - using namespace Acts::UnitLiterals; - - // This array relates the Acts and EDM4eic covariance matrices, including - // the unit conversion to get from Acts units into EDM4eic units. - // - // Note: std::map is not constexpr, so we use a constexpr std::array - // std::array initialization need double braces since arrays are aggregates - // ref: https://en.cppreference.com/w/cpp/language/aggregate_initialization - static constexpr std::array, 6> edm4eic_indexed_units{{ - {Acts::eBoundLoc0, Acts::UnitConstants::mm}, - {Acts::eBoundLoc1, Acts::UnitConstants::mm}, - {Acts::eBoundPhi, 1.}, - {Acts::eBoundTheta, 1.}, - {Acts::eBoundQOverP, 1. / Acts::UnitConstants::GeV}, - {Acts::eBoundTime, Acts::UnitConstants::ns} - }}; - - CKFTracking::CKFTracking() { - } - - void CKFTracking::init(std::shared_ptr geo_svc, std::shared_ptr log) { - m_log = log; - m_acts_logger = eicrecon::getSpdlogLogger("CKF", m_log); - - m_geoSvc = geo_svc; - - m_BField = std::dynamic_pointer_cast(m_geoSvc->getFieldProvider()); - m_fieldctx = eicrecon::BField::BFieldVariant(m_BField); - - // eta bins, chi2 and #sourclinks per surface cutoffs - m_sourcelinkSelectorCfg = { - {Acts::GeometryIdentifier(), - {m_cfg.etaBins, m_cfg.chi2CutOff, - {m_cfg.numMeasurementsCutOff.begin(), m_cfg.numMeasurementsCutOff.end()} - } - }, - }; - m_trackFinderFunc = CKFTracking::makeCKFTrackingFunction(m_geoSvc->trackingGeometry(), m_BField, logger()); - } - - std::tuple< - std::vector, - std::vector - > - CKFTracking::process(const edm4eic::TrackParametersCollection& init_trk_params, - const edm4eic::Measurement2DCollection& meas2Ds) { - - - // create sourcelink and measurement containers - auto measurements = std::make_shared(); - - // need list here for stable addresses - std::list sourceLinkStorage; - ActsExamples::IndexSourceLinkContainer src_links; - src_links.reserve(meas2Ds.size()); - std::size_t hit_index = 0; - - - for (const auto& meas2D : meas2Ds) { - - // --follow example from ACTS to create source links - sourceLinkStorage.emplace_back(meas2D.getSurface(), hit_index); - ActsExamples::IndexSourceLink& sourceLink = sourceLinkStorage.back(); - // Add to output containers: - // index map and source link container are geometry-ordered. - // since the input is also geometry-ordered, new items can - // be added at the end. - src_links.insert(src_links.end(), sourceLink); - // --- - // Create ACTS measurements - Acts::Vector2 loc = Acts::Vector2::Zero(); - loc[Acts::eBoundLoc0] = meas2D.getLoc().a; - loc[Acts::eBoundLoc1] = meas2D.getLoc().b; - - - Acts::SquareMatrix2 cov = Acts::SquareMatrix2::Zero(); - cov(0, 0) = meas2D.getCovariance().xx; - cov(1, 1) = meas2D.getCovariance().yy; - cov(0, 1) = meas2D.getCovariance().xy; - cov(1, 0) = meas2D.getCovariance().xy; +using namespace Acts::UnitLiterals; + +// This array relates the Acts and EDM4eic covariance matrices, including +// the unit conversion to get from Acts units into EDM4eic units. +// +// Note: std::map is not constexpr, so we use a constexpr std::array +// std::array initialization need double braces since arrays are aggregates +// ref: https://en.cppreference.com/w/cpp/language/aggregate_initialization +static constexpr std::array, 6> edm4eic_indexed_units{ + {{Acts::eBoundLoc0, Acts::UnitConstants::mm}, + {Acts::eBoundLoc1, Acts::UnitConstants::mm}, + {Acts::eBoundPhi, 1.}, + {Acts::eBoundTheta, 1.}, + {Acts::eBoundQOverP, 1. / Acts::UnitConstants::GeV}, + {Acts::eBoundTime, Acts::UnitConstants::ns}}}; + +CKFTracking::CKFTracking() {} + +void CKFTracking::init(std::shared_ptr geo_svc, + std::shared_ptr log) { + m_log = log; + m_acts_logger = eicrecon::getSpdlogLogger("CKF", m_log); + + m_geoSvc = geo_svc; + + m_BField = + std::dynamic_pointer_cast(m_geoSvc->getFieldProvider()); + m_fieldctx = eicrecon::BField::BFieldVariant(m_BField); + + // eta bins, chi2 and #sourclinks per surface cutoffs + m_sourcelinkSelectorCfg = { + {Acts::GeometryIdentifier(), + {m_cfg.etaBins, + m_cfg.chi2CutOff, + {m_cfg.numMeasurementsCutOff.begin(), m_cfg.numMeasurementsCutOff.end()}}}, + }; + m_trackFinderFunc = + CKFTracking::makeCKFTrackingFunction(m_geoSvc->trackingGeometry(), m_BField, logger()); +} + +std::tuple, + std::vector> +CKFTracking::process(const edm4eic::TrackParametersCollection& init_trk_params, + const edm4eic::Measurement2DCollection& meas2Ds) { + + // create sourcelink and measurement containers + auto measurements = std::make_shared(); + + // need list here for stable addresses + std::list sourceLinkStorage; + ActsExamples::IndexSourceLinkContainer src_links; + src_links.reserve(meas2Ds.size()); + std::size_t hit_index = 0; + + for (const auto& meas2D : meas2Ds) { + + // --follow example from ACTS to create source links + sourceLinkStorage.emplace_back(meas2D.getSurface(), hit_index); + ActsExamples::IndexSourceLink& sourceLink = sourceLinkStorage.back(); + // Add to output containers: + // index map and source link container are geometry-ordered. + // since the input is also geometry-ordered, new items can + // be added at the end. + src_links.insert(src_links.end(), sourceLink); + // --- + // Create ACTS measurements + Acts::Vector2 loc = Acts::Vector2::Zero(); + loc[Acts::eBoundLoc0] = meas2D.getLoc().a; + loc[Acts::eBoundLoc1] = meas2D.getLoc().b; + + Acts::SquareMatrix2 cov = Acts::SquareMatrix2::Zero(); + cov(0, 0) = meas2D.getCovariance().xx; + cov(1, 1) = meas2D.getCovariance().yy; + cov(0, 1) = meas2D.getCovariance().xy; + cov(1, 0) = meas2D.getCovariance().xy; #if Acts_VERSION_MAJOR >= 36 - auto measurement = ActsExamples::makeFixedSizeMeasurement( - Acts::SourceLink{sourceLink}, loc, cov, Acts::eBoundLoc0, Acts::eBoundLoc1); + auto measurement = ActsExamples::makeFixedSizeMeasurement( + Acts::SourceLink{sourceLink}, loc, cov, Acts::eBoundLoc0, Acts::eBoundLoc1); #else - auto measurement = Acts::makeMeasurement( - Acts::SourceLink{sourceLink}, loc, cov, Acts::eBoundLoc0, Acts::eBoundLoc1); + auto measurement = Acts::makeMeasurement(Acts::SourceLink{sourceLink}, loc, cov, + Acts::eBoundLoc0, Acts::eBoundLoc1); #endif - measurements->emplace_back(std::move(measurement)); - - hit_index++; - } - - ActsExamples::TrackParametersContainer acts_init_trk_params; - for (const auto& track_parameter: init_trk_params) { - - Acts::BoundVector params; - params(Acts::eBoundLoc0) = track_parameter.getLoc().a * Acts::UnitConstants::mm; // cylinder radius - params(Acts::eBoundLoc1) = track_parameter.getLoc().b * Acts::UnitConstants::mm; // cylinder length - params(Acts::eBoundPhi) = track_parameter.getPhi(); - params(Acts::eBoundTheta) = track_parameter.getTheta(); - params(Acts::eBoundQOverP) = track_parameter.getQOverP() / Acts::UnitConstants::GeV; - params(Acts::eBoundTime) = track_parameter.getTime() * Acts::UnitConstants::ns; - - double charge = std::copysign(1., track_parameter.getQOverP()); - - Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Zero(); - for (size_t i = 0; const auto& [a, x] : edm4eic_indexed_units) { - for (size_t j = 0; const auto& [b, y] : edm4eic_indexed_units) { - cov(a, b) = track_parameter.getCovariance()(i,j) * x * y; - ++j; - } - ++i; - } + measurements->emplace_back(std::move(measurement)); + + hit_index++; + } + + ActsExamples::TrackParametersContainer acts_init_trk_params; + for (const auto& track_parameter : init_trk_params) { + + Acts::BoundVector params; + params(Acts::eBoundLoc0) = + track_parameter.getLoc().a * Acts::UnitConstants::mm; // cylinder radius + params(Acts::eBoundLoc1) = + track_parameter.getLoc().b * Acts::UnitConstants::mm; // cylinder length + params(Acts::eBoundPhi) = track_parameter.getPhi(); + params(Acts::eBoundTheta) = track_parameter.getTheta(); + params(Acts::eBoundQOverP) = track_parameter.getQOverP() / Acts::UnitConstants::GeV; + params(Acts::eBoundTime) = track_parameter.getTime() * Acts::UnitConstants::ns; + + double charge = std::copysign(1., track_parameter.getQOverP()); + + Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Zero(); + for (size_t i = 0; const auto& [a, x] : edm4eic_indexed_units) { + for (size_t j = 0; const auto& [b, y] : edm4eic_indexed_units) { + cov(a, b) = track_parameter.getCovariance()(i, j) * x * y; + ++j; + } + ++i; + } - // Construct a perigee surface as the target surface - auto pSurface = Acts::Surface::makeShared(Acts::Vector3(0,0,0)); + // Construct a perigee surface as the target surface + auto pSurface = Acts::Surface::makeShared(Acts::Vector3(0, 0, 0)); - // Create parameters - acts_init_trk_params.emplace_back(pSurface, params, cov, Acts::ParticleHypothesis::pion()); - } + // Create parameters + acts_init_trk_params.emplace_back(pSurface, params, cov, Acts::ParticleHypothesis::pion()); + } - //// Construct a perigee surface as the target surface - auto pSurface = Acts::Surface::makeShared(Acts::Vector3{0., 0., 0.}); + //// Construct a perigee surface as the target surface + auto pSurface = Acts::Surface::makeShared(Acts::Vector3{0., 0., 0.}); - ACTS_LOCAL_LOGGER(eicrecon::getSpdlogLogger("CKF", m_log, {"^No tracks found$"})); + ACTS_LOCAL_LOGGER(eicrecon::getSpdlogLogger("CKF", m_log, {"^No tracks found$"})); - Acts::PropagatorPlainOptions pOptions; - pOptions.maxSteps = 10000; + Acts::PropagatorPlainOptions pOptions; + pOptions.maxSteps = 10000; - ActsExamples::PassThroughCalibrator pcalibrator; - ActsExamples::MeasurementCalibratorAdapter calibrator(pcalibrator, *measurements); - Acts::GainMatrixUpdater kfUpdater; + ActsExamples::PassThroughCalibrator pcalibrator; + ActsExamples::MeasurementCalibratorAdapter calibrator(pcalibrator, *measurements); + Acts::GainMatrixUpdater kfUpdater; #if Acts_VERSION_MAJOR < 34 - Acts::GainMatrixSmoother kfSmoother; + Acts::GainMatrixSmoother kfSmoother; #endif - Acts::MeasurementSelector measSel{m_sourcelinkSelectorCfg}; - - Acts::CombinatorialKalmanFilterExtensions - extensions; - extensions.calibrator.connect<&ActsExamples::MeasurementCalibratorAdapter::calibrate>( - &calibrator); - extensions.updater.connect< - &Acts::GainMatrixUpdater::operator()>( - &kfUpdater); + Acts::MeasurementSelector measSel{m_sourcelinkSelectorCfg}; + + Acts::CombinatorialKalmanFilterExtensions extensions; + extensions.calibrator.connect<&ActsExamples::MeasurementCalibratorAdapter::calibrate>( + &calibrator); + extensions.updater.connect<&Acts::GainMatrixUpdater::operator()>( + &kfUpdater); #if Acts_VERSION_MAJOR < 34 - extensions.smoother.connect< - &Acts::GainMatrixSmoother::operator()>( - &kfSmoother); + extensions.smoother.connect<&Acts::GainMatrixSmoother::operator()>( + &kfSmoother); #endif - extensions.measurementSelector.connect< - &Acts::MeasurementSelector::select>( - &measSel); + extensions.measurementSelector + .connect<&Acts::MeasurementSelector::select>(&measSel); - ActsExamples::IndexSourceLinkAccessor slAccessor; - slAccessor.container = &src_links; - Acts::SourceLinkAccessorDelegate - slAccessorDelegate; - slAccessorDelegate.connect<&ActsExamples::IndexSourceLinkAccessor::range>(&slAccessor); + ActsExamples::IndexSourceLinkAccessor slAccessor; + slAccessor.container = &src_links; + Acts::SourceLinkAccessorDelegate + slAccessorDelegate; + slAccessorDelegate.connect<&ActsExamples::IndexSourceLinkAccessor::range>(&slAccessor); - // Set the CombinatorialKalmanFilter options + // Set the CombinatorialKalmanFilter options #if Acts_VERSION_MAJOR < 34 - CKFTracking::TrackFinderOptions options( - m_geoctx, m_fieldctx, m_calibctx, slAccessorDelegate, - extensions, pOptions, &(*pSurface)); + CKFTracking::TrackFinderOptions options(m_geoctx, m_fieldctx, m_calibctx, slAccessorDelegate, + extensions, pOptions, &(*pSurface)); #else - CKFTracking::TrackFinderOptions options( - m_geoctx, m_fieldctx, m_calibctx, slAccessorDelegate, - extensions, pOptions); + CKFTracking::TrackFinderOptions options(m_geoctx, m_fieldctx, m_calibctx, slAccessorDelegate, + extensions, pOptions); #endif #if Acts_VERSION_MAJOR >= 34 - Acts::Propagator, Acts::Navigator> extrapolator( - Acts::EigenStepper<>(m_BField), - Acts::Navigator({m_geoSvc->trackingGeometry()}, - logger().cloneWithSuffix("Navigator")), - logger().cloneWithSuffix("Propagator")); - - Acts::PropagatorOptions, - Acts::AbortList> - extrapolationOptions(m_geoctx, m_fieldctx); + Acts::Propagator, Acts::Navigator> extrapolator( + Acts::EigenStepper<>(m_BField), + Acts::Navigator({m_geoSvc->trackingGeometry()}, logger().cloneWithSuffix("Navigator")), + logger().cloneWithSuffix("Propagator")); + + Acts::PropagatorOptions, + Acts::AbortList> + extrapolationOptions(m_geoctx, m_fieldctx); #endif - // Create track container - auto trackContainer = std::make_shared(); - auto trackStateContainer = std::make_shared(); - ActsExamples::TrackContainer acts_tracks(trackContainer, trackStateContainer); + // Create track container + auto trackContainer = std::make_shared(); + auto trackStateContainer = std::make_shared(); + ActsExamples::TrackContainer acts_tracks(trackContainer, trackStateContainer); - // Add seed number column - acts_tracks.addColumn("seed"); + // Add seed number column + acts_tracks.addColumn("seed"); #if Acts_VERSION_MAJOR >= 32 - Acts::ProxyAccessor seedNumber("seed"); + Acts::ProxyAccessor seedNumber("seed"); #else - Acts::TrackAccessor seedNumber("seed"); -#endif - std::vector failed_tracks; - - // Loop over seeds - for (std::size_t iseed = 0; iseed < acts_init_trk_params.size(); ++iseed) { - auto result = - (*m_trackFinderFunc)(acts_init_trk_params.at(iseed), options, acts_tracks); - - if (!result.ok()) { - m_log->debug("Track finding failed for seed {} with error {}", iseed, result.error()); - continue; - } - - // Set seed number for all found tracks - auto& tracksForSeed = result.value(); - for (auto& track : tracksForSeed) { - -#if Acts_VERSION_MAJOR >=34 - auto smoothingResult = Acts::smoothTrack(m_geoctx, track, logger()); - if (!smoothingResult.ok()) { - ACTS_ERROR("Smoothing for seed " - << iseed << " and track " << track.index() - << " failed with error " << smoothingResult.error()); - continue; - } - - auto extrapolationResult = Acts::extrapolateTrackToReferenceSurface( - track, *pSurface, extrapolator, extrapolationOptions, - Acts::TrackExtrapolationStrategy::firstOrLast, logger()); - if (!extrapolationResult.ok()) { - ACTS_ERROR("Extrapolation for seed " - << iseed << " and track " << track.index() - << " failed with error " << extrapolationResult.error()); - failed_tracks.push_back(track.index()); - continue; - } + Acts::TrackAccessor seedNumber("seed"); #endif + std::vector failed_tracks; + + // Loop over seeds + for (std::size_t iseed = 0; iseed < acts_init_trk_params.size(); ++iseed) { + auto result = (*m_trackFinderFunc)(acts_init_trk_params.at(iseed), options, acts_tracks); + + if (!result.ok()) { + m_log->debug("Track finding failed for seed {} with error {}", iseed, result.error()); + continue; + } - seedNumber(track) = iseed; - } - } + // Set seed number for all found tracks + auto& tracksForSeed = result.value(); + for (auto& track : tracksForSeed) { - for (Acts::TrackIndexType track_index : std::ranges::reverse_view(failed_tracks)) { - // NOTE This does not remove track states corresponding to the - // removed tracks. Doing so would require implementing some garbage - // collection. We'll just assume no algorithm will access them - // directly. - acts_tracks.removeTrack(track_index); +#if Acts_VERSION_MAJOR >= 34 + auto smoothingResult = Acts::smoothTrack(m_geoctx, track, logger()); + if (!smoothingResult.ok()) { + ACTS_ERROR("Smoothing for seed " << iseed << " and track " << track.index() + << " failed with error " << smoothingResult.error()); + continue; + } + + auto extrapolationResult = Acts::extrapolateTrackToReferenceSurface( + track, *pSurface, extrapolator, extrapolationOptions, + Acts::TrackExtrapolationStrategy::firstOrLast, logger()); + if (!extrapolationResult.ok()) { + ACTS_ERROR("Extrapolation for seed " << iseed << " and track " << track.index() + << " failed with error " + << extrapolationResult.error()); + failed_tracks.push_back(track.index()); + continue; + } +#endif + + seedNumber(track) = iseed; + } + } + + for (Acts::TrackIndexType track_index : std::ranges::reverse_view(failed_tracks)) { + // NOTE This does not remove track states corresponding to the + // removed tracks. Doing so would require implementing some garbage + // collection. We'll just assume no algorithm will access them + // directly. + acts_tracks.removeTrack(track_index); #if Acts_VERSION_MAJOR < 36 - // Workaround an upstream bug in Acts::VectorTrackContainer::removeTrack_impl() - // https://github.com/acts-project/acts/commit/94cf81f3f1109210b963977e0904516b949b1154 - trackContainer->m_particleHypothesis.erase(trackContainer->m_particleHypothesis.begin() + track_index); + // Workaround an upstream bug in Acts::VectorTrackContainer::removeTrack_impl() + // https://github.com/acts-project/acts/commit/94cf81f3f1109210b963977e0904516b949b1154 + trackContainer->m_particleHypothesis.erase(trackContainer->m_particleHypothesis.begin() + + track_index); #endif - } - - // Move track states and track container to const containers - // NOTE Using the non-const containers leads to references to - // implicitly converted temporaries inside the Trajectories. - auto constTrackStateContainer = - std::make_shared( - std::move(*trackStateContainer)); - - auto constTrackContainer = - std::make_shared( - std::move(*trackContainer)); - - // FIXME JANA2 std::vector requires wrapping ConstTrackContainer, instead of: - //ConstTrackContainer constTracks(constTrackContainer, constTrackStateContainer); - std::vector constTracks_v; - constTracks_v.push_back( - new ActsExamples::ConstTrackContainer( - constTrackContainer, - constTrackStateContainer)); - auto& constTracks = *(constTracks_v.front()); - - // Seed number column accessor + } + + // Move track states and track container to const containers + // NOTE Using the non-const containers leads to references to + // implicitly converted temporaries inside the Trajectories. + auto constTrackStateContainer = + std::make_shared(std::move(*trackStateContainer)); + + auto constTrackContainer = + std::make_shared(std::move(*trackContainer)); + + // FIXME JANA2 std::vector requires wrapping ConstTrackContainer, instead of: + //ConstTrackContainer constTracks(constTrackContainer, constTrackStateContainer); + std::vector constTracks_v; + constTracks_v.push_back( + new ActsExamples::ConstTrackContainer(constTrackContainer, constTrackStateContainer)); + auto& constTracks = *(constTracks_v.front()); + + // Seed number column accessor #if Acts_VERSION_MAJOR >= 32 - const Acts::ConstProxyAccessor constSeedNumber("seed"); + const Acts::ConstProxyAccessor constSeedNumber("seed"); #else - const Acts::ConstTrackAccessor constSeedNumber("seed"); + const Acts::ConstTrackAccessor constSeedNumber("seed"); #endif - // Prepare the output data with MultiTrajectory, per seed - std::vector acts_trajectories; - acts_trajectories.reserve(init_trk_params.size()); - - ActsExamples::Trajectories::IndexedParameters parameters; - std::vector tips; - - std::optional lastSeed; - for (const auto& track : constTracks) { - if (!lastSeed) { - lastSeed = constSeedNumber(track); - } - - if (constSeedNumber(track) != lastSeed.value()) { - // make copies and clear vectors - acts_trajectories.push_back(new ActsExamples::Trajectories( - constTracks.trackStateContainer(), - tips, parameters)); - - tips.clear(); - parameters.clear(); - } - - lastSeed = constSeedNumber(track); - - tips.push_back(track.tipIndex()); - parameters.emplace( - std::pair{track.tipIndex(), - ActsExamples::TrackParameters{track.referenceSurface().getSharedPtr(), - track.parameters(), track.covariance(), - track.particleHypothesis()}}); - } - - if (tips.empty()) { - m_log->info("Last trajectory is empty"); - } - - // last entry: move vectors - acts_trajectories.push_back(new ActsExamples::Trajectories( - constTracks.trackStateContainer(), - std::move(tips), std::move(parameters))); - - return std::make_tuple(std::move(acts_trajectories), std::move(constTracks_v)); + // Prepare the output data with MultiTrajectory, per seed + std::vector acts_trajectories; + acts_trajectories.reserve(init_trk_params.size()); + + ActsExamples::Trajectories::IndexedParameters parameters; + std::vector tips; + + std::optional lastSeed; + for (const auto& track : constTracks) { + if (!lastSeed) { + lastSeed = constSeedNumber(track); + } + + if (constSeedNumber(track) != lastSeed.value()) { + // make copies and clear vectors + acts_trajectories.push_back( + new ActsExamples::Trajectories(constTracks.trackStateContainer(), tips, parameters)); + + tips.clear(); + parameters.clear(); } + lastSeed = constSeedNumber(track); + + tips.push_back(track.tipIndex()); + parameters.emplace(std::pair{ + track.tipIndex(), + ActsExamples::TrackParameters{track.referenceSurface().getSharedPtr(), track.parameters(), + track.covariance(), track.particleHypothesis()}}); + } + + if (tips.empty()) { + m_log->info("Last trajectory is empty"); + } + + // last entry: move vectors + acts_trajectories.push_back(new ActsExamples::Trajectories( + constTracks.trackStateContainer(), std::move(tips), std::move(parameters))); + + return std::make_tuple(std::move(acts_trajectories), std::move(constTracks_v)); +} + } // namespace eicrecon diff --git a/src/algorithms/tracking/CKFTracking.h b/src/algorithms/tracking/CKFTracking.h index 896944c542..24e17abad4 100644 --- a/src/algorithms/tracking/CKFTracking.h +++ b/src/algorithms/tracking/CKFTracking.h @@ -36,62 +36,60 @@ namespace eicrecon { * \ingroup tracking */ - class CKFTracking: public WithPodConfig { - public: - /// Track finder function that takes input measurements, initial trackstate - /// and track finder options and returns some track-finder-specific result. - using TrackFinderOptions = - Acts::CombinatorialKalmanFilterOptions; - using TrackFinderResult = - Acts::Result>; - - /// Find function that takes the above parameters - /// @note This is separated into a virtual interface to keep compilation units - /// small - class CKFTrackingFunction { - public: - virtual ~CKFTrackingFunction() = default; - - virtual TrackFinderResult operator()(const ActsExamples::TrackParameters&, - const TrackFinderOptions&, - ActsExamples::TrackContainer&) const = 0; - }; - - /// Create the track finder function implementation. - /// The magnetic field is intentionally given by-value since the variantresults - /// contains shared_ptr anyways. - static std::shared_ptr makeCKFTrackingFunction( - std::shared_ptr trackingGeometry, - std::shared_ptr magneticField, - const Acts::Logger& logger); - - CKFTracking(); - - void init(std::shared_ptr geo_svc, std::shared_ptr log); - - std::tuple< - std::vector, - std::vector - > - process(const edm4eic::TrackParametersCollection& init_trk_params, - const edm4eic::Measurement2DCollection& meas2Ds); - - private: - std::shared_ptr m_log; - std::shared_ptr m_acts_logger{nullptr}; - std::shared_ptr m_trackFinderFunc; - std::shared_ptr m_geoSvc; - - std::shared_ptr m_BField = nullptr; - Acts::GeometryContext m_geoctx; - Acts::CalibrationContext m_calibctx; - Acts::MagneticFieldContext m_fieldctx; - - Acts::MeasurementSelector::Config m_sourcelinkSelectorCfg; - - /// Private access to the logging instance - const Acts::Logger& logger() const { return *m_acts_logger; } - }; - -} // namespace eicrecon::Reco +class CKFTracking : public WithPodConfig { +public: + /// Track finder function that takes input measurements, initial trackstate + /// and track finder options and returns some track-finder-specific result. + using TrackFinderOptions = + Acts::CombinatorialKalmanFilterOptions; + using TrackFinderResult = Acts::Result>; + + /// Find function that takes the above parameters + /// @note This is separated into a virtual interface to keep compilation units + /// small + class CKFTrackingFunction { + public: + virtual ~CKFTrackingFunction() = default; + + virtual TrackFinderResult operator()(const ActsExamples::TrackParameters&, + const TrackFinderOptions&, + ActsExamples::TrackContainer&) const = 0; + }; + + /// Create the track finder function implementation. + /// The magnetic field is intentionally given by-value since the variantresults + /// contains shared_ptr anyways. + static std::shared_ptr + makeCKFTrackingFunction(std::shared_ptr trackingGeometry, + std::shared_ptr magneticField, + const Acts::Logger& logger); + + CKFTracking(); + + void init(std::shared_ptr geo_svc, + std::shared_ptr log); + + std::tuple, + std::vector> + process(const edm4eic::TrackParametersCollection& init_trk_params, + const edm4eic::Measurement2DCollection& meas2Ds); + +private: + std::shared_ptr m_log; + std::shared_ptr m_acts_logger{nullptr}; + std::shared_ptr m_trackFinderFunc; + std::shared_ptr m_geoSvc; + + std::shared_ptr m_BField = nullptr; + Acts::GeometryContext m_geoctx; + Acts::CalibrationContext m_calibctx; + Acts::MagneticFieldContext m_fieldctx; + + Acts::MeasurementSelector::Config m_sourcelinkSelectorCfg; + + /// Private access to the logging instance + const Acts::Logger& logger() const { return *m_acts_logger; } +}; + +} // namespace eicrecon diff --git a/src/algorithms/tracking/CKFTrackingConfig.h b/src/algorithms/tracking/CKFTrackingConfig.h index 9332cf2205..08192192c2 100644 --- a/src/algorithms/tracking/CKFTrackingConfig.h +++ b/src/algorithms/tracking/CKFTrackingConfig.h @@ -7,9 +7,9 @@ #include namespace eicrecon { - struct CKFTrackingConfig { - std::vector etaBins = {}; // {this, "etaBins", {}}; - std::vector chi2CutOff = {15.}; //{this, "chi2CutOff", {15.}}; - std::vector numMeasurementsCutOff = {10}; //{this, "numMeasurementsCutOff", {10}}; - }; -} +struct CKFTrackingConfig { + std::vector etaBins = {}; // {this, "etaBins", {}}; + std::vector chi2CutOff = {15.}; //{this, "chi2CutOff", {15.}}; + std::vector numMeasurementsCutOff = {10}; //{this, "numMeasurementsCutOff", {10}}; +}; +} // namespace eicrecon diff --git a/src/algorithms/tracking/CKFTrackingFunction.cc b/src/algorithms/tracking/CKFTrackingFunction.cc index 5e748ff5b9..e7a6e2fb90 100644 --- a/src/algorithms/tracking/CKFTrackingFunction.cc +++ b/src/algorithms/tracking/CKFTrackingFunction.cc @@ -29,62 +29,56 @@ #include "ActsExamples/EventData/Track.hpp" #include "CKFTracking.h" -namespace eicrecon{ +namespace eicrecon { - using Updater = Acts::GainMatrixUpdater; - using Smoother = Acts::GainMatrixSmoother; +using Updater = Acts::GainMatrixUpdater; +using Smoother = Acts::GainMatrixSmoother; - using Stepper = Acts::EigenStepper<>; - using Navigator = Acts::Navigator; - using Propagator = Acts::Propagator; +using Stepper = Acts::EigenStepper<>; +using Navigator = Acts::Navigator; +using Propagator = Acts::Propagator; - using CKF = - Acts::CombinatorialKalmanFilter; +using CKF = Acts::CombinatorialKalmanFilter; - using TrackContainer = - Acts::TrackContainer; +using TrackContainer = + Acts::TrackContainer; - /** Finder implementation . +/** Finder implementation . * * \ingroup track */ - struct CKFTrackingFunctionImpl - : public eicrecon::CKFTracking::CKFTrackingFunction { - CKF trackFinder; - - CKFTrackingFunctionImpl(CKF&& f) : trackFinder(std::move(f)) {} - - eicrecon::CKFTracking::TrackFinderResult operator()( - const ActsExamples::TrackParameters& initialParameters, - const eicrecon::CKFTracking::TrackFinderOptions& options, - TrackContainer& tracks) const override { - return trackFinder.findTracks(initialParameters, options, tracks); - }; +struct CKFTrackingFunctionImpl : public eicrecon::CKFTracking::CKFTrackingFunction { + CKF trackFinder; + + CKFTrackingFunctionImpl(CKF&& f) : trackFinder(std::move(f)) {} + + eicrecon::CKFTracking::TrackFinderResult + operator()(const ActsExamples::TrackParameters& initialParameters, + const eicrecon::CKFTracking::TrackFinderOptions& options, + TrackContainer& tracks) const override { + return trackFinder.findTracks(initialParameters, options, tracks); }; +}; -} // namespace +} // namespace eicrecon namespace eicrecon { - std::shared_ptr - CKFTracking::makeCKFTrackingFunction( - std::shared_ptr trackingGeometry, - std::shared_ptr magneticField, - const Acts::Logger& logger) - { - Stepper stepper(std::move(magneticField)); - Navigator::Config cfg{trackingGeometry}; - cfg.resolvePassive = false; - cfg.resolveMaterial = true; - cfg.resolveSensitive = true; - Navigator navigator(cfg); - - Propagator propagator(std::move(stepper), std::move(navigator)); - CKF trackFinder(std::move(propagator), logger.cloneWithSuffix("CKF")); - - // build the track finder functions. owns the track finder object. - return std::make_shared(std::move(trackFinder)); - } - -} // namespace eicrecon::Reco +std::shared_ptr CKFTracking::makeCKFTrackingFunction( + std::shared_ptr trackingGeometry, + std::shared_ptr magneticField, const Acts::Logger& logger) { + Stepper stepper(std::move(magneticField)); + Navigator::Config cfg{trackingGeometry}; + cfg.resolvePassive = false; + cfg.resolveMaterial = true; + cfg.resolveSensitive = true; + Navigator navigator(cfg); + + Propagator propagator(std::move(stepper), std::move(navigator)); + CKF trackFinder(std::move(propagator), logger.cloneWithSuffix("CKF")); + + // build the track finder functions. owns the track finder object. + return std::make_shared(std::move(trackFinder)); +} + +} // namespace eicrecon diff --git a/src/algorithms/tracking/DD4hepBField.cc b/src/algorithms/tracking/DD4hepBField.cc index f8f7a1ffa2..468bcac327 100644 --- a/src/algorithms/tracking/DD4hepBField.cc +++ b/src/algorithms/tracking/DD4hepBField.cc @@ -15,35 +15,32 @@ namespace eicrecon::BField { - Acts::Result DD4hepBField::getField(const Acts::Vector3& position, - Acts::MagneticFieldProvider::Cache& /*cache*/) const - { - dd4hep::Position pos( - position[0] * (dd4hep::mm / Acts::UnitConstants::mm), - position[1] * (dd4hep::mm / Acts::UnitConstants::mm), - position[2] * (dd4hep::mm / Acts::UnitConstants::mm)); - - auto fieldObj = m_det->field(); - auto field = fieldObj.magneticField(pos) * (Acts::UnitConstants::T / dd4hep::tesla); - - // FIXME Acts doesn't seem to like exact zero components - if (field.x() * field.y() * field.z() == 0) { - static dd4hep::Direction epsilon{ - std::numeric_limits::epsilon(), - std::numeric_limits::epsilon(), - std::numeric_limits::epsilon() - }; - field += epsilon; - } - - return Acts::Result::success({field.x(), field.y(), field.z()}); +Acts::Result +DD4hepBField::getField(const Acts::Vector3& position, + Acts::MagneticFieldProvider::Cache& /*cache*/) const { + dd4hep::Position pos(position[0] * (dd4hep::mm / Acts::UnitConstants::mm), + position[1] * (dd4hep::mm / Acts::UnitConstants::mm), + position[2] * (dd4hep::mm / Acts::UnitConstants::mm)); + + auto fieldObj = m_det->field(); + auto field = fieldObj.magneticField(pos) * (Acts::UnitConstants::T / dd4hep::tesla); + + // FIXME Acts doesn't seem to like exact zero components + if (field.x() * field.y() * field.z() == 0) { + static dd4hep::Direction epsilon{std::numeric_limits::epsilon(), + std::numeric_limits::epsilon(), + std::numeric_limits::epsilon()}; + field += epsilon; } - Acts::Result DD4hepBField::getFieldGradient(const Acts::Vector3& position, - Acts::ActsMatrix<3, 3>& /*derivative*/, - Acts::MagneticFieldProvider::Cache& cache) const - { - return this->getField(position, cache); - } + return Acts::Result::success({field.x(), field.y(), field.z()}); +} + +Acts::Result +DD4hepBField::getFieldGradient(const Acts::Vector3& position, + Acts::ActsMatrix<3, 3>& /*derivative*/, + Acts::MagneticFieldProvider::Cache& cache) const { + return this->getField(position, cache); +} } // namespace eicrecon::BField diff --git a/src/algorithms/tracking/DD4hepBField.h b/src/algorithms/tracking/DD4hepBField.h index 12f088c235..838e9a7a5f 100644 --- a/src/algorithms/tracking/DD4hepBField.h +++ b/src/algorithms/tracking/DD4hepBField.h @@ -17,46 +17,43 @@ #include #include - - - namespace eicrecon::BField { - ///// The Context to be handed around - //struct ScalableBFieldContext { - // double scalor = 1.; - //}; +///// The Context to be handed around +//struct ScalableBFieldContext { +// double scalor = 1.; +//}; - /** Use the dd4hep magnetic field in acts. +/** Use the dd4hep magnetic field in acts. * * \ingroup magnets * \ingroup magsvc */ - class DD4hepBField final : public Acts::MagneticFieldProvider { - public: - gsl::not_null m_det; +class DD4hepBField final : public Acts::MagneticFieldProvider { +public: + gsl::not_null m_det; - public: - struct Cache { - Cache(const Acts::MagneticFieldContext& /*mcfg*/) { } - }; +public: + struct Cache { + Cache(const Acts::MagneticFieldContext& /*mcfg*/) {} + }; - Acts::MagneticFieldProvider::Cache makeCache(const Acts::MagneticFieldContext& mctx) const override - { + Acts::MagneticFieldProvider::Cache + makeCache(const Acts::MagneticFieldContext& mctx) const override { #if Acts_VERSION_MAJOR >= 32 - return Acts::MagneticFieldProvider::Cache(std::in_place_type, mctx); + return Acts::MagneticFieldProvider::Cache(std::in_place_type, mctx); #else - return Acts::MagneticFieldProvider::Cache::make(mctx); + return Acts::MagneticFieldProvider::Cache::make(mctx); #endif - } + } - /** construct constant magnetic field from field vector. + /** construct constant magnetic field from field vector. * * @param [in] DD4hep detector instance */ - explicit DD4hepBField(gsl::not_null det) : m_det(det) {} + explicit DD4hepBField(gsl::not_null det) : m_det(det) {} - /** retrieve magnetic field value. + /** retrieve magnetic field value. * * @param [in] position global position * @param [in] cache Cache object (is ignored) @@ -65,9 +62,10 @@ namespace eicrecon::BField { * @note The @p position is ignored and only kept as argument to provide * a consistent interface with other magnetic field services. */ - Acts::Result getField(const Acts::Vector3& position, Acts::MagneticFieldProvider::Cache& cache) const override; + Acts::Result getField(const Acts::Vector3& position, + Acts::MagneticFieldProvider::Cache& cache) const override; - /** @brief retrieve magnetic field value & its gradient + /** @brief retrieve magnetic field value & its gradient * * @param [in] position global position * @param [out] derivative gradient of magnetic field vector as (3x3) @@ -80,12 +78,11 @@ namespace eicrecon::BField { * @note currently the derivative is not calculated * @todo return derivative */ - Acts::Result getFieldGradient(const Acts::Vector3& position, Acts::ActsMatrix<3, 3>& /*derivative*/, - Acts::MagneticFieldProvider::Cache& cache) const override; - }; - - using BFieldVariant = std::variant>; - + Acts::Result + getFieldGradient(const Acts::Vector3& position, Acts::ActsMatrix<3, 3>& /*derivative*/, + Acts::MagneticFieldProvider::Cache& cache) const override; +}; +using BFieldVariant = std::variant>; } // namespace eicrecon::BField diff --git a/src/algorithms/tracking/IterativeVertexFinder.cc b/src/algorithms/tracking/IterativeVertexFinder.cc index 8485a0be59..aba9a1f098 100644 --- a/src/algorithms/tracking/IterativeVertexFinder.cc +++ b/src/algorithms/tracking/IterativeVertexFinder.cc @@ -72,17 +72,17 @@ std::unique_ptr eicrecon::IterativeVertexFinder::prod auto outputVertices = std::make_unique(); - using Propagator = Acts::Propagator>; + using Propagator = Acts::Propagator>; #if Acts_VERSION_MAJOR >= 33 - using Linearizer = Acts::HelicalTrackLinearizer; - using VertexFitter = Acts::FullBilloirVertexFitter; + using Linearizer = Acts::HelicalTrackLinearizer; + using VertexFitter = Acts::FullBilloirVertexFitter; using ImpactPointEstimator = Acts::ImpactPointEstimator; using VertexSeeder = Acts::ZScanVertexFinder; using VertexFinder = Acts::IterativeVertexFinder; using VertexFinderOptions = Acts::VertexingOptions; #else - using Linearizer = Acts::HelicalTrackLinearizer; - using VertexFitter = Acts::FullBilloirVertexFitter; + using Linearizer = Acts::HelicalTrackLinearizer; + using VertexFitter = Acts::FullBilloirVertexFitter; using ImpactPointEstimator = Acts::ImpactPointEstimator; using VertexSeeder = Acts::ZScanVertexFinder; using VertexFinder = Acts::IterativeVertexFinder; @@ -95,17 +95,17 @@ std::unique_ptr eicrecon::IterativeVertexFinder::prod // Set up propagator with void navigator #if Acts_VERSION_MAJOR >= 32 - auto propagator = std::make_shared( - stepper, Acts::VoidNavigator{}, logger().cloneWithSuffix("Prop")); + auto propagator = std::make_shared(stepper, Acts::VoidNavigator{}, + logger().cloneWithSuffix("Prop")); #else - auto propagator = std::make_shared( - stepper, Acts::detail::VoidNavigator{}, logger().cloneWithSuffix("Prop")); + auto propagator = std::make_shared(stepper, Acts::detail::VoidNavigator{}, + logger().cloneWithSuffix("Prop")); #endif // Setup the track linearizer #if Acts_VERSION_MAJOR >= 33 Linearizer::Config linearizerCfg; - linearizerCfg.bField = m_BField; + linearizerCfg.bField = m_BField; linearizerCfg.propagator = propagator; #else Linearizer::Config linearizerCfg(m_BField, propagator); @@ -115,10 +115,8 @@ std::unique_ptr eicrecon::IterativeVertexFinder::prod // Setup the vertex fitter VertexFitter::Config vertexFitterCfg; #if Acts_VERSION_MAJOR >= 33 - vertexFitterCfg.extractParameters - .connect<&Acts::InputTrack::extractParameters>(); - vertexFitterCfg.trackLinearizer.connect<&Linearizer::linearizeTrack>( - &linearizer); + vertexFitterCfg.extractParameters.connect<&Acts::InputTrack::extractParameters>(); + vertexFitterCfg.trackLinearizer.connect<&Linearizer::linearizeTrack>(&linearizer); #endif VertexFitter vertexFitter(vertexFitterCfg); @@ -127,43 +125,37 @@ std::unique_ptr eicrecon::IterativeVertexFinder::prod ImpactPointEstimator ipEst(ipEstCfg); VertexSeeder::Config seederCfg(ipEst); #if Acts_VERSION_MAJOR >= 33 - seederCfg.extractParameters - .connect<&Acts::InputTrack::extractParameters>(); + seederCfg.extractParameters.connect<&Acts::InputTrack::extractParameters>(); auto seeder = std::make_shared(seederCfg); #else VertexSeeder seeder(seederCfg); #endif // Set up the actual vertex finder - VertexFinder::Config finderCfg( - std::move(vertexFitter), + VertexFinder::Config finderCfg(std::move(vertexFitter), #if Acts_VERSION_MAJOR < 33 - std::move(linearizer), + std::move(linearizer), #endif - std::move(seeder), - std::move(ipEst)); + std::move(seeder), std::move(ipEst)); finderCfg.maxVertices = m_cfg.maxVertices; finderCfg.reassignTracksAfterFirstFit = m_cfg.reassignTracksAfterFirstFit; #if Acts_VERSION_MAJOR >= 31 - #if Acts_VERSION_MAJOR >= 33 +#if Acts_VERSION_MAJOR >= 33 finderCfg.extractParameters.connect<&Acts::InputTrack::extractParameters>(); finderCfg.trackLinearizer.connect<&Linearizer::linearizeTrack>(&linearizer); - #if Acts_VERSION_MAJOR >= 36 +#if Acts_VERSION_MAJOR >= 36 finderCfg.field = m_BField; - #else +#else finderCfg.field = std::dynamic_pointer_cast( - std::const_pointer_cast(m_BField)); - #endif - #endif + std::const_pointer_cast(m_BField)); +#endif +#endif VertexFinder finder(std::move(finderCfg)); #else VertexFinder finder(finderCfg); #endif #if Acts_VERSION_MAJOR >= 33 - Acts::IVertexFinder::State state( - std::in_place_type, - *m_BField, - m_fieldctx); + Acts::IVertexFinder::State state(std::in_place_type, *m_BField, m_fieldctx); #else VertexFinder::State state(*m_BField, m_fieldctx); #endif @@ -189,7 +181,9 @@ std::unique_ptr eicrecon::IterativeVertexFinder::prod #else inputTrackPointers.push_back(&(trajectory->trackParameters(tip))); #endif - m_log->trace("Track local position at input = {} mm, {} mm", par.localPosition().x() / Acts::UnitConstants::mm, par.localPosition().y() / Acts::UnitConstants::mm); + m_log->trace("Track local position at input = {} mm, {} mm", + par.localPosition().x() / Acts::UnitConstants::mm, + par.localPosition().y() / Acts::UnitConstants::mm); } } @@ -205,21 +199,22 @@ std::unique_ptr eicrecon::IterativeVertexFinder::prod } for (const auto& vtx : vertices) { - edm4eic::Cov4f cov(vtx.fullCovariance()(0,0), vtx.fullCovariance()(1,1), vtx.fullCovariance()(2,2), vtx.fullCovariance()(3,3), - vtx.fullCovariance()(0,1), vtx.fullCovariance()(0,2), vtx.fullCovariance()(0,3), - vtx.fullCovariance()(1,2), vtx.fullCovariance()(1,3), - vtx.fullCovariance()(2,3)); + edm4eic::Cov4f cov(vtx.fullCovariance()(0, 0), vtx.fullCovariance()(1, 1), + vtx.fullCovariance()(2, 2), vtx.fullCovariance()(3, 3), + vtx.fullCovariance()(0, 1), vtx.fullCovariance()(0, 2), + vtx.fullCovariance()(0, 3), vtx.fullCovariance()(1, 2), + vtx.fullCovariance()(1, 3), vtx.fullCovariance()(2, 3)); auto eicvertex = outputVertices->create(); - eicvertex.setType(1); // boolean flag if vertex is primary vertex of event - eicvertex.setChi2((float)vtx.fitQuality().first); // chi2 - eicvertex.setNdf((float)vtx.fitQuality().second); // ndf + eicvertex.setType(1); // boolean flag if vertex is primary vertex of event + eicvertex.setChi2((float)vtx.fitQuality().first); // chi2 + eicvertex.setNdf((float)vtx.fitQuality().second); // ndf eicvertex.setPosition({ - (float)vtx.position().x(), - (float)vtx.position().y(), - (float)vtx.position().z(), - (float)vtx.time(), - }); // vtxposition - eicvertex.setPositionError(cov); // covariance + (float)vtx.position().x(), + (float)vtx.position().y(), + (float)vtx.position().z(), + (float)vtx.time(), + }); // vtxposition + eicvertex.setPositionError(cov); // covariance for (const auto& t : vtx.tracks()) { #if Acts_VERSION_MAJOR >= 33 @@ -227,30 +222,38 @@ std::unique_ptr eicrecon::IterativeVertexFinder::prod #else const auto& par = *t.originalParams; #endif - m_log->trace("Track local position from vertex = {} mm, {} mm", par.localPosition().x() / Acts::UnitConstants::mm, par.localPosition().y() / Acts::UnitConstants::mm); + m_log->trace("Track local position from vertex = {} mm, {} mm", + par.localPosition().x() / Acts::UnitConstants::mm, + par.localPosition().y() / Acts::UnitConstants::mm); float loc_a = par.localPosition().x(); float loc_b = par.localPosition().y(); for (const auto& part : *reconParticles) { const auto& tracks = part.getTracks(); for (const auto trk : tracks) { - const auto& traj = trk.getTrajectory(); + const auto& traj = trk.getTrajectory(); const auto& trkPars = traj.getTrackParameters(); for (const auto par : trkPars) { const double EPSILON = 1.0e-4; // mm - if (fabs((par.getLoc().a / edm4eic::unit::mm) - (loc_a / Acts::UnitConstants::mm)) < EPSILON - && fabs((par.getLoc().b / edm4eic::unit::mm) - (loc_b / Acts::UnitConstants::mm)) < EPSILON) { - m_log->trace("From ReconParticles, track local position [Loc a, Loc b] = {} mm, {} mm", par.getLoc().a / edm4eic::unit::mm, par.getLoc().b / edm4eic::unit::mm); + if (fabs((par.getLoc().a / edm4eic::unit::mm) - (loc_a / Acts::UnitConstants::mm)) < + EPSILON && + fabs((par.getLoc().b / edm4eic::unit::mm) - (loc_b / Acts::UnitConstants::mm)) < + EPSILON) { + m_log->trace( + "From ReconParticles, track local position [Loc a, Loc b] = {} mm, {} mm", + par.getLoc().a / edm4eic::unit::mm, par.getLoc().b / edm4eic::unit::mm); eicvertex.addToAssociatedParticles(part); } // endif } // end for par } // end for trk } // end for part } // end for t - m_log->debug("One vertex found at (x,y,z) = ({}, {}, {}) mm.", vtx.position().x() / Acts::UnitConstants::mm, vtx.position().y() / Acts::UnitConstants::mm, vtx.position().z() / Acts::UnitConstants::mm); + m_log->debug("One vertex found at (x,y,z) = ({}, {}, {}) mm.", + vtx.position().x() / Acts::UnitConstants::mm, + vtx.position().y() / Acts::UnitConstants::mm, + vtx.position().z() / Acts::UnitConstants::mm); } // end for vtx - return std::move(outputVertices); } diff --git a/src/algorithms/tracking/IterativeVertexFinder.h b/src/algorithms/tracking/IterativeVertexFinder.h index 1bdb81ad93..05d1e45f79 100644 --- a/src/algorithms/tracking/IterativeVertexFinder.h +++ b/src/algorithms/tracking/IterativeVertexFinder.h @@ -25,7 +25,8 @@ class IterativeVertexFinder void init(std::shared_ptr geo_svc, std::shared_ptr log); std::unique_ptr - produce(std::vector trajectories, const edm4eic::ReconstructedParticleCollection* reconParticles); + produce(std::vector trajectories, + const edm4eic::ReconstructedParticleCollection* reconParticles); private: std::shared_ptr m_log; diff --git a/src/algorithms/tracking/IterativeVertexFinderConfig.h b/src/algorithms/tracking/IterativeVertexFinderConfig.h index 2a3cf77afc..a7f63afd85 100644 --- a/src/algorithms/tracking/IterativeVertexFinderConfig.h +++ b/src/algorithms/tracking/IterativeVertexFinderConfig.h @@ -3,7 +3,7 @@ namespace eicrecon { struct IterativeVertexFinderConfig { - int maxVertices = 10; + int maxVertices = 10; bool reassignTracksAfterFirstFit = true; }; diff --git a/src/algorithms/tracking/OrthogonalTrackSeedingConfig.h b/src/algorithms/tracking/OrthogonalTrackSeedingConfig.h index 5339977846..94585fc958 100644 --- a/src/algorithms/tracking/OrthogonalTrackSeedingConfig.h +++ b/src/algorithms/tracking/OrthogonalTrackSeedingConfig.h @@ -10,83 +10,91 @@ namespace eicrecon { - struct OrthogonalTrackSeedingConfig { +struct OrthogonalTrackSeedingConfig { - ////////////////////////////////////////////////////////////////////////// - /// SEED FINDER GENERAL PARAMETERS - float rMax = 440. * Acts::UnitConstants::mm; // max r to look for hits to compose seeds - float rMin = 33. * Acts::UnitConstants::mm; // min r to look for hits to compose seeds - float zMax = 1700. * Acts::UnitConstants::mm; // max z to look for hits to compose seeds - float zMin = -1500. * Acts::UnitConstants::mm; // min z to look for hits to compose seeds - float deltaRMinTopSP = 10. * Acts::UnitConstants::mm; // Min distance in r between middle and top SP in one seed - float deltaRMaxTopSP = 450. * Acts::UnitConstants::mm; // Max distance in r between middle and top SP in one seed - float deltaRMinBottomSP = 10. * Acts::UnitConstants::mm; // Min distance in r between middle and bottom SP in one seed - float deltaRMaxBottomSP = 200. * Acts::UnitConstants::mm; // Max distance in r between middle and bottom SP in one seed - float collisionRegionMin = -250 * Acts::UnitConstants::mm; // Min z for primary vertex - float collisionRegionMax = 250 * Acts::UnitConstants::mm; // Max z for primary vertex + ////////////////////////////////////////////////////////////////////////// + /// SEED FINDER GENERAL PARAMETERS + float rMax = 440. * Acts::UnitConstants::mm; // max r to look for hits to compose seeds + float rMin = 33. * Acts::UnitConstants::mm; // min r to look for hits to compose seeds + float zMax = 1700. * Acts::UnitConstants::mm; // max z to look for hits to compose seeds + float zMin = -1500. * Acts::UnitConstants::mm; // min z to look for hits to compose seeds + float deltaRMinTopSP = + 10. * Acts::UnitConstants::mm; // Min distance in r between middle and top SP in one seed + float deltaRMaxTopSP = + 450. * Acts::UnitConstants::mm; // Max distance in r between middle and top SP in one seed + float deltaRMinBottomSP = + 10. * Acts::UnitConstants::mm; // Min distance in r between middle and bottom SP in one seed + float deltaRMaxBottomSP = + 200. * Acts::UnitConstants::mm; // Max distance in r between middle and bottom SP in one seed + float collisionRegionMin = -250 * Acts::UnitConstants::mm; // Min z for primary vertex + float collisionRegionMax = 250 * Acts::UnitConstants::mm; // Max z for primary vertex - unsigned int maxSeedsPerSpM = 0; // max number of seeds a single middle sp can belong to - 1 - float cotThetaMax = 1.0 / tan(2. * atan(exp(-4.0))); // Cotangent of max theta angle (based on eta) + unsigned int maxSeedsPerSpM = 0; // max number of seeds a single middle sp can belong to - 1 + float cotThetaMax = + 1.0 / tan(2. * atan(exp(-4.0))); // Cotangent of max theta angle (based on eta) - float sigmaScattering = 5; // How many standard devs of scattering angles to consider - float radLengthPerSeed = 0.1; // Average radiation lengths of material on the length of a seed - float minPt = (100. * Acts::UnitConstants::MeV) / cotThetaMax; // MeV (in Acts units of GeV) - minimum transverse momentum - float bFieldInZ = 1.7 * Acts::UnitConstants::T; // T (in Acts units of GeV/[e*mm]) - Magnetic field strength - float beamPosX = 0; // x offset for beam position - float beamPosY = 0; // y offset for beam position - float impactMax = 3. * Acts::UnitConstants::mm; // Maximum transverse PCA allowed - float rMinMiddle = 20. * Acts::UnitConstants::mm; // Middle spacepoint must fall between these two radii - float rMaxMiddle = 400. * Acts::UnitConstants::mm; + float sigmaScattering = 5; // How many standard devs of scattering angles to consider + float radLengthPerSeed = 0.1; // Average radiation lengths of material on the length of a seed + float minPt = (100. * Acts::UnitConstants::MeV) / + cotThetaMax; // MeV (in Acts units of GeV) - minimum transverse momentum + float bFieldInZ = + 1.7 * Acts::UnitConstants::T; // T (in Acts units of GeV/[e*mm]) - Magnetic field strength + float beamPosX = 0; // x offset for beam position + float beamPosY = 0; // y offset for beam position + float impactMax = 3. * Acts::UnitConstants::mm; // Maximum transverse PCA allowed + float rMinMiddle = + 20. * Acts::UnitConstants::mm; // Middle spacepoint must fall between these two radii + float rMaxMiddle = 400. * Acts::UnitConstants::mm; - float deltaPhiMax = 0.085; // Max difference in phi between middle and either top or bottom sp + float deltaPhiMax = 0.085; // Max difference in phi between middle and either top or bottom sp - ////////////////////////////////////////////////////////////////////////// - /// SEED FILTER GENERAL PARAMETERS - /// The parameters below control the process of filtering out seeds before - /// sending them off to track reconstruction. These parameters first correspond - /// to global settings (more loose) followed by more strict cuts for the central - /// and forward/backward regions separately. + ////////////////////////////////////////////////////////////////////////// + /// SEED FILTER GENERAL PARAMETERS + /// The parameters below control the process of filtering out seeds before + /// sending them off to track reconstruction. These parameters first correspond + /// to global settings (more loose) followed by more strict cuts for the central + /// and forward/backward regions separately. - float maxSeedsPerSpM_filter = 0; // max number of seeds a single middle sp can belong to - 1 - float deltaRMin = 5* Acts::UnitConstants::mm; - bool seedConfirmation = false; - float deltaInvHelixDiameter = 0.00003 * 1. / Acts::UnitConstants::mm; - float impactWeightFactor = 1.; - float zOriginWeightFactor = 1.; - float compatSeedWeight = 200.; - size_t compatSeedLimit = 2; - float seedWeightIncrement = 0; + float maxSeedsPerSpM_filter = 0; // max number of seeds a single middle sp can belong to - 1 + float deltaRMin = 5 * Acts::UnitConstants::mm; + bool seedConfirmation = false; + float deltaInvHelixDiameter = 0.00003 * 1. / Acts::UnitConstants::mm; + float impactWeightFactor = 1.; + float zOriginWeightFactor = 1.; + float compatSeedWeight = 200.; + size_t compatSeedLimit = 2; + float seedWeightIncrement = 0; - /////////////////////////////////////// - /// CENTRAL SEED FILTER PARAMETERS - float zMinSeedConfCentral = -250 * Acts::UnitConstants::mm; - float zMaxSeedConfCentral = 250 * Acts::UnitConstants::mm; - float rMaxSeedConfCentral = 140 * Acts::UnitConstants::mm; - size_t nTopForLargeRCentral = 1; - size_t nTopForSmallRCentral = 2; - float seedConfMinBottomRadiusCentral = 60.0 * Acts::UnitConstants::mm; - float seedConfMaxZOriginCentral = 150.0 * Acts::UnitConstants::mm; - float minImpactSeedConfCentral = 1.0 * Acts::UnitConstants::mm; + /////////////////////////////////////// + /// CENTRAL SEED FILTER PARAMETERS + float zMinSeedConfCentral = -250 * Acts::UnitConstants::mm; + float zMaxSeedConfCentral = 250 * Acts::UnitConstants::mm; + float rMaxSeedConfCentral = 140 * Acts::UnitConstants::mm; + size_t nTopForLargeRCentral = 1; + size_t nTopForSmallRCentral = 2; + float seedConfMinBottomRadiusCentral = 60.0 * Acts::UnitConstants::mm; + float seedConfMaxZOriginCentral = 150.0 * Acts::UnitConstants::mm; + float minImpactSeedConfCentral = 1.0 * Acts::UnitConstants::mm; - /////////////////////////////////////// - /// FORWARD / BACKWARD SEED FILTER PARAMETERS - float zMinSeedConfForward = -3000 * Acts::UnitConstants::mm; - float zMaxSeedConfForward = 3000 * Acts::UnitConstants::mm; - float rMaxSeedConfForward = 140 * Acts::UnitConstants::mm; - size_t nTopForLargeRForward = 1; - size_t nTopForSmallRForward = 2; - float seedConfMinBottomRadiusForward = 60.0 * Acts::UnitConstants::mm; - float seedConfMaxZOriginForward = 150.0 * Acts::UnitConstants::mm; - float minImpactSeedConfForward = 1.0 * Acts::UnitConstants::mm; + /////////////////////////////////////// + /// FORWARD / BACKWARD SEED FILTER PARAMETERS + float zMinSeedConfForward = -3000 * Acts::UnitConstants::mm; + float zMaxSeedConfForward = 3000 * Acts::UnitConstants::mm; + float rMaxSeedConfForward = 140 * Acts::UnitConstants::mm; + size_t nTopForLargeRForward = 1; + size_t nTopForSmallRForward = 2; + float seedConfMinBottomRadiusForward = 60.0 * Acts::UnitConstants::mm; + float seedConfMaxZOriginForward = 150.0 * Acts::UnitConstants::mm; + float minImpactSeedConfForward = 1.0 * Acts::UnitConstants::mm; - ////////////////////////////////////// - ///Seed Covariance Error Matrix - float locaError = 1.5 * Acts::UnitConstants::mm; //Error on Loc a - float locbError = 1.5 * Acts::UnitConstants::mm; //Error on Loc b - float phiError = 0.02 * Acts::UnitConstants::rad; //Error on phi - float thetaError = 0.002 * Acts::UnitConstants::rad; //Error on theta - float qOverPError = 0.025 / Acts::UnitConstants::GeV; //Error on q over p - float timeError = 0.1 * Acts::UnitConstants::mm; //Error on time - // Note: Acts native time units are mm: https://acts.readthedocs.io/en/latest/core/definitions/units.html - }; -} + ////////////////////////////////////// + ///Seed Covariance Error Matrix + float locaError = 1.5 * Acts::UnitConstants::mm; //Error on Loc a + float locbError = 1.5 * Acts::UnitConstants::mm; //Error on Loc b + float phiError = 0.02 * Acts::UnitConstants::rad; //Error on phi + float thetaError = 0.002 * Acts::UnitConstants::rad; //Error on theta + float qOverPError = 0.025 / Acts::UnitConstants::GeV; //Error on q over p + float timeError = 0.1 * Acts::UnitConstants::mm; //Error on time + // Note: Acts native time units are mm: https://acts.readthedocs.io/en/latest/core/definitions/units.html +}; +} // namespace eicrecon diff --git a/src/algorithms/tracking/SpacePoint.h b/src/algorithms/tracking/SpacePoint.h index b459279313..672a80a15e 100644 --- a/src/algorithms/tracking/SpacePoint.h +++ b/src/algorithms/tracking/SpacePoint.h @@ -6,33 +6,28 @@ #include "ActsGeometryProvider.h" namespace eicrecon { -class SpacePoint : public edm4eic::TrackerHit -{ - public: - const Acts::Surface *m_surface = nullptr; +class SpacePoint : public edm4eic::TrackerHit { +public: + const Acts::Surface* m_surface = nullptr; SpacePoint(const TrackerHit& hit) : TrackerHit(hit) {} - void setSurface(std::shared_ptr m_geoSvc) - { - const auto its = m_geoSvc->surfaceMap().find(getCellID()); - if (its == m_geoSvc->surfaceMap().end()) { - m_surface = nullptr; - } - else { - m_surface = its->second; - } + void setSurface(std::shared_ptr m_geoSvc) { + const auto its = m_geoSvc->surfaceMap().find(getCellID()); + if (its == m_geoSvc->surfaceMap().end()) { + m_surface = nullptr; + } else { + m_surface = its->second; } + } float x() const { return getPosition()[0]; } float y() const { return getPosition()[1]; } float z() const { return getPosition()[2]; } float r() const { return std::hypot(x(), y()); } - float varianceR() const - { - return (std::pow(x(), 2) * getPositionError().xx + - std::pow(y(), 2) * getPositionError().yy) / - (std::pow(x(), 2) + std::pow(y(), 2)); + float varianceR() const { + return (std::pow(x(), 2) * getPositionError().xx + std::pow(y(), 2) * getPositionError().yy) / + (std::pow(x(), 2) + std::pow(y(), 2)); } float varianceZ() const { return getPositionError().zz; } @@ -43,24 +38,17 @@ class SpacePoint : public edm4eic::TrackerHit if (m_surface == nullptr) { return false; } - return m_surface->isOnSurface(Acts::GeometryContext(), {x(), y(), z()}, - {0, 0, 0}); + return m_surface->isOnSurface(Acts::GeometryContext(), {x(), y(), z()}, {0, 0, 0}); } }; -inline bool operator==(SpacePoint a, SpacePoint b) -{ - return (a.getObjectID() == b.getObjectID()); -} -static bool spCompare(SpacePoint r, SpacePoint s) -{ - return - std::hypot(r.x(), r.y(), r.z()) < - std::hypot(s.x(), s.y(), s.z()); +inline bool operator==(SpacePoint a, SpacePoint b) { return (a.getObjectID() == b.getObjectID()); } +static bool spCompare(SpacePoint r, SpacePoint s) { + return std::hypot(r.x(), r.y(), r.z()) < std::hypot(s.x(), s.y(), s.z()); } using SpacePointPtr = std::unique_ptr; /// Container of sim seed using SeedContainer = std::vector>; -} +} // namespace eicrecon diff --git a/src/algorithms/tracking/TrackParamTruthInit.cc b/src/algorithms/tracking/TrackParamTruthInit.cc index 2430c839ed..42abc525e7 100644 --- a/src/algorithms/tracking/TrackParamTruthInit.cc +++ b/src/algorithms/tracking/TrackParamTruthInit.cc @@ -23,122 +23,122 @@ #include "extensions/spdlog/SpdlogFormatters.h" // IWYU pragma: keep - -void eicrecon::TrackParamTruthInit::init(std::shared_ptr geo_svc, const std::shared_ptr logger) { - m_log = logger; - m_geoSvc = geo_svc; +void eicrecon::TrackParamTruthInit::init(std::shared_ptr geo_svc, + const std::shared_ptr logger) { + m_log = logger; + m_geoSvc = geo_svc; } std::unique_ptr eicrecon::TrackParamTruthInit::produce(const edm4hep::MCParticleCollection* mcparticles) { - // MCParticles uses numerical values in its specified units, - // while m_cfg is in the DD4hep unit system - - // Create output collection - auto track_parameters = std::make_unique(); - - // Loop over input particles - for (const auto& mcparticle: *mcparticles) { - - // require generatorStatus == 1 for stable generated particles in HepMC3 and DDSim gun - if (mcparticle.getGeneratorStatus() != 1 ) { - m_log->trace("ignoring particle with generatorStatus = {}", mcparticle.getGeneratorStatus()); - continue; - } - - // require close to interaction vertex - auto v = mcparticle.getVertex(); - if (abs(v.x) * dd4hep::mm > m_cfg.maxVertexX || - abs(v.y) * dd4hep::mm > m_cfg.maxVertexY || - abs(v.z) * dd4hep::mm > m_cfg.maxVertexZ) { - m_log->trace("ignoring particle with vs = {} [mm]", v); - continue; - } - - // require minimum momentum - const auto& p = mcparticle.getMomentum(); - const auto pmag = std::hypot(p.x, p.y, p.z); - if (pmag * dd4hep::GeV < m_cfg.minMomentum) { - m_log->trace("ignoring particle with p = {} GeV ", pmag); - continue; - } - - // require minimum pseudorapidity - const auto phi = std::atan2(p.y, p.x); - const auto theta = std::atan2(std::hypot(p.x, p.y), p.z); - const auto eta = -std::log(std::tan(theta/2)); - if (eta > m_cfg.maxEtaForward || eta < -std::abs(m_cfg.maxEtaBackward)) { - m_log->trace("ignoring particle with Eta = {}", eta); - continue; - } - - // get the particle charge - // note that we cannot trust the mcparticles charge, as DD4hep - // sets this value to zero! let's lookup by PDGID instead - const auto pdg = mcparticle.getPDG(); - const auto particle = m_particleSvc.particle(pdg); - double charge = std::copysign(1.0, particle.charge); - if (abs(charge) < std::numeric_limits::epsilon()) { - m_log->trace("ignoring neutral particle"); - continue; - } - - // modify initial momentum to avoid bleeding truth to results when fit fails - const auto pinit = pmag * (1.0 + m_cfg.momentumSmear * m_normDist(generator)); - - // define line surface for local position values - auto perigee = Acts::Surface::makeShared(Acts::Vector3(0,0,0)); - - // track particle back to transverse point-of-closest approach - // with respect to the defined line surface - auto linesurface_parameter = -(v.x*p.x + v.y*p.y)/(p.x*p.x + p.y*p.y); - - auto xpca = v.x + linesurface_parameter*p.x; - auto ypca = v.y + linesurface_parameter*p.y; - auto zpca = v.z + linesurface_parameter*p.z; - - Acts::Vector3 global(xpca, ypca, zpca); - Acts::Vector3 direction(sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta)); - - // convert from global to local coordinates using the defined line surface - auto local = perigee->globalToLocal(m_geoSvc->getActsGeometryContext(), global, direction); - - if(!local.ok()) - { - m_log->error("skipping the track because globaltoLocal function failed"); - continue; - } - - Acts::Vector2 localpos = local.value(); - - // Insert into edm4eic::TrackParameters, which uses numerical values in its specified units - auto track_parameter = track_parameters->create(); - track_parameter.setType(-1); // type --> seed(-1) - track_parameter.setLoc({static_cast(localpos(0)), static_cast(localpos(1))}); // 2d location on surface [mm] - track_parameter.setPhi(phi); // phi [rad] - track_parameter.setTheta(theta); // theta [rad] - track_parameter.setQOverP(charge / (pinit / dd4hep::GeV)); // Q/p [e/GeV] - track_parameter.setTime(mcparticle.getTime()); // time [ns] - edm4eic::Cov6f cov; - cov(0,0) = 1.0; // loc0 - cov(1,1) = 1.0; // loc1 - cov(2,2) = 0.05; // phi - cov(3,3) = 0.01; // theta - cov(4,4) = 0.1; // qOverP - cov(5,5) = 10e9; // time - track_parameter.setCovariance(cov); - - // Debug output - if (m_log->level() <= spdlog::level::debug) { - m_log->debug("Invoke track finding seeded by truth particle with:"); - m_log->debug(" p = {} GeV (smeared to {} GeV)", pmag / dd4hep::GeV, pinit / dd4hep::GeV); - m_log->debug(" q = {}", charge); - m_log->debug(" q/p = {} e/GeV (smeared to {} e/GeV)", charge / (pmag / dd4hep::GeV), charge / (pinit / dd4hep::GeV)); - m_log->debug(" theta = {}", theta); - m_log->debug(" phi = {}", phi); - } + // MCParticles uses numerical values in its specified units, + // while m_cfg is in the DD4hep unit system + + // Create output collection + auto track_parameters = std::make_unique(); + + // Loop over input particles + for (const auto& mcparticle : *mcparticles) { + + // require generatorStatus == 1 for stable generated particles in HepMC3 and DDSim gun + if (mcparticle.getGeneratorStatus() != 1) { + m_log->trace("ignoring particle with generatorStatus = {}", mcparticle.getGeneratorStatus()); + continue; + } + + // require close to interaction vertex + auto v = mcparticle.getVertex(); + if (abs(v.x) * dd4hep::mm > m_cfg.maxVertexX || abs(v.y) * dd4hep::mm > m_cfg.maxVertexY || + abs(v.z) * dd4hep::mm > m_cfg.maxVertexZ) { + m_log->trace("ignoring particle with vs = {} [mm]", v); + continue; } - return std::move(track_parameters); + // require minimum momentum + const auto& p = mcparticle.getMomentum(); + const auto pmag = std::hypot(p.x, p.y, p.z); + if (pmag * dd4hep::GeV < m_cfg.minMomentum) { + m_log->trace("ignoring particle with p = {} GeV ", pmag); + continue; + } + + // require minimum pseudorapidity + const auto phi = std::atan2(p.y, p.x); + const auto theta = std::atan2(std::hypot(p.x, p.y), p.z); + const auto eta = -std::log(std::tan(theta / 2)); + if (eta > m_cfg.maxEtaForward || eta < -std::abs(m_cfg.maxEtaBackward)) { + m_log->trace("ignoring particle with Eta = {}", eta); + continue; + } + + // get the particle charge + // note that we cannot trust the mcparticles charge, as DD4hep + // sets this value to zero! let's lookup by PDGID instead + const auto pdg = mcparticle.getPDG(); + const auto particle = m_particleSvc.particle(pdg); + double charge = std::copysign(1.0, particle.charge); + if (abs(charge) < std::numeric_limits::epsilon()) { + m_log->trace("ignoring neutral particle"); + continue; + } + + // modify initial momentum to avoid bleeding truth to results when fit fails + const auto pinit = pmag * (1.0 + m_cfg.momentumSmear * m_normDist(generator)); + + // define line surface for local position values + auto perigee = Acts::Surface::makeShared(Acts::Vector3(0, 0, 0)); + + // track particle back to transverse point-of-closest approach + // with respect to the defined line surface + auto linesurface_parameter = -(v.x * p.x + v.y * p.y) / (p.x * p.x + p.y * p.y); + + auto xpca = v.x + linesurface_parameter * p.x; + auto ypca = v.y + linesurface_parameter * p.y; + auto zpca = v.z + linesurface_parameter * p.z; + + Acts::Vector3 global(xpca, ypca, zpca); + Acts::Vector3 direction(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); + + // convert from global to local coordinates using the defined line surface + auto local = perigee->globalToLocal(m_geoSvc->getActsGeometryContext(), global, direction); + + if (!local.ok()) { + m_log->error("skipping the track because globaltoLocal function failed"); + continue; + } + + Acts::Vector2 localpos = local.value(); + + // Insert into edm4eic::TrackParameters, which uses numerical values in its specified units + auto track_parameter = track_parameters->create(); + track_parameter.setType(-1); // type --> seed(-1) + track_parameter.setLoc({static_cast(localpos(0)), + static_cast(localpos(1))}); // 2d location on surface [mm] + track_parameter.setPhi(phi); // phi [rad] + track_parameter.setTheta(theta); // theta [rad] + track_parameter.setQOverP(charge / (pinit / dd4hep::GeV)); // Q/p [e/GeV] + track_parameter.setTime(mcparticle.getTime()); // time [ns] + edm4eic::Cov6f cov; + cov(0, 0) = 1.0; // loc0 + cov(1, 1) = 1.0; // loc1 + cov(2, 2) = 0.05; // phi + cov(3, 3) = 0.01; // theta + cov(4, 4) = 0.1; // qOverP + cov(5, 5) = 10e9; // time + track_parameter.setCovariance(cov); + + // Debug output + if (m_log->level() <= spdlog::level::debug) { + m_log->debug("Invoke track finding seeded by truth particle with:"); + m_log->debug(" p = {} GeV (smeared to {} GeV)", pmag / dd4hep::GeV, + pinit / dd4hep::GeV); + m_log->debug(" q = {}", charge); + m_log->debug(" q/p = {} e/GeV (smeared to {} e/GeV)", charge / (pmag / dd4hep::GeV), + charge / (pinit / dd4hep::GeV)); + m_log->debug(" theta = {}", theta); + m_log->debug(" phi = {}", phi); + } + } + return std::move(track_parameters); } diff --git a/src/algorithms/tracking/TrackParamTruthInit.h b/src/algorithms/tracking/TrackParamTruthInit.h index 0af8b5980a..bc38445c06 100644 --- a/src/algorithms/tracking/TrackParamTruthInit.h +++ b/src/algorithms/tracking/TrackParamTruthInit.h @@ -16,24 +16,23 @@ #include "algorithms/interfaces/WithPodConfig.h" namespace eicrecon { - class TrackParamTruthInit: public WithPodConfig { +class TrackParamTruthInit : public WithPodConfig { - public: +public: + void init(std::shared_ptr geo_svc, + const std::shared_ptr logger); - void init(std::shared_ptr geo_svc, const std::shared_ptr logger); + std::unique_ptr + produce(const edm4hep::MCParticleCollection* parts); - std::unique_ptr - produce(const edm4hep::MCParticleCollection* parts); +private: + std::shared_ptr m_log; + std::shared_ptr m_geoSvc; - private: - std::shared_ptr m_log; - std::shared_ptr m_geoSvc; + const algorithms::ParticleSvc& m_particleSvc = algorithms::ParticleSvc::instance(); - const algorithms::ParticleSvc& m_particleSvc = algorithms::ParticleSvc::instance(); - - std::default_random_engine generator; // TODO: need something more appropriate here - std::uniform_int_distribution m_uniformIntDist{-1, 1}; // defaults to min=-1, max=1 - std::normal_distribution m_normDist; - - }; -} // namespace eicrecon + std::default_random_engine generator; // TODO: need something more appropriate here + std::uniform_int_distribution m_uniformIntDist{-1, 1}; // defaults to min=-1, max=1 + std::normal_distribution m_normDist; +}; +} // namespace eicrecon diff --git a/src/algorithms/tracking/TrackParamTruthInitConfig.h b/src/algorithms/tracking/TrackParamTruthInitConfig.h index d09c479b8e..09ae8ec69a 100644 --- a/src/algorithms/tracking/TrackParamTruthInitConfig.h +++ b/src/algorithms/tracking/TrackParamTruthInitConfig.h @@ -8,12 +8,11 @@ struct TrackParamTruthInitConfig { - double maxVertexX = 80 * dd4hep::mm; - double maxVertexY = 80 * dd4hep::mm; - double maxVertexZ = 200 * dd4hep::mm; - double minMomentum = 100 * dd4hep::MeV; - double maxEtaForward = 6.0; - double maxEtaBackward = 4.1; - double momentumSmear = 0.1; - + double maxVertexX = 80 * dd4hep::mm; + double maxVertexY = 80 * dd4hep::mm; + double maxVertexZ = 200 * dd4hep::mm; + double minMomentum = 100 * dd4hep::MeV; + double maxEtaForward = 6.0; + double maxEtaBackward = 4.1; + double momentumSmear = 0.1; }; diff --git a/src/algorithms/tracking/TrackProjector.cc b/src/algorithms/tracking/TrackProjector.cc index 7a5815dc50..4b1ea0c4e9 100644 --- a/src/algorithms/tracking/TrackProjector.cc +++ b/src/algorithms/tracking/TrackProjector.cc @@ -25,201 +25,174 @@ #include "extensions/spdlog/SpdlogFormatters.h" // IWYU pragma: keep #if FMT_VERSION >= 90000 -template<> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; #endif // FMT_VERSION >= 90000 namespace eicrecon { - void - TrackProjector::init(std::shared_ptr geo_svc, std::shared_ptr logger) { - m_log = logger; - m_geo_provider = geo_svc; +void TrackProjector::init(std::shared_ptr geo_svc, + std::shared_ptr logger) { + m_log = logger; + m_geo_provider = geo_svc; +} + +std::unique_ptr +TrackProjector::execute(std::vector trajectories) { + + // create output collections + auto track_segments = std::make_unique(); + m_log->debug("Track projector event process. Num of input trajectories: {}", + std::size(trajectories)); + + // Loop over the trajectories + for (const auto& traj : trajectories) { + // Get the entry index for the single trajectory + // The trajectory entry indices and the multiTrajectory + const auto& mj = traj->multiTrajectory(); + const auto& trackTips = traj->tips(); + m_log->debug("------ Trajectory ------"); + m_log->debug(" Num of elements in trackTips {}", trackTips.size()); + + // Skip empty + if (trackTips.empty()) { + m_log->debug(" Empty multiTrajectory."); + continue; } - - - std::unique_ptr TrackProjector::execute(std::vector trajectories) { - - // create output collections - auto track_segments = std::make_unique(); - m_log->debug("Track projector event process. Num of input trajectories: {}", std::size(trajectories)); - - // Loop over the trajectories - for (const auto &traj: trajectories) { - // Get the entry index for the single trajectory - // The trajectory entry indices and the multiTrajectory - const auto &mj = traj->multiTrajectory(); - const auto &trackTips = traj->tips(); - m_log->debug("------ Trajectory ------"); - m_log->debug(" Num of elements in trackTips {}", trackTips.size()); - - // Skip empty - if (trackTips.empty()) { - m_log->debug(" Empty multiTrajectory."); - continue; - } - const auto &trackTip = trackTips.front(); - - // Collect the trajectory summary info - auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); - int m_nMeasurements = trajState.nMeasurements; - int m_nStates = trajState.nStates; - int m_nCalibrated = 0; - m_log->debug(" Num measurement in trajectory {}", m_nMeasurements); - m_log->debug(" Num state in trajectory {}", m_nStates); - - auto track_segment = track_segments->create(); - - // visit the track points - mj.visitBackwards(trackTip, [&](auto &&trackstate) { - // get volume info - auto geoID = trackstate.referenceSurface().geometryId(); - auto volume = geoID.volume(); - auto layer = geoID.layer(); - - if (trackstate.hasCalibrated()) { - m_nCalibrated++; - } - - // get track state bound parameters and their boundCovs - const auto &boundParams = trackstate.predicted(); - const auto &boundCov = trackstate.predictedCovariance(); - - // convert local to global - auto global = trackstate.referenceSurface().localToGlobal( - m_geo_provider->getActsGeometryContext(), - {boundParams[Acts::eBoundLoc0], boundParams[Acts::eBoundLoc1]}, - Acts::makeDirectionFromPhiTheta( - boundParams[Acts::eBoundPhi], - boundParams[Acts::eBoundTheta] - ) - ); + const auto& trackTip = trackTips.front(); + + // Collect the trajectory summary info + auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); + int m_nMeasurements = trajState.nMeasurements; + int m_nStates = trajState.nStates; + int m_nCalibrated = 0; + m_log->debug(" Num measurement in trajectory {}", m_nMeasurements); + m_log->debug(" Num state in trajectory {}", m_nStates); + + auto track_segment = track_segments->create(); + + // visit the track points + mj.visitBackwards(trackTip, [&](auto&& trackstate) { + // get volume info + auto geoID = trackstate.referenceSurface().geometryId(); + auto volume = geoID.volume(); + auto layer = geoID.layer(); + + if (trackstate.hasCalibrated()) { + m_nCalibrated++; + } + + // get track state bound parameters and their boundCovs + const auto& boundParams = trackstate.predicted(); + const auto& boundCov = trackstate.predictedCovariance(); + + // convert local to global + auto global = trackstate.referenceSurface().localToGlobal( + m_geo_provider->getActsGeometryContext(), + {boundParams[Acts::eBoundLoc0], boundParams[Acts::eBoundLoc1]}, + Acts::makeDirectionFromPhiTheta(boundParams[Acts::eBoundPhi], + boundParams[Acts::eBoundTheta])); #if Acts_VERSION_MAJOR >= 34 - auto freeParams = Acts::transformBoundToFreeParameters( - trackstate.referenceSurface(), - m_geo_provider->getActsGeometryContext(), - boundParams); - auto jacobian = trackstate.referenceSurface().boundToFreeJacobian( - m_geo_provider->getActsGeometryContext(), - freeParams.template segment<3>(Acts::eFreePos0), - freeParams.template segment<3>(Acts::eFreeDir0) - ); + auto freeParams = Acts::transformBoundToFreeParameters( + trackstate.referenceSurface(), m_geo_provider->getActsGeometryContext(), boundParams); + auto jacobian = trackstate.referenceSurface().boundToFreeJacobian( + m_geo_provider->getActsGeometryContext(), freeParams.template segment<3>(Acts::eFreePos0), + freeParams.template segment<3>(Acts::eFreeDir0)); #else auto jacobian = trackstate.referenceSurface().boundToFreeJacobian( m_geo_provider->getActsGeometryContext(), boundParams ); #endif - auto freeCov = jacobian * boundCov * jacobian.transpose(); - - // global position - const decltype(edm4eic::TrackPoint::position) position{ - static_cast(global.x()), - static_cast(global.y()), - static_cast(global.z()) - }; - - // local position - const decltype(edm4eic::TrackParametersData::loc) loc{ - static_cast(boundParams[Acts::eBoundLoc0]), - static_cast(boundParams[Acts::eBoundLoc1]) - }; - const edm4eic::Cov2f locError{ - static_cast(boundCov(Acts::eBoundLoc0, Acts::eBoundLoc0)), - static_cast(boundCov(Acts::eBoundLoc1, Acts::eBoundLoc1)), - static_cast(boundCov(Acts::eBoundLoc0, Acts::eBoundLoc1)) - }; - const decltype(edm4eic::TrackPoint::positionError) positionError{ - static_cast(freeCov(Acts::eFreePos0, Acts::eFreePos0)), - static_cast(freeCov(Acts::eFreePos1, Acts::eFreePos1)), - static_cast(freeCov(Acts::eFreePos2, Acts::eFreePos2)), - static_cast(freeCov(Acts::eFreePos0, Acts::eFreePos1)), - static_cast(freeCov(Acts::eFreePos0, Acts::eFreePos2)), - static_cast(freeCov(Acts::eFreePos1, Acts::eFreePos2)), - }; - - // momentum - const decltype(edm4eic::TrackPoint::momentum) momentum = edm4hep::utils::sphericalToVector( - static_cast(1.0 / std::abs(boundParams[Acts::eBoundQOverP])), - static_cast(boundParams[Acts::eBoundTheta]), - static_cast(boundParams[Acts::eBoundPhi]) - ); - const decltype(edm4eic::TrackPoint::momentumError) momentumError{ - static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundTheta)), - static_cast(boundCov(Acts::eBoundPhi, Acts::eBoundPhi)), - static_cast(boundCov(Acts::eBoundQOverP, Acts::eBoundQOverP)), - static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundPhi)), - static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundQOverP)), - static_cast(boundCov(Acts::eBoundPhi, Acts::eBoundQOverP)) - }; - const float time{static_cast(boundParams(Acts::eBoundTime))}; - const float timeError{static_cast(sqrt(boundCov(Acts::eBoundTime, Acts::eBoundTime)))}; - const float theta(boundParams[Acts::eBoundTheta]); - const float phi(boundParams[Acts::eBoundPhi]); - const decltype(edm4eic::TrackPoint::directionError) directionError{ - static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundTheta)), - static_cast(boundCov(Acts::eBoundPhi, Acts::eBoundPhi)), - static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundPhi)) - }; - const float pathLength = static_cast(trackstate.pathLength()); - const float pathLengthError = 0; - - uint64_t surface = trackstate.referenceSurface().geometryId().value(); - uint32_t system = 0; - - // Store track point - track_segment.addToPoints({ - surface, - system, - position, - positionError, - momentum, - momentumError, - time, - timeError, - theta, - phi, - directionError, - pathLength, - pathLengthError - }); - - - m_log->debug(" ******************************"); - m_log->debug(" position: {}", position); - m_log->debug(" positionError: {}", positionError); - m_log->debug(" momentum: {}", momentum); - m_log->debug(" momentumError: {}", momentumError); - m_log->debug(" time: {}", time); - m_log->debug(" timeError: {}", timeError); - m_log->debug(" theta: {}", theta); - m_log->debug(" phi: {}", phi); - m_log->debug(" directionError: {}", directionError); - m_log->debug(" pathLength: {}", pathLength); - m_log->debug(" pathLengthError: {}", pathLengthError); - m_log->debug(" geoID = {}", geoID); - m_log->debug(" volume = {}, layer = {}", volume, layer); - m_log->debug(" pathlength = {}", pathLength); - m_log->debug(" hasCalibrated = {}", trackstate.hasCalibrated()); - m_log->debug(" ******************************"); - - // Local position on the reference surface. - //m_log->debug("boundParams[eBoundLoc0] = {}", boundParams[Acts::eBoundLoc0]); - //m_log->debug("boundParams[eBoundLoc1] = {}", boundParams[Acts::eBoundLoc1]); - //m_log->debug("boundParams[eBoundPhi] = {}", boundParams[Acts::eBoundPhi]); - //m_log->debug("boundParams[eBoundTheta] = {}", boundParams[Acts::eBoundTheta]); - //m_log->debug("boundParams[eBoundQOverP] = {}", boundParams[Acts::eBoundQOverP]); - //m_log->debug("boundParams[eBoundTime] = {}", boundParams[Acts::eBoundTime]); - //m_log->debug("predicted variables: {}", trackstate.predicted()); - }); - - m_log->debug(" Num calibrated state in trajectory {}", m_nCalibrated); - m_log->debug("------ end of trajectory process ------"); - } - - m_log->debug("END OF Track projector event process"); - return std::move(track_segments); - } - - -} // namespace eicrecon::Reco + auto freeCov = jacobian * boundCov * jacobian.transpose(); + + // global position + const decltype(edm4eic::TrackPoint::position) position{static_cast(global.x()), + static_cast(global.y()), + static_cast(global.z())}; + + // local position + const decltype(edm4eic::TrackParametersData::loc) loc{ + static_cast(boundParams[Acts::eBoundLoc0]), + static_cast(boundParams[Acts::eBoundLoc1])}; + const edm4eic::Cov2f locError{ + static_cast(boundCov(Acts::eBoundLoc0, Acts::eBoundLoc0)), + static_cast(boundCov(Acts::eBoundLoc1, Acts::eBoundLoc1)), + static_cast(boundCov(Acts::eBoundLoc0, Acts::eBoundLoc1))}; + const decltype(edm4eic::TrackPoint::positionError) positionError{ + static_cast(freeCov(Acts::eFreePos0, Acts::eFreePos0)), + static_cast(freeCov(Acts::eFreePos1, Acts::eFreePos1)), + static_cast(freeCov(Acts::eFreePos2, Acts::eFreePos2)), + static_cast(freeCov(Acts::eFreePos0, Acts::eFreePos1)), + static_cast(freeCov(Acts::eFreePos0, Acts::eFreePos2)), + static_cast(freeCov(Acts::eFreePos1, Acts::eFreePos2)), + }; + + // momentum + const decltype(edm4eic::TrackPoint::momentum) momentum = edm4hep::utils::sphericalToVector( + static_cast(1.0 / std::abs(boundParams[Acts::eBoundQOverP])), + static_cast(boundParams[Acts::eBoundTheta]), + static_cast(boundParams[Acts::eBoundPhi])); + const decltype(edm4eic::TrackPoint::momentumError) momentumError{ + static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundTheta)), + static_cast(boundCov(Acts::eBoundPhi, Acts::eBoundPhi)), + static_cast(boundCov(Acts::eBoundQOverP, Acts::eBoundQOverP)), + static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundPhi)), + static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundQOverP)), + static_cast(boundCov(Acts::eBoundPhi, Acts::eBoundQOverP))}; + const float time{static_cast(boundParams(Acts::eBoundTime))}; + const float timeError{static_cast(sqrt(boundCov(Acts::eBoundTime, Acts::eBoundTime)))}; + const float theta(boundParams[Acts::eBoundTheta]); + const float phi(boundParams[Acts::eBoundPhi]); + const decltype(edm4eic::TrackPoint::directionError) directionError{ + static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundTheta)), + static_cast(boundCov(Acts::eBoundPhi, Acts::eBoundPhi)), + static_cast(boundCov(Acts::eBoundTheta, Acts::eBoundPhi))}; + const float pathLength = static_cast(trackstate.pathLength()); + const float pathLengthError = 0; + + uint64_t surface = trackstate.referenceSurface().geometryId().value(); + uint32_t system = 0; + + // Store track point + track_segment.addToPoints({surface, system, position, positionError, momentum, momentumError, + time, timeError, theta, phi, directionError, pathLength, + pathLengthError}); + + m_log->debug(" ******************************"); + m_log->debug(" position: {}", position); + m_log->debug(" positionError: {}", positionError); + m_log->debug(" momentum: {}", momentum); + m_log->debug(" momentumError: {}", momentumError); + m_log->debug(" time: {}", time); + m_log->debug(" timeError: {}", timeError); + m_log->debug(" theta: {}", theta); + m_log->debug(" phi: {}", phi); + m_log->debug(" directionError: {}", directionError); + m_log->debug(" pathLength: {}", pathLength); + m_log->debug(" pathLengthError: {}", pathLengthError); + m_log->debug(" geoID = {}", geoID); + m_log->debug(" volume = {}, layer = {}", volume, layer); + m_log->debug(" pathlength = {}", pathLength); + m_log->debug(" hasCalibrated = {}", trackstate.hasCalibrated()); + m_log->debug(" ******************************"); + + // Local position on the reference surface. + //m_log->debug("boundParams[eBoundLoc0] = {}", boundParams[Acts::eBoundLoc0]); + //m_log->debug("boundParams[eBoundLoc1] = {}", boundParams[Acts::eBoundLoc1]); + //m_log->debug("boundParams[eBoundPhi] = {}", boundParams[Acts::eBoundPhi]); + //m_log->debug("boundParams[eBoundTheta] = {}", boundParams[Acts::eBoundTheta]); + //m_log->debug("boundParams[eBoundQOverP] = {}", boundParams[Acts::eBoundQOverP]); + //m_log->debug("boundParams[eBoundTime] = {}", boundParams[Acts::eBoundTime]); + //m_log->debug("predicted variables: {}", trackstate.predicted()); + }); + + m_log->debug(" Num calibrated state in trajectory {}", m_nCalibrated); + m_log->debug("------ end of trajectory process ------"); + } + + m_log->debug("END OF Track projector event process"); + return std::move(track_segments); +} + +} // namespace eicrecon diff --git a/src/algorithms/tracking/TrackProjector.h b/src/algorithms/tracking/TrackProjector.h index 2af5a74bb9..fdacdbf0dc 100644 --- a/src/algorithms/tracking/TrackProjector.h +++ b/src/algorithms/tracking/TrackProjector.h @@ -12,27 +12,24 @@ #include "ActsGeometryProvider.h" - namespace eicrecon { - /** Extract the particles form fit trajectories. +/** Extract the particles form fit trajectories. * * \ingroup tracking */ - class TrackProjector { - - public: - - void init(std::shared_ptr geo_svc, std::shared_ptr logger); - - std::unique_ptr execute(std::vector trajectories); - - private: - std::shared_ptr m_geo_provider; - std::shared_ptr m_log; +class TrackProjector { - }; +public: + void init(std::shared_ptr geo_svc, + std::shared_ptr logger); + std::unique_ptr + execute(std::vector trajectories); +private: + std::shared_ptr m_geo_provider; + std::shared_ptr m_log; +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/algorithms/tracking/TrackPropagation.cc b/src/algorithms/tracking/TrackPropagation.cc index 6ad4e98138..6ffe82a803 100644 --- a/src/algorithms/tracking/TrackPropagation.cc +++ b/src/algorithms/tracking/TrackPropagation.cc @@ -48,284 +48,289 @@ namespace eicrecon { -template -struct multilambda : L... { +template struct multilambda : L... { using L::operator()...; - constexpr multilambda(L...lambda) : L(std::move(lambda))... {} + constexpr multilambda(L... lambda) : L(std::move(lambda))... {} }; void TrackPropagation::init(const dd4hep::Detector* detector, std::shared_ptr geo_svc, std::shared_ptr logger) { - m_geoSvc = geo_svc; - m_log = logger; + m_geoSvc = geo_svc; + m_log = logger; - std::map system_id_layers; + std::map system_id_layers; - multilambda _toDouble = { + multilambda _toDouble = { [](const std::string& v) { return dd4hep::_toDouble(v); }, - [](const double& v) { return v; }, - }; - - auto _toActsSurface = [&_toDouble, &detector, &system_id_layers]( - const std::variant surface_variant) -> std::shared_ptr { - if (std::holds_alternative(surface_variant)) { - CylinderSurfaceConfig surface = std::get(surface_variant); - const double rmin = std::visit(_toDouble, surface.rmin) / dd4hep::mm * Acts::UnitConstants::mm; - const double zmin = std::visit(_toDouble, surface.zmin) / dd4hep::mm * Acts::UnitConstants::mm; - const double zmax = std::visit(_toDouble, surface.zmax) / dd4hep::mm * Acts::UnitConstants::mm; - const uint32_t system_id = detector->constant(surface.id); - auto bounds = std::make_shared(rmin, (zmax-zmin)/2); - auto t = Acts::Translation3(Acts::Vector3(0, 0, (zmax+zmin)/2)); - auto tf = Acts::Transform3(t); - auto acts_surface = Acts::Surface::makeShared(tf, bounds); - acts_surface->assignGeometryId(Acts::GeometryIdentifier().setExtra(system_id).setLayer(++system_id_layers[system_id])); - return acts_surface; - } - if (std::holds_alternative(surface_variant)) { - DiscSurfaceConfig surface = std::get(surface_variant); - const double zmin = std::visit(_toDouble, surface.zmin) / dd4hep::mm * Acts::UnitConstants::mm; - const double rmin = std::visit(_toDouble, surface.rmin) / dd4hep::mm * Acts::UnitConstants::mm; - const double rmax = std::visit(_toDouble, surface.rmax) / dd4hep::mm * Acts::UnitConstants::mm; - const uint32_t system_id = detector->constant(surface.id); - auto bounds = std::make_shared(rmin, rmax); - auto t = Acts::Translation3(Acts::Vector3(0, 0, zmin)); - auto tf = Acts::Transform3(t); - auto acts_surface = Acts::Surface::makeShared(tf, bounds); - acts_surface->assignGeometryId(Acts::GeometryIdentifier().setExtra(system_id).setLayer(++system_id_layers[system_id])); - return acts_surface; - } - throw std::domain_error("Unknown surface type"); - }; - m_target_surfaces.resize(m_cfg.target_surfaces.size()); - std::transform(m_cfg.target_surfaces.cbegin(), m_cfg.target_surfaces.cend(), m_target_surfaces.begin(), _toActsSurface); - m_filter_surfaces.resize(m_cfg.filter_surfaces.size()); - std::transform(m_cfg.filter_surfaces.cbegin(), m_cfg.filter_surfaces.cend(), m_filter_surfaces.begin(), _toActsSurface); - - m_log->trace("Initialized"); + [](const double& v) { return v; }, + }; + + auto _toActsSurface = + [&_toDouble, &detector, &system_id_layers]( + const std::variant surface_variant) + -> std::shared_ptr { + if (std::holds_alternative(surface_variant)) { + CylinderSurfaceConfig surface = std::get(surface_variant); + const double rmin = + std::visit(_toDouble, surface.rmin) / dd4hep::mm * Acts::UnitConstants::mm; + const double zmin = + std::visit(_toDouble, surface.zmin) / dd4hep::mm * Acts::UnitConstants::mm; + const double zmax = + std::visit(_toDouble, surface.zmax) / dd4hep::mm * Acts::UnitConstants::mm; + const uint32_t system_id = detector->constant(surface.id); + auto bounds = std::make_shared(rmin, (zmax - zmin) / 2); + auto t = Acts::Translation3(Acts::Vector3(0, 0, (zmax + zmin) / 2)); + auto tf = Acts::Transform3(t); + auto acts_surface = Acts::Surface::makeShared(tf, bounds); + acts_surface->assignGeometryId( + Acts::GeometryIdentifier().setExtra(system_id).setLayer(++system_id_layers[system_id])); + return acts_surface; + } + if (std::holds_alternative(surface_variant)) { + DiscSurfaceConfig surface = std::get(surface_variant); + const double zmin = + std::visit(_toDouble, surface.zmin) / dd4hep::mm * Acts::UnitConstants::mm; + const double rmin = + std::visit(_toDouble, surface.rmin) / dd4hep::mm * Acts::UnitConstants::mm; + const double rmax = + std::visit(_toDouble, surface.rmax) / dd4hep::mm * Acts::UnitConstants::mm; + const uint32_t system_id = detector->constant(surface.id); + auto bounds = std::make_shared(rmin, rmax); + auto t = Acts::Translation3(Acts::Vector3(0, 0, zmin)); + auto tf = Acts::Transform3(t); + auto acts_surface = Acts::Surface::makeShared(tf, bounds); + acts_surface->assignGeometryId( + Acts::GeometryIdentifier().setExtra(system_id).setLayer(++system_id_layers[system_id])); + return acts_surface; + } + throw std::domain_error("Unknown surface type"); + }; + m_target_surfaces.resize(m_cfg.target_surfaces.size()); + std::transform(m_cfg.target_surfaces.cbegin(), m_cfg.target_surfaces.cend(), + m_target_surfaces.begin(), _toActsSurface); + m_filter_surfaces.resize(m_cfg.filter_surfaces.size()); + std::transform(m_cfg.filter_surfaces.cbegin(), m_cfg.filter_surfaces.cend(), + m_filter_surfaces.begin(), _toActsSurface); + + m_log->trace("Initialized"); } - void TrackPropagation::propagateToSurfaceList( - const std::tuple, const std::vector> input, - const std::tuple output) const -{ - const auto [tracks, acts_trajectories, acts_tracks] = input; - auto [track_segments] = output; - - // logging - m_log->trace("Propagate trajectories: --------------------"); - m_log->trace("number of tracks: {}", tracks.size()); - m_log->trace("number of acts_trajectories: {}", acts_trajectories.size()); - m_log->trace("number of acts_tracks: {}", acts_tracks.size()); - - // loop over input trajectories - for (size_t i = 0; const auto& traj : acts_trajectories) { - - // check if this trajectory can be propagated to any filter surface - bool trajectory_reaches_filter_surface{false}; - for (const auto& filter_surface: m_filter_surfaces) { - auto point = propagate(edm4eic::Track{}, traj, filter_surface); - if (point) { - trajectory_reaches_filter_surface = true; - break; - } + const std::tuple, + const std::vector> + input, + const std::tuple output) const { + const auto [tracks, acts_trajectories, acts_tracks] = input; + auto [track_segments] = output; + + // logging + m_log->trace("Propagate trajectories: --------------------"); + m_log->trace("number of tracks: {}", tracks.size()); + m_log->trace("number of acts_trajectories: {}", acts_trajectories.size()); + m_log->trace("number of acts_tracks: {}", acts_tracks.size()); + + // loop over input trajectories + for (size_t i = 0; const auto& traj : acts_trajectories) { + + // check if this trajectory can be propagated to any filter surface + bool trajectory_reaches_filter_surface{false}; + for (const auto& filter_surface : m_filter_surfaces) { + auto point = propagate(edm4eic::Track{}, traj, filter_surface); + if (point) { + trajectory_reaches_filter_surface = true; + break; } - if (trajectory_reaches_filter_surface == false) { - ++i; + } + if (trajectory_reaches_filter_surface == false) { + ++i; + continue; + } + + // start a mutable TrackSegment + auto track_segment = track_segments->create(); + + // corresponding track + if (tracks.size() == acts_trajectories.size()) { + m_log->trace("track segment connected to track {}", i); + track_segment.setTrack(tracks[i]); + ++i; + } + + // zero measurements of segment length + decltype(edm4eic::TrackSegmentData::length) length = 0; + decltype(edm4eic::TrackSegmentData::lengthError) length_error = 0; + + // loop over projection-target surfaces + for (const auto& target_surface : m_target_surfaces) { + + // project the trajectory `traj` to this surface + auto point = propagate(edm4eic::Track{}, traj, target_surface); + if (!point) { + m_log->trace("<> Failed to propagate trajectory to this plane"); continue; } - // start a mutable TrackSegment - auto track_segment = track_segments->create(); + // logging + m_log->trace("<> trajectory: x=( {:>10.2f} {:>10.2f} {:>10.2f} )", point->position.x, + point->position.y, point->position.z); + m_log->trace(" p=( {:>10.2f} {:>10.2f} {:>10.2f} )", point->momentum.x, + point->momentum.y, point->momentum.z); + + // track point cut + if (!m_cfg.track_point_cut(*point)) { + m_log->trace(" => REJECTED by trackPointCut"); + if (m_cfg.skip_track_on_track_point_cut_failure) + break; + continue; + } - // corresponding track - if (tracks.size() == acts_trajectories.size()) { - m_log->trace("track segment connected to track {}", i); - track_segment.setTrack(tracks[i]); - ++i; + // update the `TrackSegment` length + // FIXME: `length` and `length_error` are currently not used by any callers, and may not be correctly calculated here + if (track_segment.points_size() > 0) { + auto pos0 = point->position; + auto pos1 = std::prev(track_segment.points_end())->position; + auto dist = edm4hep::utils::magnitude(pos0 - pos1); + length += dist; + m_log->trace(" dist to previous point: {}", dist); } - // zero measurements of segment length - decltype(edm4eic::TrackSegmentData::length) length = 0; - decltype(edm4eic::TrackSegmentData::lengthError) length_error = 0; - - // loop over projection-target surfaces - for (const auto& target_surface : m_target_surfaces) { - - // project the trajectory `traj` to this surface - auto point = propagate(edm4eic::Track{}, traj, target_surface); - if (!point) { - m_log->trace("<> Failed to propagate trajectory to this plane"); - continue; - } - - // logging - m_log->trace("<> trajectory: x=( {:>10.2f} {:>10.2f} {:>10.2f} )", - point->position.x, point->position.y, point->position.z); - m_log->trace(" p=( {:>10.2f} {:>10.2f} {:>10.2f} )", - point->momentum.x, point->momentum.y, point->momentum.z); - - // track point cut - if (!m_cfg.track_point_cut(*point)) { - m_log->trace(" => REJECTED by trackPointCut"); - if (m_cfg.skip_track_on_track_point_cut_failure) - break; - continue; - } - - // update the `TrackSegment` length - // FIXME: `length` and `length_error` are currently not used by any callers, and may not be correctly calculated here - if (track_segment.points_size()>0) { - auto pos0 = point->position; - auto pos1 = std::prev(track_segment.points_end())->position; - auto dist = edm4hep::utils::magnitude(pos0-pos1); - length += dist; - m_log->trace(" dist to previous point: {}", dist); - } - - // add the `TrackPoint` to the `TrackSegment` - track_segment.addToPoints(*point); - - } // end `targetSurfaces` loop - - // set final length and length error - track_segment.setLength(length); - track_segment.setLengthError(length_error); - - } // end loop over input trajectories + // add the `TrackPoint` to the `TrackSegment` + track_segment.addToPoints(*point); + + } // end `targetSurfaces` loop + + // set final length and length error + track_segment.setLength(length); + track_segment.setLengthError(length_error); + + } // end loop over input trajectories +} + +std::unique_ptr +TrackPropagation::propagate(const edm4eic::Track& track, + const ActsExamples::Trajectories* acts_trajectory, + const std::shared_ptr& targetSurf) const { + + // Get the entry index for the single trajectory + // The trajectory entry indices and the multiTrajectory + const auto& mj = acts_trajectory->multiTrajectory(); + const auto& trackTips = acts_trajectory->tips(); + + m_log->trace(" Number of elements in trackTips {}", trackTips.size()); + + // Skip empty + if (trackTips.empty()) { + m_log->trace(" Empty multiTrajectory."); + return nullptr; } + const auto& trackTip = trackTips.front(); + + // Collect the trajectory summary info + auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); + int m_nMeasurements = trajState.nMeasurements; + int m_nStates = trajState.nStates; + m_log->trace(" Num measurement in trajectory: {}", m_nMeasurements); + m_log->trace(" Num states in trajectory : {}", m_nStates); + //================================================= + //Track projection + //Reference sPHENIX code: https://github.com/sPHENIX-Collaboration/coresoftware/blob/335e6da4ccacc8374cada993485fe81d82e74a4f/offline/packages/trackreco/PHActsTrackProjection.h + //================================================= + const auto& initial_bound_parameters = acts_trajectory->trackParameters(trackTip); - std::unique_ptr TrackPropagation::propagate( - const edm4eic::Track& track, - const ActsExamples::Trajectories *acts_trajectory, - const std::shared_ptr &targetSurf) const { - - // Get the entry index for the single trajectory - // The trajectory entry indices and the multiTrajectory - const auto &mj = acts_trajectory->multiTrajectory(); - const auto &trackTips = acts_trajectory->tips(); - - m_log->trace(" Number of elements in trackTips {}", trackTips.size()); - - // Skip empty - if (trackTips.empty()) { - m_log->trace(" Empty multiTrajectory."); - return nullptr; - } - const auto &trackTip = trackTips.front(); - - // Collect the trajectory summary info - auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); - int m_nMeasurements = trajState.nMeasurements; - int m_nStates = trajState.nStates; - - m_log->trace(" Num measurement in trajectory: {}", m_nMeasurements); - m_log->trace(" Num states in trajectory : {}", m_nStates); - - - - //================================================= - //Track projection - //Reference sPHENIX code: https://github.com/sPHENIX-Collaboration/coresoftware/blob/335e6da4ccacc8374cada993485fe81d82e74a4f/offline/packages/trackreco/PHActsTrackProjection.h - //================================================= - const auto &initial_bound_parameters = acts_trajectory->trackParameters(trackTip); - - - m_log->trace(" TrackPropagation. Propagating to surface # {}", typeid(targetSurf->type()).name()); - - std::shared_ptr trackingGeometry = m_geoSvc->trackingGeometry(); - std::shared_ptr magneticField = m_geoSvc->getFieldProvider(); - using Stepper = Acts::EigenStepper<>; - using Propagator = Acts::Propagator; - Stepper stepper(magneticField); - Propagator propagator(stepper); - - ACTS_LOCAL_LOGGER(eicrecon::getSpdlogLogger("PROP", m_log)); - - Acts::PropagatorOptions<> options(m_geoContext, m_fieldContext); - - auto result = propagator.propagate(initial_bound_parameters, *targetSurf, options); - - // check propagation result - if (!result.ok()) { - m_log->trace(" propagation failed (!result.ok())"); - return nullptr; - } - m_log->trace(" propagation result is OK"); - - // Pulling results to convenient variables - auto trackStateParams = *((*result).endParameters); - const auto ¶meter = trackStateParams.parameters(); - const auto &covariance = *trackStateParams.covariance(); - - // Path length - const float pathLength = (*result).pathLength; - const float pathLengthError = 0; - m_log->trace(" path len = {}", pathLength); - - // Position: - auto projectionPos = trackStateParams.position(m_geoContext); - const decltype(edm4eic::TrackPoint::position) position{ - static_cast(projectionPos(0)), - static_cast(projectionPos(1)), - static_cast(projectionPos(2)) - }; - const decltype(edm4eic::TrackPoint::positionError) positionError{0, 0, 0}; - m_log->trace(" pos x = {}", position.x); - m_log->trace(" pos y = {}", position.y); - m_log->trace(" pos z = {}", position.z); - - // Momentum - const decltype(edm4eic::TrackPoint::momentum) momentum = edm4hep::utils::sphericalToVector( - static_cast(1.0 / std::abs(parameter[Acts::eBoundQOverP])), - static_cast(parameter[Acts::eBoundTheta]), - static_cast(parameter[Acts::eBoundPhi]) - ); - const decltype(edm4eic::TrackPoint::momentumError) momentumError{ - static_cast(covariance(Acts::eBoundTheta, Acts::eBoundTheta)), - static_cast(covariance(Acts::eBoundPhi, Acts::eBoundPhi)), - static_cast(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)), - static_cast(covariance(Acts::eBoundTheta, Acts::eBoundPhi)), - static_cast(covariance(Acts::eBoundTheta, Acts::eBoundQOverP)), - static_cast(covariance(Acts::eBoundPhi, Acts::eBoundQOverP)) - }; - - // time - const float time{static_cast(parameter(Acts::eBoundTime))}; - const float timeError{static_cast(sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)))}; - - // Direction - const float theta(parameter[Acts::eBoundTheta]); - const float phi(parameter[Acts::eBoundPhi]); - const decltype(edm4eic::TrackPoint::directionError) directionError{ - static_cast(covariance(Acts::eBoundTheta, Acts::eBoundTheta)), - static_cast(covariance(Acts::eBoundPhi, Acts::eBoundPhi)), - static_cast(covariance(Acts::eBoundTheta, Acts::eBoundPhi)) - }; - - - // >oO debug print - m_log->trace(" loc 0 = {:.4f}", parameter[Acts::eBoundLoc0]); - m_log->trace(" loc 1 = {:.4f}", parameter[Acts::eBoundLoc1]); - m_log->trace(" phi = {:.4f}", parameter[Acts::eBoundPhi]); - m_log->trace(" theta = {:.4f}", parameter[Acts::eBoundTheta]); - m_log->trace(" q/p = {:.4f}", parameter[Acts::eBoundQOverP]); - m_log->trace(" p = {:.4f}", 1.0 / parameter[Acts::eBoundQOverP]); - m_log->trace(" err phi = {:.4f}", sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi))); - m_log->trace(" err th = {:.4f}", sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta))); - m_log->trace(" err q/p = {:.4f}", sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP))); - m_log->trace(" chi2 = {:.4f}", trajState.chi2Sum); - m_log->trace(" loc err = {:.4f}", static_cast(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0))); - m_log->trace(" loc err = {:.4f}", static_cast(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1))); - m_log->trace(" loc err = {:.4f}", static_cast(covariance(Acts::eBoundLoc0, Acts::eBoundLoc1))); - - uint64_t surface = targetSurf->geometryId().value(); - uint32_t system = 0; // default value...will be set in TrackPropagation factory - - /* + m_log->trace(" TrackPropagation. Propagating to surface # {}", + typeid(targetSurf->type()).name()); + + std::shared_ptr trackingGeometry = m_geoSvc->trackingGeometry(); + std::shared_ptr magneticField = m_geoSvc->getFieldProvider(); + using Stepper = Acts::EigenStepper<>; + using Propagator = Acts::Propagator; + Stepper stepper(magneticField); + Propagator propagator(stepper); + + ACTS_LOCAL_LOGGER(eicrecon::getSpdlogLogger("PROP", m_log)); + + Acts::PropagatorOptions<> options(m_geoContext, m_fieldContext); + + auto result = propagator.propagate(initial_bound_parameters, *targetSurf, options); + + // check propagation result + if (!result.ok()) { + m_log->trace(" propagation failed (!result.ok())"); + return nullptr; + } + m_log->trace(" propagation result is OK"); + + // Pulling results to convenient variables + auto trackStateParams = *((*result).endParameters); + const auto& parameter = trackStateParams.parameters(); + const auto& covariance = *trackStateParams.covariance(); + + // Path length + const float pathLength = (*result).pathLength; + const float pathLengthError = 0; + m_log->trace(" path len = {}", pathLength); + + // Position: + auto projectionPos = trackStateParams.position(m_geoContext); + const decltype(edm4eic::TrackPoint::position) position{static_cast(projectionPos(0)), + static_cast(projectionPos(1)), + static_cast(projectionPos(2))}; + const decltype(edm4eic::TrackPoint::positionError) positionError{0, 0, 0}; + m_log->trace(" pos x = {}", position.x); + m_log->trace(" pos y = {}", position.y); + m_log->trace(" pos z = {}", position.z); + + // Momentum + const decltype(edm4eic::TrackPoint::momentum) momentum = edm4hep::utils::sphericalToVector( + static_cast(1.0 / std::abs(parameter[Acts::eBoundQOverP])), + static_cast(parameter[Acts::eBoundTheta]), + static_cast(parameter[Acts::eBoundPhi])); + const decltype(edm4eic::TrackPoint::momentumError) momentumError{ + static_cast(covariance(Acts::eBoundTheta, Acts::eBoundTheta)), + static_cast(covariance(Acts::eBoundPhi, Acts::eBoundPhi)), + static_cast(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)), + static_cast(covariance(Acts::eBoundTheta, Acts::eBoundPhi)), + static_cast(covariance(Acts::eBoundTheta, Acts::eBoundQOverP)), + static_cast(covariance(Acts::eBoundPhi, Acts::eBoundQOverP))}; + + // time + const float time{static_cast(parameter(Acts::eBoundTime))}; + const float timeError{static_cast(sqrt(covariance(Acts::eBoundTime, Acts::eBoundTime)))}; + + // Direction + const float theta(parameter[Acts::eBoundTheta]); + const float phi(parameter[Acts::eBoundPhi]); + const decltype(edm4eic::TrackPoint::directionError) directionError{ + static_cast(covariance(Acts::eBoundTheta, Acts::eBoundTheta)), + static_cast(covariance(Acts::eBoundPhi, Acts::eBoundPhi)), + static_cast(covariance(Acts::eBoundTheta, Acts::eBoundPhi))}; + + // >oO debug print + m_log->trace(" loc 0 = {:.4f}", parameter[Acts::eBoundLoc0]); + m_log->trace(" loc 1 = {:.4f}", parameter[Acts::eBoundLoc1]); + m_log->trace(" phi = {:.4f}", parameter[Acts::eBoundPhi]); + m_log->trace(" theta = {:.4f}", parameter[Acts::eBoundTheta]); + m_log->trace(" q/p = {:.4f}", parameter[Acts::eBoundQOverP]); + m_log->trace(" p = {:.4f}", 1.0 / parameter[Acts::eBoundQOverP]); + m_log->trace(" err phi = {:.4f}", sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi))); + m_log->trace(" err th = {:.4f}", sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta))); + m_log->trace(" err q/p = {:.4f}", sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP))); + m_log->trace(" chi2 = {:.4f}", trajState.chi2Sum); + m_log->trace(" loc err = {:.4f}", + static_cast(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0))); + m_log->trace(" loc err = {:.4f}", + static_cast(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1))); + m_log->trace(" loc err = {:.4f}", + static_cast(covariance(Acts::eBoundLoc0, Acts::eBoundLoc1))); + + uint64_t surface = targetSurf->geometryId().value(); + uint32_t system = 0; // default value...will be set in TrackPropagation factory + + /* ::edm4hep::Vector3f position{}; ///< Position of the trajectory point [mm] ::edm4eic::Cov3f positionError{}; ///< Error on the position ::edm4hep::Vector3f momentum{}; ///< 3-momentum at the point [GeV] @@ -338,21 +343,9 @@ void TrackPropagation::propagateToSurfaceList( float pathlength{}; ///< Pathlength from the origin to this point float pathlengthError{}; ///< Error on the pathlenght */ - return std::make_unique(edm4eic::TrackPoint{ - surface, - system, - position, - positionError, - momentum, - momentumError, - time, - timeError, - theta, - phi, - directionError, - pathLength, - pathLengthError - }); - } + return std::make_unique( + edm4eic::TrackPoint{surface, system, position, positionError, momentum, momentumError, time, + timeError, theta, phi, directionError, pathLength, pathLengthError}); +} } // namespace eicrecon diff --git a/src/algorithms/tracking/TrackPropagation.h b/src/algorithms/tracking/TrackPropagation.h index 6115e3f244..883608ddde 100644 --- a/src/algorithms/tracking/TrackPropagation.h +++ b/src/algorithms/tracking/TrackPropagation.h @@ -28,68 +28,70 @@ namespace eicrecon { - using ActsTrackPropagationResult = Acts::Result>; +using ActsTrackPropagationResult = Acts::Result>; - /** Extract the particles form fit trajectories. +/** Extract the particles form fit trajectories. * * \ingroup tracking */ - class TrackPropagation: public eicrecon::WithPodConfig { - - - public: - - /** Initialize algorithm */ - void init(const dd4hep::Detector* detector, std::shared_ptr geo_svc, std::shared_ptr logger); - - void process( - const std::tuple, const std::vector> input, - const std::tuple output) const { - - const auto [tracks, acts_trajectories, acts_tracks] = input; - auto [propagated_tracks] = output; - - for (size_t i = 0; auto traj: acts_trajectories) { - auto this_propagated_track = propagated_tracks->create(); - if (tracks.size() == acts_trajectories.size()) { - m_log->trace("track segment connected to track {}", i); - this_propagated_track.setTrack(tracks[i]); - } - for (auto& surf : m_target_surfaces) { - auto prop_point = propagate( - tracks.size() == acts_trajectories.size() ? tracks[i] : edm4eic::Track{}, - traj, surf); - if (!prop_point) continue; - prop_point->surface = surf->geometryId().layer(); - prop_point->system = surf->geometryId().extra(); - this_propagated_track.addToPoints(*prop_point); - } - ++i; - } - } - - /** Propagates a single trajectory to a given surface */ - std::unique_ptr propagate( - const edm4eic::Track&, - const ActsExamples::Trajectories*, +class TrackPropagation : public eicrecon::WithPodConfig { + +public: + /** Initialize algorithm */ + void init(const dd4hep::Detector* detector, std::shared_ptr geo_svc, + std::shared_ptr logger); + + void process(const std::tuple, + const std::vector> + input, + const std::tuple output) const { + + const auto [tracks, acts_trajectories, acts_tracks] = input; + auto [propagated_tracks] = output; + + for (size_t i = 0; auto traj : acts_trajectories) { + auto this_propagated_track = propagated_tracks->create(); + if (tracks.size() == acts_trajectories.size()) { + m_log->trace("track segment connected to track {}", i); + this_propagated_track.setTrack(tracks[i]); + } + for (auto& surf : m_target_surfaces) { + auto prop_point = propagate( + tracks.size() == acts_trajectories.size() ? tracks[i] : edm4eic::Track{}, traj, surf); + if (!prop_point) + continue; + prop_point->surface = surf->geometryId().layer(); + prop_point->system = surf->geometryId().extra(); + this_propagated_track.addToPoints(*prop_point); + } + ++i; + } + } + + /** Propagates a single trajectory to a given surface */ + std::unique_ptr + propagate(const edm4eic::Track&, const ActsExamples::Trajectories*, const std::shared_ptr& targetSurf) const; - /** Propagates a collection of trajectories to a list of surfaces, and returns the full `TrackSegment`; + /** Propagates a collection of trajectories to a list of surfaces, and returns the full `TrackSegment`; * @param trajectories the input collection of trajectories * @return the resulting collection of propagated tracks */ - void propagateToSurfaceList( - const std::tuple, const std::vector> input, - const std::tuple output) const; - - private: - - Acts::GeometryContext m_geoContext; - Acts::MagneticFieldContext m_fieldContext; - std::shared_ptr m_geoSvc; - std::shared_ptr m_log; - - std::vector> m_filter_surfaces; - std::vector> m_target_surfaces; - }; + void propagateToSurfaceList( + const std::tuple, + const std::vector> + input, + const std::tuple output) const; + +private: + Acts::GeometryContext m_geoContext; + Acts::MagneticFieldContext m_fieldContext; + std::shared_ptr m_geoSvc; + std::shared_ptr m_log; + + std::vector> m_filter_surfaces; + std::vector> m_target_surfaces; +}; } // namespace eicrecon diff --git a/src/algorithms/tracking/TrackPropagationConfig.h b/src/algorithms/tracking/TrackPropagationConfig.h index 91c623fb63..38acfda097 100644 --- a/src/algorithms/tracking/TrackPropagationConfig.h +++ b/src/algorithms/tracking/TrackPropagationConfig.h @@ -10,30 +10,29 @@ namespace eicrecon { - struct CylinderSurfaceConfig { - std::string id; - std::variant rmin; - std::variant zmin; - std::variant zmax; - }; - - struct DiscSurfaceConfig { - std::string id; - std::variant zmin; - std::variant rmin; - std::variant rmax; - }; - - using SurfaceConfig = std::variant; - - struct TrackPropagationConfig { - std::vector filter_surfaces{}; - std::vector target_surfaces{}; - - std::function track_point_cut{ - [](const edm4eic::TrackPoint&) { return true; } - }; - bool skip_track_on_track_point_cut_failure{false}; - }; - -} // eicrecon +struct CylinderSurfaceConfig { + std::string id; + std::variant rmin; + std::variant zmin; + std::variant zmax; +}; + +struct DiscSurfaceConfig { + std::string id; + std::variant zmin; + std::variant rmin; + std::variant rmax; +}; + +using SurfaceConfig = std::variant; + +struct TrackPropagationConfig { + std::vector filter_surfaces{}; + std::vector target_surfaces{}; + + std::function track_point_cut{ + [](const edm4eic::TrackPoint&) { return true; }}; + bool skip_track_on_track_point_cut_failure{false}; +}; + +} // namespace eicrecon diff --git a/src/algorithms/tracking/TrackSeeding.cc b/src/algorithms/tracking/TrackSeeding.cc index 3c285d631b..e7c0ff86d5 100644 --- a/src/algorithms/tracking/TrackSeeding.cc +++ b/src/algorithms/tracking/TrackSeeding.cc @@ -28,257 +28,242 @@ #include #include -namespace -{ - //! convenience square method - template - inline constexpr T square( const T& x ) { return x*x; } -} +namespace { +//! convenience square method +template inline constexpr T square(const T& x) { return x * x; } +} // namespace -void eicrecon::TrackSeeding::init(std::shared_ptr geo_svc, std::shared_ptr log) { +void eicrecon::TrackSeeding::init(std::shared_ptr geo_svc, + std::shared_ptr log) { - m_log = log; + m_log = log; - m_geoSvc = geo_svc; + m_geoSvc = geo_svc; - m_BField = std::dynamic_pointer_cast(m_geoSvc->getFieldProvider()); - m_fieldctx = eicrecon::BField::BFieldVariant(m_BField); + m_BField = + std::dynamic_pointer_cast(m_geoSvc->getFieldProvider()); + m_fieldctx = eicrecon::BField::BFieldVariant(m_BField); - configure(); + configure(); } void eicrecon::TrackSeeding::configure() { - // Filter parameters - m_seedFilterConfig.maxSeedsPerSpM = m_cfg.maxSeedsPerSpM_filter; - m_seedFilterConfig.deltaRMin = m_cfg.deltaRMin; - m_seedFilterConfig.seedConfirmation = m_cfg.seedConfirmation; - m_seedFilterConfig.deltaInvHelixDiameter = m_cfg.deltaInvHelixDiameter; - m_seedFilterConfig.impactWeightFactor = m_cfg.impactWeightFactor; - m_seedFilterConfig.zOriginWeightFactor = m_cfg.zOriginWeightFactor; - m_seedFilterConfig.compatSeedWeight = m_cfg.compatSeedWeight; - m_seedFilterConfig.compatSeedLimit = m_cfg.compatSeedLimit; - m_seedFilterConfig.seedWeightIncrement = m_cfg.seedWeightIncrement; - - m_seedFilterConfig.centralSeedConfirmationRange = Acts::SeedConfirmationRangeConfig{ - m_cfg.zMinSeedConfCentral, - m_cfg.zMaxSeedConfCentral, - m_cfg.rMaxSeedConfCentral, - m_cfg.nTopForLargeRCentral, - m_cfg.nTopForSmallRCentral, - m_cfg.seedConfMinBottomRadiusCentral, - m_cfg.seedConfMaxZOriginCentral, - m_cfg.minImpactSeedConfCentral - }; - - m_seedFilterConfig.forwardSeedConfirmationRange = Acts::SeedConfirmationRangeConfig{ - m_cfg.zMinSeedConfForward, - m_cfg.zMaxSeedConfForward, - m_cfg.rMaxSeedConfForward, - m_cfg.nTopForLargeRForward, - m_cfg.nTopForSmallRForward, - m_cfg.seedConfMinBottomRadiusForward, - m_cfg.seedConfMaxZOriginForward, - m_cfg.minImpactSeedConfForward - }; - - m_seedFilterConfig = m_seedFilterConfig.toInternalUnits(); - - // Finder parameters - m_seedFinderConfig.seedFilter = std::make_unique>(Acts::SeedFilter(m_seedFilterConfig)); - m_seedFinderConfig.rMax = m_cfg.rMax; - m_seedFinderConfig.rMin = m_cfg.rMin; - m_seedFinderConfig.deltaRMinTopSP = m_cfg.deltaRMinTopSP; - m_seedFinderConfig.deltaRMaxTopSP = m_cfg.deltaRMaxTopSP; - m_seedFinderConfig.deltaRMinBottomSP = m_cfg.deltaRMinBottomSP; - m_seedFinderConfig.deltaRMaxBottomSP = m_cfg.deltaRMaxBottomSP; - m_seedFinderConfig.collisionRegionMin = m_cfg.collisionRegionMin; - m_seedFinderConfig.collisionRegionMax = m_cfg.collisionRegionMax; - m_seedFinderConfig.zMin = m_cfg.zMin; - m_seedFinderConfig.zMax = m_cfg.zMax; - m_seedFinderConfig.maxSeedsPerSpM = m_cfg.maxSeedsPerSpM; - m_seedFinderConfig.cotThetaMax = m_cfg.cotThetaMax; - m_seedFinderConfig.sigmaScattering = m_cfg.sigmaScattering; - m_seedFinderConfig.radLengthPerSeed = m_cfg.radLengthPerSeed; - m_seedFinderConfig.minPt = m_cfg.minPt; - m_seedFinderConfig.impactMax = m_cfg.impactMax; - m_seedFinderConfig.rMinMiddle = m_cfg.rMinMiddle; - m_seedFinderConfig.rMaxMiddle = m_cfg.rMaxMiddle; - m_seedFinderConfig.deltaPhiMax = m_cfg.deltaPhiMax; - - m_seedFinderOptions.beamPos = Acts::Vector2(m_cfg.beamPosX, m_cfg.beamPosY); - m_seedFinderOptions.bFieldInZ = m_cfg.bFieldInZ; - - m_seedFinderConfig = - m_seedFinderConfig.toInternalUnits().calculateDerivedQuantities(); - m_seedFinderOptions = + // Filter parameters + m_seedFilterConfig.maxSeedsPerSpM = m_cfg.maxSeedsPerSpM_filter; + m_seedFilterConfig.deltaRMin = m_cfg.deltaRMin; + m_seedFilterConfig.seedConfirmation = m_cfg.seedConfirmation; + m_seedFilterConfig.deltaInvHelixDiameter = m_cfg.deltaInvHelixDiameter; + m_seedFilterConfig.impactWeightFactor = m_cfg.impactWeightFactor; + m_seedFilterConfig.zOriginWeightFactor = m_cfg.zOriginWeightFactor; + m_seedFilterConfig.compatSeedWeight = m_cfg.compatSeedWeight; + m_seedFilterConfig.compatSeedLimit = m_cfg.compatSeedLimit; + m_seedFilterConfig.seedWeightIncrement = m_cfg.seedWeightIncrement; + + m_seedFilterConfig.centralSeedConfirmationRange = Acts::SeedConfirmationRangeConfig{ + m_cfg.zMinSeedConfCentral, m_cfg.zMaxSeedConfCentral, + m_cfg.rMaxSeedConfCentral, m_cfg.nTopForLargeRCentral, + m_cfg.nTopForSmallRCentral, m_cfg.seedConfMinBottomRadiusCentral, + m_cfg.seedConfMaxZOriginCentral, m_cfg.minImpactSeedConfCentral}; + + m_seedFilterConfig.forwardSeedConfirmationRange = Acts::SeedConfirmationRangeConfig{ + m_cfg.zMinSeedConfForward, m_cfg.zMaxSeedConfForward, + m_cfg.rMaxSeedConfForward, m_cfg.nTopForLargeRForward, + m_cfg.nTopForSmallRForward, m_cfg.seedConfMinBottomRadiusForward, + m_cfg.seedConfMaxZOriginForward, m_cfg.minImpactSeedConfForward}; + + m_seedFilterConfig = m_seedFilterConfig.toInternalUnits(); + + // Finder parameters + m_seedFinderConfig.seedFilter = std::make_unique>( + Acts::SeedFilter(m_seedFilterConfig)); + m_seedFinderConfig.rMax = m_cfg.rMax; + m_seedFinderConfig.rMin = m_cfg.rMin; + m_seedFinderConfig.deltaRMinTopSP = m_cfg.deltaRMinTopSP; + m_seedFinderConfig.deltaRMaxTopSP = m_cfg.deltaRMaxTopSP; + m_seedFinderConfig.deltaRMinBottomSP = m_cfg.deltaRMinBottomSP; + m_seedFinderConfig.deltaRMaxBottomSP = m_cfg.deltaRMaxBottomSP; + m_seedFinderConfig.collisionRegionMin = m_cfg.collisionRegionMin; + m_seedFinderConfig.collisionRegionMax = m_cfg.collisionRegionMax; + m_seedFinderConfig.zMin = m_cfg.zMin; + m_seedFinderConfig.zMax = m_cfg.zMax; + m_seedFinderConfig.maxSeedsPerSpM = m_cfg.maxSeedsPerSpM; + m_seedFinderConfig.cotThetaMax = m_cfg.cotThetaMax; + m_seedFinderConfig.sigmaScattering = m_cfg.sigmaScattering; + m_seedFinderConfig.radLengthPerSeed = m_cfg.radLengthPerSeed; + m_seedFinderConfig.minPt = m_cfg.minPt; + m_seedFinderConfig.impactMax = m_cfg.impactMax; + m_seedFinderConfig.rMinMiddle = m_cfg.rMinMiddle; + m_seedFinderConfig.rMaxMiddle = m_cfg.rMaxMiddle; + m_seedFinderConfig.deltaPhiMax = m_cfg.deltaPhiMax; + + m_seedFinderOptions.beamPos = Acts::Vector2(m_cfg.beamPosX, m_cfg.beamPosY); + m_seedFinderOptions.bFieldInZ = m_cfg.bFieldInZ; + + m_seedFinderConfig = m_seedFinderConfig.toInternalUnits().calculateDerivedQuantities(); + m_seedFinderOptions = m_seedFinderOptions.toInternalUnits().calculateDerivedQuantities(m_seedFinderConfig); - } -std::unique_ptr eicrecon::TrackSeeding::produce(const edm4eic::TrackerHitCollection& trk_hits) { +std::unique_ptr +eicrecon::TrackSeeding::produce(const edm4eic::TrackerHitCollection& trk_hits) { std::vector spacePoints = getSpacePoints(trk_hits); - Acts::SeedFinderOrthogonal finder(m_seedFinderConfig); // FIXME move into class scope + Acts::SeedFinderOrthogonal finder( + m_seedFinderConfig); // FIXME move into class scope #if Acts_VERSION_MAJOR >= 32 std::function>( - const eicrecon::SpacePoint *sp)> - create_coordinates = [](const eicrecon::SpacePoint *sp) { + const eicrecon::SpacePoint* sp)> + create_coordinates = [](const eicrecon::SpacePoint* sp) { Acts::Vector3 position(sp->x(), sp->y(), sp->z()); Acts::Vector2 variance(sp->varianceR(), sp->varianceZ()); return std::make_tuple(position, variance, sp->t()); }; #else - std::function( - const eicrecon::SpacePoint *sp)> - create_coordinates = [](const eicrecon::SpacePoint *sp) { + std::function(const eicrecon::SpacePoint* sp)> + create_coordinates = [](const eicrecon::SpacePoint* sp) { Acts::Vector3 position(sp->x(), sp->y(), sp->z()); Acts::Vector2 variance(sp->varianceR(), sp->varianceZ()); return std::make_pair(position, variance); }; #endif - eicrecon::SeedContainer seeds = finder.createSeeds(m_seedFinderOptions, spacePoints, create_coordinates); + eicrecon::SeedContainer seeds = + finder.createSeeds(m_seedFinderOptions, spacePoints, create_coordinates); std::unique_ptr trackparams = makeTrackParams(seeds); - for (auto& sp: spacePoints) { + for (auto& sp : spacePoints) { delete sp; } return std::move(trackparams); } -std::vector eicrecon::TrackSeeding::getSpacePoints(const edm4eic::TrackerHitCollection& trk_hits) -{ +std::vector +eicrecon::TrackSeeding::getSpacePoints(const edm4eic::TrackerHitCollection& trk_hits) { std::vector spacepoints; - for(const auto hit : trk_hits) - { - const eicrecon::SpacePoint* sp = new SpacePoint(hit); - spacepoints.push_back(sp); - } + for (const auto hit : trk_hits) { + const eicrecon::SpacePoint* sp = new SpacePoint(hit); + spacepoints.push_back(sp); + } return spacepoints; } -std::unique_ptr eicrecon::TrackSeeding::makeTrackParams(SeedContainer& seeds) -{ +std::unique_ptr +eicrecon::TrackSeeding::makeTrackParams(SeedContainer& seeds) { auto trackparams = std::make_unique(); - for(auto& seed : seeds) - { - std::vector> xyHitPositions; - std::vector> rzHitPositions; - for(const auto& spptr : seed.sp()) - { - xyHitPositions.emplace_back(spptr->x(), spptr->y()); - rzHitPositions.emplace_back(spptr->r(), spptr->z()); - } - - auto RX0Y0 = circleFit(xyHitPositions); - float R = std::get<0>(RX0Y0); - float X0 = std::get<1>(RX0Y0); - float Y0 = std::get<2>(RX0Y0); - if (!(std::isfinite(R) && - std::isfinite(std::abs(X0)) && - std::isfinite(std::abs(Y0)))) { - // avoid float overflow for hits on a line - continue; - } - if ( std::hypot(X0,Y0) < std::numeric_limits::epsilon() || - !std::isfinite(std::hypot(X0,Y0)) ) { - //Avoid center of circle at origin, where there is no point-of-closest approach - //Also, avoid float overfloat on circle center - continue; - } - - auto slopeZ0 = lineFit(rzHitPositions); - const auto xypos = findPCA(RX0Y0); - - - //Determine charge - int charge = determineCharge(xyHitPositions, xypos, RX0Y0); - - float theta = atan(1./std::get<0>(slopeZ0)); - // normalize to 0(Acts::Vector3(0,0,0)); - Acts::Vector3 global(xypos.first, xypos.second, z0); - - //Compute local position at PCA - Acts::Vector2 localpos; - Acts::Vector3 direction(sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta)); - - auto local = perigee->globalToLocal(m_geoSvc->getActsGeometryContext(), - global, - direction); - - if(!local.ok()) - { - continue; - } - - localpos = local.value(); - - auto trackparam = trackparams->create(); - trackparam.setType(-1); // type --> seed(-1) - trackparam.setLoc({static_cast(localpos(0)), static_cast(localpos(1))}); // 2d location on surface - trackparam.setPhi(static_cast(phi)); // phi [rad] - trackparam.setTheta(theta); //theta [rad] - trackparam.setQOverP(qOverP); // Q/p [e/GeV] - trackparam.setTime(10); // time in ns - edm4eic::Cov6f cov; - cov(0,0) = m_cfg.locaError / Acts::UnitConstants::mm; // loc0 - cov(1,1) = m_cfg.locbError / Acts::UnitConstants::mm; // loc1 - cov(2,2) = m_cfg.phiError / Acts::UnitConstants::rad; // phi - cov(3,3) = m_cfg.thetaError / Acts::UnitConstants::rad; // theta - cov(4,4) = m_cfg.qOverPError * Acts::UnitConstants::GeV; // qOverP - cov(5,5) = m_cfg.timeError / Acts::UnitConstants::ns; // time - trackparam.setCovariance(cov); + for (auto& seed : seeds) { + std::vector> xyHitPositions; + std::vector> rzHitPositions; + for (const auto& spptr : seed.sp()) { + xyHitPositions.emplace_back(spptr->x(), spptr->y()); + rzHitPositions.emplace_back(spptr->r(), spptr->z()); + } + + auto RX0Y0 = circleFit(xyHitPositions); + float R = std::get<0>(RX0Y0); + float X0 = std::get<1>(RX0Y0); + float Y0 = std::get<2>(RX0Y0); + if (!(std::isfinite(R) && std::isfinite(std::abs(X0)) && std::isfinite(std::abs(Y0)))) { + // avoid float overflow for hits on a line + continue; + } + if (std::hypot(X0, Y0) < std::numeric_limits::epsilon() || + !std::isfinite(std::hypot(X0, Y0))) { + //Avoid center of circle at origin, where there is no point-of-closest approach + //Also, avoid float overfloat on circle center + continue; } + auto slopeZ0 = lineFit(rzHitPositions); + const auto xypos = findPCA(RX0Y0); + + //Determine charge + int charge = determineCharge(xyHitPositions, xypos, RX0Y0); + + float theta = atan(1. / std::get<0>(slopeZ0)); + // normalize to 0(Acts::Vector3(0, 0, 0)); + Acts::Vector3 global(xypos.first, xypos.second, z0); + + //Compute local position at PCA + Acts::Vector2 localpos; + Acts::Vector3 direction(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); + + auto local = perigee->globalToLocal(m_geoSvc->getActsGeometryContext(), global, direction); + + if (!local.ok()) { + continue; + } + + localpos = local.value(); + + auto trackparam = trackparams->create(); + trackparam.setType(-1); // type --> seed(-1) + trackparam.setLoc({static_cast(localpos(0)), + static_cast(localpos(1))}); // 2d location on surface + trackparam.setPhi(static_cast(phi)); // phi [rad] + trackparam.setTheta(theta); //theta [rad] + trackparam.setQOverP(qOverP); // Q/p [e/GeV] + trackparam.setTime(10); // time in ns + edm4eic::Cov6f cov; + cov(0, 0) = m_cfg.locaError / Acts::UnitConstants::mm; // loc0 + cov(1, 1) = m_cfg.locbError / Acts::UnitConstants::mm; // loc1 + cov(2, 2) = m_cfg.phiError / Acts::UnitConstants::rad; // phi + cov(3, 3) = m_cfg.thetaError / Acts::UnitConstants::rad; // theta + cov(4, 4) = m_cfg.qOverPError * Acts::UnitConstants::GeV; // qOverP + cov(5, 5) = m_cfg.timeError / Acts::UnitConstants::ns; // time + trackparam.setCovariance(cov); + } + return std::move(trackparams); } -std::pair eicrecon::TrackSeeding::findPCA(std::tuple& circleParams) const -{ - const float R = std::get<0>(circleParams); +std::pair +eicrecon::TrackSeeding::findPCA(std::tuple& circleParams) const { + const float R = std::get<0>(circleParams); const float X0 = std::get<1>(circleParams); const float Y0 = std::get<2>(circleParams); const double R0 = std::hypot(X0, Y0); //Calculate point on circle closest to origin - const double xmin = X0 * (1. - R/R0); - const double ymin = Y0 * (1. - R/R0); + const double xmin = X0 * (1. - R / R0); + const double ymin = Y0 * (1. - R / R0); - return std::make_pair(xmin,ymin); + return std::make_pair(xmin, ymin); } -int eicrecon::TrackSeeding::determineCharge(std::vector>& positions, const std::pair& PCA, std::tuple& RX0Y0) const -{ +int eicrecon::TrackSeeding::determineCharge(std::vector>& positions, + const std::pair& PCA, + std::tuple& RX0Y0) const { const auto& firstpos = positions.at(0); - auto hit_x = firstpos.first; - auto hit_y = firstpos.second; + auto hit_x = firstpos.first; + auto hit_y = firstpos.second; auto xpos = PCA.first; auto ypos = PCA.second; @@ -286,9 +271,9 @@ int eicrecon::TrackSeeding::determineCharge(std::vector>& float X0 = std::get<1>(RX0Y0); float Y0 = std::get<2>(RX0Y0); - Acts::Vector3 B_z(0,0,1); - Acts::Vector3 radial(X0-xpos, Y0-ypos, 0); - Acts::Vector3 hit(hit_x-xpos, hit_y-ypos, 0); + Acts::Vector3 B_z(0, 0, 1); + Acts::Vector3 radial(X0 - xpos, Y0 - ypos, 0); + Acts::Vector3 hit(hit_x - xpos, hit_y - ypos, 0); auto cross = radial.cross(hit); @@ -297,8 +282,7 @@ int eicrecon::TrackSeeding::determineCharge(std::vector>& return copysign(1., -dot); } - - /** +/** * Circle fit to a given set of data points (in 2D) * This is an algebraic fit, due to Taubin, based on the journal article * G. Taubin, "Estimation Of Planar Curves, Surfaces And Nonplanar @@ -310,15 +294,14 @@ int eicrecon::TrackSeeding::determineCharge(std::vector>& * It provides a very good initial guess for a subsequent geometric fit. * Nikolai Chernov (September 2012) */ -std::tuple eicrecon::TrackSeeding::circleFit(std::vector>& positions) const -{ +std::tuple +eicrecon::TrackSeeding::circleFit(std::vector>& positions) const { // Compute x- and y- sample means - double meanX = 0; - double meanY = 0; + double meanX = 0; + double meanY = 0; double weight = 0; - for( const auto& [x,y] : positions) - { + for (const auto& [x, y] : positions) { meanX += x; meanY += y; ++weight; @@ -335,18 +318,17 @@ std::tuple eicrecon::TrackSeeding::circleFit(std::vector=std::abs(y)) break; - - x = xnew; y = ynew; - + for (int iter = 0; iter < iter_max; ++iter) { + const double Dy = A1 + x * (A22 + A33 * x); + const double xnew = x - y / Dy; + if ((xnew == x) || (!std::isfinite(xnew))) + break; + + const double ynew = A0 + xnew * (A1 + xnew * (A2 + xnew * A3)); + if (std::abs(ynew) >= std::abs(y)) + break; + + x = xnew; + y = ynew; } // computing parameters of the fitting circle - const double DET = std::pow(x,2) - x*Mz + Cov_xy; - const double Xcenter = (Mxz*(Myy - x) - Myz*Mxy)/DET/2; - const double Ycenter = (Myz*(Mxx - x) - Mxz*Mxy)/DET/2; + const double DET = std::pow(x, 2) - x * Mz + Cov_xy; + const double Xcenter = (Mxz * (Myy - x) - Myz * Mxy) / DET / 2; + const double Ycenter = (Myz * (Mxx - x) - Mxz * Mxy) / DET / 2; // assembling the output float X0 = Xcenter + meanX; float Y0 = Ycenter + meanY; - float R = std::sqrt( std::pow(Xcenter,2) + std::pow(Ycenter,2) + Mz); - return std::make_tuple( R, X0, Y0 ); + float R = std::sqrt(std::pow(Xcenter, 2) + std::pow(Ycenter, 2) + Mz); + return std::make_tuple(R, X0, Y0); } -std::tuple eicrecon::TrackSeeding::lineFit(std::vector>& positions) const -{ - double xsum=0; - double x2sum=0; - double ysum=0; - double xysum=0; - for( const auto& [r,z]:positions ) - { - xsum=xsum+r; //calculate sigma(xi) - ysum=ysum+z; //calculate sigma(yi) - x2sum=x2sum+std::pow(r,2); //calculate sigma(x^2i) - xysum=xysum+r*z; //calculate sigma(xi*yi) +std::tuple +eicrecon::TrackSeeding::lineFit(std::vector>& positions) const { + double xsum = 0; + double x2sum = 0; + double ysum = 0; + double xysum = 0; + for (const auto& [r, z] : positions) { + xsum = xsum + r; //calculate sigma(xi) + ysum = ysum + z; //calculate sigma(yi) + x2sum = x2sum + std::pow(r, 2); //calculate sigma(x^2i) + xysum = xysum + r * z; //calculate sigma(xi*yi) } - const auto npts = positions.size(); - const double denominator = (x2sum*npts-std::pow(xsum,2)); - const float a= (xysum*npts-xsum*ysum)/denominator; //calculate slope - const float b= (x2sum*ysum-xsum*xysum)/denominator; //calculate intercept - return std::make_tuple( a, b ); + const auto npts = positions.size(); + const double denominator = (x2sum * npts - std::pow(xsum, 2)); + const float a = (xysum * npts - xsum * ysum) / denominator; //calculate slope + const float b = (x2sum * ysum - xsum * xysum) / denominator; //calculate intercept + return std::make_tuple(a, b); } diff --git a/src/algorithms/tracking/TrackSeeding.h b/src/algorithms/tracking/TrackSeeding.h index 2f0b8d885b..ede20edc70 100644 --- a/src/algorithms/tracking/TrackSeeding.h +++ b/src/algorithms/tracking/TrackSeeding.h @@ -23,33 +23,36 @@ #include "SpacePoint.h" #include "algorithms/interfaces/WithPodConfig.h" - namespace eicrecon { - class TrackSeeding: - public eicrecon::WithPodConfig { - public: - void init(std::shared_ptr geo_svc, std::shared_ptr log); - std::unique_ptr produce(const edm4eic::TrackerHitCollection& trk_hits); - - private: - void configure(); - - std::shared_ptr m_log; - std::shared_ptr m_geoSvc; - - std::shared_ptr m_BField = nullptr; - Acts::MagneticFieldContext m_fieldctx; - - Acts::SeedFilterConfig m_seedFilterConfig; - Acts::SeedFinderOptions m_seedFinderOptions; - Acts::SeedFinderOrthogonalConfig m_seedFinderConfig; - - int determineCharge(std::vector>& positions, const std::pair& PCA, std::tuple& RX0Y0) const; - std::pair findPCA(std::tuple& circleParams) const; - std::vector getSpacePoints(const edm4eic::TrackerHitCollection& trk_hits); - std::unique_ptr makeTrackParams(SeedContainer& seeds); - - std::tuple circleFit(std::vector>& positions) const; - std::tuple lineFit(std::vector>& positions) const; - }; -} +class TrackSeeding : public eicrecon::WithPodConfig { +public: + void init(std::shared_ptr geo_svc, + std::shared_ptr log); + std::unique_ptr + produce(const edm4eic::TrackerHitCollection& trk_hits); + +private: + void configure(); + + std::shared_ptr m_log; + std::shared_ptr m_geoSvc; + + std::shared_ptr m_BField = nullptr; + Acts::MagneticFieldContext m_fieldctx; + + Acts::SeedFilterConfig m_seedFilterConfig; + Acts::SeedFinderOptions m_seedFinderOptions; + Acts::SeedFinderOrthogonalConfig m_seedFinderConfig; + + int determineCharge(std::vector>& positions, + const std::pair& PCA, + std::tuple& RX0Y0) const; + std::pair findPCA(std::tuple& circleParams) const; + std::vector + getSpacePoints(const edm4eic::TrackerHitCollection& trk_hits); + std::unique_ptr makeTrackParams(SeedContainer& seeds); + + std::tuple circleFit(std::vector>& positions) const; + std::tuple lineFit(std::vector>& positions) const; +}; +} // namespace eicrecon diff --git a/src/algorithms/tracking/TrackerHitReconstruction.cc b/src/algorithms/tracking/TrackerHitReconstruction.cc index 5fe85534e4..48b6940865 100644 --- a/src/algorithms/tracking/TrackerHitReconstruction.cc +++ b/src/algorithms/tracking/TrackerHitReconstruction.cc @@ -19,73 +19,77 @@ namespace eicrecon { namespace { - inline double get_resolution(const double pixel_size) { - constexpr const double sqrt_12 = 3.4641016151; - return pixel_size / sqrt_12; - } - inline double get_variance(const double pixel_size) { - const double res = get_resolution(pixel_size); - return res * res; - } + inline double get_resolution(const double pixel_size) { + constexpr const double sqrt_12 = 3.4641016151; + return pixel_size / sqrt_12; + } + inline double get_variance(const double pixel_size) { + const double res = get_resolution(pixel_size); + return res * res; + } } // namespace -void TrackerHitReconstruction::init(const dd4hep::rec::CellIDPositionConverter* converter, std::shared_ptr& logger) { +void TrackerHitReconstruction::init(const dd4hep::rec::CellIDPositionConverter* converter, + std::shared_ptr& logger) { - m_log = logger; + m_log = logger; - m_converter = converter; + m_converter = converter; } -std::unique_ptr TrackerHitReconstruction::process(const edm4eic::RawTrackerHitCollection& raw_hits) { - using dd4hep::mm; - - auto rec_hits { std::make_unique() }; - - for (const auto& raw_hit : raw_hits) { - - auto id = raw_hit.getCellID(); - - // Get position and dimension - auto pos = m_converter->position(id); - auto dim = m_converter->cellDimensions(id); - - // >oO trace - if(m_log->level() == spdlog::level::trace) { - m_log->trace("position x={:.2f} y={:.2f} z={:.2f} [mm]: ", pos.x()/ mm, pos.y()/ mm, pos.z()/ mm); - m_log->trace("dimension size: {}", dim.size()); - for (size_t j = 0; j < std::size(dim); ++j) { - m_log->trace(" - dimension {:<5} size: {:.2}", j, dim[j]); - } - } - - // Note about variance: - // The variance is used to obtain a diagonal covariance matrix. - // Note that the covariance matrix is written in DD4hep surface coordinates, - // *NOT* global position coordinates. This implies that: - // - XY segmentation: xx -> sigma_x, yy-> sigma_y, zz -> 0, tt -> 0 - // - XZ segmentation: xx -> sigma_x, yy-> sigma_z, zz -> 0, tt -> 0 - // - XYZ segmentation: xx -> sigma_x, yy-> sigma_y, zz -> sigma_z, tt -> 0 - // This is properly in line with how we get the local coordinates for the hit - // in the TrackerSourceLinker. - #if EDM4EIC_VERSION_MAJOR >= 7 - auto rec_hit = - #endif - rec_hits->create( - raw_hit.getCellID(), // Raw DD4hep cell ID - edm4hep::Vector3f{static_cast(pos.x() / mm), static_cast(pos.y() / mm), static_cast(pos.z() / mm)}, // mm - edm4eic::CovDiag3f{get_variance(dim[0] / mm), get_variance(dim[1] / mm), // variance (see note above) - std::size(dim) > 2 ? get_variance(dim[2] / mm) : 0.}, - static_cast((double)(raw_hit.getTimeStamp()) / 1000.0), // ns - m_cfg.timeResolution, // in ns - static_cast(raw_hit.getCharge() / 1.0e6), // Collected energy (GeV) - 0.0F); // Error on the energy -#if EDM4EIC_VERSION_MAJOR >= 7 - rec_hit.setRawHit(raw_hit); -#endif +std::unique_ptr +TrackerHitReconstruction::process(const edm4eic::RawTrackerHitCollection& raw_hits) { + using dd4hep::mm; + + auto rec_hits{std::make_unique()}; + + for (const auto& raw_hit : raw_hits) { + + auto id = raw_hit.getCellID(); + // Get position and dimension + auto pos = m_converter->position(id); + auto dim = m_converter->cellDimensions(id); + + // >oO trace + if (m_log->level() == spdlog::level::trace) { + m_log->trace("position x={:.2f} y={:.2f} z={:.2f} [mm]: ", pos.x() / mm, pos.y() / mm, + pos.z() / mm); + m_log->trace("dimension size: {}", dim.size()); + for (size_t j = 0; j < std::size(dim); ++j) { + m_log->trace(" - dimension {:<5} size: {:.2}", j, dim[j]); + } } - return std::move(rec_hits); + // Note about variance: + // The variance is used to obtain a diagonal covariance matrix. + // Note that the covariance matrix is written in DD4hep surface coordinates, + // *NOT* global position coordinates. This implies that: + // - XY segmentation: xx -> sigma_x, yy-> sigma_y, zz -> 0, tt -> 0 + // - XZ segmentation: xx -> sigma_x, yy-> sigma_z, zz -> 0, tt -> 0 + // - XYZ segmentation: xx -> sigma_x, yy-> sigma_y, zz -> sigma_z, tt -> 0 + // This is properly in line with how we get the local coordinates for the hit + // in the TrackerSourceLinker. +#if EDM4EIC_VERSION_MAJOR >= 7 + auto rec_hit = +#endif + rec_hits->create(raw_hit.getCellID(), // Raw DD4hep cell ID + edm4hep::Vector3f{static_cast(pos.x() / mm), + static_cast(pos.y() / mm), + static_cast(pos.z() / mm)}, // mm + edm4eic::CovDiag3f{get_variance(dim[0] / mm), + get_variance(dim[1] / mm), // variance (see note above) + std::size(dim) > 2 ? get_variance(dim[2] / mm) : 0.}, + static_cast((double)(raw_hit.getTimeStamp()) / 1000.0), // ns + m_cfg.timeResolution, // in ns + static_cast(raw_hit.getCharge() / 1.0e6), // Collected energy (GeV) + 0.0F); // Error on the energy +#if EDM4EIC_VERSION_MAJOR >= 7 + rec_hit.setRawHit(raw_hit); +#endif + } + + return std::move(rec_hits); } } // namespace eicrecon diff --git a/src/algorithms/tracking/TrackerHitReconstruction.h b/src/algorithms/tracking/TrackerHitReconstruction.h index e6b67e2d6f..138cd33f2f 100644 --- a/src/algorithms/tracking/TrackerHitReconstruction.h +++ b/src/algorithms/tracking/TrackerHitReconstruction.h @@ -14,26 +14,32 @@ namespace eicrecon { - /** +/** * Produces edm4eic::TrackerHit with geometric info from edm4eic::RawTrackerHit */ - class TrackerHitReconstruction : public WithPodConfig { - - public: - /// Once in a lifetime initialization - void init(const dd4hep::rec::CellIDPositionConverter* converter, std::shared_ptr& logger); - - /// Processes RawTrackerHit and produces a TrackerHit - std::unique_ptr process(const edm4eic::RawTrackerHitCollection& raw_hits); - - /// Set a configuration - eicrecon::TrackerHitReconstructionConfig& applyConfig(eicrecon::TrackerHitReconstructionConfig& cfg) {m_cfg = cfg; return m_cfg;} - - private: - /** algorithm logger */ - std::shared_ptr m_log; - - /// Cell ID position converter - const dd4hep::rec::CellIDPositionConverter* m_converter; - }; -} +class TrackerHitReconstruction : public WithPodConfig { + +public: + /// Once in a lifetime initialization + void init(const dd4hep::rec::CellIDPositionConverter* converter, + std::shared_ptr& logger); + + /// Processes RawTrackerHit and produces a TrackerHit + std::unique_ptr + process(const edm4eic::RawTrackerHitCollection& raw_hits); + + /// Set a configuration + eicrecon::TrackerHitReconstructionConfig& + applyConfig(eicrecon::TrackerHitReconstructionConfig& cfg) { + m_cfg = cfg; + return m_cfg; + } + +private: + /** algorithm logger */ + std::shared_ptr m_log; + + /// Cell ID position converter + const dd4hep::rec::CellIDPositionConverter* m_converter; +}; +} // namespace eicrecon diff --git a/src/algorithms/tracking/TrackerHitReconstructionConfig.h b/src/algorithms/tracking/TrackerHitReconstructionConfig.h index 35d81adbe4..c903611564 100644 --- a/src/algorithms/tracking/TrackerHitReconstructionConfig.h +++ b/src/algorithms/tracking/TrackerHitReconstructionConfig.h @@ -4,7 +4,7 @@ #pragma once namespace eicrecon { - struct TrackerHitReconstructionConfig { - float timeResolution = 10; - }; -} +struct TrackerHitReconstructionConfig { + float timeResolution = 10; +}; +} // namespace eicrecon diff --git a/src/algorithms/tracking/TrackerMeasurementFromHits.cc b/src/algorithms/tracking/TrackerMeasurementFromHits.cc index 53c429e28f..2ca9e97c0e 100644 --- a/src/algorithms/tracking/TrackerMeasurementFromHits.cc +++ b/src/algorithms/tracking/TrackerMeasurementFromHits.cc @@ -27,111 +27,123 @@ #include #include - namespace eicrecon { - - void TrackerMeasurementFromHits::init(const dd4hep::Detector* detector, - const dd4hep::rec::CellIDPositionConverter* converter, - std::shared_ptr acts_context, - std::shared_ptr logger) { - m_dd4hepGeo = detector; - m_converter = converter; - m_log = logger; - m_acts_context = std::move(acts_context); - m_detid_b0tracker = m_dd4hepGeo->constant("B0Tracker_Station_1_ID"); +void TrackerMeasurementFromHits::init(const dd4hep::Detector* detector, + const dd4hep::rec::CellIDPositionConverter* converter, + std::shared_ptr acts_context, + std::shared_ptr logger) { + m_dd4hepGeo = detector; + m_converter = converter; + m_log = logger; + m_acts_context = std::move(acts_context); + m_detid_b0tracker = m_dd4hepGeo->constant("B0Tracker_Station_1_ID"); } +std::unique_ptr +TrackerMeasurementFromHits::produce(const edm4eic::TrackerHitCollection& trk_hits) { + constexpr double mm_acts = Acts::UnitConstants::mm; + constexpr double mm_conv = mm_acts / dd4hep::mm; // = 1/0.1 + + // output collections + auto meas2Ds = std::make_unique(); + + // To do: add clustering to allow forming one measurement from several hits. + // For now, one hit = one measurement. + for (const auto hit : trk_hits) { + + Acts::SquareMatrix2 cov = Acts::SquareMatrix2::Zero(); + cov(0, 0) = hit.getPositionError().xx * mm_acts * mm_acts; // note mm = 1 (Acts) + cov(1, 1) = hit.getPositionError().yy * mm_acts * mm_acts; + cov(0, 1) = cov(1, 0) = 0.0; + + const auto* vol_ctx = m_converter->findContext(hit.getCellID()); + auto vol_id = vol_ctx->identifier; + + auto surfaceMap = m_acts_context->surfaceMap(); + + // m_log->trace("Hit preparation information: {}", hit_index); + m_log->trace(" System id: {}, Cell id: {}", hit.getCellID() & 0xFF, hit.getCellID()); + m_log->trace(" cov matrix: {:>12.2e} {:>12.2e}", cov(0, 0), cov(0, 1)); + m_log->trace(" {:>12.2e} {:>12.2e}", cov(1, 0), cov(1, 1)); + m_log->trace(" surfaceMap size: {}", surfaceMap.size()); - std::unique_ptr TrackerMeasurementFromHits::produce(const edm4eic::TrackerHitCollection& trk_hits) { - constexpr double mm_acts = Acts::UnitConstants::mm; - constexpr double mm_conv = mm_acts / dd4hep::mm; // = 1/0.1 - - // output collections - auto meas2Ds = std::make_unique(); - - // To do: add clustering to allow forming one measurement from several hits. - // For now, one hit = one measurement. - for (const auto hit: trk_hits) { - - Acts::SquareMatrix2 cov = Acts::SquareMatrix2::Zero(); - cov(0, 0) = hit.getPositionError().xx * mm_acts * mm_acts; // note mm = 1 (Acts) - cov(1, 1) = hit.getPositionError().yy * mm_acts * mm_acts; - cov(0, 1) = cov(1, 0) = 0.0; - - const auto* vol_ctx = m_converter->findContext(hit.getCellID()); - auto vol_id = vol_ctx->identifier; - - auto surfaceMap = m_acts_context->surfaceMap(); - - // m_log->trace("Hit preparation information: {}", hit_index); - m_log->trace(" System id: {}, Cell id: {}", hit.getCellID() &0xFF, hit.getCellID()); - m_log->trace(" cov matrix: {:>12.2e} {:>12.2e}", cov(0,0), cov(0,1)); - m_log->trace(" {:>12.2e} {:>12.2e}", cov(1,0), cov(1,1)); - m_log->trace(" surfaceMap size: {}", surfaceMap.size()); - - const auto is = surfaceMap.find(vol_id); - if (is == m_acts_context->surfaceMap().end()) { - m_log->warn(" WARNING: vol_id ({}) not found in m_surfaces.", vol_id ); - continue; - } - const Acts::Surface* surface = is->second; - // variable surf_center not used anywhere; - - const auto& hit_pos = hit.getPosition(); // 3d position - - Acts::Vector2 loc = Acts::Vector2::Zero(); - Acts::Vector2 pos; - auto hit_det = hit.getCellID()&0xFF; - auto onSurfaceTolerance = 0.1*Acts::UnitConstants::um; // By default, ACTS uses 0.1 micron as the on surface tolerance - if (hit_det==m_detid_b0tracker){ - onSurfaceTolerance = 1*Acts::UnitConstants::um; // FIXME Ugly hack for testing B0. Should be a way to increase this tolerance in geometry. - } - - try { - // transform global position into local coordinates - // geometry context contains nothing here - pos = surface->globalToLocal( - Acts::GeometryContext(), - {hit_pos.x, hit_pos.y, hit_pos.z}, - {0, 0, 0}, onSurfaceTolerance).value(); - - loc[Acts::eBoundLoc0] = pos[0]; - loc[Acts::eBoundLoc1] = pos[1]; - } - catch(std::exception &ex) { - m_log->warn("Can't convert globalToLocal for hit: vol_id={} det_id={} CellID={} x={} y={} z={}", - vol_id, hit.getCellID()&0xFF, hit.getCellID(), hit_pos.x, hit_pos.y, hit_pos.z); - continue; - } - - if (m_log->level() <= spdlog::level::trace) { - auto volman = m_acts_context->dd4hepDetector()->volumeManager(); - auto alignment = volman.lookupDetElement(vol_id).nominal(); - auto local_position = (alignment.worldToLocal({hit_pos.x / mm_conv, hit_pos.y / mm_conv, hit_pos.z / mm_conv})) * mm_conv; - double surf_center_x = surface->center(Acts::GeometryContext()).transpose()[0]; - double surf_center_y = surface->center(Acts::GeometryContext()).transpose()[1]; - double surf_center_z = surface->center(Acts::GeometryContext()).transpose()[2]; - m_log->trace(" hit position : {:>10.2f} {:>10.2f} {:>10.2f}", hit_pos.x, hit_pos.y, hit_pos.z); - m_log->trace(" local position : {:>10.2f} {:>10.2f} {:>10.2f}", local_position.x(), local_position.y(), local_position.z()); - m_log->trace(" surface center : {:>10.2f} {:>10.2f} {:>10.2f}", surf_center_x, surf_center_y, surf_center_z); - m_log->trace(" acts local center: {:>10.2f} {:>10.2f}", pos.transpose()[0], pos.transpose()[1]); - m_log->trace(" acts loc pos : {:>10.2f} {:>10.2f}", loc[Acts::eBoundLoc0], loc[Acts::eBoundLoc1]); - } - - - auto meas2D = meas2Ds->create(); - meas2D.setSurface(surface->geometryId().value()); // Surface for bound coordinates (geometryID) - meas2D.setLoc({static_cast(pos[0]),static_cast(pos[1])}); // 2D location on surface - meas2D.setTime(hit.getTime()); // Measurement time - // fixme: no off-diagonal terms. cov(0,1) = cov(1,0)?? - meas2D.setCovariance({cov(0,0), cov(1,1), hit.getTimeError() * hit.getTimeError(), cov(0,1)}); // Covariance on location and time - meas2D.addToWeights(1.0); // Weight for each of the hits, mirrors hits array - meas2D.addToHits(hit); - } - - m_log->debug("All hits processed. Hits size: {} measurements->size: {}", trk_hits.size(), meas2Ds->size()); - - return std::move(meas2Ds); + const auto is = surfaceMap.find(vol_id); + if (is == m_acts_context->surfaceMap().end()) { + m_log->warn(" WARNING: vol_id ({}) not found in m_surfaces.", vol_id); + continue; } + const Acts::Surface* surface = is->second; + // variable surf_center not used anywhere; + + const auto& hit_pos = hit.getPosition(); // 3d position + + Acts::Vector2 loc = Acts::Vector2::Zero(); + Acts::Vector2 pos; + auto hit_det = hit.getCellID() & 0xFF; + auto onSurfaceTolerance = + 0.1 * + Acts::UnitConstants::um; // By default, ACTS uses 0.1 micron as the on surface tolerance + if (hit_det == m_detid_b0tracker) { + onSurfaceTolerance = + 1 * + Acts::UnitConstants:: + um; // FIXME Ugly hack for testing B0. Should be a way to increase this tolerance in geometry. + } + + try { + // transform global position into local coordinates + // geometry context contains nothing here + pos = surface + ->globalToLocal(Acts::GeometryContext(), {hit_pos.x, hit_pos.y, hit_pos.z}, + {0, 0, 0}, onSurfaceTolerance) + .value(); + + loc[Acts::eBoundLoc0] = pos[0]; + loc[Acts::eBoundLoc1] = pos[1]; + } catch (std::exception& ex) { + m_log->warn( + "Can't convert globalToLocal for hit: vol_id={} det_id={} CellID={} x={} y={} z={}", + vol_id, hit.getCellID() & 0xFF, hit.getCellID(), hit_pos.x, hit_pos.y, hit_pos.z); + continue; + } + + if (m_log->level() <= spdlog::level::trace) { + auto volman = m_acts_context->dd4hepDetector()->volumeManager(); + auto alignment = volman.lookupDetElement(vol_id).nominal(); + auto local_position = (alignment.worldToLocal( + {hit_pos.x / mm_conv, hit_pos.y / mm_conv, hit_pos.z / mm_conv})) * + mm_conv; + double surf_center_x = surface->center(Acts::GeometryContext()).transpose()[0]; + double surf_center_y = surface->center(Acts::GeometryContext()).transpose()[1]; + double surf_center_z = surface->center(Acts::GeometryContext()).transpose()[2]; + m_log->trace(" hit position : {:>10.2f} {:>10.2f} {:>10.2f}", hit_pos.x, hit_pos.y, + hit_pos.z); + m_log->trace(" local position : {:>10.2f} {:>10.2f} {:>10.2f}", local_position.x(), + local_position.y(), local_position.z()); + m_log->trace(" surface center : {:>10.2f} {:>10.2f} {:>10.2f}", surf_center_x, + surf_center_y, surf_center_z); + m_log->trace(" acts local center: {:>10.2f} {:>10.2f}", pos.transpose()[0], + pos.transpose()[1]); + m_log->trace(" acts loc pos : {:>10.2f} {:>10.2f}", loc[Acts::eBoundLoc0], + loc[Acts::eBoundLoc1]); + } + + auto meas2D = meas2Ds->create(); + meas2D.setSurface(surface->geometryId().value()); // Surface for bound coordinates (geometryID) + meas2D.setLoc( + {static_cast(pos[0]), static_cast(pos[1])}); // 2D location on surface + meas2D.setTime(hit.getTime()); // Measurement time + // fixme: no off-diagonal terms. cov(0,1) = cov(1,0)?? + meas2D.setCovariance({cov(0, 0), cov(1, 1), hit.getTimeError() * hit.getTimeError(), + cov(0, 1)}); // Covariance on location and time + meas2D.addToWeights(1.0); // Weight for each of the hits, mirrors hits array + meas2D.addToHits(hit); + } + + m_log->debug("All hits processed. Hits size: {} measurements->size: {}", trk_hits.size(), + meas2Ds->size()); + + return std::move(meas2Ds); +} } // namespace eicrecon diff --git a/src/algorithms/tracking/TrackerMeasurementFromHits.h b/src/algorithms/tracking/TrackerMeasurementFromHits.h index 5c7de0275a..e25ff8d56a 100644 --- a/src/algorithms/tracking/TrackerMeasurementFromHits.h +++ b/src/algorithms/tracking/TrackerMeasurementFromHits.h @@ -18,26 +18,26 @@ namespace eicrecon { - class TrackerMeasurementFromHits { - public: - void init(const dd4hep::Detector* detector, - const dd4hep::rec::CellIDPositionConverter* converter, - std::shared_ptr acts_context, - std::shared_ptr logger); +class TrackerMeasurementFromHits { +public: + void init(const dd4hep::Detector* detector, const dd4hep::rec::CellIDPositionConverter* converter, + std::shared_ptr acts_context, + std::shared_ptr logger); - std::unique_ptr produce(const edm4eic::TrackerHitCollection& trk_hits); + std::unique_ptr + produce(const edm4eic::TrackerHitCollection& trk_hits); - private: - std::shared_ptr m_log; +private: + std::shared_ptr m_log; - /// Geometry and Cell ID position converter - const dd4hep::Detector* m_dd4hepGeo; - const dd4hep::rec::CellIDPositionConverter* m_converter; + /// Geometry and Cell ID position converter + const dd4hep::Detector* m_dd4hepGeo; + const dd4hep::rec::CellIDPositionConverter* m_converter; - std::shared_ptr m_acts_context; + std::shared_ptr m_acts_context; - /// Detector-specific information - int m_detid_b0tracker; - }; + /// Detector-specific information + int m_detid_b0tracker; +}; -} +} // namespace eicrecon diff --git a/src/algorithms/tracking/TracksToParticles.cc b/src/algorithms/tracking/TracksToParticles.cc index 499f65f5b8..d4188b79a6 100644 --- a/src/algorithms/tracking/TracksToParticles.cc +++ b/src/algorithms/tracking/TracksToParticles.cc @@ -16,63 +16,64 @@ #include "TracksToParticles.h" - namespace eicrecon { - void TracksToParticles::init() {} - - void TracksToParticles::process( - const TracksToParticles::Input& input, const TracksToParticles::Output& output - ) const { - const auto [tracks, track_assocs] = input; - auto [parts, part_assocs] = output; +void TracksToParticles::init() {} - for (const auto &track: *tracks) { - auto trajectory = track.getTrajectory(); - for (const auto &trk: trajectory.getTrackParameters()) { - const auto mom = edm4hep::utils::sphericalToVector(1.0 / std::abs(trk.getQOverP()), trk.getTheta(), - trk.getPhi()); - const auto charge_rec = std::copysign(1., trk.getQOverP()); +void TracksToParticles::process(const TracksToParticles::Input& input, + const TracksToParticles::Output& output) const { + const auto [tracks, track_assocs] = input; + auto [parts, part_assocs] = output; + for (const auto& track : *tracks) { + auto trajectory = track.getTrajectory(); + for (const auto& trk : trajectory.getTrackParameters()) { + const auto mom = edm4hep::utils::sphericalToVector(1.0 / std::abs(trk.getQOverP()), + trk.getTheta(), trk.getPhi()); + const auto charge_rec = std::copysign(1., trk.getQOverP()); - debug("Converting track: index={:<4} momentum={:<8.3f} theta={:<8.3f} phi={:<8.2f} charge={:<4}", - trk.getObjectID().index, edm4hep::utils::magnitude(mom), edm4hep::utils::anglePolar(mom), edm4hep::utils::angleAzimuthal(mom), charge_rec); + debug("Converting track: index={:<4} momentum={:<8.3f} theta={:<8.3f} phi={:<8.2f} " + "charge={:<4}", + trk.getObjectID().index, edm4hep::utils::magnitude(mom), + edm4hep::utils::anglePolar(mom), edm4hep::utils::angleAzimuthal(mom), charge_rec); - auto rec_part = parts->create(); - rec_part.addToTracks(track); - rec_part.setType(0); - rec_part.setEnergy(edm4hep::utils::magnitude(mom)); - rec_part.setMomentum(mom); - rec_part.setCharge(charge_rec); - rec_part.setMass(0.); - rec_part.setGoodnessOfPID(0); // assume no PID until proven otherwise - // rec_part.covMatrix() // @TODO: covariance matrix on 4-momentum + auto rec_part = parts->create(); + rec_part.addToTracks(track); + rec_part.setType(0); + rec_part.setEnergy(edm4hep::utils::magnitude(mom)); + rec_part.setMomentum(mom); + rec_part.setCharge(charge_rec); + rec_part.setMass(0.); + rec_part.setGoodnessOfPID(0); // assume no PID until proven otherwise + // rec_part.covMatrix() // @TODO: covariance matrix on 4-momentum - double max_weight = -1.; - for (auto track_assoc : *track_assocs) { - if (track_assoc.getRec() == track) { - trace("Found track association: index={} -> index={}, weight={}", - track_assoc.getRec().getObjectID().index, - track_assoc.getSim().getObjectID().index, - track_assoc.getWeight()); - auto part_assoc = part_assocs->create(); - part_assoc.setRec(rec_part); - part_assoc.setSim(track_assoc.getSim()); - part_assoc.setRecID(part_assoc.getRec().getObjectID().index); - part_assoc.setSimID(part_assoc.getSim().getObjectID().index); - part_assoc.setWeight(track_assoc.getWeight()); + double max_weight = -1.; + for (auto track_assoc : *track_assocs) { + if (track_assoc.getRec() == track) { + trace("Found track association: index={} -> index={}, weight={}", + track_assoc.getRec().getObjectID().index, track_assoc.getSim().getObjectID().index, + track_assoc.getWeight()); + auto part_assoc = part_assocs->create(); + part_assoc.setRec(rec_part); + part_assoc.setSim(track_assoc.getSim()); + part_assoc.setRecID(part_assoc.getRec().getObjectID().index); + part_assoc.setSimID(part_assoc.getSim().getObjectID().index); + part_assoc.setWeight(track_assoc.getWeight()); - if (max_weight < track_assoc.getWeight()) { - max_weight = track_assoc.getWeight(); - edm4hep::Vector3f referencePoint = { - static_cast(track_assoc.getSim().getVertex().x), - static_cast(track_assoc.getSim().getVertex().y), - static_cast(track_assoc.getSim().getVertex().z)}; // @TODO: not sure if vertex/reference point makes sense here - rec_part.setReferencePoint(referencePoint); - } - } - } + if (max_weight < track_assoc.getWeight()) { + max_weight = track_assoc.getWeight(); + edm4hep::Vector3f referencePoint = { + static_cast(track_assoc.getSim().getVertex().x), + static_cast(track_assoc.getSim().getVertex().y), + static_cast( + track_assoc.getSim() + .getVertex() + .z)}; // @TODO: not sure if vertex/reference point makes sense here + rec_part.setReferencePoint(referencePoint); } } + } } + } } +} // namespace eicrecon diff --git a/src/algorithms/tracking/TracksToParticles.h b/src/algorithms/tracking/TracksToParticles.h index cf0ffc9746..0ef3941c20 100644 --- a/src/algorithms/tracking/TracksToParticles.h +++ b/src/algorithms/tracking/TracksToParticles.h @@ -1,7 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2022 - 2024, Sylvester Joosten, Wouter Deconinck, Dmitry Romanov, Christopher Dilks, Dmitry Kalinkin - #pragma once #include @@ -15,29 +14,25 @@ #include "algorithms/interfaces/WithPodConfig.h" - namespace eicrecon { -using TracksToParticlesAlgorithm = - algorithms::Algorithm< - algorithms::Input< - edm4eic::TrackCollection, - std::optional - >, - algorithms::Output< - edm4eic::ReconstructedParticleCollection, - std::optional - > - >; +using TracksToParticlesAlgorithm = algorithms::Algorithm< + algorithms::Input>, + algorithms::Output>>; class TracksToParticles : public TracksToParticlesAlgorithm, public WithPodConfig { public: - - TracksToParticles(std::string_view name) : TracksToParticlesAlgorithm{name, {"inputTracksCollection", "inputTrackAssociationsCollection"}, {"outputReconstructedParticlesCollection", "outputAssociationsCollection"}, "Converts track to particles with associations"} {}; - - void init() final; - void process(const Input&, const Output&) const final; - + TracksToParticles(std::string_view name) + : TracksToParticlesAlgorithm{ + name, + {"inputTracksCollection", "inputTrackAssociationsCollection"}, + {"outputReconstructedParticlesCollection", "outputAssociationsCollection"}, + "Converts track to particles with associations"} {}; + + void init() final; + void process(const Input&, const Output&) const final; }; -} +} // namespace eicrecon diff --git a/src/benchmarks/detectors/EcalBarrelScFiCheck/EcalBarrelScFiCheck.cc b/src/benchmarks/detectors/EcalBarrelScFiCheck/EcalBarrelScFiCheck.cc index 4b95373a25..f430586252 100644 --- a/src/benchmarks/detectors/EcalBarrelScFiCheck/EcalBarrelScFiCheck.cc +++ b/src/benchmarks/detectors/EcalBarrelScFiCheck/EcalBarrelScFiCheck.cc @@ -4,8 +4,8 @@ // The following just makes this a JANA plugin extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->Add(new EcalBarrelScFiCheckProcessor); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new EcalBarrelScFiCheckProcessor); +} } diff --git a/src/benchmarks/detectors/EcalBarrelScFiCheck/EcalBarrelScFiCheckProcessor.cc b/src/benchmarks/detectors/EcalBarrelScFiCheck/EcalBarrelScFiCheckProcessor.cc index 88234a2428..4cc1bd815b 100644 --- a/src/benchmarks/detectors/EcalBarrelScFiCheck/EcalBarrelScFiCheckProcessor.cc +++ b/src/benchmarks/detectors/EcalBarrelScFiCheck/EcalBarrelScFiCheckProcessor.cc @@ -21,78 +21,106 @@ //------------------------------------------- // InitWithGlobalRootLock //------------------------------------------- -void EcalBarrelScFiCheckProcessor::InitWithGlobalRootLock(){ - - auto rootfile_svc = GetApplication()->GetService(); - auto rootfile = rootfile_svc->GetHistFile(); - rootfile->mkdir("EcalBarrelScFi")->cd(); - - hist1D["EcalBarrelScFiHits_hits_per_event"] = new TH1I("EcalBarrelScFiHits_hits_per_event", "EcalBarrelScFi Simulated hit Nhits/event;Nhits", 300, 0.0, 3000); - hist2D["EcalBarrelScFiHits_occupancy"] = new TH2I("EcalBarrelScFiHits_occupancy", "EcalBarrelScFi Simulated hit occupancy;column;row", 70, -700.0, 700.0, 70, -700.0, 700.0); - hist1D["EcalBarrelScFiHits_hit_energy"] = new TH1D("EcalBarrelScFiHits_hit_energy", "EcalBarrelScFi Simulated hit energy;GeV", 1000, 0.0, 2.0); - - hist1D["EcalBarrelScFiRawHits_hits_per_event"] = new TH1I("EcalBarrelScFiRawHits_hits_per_event", "EcalBarrelScFi Simulated digitized hit Nhits/event;Nhits", 300, 0.0, 3000); - hist1D["EcalBarrelScFiRawHits_amplitude"] = new TH1D("EcalBarrelScFiRawHits_amplitude", "EcalBarrelScFi Simulated digitized hit amplitude;amplitude", 1000, 0.0, 8200.0); - hist1D["EcalBarrelScFiRawHits_timestamp"] = new TH1I("EcalBarrelScFiRawHits_timestamp", "EcalBarrelScFi Simulated digitized hit timestamp;timestamp", 1024, 0.0, 8191.0); - - hist1D["EcalBarrelScFiRecHits_hits_per_event"] = new TH1I("EcalBarrelScFiRecHits_hits_per_event", "EcalBarrelScFi Reconstructed hit Nhits/event;Nhits", 300, 0.0, 3000); - hist1D["EcalBarrelScFiRecHits_hit_energy"] = new TH1D("EcalBarrelScFiRecHits_hit_energy", "EcalBarrelScFi Reconstructed hit energy;MeV", 1000, 0.0, 100.0); - hist2D["EcalBarrelScFiRecHits_xy"] = new TH2D("EcalBarrelScFiRecHits_xy", "EcalBarrelScFi Reconstructed hit Y vs. X (energy weighted);x;y", 128, -1100.0, 1100.0, 128, -1100.0, 1100.0); - hist1D["EcalBarrelScFiRecHits_z"] = new TH1D("EcalBarrelScFiRecHits_z", "EcalBarrelScFi Reconstructed hit Z;z", 400, -3000.0, 1600.0); - hist1D["EcalBarrelScFiRecHits_time"] = new TH1D("EcalBarrelScFiRecHits_time", "EcalBarrelScFi Reconstructed hit time;time", 1000, -10.0, 2000.0); - - hist1D["EcalBarrelScFiProtoClusters_clusters_per_event"] = new TH1I("EcalBarrelScFiProtoClusters_clusters_per_event", "EcalBarrelScFi Protoclusters Nclusters/event;Nclusters", 61, -0.5, 60.5); - hist1D["EcalBarrelScFiProtoClusters_hits_per_cluster"] = new TH1I("EcalBarrelScFiProtoClusters_hits_per_cluster", "EcalBarrelScFi Protoclusters Nhits/cluster;Nhits", 101, -0.5, 100.5); - - // Set some draw options - hist2D["EcalBarrelScFiHits_occupancy"]->SetOption("colz"); - hist2D["EcalBarrelScFiRecHits_xy"]->SetOption("colz"); +void EcalBarrelScFiCheckProcessor::InitWithGlobalRootLock() { + + auto rootfile_svc = GetApplication()->GetService(); + auto rootfile = rootfile_svc->GetHistFile(); + rootfile->mkdir("EcalBarrelScFi")->cd(); + + hist1D["EcalBarrelScFiHits_hits_per_event"] = + new TH1I("EcalBarrelScFiHits_hits_per_event", + "EcalBarrelScFi Simulated hit Nhits/event;Nhits", 300, 0.0, 3000); + hist2D["EcalBarrelScFiHits_occupancy"] = + new TH2I("EcalBarrelScFiHits_occupancy", "EcalBarrelScFi Simulated hit occupancy;column;row", + 70, -700.0, 700.0, 70, -700.0, 700.0); + hist1D["EcalBarrelScFiHits_hit_energy"] = new TH1D( + "EcalBarrelScFiHits_hit_energy", "EcalBarrelScFi Simulated hit energy;GeV", 1000, 0.0, 2.0); + + hist1D["EcalBarrelScFiRawHits_hits_per_event"] = + new TH1I("EcalBarrelScFiRawHits_hits_per_event", + "EcalBarrelScFi Simulated digitized hit Nhits/event;Nhits", 300, 0.0, 3000); + hist1D["EcalBarrelScFiRawHits_amplitude"] = + new TH1D("EcalBarrelScFiRawHits_amplitude", + "EcalBarrelScFi Simulated digitized hit amplitude;amplitude", 1000, 0.0, 8200.0); + hist1D["EcalBarrelScFiRawHits_timestamp"] = + new TH1I("EcalBarrelScFiRawHits_timestamp", + "EcalBarrelScFi Simulated digitized hit timestamp;timestamp", 1024, 0.0, 8191.0); + + hist1D["EcalBarrelScFiRecHits_hits_per_event"] = + new TH1I("EcalBarrelScFiRecHits_hits_per_event", + "EcalBarrelScFi Reconstructed hit Nhits/event;Nhits", 300, 0.0, 3000); + hist1D["EcalBarrelScFiRecHits_hit_energy"] = + new TH1D("EcalBarrelScFiRecHits_hit_energy", "EcalBarrelScFi Reconstructed hit energy;MeV", + 1000, 0.0, 100.0); + hist2D["EcalBarrelScFiRecHits_xy"] = new TH2D( + "EcalBarrelScFiRecHits_xy", "EcalBarrelScFi Reconstructed hit Y vs. X (energy weighted);x;y", + 128, -1100.0, 1100.0, 128, -1100.0, 1100.0); + hist1D["EcalBarrelScFiRecHits_z"] = new TH1D( + "EcalBarrelScFiRecHits_z", "EcalBarrelScFi Reconstructed hit Z;z", 400, -3000.0, 1600.0); + hist1D["EcalBarrelScFiRecHits_time"] = + new TH1D("EcalBarrelScFiRecHits_time", "EcalBarrelScFi Reconstructed hit time;time", 1000, + -10.0, 2000.0); + + hist1D["EcalBarrelScFiProtoClusters_clusters_per_event"] = + new TH1I("EcalBarrelScFiProtoClusters_clusters_per_event", + "EcalBarrelScFi Protoclusters Nclusters/event;Nclusters", 61, -0.5, 60.5); + hist1D["EcalBarrelScFiProtoClusters_hits_per_cluster"] = + new TH1I("EcalBarrelScFiProtoClusters_hits_per_cluster", + "EcalBarrelScFi Protoclusters Nhits/cluster;Nhits", 101, -0.5, 100.5); + + // Set some draw options + hist2D["EcalBarrelScFiHits_occupancy"]->SetOption("colz"); + hist2D["EcalBarrelScFiRecHits_xy"]->SetOption("colz"); } //------------------------------------------- // ProcessSequential //------------------------------------------- void EcalBarrelScFiCheckProcessor::ProcessSequential(const std::shared_ptr& event) { - const auto &EcalBarrelScFiHits = *(event->GetCollection("EcalBarrelScFiHits")); - const auto &EcalBarrelScFiRawHits = *(event->GetCollection("EcalBarrelScFiRawHits")); - const auto &EcalBarrelScFiRecHits = *(event->GetCollection("EcalBarrelScFiRecHits")); - const auto &EcalBarrelScFiProtoClusters = *(event->GetCollection("EcalBarrelScFiProtoClusters")); - - // Fill histograms here - - // EcalBarrelScFiHits - hist1D["EcalBarrelScFiHits_hits_per_event"]->Fill(EcalBarrelScFiHits.size()); - for( auto hit : EcalBarrelScFiHits ){ - auto row = floor(hit.getPosition().y); - auto col = floor(hit.getPosition().x); - hist2D["EcalBarrelScFiHits_occupancy"]->Fill(row, col); - - hist1D["EcalBarrelScFiHits_hit_energy"]->Fill(hit.getEnergy()); - } - - // EcalBarrelScFiRawHits - hist1D["EcalBarrelScFiRawHits_hits_per_event"]->Fill(EcalBarrelScFiRawHits.size()); - for( auto hit : EcalBarrelScFiRawHits ){ - hist1D["EcalBarrelScFiRawHits_amplitude"]->Fill( hit.getAmplitude() ); - hist1D["EcalBarrelScFiRawHits_timestamp"]->Fill( hit.getTimeStamp() ); - } - - // EcalBarrelScFiRecHits - hist1D["EcalBarrelScFiRecHits_hits_per_event"]->Fill(EcalBarrelScFiRecHits.size()); - for( auto hit : EcalBarrelScFiRecHits ){ - auto &pos = hit.getPosition(); - hist1D["EcalBarrelScFiRecHits_hit_energy"]->Fill(hit.getEnergy() / dd4hep::MeV); - hist2D["EcalBarrelScFiRecHits_xy"]->Fill( pos.x, pos.y, hit.getEnergy() ); - hist1D["EcalBarrelScFiRecHits_z"]->Fill(pos.z); - hist1D["EcalBarrelScFiRecHits_time"]->Fill( hit.getTime() ); - } - - - // EcalBarrelScFiProtoClusters - hist1D["EcalBarrelScFiProtoClusters_clusters_per_event"]->Fill(EcalBarrelScFiProtoClusters.size()); - for (auto proto : EcalBarrelScFiProtoClusters ){ - hist1D["EcalBarrelScFiProtoClusters_hits_per_cluster"]->Fill( proto.getHits().size() ); - } + const auto& EcalBarrelScFiHits = + *(event->GetCollection("EcalBarrelScFiHits")); + const auto& EcalBarrelScFiRawHits = + *(event->GetCollection("EcalBarrelScFiRawHits")); + const auto& EcalBarrelScFiRecHits = + *(event->GetCollection("EcalBarrelScFiRecHits")); + const auto& EcalBarrelScFiProtoClusters = + *(event->GetCollection("EcalBarrelScFiProtoClusters")); + + // Fill histograms here + + // EcalBarrelScFiHits + hist1D["EcalBarrelScFiHits_hits_per_event"]->Fill(EcalBarrelScFiHits.size()); + for (auto hit : EcalBarrelScFiHits) { + auto row = floor(hit.getPosition().y); + auto col = floor(hit.getPosition().x); + hist2D["EcalBarrelScFiHits_occupancy"]->Fill(row, col); + + hist1D["EcalBarrelScFiHits_hit_energy"]->Fill(hit.getEnergy()); + } + + // EcalBarrelScFiRawHits + hist1D["EcalBarrelScFiRawHits_hits_per_event"]->Fill(EcalBarrelScFiRawHits.size()); + for (auto hit : EcalBarrelScFiRawHits) { + hist1D["EcalBarrelScFiRawHits_amplitude"]->Fill(hit.getAmplitude()); + hist1D["EcalBarrelScFiRawHits_timestamp"]->Fill(hit.getTimeStamp()); + } + + // EcalBarrelScFiRecHits + hist1D["EcalBarrelScFiRecHits_hits_per_event"]->Fill(EcalBarrelScFiRecHits.size()); + for (auto hit : EcalBarrelScFiRecHits) { + auto& pos = hit.getPosition(); + hist1D["EcalBarrelScFiRecHits_hit_energy"]->Fill(hit.getEnergy() / dd4hep::MeV); + hist2D["EcalBarrelScFiRecHits_xy"]->Fill(pos.x, pos.y, hit.getEnergy()); + hist1D["EcalBarrelScFiRecHits_z"]->Fill(pos.z); + hist1D["EcalBarrelScFiRecHits_time"]->Fill(hit.getTime()); + } + + // EcalBarrelScFiProtoClusters + hist1D["EcalBarrelScFiProtoClusters_clusters_per_event"]->Fill( + EcalBarrelScFiProtoClusters.size()); + for (auto proto : EcalBarrelScFiProtoClusters) { + hist1D["EcalBarrelScFiProtoClusters_hits_per_cluster"]->Fill(proto.getHits().size()); + } } //------------------------------------------- @@ -100,6 +128,5 @@ void EcalBarrelScFiCheckProcessor::ProcessSequential(const std::shared_ptr #include -class EcalBarrelScFiCheckProcessor: public JEventProcessorSequentialRoot { +class EcalBarrelScFiCheckProcessor : public JEventProcessorSequentialRoot { private: - - // Declare histogram and tree pointers - std::map hist1D; - std::map hist2D; + // Declare histogram and tree pointers + std::map hist1D; + std::map hist2D; public: - EcalBarrelScFiCheckProcessor() { SetTypeName(NAME_OF_THIS); } + EcalBarrelScFiCheckProcessor() { SetTypeName(NAME_OF_THIS); } - void InitWithGlobalRootLock() override; - void ProcessSequential(const std::shared_ptr& event) override; - void FinishWithGlobalRootLock() override; + void InitWithGlobalRootLock() override; + void ProcessSequential(const std::shared_ptr& event) override; + void FinishWithGlobalRootLock() override; }; diff --git a/src/benchmarks/reconstruction/TRACKINGcheck/TRACKINGcheck.cc b/src/benchmarks/reconstruction/TRACKINGcheck/TRACKINGcheck.cc index aa7f0e6cad..59322d4e96 100644 --- a/src/benchmarks/reconstruction/TRACKINGcheck/TRACKINGcheck.cc +++ b/src/benchmarks/reconstruction/TRACKINGcheck/TRACKINGcheck.cc @@ -4,8 +4,8 @@ // The following just makes this a JANA plugin extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->Add(new TRACKINGcheckProcessor); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new TRACKINGcheckProcessor); +} } diff --git a/src/benchmarks/reconstruction/TRACKINGcheck/TRACKINGcheckProcessor.cc b/src/benchmarks/reconstruction/TRACKINGcheck/TRACKINGcheckProcessor.cc index c2cb9afb8e..052b7e651f 100644 --- a/src/benchmarks/reconstruction/TRACKINGcheck/TRACKINGcheckProcessor.cc +++ b/src/benchmarks/reconstruction/TRACKINGcheck/TRACKINGcheckProcessor.cc @@ -15,45 +15,52 @@ //------------------------------------------- // InitWithGlobalRootLock //------------------------------------------- -void TRACKINGcheckProcessor::InitWithGlobalRootLock(){ - - auto rootfile_svc = GetApplication()->GetService(); - auto *rootfile = rootfile_svc->GetHistFile(); - rootfile->mkdir("TRACKING")->cd(); - - hist1D["Trajectories_trajectories_per_event"] = new TH1I("Trajectories_trajectories_per_event", "TRACKING Reconstructed trajectories/event;Ntrajectories", 201, -0.5, 200.5); - hist1D["Trajectories_time"] = new TH1D("Trajectories_time", "TRACKING reconstructed particle time;time (ns)", 200, -100.0, 100.0); - hist2D["Trajectories_xy"] = new TH2D("Trajectories_xy", "TRACKING reconstructed position Y vs. X;x;y", 100, -1000.0, 1000.0, 100, -1000., 1000.0); - hist1D["Trajectories_z"] = new TH1D("Trajectories_z", "TRACKING reconstructed position Z;z", 200, -50.0, 50.0); - - // Set some draw options - hist2D["Trajectories_xy"]->SetOption("colz"); +void TRACKINGcheckProcessor::InitWithGlobalRootLock() { + + auto rootfile_svc = GetApplication()->GetService(); + auto* rootfile = rootfile_svc->GetHistFile(); + rootfile->mkdir("TRACKING")->cd(); + + hist1D["Trajectories_trajectories_per_event"] = + new TH1I("Trajectories_trajectories_per_event", + "TRACKING Reconstructed trajectories/event;Ntrajectories", 201, -0.5, 200.5); + hist1D["Trajectories_time"] = new TH1D( + "Trajectories_time", "TRACKING reconstructed particle time;time (ns)", 200, -100.0, 100.0); + hist2D["Trajectories_xy"] = + new TH2D("Trajectories_xy", "TRACKING reconstructed position Y vs. X;x;y", 100, -1000.0, + 1000.0, 100, -1000., 1000.0); + hist1D["Trajectories_z"] = + new TH1D("Trajectories_z", "TRACKING reconstructed position Z;z", 200, -50.0, 50.0); + + // Set some draw options + hist2D["Trajectories_xy"]->SetOption("colz"); } //------------------------------------------- // ProcessSequential //------------------------------------------- void TRACKINGcheckProcessor::ProcessSequential(const std::shared_ptr& event) { - auto Trajectories = event->Get("CentralCKFActsTrajectories"); + auto Trajectories = event->Get("CentralCKFActsTrajectories"); - // Fill histograms here + // Fill histograms here - // Trajectories - hist1D["Trajectories_trajectories_per_event"]->Fill(Trajectories.size()); + // Trajectories + hist1D["Trajectories_trajectories_per_event"]->Fill(Trajectories.size()); - for( const auto *traj : Trajectories ){ - for( auto entryIndex : traj->tips() ){ - if( ! traj->hasTrackParameters( entryIndex) ) continue; - auto trackparams = traj->trackParameters( entryIndex ); + for (const auto* traj : Trajectories) { + for (auto entryIndex : traj->tips()) { + if (!traj->hasTrackParameters(entryIndex)) + continue; + auto trackparams = traj->trackParameters(entryIndex); - auto pos = trackparams.position(Acts::GeometryContext()); - auto t = trackparams.time(); + auto pos = trackparams.position(Acts::GeometryContext()); + auto t = trackparams.time(); - hist1D["Trajectories_time"]->Fill( t ); - hist2D["Trajectories_xy"]->Fill( pos.x(), pos.y()); - hist1D["Trajectories_z"]->Fill( pos.z() ); - } + hist1D["Trajectories_time"]->Fill(t); + hist2D["Trajectories_xy"]->Fill(pos.x(), pos.y()); + hist1D["Trajectories_z"]->Fill(pos.z()); } + } } //------------------------------------------- @@ -61,6 +68,5 @@ void TRACKINGcheckProcessor::ProcessSequential(const std::shared_ptr #include - -class TRACKINGcheckProcessor: public JEventProcessorSequentialRoot { +class TRACKINGcheckProcessor : public JEventProcessorSequentialRoot { private: - - // Containers for histograms - std::map hist1D; - std::map hist2D; + // Containers for histograms + std::map hist1D; + std::map hist2D; public: - TRACKINGcheckProcessor() { SetTypeName(NAME_OF_THIS); } + TRACKINGcheckProcessor() { SetTypeName(NAME_OF_THIS); } - void InitWithGlobalRootLock() override; - void ProcessSequential(const std::shared_ptr& event) override; - void FinishWithGlobalRootLock() override; + void InitWithGlobalRootLock() override; + void ProcessSequential(const std::shared_ptr& event) override; + void FinishWithGlobalRootLock() override; }; diff --git a/src/benchmarks/reconstruction/TRACKINGcheck/macros/TRACKINGcheck.C b/src/benchmarks/reconstruction/TRACKINGcheck/macros/TRACKINGcheck.C index b462ad2a52..95d25b66dd 100644 --- a/src/benchmarks/reconstruction/TRACKINGcheck/macros/TRACKINGcheck.C +++ b/src/benchmarks/reconstruction/TRACKINGcheck/macros/TRACKINGcheck.C @@ -1,82 +1,84 @@ -void EEMCcheck(void) -{ - auto fil = new TFile("eicrecon.root"); - - auto EcalEndcapNhits_hits_per_event = (TH1I*)fil->Get("EEMC/EcalEndcapNhits_hits_per_event"); - auto EcalEndcapNhits_occupancy = (TH2I*)fil->Get("EEMC/EcalEndcapNhits_occupancy"); - auto EcalEndcapNhits_hit_energy = (TH1D*)fil->Get("EEMC/EcalEndcapNhits_hit_energy"); - - auto EcalEndcapNRawhits_hits_per_event = (TH1I*)fil->Get("EEMC/EcalEndcapNRawhits_hits_per_event"); - auto EcalEndcapNRawhits_amplitude = (TH1D*)fil->Get("EEMC/EcalEndcapNRawhits_amplitude"); - auto EcalEndcapNRawhits_timestamp = (TH1I*)fil->Get("EEMC/EcalEndcapNRawhits_timestamp"); - - auto EcalEndcapNRechits_hits_per_event = (TH1I*)fil->Get("EEMC/EcalEndcapNRechits_hits_per_event"); - auto EcalEndcapNRecHits_hit_energy = (TH1D*)fil->Get("EEMC/EcalEndcapNRecHits_hit_energy"); - auto EcalEndcapNRecHits_xy = (TH2D*)fil->Get("EEMC/EcalEndcapNRecHits_xy"); - auto EcalEndcapNRecHits_z = (TH1D*)fil->Get("EEMC/EcalEndcapNRecHits_z"); - auto EcalEndcapNRecHits_time = (TH1D*)fil->Get("EEMC/EcalEndcapNRecHits_time"); - - auto EcalEndcapNIslandProtoClusters_clusters_per_event = (TH1I*)fil->Get("EEMC/EcalEndcapNIslandProtoClusters_clusters_per_event"); - auto EcalEndcapNIslandProtoClusters_hits_per_cluster = (TH1I*)fil->Get("EEMC/EcalEndcapNIslandProtoClusters_hits_per_cluster"); - - - auto c1 = new TCanvas("c1", "", 1700, 1000); - c1->Divide(4,4); - - //---------------- EcalEndcapNhits - c1->cd(1); - gPad->SetLogy(); - EcalEndcapNhits_hits_per_event->Draw(); - - c1->cd(2); - EcalEndcapNhits_occupancy->Draw(); - - c1->cd(3); - gPad->SetLogy(); - EcalEndcapNhits_hit_energy->Draw(); - - //---------------- EcalEndcapNRawhits - c1->cd(5); - gPad->SetLogy(); - EcalEndcapNRawhits_hits_per_event->Draw(); - - c1->cd(6); - gPad->SetLogy(); - EcalEndcapNRawhits_amplitude->Draw(); - - c1->cd(7); - EcalEndcapNRawhits_timestamp->Draw(); - - //---------------- EcalEndcapNRecHits - c1->cd(9); - gPad->SetLogy(); - EcalEndcapNRechits_hits_per_event->Draw(); - - c1->cd(10); - EcalEndcapNRecHits_xy->Draw(); - - c1->cd(11); - EcalEndcapNRecHits_z->Draw(); - - c1->cd(12); - gPad->SetLogy(); - EcalEndcapNRecHits_time->Draw(); - - c1->cd(8); - gPad->SetLogy(); - EcalEndcapNRecHits_hit_energy->Draw(); - - //---------------- EcalEndcapNIslandProtoClusters - c1->cd(13); - gPad->SetLogy(); - EcalEndcapNIslandProtoClusters_clusters_per_event->Draw(); - - c1->cd(14); - gPad->SetLogy(); - EcalEndcapNIslandProtoClusters_hits_per_cluster->Draw(); - - c1->SaveAs("EEMCcheck.pdf"); - c1->SaveAs("EEMCcheck.png"); +void EEMCcheck(void) { + auto fil = new TFile("eicrecon.root"); + + auto EcalEndcapNhits_hits_per_event = (TH1I*)fil->Get("EEMC/EcalEndcapNhits_hits_per_event"); + auto EcalEndcapNhits_occupancy = (TH2I*)fil->Get("EEMC/EcalEndcapNhits_occupancy"); + auto EcalEndcapNhits_hit_energy = (TH1D*)fil->Get("EEMC/EcalEndcapNhits_hit_energy"); + + auto EcalEndcapNRawhits_hits_per_event = + (TH1I*)fil->Get("EEMC/EcalEndcapNRawhits_hits_per_event"); + auto EcalEndcapNRawhits_amplitude = (TH1D*)fil->Get("EEMC/EcalEndcapNRawhits_amplitude"); + auto EcalEndcapNRawhits_timestamp = (TH1I*)fil->Get("EEMC/EcalEndcapNRawhits_timestamp"); + + auto EcalEndcapNRechits_hits_per_event = + (TH1I*)fil->Get("EEMC/EcalEndcapNRechits_hits_per_event"); + auto EcalEndcapNRecHits_hit_energy = (TH1D*)fil->Get("EEMC/EcalEndcapNRecHits_hit_energy"); + auto EcalEndcapNRecHits_xy = (TH2D*)fil->Get("EEMC/EcalEndcapNRecHits_xy"); + auto EcalEndcapNRecHits_z = (TH1D*)fil->Get("EEMC/EcalEndcapNRecHits_z"); + auto EcalEndcapNRecHits_time = (TH1D*)fil->Get("EEMC/EcalEndcapNRecHits_time"); + + auto EcalEndcapNIslandProtoClusters_clusters_per_event = + (TH1I*)fil->Get("EEMC/EcalEndcapNIslandProtoClusters_clusters_per_event"); + auto EcalEndcapNIslandProtoClusters_hits_per_cluster = + (TH1I*)fil->Get("EEMC/EcalEndcapNIslandProtoClusters_hits_per_cluster"); + + auto c1 = new TCanvas("c1", "", 1700, 1000); + c1->Divide(4, 4); + + //---------------- EcalEndcapNhits + c1->cd(1); + gPad->SetLogy(); + EcalEndcapNhits_hits_per_event->Draw(); + + c1->cd(2); + EcalEndcapNhits_occupancy->Draw(); + + c1->cd(3); + gPad->SetLogy(); + EcalEndcapNhits_hit_energy->Draw(); + + //---------------- EcalEndcapNRawhits + c1->cd(5); + gPad->SetLogy(); + EcalEndcapNRawhits_hits_per_event->Draw(); + + c1->cd(6); + gPad->SetLogy(); + EcalEndcapNRawhits_amplitude->Draw(); + + c1->cd(7); + EcalEndcapNRawhits_timestamp->Draw(); + + //---------------- EcalEndcapNRecHits + c1->cd(9); + gPad->SetLogy(); + EcalEndcapNRechits_hits_per_event->Draw(); + + c1->cd(10); + EcalEndcapNRecHits_xy->Draw(); + + c1->cd(11); + EcalEndcapNRecHits_z->Draw(); + + c1->cd(12); + gPad->SetLogy(); + EcalEndcapNRecHits_time->Draw(); + + c1->cd(8); + gPad->SetLogy(); + EcalEndcapNRecHits_hit_energy->Draw(); + + //---------------- EcalEndcapNIslandProtoClusters + c1->cd(13); + gPad->SetLogy(); + EcalEndcapNIslandProtoClusters_clusters_per_event->Draw(); + + c1->cd(14); + gPad->SetLogy(); + EcalEndcapNIslandProtoClusters_hits_per_cluster->Draw(); + + c1->SaveAs("EEMCcheck.pdf"); + c1->SaveAs("EEMCcheck.png"); } diff --git a/src/benchmarks/reconstruction/femc_studies/femc_studies.cc b/src/benchmarks/reconstruction/femc_studies/femc_studies.cc index e2e8fa7721..47b47b6e02 100644 --- a/src/benchmarks/reconstruction/femc_studies/femc_studies.cc +++ b/src/benchmarks/reconstruction/femc_studies/femc_studies.cc @@ -4,8 +4,8 @@ // The following just makes this a JANA plugin extern "C" { - void InitPlugin(JApplication* app) { - InitJANAPlugin(app); - app->Add(new femc_studiesProcessor()); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new femc_studiesProcessor()); +} } diff --git a/src/benchmarks/reconstruction/femc_studies/femc_studiesProcessor.cc b/src/benchmarks/reconstruction/femc_studies/femc_studiesProcessor.cc index 743d21ecb8..80e74308a9 100644 --- a/src/benchmarks/reconstruction/femc_studies/femc_studiesProcessor.cc +++ b/src/benchmarks/reconstruction/femc_studies/femc_studiesProcessor.cc @@ -37,7 +37,6 @@ #include "services/log/Log_service.h" #include "services/rootfile/RootFile_service.h" - //******************************************************************************************// // InitWithGlobalRootLock //******************************************************************************************// @@ -47,7 +46,7 @@ void femc_studiesProcessor::Init() { // =============================================================================================== // Get JANA application and seup general variables // =============================================================================================== - auto *app = GetApplication(); + auto* app = GetApplication(); m_log = app->GetService()->logger(plugin_name); @@ -60,7 +59,7 @@ void femc_studiesProcessor::Init() { // Get TDirectory for histograms root file auto globalRootLock = app->GetService(); globalRootLock->acquire_write_lock(); - auto *file = root_file_service->GetHistFile(); + auto* file = root_file_service->GetHistFile(); globalRootLock->release_lock(); // =============================================================================================== @@ -71,19 +70,22 @@ void femc_studiesProcessor::Init() { // =============================================================================================== // Simulations hists // =============================================================================================== - hMCEnergyVsEta = new TH2D("hMCEnergyVsEta", "; E (GeV); #eta", 1500, 0., 150., 500, 0, 5); + hMCEnergyVsEta = new TH2D("hMCEnergyVsEta", "; E (GeV); #eta", 1500, 0., 150., 500, 0, 5); hMCEnergyVsEta->SetDirectory(m_dir_main); // =============================================================================================== // Sum cell clusters rec histos // =============================================================================================== - hClusterEcalib_E_eta = new TH3D("hClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,rec hit}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hClusterNCells_E_eta = new TH3D("hClusterNCells_E_eta", "; E_{MC} (GeV); N_{cells}; #eta", - 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); - hClusterEcalib_E_phi = new TH3D("hClusterEcalib_E_phi", "; E_{MC} (GeV); E_{rec,rec hit}/E_{MC}; #varphi (rad)", - 1500, 0., 150.0, 200, 0., 2.0, 360 , -TMath::Pi(), TMath::Pi()); - hPosCaloHitsXY = new TH2D("hPosCaloHitsXY", "; X (cm); Y (cm)", 400, -400., 400., 400, -400., 400.); + hClusterEcalib_E_eta = + new TH3D("hClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,rec hit}/E_{MC}; #eta", 1500, 0., + 150.0, 200, 0., 2.0, 50, 0, 5); + hClusterNCells_E_eta = new TH3D("hClusterNCells_E_eta", "; E_{MC} (GeV); N_{cells}; #eta", 1500, + 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); + hClusterEcalib_E_phi = + new TH3D("hClusterEcalib_E_phi", "; E_{MC} (GeV); E_{rec,rec hit}/E_{MC}; #varphi (rad)", + 1500, 0., 150.0, 200, 0., 2.0, 360, -TMath::Pi(), TMath::Pi()); + hPosCaloHitsXY = + new TH2D("hPosCaloHitsXY", "; X (cm); Y (cm)", 400, -400., 400., 400, -400., 400.); hClusterEcalib_E_eta->SetDirectory(m_dir_main); hClusterNCells_E_eta->SetDirectory(m_dir_main); hClusterEcalib_E_phi->SetDirectory(m_dir_main); @@ -92,16 +94,23 @@ void femc_studiesProcessor::Init() { // =============================================================================================== // Sum cell clusters sim histos // =============================================================================================== - hClusterESimcalib_E_eta = new TH3D("hClusterESimcalib_E_eta", "; E_{MC} (GeV); E_{rec,sim hit}/E_{MC}; #eta" , - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hClusterSimNCells_E_eta = new TH3D("hClusterSimNCells_E_eta", "; E_{MC} (GeV); N_{cells, sim}; #eta", - 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); - hClusterESimcalib_E_phi = new TH3D("hClusterESimcalib_E_phi", "; E_{MC} (GeV); E_{rec,sim hit}/E_{MC}; #varphi (rad)" , - 1500, 0., 150.0, 200, 0., 2.0, 360 , -TMath::Pi(), TMath::Pi()); - hCellESim_layerX = new TH2D("hCellESim_layerX", "; #cell ID X; E_{rec,sim hit} (GeV)" , 500, -0.5, 499.5, 5000, 0, 1); - hCellESim_layerY = new TH2D("hCellESim_layerY", "; #cell ID Y; E_{rec,sim hit} (GeV)" , 500, -0.5, 499.5, 5000, 0, 1); - hCellTSim_layerX = new TH2D("hCellTSim_layerX", "; #cell ID X; t_{rec,sim hit} (GeV)" , 500, -0.5, 499.5, 5000, 0, 1000); - hPosCaloSimHitsXY = new TH2D("hPosCaloSimHitsXY", "; X (cm); Y (cm)", 400, -400., 400., 400, -400., 400.); + hClusterESimcalib_E_eta = + new TH3D("hClusterESimcalib_E_eta", "; E_{MC} (GeV); E_{rec,sim hit}/E_{MC}; #eta", 1500, 0., + 150.0, 200, 0., 2.0, 50, 0, 5); + hClusterSimNCells_E_eta = + new TH3D("hClusterSimNCells_E_eta", "; E_{MC} (GeV); N_{cells, sim}; #eta", 1500, 0., 150.0, + 500, -0.5, 499.5, 50, 0, 5); + hClusterESimcalib_E_phi = + new TH3D("hClusterESimcalib_E_phi", "; E_{MC} (GeV); E_{rec,sim hit}/E_{MC}; #varphi (rad)", + 1500, 0., 150.0, 200, 0., 2.0, 360, -TMath::Pi(), TMath::Pi()); + hCellESim_layerX = new TH2D("hCellESim_layerX", "; #cell ID X; E_{rec,sim hit} (GeV)", 500, -0.5, + 499.5, 5000, 0, 1); + hCellESim_layerY = new TH2D("hCellESim_layerY", "; #cell ID Y; E_{rec,sim hit} (GeV)", 500, -0.5, + 499.5, 5000, 0, 1); + hCellTSim_layerX = new TH2D("hCellTSim_layerX", "; #cell ID X; t_{rec,sim hit} (GeV)", 500, -0.5, + 499.5, 5000, 0, 1000); + hPosCaloSimHitsXY = + new TH2D("hPosCaloSimHitsXY", "; X (cm); Y (cm)", 400, -400., 400., 400, -400., 400.); hClusterESimcalib_E_eta->SetDirectory(m_dir_main); hClusterSimNCells_E_eta->SetDirectory(m_dir_main); hClusterESimcalib_E_phi->SetDirectory(m_dir_main); @@ -113,15 +122,18 @@ void femc_studiesProcessor::Init() { // =============================================================================================== // rec cluster MA clusters histos // =============================================================================================== - hRecClusterEcalib_E_eta = new TH3D("hRecClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,rec clus}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hRecNClusters_E_eta = new TH3D("hRecNClusters_E_eta", "; E_{MC} (GeV); N_{rec cl.}; #eta", - 1500, 0., 150.0, 10, -0.5, 9.5, 50, 0, 5); + hRecClusterEcalib_E_eta = + new TH3D("hRecClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,rec clus}/E_{MC}; #eta", 1500, 0., + 150.0, 200, 0., 2.0, 50, 0, 5); + hRecNClusters_E_eta = new TH3D("hRecNClusters_E_eta", "; E_{MC} (GeV); N_{rec cl.}; #eta", 1500, + 0., 150.0, 10, -0.5, 9.5, 50, 0, 5); // rec cluster highest - hRecClusterEcalib_Ehigh_eta = new TH3D("hRecClusterEcalib_Ehigh_eta", "; E_{MC} (GeV); E_{rec,rec clus high.}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hRecClusterNCells_Ehigh_eta = new TH3D("hRecClusterNCells_Ehigh_eta", "; E_{MC} (GeV); N_{cells, rec cl., high.}; #eta", - 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); + hRecClusterEcalib_Ehigh_eta = + new TH3D("hRecClusterEcalib_Ehigh_eta", "; E_{MC} (GeV); E_{rec,rec clus high.}/E_{MC}; #eta", + 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); + hRecClusterNCells_Ehigh_eta = + new TH3D("hRecClusterNCells_Ehigh_eta", "; E_{MC} (GeV); N_{cells, rec cl., high.}; #eta", + 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); hRecClusterEcalib_E_eta->SetDirectory(m_dir_main); hRecNClusters_E_eta->SetDirectory(m_dir_main); hRecClusterEcalib_Ehigh_eta->SetDirectory(m_dir_main); @@ -130,15 +142,18 @@ void femc_studiesProcessor::Init() { // =============================================================================================== // rec cluster framework Island clusters histos // =============================================================================================== - hRecFClusterEcalib_E_eta = new TH3D("hRecFClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,island clus}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hRecFNClusters_E_eta = new TH3D("hRecFNClusters_E_eta", "; E_{MC} (GeV); N_{rec f. cl.}; #eta", - 1500, 0., 150.0, 10, -0.5, 9.5, 50, 0, 5); + hRecFClusterEcalib_E_eta = + new TH3D("hRecFClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,island clus}/E_{MC}; #eta", 1500, + 0., 150.0, 200, 0., 2.0, 50, 0, 5); + hRecFNClusters_E_eta = new TH3D("hRecFNClusters_E_eta", "; E_{MC} (GeV); N_{rec f. cl.}; #eta", + 1500, 0., 150.0, 10, -0.5, 9.5, 50, 0, 5); // rec cluster framework highest - hRecFClusterEcalib_Ehigh_eta = new TH3D("hRecFClusterEcalib_Ehigh_eta", "; E_{MC} (GeV); E_{rec,island clus high.}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hRecFClusterNCells_Ehigh_eta = new TH3D("hRecFClusterNCells_Ehigh_eta", "; E_{MC} (GeV); N_{cells, rec f. cl., high.}; #eta", - 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); + hRecFClusterEcalib_Ehigh_eta = new TH3D("hRecFClusterEcalib_Ehigh_eta", + "; E_{MC} (GeV); E_{rec,island clus high.}/E_{MC}; #eta", + 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); + hRecFClusterNCells_Ehigh_eta = + new TH3D("hRecFClusterNCells_Ehigh_eta", "; E_{MC} (GeV); N_{cells, rec f. cl., high.}; #eta", + 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); hRecFClusterEcalib_E_eta->SetDirectory(m_dir_main); hRecFNClusters_E_eta->SetDirectory(m_dir_main); hRecFClusterEcalib_Ehigh_eta->SetDirectory(m_dir_main); @@ -147,23 +162,23 @@ void femc_studiesProcessor::Init() { // =============================================================================================== // Sampling fraction // =============================================================================================== - hSamplingFractionEta = new TH2D("hSamplingFractionEta", "; #eta; f", 400, 1., 5., 500, 0., 0.2); + hSamplingFractionEta = new TH2D("hSamplingFractionEta", "; #eta; f", 400, 1., 5., 500, 0., 0.2); hSamplingFractionEta->SetDirectory(m_dir_main); // =============================================================================================== // Tree for clusterizer studies // =============================================================================================== - if (enableTree){ - event_tree = new TTree("event_tree", "event_tree"); + if (enableTree) { + event_tree = new TTree("event_tree", "event_tree"); event_tree->SetDirectory(m_dir_main); - t_fEMC_towers_cellE = new float[maxNTowers]; - t_fEMC_towers_cellT = new float[maxNTowers]; - t_fEMC_towers_cellIDx = new short[maxNTowers]; - t_fEMC_towers_cellIDy = new short[maxNTowers]; - t_fEMC_towers_clusterIDA = new short[maxNTowers]; - t_fEMC_towers_clusterIDB = new short[maxNTowers]; - t_fEMC_towers_cellTrueID = new int[maxNTowers]; + t_fEMC_towers_cellE = new float[maxNTowers]; + t_fEMC_towers_cellT = new float[maxNTowers]; + t_fEMC_towers_cellIDx = new short[maxNTowers]; + t_fEMC_towers_cellIDy = new short[maxNTowers]; + t_fEMC_towers_clusterIDA = new short[maxNTowers]; + t_fEMC_towers_clusterIDB = new short[maxNTowers]; + t_fEMC_towers_cellTrueID = new int[maxNTowers]; // towers FEMC event_tree->Branch("tower_FEMC_N", &t_fEMC_towers_N, "tower_FEMC_N/I"); @@ -171,21 +186,24 @@ void femc_studiesProcessor::Init() { event_tree->Branch("tower_FEMC_T", t_fEMC_towers_cellT, "tower_FEMC_T[tower_FEMC_N]/F"); event_tree->Branch("tower_FEMC_ix", t_fEMC_towers_cellIDx, "tower_FEMC_ix[tower_FEMC_N]/S"); event_tree->Branch("tower_FEMC_iy", t_fEMC_towers_cellIDy, "tower_FEMC_iy[tower_FEMC_N]/S"); - event_tree->Branch("tower_FEMC_clusIDA", t_fEMC_towers_clusterIDA, "tower_FEMC_clusIDA[tower_FEMC_N]/S"); - event_tree->Branch("tower_FEMC_clusIDB", t_fEMC_towers_clusterIDB, "tower_FEMC_clusIDB[tower_FEMC_N]/S"); - event_tree->Branch("tower_FEMC_trueID", t_fEMC_towers_cellTrueID, "tower_FEMC_trueID[tower_FEMC_N]/I"); + event_tree->Branch("tower_FEMC_clusIDA", t_fEMC_towers_clusterIDA, + "tower_FEMC_clusIDA[tower_FEMC_N]/S"); + event_tree->Branch("tower_FEMC_clusIDB", t_fEMC_towers_clusterIDB, + "tower_FEMC_clusIDB[tower_FEMC_N]/S"); + event_tree->Branch("tower_FEMC_trueID", t_fEMC_towers_cellTrueID, + "tower_FEMC_trueID[tower_FEMC_N]/I"); } // =============================================================================================== // Tree for cluster studies // =============================================================================================== - if (enableTreeCluster){ - cluster_tree = new TTree("cluster_tree", "cluster_tree"); + if (enableTreeCluster) { + cluster_tree = new TTree("cluster_tree", "cluster_tree"); cluster_tree->SetDirectory(m_dir_main); - t_mc_E = new float[maxNMC]; - t_mc_Phi = new float[maxNMC]; - t_mc_Eta = new float[maxNMC]; + t_mc_E = new float[maxNMC]; + t_mc_Phi = new float[maxNMC]; + t_mc_Eta = new float[maxNMC]; t_fEMC_cluster_E = new float[maxNCluster]; t_fEMC_cluster_NCells = new int[maxNCluster]; t_fEMC_cluster_Phi = new float[maxNCluster]; @@ -199,9 +217,12 @@ void femc_studiesProcessor::Init() { // clusters FECal cluster_tree->Branch("cluster_FEMC_N", &t_fEMC_clusters_N, "cluster_FEMC_N/I"); cluster_tree->Branch("cluster_FEMC_E", t_fEMC_cluster_E, "cluster_FEMC_E[cluster_FEMC_N]/F"); - cluster_tree->Branch("cluster_FEMC_Ncells", t_fEMC_cluster_NCells, "cluster_FEMC_Ncells[cluster_FEMC_N]/I"); - cluster_tree->Branch("cluster_FEMC_Eta", t_fEMC_cluster_Eta, "cluster_FEMC_Eta[cluster_FEMC_N]/F"); - cluster_tree->Branch("cluster_FEMC_Phi", t_fEMC_cluster_Phi, "cluster_FEMC_Phi[cluster_FEMC_N]/F"); + cluster_tree->Branch("cluster_FEMC_Ncells", t_fEMC_cluster_NCells, + "cluster_FEMC_Ncells[cluster_FEMC_N]/I"); + cluster_tree->Branch("cluster_FEMC_Eta", t_fEMC_cluster_Eta, + "cluster_FEMC_Eta[cluster_FEMC_N]/F"); + cluster_tree->Branch("cluster_FEMC_Phi", t_fEMC_cluster_Phi, + "cluster_FEMC_Phi[cluster_FEMC_N]/F"); } std::cout << __PRETTY_FUNCTION__ << " " << __LINE__ << std::endl; @@ -209,31 +230,30 @@ void femc_studiesProcessor::Init() { std::cout << "--------------------------\nID specification:\n"; try { m_decoder = detector->readout("EcalEndcapPHits").idSpec().decoder(); - std::cout << "1st: "<< m_decoder << std::endl; + std::cout << "1st: " << m_decoder << std::endl; std::cout << "full list: " << " " << m_decoder->fieldDescription() << std::endl; } catch (...) { - std::cout <<"2nd: " << m_decoder << std::endl; - m_log->error("readoutClass not in the output"); - throw std::runtime_error("readoutClass not in the output."); + std::cout << "2nd: " << m_decoder << std::endl; + m_log->error("readoutClass not in the output"); + throw std::runtime_error("readoutClass not in the output."); } - } //******************************************************************************************// // ProcessSequential //******************************************************************************************// void femc_studiesProcessor::Process(const std::shared_ptr& event) { -// void femc_studiesProcessor::ProcessSequential(const std::shared_ptr& event) { + // void femc_studiesProcessor::ProcessSequential(const std::shared_ptr& event) { // =============================================================================================== // process MC particles // =============================================================================================== - const auto &mcParticles = *(event->GetCollection("MCParticles")); - double mceta = 0; - double mcphi = 0; - double mcp = 0; - double mcenergy = 0; - int iMC = 0; + const auto& mcParticles = *(event->GetCollection("MCParticles")); + double mceta = 0; + double mcphi = 0; + double mcp = 0; + double mcenergy = 0; + int iMC = 0; for (const auto mcparticle : mcParticles) { if (mcparticle.getGeneratorStatus() != 1) continue; @@ -246,11 +266,12 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) mcphi = atan2(mom.y, mom.x); // determine mc momentum mcp = sqrt(mom.x * mom.x + mom.y * mom.y + mom.z * mom.z); - m_log->trace("MC particle:{} \t {} \t {} \t totmom: {} phi {} eta {}", mom.x, mom.y, mom.z, mcp, mcphi, mceta); - hMCEnergyVsEta->Fill(mcp,mceta); + m_log->trace("MC particle:{} \t {} \t {} \t totmom: {} phi {} eta {}", mom.x, mom.y, mom.z, mcp, + mcphi, mceta); + hMCEnergyVsEta->Fill(mcp, mceta); - if (enableTreeCluster){ - if (iMC < maxNMC){ + if (enableTreeCluster) { + if (iMC < maxNMC) { t_mc_E[iMC] = mcenergy; t_mc_Phi[iMC] = mcphi; t_mc_Eta[iMC] = mceta; @@ -258,38 +279,40 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) } iMC++; } - if (enableTreeCluster) t_mc_N = iMC; + if (enableTreeCluster) + t_mc_N = iMC; // =============================================================================================== // process sim hits // =============================================================================================== std::vector input_tower_sim; - int nCaloHitsSim = 0; - float sumActiveCaloEnergy = 0; + int nCaloHitsSim = 0; + float sumActiveCaloEnergy = 0; float sumPassiveCaloEnergy = 0; - const auto &simHits = *(event->GetCollection(nameSimHits)); + const auto& simHits = *(event->GetCollection(nameSimHits)); for (const auto caloHit : simHits) { float x = caloHit.getPosition().x / 10.; float y = caloHit.getPosition().y / 10.; float z = caloHit.getPosition().z / 10.; uint64_t cellID = caloHit.getCellID(); float energy = caloHit.getEnergy(); - double time = std::numeric_limits::max(); + double time = std::numeric_limits::max(); for (const auto& c : caloHit.getContributions()) { - if (c.getTime() <= time) { - time = c.getTime(); - } + if (c.getTime() <= time) { + time = c.getTime(); + } } - auto detector_layer_x = floor((x+246)/2.5); - auto detector_layer_y = floor((y+246)/2.5); + auto detector_layer_x = floor((x + 246) / 2.5); + auto detector_layer_y = floor((y + 246) / 2.5); auto detector_passive = 0; - if(detector_passive == 0) { + if (detector_passive == 0) { sumActiveCaloEnergy += energy; } else { sumPassiveCaloEnergy += energy; } - if (detector_passive > 0) continue; + if (detector_passive > 0) + continue; // calc cell IDs int cellIDx = detector_layer_x; int cellIDy = detector_layer_y; @@ -312,16 +335,16 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) } if (!found) { towersStrct tempstructT; - tempstructT.energy = energy; - tempstructT.time = time; - tempstructT.posx = x; - tempstructT.posy = y; - tempstructT.posz = z; - tempstructT.cellID = cellID; - tempstructT.cellIDx = cellIDx; - tempstructT.cellIDy = cellIDy; - tempstructT.cellIDz = cellIDz; - tempstructT.tower_trueID = 0; //TODO how to get trueID? + tempstructT.energy = energy; + tempstructT.time = time; + tempstructT.posx = x; + tempstructT.posy = y; + tempstructT.posz = z; + tempstructT.cellID = cellID; + tempstructT.cellIDx = cellIDx; + tempstructT.cellIDy = cellIDy; + tempstructT.cellIDz = cellIDz; + tempstructT.tower_trueID = 0; //TODO how to get trueID? input_tower_sim.push_back(tempstructT); } } @@ -329,8 +352,8 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) // =============================================================================================== // read rec hits & fill structs // =============================================================================================== - const auto &recHits = *(event->GetCollection(nameRecHits)); - int nCaloHitsRec = 0; + const auto& recHits = *(event->GetCollection(nameRecHits)); + int nCaloHitsRec = 0; std::vector input_tower_rec; std::vector input_tower_recSav; // process rec hits @@ -343,9 +366,10 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) float time = caloHit.getTime(); auto detector_passive = 0; - auto detector_layer_x = floor((x+246)/2.5); - auto detector_layer_y = floor((y+246)/2.5); - if (detector_passive > 0) continue; + auto detector_layer_x = floor((x + 246) / 2.5); + auto detector_layer_y = floor((y + 246) / 2.5); + if (detector_passive > 0) + continue; // calc cell IDs int cellIDx = detector_layer_x; @@ -366,26 +390,28 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) } if (!found) { towersStrct tempstructT; - tempstructT.energy = energy; - tempstructT.time = time; - tempstructT.posx = x; - tempstructT.posy = y; - tempstructT.posz = z; - tempstructT.cellID = cellID; - tempstructT.cellIDx = cellIDx; - tempstructT.cellIDy = cellIDy; - tempstructT.tower_trueID = 0; //TODO how to get trueID? + tempstructT.energy = energy; + tempstructT.time = time; + tempstructT.posx = x; + tempstructT.posy = y; + tempstructT.posz = z; + tempstructT.cellID = cellID; + tempstructT.cellIDx = cellIDx; + tempstructT.cellIDy = cellIDy; + tempstructT.tower_trueID = 0; //TODO how to get trueID? input_tower_rec.push_back(tempstructT); input_tower_recSav.push_back(tempstructT); } } m_log->trace("FEMC mod: nCaloHits sim {}\t rec {}", nCaloHitsSim, nCaloHitsRec); - if (nCaloHitsRec > 0) nEventsWithCaloHits++; + if (nCaloHitsRec > 0) + nEventsWithCaloHits++; // =============================================================================================== // sort tower arrays // =============================================================================================== - hSamplingFractionEta->Fill(mceta, sumActiveCaloEnergy / (sumActiveCaloEnergy+sumPassiveCaloEnergy)); + hSamplingFractionEta->Fill(mceta, + sumActiveCaloEnergy / (sumActiveCaloEnergy + sumPassiveCaloEnergy)); std::sort(input_tower_rec.begin(), input_tower_rec.end(), &acompare); std::sort(input_tower_recSav.begin(), input_tower_recSav.end(), &acompare); std::sort(input_tower_sim.begin(), input_tower_sim.end(), &acompare); @@ -405,34 +431,35 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) // sim hits double tot_energySimHit = 0; for (auto& tower : input_tower_sim) { - tower.energy = tower.energy/samplingFraction; // calibrate + tower.energy = tower.energy / samplingFraction; // calibrate tot_energySimHit += tower.energy; } - m_log->trace("Mc E: {} \t eta: {} \t sim E rec: {}\t rec E rec: {}", mcenergy, mceta, tot_energySimHit, tot_energyRecHit); + m_log->trace("Mc E: {} \t eta: {} \t sim E rec: {}\t rec E rec: {}", mcenergy, mceta, + tot_energySimHit, tot_energyRecHit); // =============================================================================================== // Fill summed hits histos // =============================================================================================== // rec hits hClusterNCells_E_eta->Fill(mcenergy, nCaloHitsRec, mceta); - hClusterEcalib_E_eta->Fill(mcenergy, tot_energyRecHit/mcenergy, mceta); - hClusterEcalib_E_phi->Fill(mcenergy, tot_energyRecHit/mcenergy, mcphi); + hClusterEcalib_E_eta->Fill(mcenergy, tot_energyRecHit / mcenergy, mceta); + hClusterEcalib_E_phi->Fill(mcenergy, tot_energyRecHit / mcenergy, mcphi); // sim hits hClusterSimNCells_E_eta->Fill(mcenergy, nCaloHitsSim, mceta); - hClusterESimcalib_E_eta->Fill(mcenergy, tot_energySimHit/mcenergy, mceta); - hClusterESimcalib_E_phi->Fill(mcenergy, tot_energySimHit/mcenergy, mcphi); + hClusterESimcalib_E_eta->Fill(mcenergy, tot_energySimHit / mcenergy, mceta); + hClusterESimcalib_E_phi->Fill(mcenergy, tot_energySimHit / mcenergy, mcphi); // =============================================================================================== // MA clusterization // =============================================================================================== - int removedCells = 0; - float minAggE = 0.001; - float seedE = 0.20; + int removedCells = 0; + float minAggE = 0.001; + float seedE = 0.20; - if (!input_tower_rec.empty()){ + if (!input_tower_rec.empty()) { // clean up rec array for clusterization - while (input_tower_rec.at(input_tower_rec.size()-1).energy < minAggE ){ + while (input_tower_rec.at(input_tower_rec.size() - 1).energy < minAggE) { input_tower_rec.pop_back(); removedCells++; } @@ -443,30 +470,39 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) std::vector clusters_calo; // vector of towers within the currently found cluster std::vector cluster_towers; - while (!input_tower_rec.empty() ) { + while (!input_tower_rec.empty()) { cluster_towers.clear(); clustersStrct tempstructC; // always start with highest energetic tower - if(input_tower_rec.at(0).energy > seedE){ - m_log->trace("seed: {}\t {} \t {}", input_tower_rec.at(0).energy, input_tower_rec.at(0).cellIDx, input_tower_rec.at(0).cellIDy ); + if (input_tower_rec.at(0).energy > seedE) { + m_log->trace("seed: {}\t {} \t {}", input_tower_rec.at(0).energy, + input_tower_rec.at(0).cellIDx, input_tower_rec.at(0).cellIDy); tempstructC = findMACluster(seedE, minAggE, input_tower_rec, cluster_towers, 0.1); // determine remaining cluster properties from its towers - float* showershape_eta_phi = CalculateM02andWeightedPosition(cluster_towers, tempstructC.cluster_E, 4.5); - tempstructC.cluster_M02 = showershape_eta_phi[0]; - tempstructC.cluster_M20 = showershape_eta_phi[1]; - tempstructC.cluster_Eta = showershape_eta_phi[2]; - tempstructC.cluster_Phi = showershape_eta_phi[3]; - tempstructC.cluster_X = showershape_eta_phi[4]; - tempstructC.cluster_Y = showershape_eta_phi[5]; - tempstructC.cluster_Z = showershape_eta_phi[6]; + float* showershape_eta_phi = + CalculateM02andWeightedPosition(cluster_towers, tempstructC.cluster_E, 4.5); + tempstructC.cluster_M02 = showershape_eta_phi[0]; + tempstructC.cluster_M20 = showershape_eta_phi[1]; + tempstructC.cluster_Eta = showershape_eta_phi[2]; + tempstructC.cluster_Phi = showershape_eta_phi[3]; + tempstructC.cluster_X = showershape_eta_phi[4]; + tempstructC.cluster_Y = showershape_eta_phi[5]; + tempstructC.cluster_Z = showershape_eta_phi[6]; tempstructC.cluster_towers = cluster_towers; - m_log->trace("---------> \t {} \tcluster with E = {} \tEta: {} \tPhi: {} \tX: {} \tY: {} \tZ: {} \tntowers: {} \ttrueID: {}", nclusters, tempstructC.cluster_E, tempstructC.cluster_Eta, tempstructC.cluster_Phi, tempstructC.cluster_X, tempstructC.cluster_Y, tempstructC.cluster_Z, tempstructC.cluster_NTowers, tempstructC.cluster_trueID ); + m_log->trace("---------> \t {} \tcluster with E = {} \tEta: {} \tPhi: {} \tX: {} \tY: {} " + "\tZ: {} \tntowers: {} \ttrueID: {}", + nclusters, tempstructC.cluster_E, tempstructC.cluster_Eta, + tempstructC.cluster_Phi, tempstructC.cluster_X, tempstructC.cluster_Y, + tempstructC.cluster_Z, tempstructC.cluster_NTowers, + tempstructC.cluster_trueID); clusters_calo.push_back(tempstructC); nclusters++; } else { - m_log->trace("remaining: {} largest: {} \t {} \t {} \t {}", (int)input_tower_rec.size(), input_tower_rec.at(0).energy, input_tower_rec.at(0).cellIDx, input_tower_rec.at(0).cellIDy, input_tower_rec.at(0).cellIDz); + m_log->trace("remaining: {} largest: {} \t {} \t {} \t {}", (int)input_tower_rec.size(), + input_tower_rec.at(0).energy, input_tower_rec.at(0).cellIDx, + input_tower_rec.at(0).cellIDy, input_tower_rec.at(0).cellIDz); input_tower_rec.clear(); } } @@ -475,20 +511,21 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) // --------------------------- Fill LFHCal MA clusters in tree and hists ------------------------- // ----------------------------------------------------------------------------------------------- std::sort(clusters_calo.begin(), clusters_calo.end(), &acompareCl); - m_log->info("-----> found {} clusters" , clusters_calo.size()); + m_log->info("-----> found {} clusters", clusters_calo.size()); hRecNClusters_E_eta->Fill(mcenergy, clusters_calo.size(), mceta); int iCl = 0; for (const auto cluster : clusters_calo) { - if (iCl < maxNCluster && enableTreeCluster){ - t_fEMC_cluster_E[iCl] = (float)cluster.cluster_E; - t_fEMC_cluster_NCells[iCl] = (int)cluster.cluster_NTowers; - t_fEMC_cluster_Eta[iCl] = (float)cluster.cluster_Eta; - t_fEMC_cluster_Phi[iCl] = (float)cluster.cluster_Phi; + if (iCl < maxNCluster && enableTreeCluster) { + t_fEMC_cluster_E[iCl] = (float)cluster.cluster_E; + t_fEMC_cluster_NCells[iCl] = (int)cluster.cluster_NTowers; + t_fEMC_cluster_Eta[iCl] = (float)cluster.cluster_Eta; + t_fEMC_cluster_Phi[iCl] = (float)cluster.cluster_Phi; } - hRecClusterEcalib_E_eta->Fill(mcenergy, cluster.cluster_E/mcenergy, mceta); - for (const auto cluster_tower : cluster.cluster_towers){ + hRecClusterEcalib_E_eta->Fill(mcenergy, cluster.cluster_E / mcenergy, mceta); + for (const auto cluster_tower : cluster.cluster_towers) { int pSav = 0; - while(cluster_tower.cellID != input_tower_recSav.at(pSav).cellID && pSav < (int)input_tower_recSav.size() ) { + while (cluster_tower.cellID != input_tower_recSav.at(pSav).cellID && + pSav < (int)input_tower_recSav.size()) { pSav++; } if (cluster_tower.cellID == input_tower_recSav.at(pSav).cellID) { @@ -496,45 +533,47 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) } } - if (iCl == 0){ - hRecClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.cluster_E/mcenergy, mceta); + if (iCl == 0) { + hRecClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.cluster_E / mcenergy, mceta); hRecClusterNCells_Ehigh_eta->Fill(mcenergy, cluster.cluster_NTowers, mceta); } iCl++; m_log->trace("MA cluster {}:\t {} \t {}", iCl, cluster.cluster_E, cluster.cluster_NTowers); } - if (iCl < maxNCluster && enableTreeCluster) t_fEMC_clusters_N = (int)iCl; + if (iCl < maxNCluster && enableTreeCluster) + t_fEMC_clusters_N = (int)iCl; clusters_calo.clear(); } else { hRecNClusters_E_eta->Fill(mcenergy, 0., mceta); - if (enableTreeCluster) t_fEMC_clusters_N = 0; + if (enableTreeCluster) + t_fEMC_clusters_N = 0; } // =============================================================================================== // ------------------------------- Fill LFHCAl Island clusters in hists -------------------------- // =============================================================================================== - int iClF = 0; - float highestEFr = 0; - int iClFHigh = 0; + int iClF = 0; + float highestEFr = 0; + int iClFHigh = 0; - const auto &fecalClustersF = *(event->GetCollection(nameClusters)); + const auto& fecalClustersF = *(event->GetCollection(nameClusters)); for (const auto cluster : fecalClustersF) { - if (cluster.getEnergy() > highestEFr){ - iClFHigh = iClF; - highestEFr = cluster.getEnergy(); + if (cluster.getEnergy() > highestEFr) { + iClFHigh = iClF; + highestEFr = cluster.getEnergy(); } - hRecFClusterEcalib_E_eta->Fill(mcenergy, cluster.getEnergy()/mcenergy, mceta); + hRecFClusterEcalib_E_eta->Fill(mcenergy, cluster.getEnergy() / mcenergy, mceta); m_log->trace("Island cluster {}:\t {} \t {}", iClF, cluster.getEnergy(), cluster.getNhits()); iClF++; } hRecFNClusters_E_eta->Fill(mcenergy, iClF, mceta); // fill hists for highest Island cluster - iClF = 0; + iClF = 0; for (const auto cluster : fecalClustersF) { - if (iClF == iClFHigh){ - hRecFClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.getEnergy()/mcenergy, mceta); + if (iClF == iClFHigh) { + hRecFClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.getEnergy() / mcenergy, mceta); hRecFClusterNCells_Ehigh_eta->Fill(mcenergy, cluster.getNhits(), mceta); } iClF++; @@ -543,10 +582,13 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) // =============================================================================================== // Write clusterizer tree & clean-up variables // =============================================================================================== - if (enableTree){ + if (enableTree) { t_fEMC_towers_N = (int)input_tower_recSav.size(); - for (int iCell = 0; iCell < (int)input_tower_recSav.size(); iCell++){ - m_log->trace("{} \t {} \t {} \t {} \t {}", input_tower_recSav.at(iCell).cellIDx, input_tower_recSav.at(iCell).cellIDy , input_tower_recSav.at(iCell).energy, input_tower_recSav.at(iCell).tower_clusterIDA, input_tower_recSav.at(iCell).tower_clusterIDB ); + for (int iCell = 0; iCell < (int)input_tower_recSav.size(); iCell++) { + m_log->trace("{} \t {} \t {} \t {} \t {}", input_tower_recSav.at(iCell).cellIDx, + input_tower_recSav.at(iCell).cellIDy, input_tower_recSav.at(iCell).energy, + input_tower_recSav.at(iCell).tower_clusterIDA, + input_tower_recSav.at(iCell).tower_clusterIDB); t_fEMC_towers_cellE[iCell] = (float)input_tower_recSav.at(iCell).energy; t_fEMC_towers_cellT[iCell] = (float)input_tower_recSav.at(iCell).time; @@ -560,48 +602,47 @@ void femc_studiesProcessor::Process(const std::shared_ptr& event) event_tree->Fill(); t_fEMC_towers_N = 0; - for (Int_t itow = 0; itow < maxNTowers; itow++){ - t_fEMC_towers_cellE[itow] = 0; - t_fEMC_towers_cellT[itow] = 0; - t_fEMC_towers_cellIDx[itow] = 0; - t_fEMC_towers_cellIDy[itow] = 0; - t_fEMC_towers_clusterIDA[itow] = 0; - t_fEMC_towers_clusterIDB[itow] = 0; - t_fEMC_towers_cellTrueID[itow] = 0; + for (Int_t itow = 0; itow < maxNTowers; itow++) { + t_fEMC_towers_cellE[itow] = 0; + t_fEMC_towers_cellT[itow] = 0; + t_fEMC_towers_cellIDx[itow] = 0; + t_fEMC_towers_cellIDy[itow] = 0; + t_fEMC_towers_clusterIDA[itow] = 0; + t_fEMC_towers_clusterIDB[itow] = 0; + t_fEMC_towers_cellTrueID[itow] = 0; } } // =============================================================================================== // Write cluster tree & clean-up variables // =============================================================================================== - if (enableTreeCluster){ + if (enableTreeCluster) { cluster_tree->Fill(); - t_mc_N = 0; - t_fEMC_clusters_N = 0; - t_fEMC_clusters_N = 0; - for (Int_t iMC = 0; iMC < maxNMC; iMC++){ - t_mc_E[iMC] = 0; - t_mc_Phi[iMC] = 0; - t_mc_Eta[iMC] = 0; + t_mc_N = 0; + t_fEMC_clusters_N = 0; + t_fEMC_clusters_N = 0; + for (Int_t iMC = 0; iMC < maxNMC; iMC++) { + t_mc_E[iMC] = 0; + t_mc_Phi[iMC] = 0; + t_mc_Eta[iMC] = 0; } - for (Int_t iCl = 0; iCl < maxNCluster; iCl++){ - t_fEMC_cluster_E[iCl] = 0; - t_fEMC_cluster_NCells[iCl] = 0; - t_fEMC_cluster_Eta[iCl] = 0; - t_fEMC_cluster_Phi[iCl] = 0; + for (Int_t iCl = 0; iCl < maxNCluster; iCl++) { + t_fEMC_cluster_E[iCl] = 0; + t_fEMC_cluster_NCells[iCl] = 0; + t_fEMC_cluster_Eta[iCl] = 0; + t_fEMC_cluster_Phi[iCl] = 0; } } - } - //******************************************************************************************// // FinishWithGlobalRootLock //******************************************************************************************// void femc_studiesProcessor::Finish() { - std::cout << "------> FEMC " << nEventsWithCaloHits << " with calo info present"<< std::endl; - if (enableTreeCluster) cluster_tree->Write(); + std::cout << "------> FEMC " << nEventsWithCaloHits << " with calo info present" << std::endl; + if (enableTreeCluster) + cluster_tree->Write(); // Do any final calculations here. if (enableTree) { diff --git a/src/benchmarks/reconstruction/femc_studies/femc_studiesProcessor.h b/src/benchmarks/reconstruction/femc_studies/femc_studiesProcessor.h index 7522dbd477..e37fc2fb9c 100644 --- a/src/benchmarks/reconstruction/femc_studies/femc_studiesProcessor.h +++ b/src/benchmarks/reconstruction/femc_studies/femc_studiesProcessor.h @@ -16,74 +16,73 @@ #include #include -class femc_studiesProcessor: public JEventProcessor { +class femc_studiesProcessor : public JEventProcessor { public: - femc_studiesProcessor() { SetTypeName(NAME_OF_THIS); } + femc_studiesProcessor() { SetTypeName(NAME_OF_THIS); } - void Init() override; -// void InitWithGlobalRootLock() override; - void Process(const std::shared_ptr& event) override; -// void ProcessSequential(const std::shared_ptr& event) override; -// void FinishWithGlobalRootLock() override; - void Finish() override; - TDirectory *m_dir_main; - // Declare histogram and tree pointers here. e.g. - TH2D* hMCEnergyVsEta; - TH3D* hClusterEcalib_E_eta; - TH3D* hClusterNCells_E_eta; - TH3D* hClusterEcalib_E_phi; - TH2D* hPosCaloHitsXY; - TH3D* hClusterESimcalib_E_eta; - TH3D* hClusterSimNCells_E_eta; - TH3D* hClusterESimcalib_E_phi; - TH2D* hCellESim_layerX; - TH2D* hCellESim_layerY; - TH2D* hCellTSim_layerX; - TH2D* hPosCaloSimHitsXY; - TH3D* hRecClusterEcalib_E_eta; - TH3D* hRecNClusters_E_eta; - TH3D* hRecClusterEcalib_Ehigh_eta; - TH3D* hRecClusterNCells_Ehigh_eta; - TH3D* hRecFClusterEcalib_E_eta; - TH3D* hRecFNClusters_E_eta; - TH3D* hRecFClusterEcalib_Ehigh_eta; - TH3D* hRecFClusterNCells_Ehigh_eta; - TH2D* hSamplingFractionEta; + void Init() override; + // void InitWithGlobalRootLock() override; + void Process(const std::shared_ptr& event) override; + // void ProcessSequential(const std::shared_ptr& event) override; + // void FinishWithGlobalRootLock() override; + void Finish() override; + TDirectory* m_dir_main; + // Declare histogram and tree pointers here. e.g. + TH2D* hMCEnergyVsEta; + TH3D* hClusterEcalib_E_eta; + TH3D* hClusterNCells_E_eta; + TH3D* hClusterEcalib_E_phi; + TH2D* hPosCaloHitsXY; + TH3D* hClusterESimcalib_E_eta; + TH3D* hClusterSimNCells_E_eta; + TH3D* hClusterESimcalib_E_phi; + TH2D* hCellESim_layerX; + TH2D* hCellESim_layerY; + TH2D* hCellTSim_layerX; + TH2D* hPosCaloSimHitsXY; + TH3D* hRecClusterEcalib_E_eta; + TH3D* hRecNClusters_E_eta; + TH3D* hRecClusterEcalib_Ehigh_eta; + TH3D* hRecClusterNCells_Ehigh_eta; + TH3D* hRecFClusterEcalib_E_eta; + TH3D* hRecFNClusters_E_eta; + TH3D* hRecFClusterEcalib_Ehigh_eta; + TH3D* hRecFClusterNCells_Ehigh_eta; + TH2D* hSamplingFractionEta; - bool enableTree = false; - TTree* event_tree; - const int maxNTowers = 65000; - int t_fEMC_towers_N; - short* t_fEMC_towers_cellIDx; - short* t_fEMC_towers_cellIDy; - short* t_fEMC_towers_clusterIDA; - short* t_fEMC_towers_clusterIDB; - float* t_fEMC_towers_cellE; - float* t_fEMC_towers_cellT; - int* t_fEMC_towers_cellTrueID; + bool enableTree = false; + TTree* event_tree; + const int maxNTowers = 65000; + int t_fEMC_towers_N; + short* t_fEMC_towers_cellIDx; + short* t_fEMC_towers_cellIDy; + short* t_fEMC_towers_clusterIDA; + short* t_fEMC_towers_clusterIDB; + float* t_fEMC_towers_cellE; + float* t_fEMC_towers_cellT; + int* t_fEMC_towers_cellTrueID; - bool enableTreeCluster = false; - TTree* cluster_tree; - const int maxNCluster = 50; - const int maxNMC = 50; - int t_mc_N; - float* t_mc_E; - float* t_mc_Phi; - float* t_mc_Eta; - int t_fEMC_clusters_N; - float* t_fEMC_cluster_E; - int* t_fEMC_cluster_NCells; - float* t_fEMC_cluster_Phi; - float* t_fEMC_cluster_Eta; - - int nEventsWithCaloHits = 0; - std::shared_ptr m_log; - dd4hep::DDSegmentation::BitFieldCoder* m_decoder; - std::string nameSimHits = "EcalEndcapPHits"; - std::string nameRecHits = "EcalEndcapPRecHits"; - std::string nameClusters = "EcalEndcapPClusters"; - std::string nameProtoClusters = "EcalEndcapPIslandProtoClusters"; - short iLx; - short iLy; + bool enableTreeCluster = false; + TTree* cluster_tree; + const int maxNCluster = 50; + const int maxNMC = 50; + int t_mc_N; + float* t_mc_E; + float* t_mc_Phi; + float* t_mc_Eta; + int t_fEMC_clusters_N; + float* t_fEMC_cluster_E; + int* t_fEMC_cluster_NCells; + float* t_fEMC_cluster_Phi; + float* t_fEMC_cluster_Eta; + int nEventsWithCaloHits = 0; + std::shared_ptr m_log; + dd4hep::DDSegmentation::BitFieldCoder* m_decoder; + std::string nameSimHits = "EcalEndcapPHits"; + std::string nameRecHits = "EcalEndcapPRecHits"; + std::string nameClusters = "EcalEndcapPClusters"; + std::string nameProtoClusters = "EcalEndcapPIslandProtoClusters"; + short iLx; + short iLy; }; diff --git a/src/benchmarks/reconstruction/lfhcal_studies/clusterizer_MA.h b/src/benchmarks/reconstruction/lfhcal_studies/clusterizer_MA.h index bbef61f5f9..df6d2ffac9 100644 --- a/src/benchmarks/reconstruction/lfhcal_studies/clusterizer_MA.h +++ b/src/benchmarks/reconstruction/lfhcal_studies/clusterizer_MA.h @@ -7,8 +7,20 @@ #include #include -struct towersStrct{ - towersStrct(): energy(0), time (0), posx(0), posy(0), posz(0), cellID(0), cellIDx(-1), cellIDy(-1), cellIDz(-1), tower_trueID(-10000), tower_clusterIDA(-1), tower_clusterIDB(-1) {} +struct towersStrct { + towersStrct() + : energy(0) + , time(0) + , posx(0) + , posy(0) + , posz(0) + , cellID(0) + , cellIDx(-1) + , cellIDy(-1) + , cellIDz(-1) + , tower_trueID(-10000) + , tower_clusterIDA(-1) + , tower_clusterIDB(-1) {} float energy; float time; float posx; @@ -21,12 +33,24 @@ struct towersStrct{ int tower_trueID; int tower_clusterIDA; int tower_clusterIDB; -} ; +}; bool acompare(towersStrct lhs, towersStrct rhs) { return lhs.energy > rhs.energy; } -struct clustersStrct{ - clustersStrct(): cluster_E(0.), cluster_seed(0.), cluster_Eta(-10.), cluster_Phi(-10.), cluster_X(0.) , cluster_Y(0.), cluster_Z(0.), cluster_M02(0.), cluster_M20(0.), cluster_NTowers(0), cluster_trueID(-10000), cluster_NtrueID(0) {} +struct clustersStrct { + clustersStrct() + : cluster_E(0.) + , cluster_seed(0.) + , cluster_Eta(-10.) + , cluster_Phi(-10.) + , cluster_X(0.) + , cluster_Y(0.) + , cluster_Z(0.) + , cluster_M02(0.) + , cluster_M20(0.) + , cluster_NTowers(0) + , cluster_trueID(-10000) + , cluster_NtrueID(0) {} float cluster_E; float cluster_seed; float cluster_Eta; @@ -40,7 +64,7 @@ struct clustersStrct{ int cluster_trueID; int cluster_NtrueID; std::vector cluster_towers; -} ; +}; bool acompareCl(clustersStrct lhs, clustersStrct rhs) { return lhs.cluster_E > rhs.cluster_E; } @@ -50,62 +74,64 @@ bool acompareCl(clustersStrct lhs, clustersStrct rhs) { return lhs.cluster_E > r //**************************************************************************************************************// //**************************************************************************************************************// clustersStrct findMACluster( - float seed, // minimum seed energy - float agg, // minimum aggregation energy - std::vector &input_towers_temp, // temporary full tower array - std::vector &cluster_towers_temp, // towers associated to cluster -// std::vector clslabels_temp // MC labels in cluster - float aggMargin = 1.0 // aggregation margin - ){ + float seed, // minimum seed energy + float agg, // minimum aggregation energy + std::vector& input_towers_temp, // temporary full tower array + std::vector& cluster_towers_temp, // towers associated to cluster + // std::vector clslabels_temp // MC labels in cluster + float aggMargin = 1.0 // aggregation margin +) { clustersStrct tempstructC; - if(input_towers_temp.at(0).energy > seed){ -// std::cout << "new cluster" << std::endl; + if (input_towers_temp.at(0).energy > seed) { + // std::cout << "new cluster" << std::endl; // fill seed cell information into current cluster tempstructC.cluster_E = input_towers_temp.at(0).energy; tempstructC.cluster_seed = input_towers_temp.at(0).energy; tempstructC.cluster_NTowers = 1; tempstructC.cluster_NtrueID = 1; - tempstructC.cluster_trueID = input_towers_temp.at(0).tower_trueID; // TODO save all MC labels? + tempstructC.cluster_trueID = input_towers_temp.at(0).tower_trueID; // TODO save all MC labels? cluster_towers_temp.push_back(input_towers_temp.at(0)); -// clslabels_temp.push_back(input_towers_temp.at(0).tower_trueID); -// std::cout << "seed: "<< input_towers_temp.at(0).cellIDx << "\t" << input_towers_temp.at(0).cellIDy -// << "\t" << input_towers_temp.at(0).cellIDz << "\t E:"<< tempstructC.cluster_E << std::endl; - + // clslabels_temp.push_back(input_towers_temp.at(0).tower_trueID); + // std::cout << "seed: "<< input_towers_temp.at(0).cellIDx << "\t" << input_towers_temp.at(0).cellIDy + // << "\t" << input_towers_temp.at(0).cellIDz << "\t E:"<< tempstructC.cluster_E << std::endl; // remove seed tower from sample input_towers_temp.erase(input_towers_temp.begin()); - for (int tit = 0; tit < (int)cluster_towers_temp.size(); tit++){ + for (int tit = 0; tit < (int)cluster_towers_temp.size(); tit++) { // Now go recursively to all neighbours and add them to the cluster if they fulfill the conditions int iEtaTwr = cluster_towers_temp.at(tit).cellIDx; int iPhiTwr = cluster_towers_temp.at(tit).cellIDy; int iLTwr = cluster_towers_temp.at(tit).cellIDz; - int refC = 0; - for (int ait = 0; ait < (int)input_towers_temp.size(); ait++){ + int refC = 0; + for (int ait = 0; ait < (int)input_towers_temp.size(); ait++) { int iEtaTwrAgg = input_towers_temp.at(ait).cellIDx; int iPhiTwrAgg = input_towers_temp.at(ait).cellIDy; int iLTwrAgg = input_towers_temp.at(ait).cellIDz; - int deltaL = TMath::Abs(iLTwrAgg-iLTwr) ; - int deltaPhi = TMath::Abs(iPhiTwrAgg-iPhiTwr) ; - int deltaEta = TMath::Abs(iEtaTwrAgg-iEtaTwr) ; - bool neighbor = (deltaL+deltaPhi+deltaEta == 1); - bool corner2D = (deltaL == 0 && deltaPhi == 1 && deltaEta == 1) || (deltaL == 1 && deltaPhi == 0 && deltaEta == 1) || (deltaL == 1 && deltaPhi == 1 && deltaEta == 0); -// first condition asks for V3-like neighbors, while second condition also checks diagonally attached towers - if(neighbor || corner2D ){ + int deltaL = TMath::Abs(iLTwrAgg - iLTwr); + int deltaPhi = TMath::Abs(iPhiTwrAgg - iPhiTwr); + int deltaEta = TMath::Abs(iEtaTwrAgg - iEtaTwr); + bool neighbor = (deltaL + deltaPhi + deltaEta == 1); + bool corner2D = (deltaL == 0 && deltaPhi == 1 && deltaEta == 1) || + (deltaL == 1 && deltaPhi == 0 && deltaEta == 1) || + (deltaL == 1 && deltaPhi == 1 && deltaEta == 0); + // first condition asks for V3-like neighbors, while second condition also checks diagonally attached towers + if (neighbor || corner2D) { // only aggregate towers with lower energy than current tower - if(input_towers_temp.at(ait).energy >= (cluster_towers_temp.at(tit).energy + aggMargin)) continue; - tempstructC.cluster_E+=input_towers_temp.at(ait).energy; + if (input_towers_temp.at(ait).energy >= (cluster_towers_temp.at(tit).energy + aggMargin)) + continue; + tempstructC.cluster_E += input_towers_temp.at(ait).energy; tempstructC.cluster_NTowers++; cluster_towers_temp.push_back(input_towers_temp.at(ait)); -// if(!(std::find(clslabels_temp.begin(), clslabels_temp.end(), input_towers_temp.at(ait).tower_trueID) != clslabels_temp.end())){ -// tempstructC.cluster_NtrueID++; -// clslabels_temp.push_back(input_towers_temp.at(ait).tower_trueID); -// } -// std::cout << "aggregated: "<< iEtaTwrAgg << "\t" << iPhiTwrAgg << "\t" << iLTwrAgg << "\t E:" << input_towers_temp.at(ait).energy << "\t reference: "<< refC << "\t"<< iEtaTwr << "\t" << iPhiTwr << "\t" << iLTwr << "\t cond.: \t"<< neighbor << "\t" << corner2D << "\t diffs: " << deltaEta << "\t" << deltaPhi << "\t" << deltaL<< std::endl; + // if(!(std::find(clslabels_temp.begin(), clslabels_temp.end(), input_towers_temp.at(ait).tower_trueID) != clslabels_temp.end())){ + // tempstructC.cluster_NtrueID++; + // clslabels_temp.push_back(input_towers_temp.at(ait).tower_trueID); + // } + // std::cout << "aggregated: "<< iEtaTwrAgg << "\t" << iPhiTwrAgg << "\t" << iLTwrAgg << "\t E:" << input_towers_temp.at(ait).energy << "\t reference: "<< refC << "\t"<< iEtaTwr << "\t" << iPhiTwr << "\t" << iLTwr << "\t cond.: \t"<< neighbor << "\t" << corner2D << "\t diffs: " << deltaEta << "\t" << deltaPhi << "\t" << deltaL<< std::endl; - input_towers_temp.erase(input_towers_temp.begin()+ait); + input_towers_temp.erase(input_towers_temp.begin() + ait); ait--; refC++; } @@ -115,76 +141,84 @@ clustersStrct findMACluster( return tempstructC; } - // ANCHOR function to determine shower shape -float * CalculateM02andWeightedPosition(std::vector cluster_towers, float cluster_E_calc, float weight0){ - static float returnVariables[8]; //0:M02, 1:M20, 2:eta, 3: phi - float w_tot = 0; - std::vector w_i; - TVector3 vecTwr; - TVector3 vecTwrTmp; - float zHC = 1; - float w_0 = weight0; - - vecTwr = {0.,0.,0.}; - //calculation of weights and weighted position vector - int Nweighted = 0; - for(int cellI=0; cellI<(int)cluster_towers.size(); cellI++){ - w_i.push_back(TMath::Max( (float)0, (float) (w_0 + TMath::Log(cluster_towers.at(cellI).energy/cluster_E_calc) ))); - w_tot += w_i.at(cellI); - if(w_i.at(cellI)>0){ - Nweighted++; - vecTwrTmp = TVector3(cluster_towers.at(cellI).posx, cluster_towers.at(cellI).posy, cluster_towers.at(cellI).posz ); - vecTwr += w_i.at(cellI)*vecTwrTmp; - } +float* CalculateM02andWeightedPosition(std::vector cluster_towers, + float cluster_E_calc, float weight0) { + static float returnVariables[8]; //0:M02, 1:M20, 2:eta, 3: phi + float w_tot = 0; + std::vector w_i; + TVector3 vecTwr; + TVector3 vecTwrTmp; + float zHC = 1; + float w_0 = weight0; + + vecTwr = {0., 0., 0.}; + //calculation of weights and weighted position vector + int Nweighted = 0; + for (int cellI = 0; cellI < (int)cluster_towers.size(); cellI++) { + w_i.push_back(TMath::Max( + (float)0, (float)(w_0 + TMath::Log(cluster_towers.at(cellI).energy / cluster_E_calc)))); + w_tot += w_i.at(cellI); + if (w_i.at(cellI) > 0) { + Nweighted++; + vecTwrTmp = TVector3(cluster_towers.at(cellI).posx, cluster_towers.at(cellI).posy, + cluster_towers.at(cellI).posz); + vecTwr += w_i.at(cellI) * vecTwrTmp; } - // correct Eta position for average shift in calo - returnVariables[2]= vecTwr.Eta(); - returnVariables[3]= vecTwr.Phi(); //(vecTwr.Phi()<0 ? vecTwr.Phi()+TMath::Pi() : vecTwr.Phi()-TMath::Pi()); - vecTwr*=1./w_tot; -// std::cout << "Cluster: X: "<< vecTwr.X() << "\t" << " Y: "<< vecTwr.Y() << "\t" << " Z: "<< vecTwr.Z() << std::endl; - returnVariables[4]=vecTwr.X(); - returnVariables[5]=vecTwr.Y(); - returnVariables[6]=vecTwr.Z(); - - //calculation of M02 - float delta_phi_phi[4] = {0}; - float delta_eta_eta[4] = {0}; - float delta_eta_phi[4] = {0}; - float dispersion = 0; - - for(int cellI=0; cellI<(int)cluster_towers.size(); cellI++){ - int iphi=cluster_towers.at(cellI).cellIDy; - int ieta=cluster_towers.at(cellI).cellIDx; - delta_phi_phi[1] += (w_i.at(cellI)*iphi*iphi)/w_tot; - delta_phi_phi[2] += (w_i.at(cellI)*iphi)/w_tot; - delta_phi_phi[3] += (w_i.at(cellI)*iphi)/w_tot; - - delta_eta_eta[1] += (w_i.at(cellI)*ieta*ieta)/w_tot; - delta_eta_eta[2] += (w_i.at(cellI)*ieta)/w_tot; - delta_eta_eta[3] += (w_i.at(cellI)*ieta)/w_tot; - - delta_eta_phi[1] += (w_i.at(cellI)*ieta*iphi)/w_tot; - delta_eta_phi[2] += (w_i.at(cellI)*iphi)/w_tot; - delta_eta_phi[3] += (w_i.at(cellI)*ieta)/w_tot; - - vecTwrTmp = TVector3(cluster_towers.at(cellI).posx, cluster_towers.at(cellI).posy, cluster_towers.at(cellI).posz ); - // scale cluster position to z-plane - vecTwr*=abs(vecTwrTmp.Z()/vecTwr.Z()); - float dx2 = pow(vecTwrTmp.X()-vecTwr.X(),2); - float dy2 = pow(vecTwrTmp.Y()-vecTwr.Y(),2); - float dz2 = pow(vecTwrTmp.Z()-vecTwr.Z(),2); - dispersion+= (w_i.at(cellI)*(dx2+dy2+dz2))/w_tot; - } - returnVariables[7]=dispersion; - delta_phi_phi[0] = delta_phi_phi[1] - (delta_phi_phi[2] * delta_phi_phi[3]); - delta_eta_eta[0] = delta_eta_eta[1] - (delta_eta_eta[2] * delta_eta_eta[3]); - delta_eta_phi[0] = delta_eta_phi[1] - (delta_eta_phi[2] * delta_eta_phi[3]); - - float calcM02 = 0.5 * ( delta_phi_phi[0] + delta_eta_eta[0] ) + TMath::Sqrt( 0.25 * TMath::Power( ( delta_phi_phi[0] - delta_eta_eta[0] ), 2 ) + TMath::Power( delta_eta_phi[0], 2 ) ); - float calcM20 = 0.5 * ( delta_phi_phi[0] + delta_eta_eta[0] ) - TMath::Sqrt( 0.25 * TMath::Power( ( delta_phi_phi[0] - delta_eta_eta[0] ), 2 ) + TMath::Power( delta_eta_phi[0], 2 ) ); -// std::cout << "M02_calc: " << calcM02 << "\t\t = 0.5 * ( " << delta_phi_phi[0] <<" + "<Add(new lfhcal_studiesProcessor()); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new lfhcal_studiesProcessor()); +} } diff --git a/src/benchmarks/reconstruction/lfhcal_studies/lfhcal_studiesProcessor.cc b/src/benchmarks/reconstruction/lfhcal_studies/lfhcal_studiesProcessor.cc index 46f4483674..5b56d41bcf 100644 --- a/src/benchmarks/reconstruction/lfhcal_studies/lfhcal_studiesProcessor.cc +++ b/src/benchmarks/reconstruction/lfhcal_studies/lfhcal_studiesProcessor.cc @@ -37,7 +37,6 @@ #include "services/log/Log_service.h" #include "services/rootfile/RootFile_service.h" - //******************************************************************************************// // InitWithGlobalRootLock //******************************************************************************************// @@ -60,7 +59,7 @@ void lfhcal_studiesProcessor::Init() { // Get TDirectory for histograms root file auto globalRootLock = app->GetService(); globalRootLock->acquire_write_lock(); - auto *file = root_file_service->GetHistFile(); + auto* file = root_file_service->GetHistFile(); globalRootLock->release_lock(); // =============================================================================================== @@ -71,21 +70,26 @@ void lfhcal_studiesProcessor::Init() { // =============================================================================================== // Simulations hists // =============================================================================================== - hMCEnergyVsEta = new TH2D("hMCEnergyVsEta", "; E (GeV); #eta", 1500, 0., 150., 500, 0, 5); + hMCEnergyVsEta = new TH2D("hMCEnergyVsEta", "; E (GeV); #eta", 1500, 0., 150., 500, 0, 5); hMCEnergyVsEta->SetDirectory(m_dir_main); // =============================================================================================== // Sum cell clusters rec histos // =============================================================================================== - hClusterEcalib_E_eta = new TH3D("hClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,rec hit}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hClusterNCells_E_eta = new TH3D("hClusterNCells_E_eta", "; E_{MC} (GeV); N_{cells}; #eta", - 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); - hClusterEcalib_E_phi = new TH3D("hClusterEcalib_E_phi", "; E_{MC} (GeV); E_{rec,rec hit}/E_{MC}; #varphi (rad)", - 1500, 0., 150.0, 200, 0., 2.0, 360 , -TMath::Pi(), TMath::Pi()); - hPosCaloHitsXY = new TH2D("hPosCaloHitsXY", "; X (cm); Y (cm)", 400, -400., 400., 400, -400., 400.); - hPosCaloHitsZX = new TH2D("hPosCaloHitsZX", "; Z (cm); X (cm)", 200, 300., 500., 400, -400., 400.); - hPosCaloHitsZY = new TH2D("hPosCaloHitsZY", "; Z (cm); Y (cm)", 200, 300., 500., 400, -400., 400.); + hClusterEcalib_E_eta = + new TH3D("hClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,rec hit}/E_{MC}; #eta", 1500, 0., + 150.0, 200, 0., 2.0, 50, 0, 5); + hClusterNCells_E_eta = new TH3D("hClusterNCells_E_eta", "; E_{MC} (GeV); N_{cells}; #eta", 1500, + 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); + hClusterEcalib_E_phi = + new TH3D("hClusterEcalib_E_phi", "; E_{MC} (GeV); E_{rec,rec hit}/E_{MC}; #varphi (rad)", + 1500, 0., 150.0, 200, 0., 2.0, 360, -TMath::Pi(), TMath::Pi()); + hPosCaloHitsXY = + new TH2D("hPosCaloHitsXY", "; X (cm); Y (cm)", 400, -400., 400., 400, -400., 400.); + hPosCaloHitsZX = + new TH2D("hPosCaloHitsZX", "; Z (cm); X (cm)", 200, 300., 500., 400, -400., 400.); + hPosCaloHitsZY = + new TH2D("hPosCaloHitsZY", "; Z (cm); Y (cm)", 200, 300., 500., 400, -400., 400.); hClusterEcalib_E_eta->SetDirectory(m_dir_main); hClusterNCells_E_eta->SetDirectory(m_dir_main); hClusterEcalib_E_phi->SetDirectory(m_dir_main); @@ -96,19 +100,29 @@ void lfhcal_studiesProcessor::Init() { // =============================================================================================== // Sum cell clusters sim histos // =============================================================================================== - hClusterESimcalib_E_eta = new TH3D("hClusterESimcalib_E_eta", "; E_{MC} (GeV); E_{rec,sim hit}/E_{MC}; #eta" , - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hClusterSimNCells_E_eta = new TH3D("hClusterSimNCells_E_eta", "; E_{MC} (GeV); N_{cells, sim}; #eta", - 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); - hClusterESimcalib_E_phi = new TH3D("hClusterESimcalib_E_phi", "; E_{MC} (GeV); E_{rec,sim hit}/E_{MC}; #varphi (rad)" , - 1500, 0., 150.0, 200, 0., 2.0, 360 , -TMath::Pi(), TMath::Pi()); - hCellESim_layerX = new TH2D("hCellESim_layerX", "; #cell ID X; E_{rec,sim hit} (GeV)" , 240, -0.5, 239.5, 5000, 0, 1); - hCellESim_layerY = new TH2D("hCellESim_layerY", "; #cell ID Y; E_{rec,sim hit} (GeV)" , 240, -0.5, 239.5, 5000, 0, 1); - hCellESim_layerZ = new TH2D("hCellESim_layerZ", "; #cell ID Z; E_{rec,sim hit} (GeV)" , 70, -0.5, 69.5, 5000, 0, 1); - hCellTSim_layerZ = new TH2D("hCellTSim_layerZ", "; #cell ID Z; t_{rec,sim hit} (GeV)" , 70, -0.5, 69.5, 5000, 0, 1000); - hPosCaloSimHitsXY = new TH2D("hPosCaloSimHitsXY", "; X (cm); Y (cm)", 400, -400., 400., 400, -400., 400.); - hPosCaloSimHitsZX = new TH2D("hPosCaloSimHitsZX", "; Z (cm); X (cm)", 200, 300., 500., 400, -400., 400.); - hPosCaloSimHitsZY = new TH2D("hPosCaloSimHitsZY", "; Z (cm); Y (cm)", 200, 300., 500., 400, -400., 400.); + hClusterESimcalib_E_eta = + new TH3D("hClusterESimcalib_E_eta", "; E_{MC} (GeV); E_{rec,sim hit}/E_{MC}; #eta", 1500, 0., + 150.0, 200, 0., 2.0, 50, 0, 5); + hClusterSimNCells_E_eta = + new TH3D("hClusterSimNCells_E_eta", "; E_{MC} (GeV); N_{cells, sim}; #eta", 1500, 0., 150.0, + 500, -0.5, 499.5, 50, 0, 5); + hClusterESimcalib_E_phi = + new TH3D("hClusterESimcalib_E_phi", "; E_{MC} (GeV); E_{rec,sim hit}/E_{MC}; #varphi (rad)", + 1500, 0., 150.0, 200, 0., 2.0, 360, -TMath::Pi(), TMath::Pi()); + hCellESim_layerX = new TH2D("hCellESim_layerX", "; #cell ID X; E_{rec,sim hit} (GeV)", 240, -0.5, + 239.5, 5000, 0, 1); + hCellESim_layerY = new TH2D("hCellESim_layerY", "; #cell ID Y; E_{rec,sim hit} (GeV)", 240, -0.5, + 239.5, 5000, 0, 1); + hCellESim_layerZ = new TH2D("hCellESim_layerZ", "; #cell ID Z; E_{rec,sim hit} (GeV)", 70, -0.5, + 69.5, 5000, 0, 1); + hCellTSim_layerZ = new TH2D("hCellTSim_layerZ", "; #cell ID Z; t_{rec,sim hit} (GeV)", 70, -0.5, + 69.5, 5000, 0, 1000); + hPosCaloSimHitsXY = + new TH2D("hPosCaloSimHitsXY", "; X (cm); Y (cm)", 400, -400., 400., 400, -400., 400.); + hPosCaloSimHitsZX = + new TH2D("hPosCaloSimHitsZX", "; Z (cm); X (cm)", 200, 300., 500., 400, -400., 400.); + hPosCaloSimHitsZY = + new TH2D("hPosCaloSimHitsZY", "; Z (cm); Y (cm)", 200, 300., 500., 400, -400., 400.); hClusterESimcalib_E_eta->SetDirectory(m_dir_main); hClusterSimNCells_E_eta->SetDirectory(m_dir_main); hClusterESimcalib_E_phi->SetDirectory(m_dir_main); @@ -123,15 +137,18 @@ void lfhcal_studiesProcessor::Init() { // =============================================================================================== // rec cluster MA clusters histos // =============================================================================================== - hRecClusterEcalib_E_eta = new TH3D("hRecClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,rec clus}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hRecNClusters_E_eta = new TH3D("hRecNClusters_E_eta", "; E_{MC} (GeV); N_{rec cl.}; #eta", - 1500, 0., 150.0, 10, -0.5, 9.5, 50, 0, 5); + hRecClusterEcalib_E_eta = + new TH3D("hRecClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,rec clus}/E_{MC}; #eta", 1500, 0., + 150.0, 200, 0., 2.0, 50, 0, 5); + hRecNClusters_E_eta = new TH3D("hRecNClusters_E_eta", "; E_{MC} (GeV); N_{rec cl.}; #eta", 1500, + 0., 150.0, 10, -0.5, 9.5, 50, 0, 5); // rec cluster highest - hRecClusterEcalib_Ehigh_eta = new TH3D("hRecClusterEcalib_Ehigh_eta", "; E_{MC} (GeV); E_{rec,rec clus high.}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hRecClusterNCells_Ehigh_eta = new TH3D("hRecClusterNCells_Ehigh_eta", "; E_{MC} (GeV); N_{cells, rec cl., high.}; #eta", - 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); + hRecClusterEcalib_Ehigh_eta = + new TH3D("hRecClusterEcalib_Ehigh_eta", "; E_{MC} (GeV); E_{rec,rec clus high.}/E_{MC}; #eta", + 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); + hRecClusterNCells_Ehigh_eta = + new TH3D("hRecClusterNCells_Ehigh_eta", "; E_{MC} (GeV); N_{cells, rec cl., high.}; #eta", + 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); hRecClusterEcalib_E_eta->SetDirectory(m_dir_main); hRecNClusters_E_eta->SetDirectory(m_dir_main); hRecClusterEcalib_Ehigh_eta->SetDirectory(m_dir_main); @@ -140,15 +157,18 @@ void lfhcal_studiesProcessor::Init() { // =============================================================================================== // rec cluster framework Island clusters histos // =============================================================================================== - hRecFClusterEcalib_E_eta = new TH3D("hRecFClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,island clus}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hRecFNClusters_E_eta = new TH3D("hRecFNClusters_E_eta", "; E_{MC} (GeV); N_{rec f. cl.}; #eta", - 1500, 0., 150.0, 10, -0.5, 9.5, 50, 0, 5); + hRecFClusterEcalib_E_eta = + new TH3D("hRecFClusterEcalib_E_eta", "; E_{MC} (GeV); E_{rec,island clus}/E_{MC}; #eta", 1500, + 0., 150.0, 200, 0., 2.0, 50, 0, 5); + hRecFNClusters_E_eta = new TH3D("hRecFNClusters_E_eta", "; E_{MC} (GeV); N_{rec f. cl.}; #eta", + 1500, 0., 150.0, 10, -0.5, 9.5, 50, 0, 5); // rec cluster framework highest - hRecFClusterEcalib_Ehigh_eta = new TH3D("hRecFClusterEcalib_Ehigh_eta", "; E_{MC} (GeV); E_{rec,island clus high.}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hRecFClusterNCells_Ehigh_eta = new TH3D("hRecFClusterNCells_Ehigh_eta", "; E_{MC} (GeV); N_{cells, rec f. cl., high.}; #eta", - 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); + hRecFClusterEcalib_Ehigh_eta = new TH3D("hRecFClusterEcalib_Ehigh_eta", + "; E_{MC} (GeV); E_{rec,island clus high.}/E_{MC}; #eta", + 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); + hRecFClusterNCells_Ehigh_eta = + new TH3D("hRecFClusterNCells_Ehigh_eta", "; E_{MC} (GeV); N_{cells, rec f. cl., high.}; #eta", + 1500, 0., 150.0, 500, -0.5, 499.5, 50, 0, 5); hRecFClusterEcalib_E_eta->SetDirectory(m_dir_main); hRecFNClusters_E_eta->SetDirectory(m_dir_main); hRecFClusterEcalib_Ehigh_eta->SetDirectory(m_dir_main); @@ -157,13 +177,17 @@ void lfhcal_studiesProcessor::Init() { // =============================================================================================== // FEcal rec cluster framework Island clusters histos // =============================================================================================== - hRecFEmClusterEcalib_E_eta = new TH3D("hRecFEmClusterEcalib_E_eta", "; E_{MC} (GeV); E_{Ecal, rec,island clus}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); - hRecFEmNClusters_E_eta = new TH3D("hRecFEmNClusters_E_eta", "; E_{MC} (GeV); N_{Ecal, rec f. cl.}; #eta", - 1500, 0., 150.0, 10, -0.5, 9.5, 50, 0, 5); + hRecFEmClusterEcalib_E_eta = new TH3D("hRecFEmClusterEcalib_E_eta", + "; E_{MC} (GeV); E_{Ecal, rec,island clus}/E_{MC}; #eta", + 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); + hRecFEmNClusters_E_eta = + new TH3D("hRecFEmNClusters_E_eta", "; E_{MC} (GeV); N_{Ecal, rec f. cl.}; #eta", 1500, 0., + 150.0, 10, -0.5, 9.5, 50, 0, 5); // rec cluster framework highest - hRecFEmClusterEcalib_Ehigh_eta = new TH3D("hRecFEmClusterEcalib_Ehigh_eta", "; E_{MC} (GeV); E_{Ecal, rec,island clus high.}/E_{MC}; #eta", - 1500, 0., 150.0, 200, 0., 2.0, 50, 0, 5); + hRecFEmClusterEcalib_Ehigh_eta = + new TH3D("hRecFEmClusterEcalib_Ehigh_eta", + "; E_{MC} (GeV); E_{Ecal, rec,island clus high.}/E_{MC}; #eta", 1500, 0., 150.0, 200, + 0., 2.0, 50, 0, 5); hRecFEmClusterEcalib_E_eta->SetDirectory(m_dir_main); hRecFEmNClusters_E_eta->SetDirectory(m_dir_main); hRecFEmClusterEcalib_Ehigh_eta->SetDirectory(m_dir_main); @@ -171,42 +195,48 @@ void lfhcal_studiesProcessor::Init() { // =============================================================================================== // Sampling fraction // =============================================================================================== - hSamplingFractionEta = new TH2D("hSamplingFractionEta", "; #eta; f", 400, 1., 5., 500, 0., 0.2); + hSamplingFractionEta = new TH2D("hSamplingFractionEta", "; #eta; f", 400, 1., 5., 500, 0., 0.2); hSamplingFractionEta->SetDirectory(m_dir_main); // =============================================================================================== // Tree for clusterizer studies // =============================================================================================== - if (enableTree){ - event_tree = new TTree("event_tree", "event_tree"); + if (enableTree) { + event_tree = new TTree("event_tree", "event_tree"); event_tree->SetDirectory(m_dir_main); - t_lFHCal_towers_cellE = new float[maxNTowers]; - t_lFHCal_towers_cellT = new float[maxNTowers]; - t_lFHCal_towers_cellIDx = new short[maxNTowers]; - t_lFHCal_towers_cellIDy = new short[maxNTowers]; - t_lFHCal_towers_cellIDz = new short[maxNTowers]; - t_lFHCal_towers_clusterIDA = new short[maxNTowers]; - t_lFHCal_towers_clusterIDB = new short[maxNTowers]; - t_lFHCal_towers_cellTrueID = new int[maxNTowers]; + t_lFHCal_towers_cellE = new float[maxNTowers]; + t_lFHCal_towers_cellT = new float[maxNTowers]; + t_lFHCal_towers_cellIDx = new short[maxNTowers]; + t_lFHCal_towers_cellIDy = new short[maxNTowers]; + t_lFHCal_towers_cellIDz = new short[maxNTowers]; + t_lFHCal_towers_clusterIDA = new short[maxNTowers]; + t_lFHCal_towers_clusterIDB = new short[maxNTowers]; + t_lFHCal_towers_cellTrueID = new int[maxNTowers]; // towers LFHCAL event_tree->Branch("tower_LFHCAL_N", &t_lFHCal_towers_N, "tower_LFHCAL_N/I"); event_tree->Branch("tower_LFHCAL_E", t_lFHCal_towers_cellE, "tower_LFHCAL_E[tower_LFHCAL_N]/F"); event_tree->Branch("tower_LFHCAL_T", t_lFHCal_towers_cellT, "tower_LFHCAL_T[tower_LFHCAL_N]/F"); - event_tree->Branch("tower_LFHCAL_ix", t_lFHCal_towers_cellIDx, "tower_LFHCAL_ix[tower_LFHCAL_N]/S"); - event_tree->Branch("tower_LFHCAL_iy", t_lFHCal_towers_cellIDy, "tower_LFHCAL_iy[tower_LFHCAL_N]/S"); - event_tree->Branch("tower_LFHCAL_iz", t_lFHCal_towers_cellIDz, "tower_LFHCAL_iz[tower_LFHCAL_N]/S"); - event_tree->Branch("tower_LFHCAL_clusIDA", t_lFHCal_towers_clusterIDA, "tower_LFHCAL_clusIDA[tower_LFHCAL_N]/S"); - event_tree->Branch("tower_LFHCAL_clusIDB", t_lFHCal_towers_clusterIDB, "tower_LFHCAL_clusIDB[tower_LFHCAL_N]/S"); - event_tree->Branch("tower_LFHCAL_trueID", t_lFHCal_towers_cellTrueID, "tower_LFHCAL_trueID[tower_LFHCAL_N]/I"); + event_tree->Branch("tower_LFHCAL_ix", t_lFHCal_towers_cellIDx, + "tower_LFHCAL_ix[tower_LFHCAL_N]/S"); + event_tree->Branch("tower_LFHCAL_iy", t_lFHCal_towers_cellIDy, + "tower_LFHCAL_iy[tower_LFHCAL_N]/S"); + event_tree->Branch("tower_LFHCAL_iz", t_lFHCal_towers_cellIDz, + "tower_LFHCAL_iz[tower_LFHCAL_N]/S"); + event_tree->Branch("tower_LFHCAL_clusIDA", t_lFHCal_towers_clusterIDA, + "tower_LFHCAL_clusIDA[tower_LFHCAL_N]/S"); + event_tree->Branch("tower_LFHCAL_clusIDB", t_lFHCal_towers_clusterIDB, + "tower_LFHCAL_clusIDB[tower_LFHCAL_N]/S"); + event_tree->Branch("tower_LFHCAL_trueID", t_lFHCal_towers_cellTrueID, + "tower_LFHCAL_trueID[tower_LFHCAL_N]/I"); } // =============================================================================================== // Tree for cluster studies // =============================================================================================== - if (enableTreeCluster){ - cluster_tree = new TTree("cluster_tree", "cluster_tree"); + if (enableTreeCluster) { + cluster_tree = new TTree("cluster_tree", "cluster_tree"); cluster_tree->SetDirectory(m_dir_main); t_mc_E = new float[maxNMC]; @@ -216,10 +246,10 @@ void lfhcal_studiesProcessor::Init() { t_lFHCal_cluster_NCells = new int[maxNCluster]; t_lFHCal_cluster_Phi = new float[maxNCluster]; t_lFHCal_cluster_Eta = new float[maxNCluster]; - t_fEMC_cluster_E = new float[maxNCluster]; - t_fEMC_cluster_NCells = new int[maxNCluster]; - t_fEMC_cluster_Eta = new float[maxNCluster]; - t_fEMC_cluster_Phi = new float[maxNCluster]; + t_fEMC_cluster_E = new float[maxNCluster]; + t_fEMC_cluster_NCells = new int[maxNCluster]; + t_fEMC_cluster_Eta = new float[maxNCluster]; + t_fEMC_cluster_Phi = new float[maxNCluster]; // MC particles cluster_tree->Branch("mc_N", &t_mc_N, "mc_N/I"); @@ -228,16 +258,23 @@ void lfhcal_studiesProcessor::Init() { cluster_tree->Branch("mc_Eta", t_mc_Eta, "mc_Eta[mc_N]/F"); // clusters LFHCAL cluster_tree->Branch("cluster_LFHCAL_N", &t_lFHCal_clusters_N, "cluster_LFHCAL_N/I"); - cluster_tree->Branch("cluster_LFHCAL_E", t_lFHCal_cluster_E, "cluster_LFHCAL_E[cluster_LFHCAL_N]/F"); - cluster_tree->Branch("cluster_LFHCAL_Ncells", t_lFHCal_cluster_NCells, "cluster_LFHCAL_Ncells[cluster_LFHCAL_N]/I"); - cluster_tree->Branch("cluster_LFHCAL_Eta", t_lFHCal_cluster_Eta, "cluster_LFHCAL_Eta[cluster_LFHCAL_N]/F"); - cluster_tree->Branch("cluster_LFHCAL_Phi", t_lFHCal_cluster_Phi, "cluster_LFHCAL_Phi[cluster_LFHCAL_N]/F"); + cluster_tree->Branch("cluster_LFHCAL_E", t_lFHCal_cluster_E, + "cluster_LFHCAL_E[cluster_LFHCAL_N]/F"); + cluster_tree->Branch("cluster_LFHCAL_Ncells", t_lFHCal_cluster_NCells, + "cluster_LFHCAL_Ncells[cluster_LFHCAL_N]/I"); + cluster_tree->Branch("cluster_LFHCAL_Eta", t_lFHCal_cluster_Eta, + "cluster_LFHCAL_Eta[cluster_LFHCAL_N]/F"); + cluster_tree->Branch("cluster_LFHCAL_Phi", t_lFHCal_cluster_Phi, + "cluster_LFHCAL_Phi[cluster_LFHCAL_N]/F"); // clusters FECal cluster_tree->Branch("cluster_FECAL_N", &t_fEMC_clusters_N, "cluster_FECAL_N/I"); cluster_tree->Branch("cluster_FECAL_E", t_fEMC_cluster_E, "cluster_FECAL_E[cluster_FECAL_N]/F"); - cluster_tree->Branch("cluster_FECAL_Ncells", t_fEMC_cluster_NCells, "cluster_FECAL_Ncells[cluster_FECAL_N]/I"); - cluster_tree->Branch("cluster_FECAL_Eta", t_fEMC_cluster_Eta, "cluster_FECAL_Eta[cluster_FECAL_N]/F"); - cluster_tree->Branch("cluster_FECAL_Phi", t_fEMC_cluster_Phi, "cluster_FECAL_Phi[cluster_FECAL_N]/F"); + cluster_tree->Branch("cluster_FECAL_Ncells", t_fEMC_cluster_NCells, + "cluster_FECAL_Ncells[cluster_FECAL_N]/I"); + cluster_tree->Branch("cluster_FECAL_Eta", t_fEMC_cluster_Eta, + "cluster_FECAL_Eta[cluster_FECAL_N]/F"); + cluster_tree->Branch("cluster_FECAL_Phi", t_fEMC_cluster_Phi, + "cluster_FECAL_Phi[cluster_FECAL_N]/F"); } std::cout << __PRETTY_FUNCTION__ << " " << __LINE__ << std::endl; @@ -245,35 +282,34 @@ void lfhcal_studiesProcessor::Init() { std::cout << "--------------------------\nID specification:\n"; try { m_decoder = detector->readout("LFHCALHits").idSpec().decoder(); - std::cout <<"1st: "<< m_decoder << std::endl; - iLx = m_decoder->index("towerx"); - iLy = m_decoder->index("towery"); - iLz = m_decoder->index("layerz"); + std::cout << "1st: " << m_decoder << std::endl; + iLx = m_decoder->index("towerx"); + iLy = m_decoder->index("towery"); + iLz = m_decoder->index("layerz"); iPassive = m_decoder->index("passive"); std::cout << "full list: " << " " << m_decoder->fieldDescription() << std::endl; } catch (...) { - std::cout <<"2nd: " << m_decoder << std::endl; - m_log->error("readoutClass not in the output"); - throw std::runtime_error("readoutClass not in the output."); + std::cout << "2nd: " << m_decoder << std::endl; + m_log->error("readoutClass not in the output"); + throw std::runtime_error("readoutClass not in the output."); } - } //******************************************************************************************// // ProcessSequential //******************************************************************************************// void lfhcal_studiesProcessor::Process(const std::shared_ptr& event) { -// void lfhcal_studiesProcessor::ProcessSequential(const std::shared_ptr& event) { + // void lfhcal_studiesProcessor::ProcessSequential(const std::shared_ptr& event) { // =============================================================================================== // process MC particles // =============================================================================================== - const auto &mcParticles = *(event->GetCollection("MCParticles")); - double mceta = 0; - double mcphi = 0; - double mcp = 0; - double mcenergy = 0; - int iMC = 0; + const auto& mcParticles = *(event->GetCollection("MCParticles")); + double mceta = 0; + double mcphi = 0; + double mcp = 0; + double mcenergy = 0; + int iMC = 0; for (auto mcparticle : mcParticles) { if (mcparticle.getGeneratorStatus() != 1) continue; @@ -286,11 +322,12 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event mcphi = atan2(mom.y, mom.x); // determine mc momentum mcp = sqrt(mom.x * mom.x + mom.y * mom.y + mom.z * mom.z); - m_log->trace("MC particle:{} \t {} \t {} \t totmom: {} phi {} eta {}", mom.x, mom.y, mom.z, mcp, mcphi, mceta); - hMCEnergyVsEta->Fill(mcp,mceta); + m_log->trace("MC particle:{} \t {} \t {} \t totmom: {} phi {} eta {}", mom.x, mom.y, mom.z, mcp, + mcphi, mceta); + hMCEnergyVsEta->Fill(mcp, mceta); - if (enableTreeCluster){ - if (iMC < maxNMC){ + if (enableTreeCluster) { + if (iMC < maxNMC) { t_mc_E[iMC] = mcenergy; t_mc_Phi[iMC] = mcphi; t_mc_Eta[iMC] = mceta; @@ -298,52 +335,54 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event } iMC++; } - if (enableTreeCluster) t_mc_N = iMC; + if (enableTreeCluster) + t_mc_N = iMC; // =============================================================================================== // process sim hits // =============================================================================================== std::vector input_tower_sim; - int nCaloHitsSim = 0; - float sumActiveCaloEnergy = 0; + int nCaloHitsSim = 0; + float sumActiveCaloEnergy = 0; float sumPassiveCaloEnergy = 0; - const auto &simHits = *(event->GetCollection(nameSimHits)); + const auto& simHits = *(event->GetCollection(nameSimHits)); for (const auto caloHit : simHits) { float x = caloHit.getPosition().x / 10.; float y = caloHit.getPosition().y / 10.; float z = caloHit.getPosition().z / 10.; uint64_t cellID = caloHit.getCellID(); float energy = caloHit.getEnergy(); - double time = std::numeric_limits::max(); + double time = std::numeric_limits::max(); for (const auto& c : caloHit.getContributions()) { - if (c.getTime() <= time) { - time = c.getTime(); - } + if (c.getTime() <= time) { + time = c.getTime(); + } } - auto detector_module_x = m_decoder->get(cellID, 1); - auto detector_module_y = m_decoder->get(cellID, 2); - auto detector_passive = m_decoder->get(cellID, iPassive); - auto detector_layer_x = m_decoder->get(cellID, iLx); - auto detector_layer_y = m_decoder->get(cellID, iLy); + auto detector_module_x = m_decoder->get(cellID, 1); + auto detector_module_y = m_decoder->get(cellID, 2); + auto detector_passive = m_decoder->get(cellID, iPassive); + auto detector_layer_x = m_decoder->get(cellID, iLx); + auto detector_layer_y = m_decoder->get(cellID, iLy); long detector_layer_rz = -1; if (isLFHCal) detector_layer_rz = m_decoder->get(cellID, 7); auto detector_layer_z = m_decoder->get(cellID, iLz); - if(detector_passive == 0) { + if (detector_passive == 0) { sumActiveCaloEnergy += energy; } else { sumPassiveCaloEnergy += energy; } - if (detector_passive > 0) continue; + if (detector_passive > 0) + continue; // calc cell IDs long cellIDx = -1; long cellIDy = -1; long cellIDz = -1; - if (isLFHCal){ - cellIDx = 54ll*2 - detector_module_x * 2 + detector_layer_x; - cellIDy = 54ll*2 - detector_module_y * 2 + detector_layer_y; - cellIDz = detector_layer_rz*10+detector_layer_z; + if (isLFHCal) { + cellIDx = 54ll * 2 - detector_module_x * 2 + detector_layer_x; + cellIDy = 54ll * 2 - detector_module_y * 2 + detector_layer_y; + cellIDz = detector_layer_rz * 10 + detector_layer_z; } nCaloHitsSim++; @@ -367,26 +406,25 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event } if (!found) { towersStrct tempstructT; - tempstructT.energy = energy; - tempstructT.time = time; - tempstructT.posx = x; - tempstructT.posy = y; - tempstructT.posz = z; - tempstructT.cellID = cellID; - tempstructT.cellIDx = cellIDx; - tempstructT.cellIDy = cellIDy; - tempstructT.cellIDz = cellIDz; - tempstructT.tower_trueID = 0; //TODO how to get trueID? + tempstructT.energy = energy; + tempstructT.time = time; + tempstructT.posx = x; + tempstructT.posy = y; + tempstructT.posz = z; + tempstructT.cellID = cellID; + tempstructT.cellIDx = cellIDx; + tempstructT.cellIDy = cellIDy; + tempstructT.cellIDz = cellIDz; + tempstructT.tower_trueID = 0; //TODO how to get trueID? input_tower_sim.push_back(tempstructT); } } - // =============================================================================================== // read rec hits & fill structs // =============================================================================================== - const auto &recHits = *(event->GetCollection(nameRecHits)); - int nCaloHitsRec = 0; + const auto& recHits = *(event->GetCollection(nameRecHits)); + int nCaloHitsRec = 0; std::vector input_tower_rec; std::vector input_tower_recSav; // process rec hits @@ -398,24 +436,25 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event float energy = caloHit.getEnergy(); float time = caloHit.getTime(); - auto detector_module_x = m_decoder->get(cellID, 1); - auto detector_module_y = m_decoder->get(cellID, 2); - auto detector_passive = m_decoder->get(cellID, iPassive); - auto detector_layer_x = m_decoder->get(cellID, iLx); - auto detector_layer_y = m_decoder->get(cellID, iLy); - int detector_layer_rz = -1; - if (isLFHCal){ - detector_layer_rz = m_decoder->get(cellID, 7); + auto detector_module_x = m_decoder->get(cellID, 1); + auto detector_module_y = m_decoder->get(cellID, 2); + auto detector_passive = m_decoder->get(cellID, iPassive); + auto detector_layer_x = m_decoder->get(cellID, iLx); + auto detector_layer_y = m_decoder->get(cellID, iLy); + int detector_layer_rz = -1; + if (isLFHCal) { + detector_layer_rz = m_decoder->get(cellID, 7); } - if (detector_passive > 0) continue; + if (detector_passive > 0) + continue; // calc cell IDs long cellIDx = -1; long cellIDy = -1; - if (isLFHCal){ - cellIDx = 54ll*2 - detector_module_x * 2 + detector_layer_x; - cellIDy = 54ll*2 - detector_module_y * 2 + detector_layer_y; + if (isLFHCal) { + cellIDx = 54ll * 2 - detector_module_x * 2 + detector_layer_x; + cellIDy = 54ll * 2 - detector_module_y * 2 + detector_layer_y; } hPosCaloHitsXY->Fill(x, y); @@ -435,29 +474,31 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event } if (!found) { towersStrct tempstructT; - tempstructT.energy = energy; - tempstructT.time = time; - tempstructT.posx = x; - tempstructT.posy = y; - tempstructT.posz = z; - tempstructT.cellID = cellID; - tempstructT.cellIDx = cellIDx; - tempstructT.cellIDy = cellIDy; + tempstructT.energy = energy; + tempstructT.time = time; + tempstructT.posx = x; + tempstructT.posy = y; + tempstructT.posz = z; + tempstructT.cellID = cellID; + tempstructT.cellIDx = cellIDx; + tempstructT.cellIDy = cellIDy; if (isLFHCal) - tempstructT.cellIDz = detector_layer_rz; - tempstructT.tower_trueID = 0; //TODO how to get trueID? + tempstructT.cellIDz = detector_layer_rz; + tempstructT.tower_trueID = 0; //TODO how to get trueID? input_tower_rec.push_back(tempstructT); input_tower_recSav.push_back(tempstructT); } } m_log->trace("LFHCal mod: nCaloHits sim {}\t rec {}", nCaloHitsSim, nCaloHitsRec); - if (nCaloHitsRec > 0) nEventsWithCaloHits++; + if (nCaloHitsRec > 0) + nEventsWithCaloHits++; // =============================================================================================== // sort tower arrays // =============================================================================================== - hSamplingFractionEta->Fill(mceta, sumActiveCaloEnergy / (sumActiveCaloEnergy+sumPassiveCaloEnergy)); + hSamplingFractionEta->Fill(mceta, + sumActiveCaloEnergy / (sumActiveCaloEnergy + sumPassiveCaloEnergy)); std::sort(input_tower_rec.begin(), input_tower_rec.end(), &acompare); std::sort(input_tower_recSav.begin(), input_tower_recSav.end(), &acompare); std::sort(input_tower_sim.begin(), input_tower_sim.end(), &acompare); @@ -480,36 +521,37 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event double tot_energySimHit = 0; for (auto& tower : input_tower_sim) { if (tower.cellIDz < minCellIDzDiffSamp) - tower.energy = tower.energy/samplingFractionW; // calibrate + tower.energy = tower.energy / samplingFractionW; // calibrate else - tower.energy = tower.energy/samplingFractionFe; // calibrate + tower.energy = tower.energy / samplingFractionFe; // calibrate tot_energySimHit += tower.energy; } - m_log->trace("Mc E: {} \t eta: {} \t sim E rec: {}\t rec E rec: {}", mcenergy, mceta, tot_energySimHit, tot_energyRecHit); + m_log->trace("Mc E: {} \t eta: {} \t sim E rec: {}\t rec E rec: {}", mcenergy, mceta, + tot_energySimHit, tot_energyRecHit); // =============================================================================================== // Fill summed hits histos // =============================================================================================== // rec hits hClusterNCells_E_eta->Fill(mcenergy, nCaloHitsRec, mceta); - hClusterEcalib_E_eta->Fill(mcenergy, tot_energyRecHit/mcenergy, mceta); - hClusterEcalib_E_phi->Fill(mcenergy, tot_energyRecHit/mcenergy, mcphi); + hClusterEcalib_E_eta->Fill(mcenergy, tot_energyRecHit / mcenergy, mceta); + hClusterEcalib_E_phi->Fill(mcenergy, tot_energyRecHit / mcenergy, mcphi); // sim hits hClusterSimNCells_E_eta->Fill(mcenergy, nCaloHitsSim, mceta); - hClusterESimcalib_E_eta->Fill(mcenergy, tot_energySimHit/mcenergy, mceta); - hClusterESimcalib_E_phi->Fill(mcenergy, tot_energySimHit/mcenergy, mcphi); + hClusterESimcalib_E_eta->Fill(mcenergy, tot_energySimHit / mcenergy, mceta); + hClusterESimcalib_E_phi->Fill(mcenergy, tot_energySimHit / mcenergy, mcphi); // =============================================================================================== // MA clusterization // =============================================================================================== - int removedCells = 0; - float minAggE = 0.001; - float seedE = 0.100; + int removedCells = 0; + float minAggE = 0.001; + float seedE = 0.100; - if (!input_tower_rec.empty()){ + if (!input_tower_rec.empty()) { // clean up rec array for clusterization - while (input_tower_rec.at(input_tower_rec.size()-1).energy < minAggE ){ + while (input_tower_rec.at(input_tower_rec.size() - 1).energy < minAggE) { input_tower_rec.pop_back(); removedCells++; } @@ -520,32 +562,42 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event std::vector clusters_calo; // vector of towers within the currently found cluster std::vector cluster_towers; - while (!input_tower_rec.empty() ) { + while (!input_tower_rec.empty()) { cluster_towers.clear(); clustersStrct tempstructC; // always start with highest energetic tower - if(input_tower_rec.at(0).energy > seedE){ - m_log->trace("seed: {}\t {} \t {}", input_tower_rec.at(0).energy, input_tower_rec.at(0).cellIDx, input_tower_rec.at(0).cellIDy, input_tower_rec.at(0).cellIDz); + if (input_tower_rec.at(0).energy > seedE) { + m_log->trace("seed: {}\t {} \t {}", input_tower_rec.at(0).energy, + input_tower_rec.at(0).cellIDx, input_tower_rec.at(0).cellIDy, + input_tower_rec.at(0).cellIDz); tempstructC = findMACluster(seedE, minAggE, input_tower_rec, cluster_towers); // determine remaining cluster properties from its towers - float* showershape_eta_phi = CalculateM02andWeightedPosition(cluster_towers, tempstructC.cluster_E, 4.5); - tempstructC.cluster_M02 = showershape_eta_phi[0]; - tempstructC.cluster_M20 = showershape_eta_phi[1]; - tempstructC.cluster_Eta = showershape_eta_phi[2]; - tempstructC.cluster_Phi = showershape_eta_phi[3]; - tempstructC.cluster_X = showershape_eta_phi[4]; - tempstructC.cluster_Y = showershape_eta_phi[5]; - tempstructC.cluster_Z = showershape_eta_phi[6]; + float* showershape_eta_phi = + CalculateM02andWeightedPosition(cluster_towers, tempstructC.cluster_E, 4.5); + tempstructC.cluster_M02 = showershape_eta_phi[0]; + tempstructC.cluster_M20 = showershape_eta_phi[1]; + tempstructC.cluster_Eta = showershape_eta_phi[2]; + tempstructC.cluster_Phi = showershape_eta_phi[3]; + tempstructC.cluster_X = showershape_eta_phi[4]; + tempstructC.cluster_Y = showershape_eta_phi[5]; + tempstructC.cluster_Z = showershape_eta_phi[6]; tempstructC.cluster_towers = cluster_towers; - m_log->trace("---------> \t {} \tcluster with E = {} \tEta: {} \tPhi: {} \tX: {} \tY: {} \tZ: {} \tntowers: {} \ttrueID: {}", nclusters, tempstructC.cluster_E, tempstructC.cluster_Eta, tempstructC.cluster_Phi, tempstructC.cluster_X, tempstructC.cluster_Y, tempstructC.cluster_Z, tempstructC.cluster_NTowers, tempstructC.cluster_trueID ); + m_log->trace("---------> \t {} \tcluster with E = {} \tEta: {} \tPhi: {} \tX: {} \tY: {} " + "\tZ: {} \tntowers: {} \ttrueID: {}", + nclusters, tempstructC.cluster_E, tempstructC.cluster_Eta, + tempstructC.cluster_Phi, tempstructC.cluster_X, tempstructC.cluster_Y, + tempstructC.cluster_Z, tempstructC.cluster_NTowers, + tempstructC.cluster_trueID); clusters_calo.push_back(tempstructC); clusters_calo.push_back(tempstructC); nclusters++; } else { - m_log->trace("remaining: {} largest: {} \t {} \t {} \t {}", (int)input_tower_rec.size(), input_tower_rec.at(0).energy, input_tower_rec.at(0).cellIDx, input_tower_rec.at(0).cellIDy, input_tower_rec.at(0).cellIDz); + m_log->trace("remaining: {} largest: {} \t {} \t {} \t {}", (int)input_tower_rec.size(), + input_tower_rec.at(0).energy, input_tower_rec.at(0).cellIDx, + input_tower_rec.at(0).cellIDy, input_tower_rec.at(0).cellIDz); input_tower_rec.clear(); } } @@ -554,106 +606,110 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event // --------------------------- Fill LFHCal MA clusters in tree and hists ------------------------- // ----------------------------------------------------------------------------------------------- std::sort(clusters_calo.begin(), clusters_calo.end(), &acompareCl); - m_log->info("-----> found {} clusters" , clusters_calo.size()); + m_log->info("-----> found {} clusters", clusters_calo.size()); hRecNClusters_E_eta->Fill(mcenergy, clusters_calo.size(), mceta); int iCl = 0; for (const auto cluster : clusters_calo) { - if (iCl < maxNCluster && enableTreeCluster){ - t_lFHCal_cluster_E[iCl] = (float)cluster.cluster_E; - t_lFHCal_cluster_NCells[iCl] = (int)cluster.cluster_NTowers; - t_lFHCal_cluster_Eta[iCl] = (float)cluster.cluster_Eta; - t_lFHCal_cluster_Phi[iCl] = (float)cluster.cluster_Phi; + if (iCl < maxNCluster && enableTreeCluster) { + t_lFHCal_cluster_E[iCl] = (float)cluster.cluster_E; + t_lFHCal_cluster_NCells[iCl] = (int)cluster.cluster_NTowers; + t_lFHCal_cluster_Eta[iCl] = (float)cluster.cluster_Eta; + t_lFHCal_cluster_Phi[iCl] = (float)cluster.cluster_Phi; } - hRecClusterEcalib_E_eta->Fill(mcenergy, cluster.cluster_E/mcenergy, mceta); - for (int iCell = 0; iCell < (int)cluster.cluster_towers.size(); iCell++){ + hRecClusterEcalib_E_eta->Fill(mcenergy, cluster.cluster_E / mcenergy, mceta); + for (int iCell = 0; iCell < (int)cluster.cluster_towers.size(); iCell++) { int pSav = 0; - while(cluster.cluster_towers.at(iCell).cellID != input_tower_recSav.at(pSav).cellID && pSav < (int)input_tower_recSav.size() ) pSav++; + while (cluster.cluster_towers.at(iCell).cellID != input_tower_recSav.at(pSav).cellID && + pSav < (int)input_tower_recSav.size()) + pSav++; if (cluster.cluster_towers.at(iCell).cellID == input_tower_recSav.at(pSav).cellID) input_tower_recSav.at(pSav).tower_clusterIDA = iCl; } - if (iCl == 0){ - hRecClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.cluster_E/mcenergy, mceta); + if (iCl == 0) { + hRecClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.cluster_E / mcenergy, mceta); hRecClusterNCells_Ehigh_eta->Fill(mcenergy, cluster.cluster_NTowers, mceta); } iCl++; m_log->trace("MA cluster {}:\t {} \t {}", iCl, cluster.cluster_E, cluster.cluster_NTowers); } - if (iCl < maxNCluster && enableTreeCluster) t_lFHCal_clusters_N = (int)iCl; + if (iCl < maxNCluster && enableTreeCluster) + t_lFHCal_clusters_N = (int)iCl; clusters_calo.clear(); } else { hRecNClusters_E_eta->Fill(mcenergy, 0., mceta); - if (enableTreeCluster) t_lFHCal_clusters_N = 0; + if (enableTreeCluster) + t_lFHCal_clusters_N = 0; } // =============================================================================================== // ------------------------------- Fill LFHCAl Island clusters in hists -------------------------- // =============================================================================================== - int iClF = 0; - float highestEFr = 0; - int iClFHigh = 0; + int iClF = 0; + float highestEFr = 0; + int iClFHigh = 0; - const auto &lfhcalClustersF = *(event->GetCollection(nameClusters)); + const auto& lfhcalClustersF = *(event->GetCollection(nameClusters)); for (const auto cluster : lfhcalClustersF) { - if (cluster.getEnergy() > highestEFr){ - iClFHigh = iClF; - highestEFr = cluster.getEnergy(); + if (cluster.getEnergy() > highestEFr) { + iClFHigh = iClF; + highestEFr = cluster.getEnergy(); } - hRecFClusterEcalib_E_eta->Fill(mcenergy, cluster.getEnergy()/mcenergy, mceta); + hRecFClusterEcalib_E_eta->Fill(mcenergy, cluster.getEnergy() / mcenergy, mceta); m_log->trace("Island cluster {}:\t {} \t {}", iClF, cluster.getEnergy(), cluster.getNhits()); iClF++; } hRecFNClusters_E_eta->Fill(mcenergy, iClF, mceta); // fill hists for highest Island cluster - iClF = 0; + iClF = 0; for (const auto cluster : lfhcalClustersF) { - if (iClF == iClFHigh){ - hRecFClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.getEnergy()/mcenergy, mceta); + if (iClF == iClFHigh) { + hRecFClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.getEnergy() / mcenergy, mceta); hRecFClusterNCells_Ehigh_eta->Fill(mcenergy, cluster.getNhits(), mceta); } iClF++; } - // =============================================================================================== // ------------------------------- Fill FECal Island clusters in hists -------------------------- // =============================================================================================== - int iECl = 0; - float highestEEmCl = 0; - int iEClHigh = 0; + int iECl = 0; + float highestEEmCl = 0; + int iEClHigh = 0; - if (enableECalCluster){ + if (enableECalCluster) { try { - const auto &fEMCClustersF = *(event->GetCollection("EcalEndcapPClusters")); - m_log->info("-----> found fEMCClustersF:" , fEMCClustersF.size()); + const auto& fEMCClustersF = *(event->GetCollection("EcalEndcapPClusters")); + m_log->info("-----> found fEMCClustersF:", fEMCClustersF.size()); for (const auto cluster : fEMCClustersF) { - if (iECl < maxNCluster && enableTreeCluster){ - t_fEMC_cluster_E[iECl] = (float)cluster.getEnergy(); - t_fEMC_cluster_NCells[iECl] = (int)cluster.getNhits(); - t_fEMC_cluster_Eta[iECl] = (-1.) * std::log(std::tan((float)cluster.getIntrinsicTheta() / 2.)); - t_fEMC_cluster_Phi[iECl] = (float)cluster.getIntrinsicPhi(); + if (iECl < maxNCluster && enableTreeCluster) { + t_fEMC_cluster_E[iECl] = (float)cluster.getEnergy(); + t_fEMC_cluster_NCells[iECl] = (int)cluster.getNhits(); + t_fEMC_cluster_Eta[iECl] = + (-1.) * std::log(std::tan((float)cluster.getIntrinsicTheta() / 2.)); + t_fEMC_cluster_Phi[iECl] = (float)cluster.getIntrinsicPhi(); } - if (cluster.getEnergy() > highestEEmCl){ - iEClHigh = iECl; - highestEEmCl = cluster.getEnergy(); + if (cluster.getEnergy() > highestEEmCl) { + iEClHigh = iECl; + highestEEmCl = cluster.getEnergy(); } - hRecFEmClusterEcalib_E_eta->Fill(mcenergy, cluster.getEnergy()/mcenergy, mceta); + hRecFEmClusterEcalib_E_eta->Fill(mcenergy, cluster.getEnergy() / mcenergy, mceta); iECl++; } - t_fEMC_clusters_N = iECl; + t_fEMC_clusters_N = iECl; hRecFEmNClusters_E_eta->Fill(mcenergy, iECl, mceta); // fill hists for highest Island cluster - iECl = 0; + iECl = 0; for (const auto cluster : fEMCClustersF) { - if (iECl == iEClHigh){ - hRecFEmClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.getEnergy()/mcenergy, mceta); + if (iECl == iEClHigh) { + hRecFEmClusterEcalib_Ehigh_eta->Fill(mcenergy, cluster.getEnergy() / mcenergy, mceta); } iECl++; } - } catch (...){ + } catch (...) { std::cout << "ECal clusters not in output" << std::endl; enableECalCluster = false; } @@ -661,10 +717,14 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event // =============================================================================================== // Write clusterizer tree & clean-up variables // =============================================================================================== - if (enableTree){ + if (enableTree) { t_lFHCal_towers_N = (int)input_tower_recSav.size(); - for (int iCell = 0; iCell < (int)input_tower_recSav.size(); iCell++){ - m_log->trace("{} \t {} \t {} \t {} \t {} \t {}", input_tower_recSav.at(iCell).cellIDx, input_tower_recSav.at(iCell).cellIDy, input_tower_recSav.at(iCell).cellIDz , input_tower_recSav.at(iCell).energy, input_tower_recSav.at(iCell).tower_clusterIDA, input_tower_recSav.at(iCell).tower_clusterIDB ); + for (int iCell = 0; iCell < (int)input_tower_recSav.size(); iCell++) { + m_log->trace("{} \t {} \t {} \t {} \t {} \t {}", input_tower_recSav.at(iCell).cellIDx, + input_tower_recSav.at(iCell).cellIDy, input_tower_recSav.at(iCell).cellIDz, + input_tower_recSav.at(iCell).energy, + input_tower_recSav.at(iCell).tower_clusterIDA, + input_tower_recSav.at(iCell).tower_clusterIDB); t_lFHCal_towers_cellE[iCell] = (float)input_tower_recSav.at(iCell).energy; t_lFHCal_towers_cellT[iCell] = (float)input_tower_recSav.at(iCell).time; @@ -679,51 +739,50 @@ void lfhcal_studiesProcessor::Process(const std::shared_ptr& event event_tree->Fill(); t_lFHCal_towers_N = 0; - for (Int_t itow = 0; itow < maxNTowers; itow++){ - t_lFHCal_towers_cellE[itow] = 0; - t_lFHCal_towers_cellT[itow] = 0; - t_lFHCal_towers_cellIDx[itow] = 0; - t_lFHCal_towers_cellIDy[itow] = 0; - t_lFHCal_towers_cellIDz[itow] = 0; - t_lFHCal_towers_clusterIDA[itow] = 0; - t_lFHCal_towers_clusterIDB[itow] = 0; - t_lFHCal_towers_cellTrueID[itow] = 0; + for (Int_t itow = 0; itow < maxNTowers; itow++) { + t_lFHCal_towers_cellE[itow] = 0; + t_lFHCal_towers_cellT[itow] = 0; + t_lFHCal_towers_cellIDx[itow] = 0; + t_lFHCal_towers_cellIDy[itow] = 0; + t_lFHCal_towers_cellIDz[itow] = 0; + t_lFHCal_towers_clusterIDA[itow] = 0; + t_lFHCal_towers_clusterIDB[itow] = 0; + t_lFHCal_towers_cellTrueID[itow] = 0; } } // =============================================================================================== // Write cluster tree & clean-up variables // =============================================================================================== - if (enableTreeCluster){ + if (enableTreeCluster) { cluster_tree->Fill(); - t_mc_N = 0; - t_lFHCal_clusters_N = 0; - t_fEMC_clusters_N = 0; - for (Int_t iMC = 0; iMC < maxNMC; iMC++){ - t_mc_E[iMC] = 0; - t_mc_Phi[iMC] = 0; - t_mc_Eta[iMC] = 0; + t_mc_N = 0; + t_lFHCal_clusters_N = 0; + t_fEMC_clusters_N = 0; + for (Int_t iMC = 0; iMC < maxNMC; iMC++) { + t_mc_E[iMC] = 0; + t_mc_Phi[iMC] = 0; + t_mc_Eta[iMC] = 0; } - for (Int_t iCl = 0; iCl < maxNCluster; iCl++){ - t_lFHCal_cluster_E[iCl] = 0; - t_lFHCal_cluster_NCells[iCl] = 0; - t_lFHCal_cluster_Eta[iCl] = 0; - t_lFHCal_cluster_Phi[iCl] = 0; + for (Int_t iCl = 0; iCl < maxNCluster; iCl++) { + t_lFHCal_cluster_E[iCl] = 0; + t_lFHCal_cluster_NCells[iCl] = 0; + t_lFHCal_cluster_Eta[iCl] = 0; + t_lFHCal_cluster_Phi[iCl] = 0; t_fEMC_cluster_E[iCl] = 0; t_fEMC_cluster_NCells[iCl] = 0; t_fEMC_cluster_Eta[iCl] = 0; t_fEMC_cluster_Phi[iCl] = 0; } } - } //******************************************************************************************// // Finish //******************************************************************************************// void lfhcal_studiesProcessor::Finish() { - std::cout << "------> LFHCal " << nEventsWithCaloHits << " with calo info present"<< std::endl; + std::cout << "------> LFHCal " << nEventsWithCaloHits << " with calo info present" << std::endl; // Do any final calculations here. if (enableTree) { diff --git a/src/benchmarks/reconstruction/lfhcal_studies/lfhcal_studiesProcessor.h b/src/benchmarks/reconstruction/lfhcal_studies/lfhcal_studiesProcessor.h index 27232ea3b0..4647469f48 100644 --- a/src/benchmarks/reconstruction/lfhcal_studies/lfhcal_studiesProcessor.h +++ b/src/benchmarks/reconstruction/lfhcal_studies/lfhcal_studiesProcessor.h @@ -16,93 +16,91 @@ #include #include -class lfhcal_studiesProcessor: public JEventProcessor { +class lfhcal_studiesProcessor : public JEventProcessor { public: - lfhcal_studiesProcessor() { SetTypeName(NAME_OF_THIS); } + lfhcal_studiesProcessor() { SetTypeName(NAME_OF_THIS); } - void Init() override; -// void InitWithGlobalRootLock() override; -// void ProcessSequential(const std::shared_ptr& event) override; - void Process(const std::shared_ptr& event) override; - void Finish() override; -// void FinishWithGlobalRootLock() override; - TDirectory *m_dir_main; - // Declare histogram and tree pointers here. e.g. - TH2D* hMCEnergyVsEta; - TH3D* hClusterEcalib_E_eta; - TH3D* hClusterNCells_E_eta; - TH3D* hClusterEcalib_E_phi; - TH2D* hPosCaloHitsXY; - TH2D* hPosCaloHitsZX; - TH2D* hPosCaloHitsZY; - TH3D* hClusterESimcalib_E_eta; - TH3D* hClusterSimNCells_E_eta; - TH3D* hClusterESimcalib_E_phi; - TH2D* hCellESim_layerZ; - TH2D* hCellESim_layerX; - TH2D* hCellESim_layerY; - TH2D* hCellTSim_layerZ; - TH2D* hPosCaloSimHitsXY; - TH2D* hPosCaloSimHitsZX; - TH2D* hPosCaloSimHitsZY; - TH3D* hRecClusterEcalib_E_eta; - TH3D* hRecNClusters_E_eta; - TH3D* hRecClusterEcalib_Ehigh_eta; - TH3D* hRecClusterNCells_Ehigh_eta; - TH3D* hRecFClusterEcalib_E_eta; - TH3D* hRecFNClusters_E_eta; - TH3D* hRecFClusterEcalib_Ehigh_eta; - TH3D* hRecFClusterNCells_Ehigh_eta; - TH3D* hRecFEmClusterEcalib_E_eta; - TH3D* hRecFEmNClusters_E_eta; - TH3D* hRecFEmClusterEcalib_Ehigh_eta; - TH2D* hSamplingFractionEta; + void Init() override; + // void InitWithGlobalRootLock() override; + // void ProcessSequential(const std::shared_ptr& event) override; + void Process(const std::shared_ptr& event) override; + void Finish() override; + // void FinishWithGlobalRootLock() override; + TDirectory* m_dir_main; + // Declare histogram and tree pointers here. e.g. + TH2D* hMCEnergyVsEta; + TH3D* hClusterEcalib_E_eta; + TH3D* hClusterNCells_E_eta; + TH3D* hClusterEcalib_E_phi; + TH2D* hPosCaloHitsXY; + TH2D* hPosCaloHitsZX; + TH2D* hPosCaloHitsZY; + TH3D* hClusterESimcalib_E_eta; + TH3D* hClusterSimNCells_E_eta; + TH3D* hClusterESimcalib_E_phi; + TH2D* hCellESim_layerZ; + TH2D* hCellESim_layerX; + TH2D* hCellESim_layerY; + TH2D* hCellTSim_layerZ; + TH2D* hPosCaloSimHitsXY; + TH2D* hPosCaloSimHitsZX; + TH2D* hPosCaloSimHitsZY; + TH3D* hRecClusterEcalib_E_eta; + TH3D* hRecNClusters_E_eta; + TH3D* hRecClusterEcalib_Ehigh_eta; + TH3D* hRecClusterNCells_Ehigh_eta; + TH3D* hRecFClusterEcalib_E_eta; + TH3D* hRecFNClusters_E_eta; + TH3D* hRecFClusterEcalib_Ehigh_eta; + TH3D* hRecFClusterNCells_Ehigh_eta; + TH3D* hRecFEmClusterEcalib_E_eta; + TH3D* hRecFEmNClusters_E_eta; + TH3D* hRecFEmClusterEcalib_Ehigh_eta; + TH2D* hSamplingFractionEta; - bool enableTree = true; - TTree* event_tree; - const int maxNTowers = 65000; - int t_lFHCal_towers_N; - short* t_lFHCal_towers_cellIDx; - short* t_lFHCal_towers_cellIDy; - short* t_lFHCal_towers_cellIDz; - short* t_lFHCal_towers_clusterIDA; - short* t_lFHCal_towers_clusterIDB; - float* t_lFHCal_towers_cellE; - float* t_lFHCal_towers_cellT; - int* t_lFHCal_towers_cellTrueID; + bool enableTree = true; + TTree* event_tree; + const int maxNTowers = 65000; + int t_lFHCal_towers_N; + short* t_lFHCal_towers_cellIDx; + short* t_lFHCal_towers_cellIDy; + short* t_lFHCal_towers_cellIDz; + short* t_lFHCal_towers_clusterIDA; + short* t_lFHCal_towers_clusterIDB; + float* t_lFHCal_towers_cellE; + float* t_lFHCal_towers_cellT; + int* t_lFHCal_towers_cellTrueID; - bool enableTreeCluster = true; - bool enableECalCluster = true; - TTree* cluster_tree; - const int maxNCluster = 50; - const int maxNMC = 50; - int t_mc_N; - float* t_mc_E; - float* t_mc_Phi; - float* t_mc_Eta; - int t_lFHCal_clusters_N; - float* t_lFHCal_cluster_E; - int* t_lFHCal_cluster_NCells; - float* t_lFHCal_cluster_Phi; - float* t_lFHCal_cluster_Eta; - int t_fEMC_clusters_N; - float* t_fEMC_cluster_E; - int* t_fEMC_cluster_NCells; - float* t_fEMC_cluster_Phi; - float* t_fEMC_cluster_Eta; - - - int nEventsWithCaloHits = 0; - bool isLFHCal = true; - std::shared_ptr m_log; - dd4hep::DDSegmentation::BitFieldCoder* m_decoder; - std::string nameSimHits = "LFHCALHits"; - std::string nameRecHits = "LFHCALRecHits"; - std::string nameClusters = "LFHCALClusters"; - std::string nameProtoClusters = "LFHCALIslandProtoClusters"; - short iPassive; - short iLx; - short iLy; - short iLz; + bool enableTreeCluster = true; + bool enableECalCluster = true; + TTree* cluster_tree; + const int maxNCluster = 50; + const int maxNMC = 50; + int t_mc_N; + float* t_mc_E; + float* t_mc_Phi; + float* t_mc_Eta; + int t_lFHCal_clusters_N; + float* t_lFHCal_cluster_E; + int* t_lFHCal_cluster_NCells; + float* t_lFHCal_cluster_Phi; + float* t_lFHCal_cluster_Eta; + int t_fEMC_clusters_N; + float* t_fEMC_cluster_E; + int* t_fEMC_cluster_NCells; + float* t_fEMC_cluster_Phi; + float* t_fEMC_cluster_Eta; + int nEventsWithCaloHits = 0; + bool isLFHCal = true; + std::shared_ptr m_log; + dd4hep::DDSegmentation::BitFieldCoder* m_decoder; + std::string nameSimHits = "LFHCALHits"; + std::string nameRecHits = "LFHCALRecHits"; + std::string nameClusters = "LFHCALClusters"; + std::string nameProtoClusters = "LFHCALIslandProtoClusters"; + short iPassive; + short iLx; + short iLy; + short iLz; }; diff --git a/src/benchmarks/reconstruction/tof_efficiency/TofEfficiency_processor.cc b/src/benchmarks/reconstruction/tof_efficiency/TofEfficiency_processor.cc index ddc84fa38f..ded962dd94 100644 --- a/src/benchmarks/reconstruction/tof_efficiency/TofEfficiency_processor.cc +++ b/src/benchmarks/reconstruction/tof_efficiency/TofEfficiency_processor.cc @@ -18,116 +18,132 @@ //------------------------------------------- // InitWithGlobalRootLock //------------------------------------------- -void TofEfficiency_processor::InitWithGlobalRootLock(){ - std::string plugin_name=("tof_efficiency"); - - InitLogger(GetApplication(), plugin_name); - - // Get JANA application - auto *app = GetApplication(); - - // Ask service locator a file to write histograms to - auto root_file_service = app->GetService(); - - // Get TDirectory for histograms root file - auto globalRootLock = app->GetService(); - globalRootLock->acquire_write_lock(); - auto *file = root_file_service->GetHistFile(); - globalRootLock->release_lock(); - - // Create a directory for this plugin. And subdirectories for series of histograms - m_dir_main = file->mkdir(plugin_name.c_str()); - - auto phi_limit_min = 0; - auto phi_limit_max = 6.29; - auto z_limit_min = -1250; - auto z_limit_max = 1250; - auto r_limit_min = 50; - auto r_limit_max = 675; - - m_th2_btof_phiz = new TH2F("btof_phiz", "Hit position for Barrel TOF", 100, phi_limit_min, phi_limit_max, 100, z_limit_min, z_limit_max); - m_th2_ftof_rphi = new TH2F("ftof_rphi", "Hit position for Forward TOF", 100, r_limit_min, r_limit_max, 100, phi_limit_min, phi_limit_max); - m_th2_btof_phiz->SetDirectory(m_dir_main); - m_th2_ftof_rphi->SetDirectory(m_dir_main); - - m_tntuple_track = new TNtuple("track","track with tof","det:proj_x:proj_y:proj_z:proj_pathlength:tofhit_x:tofhit_y:tofhit_z:tofhit_t:tofhit_dca"); - m_tntuple_track->SetDirectory(m_dir_main); +void TofEfficiency_processor::InitWithGlobalRootLock() { + std::string plugin_name = ("tof_efficiency"); + + InitLogger(GetApplication(), plugin_name); + + // Get JANA application + auto* app = GetApplication(); + + // Ask service locator a file to write histograms to + auto root_file_service = app->GetService(); + + // Get TDirectory for histograms root file + auto globalRootLock = app->GetService(); + globalRootLock->acquire_write_lock(); + auto* file = root_file_service->GetHistFile(); + globalRootLock->release_lock(); + + // Create a directory for this plugin. And subdirectories for series of histograms + m_dir_main = file->mkdir(plugin_name.c_str()); + + auto phi_limit_min = 0; + auto phi_limit_max = 6.29; + auto z_limit_min = -1250; + auto z_limit_max = 1250; + auto r_limit_min = 50; + auto r_limit_max = 675; + + m_th2_btof_phiz = new TH2F("btof_phiz", "Hit position for Barrel TOF", 100, phi_limit_min, + phi_limit_max, 100, z_limit_min, z_limit_max); + m_th2_ftof_rphi = new TH2F("ftof_rphi", "Hit position for Forward TOF", 100, r_limit_min, + r_limit_max, 100, phi_limit_min, phi_limit_max); + m_th2_btof_phiz->SetDirectory(m_dir_main); + m_th2_ftof_rphi->SetDirectory(m_dir_main); + + m_tntuple_track = new TNtuple( + "track", "track with tof", + "det:proj_x:proj_y:proj_z:proj_pathlength:tofhit_x:tofhit_y:tofhit_z:tofhit_t:tofhit_dca"); + m_tntuple_track->SetDirectory(m_dir_main); } //------------------------------------------- // ProcessSequential //------------------------------------------- void TofEfficiency_processor::ProcessSequential(const std::shared_ptr& event) { - const auto &mcParticles = *(event->GetCollection("MCParticles")); - const auto &trackSegments = *(event->GetCollection("CentralTrackSegments")); - const auto &barrelHits = *(event->GetCollection("TOFBarrelRecHits")); - const auto &endcapHits = *(event->GetCollection("TOFEndcapRecHits")); - - // List TOF Barrel hits from barrel - logger()->trace("TOF barrel hits:"); - m_log->trace(" {:>10} {:>10} {:>10} {:>10}", "[x]", "[y]", "[z]", "[time]"); - for (const auto hit: barrelHits) { - const auto& pos = hit.getPosition(); - float r=sqrt(pos.x*pos.x+pos.y*pos.y); - float phi=acos(pos.x/r); if(pos.y<0) phi+=3.1415927; - m_th2_btof_phiz->Fill(phi, pos.z); - m_log->trace(" {:>10.2f} {:>10.2f} {:>10.2f} {:>10.4f}", pos.x, pos.y, pos.z, hit.getTime()); - } - - // List TOF endcap hits - logger()->trace("TOF endcap hits:"); - m_log->trace(" {:>10} {:>10} {:>10} {:>10}", "[x]", "[y]", "[z]", "[time]"); - for (const auto hit: endcapHits) { - const auto& pos = hit.getPosition(); - float r=sqrt(pos.x*pos.x+pos.y*pos.y); - float phi=acos(pos.x/r); if(pos.y<0) phi+=3.1415927; - m_th2_ftof_rphi->Fill(r, phi); - m_log->trace(" {:>10.2f} {:>10.2f} {:>10.2f} {:>10.4f}", pos.x, pos.y, pos.z, hit.getTime()); - } - - // Now go through reconstructed tracks points - logger()->trace("Going over tracks:"); - m_log->trace(" {:>10} {:>10} {:>10} {:>10}", "[x]", "[y]", "[z]", "[length]"); - for( const auto track_segment : trackSegments ){ - logger()->trace(" Track trajectory"); - - for(const auto point: track_segment.getPoints()) { - auto &pos = point.position; - m_log->trace(" {:>10.2f} {:>10.2f} {:>10.2f} {:>10.2f}", pos.x, pos.y, pos.z, point.pathlength); - - int det=IsTOFHit(pos.x, pos.y, pos.z); - float distance_closest=1e6; - float hit_x=-1000, hit_y=-1000, hit_z=-1000, hit_t=-1000; - float hit_px=-1000, hit_py=-1000, hit_pz=-1000, hit_e=-1000; - if(det==1) { - for (const auto hit: barrelHits) { - const auto& hitpos = hit.getPosition(); - float distance=sqrt((hitpos.x-pos.x)*(hitpos.x-pos.x)+(hitpos.y-pos.y)*(hitpos.y-pos.y)+(hitpos.z-pos.z)*(hitpos.z-pos.z)); - if(distanceFill(det, pos.x, pos.y, pos.z, point.pathlength, hit_x, hit_y, hit_z, hit_t, distance_closest); + const auto& mcParticles = *(event->GetCollection("MCParticles")); + const auto& trackSegments = + *(event->GetCollection("CentralTrackSegments")); + const auto& barrelHits = *(event->GetCollection("TOFBarrelRecHits")); + const auto& endcapHits = *(event->GetCollection("TOFEndcapRecHits")); + + // List TOF Barrel hits from barrel + logger()->trace("TOF barrel hits:"); + m_log->trace(" {:>10} {:>10} {:>10} {:>10}", "[x]", "[y]", "[z]", "[time]"); + for (const auto hit : barrelHits) { + const auto& pos = hit.getPosition(); + float r = sqrt(pos.x * pos.x + pos.y * pos.y); + float phi = acos(pos.x / r); + if (pos.y < 0) + phi += 3.1415927; + m_th2_btof_phiz->Fill(phi, pos.z); + m_log->trace(" {:>10.2f} {:>10.2f} {:>10.2f} {:>10.4f}", pos.x, pos.y, pos.z, hit.getTime()); + } + + // List TOF endcap hits + logger()->trace("TOF endcap hits:"); + m_log->trace(" {:>10} {:>10} {:>10} {:>10}", "[x]", "[y]", "[z]", "[time]"); + for (const auto hit : endcapHits) { + const auto& pos = hit.getPosition(); + float r = sqrt(pos.x * pos.x + pos.y * pos.y); + float phi = acos(pos.x / r); + if (pos.y < 0) + phi += 3.1415927; + m_th2_ftof_rphi->Fill(r, phi); + m_log->trace(" {:>10.2f} {:>10.2f} {:>10.2f} {:>10.4f}", pos.x, pos.y, pos.z, hit.getTime()); + } + + // Now go through reconstructed tracks points + logger()->trace("Going over tracks:"); + m_log->trace(" {:>10} {:>10} {:>10} {:>10}", "[x]", "[y]", "[z]", "[length]"); + for (const auto track_segment : trackSegments) { + logger()->trace(" Track trajectory"); + + for (const auto point : track_segment.getPoints()) { + auto& pos = point.position; + m_log->trace(" {:>10.2f} {:>10.2f} {:>10.2f} {:>10.2f}", pos.x, pos.y, pos.z, + point.pathlength); + + int det = IsTOFHit(pos.x, pos.y, pos.z); + float distance_closest = 1e6; + float hit_x = -1000, hit_y = -1000, hit_z = -1000, hit_t = -1000; + float hit_px = -1000, hit_py = -1000, hit_pz = -1000, hit_e = -1000; + if (det == 1) { + for (const auto hit : barrelHits) { + const auto& hitpos = hit.getPosition(); + float distance = sqrt((hitpos.x - pos.x) * (hitpos.x - pos.x) + + (hitpos.y - pos.y) * (hitpos.y - pos.y) + + (hitpos.z - pos.z) * (hitpos.z - pos.z)); + if (distance < distance_closest) { + distance_closest = distance; + hit_x = hitpos.x; + hit_y = hitpos.y; + hit_z = hitpos.z; + hit_t = hit.getTime(); + } + } + } + if (det == 2) { + for (const auto hit : endcapHits) { + const auto& hitpos = hit.getPosition(); + float distance = sqrt((hitpos.x - pos.x) * (hitpos.x - pos.x) + + (hitpos.y - pos.y) * (hitpos.y - pos.y) + + (hitpos.z - pos.z) * (hitpos.z - pos.z)); + if (distance < distance_closest) { + distance_closest = distance; + hit_x = hitpos.x; + hit_y = hitpos.y; + hit_z = hitpos.z; + hit_t = hit.getTime(); + } } + } + if (det != 0) + m_tntuple_track->Fill(det, pos.x, pos.y, pos.z, point.pathlength, hit_x, hit_y, hit_z, + hit_t, distance_closest); } + } } //------------------------------------------- @@ -135,24 +151,26 @@ void TofEfficiency_processor::ProcessSequential(const std::shared_ptrbtof_rmin&&rbtof_zmin&&zftof_rmin&&rftof_zmin&&z btof_rmin && r < btof_rmax && z > btof_zmin && z < btof_zmax) + return 1; + else if (r > ftof_rmin && r < ftof_rmax && z > ftof_zmin && z < ftof_zmax) + return 2; + else + return 0; } diff --git a/src/benchmarks/reconstruction/tof_efficiency/TofEfficiency_processor.h b/src/benchmarks/reconstruction/tof_efficiency/TofEfficiency_processor.h index 4205eba32b..d295be67ad 100644 --- a/src/benchmarks/reconstruction/tof_efficiency/TofEfficiency_processor.h +++ b/src/benchmarks/reconstruction/tof_efficiency/TofEfficiency_processor.h @@ -16,25 +16,24 @@ #include "extensions/spdlog/SpdlogMixin.h" -class TofEfficiency_processor: public JEventProcessorSequentialRoot, public eicrecon::SpdlogMixin { +class TofEfficiency_processor : public JEventProcessorSequentialRoot, public eicrecon::SpdlogMixin { private: - - // Containers for histograms - std::map m_1d_hists; - std::map m_2d_hists; + // Containers for histograms + std::map m_1d_hists; + std::map m_2d_hists; public: - TofEfficiency_processor() { SetTypeName(NAME_OF_THIS); } + TofEfficiency_processor() { SetTypeName(NAME_OF_THIS); } - void InitWithGlobalRootLock() override; - void ProcessSequential(const std::shared_ptr& event) override; - void FinishWithGlobalRootLock() override; + void InitWithGlobalRootLock() override; + void ProcessSequential(const std::shared_ptr& event) override; + void FinishWithGlobalRootLock() override; - int IsTOFHit(float x, float y, float z); + int IsTOFHit(float x, float y, float z); - TDirectory *m_dir_main; + TDirectory* m_dir_main; - TH2F * m_th2_btof_phiz; - TH2F * m_th2_ftof_rphi; - TNtuple * m_tntuple_track; + TH2F* m_th2_btof_phiz; + TH2F* m_th2_ftof_rphi; + TNtuple* m_tntuple_track; }; diff --git a/src/benchmarks/reconstruction/tof_efficiency/tof_efficiency.cc b/src/benchmarks/reconstruction/tof_efficiency/tof_efficiency.cc index 2b579d3573..315f80a8c2 100644 --- a/src/benchmarks/reconstruction/tof_efficiency/tof_efficiency.cc +++ b/src/benchmarks/reconstruction/tof_efficiency/tof_efficiency.cc @@ -8,8 +8,8 @@ #include "TofEfficiency_processor.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->Add(new TofEfficiency_processor()); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new TofEfficiency_processor()); +} } diff --git a/src/benchmarks/reconstruction/tracking_efficiency/TrackingEfficiency_processor.cc b/src/benchmarks/reconstruction/tracking_efficiency/TrackingEfficiency_processor.cc index 5b6d635cf8..6cebe269d6 100644 --- a/src/benchmarks/reconstruction/tracking_efficiency/TrackingEfficiency_processor.cc +++ b/src/benchmarks/reconstruction/tracking_efficiency/TrackingEfficiency_processor.cc @@ -29,165 +29,160 @@ //-------------------------------- // OccupancyAnalysis (Constructor) //-------------------------------- -TrackingEfficiency_processor::TrackingEfficiency_processor(JApplication *app) : - JEventProcessor(app) -{ -} +TrackingEfficiency_processor::TrackingEfficiency_processor(JApplication* app) + : JEventProcessor(app) {} //------------------ // Init //------------------ -void TrackingEfficiency_processor::Init() -{ - std::string plugin_name=("tracking_efficiency"); +void TrackingEfficiency_processor::Init() { + std::string plugin_name = ("tracking_efficiency"); - // Get JANA application - auto *app = GetApplication(); + // Get JANA application + auto* app = GetApplication(); - // Ask service locator a file to write histograms to - auto root_file_service = app->GetService(); + // Ask service locator a file to write histograms to + auto root_file_service = app->GetService(); - // Get TDirectory for histograms root file - auto globalRootLock = app->GetService(); - globalRootLock->acquire_write_lock(); - auto *file = root_file_service->GetHistFile(); - globalRootLock->release_lock(); + // Get TDirectory for histograms root file + auto globalRootLock = app->GetService(); + globalRootLock->acquire_write_lock(); + auto* file = root_file_service->GetHistFile(); + globalRootLock->release_lock(); - // Create a directory for this plugin. And subdirectories for series of histograms - m_dir_main = file->mkdir(plugin_name.c_str()); + // Create a directory for this plugin. And subdirectories for series of histograms + m_dir_main = file->mkdir(plugin_name.c_str()); - // Get logger - m_log = app->GetService()->logger(plugin_name); + // Get logger + m_log = app->GetService()->logger(plugin_name); } - //------------------ // Process //------------------ -void TrackingEfficiency_processor::Process(const std::shared_ptr& event) -{ - using namespace ROOT; - - // EXAMPLE I - // This is access to for final result of the calculation/data transformation of central detector CFKTracking: - const auto reco_particles = event->Get("ReconstructedChargedParticles"); - - m_log->debug("Tracking reconstructed particles N={}: ", reco_particles.size()); - m_log->debug(" {:<5} {:>8} {:>8} {:>8} {:>8} {:>8}","[i]", "[px]", "[py]", "[pz]", "[P]", "[P*3]"); - - for(size_t i=0; i < reco_particles.size(); i++) { - auto& particle = *(reco_particles[i]); - - double px = particle.getMomentum().x; - double py = particle.getMomentum().y; - double pz = particle.getMomentum().z; - // ROOT::Math::PxPyPzM4D p4v(px, py, pz, particle.getMass()); - ROOT::Math::Cartesian3D p(px, py, pz); - m_log->debug(" {:<5} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f}", i, px, py, pz, p.R(), p.R()*3); +void TrackingEfficiency_processor::Process(const std::shared_ptr& event) { + using namespace ROOT; + + // EXAMPLE I + // This is access to for final result of the calculation/data transformation of central detector CFKTracking: + const auto reco_particles = + event->Get("ReconstructedChargedParticles"); + + m_log->debug("Tracking reconstructed particles N={}: ", reco_particles.size()); + m_log->debug(" {:<5} {:>8} {:>8} {:>8} {:>8} {:>8}", "[i]", "[px]", "[py]", "[pz]", "[P]", + "[P*3]"); + + for (size_t i = 0; i < reco_particles.size(); i++) { + auto& particle = *(reco_particles[i]); + + double px = particle.getMomentum().x; + double py = particle.getMomentum().y; + double pz = particle.getMomentum().z; + // ROOT::Math::PxPyPzM4D p4v(px, py, pz, particle.getMass()); + ROOT::Math::Cartesian3D p(px, py, pz); + m_log->debug(" {:<5} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f}", i, px, py, pz, p.R(), + p.R() * 3); + } + + // EXAMPLE II + // This gets access to more direct ACTS results from CFKTracking + auto acts_results = event->Get("CentralCKFActsTrajectories"); + m_log->debug("ACTS Trajectories( size: {} )", std::size(acts_results)); + m_log->debug("{:>10} {:>10} {:>10} {:>10} {:>10} {:>10} {:>12} {:>12} {:>12} {:>8}", "[loc 0]", + "[loc 1]", "[phi]", "[theta]", "[q/p]", "[p]", "[err phi]", "[err th]", "[err q/p]", + "[chi2]"); + + // Loop over the trajectories + for (const auto& traj : acts_results) { + + // Get the entry index for the single trajectory + // The trajectory entry indices and the multiTrajectory + const auto& mj = traj->multiTrajectory(); + const auto& trackTips = traj->tips(); + if (trackTips.empty()) { + m_log->debug("Empty multiTrajectory."); + continue; } - // EXAMPLE II - // This gets access to more direct ACTS results from CFKTracking - auto acts_results = event->Get("CentralCKFActsTrajectories"); - m_log->debug("ACTS Trajectories( size: {} )", std::size(acts_results)); - m_log->debug("{:>10} {:>10} {:>10} {:>10} {:>10} {:>10} {:>12} {:>12} {:>12} {:>8}", - "[loc 0]","[loc 1]", "[phi]", "[theta]", "[q/p]", "[p]", "[err phi]", "[err th]", "[err q/p]", "[chi2]" ); - - // Loop over the trajectories - for (const auto& traj : acts_results) { - - // Get the entry index for the single trajectory - // The trajectory entry indices and the multiTrajectory - const auto &mj = traj->multiTrajectory(); - const auto &trackTips = traj->tips(); - if (trackTips.empty()) { - m_log->debug("Empty multiTrajectory."); - continue; - } - - const auto &trackTip = trackTips.front(); - - // Collect the trajectory summary info - auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); - if (traj->hasTrackParameters(trackTip)) { - const auto &boundParam = traj->trackParameters(trackTip); - const auto ¶meter = boundParam.parameters(); - const auto &covariance = *boundParam.covariance(); - m_log->debug("{:>10.2f} {:>10.2f} {:>10.2f} {:>10.3f} {:>10.4f} {:>10.3f} {:>12.4e} {:>12.4e} {:>12.4e} {:>8.2f}", - parameter[Acts::eBoundLoc0], - parameter[Acts::eBoundLoc1], - parameter[Acts::eBoundPhi], - parameter[Acts::eBoundTheta], - parameter[Acts::eBoundQOverP], - 1.0 / parameter[Acts::eBoundQOverP], - sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)), - sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)), - sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)), - trajState.chi2Sum); - } - } - - - // EXAMPLE III - // Loop over MC particles - auto mc_particles = event->Get("MCParticles"); - m_log->debug("MC particles N={}: ", mc_particles.size()); - m_log->debug(" {:<5} {:<6} {:<7} {:>8} {:>8} {:>8} {:>8}","[i]", "status", "[PDG]", "[px]", "[py]", "[pz]", "[P]"); - for(size_t i=0; i < mc_particles.size(); i++) { - const auto *particle=mc_particles[i]; - - // GeneratorStatus() == 1 - stable particles from MC generator. 0 - might be added by Geant4 - if(particle->getGeneratorStatus() != 1) continue; - - double px = particle->getMomentum().x; - double py = particle->getMomentum().y; - double pz = particle->getMomentum().z; - ROOT::Math::PxPyPzM4D p4v(px, py, pz, particle->getMass()); - ROOT::Math::Cartesian3D p(px, py, pz); - if(p.R()<1) continue; - - m_log->debug(" {:<5} {:<6} {:<7} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f}", i, particle->getGeneratorStatus(), particle->getPDG(), px, py, pz, p.R()); + const auto& trackTip = trackTips.front(); + + // Collect the trajectory summary info + auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); + if (traj->hasTrackParameters(trackTip)) { + const auto& boundParam = traj->trackParameters(trackTip); + const auto& parameter = boundParam.parameters(); + const auto& covariance = *boundParam.covariance(); + m_log->debug("{:>10.2f} {:>10.2f} {:>10.2f} {:>10.3f} {:>10.4f} {:>10.3f} {:>12.4e} " + "{:>12.4e} {:>12.4e} {:>8.2f}", + parameter[Acts::eBoundLoc0], parameter[Acts::eBoundLoc1], + parameter[Acts::eBoundPhi], parameter[Acts::eBoundTheta], + parameter[Acts::eBoundQOverP], 1.0 / parameter[Acts::eBoundQOverP], + sqrt(covariance(Acts::eBoundPhi, Acts::eBoundPhi)), + sqrt(covariance(Acts::eBoundTheta, Acts::eBoundTheta)), + sqrt(covariance(Acts::eBoundQOverP, Acts::eBoundQOverP)), trajState.chi2Sum); } + } + + // EXAMPLE III + // Loop over MC particles + auto mc_particles = event->Get("MCParticles"); + m_log->debug("MC particles N={}: ", mc_particles.size()); + m_log->debug(" {:<5} {:<6} {:<7} {:>8} {:>8} {:>8} {:>8}", "[i]", "status", "[PDG]", "[px]", + "[py]", "[pz]", "[P]"); + for (size_t i = 0; i < mc_particles.size(); i++) { + const auto* particle = mc_particles[i]; + + // GeneratorStatus() == 1 - stable particles from MC generator. 0 - might be added by Geant4 + if (particle->getGeneratorStatus() != 1) + continue; + + double px = particle->getMomentum().x; + double py = particle->getMomentum().y; + double pz = particle->getMomentum().z; + ROOT::Math::PxPyPzM4D p4v(px, py, pz, particle->getMass()); + ROOT::Math::Cartesian3D p(px, py, pz); + if (p.R() < 1) + continue; + + m_log->debug(" {:<5} {:<6} {:<7} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f}", i, + particle->getGeneratorStatus(), particle->getPDG(), px, py, pz, p.R()); + } } - //------------------ // Finish //------------------ -void TrackingEfficiency_processor::Finish() -{ - fmt::print("OccupancyAnalysis::Finish() called\n"); - - - - // Next we want to create several pretty canvases (with histograms drawn on "same") - // But we don't want those canvases to pop up. So we set root to batch mode - // We will restore the mode afterwards - //bool save_is_batch = gROOT->IsBatch(); - //gROOT->SetBatch(true); - - // 3D hits distribution -// auto th3_by_det_canvas = new TCanvas("th3_by_det_cnv", "Occupancy of detectors"); -// dir_main->Append(th3_by_det_canvas); -// for (auto& kv : th3_by_detector->GetMap()) { -// auto th3_hist = kv.second; -// th3_hist->Draw("same"); -// } -// th3_by_det_canvas->GetPad(0)->BuildLegend(); -// -// // Hits Z by detector -// -// // Create pretty canvases -// auto z_by_det_canvas = new TCanvas("z_by_det_cnv", "Hit Z distribution by detector"); -// dir_main->Append(z_by_det_canvas); -// th1_hits_z->Draw("PLC PFC"); -// -// for (auto& kv : th1_z_by_detector->GetMap()) { -// auto hist = kv.second; -// hist->Draw("SAME PLC PFC"); -// hist->SetFillStyle(3001); -// } -// z_by_det_canvas->GetPad(0)->BuildLegend(); -// -// gROOT->SetBatch(save_is_batch); +void TrackingEfficiency_processor::Finish() { + fmt::print("OccupancyAnalysis::Finish() called\n"); + + // Next we want to create several pretty canvases (with histograms drawn on "same") + // But we don't want those canvases to pop up. So we set root to batch mode + // We will restore the mode afterwards + //bool save_is_batch = gROOT->IsBatch(); + //gROOT->SetBatch(true); + + // 3D hits distribution + // auto th3_by_det_canvas = new TCanvas("th3_by_det_cnv", "Occupancy of detectors"); + // dir_main->Append(th3_by_det_canvas); + // for (auto& kv : th3_by_detector->GetMap()) { + // auto th3_hist = kv.second; + // th3_hist->Draw("same"); + // } + // th3_by_det_canvas->GetPad(0)->BuildLegend(); + // + // // Hits Z by detector + // + // // Create pretty canvases + // auto z_by_det_canvas = new TCanvas("z_by_det_cnv", "Hit Z distribution by detector"); + // dir_main->Append(z_by_det_canvas); + // th1_hits_z->Draw("PLC PFC"); + // + // for (auto& kv : th1_z_by_detector->GetMap()) { + // auto hist = kv.second; + // hist->Draw("SAME PLC PFC"); + // hist->SetFillStyle(3001); + // } + // z_by_det_canvas->GetPad(0)->BuildLegend(); + // + // gROOT->SetBatch(save_is_batch); } diff --git a/src/benchmarks/reconstruction/tracking_efficiency/TrackingEfficiency_processor.h b/src/benchmarks/reconstruction/tracking_efficiency/TrackingEfficiency_processor.h index 86e7b225f4..1195269571 100644 --- a/src/benchmarks/reconstruction/tracking_efficiency/TrackingEfficiency_processor.h +++ b/src/benchmarks/reconstruction/tracking_efficiency/TrackingEfficiency_processor.h @@ -9,46 +9,44 @@ #include #include -class TrackingEfficiency_processor:public JEventProcessor -{ +class TrackingEfficiency_processor : public JEventProcessor { public: - explicit TrackingEfficiency_processor(JApplication *); - ~TrackingEfficiency_processor() override = default; - - //---------------------------- - // Init - // - // This is called once before the first call to the Process method - // below. You may, for example, want to open an output file here. - // Only one thread will call this. - void Init() override; - - //---------------------------- - // Process - // - // This is called for every event. Multiple threads may call this - // simultaneously. If you write something to an output file here - // then make sure to protect it with a mutex or similar mechanism. - // Minimize what is done while locked since that directly affects - // the multi-threaded performance. - void Process(const std::shared_ptr& event) override; - - //---------------------------- - // Finish - // - // This is called once after all events have been processed. You may, - // for example, want to close an output file here. - // Only one thread will call this. - void Finish() override; + explicit TrackingEfficiency_processor(JApplication*); + ~TrackingEfficiency_processor() override = default; + + //---------------------------- + // Init + // + // This is called once before the first call to the Process method + // below. You may, for example, want to open an output file here. + // Only one thread will call this. + void Init() override; + + //---------------------------- + // Process + // + // This is called for every event. Multiple threads may call this + // simultaneously. If you write something to an output file here + // then make sure to protect it with a mutex or similar mechanism. + // Minimize what is done while locked since that directly affects + // the multi-threaded performance. + void Process(const std::shared_ptr& event) override; + + //---------------------------- + // Finish + // + // This is called once after all events have been processed. You may, + // for example, want to close an output file here. + // Only one thread will call this. + void Finish() override; private: - - TDirectory* m_dir_main; /// Main TDirectory for this plugin 'occupancy_ana' - TH1F * m_th1_prt_pz; /// MC Particles pz - TH1F * m_th1_prt_energy; /// MC Particles total E - TH1F * m_th1_prt_theta; /// MC Particles theta angle - TH1F * m_th1_prt_phi; /// MC Particles phi angle - TH2F * m_th2_prt_pxy; /// MC Particles px,py - - std::shared_ptr m_log; + TDirectory* m_dir_main; /// Main TDirectory for this plugin 'occupancy_ana' + TH1F* m_th1_prt_pz; /// MC Particles pz + TH1F* m_th1_prt_energy; /// MC Particles total E + TH1F* m_th1_prt_theta; /// MC Particles theta angle + TH1F* m_th1_prt_phi; /// MC Particles phi angle + TH2F* m_th2_prt_pxy; /// MC Particles px,py + + std::shared_ptr m_log; }; diff --git a/src/benchmarks/reconstruction/tracking_efficiency/scripts/Plot_eta.C b/src/benchmarks/reconstruction/tracking_efficiency/scripts/Plot_eta.C index c94d14c1dd..4cb936986c 100644 --- a/src/benchmarks/reconstruction/tracking_efficiency/scripts/Plot_eta.C +++ b/src/benchmarks/reconstruction/tracking_efficiency/scripts/Plot_eta.C @@ -7,131 +7,157 @@ #include #include #include -#define mpi 0.139 // 1.864 GeV/c^2 - -void Plot_eta() -{ - - //==style of the plot==== - gStyle->SetPalette(1); - gStyle->SetOptTitle(0); - gStyle->SetTitleOffset(.85,"X");gStyle->SetTitleOffset(1.0,"Y"); - gStyle->SetTitleSize(.05,"X");gStyle->SetTitleSize(.05,"Y"); - gStyle->SetLabelSize(.04,"X");gStyle->SetLabelSize(.04,"Y"); - gStyle->SetHistLineWidth(2); - gStyle->SetOptFit(1); - gStyle->SetOptStat(0); - - - TFile *f = TFile::Open("sim.edm4hep.root"); - TTree *tree = (TTree*)f->Get("events"); - - // Timer Start +#define mpi 0.139 // 1.864 GeV/c^2 + +void Plot_eta() { + + //==style of the plot==== + gStyle->SetPalette(1); + gStyle->SetOptTitle(0); + gStyle->SetTitleOffset(.85, "X"); + gStyle->SetTitleOffset(1.0, "Y"); + gStyle->SetTitleSize(.05, "X"); + gStyle->SetTitleSize(.05, "Y"); + gStyle->SetLabelSize(.04, "X"); + gStyle->SetLabelSize(.04, "Y"); + gStyle->SetHistLineWidth(2); + gStyle->SetOptFit(1); + gStyle->SetOptStat(0); + + TFile* f = TFile::Open("sim.edm4hep.root"); + TTree* tree = (TTree*)f->Get("events"); + + // Timer Start TStopwatch timer; timer.Start(); - TCanvas * c1 = new TCanvas("c1","coutput",1400,1000); - c1->SetMargin(0.10, 0.05 ,0.1,0.05); - c1->SetGridx(); - - TH1D *hits_vtx_si = new TH1D("hits_vtx_si","hits_vtx_si",200,-4.,4.); - TH1D *hits_barrel_si = new TH1D("hits_barrel_si","hits_barrel_si",200,-4.,4.); // Barr1 - TH1D *hits_barrel_mpgd_in = new TH1D("hits_barrel_mpgd_in","hits_barrel_mpgd_in",200,-4.,4.); // BMT1 - TH1D *hits_barrel_tof = new TH1D("hits_barrel_tof","hits_barrel_tof",200,-4.,4.); - TH1D *hits_disks_si = new TH1D("hits_disks_si","hits_disks_si",200,-4.,4.); - TH1D *hits_endcap_tof = new TH1D("hits_endcap_tof","hits_endcap_tof",200,-4.,4.); - TH1D *hits_barrel_mpgd_out = new TH1D("hits_barrel_mpgd_out","hits_barrel_mpgd_out",200,-4.,4.); - TH1D *hits_fwd_mpgd = new TH1D("hits_fwd_mpgd","hits_fwd_mpgd",200,-4.,4.); - TH1D *hits_bwd_mpgd = new TH1D("hits_bwd_mpgd","hits_bwd_mpgd",200,-4.,4.); - TH1D *hits_b0tracker = new TH1D("hits_b0tracker","hits_b0tracker",200,-4.,4.); - - hits_vtx_si->GetXaxis()->SetTitle("#eta"); - hits_vtx_si->GetYaxis()->SetTitle("Entries (a.u.)"); - hits_vtx_si->GetXaxis()->CenterTitle(); - hits_vtx_si->GetYaxis()->CenterTitle(); + TCanvas* c1 = new TCanvas("c1", "coutput", 1400, 1000); + c1->SetMargin(0.10, 0.05, 0.1, 0.05); + c1->SetGridx(); + + TH1D* hits_vtx_si = new TH1D("hits_vtx_si", "hits_vtx_si", 200, -4., 4.); + TH1D* hits_barrel_si = new TH1D("hits_barrel_si", "hits_barrel_si", 200, -4., 4.); // Barr1 + TH1D* hits_barrel_mpgd_in = + new TH1D("hits_barrel_mpgd_in", "hits_barrel_mpgd_in", 200, -4., 4.); // BMT1 + TH1D* hits_barrel_tof = new TH1D("hits_barrel_tof", "hits_barrel_tof", 200, -4., 4.); + TH1D* hits_disks_si = new TH1D("hits_disks_si", "hits_disks_si", 200, -4., 4.); + TH1D* hits_endcap_tof = new TH1D("hits_endcap_tof", "hits_endcap_tof", 200, -4., 4.); + TH1D* hits_barrel_mpgd_out = + new TH1D("hits_barrel_mpgd_out", "hits_barrel_mpgd_out", 200, -4., 4.); + TH1D* hits_fwd_mpgd = new TH1D("hits_fwd_mpgd", "hits_fwd_mpgd", 200, -4., 4.); + TH1D* hits_bwd_mpgd = new TH1D("hits_bwd_mpgd", "hits_bwd_mpgd", 200, -4., 4.); + TH1D* hits_b0tracker = new TH1D("hits_b0tracker", "hits_b0tracker", 200, -4., 4.); + + hits_vtx_si->GetXaxis()->SetTitle("#eta"); + hits_vtx_si->GetYaxis()->SetTitle("Entries (a.u.)"); + hits_vtx_si->GetXaxis()->CenterTitle(); + hits_vtx_si->GetYaxis()->CenterTitle(); + + TString vtx_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(VertexBarrelHits.position.x*" + "VertexBarrelHits.position.x+VertexBarrelHits.position.y*VertexBarrelHits." + "position.y),VertexBarrelHits.position.z))/2))>>hits_vtx_si"; + TString Barrel_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(SiBarrelHits.position.x*" + "SiBarrelHits.position.x+SiBarrelHits.position.y*SiBarrelHits.position." + "y),SiBarrelHits.position.z))/2))>>hits_barrel_si"; + TString BMM_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(MPGDBarrelHits.position.x*" + "MPGDBarrelHits.position.x+MPGDBarrelHits.position.y*MPGDBarrelHits." + "position.y),MPGDBarrelHits.position.z))/2))>>hits_barrel_mpgd_in"; + TString ToF_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(TOFBarrelHits.position.x*" + "TOFBarrelHits.position.x+TOFBarrelHits.position.y*TOFBarrelHits.position." + "y),TOFBarrelHits.position.z))/2))>>hits_barrel_tof"; + TString ETracker_hits_eta = + "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(TrackerEndcapHits.position.x*TrackerEndcapHits." + "position.x+TrackerEndcapHits.position.y*TrackerEndcapHits.position.y),TrackerEndcapHits." + "position.z))/2))>>hits_disks_si"; + TString ETOF_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(TOFEndcapHits.position.x*" + "TOFEndcapHits.position.x+TOFEndcapHits.position.y*TOFEndcapHits." + "position.y),TOFEndcapHits.position.z))/2))>>hits_endcap_tof"; + TString OutBMM_hits_eta = + "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(OuterMPGDBarrelHits.position.x*" + "OuterMPGDBarrelHits.position.x+OuterMPGDBarrelHits.position.y*OuterMPGDBarrelHits.position." + "y),OuterMPGDBarrelHits.position.z))/2))>>hits_barrel_mpgd_out"; + TString FwdMM_hits_eta = + "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(ForwardMPGDEndcapHits.position.x*" + "ForwardMPGDEndcapHits.position.x+ForwardMPGDEndcapHits.position.y*ForwardMPGDEndcapHits." + "position.y),ForwardMPGDEndcapHits.position.z))/2))>>hits_fwd_mpgd"; + TString BwdMM_hits_eta = + "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(BackwardMPGDEndcapHits.position.x*" + "BackwardMPGDEndcapHits.position.x+BackwardMPGDEndcapHits.position.y*BackwardMPGDEndcapHits." + "position.y),BackwardMPGDEndcapHits.position.z))/2))>>hits_bwd_mpgd"; + TString B0_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(B0TrackerHits.position.x*" + "B0TrackerHits.position.x+B0TrackerHits.position.y*B0TrackerHits.position." + "y),B0TrackerHits.position.z))/2))>>hits_b0tracker"; + + tree->Draw(vtx_hits_eta.Data(), "VertexBarrelHits.position.y>0", "goff"); // Vtx layers + tree->Draw(Barrel_hits_eta.Data(), "SiBarrelHits.position.y>0 ", "goff"); // Barrel Si layers + tree->Draw(BMM_hits_eta.Data(), "MPGDBarrelHits.position.y>0 ", "goff"); // MPGD Barrel + tree->Draw(ToF_hits_eta.Data(), "TOFBarrelHits.position.y>0", "goff"); // TOF Hits + tree->Draw(ETracker_hits_eta.Data(), "TrackerEndcapHits.position.y>0", "goff"); // Tracker Endcap + tree->Draw(ETOF_hits_eta.Data(), "TOFEndcapHits.position.y>0", "goff"); // TOF Endcap + tree->Draw(OutBMM_hits_eta.Data(), "OuterMPGDBarrelHits.position.y>0", + "goff"); // Outer Barrel MPGD + tree->Draw(FwdMM_hits_eta.Data(), "ForwardMPGDEndcapHits.position.y>0", "goff"); // Forward MPGD + tree->Draw(BwdMM_hits_eta.Data(), "BackwardMPGDEndcapHits.position.y>0", "goff"); // Forward MPGD + tree->Draw(B0_hits_eta.Data(), "B0TrackerHits.position.y>0", "goff"); // B0 Tracker - TString vtx_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(VertexBarrelHits.position.x*VertexBarrelHits.position.x+VertexBarrelHits.position.y*VertexBarrelHits.position.y),VertexBarrelHits.position.z))/2))>>hits_vtx_si"; - TString Barrel_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(SiBarrelHits.position.x*SiBarrelHits.position.x+SiBarrelHits.position.y*SiBarrelHits.position.y),SiBarrelHits.position.z))/2))>>hits_barrel_si"; - TString BMM_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(MPGDBarrelHits.position.x*MPGDBarrelHits.position.x+MPGDBarrelHits.position.y*MPGDBarrelHits.position.y),MPGDBarrelHits.position.z))/2))>>hits_barrel_mpgd_in"; - TString ToF_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(TOFBarrelHits.position.x*TOFBarrelHits.position.x+TOFBarrelHits.position.y*TOFBarrelHits.position.y),TOFBarrelHits.position.z))/2))>>hits_barrel_tof"; - TString ETracker_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(TrackerEndcapHits.position.x*TrackerEndcapHits.position.x+TrackerEndcapHits.position.y*TrackerEndcapHits.position.y),TrackerEndcapHits.position.z))/2))>>hits_disks_si"; - TString ETOF_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(TOFEndcapHits.position.x*TOFEndcapHits.position.x+TOFEndcapHits.position.y*TOFEndcapHits.position.y),TOFEndcapHits.position.z))/2))>>hits_endcap_tof"; - TString OutBMM_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(OuterMPGDBarrelHits.position.x*OuterMPGDBarrelHits.position.x+OuterMPGDBarrelHits.position.y*OuterMPGDBarrelHits.position.y),OuterMPGDBarrelHits.position.z))/2))>>hits_barrel_mpgd_out"; - TString FwdMM_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(ForwardMPGDEndcapHits.position.x*ForwardMPGDEndcapHits.position.x+ForwardMPGDEndcapHits.position.y*ForwardMPGDEndcapHits.position.y),ForwardMPGDEndcapHits.position.z))/2))>>hits_fwd_mpgd"; - TString BwdMM_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(BackwardMPGDEndcapHits.position.x*BackwardMPGDEndcapHits.position.x+BackwardMPGDEndcapHits.position.y*BackwardMPGDEndcapHits.position.y),BackwardMPGDEndcapHits.position.z))/2))>>hits_bwd_mpgd"; - TString B0_hits_eta = "-TMath::Log(TMath::Tan((TMath::ATan2(sqrt(B0TrackerHits.position.x*B0TrackerHits.position.x+B0TrackerHits.position.y*B0TrackerHits.position.y),B0TrackerHits.position.z))/2))>>hits_b0tracker"; - - tree->Draw(vtx_hits_eta.Data(),"VertexBarrelHits.position.y>0","goff"); // Vtx layers - tree->Draw(Barrel_hits_eta.Data(),"SiBarrelHits.position.y>0 ","goff"); // Barrel Si layers - tree->Draw(BMM_hits_eta.Data(),"MPGDBarrelHits.position.y>0 ","goff"); // MPGD Barrel - tree->Draw(ToF_hits_eta.Data(),"TOFBarrelHits.position.y>0","goff"); // TOF Hits - tree->Draw(ETracker_hits_eta.Data(),"TrackerEndcapHits.position.y>0","goff"); // Tracker Endcap - tree->Draw(ETOF_hits_eta.Data(),"TOFEndcapHits.position.y>0","goff"); // TOF Endcap - tree->Draw(OutBMM_hits_eta.Data(),"OuterMPGDBarrelHits.position.y>0","goff"); // Outer Barrel MPGD - tree->Draw(FwdMM_hits_eta.Data(),"ForwardMPGDEndcapHits.position.y>0","goff"); // Forward MPGD - tree->Draw(BwdMM_hits_eta.Data(),"BackwardMPGDEndcapHits.position.y>0","goff"); // Forward MPGD - tree->Draw(B0_hits_eta.Data(),"B0TrackerHits.position.y>0","goff"); // B0 Tracker - - c1->cd(); - c1->SetLogy(); - hits_vtx_si->Scale(1./hits_vtx_si->Integral()); - hits_barrel_si->Scale(1./hits_barrel_si->Integral()); - hits_barrel_mpgd_in->Scale(1./hits_barrel_mpgd_in->Integral()); - hits_barrel_tof->Scale(1./hits_barrel_tof->Integral()); - hits_disks_si->Scale(1./hits_disks_si->Integral()); - hits_endcap_tof->Scale(1./hits_endcap_tof->Integral()); - hits_barrel_mpgd_out->Scale(1./hits_barrel_mpgd_out->Integral()); - hits_fwd_mpgd->Scale(1./hits_fwd_mpgd->Integral()); - hits_bwd_mpgd->Scale(1./hits_bwd_mpgd->Integral()); - hits_b0tracker->Scale(1./hits_b0tracker->Integral()); - hits_vtx_si->SetLineColor(kBlue); - hits_barrel_si->SetLineColor(kMagenta); - hits_barrel_mpgd_in->SetLineColor(kRed); - hits_barrel_tof->SetLineColor(kBlack); - hits_disks_si->SetLineColor(kGreen); - hits_endcap_tof->SetLineColor(kCyan); - hits_barrel_mpgd_out->SetLineColor(kOrange); - hits_fwd_mpgd->SetLineColor(kAzure); - hits_bwd_mpgd->SetLineColor(kTeal); - hits_b0tracker->SetLineColor(kViolet); - - - hits_vtx_si->SetMaximum(0.2); - hits_vtx_si->GetXaxis()->SetRangeUser(-4.0,4.0); - hits_vtx_si->Draw("hist"); - hits_barrel_si->Draw("hist-same"); - hits_barrel_mpgd_in->Draw("hist-same"); - hits_barrel_tof->Draw("hist-same"); - hits_disks_si->Draw("hist-same"); - hits_endcap_tof->Draw("hist-same"); - hits_barrel_mpgd_out->Draw("hist-same"); - hits_fwd_mpgd->Draw("hist-same"); - hits_bwd_mpgd->Draw("hist-same"); - hits_b0tracker->Draw("hist-same"); - - TLegend *l1= new TLegend(0.11,0.75,0.70,0.94); + c1->cd(); + c1->SetLogy(); + hits_vtx_si->Scale(1. / hits_vtx_si->Integral()); + hits_barrel_si->Scale(1. / hits_barrel_si->Integral()); + hits_barrel_mpgd_in->Scale(1. / hits_barrel_mpgd_in->Integral()); + hits_barrel_tof->Scale(1. / hits_barrel_tof->Integral()); + hits_disks_si->Scale(1. / hits_disks_si->Integral()); + hits_endcap_tof->Scale(1. / hits_endcap_tof->Integral()); + hits_barrel_mpgd_out->Scale(1. / hits_barrel_mpgd_out->Integral()); + hits_fwd_mpgd->Scale(1. / hits_fwd_mpgd->Integral()); + hits_bwd_mpgd->Scale(1. / hits_bwd_mpgd->Integral()); + hits_b0tracker->Scale(1. / hits_b0tracker->Integral()); + hits_vtx_si->SetLineColor(kBlue); + hits_barrel_si->SetLineColor(kMagenta); + hits_barrel_mpgd_in->SetLineColor(kRed); + hits_barrel_tof->SetLineColor(kBlack); + hits_disks_si->SetLineColor(kGreen); + hits_endcap_tof->SetLineColor(kCyan); + hits_barrel_mpgd_out->SetLineColor(kOrange); + hits_fwd_mpgd->SetLineColor(kAzure); + hits_bwd_mpgd->SetLineColor(kTeal); + hits_b0tracker->SetLineColor(kViolet); + + hits_vtx_si->SetMaximum(0.2); + hits_vtx_si->GetXaxis()->SetRangeUser(-4.0, 4.0); + hits_vtx_si->Draw("hist"); + hits_barrel_si->Draw("hist-same"); + hits_barrel_mpgd_in->Draw("hist-same"); + hits_barrel_tof->Draw("hist-same"); + hits_disks_si->Draw("hist-same"); + hits_endcap_tof->Draw("hist-same"); + hits_barrel_mpgd_out->Draw("hist-same"); + hits_fwd_mpgd->Draw("hist-same"); + hits_bwd_mpgd->Draw("hist-same"); + hits_b0tracker->Draw("hist-same"); + + TLegend* l1 = new TLegend(0.11, 0.75, 0.70, 0.94); l1->SetNColumns(2); l1->SetTextSize(0.025); l1->SetBorderSize(0); - l1->AddEntry(hits_vtx_si,"VertexBarrelHits"); - l1->AddEntry(hits_barrel_si,"SiBarrelHits"); - l1->AddEntry(hits_barrel_mpgd_in,"MPGDBarrelHits"); - l1->AddEntry(hits_barrel_tof,"TOFBarrelHits"); - l1->AddEntry(hits_disks_si,"TrackerEndcapHits"); - l1->AddEntry(hits_endcap_tof,"TOFEndcapHits"); - l1->AddEntry(hits_barrel_mpgd_out,"OuterMPGDBarrelHits"); - l1->AddEntry(hits_fwd_mpgd,"ForwardMPGDEndcapHits"); - l1->AddEntry(hits_bwd_mpgd,"BackwardMPGDEndcapHits"); - l1->AddEntry(hits_b0tracker,"B0TrackerHits"); + l1->AddEntry(hits_vtx_si, "VertexBarrelHits"); + l1->AddEntry(hits_barrel_si, "SiBarrelHits"); + l1->AddEntry(hits_barrel_mpgd_in, "MPGDBarrelHits"); + l1->AddEntry(hits_barrel_tof, "TOFBarrelHits"); + l1->AddEntry(hits_disks_si, "TrackerEndcapHits"); + l1->AddEntry(hits_endcap_tof, "TOFEndcapHits"); + l1->AddEntry(hits_barrel_mpgd_out, "OuterMPGDBarrelHits"); + l1->AddEntry(hits_fwd_mpgd, "ForwardMPGDEndcapHits"); + l1->AddEntry(hits_bwd_mpgd, "BackwardMPGDEndcapHits"); + l1->AddEntry(hits_b0tracker, "B0TrackerHits"); l1->Draw("same"); c1->cd(); l1->Draw(); c1->SaveAs("eta_DD4HEP.png"); - // Timer Stop + // Timer Stop timer.Stop(); Double_t realtime = timer.RealTime(); - Double_t cputime = timer.CpuTime(); - printf("RealTime=%f seconds, CpuTime=%f seconds\n",realtime,cputime); - + Double_t cputime = timer.CpuTime(); + printf("RealTime=%f seconds, CpuTime=%f seconds\n", realtime, cputime); } diff --git a/src/benchmarks/reconstruction/tracking_efficiency/scripts/draw_Performance.C b/src/benchmarks/reconstruction/tracking_efficiency/scripts/draw_Performance.C index 1606569efa..78ecad12a8 100644 --- a/src/benchmarks/reconstruction/tracking_efficiency/scripts/draw_Performance.C +++ b/src/benchmarks/reconstruction/tracking_efficiency/scripts/draw_Performance.C @@ -8,152 +8,159 @@ #include #include -void draw_Performance(Int_t nevent=-1) -{ - -//==========Style of the plot============ - gStyle->SetPalette(1); - gStyle->SetOptTitle(1); - gStyle->SetTitleOffset(.85,"X");gStyle->SetTitleOffset(.85,"Y"); - gStyle->SetTitleSize(.04,"X");gStyle->SetTitleSize(.04,"Y"); - gStyle->SetLabelSize(.04,"X");gStyle->SetLabelSize(.04,"Y"); - gStyle->SetHistLineWidth(2); - gStyle->SetOptFit(1); - gStyle->SetOptStat(0); - -//=======Reading the root file DD4HEP=========== - TFile* file = new TFile("tracking_test_gun.edm4eic.root"); // Tree with tracks and hits - // Create the tree reader and its data containers - TTreeReader myReader("events", file); // name of tree and file - - TTreeReaderArray charge(myReader, "MCParticles.charge"); - TTreeReaderArray vx_mc(myReader, "MCParticles.vertex.x"); - TTreeReaderArray vy_mc(myReader, "MCParticles.vertex.y"); - TTreeReaderArray vz_mc(myReader, "MCParticles.vertex.z"); - TTreeReaderArray px_mc(myReader, "MCParticles.momentum.x"); - TTreeReaderArray py_mc(myReader, "MCParticles.momentum.y"); - TTreeReaderArray pz_mc(myReader, "MCParticles.momentum.z"); - TTreeReaderArray status(myReader, "MCParticles.generatorStatus"); - TTreeReaderArray pdg(myReader, "MCParticles.PDG"); - - TTreeReaderArray px_rec(myReader, "ReconstructedChargedParticles.momentum.x"); - TTreeReaderArray py_rec(myReader, "ReconstructedChargedParticles.momentum.y"); - TTreeReaderArray pz_rec(myReader, "ReconstructedChargedParticles.momentum.z"); - - const int ngraph = 7; - TCanvas * c[ngraph]; - for (int i =0; iSetMargin(0.09, 0.1 ,0.1,0.06); - } - - // X-Y Hits - - Int_t nbins = 200; - Double_t x= 4.0; - TH2D *hetavspmc = new TH2D("hetavspmc","hetavspmc",400,0.,40.,nbins,-x,x); - TH2D *hetavsprec = new TH2D("hetavsprec","hetavsprec",400,0.,40.,nbins,-x,x); - TH2D *heff_pnum = new TH2D("heff_pnum","heff_p",400,0.,40.,nbins,-x,x); - TH2D *heff_pden = new TH2D("heff_pden","heff_p",400,0.,40.,nbins,-x,x); - - TH2D *hetavsptmc = new TH2D("hetavsptmc","hetavsptmc",400,0.,40.,nbins,-x,x); - TH2D *hetavsptrec = new TH2D("hetavsptrec","hetavsptrec",400,0.,40.,nbins,-x,x); - TH2D *heff_ptnum = new TH2D("heff_ptnum","heff_p",400,0.,40.,nbins,-x,x); - TH2D *heff_ptden = new TH2D("heff_ptden","heff_p",400,0.,40.,nbins,-x,x); - - TH1D *hpresol = new TH1D("hpresol","hpresol",200,-0.5,0.5); - - hetavspmc->GetXaxis()->SetTitle("p_{mc} (GeV/c)"); - hetavspmc->GetYaxis()->SetTitle("#eta_{mc}"); - hetavspmc->GetXaxis()->CenterTitle(); - hetavspmc->GetYaxis()->CenterTitle(); - - hetavsptmc->GetXaxis()->SetTitle("pt_{mc} (GeV/c)"); - hetavsptmc->GetYaxis()->SetTitle("#eta_{mc}"); - hetavsptmc->GetXaxis()->CenterTitle(); - hetavsptmc->GetYaxis()->CenterTitle(); - - hetavsprec->GetXaxis()->SetTitle("p_{rec} (GeV/c)"); - hetavsprec->GetYaxis()->SetTitle("#eta_{rec}"); - hetavsprec->GetXaxis()->CenterTitle(); - hetavsprec->GetYaxis()->CenterTitle(); - - hetavsptrec->GetXaxis()->SetTitle("pt_{rec} (GeV/c)"); - hetavsptrec->GetYaxis()->SetTitle("#eta_{rec}"); - hetavsptrec->GetXaxis()->CenterTitle(); - hetavsptrec->GetYaxis()->CenterTitle(); - - hpresol->GetXaxis()->SetTitle("dp/p"); - hpresol->GetYaxis()->SetTitle("Entries (a.u.)"); - hpresol->GetXaxis()->CenterTitle(); - hpresol->GetYaxis()->CenterTitle(); - - -////////////////////////////////////////////////////////////////////// - int count = 0; - while (myReader.Next()) - { - if (nevent>0 && count>nevent) continue; - // cout<<"=====Event No. "<Fill(pmc,etamc); - hetavsptmc->Fill(ptmc,etamc); - heff_pden->Fill(pmc,etamc); - heff_ptden->Fill(ptmc,etamc); - if (px_rec.GetSize()==1){ - Double_t prec = sqrt(px_rec[iParticle]*px_rec[iParticle]+py_rec[iParticle]*py_rec[iParticle]+pz_rec[iParticle]*pz_rec[iParticle]); - Double_t ptrec = sqrt(px_rec[iParticle]*px_rec[iParticle]+py_rec[iParticle]*py_rec[iParticle]); - Double_t etarec = -1.0*TMath::Log(TMath::Tan((TMath::ACos(pz_rec[iParticle]/prec))/2)); - hetavsprec->Fill(prec,etarec); - hetavsptrec->Fill(ptrec,etarec); - hpresol->Fill((prec-pmc)/pmc); - heff_pnum->Fill(pmc,etamc); - heff_ptnum->Fill(ptmc,etamc); - } - } - } +void draw_Performance(Int_t nevent = -1) { + + //==========Style of the plot============ + gStyle->SetPalette(1); + gStyle->SetOptTitle(1); + gStyle->SetTitleOffset(.85, "X"); + gStyle->SetTitleOffset(.85, "Y"); + gStyle->SetTitleSize(.04, "X"); + gStyle->SetTitleSize(.04, "Y"); + gStyle->SetLabelSize(.04, "X"); + gStyle->SetLabelSize(.04, "Y"); + gStyle->SetHistLineWidth(2); + gStyle->SetOptFit(1); + gStyle->SetOptStat(0); + + //=======Reading the root file DD4HEP=========== + TFile* file = new TFile("tracking_test_gun.edm4eic.root"); // Tree with tracks and hits + // Create the tree reader and its data containers + TTreeReader myReader("events", file); // name of tree and file + + TTreeReaderArray charge(myReader, "MCParticles.charge"); + TTreeReaderArray vx_mc(myReader, "MCParticles.vertex.x"); + TTreeReaderArray vy_mc(myReader, "MCParticles.vertex.y"); + TTreeReaderArray vz_mc(myReader, "MCParticles.vertex.z"); + TTreeReaderArray px_mc(myReader, "MCParticles.momentum.x"); + TTreeReaderArray py_mc(myReader, "MCParticles.momentum.y"); + TTreeReaderArray pz_mc(myReader, "MCParticles.momentum.z"); + TTreeReaderArray status(myReader, "MCParticles.generatorStatus"); + TTreeReaderArray pdg(myReader, "MCParticles.PDG"); + + TTreeReaderArray px_rec(myReader, "ReconstructedChargedParticles.momentum.x"); + TTreeReaderArray py_rec(myReader, "ReconstructedChargedParticles.momentum.y"); + TTreeReaderArray pz_rec(myReader, "ReconstructedChargedParticles.momentum.z"); + + const int ngraph = 7; + TCanvas* c[ngraph]; + for (int i = 0; i < ngraph; ++i) { + c[i] = new TCanvas(Form("c%d", i), Form("c%d", i), 1200, 1000); + c[i]->SetMargin(0.09, 0.1, 0.1, 0.06); + } - count++; + // X-Y Hits + + Int_t nbins = 200; + Double_t x = 4.0; + TH2D* hetavspmc = new TH2D("hetavspmc", "hetavspmc", 400, 0., 40., nbins, -x, x); + TH2D* hetavsprec = new TH2D("hetavsprec", "hetavsprec", 400, 0., 40., nbins, -x, x); + TH2D* heff_pnum = new TH2D("heff_pnum", "heff_p", 400, 0., 40., nbins, -x, x); + TH2D* heff_pden = new TH2D("heff_pden", "heff_p", 400, 0., 40., nbins, -x, x); + + TH2D* hetavsptmc = new TH2D("hetavsptmc", "hetavsptmc", 400, 0., 40., nbins, -x, x); + TH2D* hetavsptrec = new TH2D("hetavsptrec", "hetavsptrec", 400, 0., 40., nbins, -x, x); + TH2D* heff_ptnum = new TH2D("heff_ptnum", "heff_p", 400, 0., 40., nbins, -x, x); + TH2D* heff_ptden = new TH2D("heff_ptden", "heff_p", 400, 0., 40., nbins, -x, x); + + TH1D* hpresol = new TH1D("hpresol", "hpresol", 200, -0.5, 0.5); + + hetavspmc->GetXaxis()->SetTitle("p_{mc} (GeV/c)"); + hetavspmc->GetYaxis()->SetTitle("#eta_{mc}"); + hetavspmc->GetXaxis()->CenterTitle(); + hetavspmc->GetYaxis()->CenterTitle(); + + hetavsptmc->GetXaxis()->SetTitle("pt_{mc} (GeV/c)"); + hetavsptmc->GetYaxis()->SetTitle("#eta_{mc}"); + hetavsptmc->GetXaxis()->CenterTitle(); + hetavsptmc->GetYaxis()->CenterTitle(); + + hetavsprec->GetXaxis()->SetTitle("p_{rec} (GeV/c)"); + hetavsprec->GetYaxis()->SetTitle("#eta_{rec}"); + hetavsprec->GetXaxis()->CenterTitle(); + hetavsprec->GetYaxis()->CenterTitle(); + + hetavsptrec->GetXaxis()->SetTitle("pt_{rec} (GeV/c)"); + hetavsptrec->GetYaxis()->SetTitle("#eta_{rec}"); + hetavsptrec->GetXaxis()->CenterTitle(); + hetavsptrec->GetYaxis()->CenterTitle(); + + hpresol->GetXaxis()->SetTitle("dp/p"); + hpresol->GetYaxis()->SetTitle("Entries (a.u.)"); + hpresol->GetXaxis()->CenterTitle(); + hpresol->GetYaxis()->CenterTitle(); + + ////////////////////////////////////////////////////////////////////// + int count = 0; + while (myReader.Next()) { + if (nevent > 0 && count > nevent) + continue; + // cout<<"=====Event No. "<Fill(pmc, etamc); + hetavsptmc->Fill(ptmc, etamc); + heff_pden->Fill(pmc, etamc); + heff_ptden->Fill(ptmc, etamc); + if (px_rec.GetSize() == 1) { + Double_t prec = + sqrt(px_rec[iParticle] * px_rec[iParticle] + py_rec[iParticle] * py_rec[iParticle] + + pz_rec[iParticle] * pz_rec[iParticle]); + Double_t ptrec = + sqrt(px_rec[iParticle] * px_rec[iParticle] + py_rec[iParticle] * py_rec[iParticle]); + Double_t etarec = + -1.0 * TMath::Log(TMath::Tan((TMath::ACos(pz_rec[iParticle] / prec)) / 2)); + hetavsprec->Fill(prec, etarec); + hetavsptrec->Fill(ptrec, etarec); + hpresol->Fill((prec - pmc) / pmc); + heff_pnum->Fill(pmc, etamc); + heff_ptnum->Fill(ptmc, etamc); + } + } + } + count++; } - heff_pnum->Divide(heff_pden); - heff_ptnum->Divide(heff_ptden); - heff_pnum->GetYaxis()->SetTitle("Acceptance"); - heff_pnum->GetXaxis()->SetTitle("p_mc"); - heff_pnum->GetZaxis()->SetRangeUser(0.,1.1); - - heff_ptnum->GetYaxis()->SetTitle("Acceptance"); - heff_ptnum->GetXaxis()->SetTitle("pt_mc"); - heff_ptnum->GetZaxis()->SetRangeUser(0.,1.1); - - c[0]->cd(); - hetavspmc->Draw("colz"); - c[0]->SaveAs("eta_mcvspmc.png"); - c[1]->cd(); - hetavsprec->Draw("colz"); - c[1]->SaveAs("eta_mcvsprec.png"); - c[2]->cd(); - hetavsptmc->Draw("colz"); - c[2]->SaveAs("eta_mcvsptmc.png"); - c[3]->cd(); - hetavsptrec->Draw("colz"); - c[3]->SaveAs("eta_mcvsptrec.png"); - c[4]->cd(); - hpresol->Draw("hist"); - c[4]->SaveAs("ptresol.png"); - c[5]->cd(); - heff_pnum->Draw("colz"); - c[5]->SaveAs("effvsp_2D.png"); - c[6]->cd(); - heff_ptnum->Draw("colz"); - c[6]->SaveAs("effvspt_2D.png"); - + heff_pnum->Divide(heff_pden); + heff_ptnum->Divide(heff_ptden); + heff_pnum->GetYaxis()->SetTitle("Acceptance"); + heff_pnum->GetXaxis()->SetTitle("p_mc"); + heff_pnum->GetZaxis()->SetRangeUser(0., 1.1); + + heff_ptnum->GetYaxis()->SetTitle("Acceptance"); + heff_ptnum->GetXaxis()->SetTitle("pt_mc"); + heff_ptnum->GetZaxis()->SetRangeUser(0., 1.1); + + c[0]->cd(); + hetavspmc->Draw("colz"); + c[0]->SaveAs("eta_mcvspmc.png"); + c[1]->cd(); + hetavsprec->Draw("colz"); + c[1]->SaveAs("eta_mcvsprec.png"); + c[2]->cd(); + hetavsptmc->Draw("colz"); + c[2]->SaveAs("eta_mcvsptmc.png"); + c[3]->cd(); + hetavsptrec->Draw("colz"); + c[3]->SaveAs("eta_mcvsptrec.png"); + c[4]->cd(); + hpresol->Draw("hist"); + c[4]->SaveAs("ptresol.png"); + c[5]->cd(); + heff_pnum->Draw("colz"); + c[5]->SaveAs("effvsp_2D.png"); + c[6]->cd(); + heff_ptnum->Draw("colz"); + c[6]->SaveAs("effvspt_2D.png"); } diff --git a/src/benchmarks/reconstruction/tracking_efficiency/scripts/draw_hits.C b/src/benchmarks/reconstruction/tracking_efficiency/scripts/draw_hits.C index e5628cc09b..f2dce2abbb 100644 --- a/src/benchmarks/reconstruction/tracking_efficiency/scripts/draw_hits.C +++ b/src/benchmarks/reconstruction/tracking_efficiency/scripts/draw_hits.C @@ -8,301 +8,372 @@ #include #include -void draw_hits() -{ - -//==========Style of the plot============ - gStyle->SetPalette(1); - gStyle->SetOptTitle(1); - gStyle->SetTitleOffset(.85,"X");gStyle->SetTitleOffset(.85,"Y"); - gStyle->SetTitleSize(.04,"X");gStyle->SetTitleSize(.04,"Y"); - gStyle->SetLabelSize(.04,"X");gStyle->SetLabelSize(.04,"Y"); - gStyle->SetHistLineWidth(2); - gStyle->SetOptFit(1); - gStyle->SetOptStat(0); - -//=======Reading the root file DD4HEP=========== - TFile *f = TFile::Open("sim.edm4hep.root"); - TTree *sim = (TTree*)f->Get("events"); - - // Timer Start +void draw_hits() { + + //==========Style of the plot============ + gStyle->SetPalette(1); + gStyle->SetOptTitle(1); + gStyle->SetTitleOffset(.85, "X"); + gStyle->SetTitleOffset(.85, "Y"); + gStyle->SetTitleSize(.04, "X"); + gStyle->SetTitleSize(.04, "Y"); + gStyle->SetLabelSize(.04, "X"); + gStyle->SetLabelSize(.04, "Y"); + gStyle->SetHistLineWidth(2); + gStyle->SetOptFit(1); + gStyle->SetOptStat(0); + + //=======Reading the root file DD4HEP=========== + TFile* f = TFile::Open("sim.edm4hep.root"); + TTree* sim = (TTree*)f->Get("events"); + + // Timer Start TStopwatch timer; timer.Start(); - TCanvas *c1 = new TCanvas("c1","c1",1200,1000); - c1->SetMargin(0.09, 0.03 ,0.1,0.06); + TCanvas* c1 = new TCanvas("c1", "c1", 1200, 1000); + c1->SetMargin(0.09, 0.03, 0.1, 0.06); - // X-Y Hits + // X-Y Hits Int_t nbins = 320; - Double_t x= 100., y = 100.; - TH2D *hitsxy_vtx_si = new TH2D("hitsxy_vtx_si","hitsxy_vtx_si",nbins,-x,x,nbins,-y,y); - TH2D *hitsxy_barrel_si = new TH2D("hitsxy_barrel_si","hitsxy_barrel_si",nbins,-x,x,nbins,-y,y); - TH2D *hitsxy_barrel_mm_in = new TH2D("hitsxy_barrel_mm_in","hitsxy_barrel_mm_in",nbins,-x,x,nbins,-y,y); - TH2D *hitsxy_barrel_tof = new TH2D("hitsxy_barrel_tof","hitsxy_barrel_tof",nbins,-x,x,nbins,-y,y); - TH2D *hitsxy_barrel_mm_out = new TH2D("hitsxy_barrel_mm_out","hitsxy_barrel_mm_out",nbins,-x,x,nbins,-y,y); - - TString si_vtx_hitsXY ="VertexBarrelHits.position.y*0.1:VertexBarrelHits.position.x*0.1>>hitsxy_vtx_si"; - TString si_barrel_hitsXY ="SiBarrelHits.position.y*0.1:SiBarrelHits.position.x*0.1>>hitsxy_barrel_si"; - TString barrel_mpgd_in_hitsXY ="MPGDBarrelHits.position.y*0.1:MPGDBarrelHits.position.x*0.1>>hitsxy_barrel_mm_in"; - TString tof_barrel_hitsXY ="TOFBarrelHits.position.y*0.1:TOFBarrelHits.position.x*0.1>>hitsxy_barrel_tof"; - TString barrel_mpgd_out_hitsXY ="OuterMPGDBarrelHits.position.y*0.1:OuterMPGDBarrelHits.position.x*0.1>>hitsxy_barrel_mm_out"; - - sim->Draw(si_vtx_hitsXY.Data(),"",""); // Multiply by 0.1 for cm - sim->Draw(si_barrel_hitsXY.Data(),"",""); - sim->Draw(barrel_mpgd_in_hitsXY.Data(),"",""); - sim->Draw(tof_barrel_hitsXY.Data(),"",""); - sim->Draw(barrel_mpgd_out_hitsXY.Data(),"",""); - - hitsxy_vtx_si->SetMarkerStyle(31); - hitsxy_vtx_si->SetTitle("Hit Points (XY)"); - hitsxy_vtx_si->SetMarkerColor(kBlack); - hitsxy_vtx_si->SetMarkerSize(0.1); - hitsxy_vtx_si->SetLineColor(kBlack); - hitsxy_vtx_si->GetXaxis()->SetTitle("X [cm]"); - hitsxy_vtx_si->GetYaxis()->SetTitle("Y [cm]"); - hitsxy_vtx_si->GetXaxis()->CenterTitle(); - hitsxy_vtx_si->GetYaxis()->CenterTitle(); + Double_t x = 100., y = 100.; + TH2D* hitsxy_vtx_si = new TH2D("hitsxy_vtx_si", "hitsxy_vtx_si", nbins, -x, x, nbins, -y, y); + TH2D* hitsxy_barrel_si = + new TH2D("hitsxy_barrel_si", "hitsxy_barrel_si", nbins, -x, x, nbins, -y, y); + TH2D* hitsxy_barrel_mm_in = + new TH2D("hitsxy_barrel_mm_in", "hitsxy_barrel_mm_in", nbins, -x, x, nbins, -y, y); + TH2D* hitsxy_barrel_tof = + new TH2D("hitsxy_barrel_tof", "hitsxy_barrel_tof", nbins, -x, x, nbins, -y, y); + TH2D* hitsxy_barrel_mm_out = + new TH2D("hitsxy_barrel_mm_out", "hitsxy_barrel_mm_out", nbins, -x, x, nbins, -y, y); + + TString si_vtx_hitsXY = + "VertexBarrelHits.position.y*0.1:VertexBarrelHits.position.x*0.1>>hitsxy_vtx_si"; + TString si_barrel_hitsXY = + "SiBarrelHits.position.y*0.1:SiBarrelHits.position.x*0.1>>hitsxy_barrel_si"; + TString barrel_mpgd_in_hitsXY = + "MPGDBarrelHits.position.y*0.1:MPGDBarrelHits.position.x*0.1>>hitsxy_barrel_mm_in"; + TString tof_barrel_hitsXY = + "TOFBarrelHits.position.y*0.1:TOFBarrelHits.position.x*0.1>>hitsxy_barrel_tof"; + TString barrel_mpgd_out_hitsXY = + "OuterMPGDBarrelHits.position.y*0.1:OuterMPGDBarrelHits.position.x*0.1>>hitsxy_barrel_mm_out"; + + sim->Draw(si_vtx_hitsXY.Data(), "", ""); // Multiply by 0.1 for cm + sim->Draw(si_barrel_hitsXY.Data(), "", ""); + sim->Draw(barrel_mpgd_in_hitsXY.Data(), "", ""); + sim->Draw(tof_barrel_hitsXY.Data(), "", ""); + sim->Draw(barrel_mpgd_out_hitsXY.Data(), "", ""); + + hitsxy_vtx_si->SetMarkerStyle(31); + hitsxy_vtx_si->SetTitle("Hit Points (XY)"); + hitsxy_vtx_si->SetMarkerColor(kBlack); + hitsxy_vtx_si->SetMarkerSize(0.1); + hitsxy_vtx_si->SetLineColor(kBlack); + hitsxy_vtx_si->GetXaxis()->SetTitle("X [cm]"); + hitsxy_vtx_si->GetYaxis()->SetTitle("Y [cm]"); + hitsxy_vtx_si->GetXaxis()->CenterTitle(); + hitsxy_vtx_si->GetYaxis()->CenterTitle(); hitsxy_barrel_si->SetMarkerStyle(20); - hitsxy_barrel_si->SetMarkerSize(0.1); - hitsxy_barrel_si->SetMarkerColor(kMagenta); - hitsxy_barrel_si->SetLineColor(kMagenta); + hitsxy_barrel_si->SetMarkerSize(0.1); + hitsxy_barrel_si->SetMarkerColor(kMagenta); + hitsxy_barrel_si->SetLineColor(kMagenta); hitsxy_barrel_mm_in->SetMarkerStyle(20); - hitsxy_barrel_mm_in->SetMarkerSize(0.1); - hitsxy_barrel_mm_in->SetMarkerColor(kBlue); - hitsxy_barrel_mm_in->SetLineColor(kBlue); + hitsxy_barrel_mm_in->SetMarkerSize(0.1); + hitsxy_barrel_mm_in->SetMarkerColor(kBlue); + hitsxy_barrel_mm_in->SetLineColor(kBlue); hitsxy_barrel_tof->SetMarkerStyle(20); - hitsxy_barrel_tof->SetMarkerSize(0.1); - hitsxy_barrel_tof->SetMarkerColor(kGreen); - hitsxy_barrel_tof->SetLineColor(kGreen);hitsxy_barrel_mm_out->SetMarkerStyle(20); - hitsxy_barrel_mm_out->SetMarkerSize(0.1); - hitsxy_barrel_mm_out->SetMarkerColor(kBlue-7); - hitsxy_barrel_mm_out->SetLineColor(kBlue-7); - c1->cd(); + hitsxy_barrel_tof->SetMarkerSize(0.1); + hitsxy_barrel_tof->SetMarkerColor(kGreen); + hitsxy_barrel_tof->SetLineColor(kGreen); + hitsxy_barrel_mm_out->SetMarkerStyle(20); + hitsxy_barrel_mm_out->SetMarkerSize(0.1); + hitsxy_barrel_mm_out->SetMarkerColor(kBlue - 7); + hitsxy_barrel_mm_out->SetLineColor(kBlue - 7); + c1->cd(); hitsxy_vtx_si->Draw(); hitsxy_barrel_si->Draw("same"); hitsxy_barrel_mm_in->Draw("same"); hitsxy_barrel_tof->Draw("same"); - hitsxy_barrel_mm_out->Draw("same"); - - TLegend *l= new TLegend(0.65,0.85,0.90,1.0); - l->SetTextSize(0.025); - l->SetBorderSize(0); - l->AddEntry(hitsxy_vtx_si,"VertexBarrelHits"); - l->AddEntry(hitsxy_barrel_si,"SiBarrelHits"); - l->AddEntry(hitsxy_barrel_mm_in,"MPGDBarrelHits"); - l->AddEntry(hitsxy_barrel_tof,"TOFBarrelHits"); - l->AddEntry(hitsxy_barrel_mm_out,"OuterMPGDBarrelHits"); - l->Draw(); - c1->SaveAs("hitsxy_dd4hep.png"); - - TCanvas *c2 = new TCanvas("c2","c2",1200,1000); - c2->SetMargin(0.09, 0.03 ,0.1,0.06); - // Y-Z Hits - Int_t nbinsx = 400, nbinsy=1800.; - x= 200.; y = 90.; - double xmin = -200.; - - TH2D *hitsrz_vtx_si = new TH2D("hitsrz_vtx_si","hitsrz_vtx_si",nbinsx,xmin,x,nbinsy,-y,y); - TH2D *hitsrz_barrel_si = new TH2D("hitsrz_barrel_si","hitsrz_barrel_si",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_barrel_mm_in = new TH2D("hitsrz_barrel_mm_in","hitsrz_barrel_mm_in",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_barrel_mm_out = new TH2D("hitsrz_barrel_mm_out","hitsrz_barrel_mm_out",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_barrel_tof = new TH2D("hitsrz_barrel_tof","hitsrz_barrel_tof",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_disks_si = new TH2D("hitsrz_disks_si","hitsrz_disks_si",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_endcap_tof = new TH2D("hitsrz_endcap_tof","hitsrz_endcap_tof",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_fwd_mpgd = new TH2D("hitsrz_fwd_mpgd","hitsrz_fwd_mpgd",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_bwd_mpgd = new TH2D("hitsrz_bwd_mpgd","hitsrz_bwd_mpgd",nbinsx,-x,x,nbinsy,-y,y); - - TH2D *hitsrz_vtx_si_1 = new TH2D("hitsrz_vtx_si_1","hitsrz_vtx_si_1",nbinsx,xmin,x,nbinsy,-y,y); - TH2D *hitsrz_barrel_si_1 = new TH2D("hitsrz_barrel_si_1","hitsrz_barrel_si_1",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_barrel_mm_in_1 = new TH2D("hitsrz_barrel_mm_in_1","hitsrz_barrel_mm_in_1",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_barrel_mm_out_1 = new TH2D("hitsrz_barrel_mm_out_1","hitsrz_barrel_mm_out_1",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_barrel_tof_1 = new TH2D("hitsrz_barrel_tof_1","hitsrz_barrel_tof_1",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_disks_si_1 = new TH2D("hitsrz_disks_si_1","hitsrz_disks_si_1",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_endcap_tof_1 = new TH2D("hitsrz_endcap_tof_1","hitsrz_endcap_tof_1",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_fwd_mpgd_1 = new TH2D("hitsrz_fwd_mpgd_1","hitsrz_fwd_mpgd_1",nbinsx,-x,x,nbinsy,-y,y); - TH2D *hitsrz_bwd_mpgd_1 = new TH2D("hitsrz_bwd_mpgd_1","hitsrz_bwd_mpgd_1",nbinsx,-x,x,nbinsy,-y,y); - - TString si_vtx_hitsrz_posR ="sqrt(VertexBarrelHits.position.x*VertexBarrelHits.position.x+VertexBarrelHits.position.y*VertexBarrelHits.position.y)*0.1:VertexBarrelHits.position.z*0.1>>hitsrz_vtx_si"; - - TString si_barrel_hitsrz_posR ="sqrt(SiBarrelHits.position.x*SiBarrelHits.position.x+SiBarrelHits.position.y*SiBarrelHits.position.y)*0.1:SiBarrelHits.position.z*0.1>>hitsrz_barrel_si"; - - TString barrel_mpgd_in_hitsrz_posR= "sqrt(MPGDBarrelHits.position.x*MPGDBarrelHits.position.x+MPGDBarrelHits.position.y*MPGDBarrelHits.position.y)*0.1:MPGDBarrelHits.position.z*0.1>>hitsrz_barrel_mm_in"; - - TString tof_barrel_hitsrz_posR ="sqrt(TOFBarrelHits.position.x*TOFBarrelHits.position.x+TOFBarrelHits.position.y*TOFBarrelHits.position.y)*0.1:TOFBarrelHits.position.z*0.1>>hitsrz_barrel_tof"; - - TString barrel_mpgd_out_hitsrz_posR ="sqrt(OuterMPGDBarrelHits.position.x*OuterMPGDBarrelHits.position.x+OuterMPGDBarrelHits.position.y*OuterMPGDBarrelHits.position.y)*0.1:OuterMPGDBarrelHits.position.z*0.1>>hitsrz_barrel_mm_out"; - - TString disks_si_hitsrz_posR ="sqrt(TrackerEndcapHits.position.x*TrackerEndcapHits.position.x+TrackerEndcapHits.position.y*TrackerEndcapHits.position.y)*0.1:TrackerEndcapHits.position.z*0.1>>hitsrz_disks_si"; - - TString endcap_tof_hitsrz_posR ="sqrt(TOFEndcapHits.position.x*TOFEndcapHits.position.x+TOFEndcapHits.position.y*TOFEndcapHits.position.y)*0.1:TOFEndcapHits.position.z*0.1>>hitsrz_endcap_tof"; - - TString fwd_mpgd_hitsrz_posR ="sqrt(ForwardMPGDEndcapHits.position.x*ForwardMPGDEndcapHits.position.x+ForwardMPGDEndcapHits.position.y*ForwardMPGDEndcapHits.position.y)*0.1:ForwardMPGDEndcapHits.position.z*0.1>>hitsrz_fwd_mpgd"; - - TString bwd_mpgd_hitsrz_posR ="sqrt(BackwardMPGDEndcapHits.position.x*BackwardMPGDEndcapHits.position.x+BackwardMPGDEndcapHits.position.y*BackwardMPGDEndcapHits.position.y)*0.1:BackwardMPGDEndcapHits.position.z*0.1>>hitsrz_bwd_mpgd"; - - - sim->Draw(si_vtx_hitsrz_posR.Data(),"VertexBarrelHits.position.y>0",""); // Multiply by 0.1 for cm - sim->Draw(si_barrel_hitsrz_posR.Data(),"SiBarrelHits.position.y>0",""); - sim->Draw(barrel_mpgd_in_hitsrz_posR.Data(),"MPGDBarrelHits.position.y>0",""); - sim->Draw(tof_barrel_hitsrz_posR.Data(),"TOFBarrelHits.position.y>0",""); - sim->Draw(disks_si_hitsrz_posR.Data(),"TrackerEndcapHits.position.y>0",""); - sim->Draw(endcap_tof_hitsrz_posR.Data(),"TOFEndcapHits.position.y>0",""); - sim->Draw(barrel_mpgd_out_hitsrz_posR.Data(),"OuterMPGDBarrelHits.position.y>0",""); - sim->Draw(fwd_mpgd_hitsrz_posR.Data(),"ForwardMPGDEndcapHits.position.y>0",""); - sim->Draw(bwd_mpgd_hitsrz_posR.Data(),"BackwardMPGDEndcapHits.position.y>0",""); - - TString si_vtx_hitsrz_negR ="-1.0*sqrt(VertexBarrelHits.position.x*VertexBarrelHits.position.x+VertexBarrelHits.position.y*VertexBarrelHits.position.y)*0.1:VertexBarrelHits.position.z*0.1>>hitsrz_vtx_si_1"; - - TString si_barrel_hitsrz_negR ="-1.0*sqrt(SiBarrelHits.position.x*SiBarrelHits.position.x+SiBarrelHits.position.y*SiBarrelHits.position.y)*0.1:SiBarrelHits.position.z*0.1>>hitsrz_barrel_si_1"; - - TString barrel_mpgd_in_hitsrz_negR= "-1.0*sqrt(MPGDBarrelHits.position.x*MPGDBarrelHits.position.x+MPGDBarrelHits.position.y*MPGDBarrelHits.position.y)*0.1:MPGDBarrelHits.position.z*0.1>>hitsrz_barrel_mm_in_1"; - - TString tof_barrel_hitsrz_negR ="-1.0*sqrt(TOFBarrelHits.position.x*TOFBarrelHits.position.x+TOFBarrelHits.position.y*TOFBarrelHits.position.y)*0.1:TOFBarrelHits.position.z*0.1>>hitsrz_barrel_tof_1"; - - TString barrel_mpgd_out_hitsrz_negR ="-1.0*sqrt(OuterMPGDBarrelHits.position.x*OuterMPGDBarrelHits.position.x+OuterMPGDBarrelHits.position.y*OuterMPGDBarrelHits.position.y)*0.1:OuterMPGDBarrelHits.position.z*0.1>>hitsrz_barrel_mm_out_1"; - - TString disks_si_hitsrz_negR ="-1.0*sqrt(TrackerEndcapHits.position.x*TrackerEndcapHits.position.x+TrackerEndcapHits.position.y*TrackerEndcapHits.position.y)*0.1:TrackerEndcapHits.position.z*0.1>>hitsrz_disks_si_1"; - - TString endcap_tof_hitsrz_negR ="-1.0*sqrt(TOFEndcapHits.position.x*TOFEndcapHits.position.x+TOFEndcapHits.position.y*TOFEndcapHits.position.y)*0.1:TOFEndcapHits.position.z*0.1>>hitsrz_endcap_tof_1"; - - TString fwd_mpgd_hitsrz_negR ="-1.0*sqrt(ForwardMPGDEndcapHits.position.x*ForwardMPGDEndcapHits.position.x+ForwardMPGDEndcapHits.position.y*ForwardMPGDEndcapHits.position.y)*0.1:ForwardMPGDEndcapHits.position.z*0.1>>hitsrz_fwd_mpgd_1"; - - TString bwd_mpgd_hitsrz_negR ="-1.0*sqrt(BackwardMPGDEndcapHits.position.x*BackwardMPGDEndcapHits.position.x+BackwardMPGDEndcapHits.position.y*BackwardMPGDEndcapHits.position.y)*0.1:BackwardMPGDEndcapHits.position.z*0.1>>hitsrz_bwd_mpgd_1"; - - sim->Draw(si_vtx_hitsrz_negR.Data(),"VertexBarrelHits.position.y<0",""); // Multiply by 0.1 for cm - sim->Draw(si_barrel_hitsrz_negR.Data(),"SiBarrelHits.position.y<0",""); - sim->Draw(barrel_mpgd_in_hitsrz_negR.Data(),"MPGDBarrelHits.position.y<0",""); - sim->Draw(tof_barrel_hitsrz_negR.Data(),"TOFBarrelHits.position.y<0",""); - sim->Draw(disks_si_hitsrz_negR.Data(),"TrackerEndcapHits.position.y<0",""); - sim->Draw(endcap_tof_hitsrz_negR.Data(),"TOFEndcapHits.position.y<0",""); - sim->Draw(barrel_mpgd_out_hitsrz_negR.Data(),"OuterMPGDBarrelHits.position.y<0",""); - sim->Draw(fwd_mpgd_hitsrz_negR.Data(),"ForwardMPGDEndcapHits.position.y<0",""); - sim->Draw(bwd_mpgd_hitsrz_negR.Data(),"BackwardMPGDEndcapHits.position.y<0",""); - - - hitsrz_vtx_si->SetMarkerStyle(31); - hitsrz_vtx_si->SetTitle(""); - hitsrz_vtx_si->SetMarkerSize(0.1); - hitsrz_vtx_si->SetLineColor(kBlack); - hitsrz_vtx_si->SetMarkerColor(kBlack); - hitsrz_vtx_si->GetXaxis()->SetTitle("Z [cm]"); - hitsrz_vtx_si->GetYaxis()->SetTitle("R [cm]"); - hitsrz_vtx_si->GetXaxis()->CenterTitle(); - hitsrz_vtx_si->GetYaxis()->CenterTitle(); - - hitsrz_vtx_si_1->SetMarkerSize(0.1); - hitsrz_vtx_si_1->SetLineColor(kBlack); - hitsrz_vtx_si_1->SetMarkerColor(kBlack); - - hitsrz_barrel_si->SetMarkerStyle(20); - hitsrz_barrel_si->SetMarkerSize(0.1); - hitsrz_barrel_si->SetMarkerColor(kMagenta); - hitsrz_barrel_si->SetLineColor(kMagenta); - - hitsrz_barrel_si_1->SetMarkerSize(0.1); - hitsrz_barrel_si_1->SetLineColor(kMagenta); - hitsrz_barrel_si_1->SetMarkerColor(kMagenta); - - hitsrz_barrel_mm_in->SetMarkerStyle(20); - hitsrz_barrel_mm_in->SetMarkerSize(0.1); - hitsrz_barrel_mm_in->SetLineColor(kBlue); - hitsrz_barrel_mm_in->SetMarkerColor(kBlue); - hitsrz_barrel_mm_in_1->SetMarkerSize(0.1); - hitsrz_barrel_mm_in_1->SetLineColor(kBlue); - hitsrz_barrel_mm_in_1->SetMarkerColor(kBlue); - - hitsrz_barrel_tof->SetMarkerStyle(20); - hitsrz_barrel_tof->SetMarkerSize(0.1); - hitsrz_barrel_tof->SetLineColor(kGreen); - hitsrz_barrel_tof->SetMarkerColor(kGreen); - hitsrz_barrel_tof_1->SetMarkerSize(0.1); - hitsrz_barrel_tof_1->SetLineColor(kGreen); - hitsrz_barrel_tof_1->SetMarkerColor(kGreen); - - - hitsrz_barrel_mm_out->SetMarkerStyle(20); - hitsrz_barrel_mm_out->SetMarkerSize(0.1); - hitsrz_barrel_mm_out->SetMarkerColor(kBlue-7); - hitsrz_barrel_mm_out->SetLineColor(kBlue-7); - - hitsrz_barrel_mm_out_1->SetMarkerSize(0.1); - hitsrz_barrel_mm_out_1->SetLineColor(kBlue-7); - hitsrz_barrel_mm_out_1->SetMarkerColor(kBlue-7); - hitsrz_endcap_tof->SetMarkerStyle(20); - hitsrz_endcap_tof->SetMarkerSize(0.1); - hitsrz_endcap_tof->SetMarkerColor(kCyan); - hitsrz_endcap_tof->SetLineColor(kCyan); - - hitsrz_endcap_tof_1->SetMarkerSize(0.1); - hitsrz_endcap_tof_1->SetLineColor(kCyan); - hitsrz_endcap_tof_1->SetMarkerColor(kCyan); - - hitsrz_disks_si->SetMarkerStyle(20); - hitsrz_disks_si->SetMarkerSize(0.1); - hitsrz_disks_si->SetMarkerColor(kRed); - hitsrz_disks_si->SetLineColor(kRed); - - hitsrz_disks_si_1->SetMarkerSize(0.1); - hitsrz_disks_si_1->SetLineColor(kRed); - hitsrz_disks_si_1->SetMarkerColor(kRed); - - hitsrz_fwd_mpgd->SetMarkerSize(0.1); - hitsrz_fwd_mpgd->SetLineColor(kRed-7); - hitsrz_fwd_mpgd->SetMarkerColor(kRed-7); - hitsrz_fwd_mpgd_1->SetMarkerSize(0.1); - hitsrz_fwd_mpgd_1->SetLineColor(kRed-7); - hitsrz_fwd_mpgd_1->SetMarkerColor(kRed-7); - hitsrz_bwd_mpgd->SetMarkerSize(0.1); - hitsrz_bwd_mpgd->SetLineColor(kOrange); - hitsrz_bwd_mpgd->SetMarkerColor(kOrange); - - hitsrz_bwd_mpgd_1->SetMarkerSize(0.1); - hitsrz_bwd_mpgd_1->SetLineColor(kOrange); - hitsrz_bwd_mpgd_1->SetMarkerColor(kOrange); - - c2->cd(); - hitsrz_vtx_si->Draw(); - hitsrz_vtx_si_1->Draw("same"); - hitsrz_barrel_si->Draw("same"); - hitsrz_barrel_si_1->Draw("same"); - hitsrz_barrel_mm_in->Draw("same"); - hitsrz_barrel_mm_in_1->Draw("same"); - hitsrz_barrel_tof->Draw("same"); - hitsrz_barrel_tof_1->Draw("same"); - hitsrz_barrel_mm_out->Draw("same"); - hitsrz_barrel_mm_out_1->Draw("same"); - hitsrz_endcap_tof->Draw("same"); - hitsrz_endcap_tof_1->Draw("same"); - hitsrz_disks_si->Draw("same"); - hitsrz_disks_si_1->Draw("same"); - hitsrz_fwd_mpgd->Draw("same"); - hitsrz_fwd_mpgd_1->Draw("same"); - hitsrz_bwd_mpgd->Draw("same"); - hitsrz_bwd_mpgd_1->Draw("same"); - - TLegend *l1= new TLegend(0.11,0.88,0.95,0.99); + hitsxy_barrel_mm_out->Draw("same"); + + TLegend* l = new TLegend(0.65, 0.85, 0.90, 1.0); + l->SetTextSize(0.025); + l->SetBorderSize(0); + l->AddEntry(hitsxy_vtx_si, "VertexBarrelHits"); + l->AddEntry(hitsxy_barrel_si, "SiBarrelHits"); + l->AddEntry(hitsxy_barrel_mm_in, "MPGDBarrelHits"); + l->AddEntry(hitsxy_barrel_tof, "TOFBarrelHits"); + l->AddEntry(hitsxy_barrel_mm_out, "OuterMPGDBarrelHits"); + l->Draw(); + c1->SaveAs("hitsxy_dd4hep.png"); + + TCanvas* c2 = new TCanvas("c2", "c2", 1200, 1000); + c2->SetMargin(0.09, 0.03, 0.1, 0.06); + // Y-Z Hits + Int_t nbinsx = 400, nbinsy = 1800.; + x = 200.; + y = 90.; + double xmin = -200.; + + TH2D* hitsrz_vtx_si = new TH2D("hitsrz_vtx_si", "hitsrz_vtx_si", nbinsx, xmin, x, nbinsy, -y, y); + TH2D* hitsrz_barrel_si = + new TH2D("hitsrz_barrel_si", "hitsrz_barrel_si", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_barrel_mm_in = + new TH2D("hitsrz_barrel_mm_in", "hitsrz_barrel_mm_in", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_barrel_mm_out = + new TH2D("hitsrz_barrel_mm_out", "hitsrz_barrel_mm_out", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_barrel_tof = + new TH2D("hitsrz_barrel_tof", "hitsrz_barrel_tof", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_disks_si = + new TH2D("hitsrz_disks_si", "hitsrz_disks_si", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_endcap_tof = + new TH2D("hitsrz_endcap_tof", "hitsrz_endcap_tof", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_fwd_mpgd = + new TH2D("hitsrz_fwd_mpgd", "hitsrz_fwd_mpgd", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_bwd_mpgd = + new TH2D("hitsrz_bwd_mpgd", "hitsrz_bwd_mpgd", nbinsx, -x, x, nbinsy, -y, y); + + TH2D* hitsrz_vtx_si_1 = + new TH2D("hitsrz_vtx_si_1", "hitsrz_vtx_si_1", nbinsx, xmin, x, nbinsy, -y, y); + TH2D* hitsrz_barrel_si_1 = + new TH2D("hitsrz_barrel_si_1", "hitsrz_barrel_si_1", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_barrel_mm_in_1 = + new TH2D("hitsrz_barrel_mm_in_1", "hitsrz_barrel_mm_in_1", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_barrel_mm_out_1 = + new TH2D("hitsrz_barrel_mm_out_1", "hitsrz_barrel_mm_out_1", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_barrel_tof_1 = + new TH2D("hitsrz_barrel_tof_1", "hitsrz_barrel_tof_1", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_disks_si_1 = + new TH2D("hitsrz_disks_si_1", "hitsrz_disks_si_1", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_endcap_tof_1 = + new TH2D("hitsrz_endcap_tof_1", "hitsrz_endcap_tof_1", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_fwd_mpgd_1 = + new TH2D("hitsrz_fwd_mpgd_1", "hitsrz_fwd_mpgd_1", nbinsx, -x, x, nbinsy, -y, y); + TH2D* hitsrz_bwd_mpgd_1 = + new TH2D("hitsrz_bwd_mpgd_1", "hitsrz_bwd_mpgd_1", nbinsx, -x, x, nbinsy, -y, y); + + TString si_vtx_hitsrz_posR = + "sqrt(VertexBarrelHits.position.x*VertexBarrelHits.position.x+VertexBarrelHits.position.y*" + "VertexBarrelHits.position.y)*0.1:VertexBarrelHits.position.z*0.1>>hitsrz_vtx_si"; + + TString si_barrel_hitsrz_posR = + "sqrt(SiBarrelHits.position.x*SiBarrelHits.position.x+SiBarrelHits.position.y*SiBarrelHits." + "position.y)*0.1:SiBarrelHits.position.z*0.1>>hitsrz_barrel_si"; + + TString barrel_mpgd_in_hitsrz_posR = + "sqrt(MPGDBarrelHits.position.x*MPGDBarrelHits.position.x+MPGDBarrelHits.position.y*" + "MPGDBarrelHits.position.y)*0.1:MPGDBarrelHits.position.z*0.1>>hitsrz_barrel_mm_in"; + + TString tof_barrel_hitsrz_posR = + "sqrt(TOFBarrelHits.position.x*TOFBarrelHits.position.x+TOFBarrelHits.position.y*" + "TOFBarrelHits.position.y)*0.1:TOFBarrelHits.position.z*0.1>>hitsrz_barrel_tof"; + + TString barrel_mpgd_out_hitsrz_posR = + "sqrt(OuterMPGDBarrelHits.position.x*OuterMPGDBarrelHits.position.x+OuterMPGDBarrelHits." + "position.y*OuterMPGDBarrelHits.position.y)*0.1:OuterMPGDBarrelHits.position.z*0.1>>hitsrz_" + "barrel_mm_out"; + + TString disks_si_hitsrz_posR = + "sqrt(TrackerEndcapHits.position.x*TrackerEndcapHits.position.x+TrackerEndcapHits.position.y*" + "TrackerEndcapHits.position.y)*0.1:TrackerEndcapHits.position.z*0.1>>hitsrz_disks_si"; + + TString endcap_tof_hitsrz_posR = + "sqrt(TOFEndcapHits.position.x*TOFEndcapHits.position.x+TOFEndcapHits.position.y*" + "TOFEndcapHits.position.y)*0.1:TOFEndcapHits.position.z*0.1>>hitsrz_endcap_tof"; + + TString fwd_mpgd_hitsrz_posR = + "sqrt(ForwardMPGDEndcapHits.position.x*ForwardMPGDEndcapHits.position.x+" + "ForwardMPGDEndcapHits.position.y*ForwardMPGDEndcapHits.position.y)*0.1:" + "ForwardMPGDEndcapHits.position.z*0.1>>hitsrz_fwd_mpgd"; + + TString bwd_mpgd_hitsrz_posR = + "sqrt(BackwardMPGDEndcapHits.position.x*BackwardMPGDEndcapHits.position.x+" + "BackwardMPGDEndcapHits.position.y*BackwardMPGDEndcapHits.position.y)*0.1:" + "BackwardMPGDEndcapHits.position.z*0.1>>hitsrz_bwd_mpgd"; + + sim->Draw(si_vtx_hitsrz_posR.Data(), "VertexBarrelHits.position.y>0", + ""); // Multiply by 0.1 for cm + sim->Draw(si_barrel_hitsrz_posR.Data(), "SiBarrelHits.position.y>0", ""); + sim->Draw(barrel_mpgd_in_hitsrz_posR.Data(), "MPGDBarrelHits.position.y>0", ""); + sim->Draw(tof_barrel_hitsrz_posR.Data(), "TOFBarrelHits.position.y>0", ""); + sim->Draw(disks_si_hitsrz_posR.Data(), "TrackerEndcapHits.position.y>0", ""); + sim->Draw(endcap_tof_hitsrz_posR.Data(), "TOFEndcapHits.position.y>0", ""); + sim->Draw(barrel_mpgd_out_hitsrz_posR.Data(), "OuterMPGDBarrelHits.position.y>0", ""); + sim->Draw(fwd_mpgd_hitsrz_posR.Data(), "ForwardMPGDEndcapHits.position.y>0", ""); + sim->Draw(bwd_mpgd_hitsrz_posR.Data(), "BackwardMPGDEndcapHits.position.y>0", ""); + + TString si_vtx_hitsrz_negR = + "-1.0*sqrt(VertexBarrelHits.position.x*VertexBarrelHits.position.x+VertexBarrelHits.position." + "y*VertexBarrelHits.position.y)*0.1:VertexBarrelHits.position.z*0.1>>hitsrz_vtx_si_1"; + + TString si_barrel_hitsrz_negR = + "-1.0*sqrt(SiBarrelHits.position.x*SiBarrelHits.position.x+SiBarrelHits.position.y*" + "SiBarrelHits.position.y)*0.1:SiBarrelHits.position.z*0.1>>hitsrz_barrel_si_1"; + + TString barrel_mpgd_in_hitsrz_negR = + "-1.0*sqrt(MPGDBarrelHits.position.x*MPGDBarrelHits.position.x+MPGDBarrelHits.position.y*" + "MPGDBarrelHits.position.y)*0.1:MPGDBarrelHits.position.z*0.1>>hitsrz_barrel_mm_in_1"; + + TString tof_barrel_hitsrz_negR = + "-1.0*sqrt(TOFBarrelHits.position.x*TOFBarrelHits.position.x+TOFBarrelHits.position.y*" + "TOFBarrelHits.position.y)*0.1:TOFBarrelHits.position.z*0.1>>hitsrz_barrel_tof_1"; + + TString barrel_mpgd_out_hitsrz_negR = + "-1.0*sqrt(OuterMPGDBarrelHits.position.x*OuterMPGDBarrelHits.position.x+OuterMPGDBarrelHits." + "position.y*OuterMPGDBarrelHits.position.y)*0.1:OuterMPGDBarrelHits.position.z*0.1>>hitsrz_" + "barrel_mm_out_1"; + + TString disks_si_hitsrz_negR = + "-1.0*sqrt(TrackerEndcapHits.position.x*TrackerEndcapHits.position.x+TrackerEndcapHits." + "position.y*TrackerEndcapHits.position.y)*0.1:TrackerEndcapHits.position.z*0.1>>hitsrz_disks_" + "si_1"; + + TString endcap_tof_hitsrz_negR = + "-1.0*sqrt(TOFEndcapHits.position.x*TOFEndcapHits.position.x+TOFEndcapHits.position.y*" + "TOFEndcapHits.position.y)*0.1:TOFEndcapHits.position.z*0.1>>hitsrz_endcap_tof_1"; + + TString fwd_mpgd_hitsrz_negR = + "-1.0*sqrt(ForwardMPGDEndcapHits.position.x*ForwardMPGDEndcapHits.position.x+" + "ForwardMPGDEndcapHits.position.y*ForwardMPGDEndcapHits.position.y)*0.1:" + "ForwardMPGDEndcapHits.position.z*0.1>>hitsrz_fwd_mpgd_1"; + + TString bwd_mpgd_hitsrz_negR = + "-1.0*sqrt(BackwardMPGDEndcapHits.position.x*BackwardMPGDEndcapHits.position.x+" + "BackwardMPGDEndcapHits.position.y*BackwardMPGDEndcapHits.position.y)*0.1:" + "BackwardMPGDEndcapHits.position.z*0.1>>hitsrz_bwd_mpgd_1"; + + sim->Draw(si_vtx_hitsrz_negR.Data(), "VertexBarrelHits.position.y<0", + ""); // Multiply by 0.1 for cm + sim->Draw(si_barrel_hitsrz_negR.Data(), "SiBarrelHits.position.y<0", ""); + sim->Draw(barrel_mpgd_in_hitsrz_negR.Data(), "MPGDBarrelHits.position.y<0", ""); + sim->Draw(tof_barrel_hitsrz_negR.Data(), "TOFBarrelHits.position.y<0", ""); + sim->Draw(disks_si_hitsrz_negR.Data(), "TrackerEndcapHits.position.y<0", ""); + sim->Draw(endcap_tof_hitsrz_negR.Data(), "TOFEndcapHits.position.y<0", ""); + sim->Draw(barrel_mpgd_out_hitsrz_negR.Data(), "OuterMPGDBarrelHits.position.y<0", ""); + sim->Draw(fwd_mpgd_hitsrz_negR.Data(), "ForwardMPGDEndcapHits.position.y<0", ""); + sim->Draw(bwd_mpgd_hitsrz_negR.Data(), "BackwardMPGDEndcapHits.position.y<0", ""); + + hitsrz_vtx_si->SetMarkerStyle(31); + hitsrz_vtx_si->SetTitle(""); + hitsrz_vtx_si->SetMarkerSize(0.1); + hitsrz_vtx_si->SetLineColor(kBlack); + hitsrz_vtx_si->SetMarkerColor(kBlack); + hitsrz_vtx_si->GetXaxis()->SetTitle("Z [cm]"); + hitsrz_vtx_si->GetYaxis()->SetTitle("R [cm]"); + hitsrz_vtx_si->GetXaxis()->CenterTitle(); + hitsrz_vtx_si->GetYaxis()->CenterTitle(); + + hitsrz_vtx_si_1->SetMarkerSize(0.1); + hitsrz_vtx_si_1->SetLineColor(kBlack); + hitsrz_vtx_si_1->SetMarkerColor(kBlack); + + hitsrz_barrel_si->SetMarkerStyle(20); + hitsrz_barrel_si->SetMarkerSize(0.1); + hitsrz_barrel_si->SetMarkerColor(kMagenta); + hitsrz_barrel_si->SetLineColor(kMagenta); + + hitsrz_barrel_si_1->SetMarkerSize(0.1); + hitsrz_barrel_si_1->SetLineColor(kMagenta); + hitsrz_barrel_si_1->SetMarkerColor(kMagenta); + + hitsrz_barrel_mm_in->SetMarkerStyle(20); + hitsrz_barrel_mm_in->SetMarkerSize(0.1); + hitsrz_barrel_mm_in->SetLineColor(kBlue); + hitsrz_barrel_mm_in->SetMarkerColor(kBlue); + hitsrz_barrel_mm_in_1->SetMarkerSize(0.1); + hitsrz_barrel_mm_in_1->SetLineColor(kBlue); + hitsrz_barrel_mm_in_1->SetMarkerColor(kBlue); + + hitsrz_barrel_tof->SetMarkerStyle(20); + hitsrz_barrel_tof->SetMarkerSize(0.1); + hitsrz_barrel_tof->SetLineColor(kGreen); + hitsrz_barrel_tof->SetMarkerColor(kGreen); + hitsrz_barrel_tof_1->SetMarkerSize(0.1); + hitsrz_barrel_tof_1->SetLineColor(kGreen); + hitsrz_barrel_tof_1->SetMarkerColor(kGreen); + + hitsrz_barrel_mm_out->SetMarkerStyle(20); + hitsrz_barrel_mm_out->SetMarkerSize(0.1); + hitsrz_barrel_mm_out->SetMarkerColor(kBlue - 7); + hitsrz_barrel_mm_out->SetLineColor(kBlue - 7); + + hitsrz_barrel_mm_out_1->SetMarkerSize(0.1); + hitsrz_barrel_mm_out_1->SetLineColor(kBlue - 7); + hitsrz_barrel_mm_out_1->SetMarkerColor(kBlue - 7); + hitsrz_endcap_tof->SetMarkerStyle(20); + hitsrz_endcap_tof->SetMarkerSize(0.1); + hitsrz_endcap_tof->SetMarkerColor(kCyan); + hitsrz_endcap_tof->SetLineColor(kCyan); + + hitsrz_endcap_tof_1->SetMarkerSize(0.1); + hitsrz_endcap_tof_1->SetLineColor(kCyan); + hitsrz_endcap_tof_1->SetMarkerColor(kCyan); + + hitsrz_disks_si->SetMarkerStyle(20); + hitsrz_disks_si->SetMarkerSize(0.1); + hitsrz_disks_si->SetMarkerColor(kRed); + hitsrz_disks_si->SetLineColor(kRed); + + hitsrz_disks_si_1->SetMarkerSize(0.1); + hitsrz_disks_si_1->SetLineColor(kRed); + hitsrz_disks_si_1->SetMarkerColor(kRed); + + hitsrz_fwd_mpgd->SetMarkerSize(0.1); + hitsrz_fwd_mpgd->SetLineColor(kRed - 7); + hitsrz_fwd_mpgd->SetMarkerColor(kRed - 7); + hitsrz_fwd_mpgd_1->SetMarkerSize(0.1); + hitsrz_fwd_mpgd_1->SetLineColor(kRed - 7); + hitsrz_fwd_mpgd_1->SetMarkerColor(kRed - 7); + hitsrz_bwd_mpgd->SetMarkerSize(0.1); + hitsrz_bwd_mpgd->SetLineColor(kOrange); + hitsrz_bwd_mpgd->SetMarkerColor(kOrange); + + hitsrz_bwd_mpgd_1->SetMarkerSize(0.1); + hitsrz_bwd_mpgd_1->SetLineColor(kOrange); + hitsrz_bwd_mpgd_1->SetMarkerColor(kOrange); + + c2->cd(); + hitsrz_vtx_si->Draw(); + hitsrz_vtx_si_1->Draw("same"); + hitsrz_barrel_si->Draw("same"); + hitsrz_barrel_si_1->Draw("same"); + hitsrz_barrel_mm_in->Draw("same"); + hitsrz_barrel_mm_in_1->Draw("same"); + hitsrz_barrel_tof->Draw("same"); + hitsrz_barrel_tof_1->Draw("same"); + hitsrz_barrel_mm_out->Draw("same"); + hitsrz_barrel_mm_out_1->Draw("same"); + hitsrz_endcap_tof->Draw("same"); + hitsrz_endcap_tof_1->Draw("same"); + hitsrz_disks_si->Draw("same"); + hitsrz_disks_si_1->Draw("same"); + hitsrz_fwd_mpgd->Draw("same"); + hitsrz_fwd_mpgd_1->Draw("same"); + hitsrz_bwd_mpgd->Draw("same"); + hitsrz_bwd_mpgd_1->Draw("same"); + + TLegend* l1 = new TLegend(0.11, 0.88, 0.95, 0.99); l1->SetNColumns(3); l1->SetTextSize(0.025); l1->SetBorderSize(0); - l1->AddEntry(hitsrz_vtx_si,"VertexBarrelHits"); - l1->AddEntry(hitsrz_barrel_si,"SiBarrelHits"); - l1->AddEntry(hitsrz_barrel_mm_in,"MPGDBarrelHits"); - l1->AddEntry(hitsrz_barrel_tof,"TOFBarrelHits"); - l1->AddEntry(hitsrz_barrel_mm_out,"OuterMPGDBarrelHits"); - l1->AddEntry(hitsrz_disks_si,"TrackerEndcapHits"); - l1->AddEntry(hitsrz_endcap_tof,"TOFEndcapHits"); - l1->AddEntry(hitsrz_fwd_mpgd,"ForwardMPGDEndcapHits"); - l1->AddEntry(hitsrz_bwd_mpgd,"BackwardMPGDEndcapHits"); + l1->AddEntry(hitsrz_vtx_si, "VertexBarrelHits"); + l1->AddEntry(hitsrz_barrel_si, "SiBarrelHits"); + l1->AddEntry(hitsrz_barrel_mm_in, "MPGDBarrelHits"); + l1->AddEntry(hitsrz_barrel_tof, "TOFBarrelHits"); + l1->AddEntry(hitsrz_barrel_mm_out, "OuterMPGDBarrelHits"); + l1->AddEntry(hitsrz_disks_si, "TrackerEndcapHits"); + l1->AddEntry(hitsrz_endcap_tof, "TOFEndcapHits"); + l1->AddEntry(hitsrz_fwd_mpgd, "ForwardMPGDEndcapHits"); + l1->AddEntry(hitsrz_bwd_mpgd, "BackwardMPGDEndcapHits"); l1->Draw(); c2->SaveAs("hitsrz_dd4hep.png"); - // Timer Stop + // Timer Stop timer.Stop(); Double_t realtime = timer.RealTime(); - Double_t cputime = timer.CpuTime(); - printf("RealTime=%f seconds, CpuTime=%f seconds\n",realtime,cputime); - + Double_t cputime = timer.CpuTime(); + printf("RealTime=%f seconds, CpuTime=%f seconds\n", realtime, cputime); } diff --git a/src/benchmarks/reconstruction/tracking_efficiency/tracking_efficiency.cc b/src/benchmarks/reconstruction/tracking_efficiency/tracking_efficiency.cc index 656b0fbe0d..77389af37b 100644 --- a/src/benchmarks/reconstruction/tracking_efficiency/tracking_efficiency.cc +++ b/src/benchmarks/reconstruction/tracking_efficiency/tracking_efficiency.cc @@ -8,8 +8,8 @@ #include "TrackingEfficiency_processor.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->Add(new TrackingEfficiency_processor(app)); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new TrackingEfficiency_processor(app)); +} } diff --git a/src/benchmarks/reconstruction/tracking_occupancy/HitReconstructionAnalysis.cc b/src/benchmarks/reconstruction/tracking_occupancy/HitReconstructionAnalysis.cc index ef3614c305..aa13c0d46f 100644 --- a/src/benchmarks/reconstruction/tracking_occupancy/HitReconstructionAnalysis.cc +++ b/src/benchmarks/reconstruction/tracking_occupancy/HitReconstructionAnalysis.cc @@ -14,48 +14,52 @@ #include "HitReconstructionAnalysis.h" -void HitReconstructionAnalysis::init(JApplication *app, TDirectory *plugin_tdir) { +void HitReconstructionAnalysis::init(JApplication* app, TDirectory* plugin_tdir) { - auto *dir = plugin_tdir->mkdir("RecOccupancies"); // TODO create directory for this analysis + auto* dir = plugin_tdir->mkdir("RecOccupancies"); // TODO create directory for this analysis - auto z_limit_min = -2000; - auto z_limit_max = 2000; - auto r_limit_min = 0; - auto r_limit_max = 1200; + auto z_limit_min = -2000; + auto z_limit_max = 2000; + auto r_limit_min = 0; + auto r_limit_max = 1200; - m_total_occup_th2 = new TH2F("total_occup", "Occupancy plot for all readouts", 200, z_limit_min, +z_limit_max, 100, r_limit_min, r_limit_max); - m_total_occup_th2->SetDirectory(dir); + m_total_occup_th2 = new TH2F("total_occup", "Occupancy plot for all readouts", 200, z_limit_min, + +z_limit_max, 100, r_limit_min, r_limit_max); + m_total_occup_th2->SetDirectory(dir); - for(auto &name: m_data_names) { - auto count_hist = std::make_shared(("count_" + name).c_str(), ("Count hits for " + name).c_str(), 100, 0, 30); - count_hist->SetDirectory(dir); - m_hits_count_hists.push_back(count_hist); + for (auto& name : m_data_names) { + auto count_hist = std::make_shared(("count_" + name).c_str(), + ("Count hits for " + name).c_str(), 100, 0, 30); + count_hist->SetDirectory(dir); + m_hits_count_hists.push_back(count_hist); - auto occup_hist = std::make_shared(("occup_" + name).c_str(), ("Occupancy plot for" + name).c_str(), 100, z_limit_min, z_limit_max, 200, r_limit_min, r_limit_max); - occup_hist->SetDirectory(dir); - m_hits_occup_hists.push_back(occup_hist); - } + auto occup_hist = + std::make_shared(("occup_" + name).c_str(), ("Occupancy plot for" + name).c_str(), + 100, z_limit_min, z_limit_max, 200, r_limit_min, r_limit_max); + occup_hist->SetDirectory(dir); + m_hits_occup_hists.push_back(occup_hist); + } } -void HitReconstructionAnalysis::process(const std::shared_ptr &event) { - for(size_t name_index = 0; name_index < m_data_names.size(); name_index++ ) { - std::string data_name = m_data_names[name_index]; - auto &count_hist = m_hits_count_hists[name_index]; - auto &occup_hist = m_hits_occup_hists[name_index]; - - try { - auto hits = event->Get(data_name); - count_hist->Fill(hits.size()); - for(const auto *hit: hits) { - float x = hit->getPosition().x; - float y = hit->getPosition().y; - float z = hit->getPosition().z; - float r = sqrt(x*x + y*y); - occup_hist->Fill(z, r); - m_total_occup_th2->Fill(z, r); - } - } catch(std::exception& e) { - // silently skip missing collections - } +void HitReconstructionAnalysis::process(const std::shared_ptr& event) { + for (size_t name_index = 0; name_index < m_data_names.size(); name_index++) { + std::string data_name = m_data_names[name_index]; + auto& count_hist = m_hits_count_hists[name_index]; + auto& occup_hist = m_hits_occup_hists[name_index]; + + try { + auto hits = event->Get(data_name); + count_hist->Fill(hits.size()); + for (const auto* hit : hits) { + float x = hit->getPosition().x; + float y = hit->getPosition().y; + float z = hit->getPosition().z; + float r = sqrt(x * x + y * y); + occup_hist->Fill(z, r); + m_total_occup_th2->Fill(z, r); + } + } catch (std::exception& e) { + // silently skip missing collections } + } } diff --git a/src/benchmarks/reconstruction/tracking_occupancy/HitReconstructionAnalysis.h b/src/benchmarks/reconstruction/tracking_occupancy/HitReconstructionAnalysis.h index 25247ce4cb..43639b16fb 100644 --- a/src/benchmarks/reconstruction/tracking_occupancy/HitReconstructionAnalysis.h +++ b/src/benchmarks/reconstruction/tracking_occupancy/HitReconstructionAnalysis.h @@ -15,33 +15,32 @@ class HitReconstructionAnalysis { public: - void init(JApplication *app, TDirectory *plugin_tdir); + void init(JApplication* app, TDirectory* plugin_tdir); - void process(const std::shared_ptr &event); + void process(const std::shared_ptr& event); private: - - /// This is edm4hep::SimTrackerHits names of different detector readouts - std::vector m_data_names = { - "SiBarrelTrackerRecHits", // Barrel Tracker - "SiBarrelVertexRecHits", // Vertex - "SiEndcapTrackerRecHits", // End Cap tracker - // MPGD - "MPGDBarrelRecHits", - "OuterMPGDBarrelRecHits", - "ForwardMPGDEndcapRecHits", - "BackwardMPGDEndcapRecHits", - // TOF - "TOFEndcapRecHits", - "TOFBarrelRecHit", - }; - - /// Hits count histogram for each hits readout name - std::vector> m_hits_count_hists; - - /// Hits occupancy histogram for each hits readout name - std::vector> m_hits_occup_hists; - - /// Total occupancy of all m_data_names - TH2F * m_total_occup_th2; /// MC Particles px,py + /// This is edm4hep::SimTrackerHits names of different detector readouts + std::vector m_data_names = { + "SiBarrelTrackerRecHits", // Barrel Tracker + "SiBarrelVertexRecHits", // Vertex + "SiEndcapTrackerRecHits", // End Cap tracker + // MPGD + "MPGDBarrelRecHits", + "OuterMPGDBarrelRecHits", + "ForwardMPGDEndcapRecHits", + "BackwardMPGDEndcapRecHits", + // TOF + "TOFEndcapRecHits", + "TOFBarrelRecHit", + }; + + /// Hits count histogram for each hits readout name + std::vector> m_hits_count_hists; + + /// Hits occupancy histogram for each hits readout name + std::vector> m_hits_occup_hists; + + /// Total occupancy of all m_data_names + TH2F* m_total_occup_th2; /// MC Particles px,py }; diff --git a/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancyAnalysis.cc b/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancyAnalysis.cc index 5a5104bb1d..20b78c228c 100644 --- a/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancyAnalysis.cc +++ b/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancyAnalysis.cc @@ -14,51 +14,52 @@ #include "TrackingOccupancyAnalysis.h" +void TrackingOccupancyAnalysis::init(JApplication* app, TDirectory* plugin_tdir) { + auto* dir = plugin_tdir->mkdir("SimOccupancies"); // TODO create directory for this analysis -void TrackingOccupancyAnalysis::init(JApplication *app, TDirectory *plugin_tdir) { - auto *dir = plugin_tdir->mkdir("SimOccupancies"); // TODO create directory for this analysis + auto z_limit_min = -2000; + auto z_limit_max = 2000; + auto r_limit_min = 0; + auto r_limit_max = 1200; - auto z_limit_min = -2000; - auto z_limit_max = 2000; - auto r_limit_min = 0; - auto r_limit_max = 1200; + m_total_occup_th2 = new TH2F("total_occup", "Occupancy plot for all readouts", 200, z_limit_min, + +z_limit_max, 100, r_limit_min, r_limit_max); + m_total_occup_th2->SetDirectory(dir); + for (auto& name : m_data_names) { + auto count_hist = std::make_shared(("count_" + name).c_str(), + ("Count hits for " + name).c_str(), 100, 0, 30); + count_hist->SetDirectory(dir); + m_hits_count_hists.push_back(count_hist); - m_total_occup_th2 = new TH2F("total_occup", "Occupancy plot for all readouts", 200, z_limit_min, +z_limit_max, 100, r_limit_min, r_limit_max); - m_total_occup_th2->SetDirectory(dir); - - for(auto &name: m_data_names) { - auto count_hist = std::make_shared(("count_" + name).c_str(), ("Count hits for " + name).c_str(), 100, 0, 30); - count_hist->SetDirectory(dir); - m_hits_count_hists.push_back(count_hist); - - auto occup_hist = std::make_shared(("occup_" + name).c_str(), ("Occupancy plot for" + name).c_str(), 100, z_limit_min, z_limit_max, 200, r_limit_min, r_limit_max); - occup_hist->SetDirectory(dir); - m_hits_occup_hists.push_back(occup_hist); - } + auto occup_hist = + std::make_shared(("occup_" + name).c_str(), ("Occupancy plot for" + name).c_str(), + 100, z_limit_min, z_limit_max, 200, r_limit_min, r_limit_max); + occup_hist->SetDirectory(dir); + m_hits_occup_hists.push_back(occup_hist); + } } +void TrackingOccupancyAnalysis::process(const std::shared_ptr& event) { -void TrackingOccupancyAnalysis::process(const std::shared_ptr &event) { - - for(size_t name_index = 0; name_index < m_data_names.size(); name_index++ ) { - std::string data_name = m_data_names[name_index]; - auto &count_hist = m_hits_count_hists[name_index]; - auto &occup_hist = m_hits_occup_hists[name_index]; + for (size_t name_index = 0; name_index < m_data_names.size(); name_index++) { + std::string data_name = m_data_names[name_index]; + auto& count_hist = m_hits_count_hists[name_index]; + auto& occup_hist = m_hits_occup_hists[name_index]; - try { - auto hits = event->Get(data_name); - count_hist->Fill(hits.size()); - for(const auto *hit: hits) { - float x = hit->getPosition().x; - float y = hit->getPosition().y; - float z = hit->getPosition().z; - float r = sqrt(x*x + y*y); - occup_hist->Fill(z, r); - m_total_occup_th2->Fill(z, r); - } - } catch(std::exception& e) { - // silently skip missing collections - } + try { + auto hits = event->Get(data_name); + count_hist->Fill(hits.size()); + for (const auto* hit : hits) { + float x = hit->getPosition().x; + float y = hit->getPosition().y; + float z = hit->getPosition().z; + float r = sqrt(x * x + y * y); + occup_hist->Fill(z, r); + m_total_occup_th2->Fill(z, r); + } + } catch (std::exception& e) { + // silently skip missing collections } + } } diff --git a/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancyAnalysis.h b/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancyAnalysis.h index 9da578e6f2..cb2abd6cc2 100644 --- a/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancyAnalysis.h +++ b/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancyAnalysis.h @@ -16,33 +16,32 @@ class TrackingOccupancyAnalysis { public: - void init(JApplication *app, TDirectory *plugin_tdir); + void init(JApplication* app, TDirectory* plugin_tdir); - void process(const std::shared_ptr &event); + void process(const std::shared_ptr& event); private: - - /// This is edm4hep::SimTrackerHits names of different detector readouts - std::vector m_data_names = { - "SiBarrelHits", // Barrel Tracker - "VertexBarrelHits", // Vertex - "TrackerEndcapHits", // End Cap tracker - // MPGD - "MPGDBarrelHits", - "OuterMPGDBarrelHits", - "ForwardMPGDEndcapHits", - "BackwardMPGDEndcapHits", - // TOF - "TOFEndcapHits", - "TOFBarrelHits", - }; - - /// Hits count histogram for each hits readout name - std::vector> m_hits_count_hists; - - /// Hits occupancy histogram for each hits readout name - std::vector> m_hits_occup_hists; - - /// Total occupancy of all m_data_names - TH2F * m_total_occup_th2; /// MC Particles px,py + /// This is edm4hep::SimTrackerHits names of different detector readouts + std::vector m_data_names = { + "SiBarrelHits", // Barrel Tracker + "VertexBarrelHits", // Vertex + "TrackerEndcapHits", // End Cap tracker + // MPGD + "MPGDBarrelHits", + "OuterMPGDBarrelHits", + "ForwardMPGDEndcapHits", + "BackwardMPGDEndcapHits", + // TOF + "TOFEndcapHits", + "TOFBarrelHits", + }; + + /// Hits count histogram for each hits readout name + std::vector> m_hits_count_hists; + + /// Hits occupancy histogram for each hits readout name + std::vector> m_hits_occup_hists; + + /// Total occupancy of all m_data_names + TH2F* m_total_occup_th2; /// MC Particles px,py }; diff --git a/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancy_processor.cc b/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancy_processor.cc index 14c08a339e..f9704922db 100644 --- a/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancy_processor.cc +++ b/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancy_processor.cc @@ -14,59 +14,52 @@ //------------------ // OccupancyAnalysis (Constructor) //------------------ -TrackingOccupancy_processor::TrackingOccupancy_processor(JApplication *app) : - JEventProcessor(app) -{ -} +TrackingOccupancy_processor::TrackingOccupancy_processor(JApplication* app) + : JEventProcessor(app) {} //------------------ // Init //------------------ -void TrackingOccupancy_processor::Init() -{ - std::string plugin_name=("tracking_occupancy"); +void TrackingOccupancy_processor::Init() { + std::string plugin_name = ("tracking_occupancy"); - // Get JANA application - auto *app = GetApplication(); + // Get JANA application + auto* app = GetApplication(); - // Ask service locator a file to write histograms to - auto root_file_service = app->GetService(); + // Ask service locator a file to write histograms to + auto root_file_service = app->GetService(); - // Get TDirectory for histograms root file - auto globalRootLock = app->GetService(); - globalRootLock->acquire_write_lock(); - auto *file = root_file_service->GetHistFile(); - globalRootLock->release_lock(); + // Get TDirectory for histograms root file + auto globalRootLock = app->GetService(); + globalRootLock->acquire_write_lock(); + auto* file = root_file_service->GetHistFile(); + globalRootLock->release_lock(); - // Create a directory for this plugin. And subdirectories for series of histograms - m_dir_main = file->mkdir(plugin_name.c_str()); + // Create a directory for this plugin. And subdirectories for series of histograms + m_dir_main = file->mkdir(plugin_name.c_str()); - // Occupancy analysis - m_occupancy_analysis.init(app, m_dir_main); - m_hit_reco_analysis.init(app, m_dir_main); + // Occupancy analysis + m_occupancy_analysis.init(app, m_dir_main); + m_hit_reco_analysis.init(app, m_dir_main); - // Get logger - m_log = app->GetService()->logger(plugin_name); + // Get logger + m_log = app->GetService()->logger(plugin_name); } - //------------------ // Process //------------------ -void TrackingOccupancy_processor::Process(const std::shared_ptr& event) -{ - // Process raw hits from DD4Hep - m_occupancy_analysis.process(event); +void TrackingOccupancy_processor::Process(const std::shared_ptr& event) { + // Process raw hits from DD4Hep + m_occupancy_analysis.process(event); - // Process hits reconstructed with - m_hit_reco_analysis.process(event); + // Process hits reconstructed with + m_hit_reco_analysis.process(event); } - //------------------ // Finish //------------------ -void TrackingOccupancy_processor::Finish() -{ - // Nothing to do here +void TrackingOccupancy_processor::Finish() { + // Nothing to do here } diff --git a/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancy_processor.h b/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancy_processor.h index 9c02f3e08c..c4b4432bb5 100644 --- a/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancy_processor.h +++ b/src/benchmarks/reconstruction/tracking_occupancy/TrackingOccupancy_processor.h @@ -12,49 +12,47 @@ #include "HitReconstructionAnalysis.h" #include "TrackingOccupancyAnalysis.h" -class TrackingOccupancy_processor:public JEventProcessor -{ +class TrackingOccupancy_processor : public JEventProcessor { public: - explicit TrackingOccupancy_processor(JApplication *); - ~TrackingOccupancy_processor() override = default; - - //---------------------------- - // Init - // - // This is called once before the first call to the Process method - // below. You may, for example, want to open an output file here. - // Only one thread will call this. - void Init() override; - - //---------------------------- - // Process - // - // This is called for every event. Multiple threads may call this - // simultaneously. If you write something to an output file here - // then make sure to protect it with a mutex or similar mechanism. - // Minimize what is done while locked since that directly affects - // the multi-threaded performance. - void Process(const std::shared_ptr& event) override; - - //---------------------------- - // Finish - // - // This is called once after all events have been processed. You may, - // for example, want to close an output file here. - // Only one thread will call this. - void Finish() override; + explicit TrackingOccupancy_processor(JApplication*); + ~TrackingOccupancy_processor() override = default; + + //---------------------------- + // Init + // + // This is called once before the first call to the Process method + // below. You may, for example, want to open an output file here. + // Only one thread will call this. + void Init() override; + + //---------------------------- + // Process + // + // This is called for every event. Multiple threads may call this + // simultaneously. If you write something to an output file here + // then make sure to protect it with a mutex or similar mechanism. + // Minimize what is done while locked since that directly affects + // the multi-threaded performance. + void Process(const std::shared_ptr& event) override; + + //---------------------------- + // Finish + // + // This is called once after all events have been processed. You may, + // for example, want to close an output file here. + // Only one thread will call this. + void Finish() override; private: + TrackingOccupancyAnalysis m_occupancy_analysis; + HitReconstructionAnalysis m_hit_reco_analysis; - TrackingOccupancyAnalysis m_occupancy_analysis; - HitReconstructionAnalysis m_hit_reco_analysis; + TDirectory* m_dir_main; /// Main TDirectory for this plugin 'occupancy_ana' + TH1F* m_th1_prt_pz; /// MC Particles pz + TH1F* m_th1_prt_energy; /// MC Particles total E + TH1F* m_th1_prt_theta; /// MC Particles theta angle + TH1F* m_th1_prt_phi; /// MC Particles phi angle + TH2F* m_th2_prt_pxy; /// MC Particles px,py - TDirectory* m_dir_main; /// Main TDirectory for this plugin 'occupancy_ana' - TH1F * m_th1_prt_pz; /// MC Particles pz - TH1F * m_th1_prt_energy; /// MC Particles total E - TH1F * m_th1_prt_theta; /// MC Particles theta angle - TH1F * m_th1_prt_phi; /// MC Particles phi angle - TH2F * m_th2_prt_pxy; /// MC Particles px,py - - std::shared_ptr m_log; + std::shared_ptr m_log; }; diff --git a/src/benchmarks/reconstruction/tracking_occupancy/tracking_occupancy.cc b/src/benchmarks/reconstruction/tracking_occupancy/tracking_occupancy.cc index 426472a153..5c37ffbc8f 100644 --- a/src/benchmarks/reconstruction/tracking_occupancy/tracking_occupancy.cc +++ b/src/benchmarks/reconstruction/tracking_occupancy/tracking_occupancy.cc @@ -8,8 +8,8 @@ #include "TrackingOccupancy_processor.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->Add(new TrackingOccupancy_processor(app)); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new TrackingOccupancy_processor(app)); +} } diff --git a/src/detectors/B0ECAL/B0ECAL.cc b/src/detectors/B0ECAL/B0ECAL.cc index 2b653f841f..52107a91b3 100644 --- a/src/detectors/B0ECAL/B0ECAL.cc +++ b/src/detectors/B0ECAL/B0ECAL.cc @@ -18,109 +18,88 @@ #include "factories/calorimetry/CalorimeterTruthClustering_factory.h" extern "C" { - void InitPlugin(JApplication *app) { +void InitPlugin(JApplication* app) { - using namespace eicrecon; + using namespace eicrecon; - InitJANAPlugin(app); + InitJANAPlugin(app); - app->Add(new JOmniFactoryGeneratorT( - "B0ECalRawHits", - {"B0ECalHits"}, + app->Add(new JOmniFactoryGeneratorT( + "B0ECalRawHits", {"B0ECalHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"B0ECalRawHits", "B0ECalRawHitAssociations"}, + {"B0ECalRawHits", "B0ECalRawHitAssociations"}, #else - {"B0ECalRawHits"}, + {"B0ECalRawHits"}, #endif - { - // The stochastic term is set using light yield in PbOW4 of N_photons = 145.75 / GeV / mm, for 6x6 mm2 sensors with PDE=0.18 (a=1/sqrt(145.75*36*0.18)) - .eRes = {0.0326 * sqrt(dd4hep::GeV), 0.00, 0.0 * dd4hep::GeV}, - .tRes = 0.0 * dd4hep::ns, - .threshold= 5.0 * dd4hep::MeV, - .capADC = 16384, - .dyRangeADC = 170 * dd4hep::GeV, - .pedMeanADC = 100, - .pedSigmaADC = 1, - .resolutionTDC = 1e-11, - .corrMeanScale = "1.0", - .readout = "B0ECalHits", - }, - app - )); - app->Add(new JOmniFactoryGeneratorT( - "B0ECalRecHits", {"B0ECalRawHits"}, {"B0ECalRecHits"}, - { - .capADC = 16384, - .dyRangeADC = 170. * dd4hep::GeV, - .pedMeanADC = 100, - .pedSigmaADC = 1, - .resolutionTDC = 1e-11, - .thresholdFactor = 0.0, - .thresholdValue = 1.0, // using threshold of 10 photons = 10 MeV = 1 ADC - .sampFrac = "0.998", - .readout = "B0ECalHits", - .sectorField = "sector", - }, - app - )); - app->Add(new JOmniFactoryGeneratorT( - "B0ECalTruthProtoClusters", {"B0ECalRecHits", "B0ECalHits"}, {"B0ECalTruthProtoClusters"}, - app - )); - app->Add(new JOmniFactoryGeneratorT( - "B0ECalIslandProtoClusters", {"B0ECalRecHits"}, {"B0ECalIslandProtoClusters"}, - { - .sectorDist = 5.0 * dd4hep::cm, - .dimScaledLocalDistXY = {1.8,1.8}, - .splitCluster = false, - .minClusterHitEdep = 1.0 * dd4hep::MeV, - .minClusterCenterEdep = 30.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "globalDistEtaPhi", - .transverseEnergyProfileScale = 1., - }, - app - )); + { + // The stochastic term is set using light yield in PbOW4 of N_photons = 145.75 / GeV / mm, for 6x6 mm2 sensors with PDE=0.18 (a=1/sqrt(145.75*36*0.18)) + .eRes = {0.0326 * sqrt(dd4hep::GeV), 0.00, 0.0 * dd4hep::GeV}, + .tRes = 0.0 * dd4hep::ns, + .threshold = 5.0 * dd4hep::MeV, + .capADC = 16384, + .dyRangeADC = 170 * dd4hep::GeV, + .pedMeanADC = 100, + .pedSigmaADC = 1, + .resolutionTDC = 1e-11, + .corrMeanScale = "1.0", + .readout = "B0ECalHits", + }, + app)); + app->Add(new JOmniFactoryGeneratorT( + "B0ECalRecHits", {"B0ECalRawHits"}, {"B0ECalRecHits"}, + { + .capADC = 16384, + .dyRangeADC = 170. * dd4hep::GeV, + .pedMeanADC = 100, + .pedSigmaADC = 1, + .resolutionTDC = 1e-11, + .thresholdFactor = 0.0, + .thresholdValue = 1.0, // using threshold of 10 photons = 10 MeV = 1 ADC + .sampFrac = "0.998", + .readout = "B0ECalHits", + .sectorField = "sector", + }, + app)); + app->Add(new JOmniFactoryGeneratorT( + "B0ECalTruthProtoClusters", {"B0ECalRecHits", "B0ECalHits"}, {"B0ECalTruthProtoClusters"}, + app)); + app->Add(new JOmniFactoryGeneratorT( + "B0ECalIslandProtoClusters", {"B0ECalRecHits"}, {"B0ECalIslandProtoClusters"}, + { + .sectorDist = 5.0 * dd4hep::cm, + .dimScaledLocalDistXY = {1.8, 1.8}, + .splitCluster = false, + .minClusterHitEdep = 1.0 * dd4hep::MeV, + .minClusterCenterEdep = 30.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "globalDistEtaPhi", + .transverseEnergyProfileScale = 1., + }, + app)); - app->Add( - new JOmniFactoryGeneratorT( - "B0ECalClusters", - {"B0ECalIslandProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "B0ECalClusters", + {"B0ECalIslandProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "B0ECalRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "B0ECalRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "B0ECalHits"}, // edm4hep::SimCalorimeterHitCollection + "B0ECalHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"B0ECalClusters", // edm4eic::Cluster - "B0ECalClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 3.6, - .enableEtaBounds = false - }, - app - ) - ); + {"B0ECalClusters", // edm4eic::Cluster + "B0ECalClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 3.6, .enableEtaBounds = false}, + app)); - app->Add( - new JOmniFactoryGeneratorT( - "B0ECalTruthClusters", - {"B0ECalTruthProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "B0ECalTruthClusters", + {"B0ECalTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "B0ECalRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "B0ECalRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "B0ECalHits"}, // edm4hep::SimCalorimeterHitCollection + "B0ECalHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"B0ECalTruthClusters", // edm4eic::Cluster - "B0ECalTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .enableEtaBounds = false - }, - app - ) - ); - } + {"B0ECalTruthClusters", // edm4eic::Cluster + "B0ECalTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = false}, + app)); +} } diff --git a/src/detectors/B0TRK/B0TRK.cc b/src/detectors/B0TRK/B0TRK.cc index ed97109140..aba407e935 100644 --- a/src/detectors/B0TRK/B0TRK.cc +++ b/src/detectors/B0TRK/B0TRK.cc @@ -13,38 +13,26 @@ #include "factories/tracking/TrackerHitReconstruction_factory.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "B0TrackerRawHits", - { - "B0TrackerHits" - }, - { - "B0TrackerRawHits", - "B0TrackerRawHitAssociations" - }, - { - .threshold = 10.0 * dd4hep::keV, - .timeResolution = 8, - }, - app - )); - - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "B0TrackerRecHits", - {"B0TrackerRawHits"}, - {"B0TrackerRecHits"}, - { - .timeResolution = 8, - }, - app - )); + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "B0TrackerRawHits", {"B0TrackerHits"}, {"B0TrackerRawHits", "B0TrackerRawHitAssociations"}, + { + .threshold = 10.0 * dd4hep::keV, + .timeResolution = 8, + }, + app)); + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "B0TrackerRecHits", {"B0TrackerRawHits"}, {"B0TrackerRecHits"}, + { + .timeResolution = 8, + }, + app)); } } // extern "C" diff --git a/src/detectors/BEMC/BEMC.cc b/src/detectors/BEMC/BEMC.cc index 7e29d1ed79..858fffddf1 100644 --- a/src/detectors/BEMC/BEMC.cc +++ b/src/detectors/BEMC/BEMC.cc @@ -20,208 +20,188 @@ #include "factories/calorimetry/ImagingTopoCluster_factory.h" #include "factories/calorimetry/TruthEnergyPositionClusterMerger_factory.h" - extern "C" { - void InitPlugin(JApplication *app) { - - using namespace eicrecon; +void InitPlugin(JApplication* app) { - InitJANAPlugin(app); + using namespace eicrecon; + InitJANAPlugin(app); - // Make sure digi and reco use the same value - decltype(CalorimeterHitDigiConfig::capADC) EcalBarrelScFi_capADC = 16384; //16384, 14bit ADC - decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalBarrelScFi_dyRangeADC = 1500 * dd4hep::MeV; - decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalBarrelScFi_pedMeanADC = 100; - decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalBarrelScFi_pedSigmaADC = 1; - decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalBarrelScFi_resolutionTDC = 10 * dd4hep::picosecond; - app->Add(new JOmniFactoryGeneratorT( - "EcalBarrelScFiRawHits", - {"EcalBarrelScFiHits"}, + // Make sure digi and reco use the same value + decltype(CalorimeterHitDigiConfig::capADC) EcalBarrelScFi_capADC = 16384; //16384, 14bit ADC + decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalBarrelScFi_dyRangeADC = 1500 * dd4hep::MeV; + decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalBarrelScFi_pedMeanADC = 100; + decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalBarrelScFi_pedSigmaADC = 1; + decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalBarrelScFi_resolutionTDC = + 10 * dd4hep::picosecond; + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelScFiRawHits", {"EcalBarrelScFiHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"EcalBarrelScFiRawHits", "EcalBarrelScFiRawHitAssociations"}, + {"EcalBarrelScFiRawHits", "EcalBarrelScFiRawHitAssociations"}, #else - {"EcalBarrelScFiRawHits"}, + {"EcalBarrelScFiRawHits"}, #endif - { - .eRes = {0.0 * sqrt(dd4hep::GeV), 0.0, 0.0 * dd4hep::GeV}, - .tRes = 0.0 * dd4hep::ns, - .threshold = 0.0*dd4hep::keV, // threshold is set in ADC in reco - .capADC = EcalBarrelScFi_capADC, - .dyRangeADC = EcalBarrelScFi_dyRangeADC, - .pedMeanADC = EcalBarrelScFi_pedMeanADC, - .pedSigmaADC = EcalBarrelScFi_pedSigmaADC, - .resolutionTDC = EcalBarrelScFi_resolutionTDC, - .corrMeanScale = "1.0", - .readout = "EcalBarrelScFiHits", - .fields = {"fiber", "z"}, - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalBarrelScFiRecHits", {"EcalBarrelScFiRawHits"}, {"EcalBarrelScFiRecHits"}, - { - .capADC = EcalBarrelScFi_capADC, - .dyRangeADC = EcalBarrelScFi_dyRangeADC, - .pedMeanADC = EcalBarrelScFi_pedMeanADC, - .pedSigmaADC = EcalBarrelScFi_pedSigmaADC, // not needed; use only thresholdValue - .resolutionTDC = EcalBarrelScFi_resolutionTDC, - .thresholdFactor = 0.0, // use only thresholdValue - .thresholdValue = 5.0, // 16384 ADC counts/1500 MeV * 0.5 MeV (desired threshold) = 5.46 - .sampFrac = "0.09285755", - .readout = "EcalBarrelScFiHits", - .layerField = "layer", - .sectorField = "sector", - .localDetFields = {"system"}, - // here we want to use grid center position (XY) but keeps the z information from fiber-segment - // TODO: a more realistic way to get z is to reconstruct it from timing - .maskPos = "xy", - .maskPosFields = {"fiber", "z"}, - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalBarrelScFiProtoClusters", {"EcalBarrelScFiRecHits"}, {"EcalBarrelScFiProtoClusters"}, - { - .sectorDist = 50. * dd4hep::mm, - .localDistXZ = {80 * dd4hep::mm, 80 * dd4hep::mm}, - .splitCluster = false, - .minClusterHitEdep = 5.0 * dd4hep::MeV, - .minClusterCenterEdep = 100.0 * dd4hep::MeV, - }, - app // TODO: Remove me once fixed - )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalBarrelScFiClusters", - {"EcalBarrelScFiProtoClusters", // edm4eic::ProtoClusterCollection + { + .eRes = {0.0 * sqrt(dd4hep::GeV), 0.0, 0.0 * dd4hep::GeV}, + .tRes = 0.0 * dd4hep::ns, + .threshold = 0.0 * dd4hep::keV, // threshold is set in ADC in reco + .capADC = EcalBarrelScFi_capADC, + .dyRangeADC = EcalBarrelScFi_dyRangeADC, + .pedMeanADC = EcalBarrelScFi_pedMeanADC, + .pedSigmaADC = EcalBarrelScFi_pedSigmaADC, + .resolutionTDC = EcalBarrelScFi_resolutionTDC, + .corrMeanScale = "1.0", + .readout = "EcalBarrelScFiHits", + .fields = {"fiber", "z"}, + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelScFiRecHits", {"EcalBarrelScFiRawHits"}, {"EcalBarrelScFiRecHits"}, + { + .capADC = EcalBarrelScFi_capADC, + .dyRangeADC = EcalBarrelScFi_dyRangeADC, + .pedMeanADC = EcalBarrelScFi_pedMeanADC, + .pedSigmaADC = EcalBarrelScFi_pedSigmaADC, // not needed; use only thresholdValue + .resolutionTDC = EcalBarrelScFi_resolutionTDC, + .thresholdFactor = 0.0, // use only thresholdValue + .thresholdValue = 5.0, // 16384 ADC counts/1500 MeV * 0.5 MeV (desired threshold) = 5.46 + .sampFrac = "0.09285755", + .readout = "EcalBarrelScFiHits", + .layerField = "layer", + .sectorField = "sector", + .localDetFields = {"system"}, + // here we want to use grid center position (XY) but keeps the z information from fiber-segment + // TODO: a more realistic way to get z is to reconstruct it from timing + .maskPos = "xy", + .maskPosFields = {"fiber", "z"}, + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelScFiProtoClusters", {"EcalBarrelScFiRecHits"}, {"EcalBarrelScFiProtoClusters"}, + { + .sectorDist = 50. * dd4hep::mm, + .localDistXZ = {80 * dd4hep::mm, 80 * dd4hep::mm}, + .splitCluster = false, + .minClusterHitEdep = 5.0 * dd4hep::MeV, + .minClusterCenterEdep = 100.0 * dd4hep::MeV, + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelScFiClusters", + {"EcalBarrelScFiProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalBarrelScFiRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociation + "EcalBarrelScFiRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociation #else - "EcalBarrelScFiHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalBarrelScFiHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalBarrelScFiClusters", // edm4eic::Cluster - "EcalBarrelScFiClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .longitudinalShowerInfoAvailable = true, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); + {"EcalBarrelScFiClusters", // edm4eic::Cluster + "EcalBarrelScFiClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 6.2, + .longitudinalShowerInfoAvailable = true, + .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); - // Make sure digi and reco use the same value - decltype(CalorimeterHitDigiConfig::capADC) EcalBarrelImaging_capADC = 8192; //8192, 13bit ADC - decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalBarrelImaging_dyRangeADC = 3 * dd4hep::MeV; - decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalBarrelImaging_pedMeanADC = 14; // Noise floor at 5 keV: 8192 / 3 * 0.005 - decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalBarrelImaging_pedSigmaADC = 5; // Upper limit for sigma for AstroPix - decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalBarrelImaging_resolutionTDC = 3.25 * dd4hep::nanosecond; - app->Add(new JOmniFactoryGeneratorT( - "EcalBarrelImagingRawHits", - {"EcalBarrelImagingHits"}, + // Make sure digi and reco use the same value + decltype(CalorimeterHitDigiConfig::capADC) EcalBarrelImaging_capADC = 8192; //8192, 13bit ADC + decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalBarrelImaging_dyRangeADC = 3 * dd4hep::MeV; + decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalBarrelImaging_pedMeanADC = + 14; // Noise floor at 5 keV: 8192 / 3 * 0.005 + decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalBarrelImaging_pedSigmaADC = + 5; // Upper limit for sigma for AstroPix + decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalBarrelImaging_resolutionTDC = + 3.25 * dd4hep::nanosecond; + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelImagingRawHits", {"EcalBarrelImagingHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"EcalBarrelImagingRawHits", "EcalBarrelImagingRawHitAssociations"}, + {"EcalBarrelImagingRawHits", "EcalBarrelImagingRawHitAssociations"}, #else - {"EcalBarrelImagingRawHits"}, + {"EcalBarrelImagingRawHits"}, #endif - { - .eRes = {0.0 * sqrt(dd4hep::GeV), 0.02, 0.0 * dd4hep::GeV}, - .tRes = 0.0 * dd4hep::ns, - .capADC = EcalBarrelImaging_capADC, - .dyRangeADC = EcalBarrelImaging_dyRangeADC, - .pedMeanADC = EcalBarrelImaging_pedMeanADC, - .pedSigmaADC = EcalBarrelImaging_pedSigmaADC, - .resolutionTDC = EcalBarrelImaging_resolutionTDC, - .corrMeanScale = "1.0", - .readout = "EcalBarrelImagingHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalBarrelImagingRecHits", {"EcalBarrelImagingRawHits"}, {"EcalBarrelImagingRecHits"}, - { - .capADC = EcalBarrelImaging_capADC, - .dyRangeADC = EcalBarrelImaging_dyRangeADC, - .pedMeanADC = EcalBarrelImaging_pedMeanADC, - .pedSigmaADC = EcalBarrelImaging_pedSigmaADC, // not needed; use only thresholdValue - .resolutionTDC = EcalBarrelImaging_resolutionTDC, - .thresholdFactor = 0.0, // use only thresholdValue - .thresholdValue = 41, // 8192 ADC counts/3 MeV * 0.015 MeV (desired threshold) = 41 - .sampFrac = "0.00429453", - .readout = "EcalBarrelImagingHits", - .layerField = "layer", - .sectorField = "sector", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalBarrelImagingProtoClusters", {"EcalBarrelImagingRecHits"}, {"EcalBarrelImagingProtoClusters"}, - { - .neighbourLayersRange = 2, // # id diff for adjacent layer - .localDistXY = {2.0 * dd4hep::mm, 2 * dd4hep::mm}, // # same layer - .layerDistEtaPhi = {10 * dd4hep::mrad, 10 * dd4hep::mrad}, // # adjacent layer - .sectorDist = 3.0 * dd4hep::cm, - .minClusterHitEdep = 0, - .minClusterCenterEdep = 0, - .minClusterEdep = 100 * dd4hep::MeV, - .minClusterNhits = 10, - }, - app // TODO: Remove me once fixed - )); + { + .eRes = {0.0 * sqrt(dd4hep::GeV), 0.02, 0.0 * dd4hep::GeV}, + .tRes = 0.0 * dd4hep::ns, + .capADC = EcalBarrelImaging_capADC, + .dyRangeADC = EcalBarrelImaging_dyRangeADC, + .pedMeanADC = EcalBarrelImaging_pedMeanADC, + .pedSigmaADC = EcalBarrelImaging_pedSigmaADC, + .resolutionTDC = EcalBarrelImaging_resolutionTDC, + .corrMeanScale = "1.0", + .readout = "EcalBarrelImagingHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelImagingRecHits", {"EcalBarrelImagingRawHits"}, {"EcalBarrelImagingRecHits"}, + { + .capADC = EcalBarrelImaging_capADC, + .dyRangeADC = EcalBarrelImaging_dyRangeADC, + .pedMeanADC = EcalBarrelImaging_pedMeanADC, + .pedSigmaADC = EcalBarrelImaging_pedSigmaADC, // not needed; use only thresholdValue + .resolutionTDC = EcalBarrelImaging_resolutionTDC, + .thresholdFactor = 0.0, // use only thresholdValue + .thresholdValue = 41, // 8192 ADC counts/3 MeV * 0.015 MeV (desired threshold) = 41 + .sampFrac = "0.00429453", + .readout = "EcalBarrelImagingHits", + .layerField = "layer", + .sectorField = "sector", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelImagingProtoClusters", {"EcalBarrelImagingRecHits"}, + {"EcalBarrelImagingProtoClusters"}, + { + .neighbourLayersRange = 2, // # id diff for adjacent layer + .localDistXY = {2.0 * dd4hep::mm, 2 * dd4hep::mm}, // # same layer + .layerDistEtaPhi = {10 * dd4hep::mrad, 10 * dd4hep::mrad}, // # adjacent layer + .sectorDist = 3.0 * dd4hep::cm, + .minClusterHitEdep = 0, + .minClusterCenterEdep = 0, + .minClusterEdep = 100 * dd4hep::MeV, + .minClusterNhits = 10, + }, + app // TODO: Remove me once fixed + )); - app->Add(new JOmniFactoryGeneratorT( - "EcalBarrelImagingClusters", - {"EcalBarrelImagingProtoClusters", + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelImagingClusters", + {"EcalBarrelImagingProtoClusters", #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalBarrelImagingRawHitAssociations"}, + "EcalBarrelImagingRawHitAssociations"}, #else - "EcalBarrelImagingHits"}, + "EcalBarrelImagingHits"}, #endif - {"EcalBarrelImagingClusters", - "EcalBarrelImagingClusterAssociations", - "EcalBarrelImagingLayers" - }, - { - .trackStopLayer = 6, - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalBarrelClusters", - { - "EcalBarrelScFiClusters", - "EcalBarrelScFiClusterAssociations", - "EcalBarrelImagingClusters", - "EcalBarrelImagingClusterAssociations" - }, - { - "EcalBarrelClusters", - "EcalBarrelClusterAssociations" - }, - { - .energyRelTolerance = 0.5, - .phiTolerance = 0.1, - .etaTolerance = 0.2, - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalBarrelTruthClusters", - { - "MCParticles", - "EcalBarrelScFiClusters", - "EcalBarrelScFiClusterAssociations", - "EcalBarrelImagingClusters", - "EcalBarrelImagingClusterAssociations" - }, - { - "EcalBarrelTruthClusters", - "EcalBarrelTruthClusterAssociations" - }, - app // TODO: Remove me once fixed - )); - } + {"EcalBarrelImagingClusters", "EcalBarrelImagingClusterAssociations", + "EcalBarrelImagingLayers"}, + { + .trackStopLayer = 6, + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelClusters", + {"EcalBarrelScFiClusters", "EcalBarrelScFiClusterAssociations", "EcalBarrelImagingClusters", + "EcalBarrelImagingClusterAssociations"}, + {"EcalBarrelClusters", "EcalBarrelClusterAssociations"}, + { + .energyRelTolerance = 0.5, + .phiTolerance = 0.1, + .etaTolerance = 0.2, + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalBarrelTruthClusters", + {"MCParticles", "EcalBarrelScFiClusters", "EcalBarrelScFiClusterAssociations", + "EcalBarrelImagingClusters", "EcalBarrelImagingClusterAssociations"}, + {"EcalBarrelTruthClusters", "EcalBarrelTruthClusterAssociations"}, + app // TODO: Remove me once fixed + )); +} } diff --git a/src/detectors/BHCAL/BHCAL.cc b/src/detectors/BHCAL/BHCAL.cc index f17e908d8d..4179b826b2 100644 --- a/src/detectors/BHCAL/BHCAL.cc +++ b/src/detectors/BHCAL/BHCAL.cc @@ -19,183 +19,154 @@ extern "C" { - void InitPlugin(JApplication *app) { - - using namespace eicrecon; - - InitJANAPlugin(app); - - // Make sure digi and reco use the same value - decltype(CalorimeterHitDigiConfig::capADC) HcalBarrel_capADC = 65536; //65536, 16bit ADC - decltype(CalorimeterHitDigiConfig::dyRangeADC) HcalBarrel_dyRangeADC = 1.0 * dd4hep::GeV; - decltype(CalorimeterHitDigiConfig::pedMeanADC) HcalBarrel_pedMeanADC = 300; - decltype(CalorimeterHitDigiConfig::pedSigmaADC) HcalBarrel_pedSigmaADC = 2; - decltype(CalorimeterHitDigiConfig::resolutionTDC) HcalBarrel_resolutionTDC = 1 * dd4hep::picosecond; - - // Set default adjacency matrix. Magic constants: - // 320 - number of tiles per row - decltype(CalorimeterIslandClusterConfig::adjacencyMatrix) HcalBarrel_adjacencyMatrix = - "(" - // check for vertically adjacent tiles - " ( (abs(eta_1 - eta_2) == 1) && (abs(phi_1 - phi_2) == 0) ) ||" - // check for horizontally adjacent tiles - " ( (abs(eta_1 - eta_2) == 0) && (abs(phi_1 - phi_2) == 1) ) ||" - // check for horizontally adjacent tiles at wraparound - " ( (abs(eta_1 - eta_2) == 0) && (abs(phi_1 - phi_2) == (320 - 1)) )" - ") == 1"; - - app->Add(new JOmniFactoryGeneratorT( - "HcalBarrelRawHits", - {"HcalBarrelHits"}, +void InitPlugin(JApplication* app) { + + using namespace eicrecon; + + InitJANAPlugin(app); + + // Make sure digi and reco use the same value + decltype(CalorimeterHitDigiConfig::capADC) HcalBarrel_capADC = 65536; //65536, 16bit ADC + decltype(CalorimeterHitDigiConfig::dyRangeADC) HcalBarrel_dyRangeADC = 1.0 * dd4hep::GeV; + decltype(CalorimeterHitDigiConfig::pedMeanADC) HcalBarrel_pedMeanADC = 300; + decltype(CalorimeterHitDigiConfig::pedSigmaADC) HcalBarrel_pedSigmaADC = 2; + decltype(CalorimeterHitDigiConfig::resolutionTDC) HcalBarrel_resolutionTDC = + 1 * dd4hep::picosecond; + + // Set default adjacency matrix. Magic constants: + // 320 - number of tiles per row + decltype(CalorimeterIslandClusterConfig::adjacencyMatrix) HcalBarrel_adjacencyMatrix = + "(" + // check for vertically adjacent tiles + " ( (abs(eta_1 - eta_2) == 1) && (abs(phi_1 - phi_2) == 0) ) ||" + // check for horizontally adjacent tiles + " ( (abs(eta_1 - eta_2) == 0) && (abs(phi_1 - phi_2) == 1) ) ||" + // check for horizontally adjacent tiles at wraparound + " ( (abs(eta_1 - eta_2) == 0) && (abs(phi_1 - phi_2) == (320 - 1)) )" + ") == 1"; + + app->Add(new JOmniFactoryGeneratorT( + "HcalBarrelRawHits", {"HcalBarrelHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"HcalBarrelRawHits", "HcalBarrelRawHitAssociations"}, + {"HcalBarrelRawHits", "HcalBarrelRawHitAssociations"}, #else - {"HcalBarrelRawHits"}, + {"HcalBarrelRawHits"}, #endif - { - .eRes = {}, - .tRes = 0.0 * dd4hep::ns, - .threshold = 0.0, // Use ADC cut instead - .capADC = HcalBarrel_capADC, - .capTime = 100, // given in ns, 4 samples in HGCROC - .dyRangeADC = HcalBarrel_dyRangeADC, - .pedMeanADC = HcalBarrel_pedMeanADC, - .pedSigmaADC = HcalBarrel_pedSigmaADC, - .resolutionTDC = HcalBarrel_resolutionTDC, - .corrMeanScale = "1.0", - .readout = "HcalBarrelHits", - }, - app // TODO: Remove me once fixed - )); - - app->Add(new JOmniFactoryGeneratorT( - "HcalBarrelRecHits", {"HcalBarrelRawHits"}, {"HcalBarrelRecHits"}, - { - .capADC = HcalBarrel_capADC, - .dyRangeADC = HcalBarrel_dyRangeADC, - .pedMeanADC = HcalBarrel_pedMeanADC, - .pedSigmaADC = HcalBarrel_pedSigmaADC, // not used; relying on energy cut - .resolutionTDC = HcalBarrel_resolutionTDC, - .thresholdFactor = 0.0, // not used; relying on flat ADC cut - .thresholdValue = 33, // pedSigmaADC + thresholdValue = half-MIP (333 ADC) - .sampFrac = "0.033", // average, from sPHENIX simulations - .readout = "HcalBarrelHits", - .layerField = "", - .sectorField = "", - }, - app // TODO: Remove me once fixed - )); - - // -------------------------------------------------------------------- - // If needed, merge adjacent phi tiles into towers. By default, - // NO merging will be done. This can be changed at runtime. - // -------------------------------------------------------------------- - app->Add(new JOmniFactoryGeneratorT( - "HcalBarrelMergedHits", {"HcalBarrelRecHits"}, {"HcalBarrelMergedHits"}, - { - .readout = "HcalBarrelHits", - .fieldTransformations = {"phi:phi"} - }, - app // TODO: Remove me once fixed - )); - - app->Add(new JOmniFactoryGeneratorT( - "HcalBarrelTruthProtoClusters", {"HcalBarrelRecHits", "HcalBarrelHits"}, {"HcalBarrelTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); - - app->Add(new JOmniFactoryGeneratorT( - "HcalBarrelIslandProtoClusters", {"HcalBarrelRecHits"}, {"HcalBarrelIslandProtoClusters"}, - { - .adjacencyMatrix = HcalBarrel_adjacencyMatrix, - .readout = "HcalBarrelHits", - .sectorDist = 5.0 * dd4hep::cm, - .splitCluster = false, - .minClusterHitEdep = 5.0 * dd4hep::MeV, - .minClusterCenterEdep = 30.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "globalDistEtaPhi", - .transverseEnergyProfileScale = 1., - }, - app // TODO: Remove me once fixed - )); - - app->Add( - new JOmniFactoryGeneratorT( - "HcalBarrelClusters", - {"HcalBarrelIslandProtoClusters", // edm4eic::ProtoClusterCollection + { + .eRes = {}, + .tRes = 0.0 * dd4hep::ns, + .threshold = 0.0, // Use ADC cut instead + .capADC = HcalBarrel_capADC, + .capTime = 100, // given in ns, 4 samples in HGCROC + .dyRangeADC = HcalBarrel_dyRangeADC, + .pedMeanADC = HcalBarrel_pedMeanADC, + .pedSigmaADC = HcalBarrel_pedSigmaADC, + .resolutionTDC = HcalBarrel_resolutionTDC, + .corrMeanScale = "1.0", + .readout = "HcalBarrelHits", + }, + app // TODO: Remove me once fixed + )); + + app->Add(new JOmniFactoryGeneratorT( + "HcalBarrelRecHits", {"HcalBarrelRawHits"}, {"HcalBarrelRecHits"}, + { + .capADC = HcalBarrel_capADC, + .dyRangeADC = HcalBarrel_dyRangeADC, + .pedMeanADC = HcalBarrel_pedMeanADC, + .pedSigmaADC = HcalBarrel_pedSigmaADC, // not used; relying on energy cut + .resolutionTDC = HcalBarrel_resolutionTDC, + .thresholdFactor = 0.0, // not used; relying on flat ADC cut + .thresholdValue = 33, // pedSigmaADC + thresholdValue = half-MIP (333 ADC) + .sampFrac = "0.033", // average, from sPHENIX simulations + .readout = "HcalBarrelHits", + .layerField = "", + .sectorField = "", + }, + app // TODO: Remove me once fixed + )); + + // -------------------------------------------------------------------- + // If needed, merge adjacent phi tiles into towers. By default, + // NO merging will be done. This can be changed at runtime. + // -------------------------------------------------------------------- + app->Add(new JOmniFactoryGeneratorT( + "HcalBarrelMergedHits", {"HcalBarrelRecHits"}, {"HcalBarrelMergedHits"}, + {.readout = "HcalBarrelHits", .fieldTransformations = {"phi:phi"}}, + app // TODO: Remove me once fixed + )); + + app->Add(new JOmniFactoryGeneratorT( + "HcalBarrelTruthProtoClusters", {"HcalBarrelRecHits", "HcalBarrelHits"}, + {"HcalBarrelTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); + + app->Add(new JOmniFactoryGeneratorT( + "HcalBarrelIslandProtoClusters", {"HcalBarrelRecHits"}, {"HcalBarrelIslandProtoClusters"}, + { + .adjacencyMatrix = HcalBarrel_adjacencyMatrix, + .readout = "HcalBarrelHits", + .sectorDist = 5.0 * dd4hep::cm, + .splitCluster = false, + .minClusterHitEdep = 5.0 * dd4hep::MeV, + .minClusterCenterEdep = 30.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "globalDistEtaPhi", + .transverseEnergyProfileScale = 1., + }, + app // TODO: Remove me once fixed + )); + + app->Add(new JOmniFactoryGeneratorT( + "HcalBarrelClusters", + {"HcalBarrelIslandProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "HcalBarrelRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "HcalBarrelRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "HcalBarrelHits"}, // edm4hep::SimCalorimeterHitCollection + "HcalBarrelHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"HcalBarrelClusters", // edm4eic::Cluster - "HcalBarrelClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); - - app->Add( - new JOmniFactoryGeneratorT( - "HcalBarrelTruthClusters", - {"HcalBarrelTruthProtoClusters", // edm4eic::ProtoClusterCollection + {"HcalBarrelClusters", // edm4eic::Cluster + "HcalBarrelClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); + + app->Add(new JOmniFactoryGeneratorT( + "HcalBarrelTruthClusters", + {"HcalBarrelTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "HcalBarrelRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "HcalBarrelRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "HcalBarrelHits"}, // edm4hep::SimCalorimeterHitCollection + "HcalBarrelHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"HcalBarrelTruthClusters", // edm4eic::Cluster - "HcalBarrelTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); - - app->Add( - new JOmniFactoryGeneratorT( - "HcalBarrelSplitMergeProtoClusters", - {"HcalBarrelIslandProtoClusters", - "CalorimeterTrackProjections"}, - {"HcalBarrelSplitMergeProtoClusters"}, - { - .idCalo = "HcalBarrel_ID", - .minSigCut = -2.0, - .avgEP = 0.50, - .sigEP = 0.25, - .drAdd = 0.40, - .sampFrac = 1.0, - .transverseEnergyProfileScale = 1.0 - }, - app // TODO: remove me once fixed - ) - ); - - app->Add( - new JOmniFactoryGeneratorT( - "HcalBarrelSplitMergeClusters", - {"HcalBarrelSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection - "HcalBarrelHits"}, // edm4hep::SimCalorimeterHitCollection - {"HcalBarrelSplitMergeClusters", // edm4eic::Cluster - "HcalBarrelSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); - - } + {"HcalBarrelTruthClusters", // edm4eic::Cluster + "HcalBarrelTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); + + app->Add(new JOmniFactoryGeneratorT( + "HcalBarrelSplitMergeProtoClusters", + {"HcalBarrelIslandProtoClusters", "CalorimeterTrackProjections"}, + {"HcalBarrelSplitMergeProtoClusters"}, + {.idCalo = "HcalBarrel_ID", + .minSigCut = -2.0, + .avgEP = 0.50, + .sigEP = 0.25, + .drAdd = 0.40, + .sampFrac = 1.0, + .transverseEnergyProfileScale = 1.0}, + app // TODO: remove me once fixed + )); + + app->Add(new JOmniFactoryGeneratorT( + "HcalBarrelSplitMergeClusters", + {"HcalBarrelSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection + "HcalBarrelHits"}, // edm4hep::SimCalorimeterHitCollection + {"HcalBarrelSplitMergeClusters", // edm4eic::Cluster + "HcalBarrelSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); +} } diff --git a/src/detectors/BTOF/BTOF.cc b/src/detectors/BTOF/BTOF.cc index 7c030ba7db..e831fb2de2 100644 --- a/src/detectors/BTOF/BTOF.cc +++ b/src/detectors/BTOF/BTOF.cc @@ -22,86 +22,74 @@ #include "services/geometry/dd4hep/DD4hep_service.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "TOFBarrelRawHits", - { - "TOFBarrelHits" - }, - { - "TOFBarrelRawHits", - "TOFBarrelRawHitAssociations" - }, - { - .threshold = 6.0 * dd4hep::keV, - .timeResolution = 0.025, // [ns] - }, - app - )); + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "TOFBarrelRawHits", {"TOFBarrelHits"}, {"TOFBarrelRawHits", "TOFBarrelRawHitAssociations"}, + { + .threshold = 6.0 * dd4hep::keV, + .timeResolution = 0.025, // [ns] + }, + app)); - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "TOFBarrelRecHits", - {"TOFBarrelRawHits"}, // Input data collection tags - {"TOFBarrelRecHits"}, // Output data tag - { - .timeResolution = 10, - }, - app - )); // Hit reco default config for factories + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "TOFBarrelRecHits", {"TOFBarrelRawHits"}, // Input data collection tags + {"TOFBarrelRecHits"}, // Output data tag + { + .timeResolution = 10, + }, + app)); // Hit reco default config for factories - int BarrelTOF_ID = 0; - try { - auto detector = app->GetService()->detector(); - BarrelTOF_ID = detector->constant("BarrelTOF_ID"); - } catch(const std::runtime_error&) { - // Nothing - } - PIDLookupConfig pid_cfg { - .filename="calibrations/tof.lut", - .system=BarrelTOF_ID, - .pdg_values={11, 211, 321, 2212}, - .charge_values={1}, - .momentum_edges={0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0}, - .polar_edges={2.50, 10.95, 19.40, 27.85, 36.30, 44.75, 53.20, 61.65, 70.10, 78.55, 87.00, 95.45, 103.90, 112.35, 120.80, 129.25, 137.70, 146.15, 154.60}, - .azimuthal_binning={0., 360., 360.}, // lower, upper, step - .momentum_bin_centers_in_lut=true, - .polar_bin_centers_in_lut=true, - }; + int BarrelTOF_ID = 0; + try { + auto detector = app->GetService()->detector(); + BarrelTOF_ID = detector->constant("BarrelTOF_ID"); + } catch (const std::runtime_error&) { + // Nothing + } + PIDLookupConfig pid_cfg{ + .filename = "calibrations/tof.lut", + .system = BarrelTOF_ID, + .pdg_values = {11, 211, 321, 2212}, + .charge_values = {1}, + .momentum_edges = {0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, + 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0}, + .polar_edges = {2.50, 10.95, 19.40, 27.85, 36.30, 44.75, 53.20, 61.65, 70.10, 78.55, 87.00, + 95.45, 103.90, 112.35, 120.80, 129.25, 137.70, 146.15, 154.60}, + .azimuthal_binning = {0., 360., 360.}, // lower, upper, step + .momentum_bin_centers_in_lut = true, + .polar_bin_centers_in_lut = true, + }; - app->Add(new JOmniFactoryGeneratorT( - "CombinedTOFTruthSeededLUTPID", - { + app->Add(new JOmniFactoryGeneratorT( + "CombinedTOFTruthSeededLUTPID", + { "ReconstructedTruthSeededChargedWithPFRICHPIDParticles", "ReconstructedTruthSeededChargedWithPFRICHPIDParticleAssociations", - }, - { + }, + { "ReconstructedTruthSeededChargedWithPFRICHTOFPIDParticles", "ReconstructedTruthSeededChargedWithPFRICHTOFPIDParticleAssociations", "CombinedTOFTruthSeededParticleIDs", - }, - pid_cfg, - app - )); + }, + pid_cfg, app)); - app->Add(new JOmniFactoryGeneratorT( - "CombinedTOFLUTPID", - { + app->Add(new JOmniFactoryGeneratorT( + "CombinedTOFLUTPID", + { "ReconstructedChargedWithPFRICHPIDParticles", "ReconstructedChargedWithPFRICHPIDParticleAssociations", - }, - { + }, + { "ReconstructedChargedWithPFRICHTOFPIDParticles", "ReconstructedChargedWithPFRICHTOFPIDParticleAssociations", "CombinedTOFParticleIDs", - }, - pid_cfg, - app - )); + }, + pid_cfg, app)); } } // extern "C" diff --git a/src/detectors/BTRK/BTRK.cc b/src/detectors/BTRK/BTRK.cc index 85b14b505a..b7b9d133a5 100644 --- a/src/detectors/BTRK/BTRK.cc +++ b/src/detectors/BTRK/BTRK.cc @@ -13,36 +13,23 @@ #include "factories/tracking/TrackerHitReconstruction_factory.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - - using namespace eicrecon; - - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelRawHits", - { - "SiBarrelHits" - }, - { - "SiBarrelRawHits", - "SiBarrelRawHitAssociations" - }, - { - .threshold = 0.54 * dd4hep::keV, - }, - app - )); - - - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelTrackerRecHits", - {"SiBarrelRawHits"}, - {"SiBarrelTrackerRecHits"}, - {}, // default config - app - )); - +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + + using namespace eicrecon; + + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelRawHits", {"SiBarrelHits"}, {"SiBarrelRawHits", "SiBarrelRawHitAssociations"}, + { + .threshold = 0.54 * dd4hep::keV, + }, + app)); + + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelTrackerRecHits", {"SiBarrelRawHits"}, {"SiBarrelTrackerRecHits"}, + {}, // default config + app)); } } // extern "C" diff --git a/src/detectors/BVTX/BVTX.cc b/src/detectors/BVTX/BVTX.cc index 799dda2ba4..149afdb5c4 100644 --- a/src/detectors/BVTX/BVTX.cc +++ b/src/detectors/BVTX/BVTX.cc @@ -13,35 +13,24 @@ #include "factories/tracking/TrackerHitReconstruction_factory.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelVertexRawHits", - { - "VertexBarrelHits" - }, - { - "SiBarrelVertexRawHits", - "SiBarrelVertexRawHitAssociations" - }, - { - .threshold = 0.54 * dd4hep::keV, - }, - app - )); - - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelVertexRecHits", - {"SiBarrelVertexRawHits"}, - {"SiBarrelVertexRecHits"}, - {}, // default config - app - )); + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelVertexRawHits", {"VertexBarrelHits"}, + {"SiBarrelVertexRawHits", "SiBarrelVertexRawHitAssociations"}, + { + .threshold = 0.54 * dd4hep::keV, + }, + app)); + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelVertexRecHits", {"SiBarrelVertexRawHits"}, {"SiBarrelVertexRecHits"}, + {}, // default config + app)); } } // extern "C" diff --git a/src/detectors/DIRC/DIRC.cc b/src/detectors/DIRC/DIRC.cc index 459fb97568..a6f0035002 100644 --- a/src/detectors/DIRC/DIRC.cc +++ b/src/detectors/DIRC/DIRC.cc @@ -19,85 +19,90 @@ #include "global/pid_lut/PIDLookup_factory.h" #include "services/geometry/dd4hep/DD4hep_service.h" - extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // configuration parameters /////////////////////////////////////////////// + // configuration parameters /////////////////////////////////////////////// - // digitization - PhotoMultiplierHitDigiConfig digi_cfg; - digi_cfg.seed = 5; // FIXME: set to 0 for a 'unique' seed, but - // that seems to delay the RNG from actually randomizing - digi_cfg.hitTimeWindow = 20.0; // [ns] - digi_cfg.timeResolution = 1/16.0; // [ns] - digi_cfg.speMean = 80.0; - digi_cfg.speError = 16.0; - digi_cfg.pedMean = 200.0; - digi_cfg.pedError = 3.0; - digi_cfg.enablePixelGaps = false; - digi_cfg.safetyFactor = 1.0; - // Actual efficiency is implemented in npsim via a stacking action - digi_cfg.enableQuantumEfficiency = false; - digi_cfg.quantumEfficiency.clear(); + // digitization + PhotoMultiplierHitDigiConfig digi_cfg; + digi_cfg.seed = 5; // FIXME: set to 0 for a 'unique' seed, but + // that seems to delay the RNG from actually randomizing + digi_cfg.hitTimeWindow = 20.0; // [ns] + digi_cfg.timeResolution = 1 / 16.0; // [ns] + digi_cfg.speMean = 80.0; + digi_cfg.speError = 16.0; + digi_cfg.pedMean = 200.0; + digi_cfg.pedError = 3.0; + digi_cfg.enablePixelGaps = false; + digi_cfg.safetyFactor = 1.0; + // Actual efficiency is implemented in npsim via a stacking action + digi_cfg.enableQuantumEfficiency = false; + digi_cfg.quantumEfficiency.clear(); - // digitization - app->Add(new JOmniFactoryGeneratorT( - "DIRCRawHits", - {"DIRCBarHits"}, - {"DIRCRawHits", "DIRCRawHitsAssociations"}, - digi_cfg, - app - )); + // digitization + app->Add(new JOmniFactoryGeneratorT( + "DIRCRawHits", {"DIRCBarHits"}, {"DIRCRawHits", "DIRCRawHitsAssociations"}, digi_cfg, app)); - int BarrelDIRC_ID = 0; - try { - auto detector = app->GetService()->detector(); - BarrelDIRC_ID = detector->constant("BarrelDIRC_ID"); - } catch(const std::runtime_error&) { - // Nothing - } - PIDLookupConfig pid_cfg { - .filename="calibrations/hpdirc.lut.gz", - .system=BarrelDIRC_ID, - .pdg_values={11, 211, 321, 2212}, - .charge_values={-1, 1}, - .momentum_edges={0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2, 7.4, 7.6, 7.8, 8.0, 8.2, 8.4, 8.6, 8.8, 9.0, 9.2, 9.4, 9.6, 9.8, 10.0, 10.2}, - .polar_edges={25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, 100.0, 101.0, 102.0, 103.0, 104.0, 105.0, 106.0, 107.0, 108.0, 109.0, 110.0, 111.0, 112.0, 113.0, 114.0, 115.0, 116.0, 117.0, 118.0, 119.0, 120.0, 121.0, 122.0, 123.0, 124.0, 125.0, 126.0, 127.0, 128.0, 129.0, 130.0, 131.0, 132.0, 133.0, 134.0, 135.0, 136.0, 137.0, 138.0, 139.0, 140.0, 141.0, 142.0, 143.0, 144.0, 145.0, 146.0, 147.0, 148.0, 149.0, 150.0, 151.0, 152.0, 153.0, 154.0, 155.0, 156.0, 157.0, 158.0, 159.0, 160.0}, - .azimuthal_binning={0.0, 30.5, 0.5}, // lower, upper, step - }; + int BarrelDIRC_ID = 0; + try { + auto detector = app->GetService()->detector(); + BarrelDIRC_ID = detector->constant("BarrelDIRC_ID"); + } catch (const std::runtime_error&) { + // Nothing + } + PIDLookupConfig pid_cfg{ + .filename = "calibrations/hpdirc.lut.gz", + .system = BarrelDIRC_ID, + .pdg_values = {11, 211, 321, 2212}, + .charge_values = {-1, 1}, + .momentum_edges = {0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, + 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, + 5.4, 5.6, 5.8, 6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2, 7.4, 7.6, 7.8, + 8.0, 8.2, 8.4, 8.6, 8.8, 9.0, 9.2, 9.4, 9.6, 9.8, 10.0, 10.2}, + .polar_edges = {25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, + 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, + 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, + 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, + 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, + 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, + 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, 100.0, 101.0, + 102.0, 103.0, 104.0, 105.0, 106.0, 107.0, 108.0, 109.0, 110.0, 111.0, 112.0, + 113.0, 114.0, 115.0, 116.0, 117.0, 118.0, 119.0, 120.0, 121.0, 122.0, 123.0, + 124.0, 125.0, 126.0, 127.0, 128.0, 129.0, 130.0, 131.0, 132.0, 133.0, 134.0, + 135.0, 136.0, 137.0, 138.0, 139.0, 140.0, 141.0, 142.0, 143.0, 144.0, 145.0, + 146.0, 147.0, 148.0, 149.0, 150.0, 151.0, 152.0, 153.0, 154.0, 155.0, 156.0, + 157.0, 158.0, 159.0, 160.0}, + .azimuthal_binning = {0.0, 30.5, 0.5}, // lower, upper, step + }; - app->Add(new JOmniFactoryGeneratorT( - "DIRCTruthSeededLUTPID", - { + app->Add(new JOmniFactoryGeneratorT( + "DIRCTruthSeededLUTPID", + { "ReconstructedTruthSeededChargedWithPFRICHTOFPIDParticles", "ReconstructedTruthSeededChargedWithPFRICHTOFPIDParticleAssociations", - }, - { + }, + { "ReconstructedTruthSeededChargedWithPFRICHTOFDIRCPIDParticles", "ReconstructedTruthSeededChargedWithPFRICHTOFDIRCPIDParticleAssociations", "DIRCTruthSeededParticleIDs", - }, - pid_cfg, - app - )); + }, + pid_cfg, app)); - app->Add(new JOmniFactoryGeneratorT( - "DIRCLUTPID", - { + app->Add(new JOmniFactoryGeneratorT( + "DIRCLUTPID", + { "ReconstructedChargedWithPFRICHTOFPIDParticles", "ReconstructedChargedWithPFRICHTOFPIDParticleAssociations", - }, - { + }, + { "ReconstructedChargedWithPFRICHTOFDIRCPIDParticles", "ReconstructedChargedWithPFRICHTOFDIRCPIDParticleAssociations", "DIRCParticleIDs", - }, - pid_cfg, - app - )); - } + }, + pid_cfg, app)); +} } diff --git a/src/detectors/DRICH/DRICH.cc b/src/detectors/DRICH/DRICH.cc index d26a43a832..9dc6a76681 100644 --- a/src/detectors/DRICH/DRICH.cc +++ b/src/detectors/DRICH/DRICH.cc @@ -38,100 +38,86 @@ #include "services/geometry/richgeo/RichGeo_service.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - - using namespace eicrecon; - - // configuration parameters /////////////////////////////////////////////// - - // digitization - PhotoMultiplierHitDigiConfig digi_cfg; - digi_cfg.seed = 5; // FIXME: set to 0 for a 'unique' seed, but - // that seems to delay the RNG from actually randomizing - digi_cfg.hitTimeWindow = 20.0; // [ns] - digi_cfg.timeResolution = 1/16.0; // [ns] - digi_cfg.speMean = 80.0; - digi_cfg.speError = 16.0; - digi_cfg.pedMean = 200.0; - digi_cfg.pedError = 3.0; - digi_cfg.enablePixelGaps = true; - digi_cfg.safetyFactor = 0.7; - digi_cfg.enableNoise = false; - digi_cfg.noiseRate = 20000; // [Hz] - digi_cfg.noiseTimeWindow = 20.0 * dd4hep::ns; // [ns] - digi_cfg.quantumEfficiency.clear(); - digi_cfg.quantumEfficiency = { // wavelength units are [nm] - {315, 0.00}, - {325, 0.04}, - {340, 0.10}, - {350, 0.20}, - {370, 0.30}, - {400, 0.35}, - {450, 0.40}, - {500, 0.38}, - {550, 0.35}, - {600, 0.27}, - {650, 0.20}, - {700, 0.15}, - {750, 0.12}, - {800, 0.08}, - {850, 0.06}, - {900, 0.04}, - {1000, 0.00} - }; - - // Track propagation - TrackPropagationConfig aerogel_track_cfg; - TrackPropagationConfig gas_track_cfg; - - // get RICH geo service - auto richGeoSvc = app->GetService(); - auto dd4hepGeo = richGeoSvc->GetDD4hepGeo(); - if (dd4hepGeo->world().children().contains("DRICH")) { - auto actsGeo = richGeoSvc->GetActsGeo("DRICH"); - auto aerogel_tracking_planes = actsGeo->TrackingPlanes(richgeo::kAerogel, 5); - auto aerogel_track_point_cut = actsGeo->TrackPointCut(richgeo::kAerogel); - auto gas_tracking_planes = actsGeo->TrackingPlanes(richgeo::kGas, 10); - auto gas_track_point_cut = actsGeo->TrackPointCut(richgeo::kGas); - auto filter_surface = gas_tracking_planes.back(); - // track propagation to each radiator - aerogel_track_cfg.filter_surfaces.push_back(filter_surface); - aerogel_track_cfg.target_surfaces = aerogel_tracking_planes; - aerogel_track_cfg.track_point_cut = aerogel_track_point_cut; - gas_track_cfg.filter_surfaces.push_back(filter_surface); - gas_track_cfg.target_surfaces = gas_tracking_planes; - gas_track_cfg.track_point_cut = gas_track_point_cut; - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + + using namespace eicrecon; + + // configuration parameters /////////////////////////////////////////////// + + // digitization + PhotoMultiplierHitDigiConfig digi_cfg; + digi_cfg.seed = 5; // FIXME: set to 0 for a 'unique' seed, but + // that seems to delay the RNG from actually randomizing + digi_cfg.hitTimeWindow = 20.0; // [ns] + digi_cfg.timeResolution = 1 / 16.0; // [ns] + digi_cfg.speMean = 80.0; + digi_cfg.speError = 16.0; + digi_cfg.pedMean = 200.0; + digi_cfg.pedError = 3.0; + digi_cfg.enablePixelGaps = true; + digi_cfg.safetyFactor = 0.7; + digi_cfg.enableNoise = false; + digi_cfg.noiseRate = 20000; // [Hz] + digi_cfg.noiseTimeWindow = 20.0 * dd4hep::ns; // [ns] + digi_cfg.quantumEfficiency.clear(); + digi_cfg.quantumEfficiency = {// wavelength units are [nm] + {315, 0.00}, {325, 0.04}, {340, 0.10}, {350, 0.20}, {370, 0.30}, + {400, 0.35}, {450, 0.40}, {500, 0.38}, {550, 0.35}, {600, 0.27}, + {650, 0.20}, {700, 0.15}, {750, 0.12}, {800, 0.08}, {850, 0.06}, + {900, 0.04}, {1000, 0.00}}; + + // Track propagation + TrackPropagationConfig aerogel_track_cfg; + TrackPropagationConfig gas_track_cfg; + + // get RICH geo service + auto richGeoSvc = app->GetService(); + auto dd4hepGeo = richGeoSvc->GetDD4hepGeo(); + if (dd4hepGeo->world().children().contains("DRICH")) { + auto actsGeo = richGeoSvc->GetActsGeo("DRICH"); + auto aerogel_tracking_planes = actsGeo->TrackingPlanes(richgeo::kAerogel, 5); + auto aerogel_track_point_cut = actsGeo->TrackPointCut(richgeo::kAerogel); + auto gas_tracking_planes = actsGeo->TrackingPlanes(richgeo::kGas, 10); + auto gas_track_point_cut = actsGeo->TrackPointCut(richgeo::kGas); + auto filter_surface = gas_tracking_planes.back(); + // track propagation to each radiator + aerogel_track_cfg.filter_surfaces.push_back(filter_surface); + aerogel_track_cfg.target_surfaces = aerogel_tracking_planes; + aerogel_track_cfg.track_point_cut = aerogel_track_point_cut; + gas_track_cfg.filter_surfaces.push_back(filter_surface); + gas_track_cfg.target_surfaces = gas_tracking_planes; + gas_track_cfg.track_point_cut = gas_track_point_cut; + } - // IRT PID - IrtCherenkovParticleIDConfig irt_cfg; - // - refractive index interpolation - irt_cfg.numRIndexBins = 100; - // - aerogel - irt_cfg.radiators.insert({"Aerogel", RadiatorConfig{}}); - irt_cfg.radiators.at("Aerogel").referenceRIndex = 1.0190; - irt_cfg.radiators.at("Aerogel").attenuation = 48; // [mm] - irt_cfg.radiators.at("Aerogel").smearingMode = "gaussian"; - irt_cfg.radiators.at("Aerogel").smearing = 2e-3; // [radians] - // - gas - irt_cfg.radiators.insert({"Gas", RadiatorConfig{}}); - irt_cfg.radiators.at("Gas").referenceRIndex = 1.00076; - irt_cfg.radiators.at("Gas").attenuation = 0; // [mm] - irt_cfg.radiators.at("Gas").smearingMode = "gaussian"; - irt_cfg.radiators.at("Gas").smearing = 5e-3; // [radians] - // - PDG list - irt_cfg.pdgList.insert(irt_cfg.pdgList.end(), { 11, 211, 321, 2212 }); - // - cheat modes - irt_cfg.cheatPhotonVertex = false; - irt_cfg.cheatTrueRadiator = false; - - // Merge PID from radiators - MergeParticleIDConfig merge_cfg; - merge_cfg.mergeMode = MergeParticleIDConfig::kAddWeights; - - // wiring between factories and data /////////////////////////////////////// - // clang-format off + // IRT PID + IrtCherenkovParticleIDConfig irt_cfg; + // - refractive index interpolation + irt_cfg.numRIndexBins = 100; + // - aerogel + irt_cfg.radiators.insert({"Aerogel", RadiatorConfig{}}); + irt_cfg.radiators.at("Aerogel").referenceRIndex = 1.0190; + irt_cfg.radiators.at("Aerogel").attenuation = 48; // [mm] + irt_cfg.radiators.at("Aerogel").smearingMode = "gaussian"; + irt_cfg.radiators.at("Aerogel").smearing = 2e-3; // [radians] + // - gas + irt_cfg.radiators.insert({"Gas", RadiatorConfig{}}); + irt_cfg.radiators.at("Gas").referenceRIndex = 1.00076; + irt_cfg.radiators.at("Gas").attenuation = 0; // [mm] + irt_cfg.radiators.at("Gas").smearingMode = "gaussian"; + irt_cfg.radiators.at("Gas").smearing = 5e-3; // [radians] + // - PDG list + irt_cfg.pdgList.insert(irt_cfg.pdgList.end(), {11, 211, 321, 2212}); + // - cheat modes + irt_cfg.cheatPhotonVertex = false; + irt_cfg.cheatTrueRadiator = false; + + // Merge PID from radiators + MergeParticleIDConfig merge_cfg; + merge_cfg.mergeMode = MergeParticleIDConfig::kAddWeights; + + // wiring between factories and data /////////////////////////////////////// + // clang-format off // digitization app->Add(new JOmniFactoryGeneratorT( @@ -237,6 +223,6 @@ extern "C" { pid_cfg, app )); - // clang-format on - } + // clang-format on +} } diff --git a/src/detectors/ECTOF/ECTOF.cc b/src/detectors/ECTOF/ECTOF.cc index e6812fc971..866cada707 100644 --- a/src/detectors/ECTOF/ECTOF.cc +++ b/src/detectors/ECTOF/ECTOF.cc @@ -13,37 +13,27 @@ #include "factories/tracking/TrackerHitReconstruction_factory.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "TOFEndcapRawHits", + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "TOFEndcapRawHits", {"TOFEndcapHits"}, {"TOFEndcapRawHits", "TOFEndcapRawHitAssociations"}, { - "TOFEndcapHits"}, - { - "TOFEndcapRawHits", - "TOFEndcapRawHitAssociations" - }, - { - .threshold = 6.0 * dd4hep::keV, - .timeResolution = 0.025, + .threshold = 6.0 * dd4hep::keV, + .timeResolution = 0.025, }, - app - )); + app)); - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "TOFEndcapRecHits", - {"TOFEndcapRawHits"}, // Input data collection tags - {"TOFEndcapRecHits"}, // Output data tag + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "TOFEndcapRecHits", {"TOFEndcapRawHits"}, // Input data collection tags + {"TOFEndcapRecHits"}, // Output data tag { - .timeResolution = 0.025, + .timeResolution = 0.025, }, - app - )); - + app)); } } // extern "C" diff --git a/src/detectors/ECTRK/ECTRK.cc b/src/detectors/ECTRK/ECTRK.cc index c8ecf3b969..564831a56f 100644 --- a/src/detectors/ECTRK/ECTRK.cc +++ b/src/detectors/ECTRK/ECTRK.cc @@ -13,35 +13,24 @@ #include "factories/tracking/TrackerHitReconstruction_factory.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "SiEndcapTrackerRawHits", - { - "TrackerEndcapHits" - }, - { - "SiEndcapTrackerRawHits", - "SiEndcapTrackerRawHitAssociations" - }, - { - .threshold = 0.54 * dd4hep::keV, - }, - app - )); - - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "SiEndcapTrackerRecHits", - {"SiEndcapTrackerRawHits"}, - {"SiEndcapTrackerRecHits"}, - {}, // default config - app - )); + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "SiEndcapTrackerRawHits", {"TrackerEndcapHits"}, + {"SiEndcapTrackerRawHits", "SiEndcapTrackerRawHitAssociations"}, + { + .threshold = 0.54 * dd4hep::keV, + }, + app)); + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "SiEndcapTrackerRecHits", {"SiEndcapTrackerRawHits"}, {"SiEndcapTrackerRecHits"}, + {}, // default config + app)); } } // extern "C" diff --git a/src/detectors/EEMC/EEMC.cc b/src/detectors/EEMC/EEMC.cc index 035b4ab3d0..e956ace749 100644 --- a/src/detectors/EEMC/EEMC.cc +++ b/src/detectors/EEMC/EEMC.cc @@ -26,204 +26,181 @@ #endif extern "C" { - void InitPlugin(JApplication *app) { +void InitPlugin(JApplication* app) { - using namespace eicrecon; + using namespace eicrecon; - InitJANAPlugin(app); + InitJANAPlugin(app); - // Make sure digi and reco use the same value - decltype(CalorimeterHitDigiConfig::capADC) EcalEndcapN_capADC = 16384; //65536, 16bit ADC - decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalEndcapN_dyRangeADC = 20.0 * dd4hep::GeV; - decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalEndcapN_pedMeanADC = 20; - decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalEndcapN_pedSigmaADC = 1; - decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalEndcapN_resolutionTDC = 10 * dd4hep::picosecond; - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNRawHits", - {"EcalEndcapNHits"}, + // Make sure digi and reco use the same value + decltype(CalorimeterHitDigiConfig::capADC) EcalEndcapN_capADC = 16384; //65536, 16bit ADC + decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalEndcapN_dyRangeADC = 20.0 * dd4hep::GeV; + decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalEndcapN_pedMeanADC = 20; + decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalEndcapN_pedSigmaADC = 1; + decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalEndcapN_resolutionTDC = + 10 * dd4hep::picosecond; + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNRawHits", {"EcalEndcapNHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"EcalEndcapNRawHits", "EcalEndcapNRawHitAssociations"}, + {"EcalEndcapNRawHits", "EcalEndcapNRawHitAssociations"}, #else - {"EcalEndcapNRawHits"}, + {"EcalEndcapNRawHits"}, #endif - { - .eRes = {0.0 * sqrt(dd4hep::GeV), 0.0, 0.0 * dd4hep::GeV}, - .tRes = 0.0 * dd4hep::ns, - .threshold = 0.0 * dd4hep::MeV, // Use ADC cut instead - .capADC = EcalEndcapN_capADC, - .dyRangeADC = EcalEndcapN_dyRangeADC, - .pedMeanADC = EcalEndcapN_pedMeanADC, - .pedSigmaADC = EcalEndcapN_pedSigmaADC, - .resolutionTDC = EcalEndcapN_resolutionTDC, - .corrMeanScale = "1.0", - .readout = "EcalEndcapNHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNRecHits", {"EcalEndcapNRawHits"}, {"EcalEndcapNRecHits"}, - { - .capADC = EcalEndcapN_capADC, - .dyRangeADC = EcalEndcapN_dyRangeADC, - .pedMeanADC = EcalEndcapN_pedMeanADC, - .pedSigmaADC = EcalEndcapN_pedSigmaADC, - .resolutionTDC = EcalEndcapN_resolutionTDC, - .thresholdFactor = 0.0, - .thresholdValue = 4.0, // (20. GeV / 16384) * 4 ~= 5 MeV - .sampFrac = "0.998", - .readout = "EcalEndcapNHits", - .sectorField = "sector", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNTruthProtoClusters", {"EcalEndcapNRecHits", "EcalEndcapNHits"}, {"EcalEndcapNTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNIslandProtoClusters", {"EcalEndcapNRecHits"}, {"EcalEndcapNIslandProtoClusters"}, - { - .adjacencyMatrix = "(abs(row_1 - row_2) + abs(column_1 - column_2)) == 1", - .peakNeighbourhoodMatrix = "max(abs(row_1 - row_2), abs(column_1 - column_2)) == 1", - .readout = "EcalEndcapNHits", - .sectorDist = 5.0 * dd4hep::cm, - .splitCluster = true, - .minClusterHitEdep = 1.0 * dd4hep::MeV, - .minClusterCenterEdep = 30.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "globalDistEtaPhi", - .transverseEnergyProfileScale = 0.08, - }, - app // TODO: Remove me once fixed - )); + { + .eRes = {0.0 * sqrt(dd4hep::GeV), 0.0, 0.0 * dd4hep::GeV}, + .tRes = 0.0 * dd4hep::ns, + .threshold = 0.0 * dd4hep::MeV, // Use ADC cut instead + .capADC = EcalEndcapN_capADC, + .dyRangeADC = EcalEndcapN_dyRangeADC, + .pedMeanADC = EcalEndcapN_pedMeanADC, + .pedSigmaADC = EcalEndcapN_pedSigmaADC, + .resolutionTDC = EcalEndcapN_resolutionTDC, + .corrMeanScale = "1.0", + .readout = "EcalEndcapNHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNRecHits", {"EcalEndcapNRawHits"}, {"EcalEndcapNRecHits"}, + { + .capADC = EcalEndcapN_capADC, + .dyRangeADC = EcalEndcapN_dyRangeADC, + .pedMeanADC = EcalEndcapN_pedMeanADC, + .pedSigmaADC = EcalEndcapN_pedSigmaADC, + .resolutionTDC = EcalEndcapN_resolutionTDC, + .thresholdFactor = 0.0, + .thresholdValue = 4.0, // (20. GeV / 16384) * 4 ~= 5 MeV + .sampFrac = "0.998", + .readout = "EcalEndcapNHits", + .sectorField = "sector", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNTruthProtoClusters", {"EcalEndcapNRecHits", "EcalEndcapNHits"}, + {"EcalEndcapNTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNIslandProtoClusters", {"EcalEndcapNRecHits"}, {"EcalEndcapNIslandProtoClusters"}, + { + .adjacencyMatrix = "(abs(row_1 - row_2) + abs(column_1 - column_2)) == 1", + .peakNeighbourhoodMatrix = "max(abs(row_1 - row_2), abs(column_1 - column_2)) == 1", + .readout = "EcalEndcapNHits", + .sectorDist = 5.0 * dd4hep::cm, + .splitCluster = true, + .minClusterHitEdep = 1.0 * dd4hep::MeV, + .minClusterCenterEdep = 30.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "globalDistEtaPhi", + .transverseEnergyProfileScale = 0.08, + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalEndcapNTruthClusters", - {"EcalEndcapNTruthProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNTruthClusters", + {"EcalEndcapNTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalEndcapNRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "EcalEndcapNRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "EcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalEndcapNTruthClusters", // edm4eic::Cluster - "EcalEndcapNTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 4.6, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); + {"EcalEndcapNTruthClusters", // edm4eic::Cluster + "EcalEndcapNTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 4.6, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( + app->Add(new JOmniFactoryGeneratorT( #if EDM4EIC_VERSION_MAJOR >= 8 - "EcalEndcapNClustersWithoutPID", + "EcalEndcapNClustersWithoutPID", #else - "EcalEndcapNClusters", + "EcalEndcapNClusters", #endif - {"EcalEndcapNIslandProtoClusters", // edm4eic::ProtoClusterCollection + {"EcalEndcapNIslandProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalEndcapNRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "EcalEndcapNRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "EcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection #endif #if EDM4EIC_VERSION_MAJOR >= 8 - {"EcalEndcapNClustersWithoutPID", // edm4eic::Cluster - "EcalEndcapNClusterAssociationsWithoutPID"}, // edm4eic::MCRecoClusterParticleAssociation + {"EcalEndcapNClustersWithoutPID", // edm4eic::Cluster + "EcalEndcapNClusterAssociationsWithoutPID"}, // edm4eic::MCRecoClusterParticleAssociation #else - {"EcalEndcapNClusters", // edm4eic::Cluster - "EcalEndcapNClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {"EcalEndcapNClusters", // edm4eic::Cluster + "EcalEndcapNClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation #endif - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 3.6, - .enableEtaBounds = false, - }, - app // TODO: Remove me once fixed - ) - ); + { + .energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 3.6, + .enableEtaBounds = false, + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalEndcapNSplitMergeProtoClusters", - {"EcalEndcapNIslandProtoClusters", - "CalorimeterTrackProjections"}, - {"EcalEndcapNSplitMergeProtoClusters"}, - { - .idCalo = "EcalEndcapN_ID", - .minSigCut = -1.0, - .avgEP = 1.0, - .sigEP = 0.10, - .drAdd = 0.08, - .sampFrac = 1.0, - .transverseEnergyProfileScale = 1.0 - }, - app // TODO: remove me once fixed - ) - ); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNSplitMergeProtoClusters", + {"EcalEndcapNIslandProtoClusters", "CalorimeterTrackProjections"}, + {"EcalEndcapNSplitMergeProtoClusters"}, + {.idCalo = "EcalEndcapN_ID", + .minSigCut = -1.0, + .avgEP = 1.0, + .sigEP = 0.10, + .drAdd = 0.08, + .sampFrac = 1.0, + .transverseEnergyProfileScale = 1.0}, + app // TODO: remove me once fixed + )); #if EDM4EIC_VERSION_MAJOR >= 8 - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNParticleIDPreML", - { - "EcalEndcapNClustersWithoutPID", - "EcalEndcapNClusterAssociationsWithoutPID", - }, - { - "EcalEndcapNParticleIDInput_features", - "EcalEndcapNParticleIDTarget", - }, - app - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNParticleIDInference", - { - "EcalEndcapNParticleIDInput_features", - }, - { - "EcalEndcapNParticleIDOutput_label", - "EcalEndcapNParticleIDOutput_probability_tensor", - }, - { - .modelPath = "calibrations/onnx/EcalEndcapN_pi_rejection.onnx", - }, - app - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNParticleIDPostML", - { - "EcalEndcapNClustersWithoutPID", - "EcalEndcapNClusterAssociationsWithoutPID", - "EcalEndcapNParticleIDOutput_probability_tensor", - }, - { - "EcalEndcapNClusters", - "EcalEndcapNClusterAssociations", - "EcalEndcapNClusterParticleIDs", - }, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNParticleIDPreML", + { + "EcalEndcapNClustersWithoutPID", + "EcalEndcapNClusterAssociationsWithoutPID", + }, + { + "EcalEndcapNParticleIDInput_features", + "EcalEndcapNParticleIDTarget", + }, + app)); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNParticleIDInference", + { + "EcalEndcapNParticleIDInput_features", + }, + { + "EcalEndcapNParticleIDOutput_label", + "EcalEndcapNParticleIDOutput_probability_tensor", + }, + { + .modelPath = "calibrations/onnx/EcalEndcapN_pi_rejection.onnx", + }, + app)); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNParticleIDPostML", + { + "EcalEndcapNClustersWithoutPID", + "EcalEndcapNClusterAssociationsWithoutPID", + "EcalEndcapNParticleIDOutput_probability_tensor", + }, + { + "EcalEndcapNClusters", + "EcalEndcapNClusterAssociations", + "EcalEndcapNClusterParticleIDs", + }, + app)); #endif - app->Add( - new JOmniFactoryGeneratorT( - "EcalEndcapNSplitMergeClusters", - {"EcalEndcapNSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection - "EcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection - {"EcalEndcapNSplitMergeClusters", // edm4eic::Cluster - "EcalEndcapNSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 3.6, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); - } + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNSplitMergeClusters", + {"EcalEndcapNSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection + "EcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection + {"EcalEndcapNSplitMergeClusters", // edm4eic::Cluster + "EcalEndcapNSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 3.6, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); +} } diff --git a/src/detectors/EHCAL/EHCAL.cc b/src/detectors/EHCAL/EHCAL.cc index 7d39c01472..230ce9fb68 100644 --- a/src/detectors/EHCAL/EHCAL.cc +++ b/src/detectors/EHCAL/EHCAL.cc @@ -19,155 +19,137 @@ #include "factories/calorimetry/TrackClusterMergeSplitter_factory.h" extern "C" { - void InitPlugin(JApplication *app) { +void InitPlugin(JApplication* app) { - using namespace eicrecon; + using namespace eicrecon; - InitJANAPlugin(app); - // Make sure digi and reco use the same value - decltype(CalorimeterHitDigiConfig::capADC) HcalEndcapN_capADC = 32768; // assuming 15 bit ADC like FHCal - decltype(CalorimeterHitDigiConfig::dyRangeADC) HcalEndcapN_dyRangeADC = 200 * dd4hep::MeV; // to be verified with simulations - decltype(CalorimeterHitDigiConfig::pedMeanADC) HcalEndcapN_pedMeanADC = 10; - decltype(CalorimeterHitDigiConfig::pedSigmaADC) HcalEndcapN_pedSigmaADC = 2; - decltype(CalorimeterHitDigiConfig::resolutionTDC) HcalEndcapN_resolutionTDC = 10 * dd4hep::picosecond; + InitJANAPlugin(app); + // Make sure digi and reco use the same value + decltype(CalorimeterHitDigiConfig::capADC) HcalEndcapN_capADC = + 32768; // assuming 15 bit ADC like FHCal + decltype(CalorimeterHitDigiConfig::dyRangeADC) HcalEndcapN_dyRangeADC = + 200 * dd4hep::MeV; // to be verified with simulations + decltype(CalorimeterHitDigiConfig::pedMeanADC) HcalEndcapN_pedMeanADC = 10; + decltype(CalorimeterHitDigiConfig::pedSigmaADC) HcalEndcapN_pedSigmaADC = 2; + decltype(CalorimeterHitDigiConfig::resolutionTDC) HcalEndcapN_resolutionTDC = + 10 * dd4hep::picosecond; - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapNRawHits", - {"HcalEndcapNHits"}, + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapNRawHits", {"HcalEndcapNHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"HcalEndcapNRawHits", "HcalEndcapNRawHitAssociations"}, + {"HcalEndcapNRawHits", "HcalEndcapNRawHitAssociations"}, #else - {"HcalEndcapNRawHits"}, + {"HcalEndcapNRawHits"}, #endif - { - .tRes = 0.0 * dd4hep::ns, - .capADC = HcalEndcapN_capADC, - .capTime = 100, // given in ns, 4 samples in HGCROC - .dyRangeADC = HcalEndcapN_dyRangeADC, - .pedMeanADC = HcalEndcapN_pedMeanADC, - .pedSigmaADC = HcalEndcapN_pedSigmaADC, - .resolutionTDC = HcalEndcapN_resolutionTDC, - .corrMeanScale = "1.0", - .readout = "HcalEndcapNHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapNRecHits", {"HcalEndcapNRawHits"}, {"HcalEndcapNRecHits"}, - { - .capADC = HcalEndcapN_capADC, - .dyRangeADC = HcalEndcapN_dyRangeADC, - .pedMeanADC = HcalEndcapN_pedMeanADC, - .pedSigmaADC = HcalEndcapN_pedSigmaADC, - .resolutionTDC = HcalEndcapN_resolutionTDC, - .thresholdFactor = 0.0, - .thresholdValue = 41.0, // 0.1875 MeV deposition out of 200 MeV max (per layer) --> adc = 10 + 0.1875 / 200 * 32768 == 41 - .sampFrac = "0.0095", // from latest study - implement at level of reco hits rather than clusters - .readout = "HcalEndcapNHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapNMergedHits", {"HcalEndcapNRecHits"}, {"HcalEndcapNMergedHits"}, - { - .readout = "HcalEndcapNHits", - .fieldTransformations = {"layer:4", "slice:0"} - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapNTruthProtoClusters", {"HcalEndcapNMergedHits", "HcalEndcapNHits"}, {"HcalEndcapNTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapNIslandProtoClusters", {"HcalEndcapNMergedHits"}, {"HcalEndcapNIslandProtoClusters"}, - { - .sectorDist = 5.0 * dd4hep::cm, - .localDistXY = {15*dd4hep::cm, 15*dd4hep::cm}, - .splitCluster = true, - .minClusterHitEdep = 0.0 * dd4hep::MeV, - .minClusterCenterEdep = 30.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "globalDistEtaPhi", - .transverseEnergyProfileScale = 1., - }, - app // TODO: Remove me once fixed - )); - app->Add( - new JOmniFactoryGeneratorT( - "HcalEndcapNTruthClusters", - {"HcalEndcapNTruthProtoClusters", // edm4eic::ProtoClusterCollection + { + .tRes = 0.0 * dd4hep::ns, + .capADC = HcalEndcapN_capADC, + .capTime = 100, // given in ns, 4 samples in HGCROC + .dyRangeADC = HcalEndcapN_dyRangeADC, + .pedMeanADC = HcalEndcapN_pedMeanADC, + .pedSigmaADC = HcalEndcapN_pedSigmaADC, + .resolutionTDC = HcalEndcapN_resolutionTDC, + .corrMeanScale = "1.0", + .readout = "HcalEndcapNHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapNRecHits", {"HcalEndcapNRawHits"}, {"HcalEndcapNRecHits"}, + { + .capADC = HcalEndcapN_capADC, + .dyRangeADC = HcalEndcapN_dyRangeADC, + .pedMeanADC = HcalEndcapN_pedMeanADC, + .pedSigmaADC = HcalEndcapN_pedSigmaADC, + .resolutionTDC = HcalEndcapN_resolutionTDC, + .thresholdFactor = 0.0, + .thresholdValue = + 41.0, // 0.1875 MeV deposition out of 200 MeV max (per layer) --> adc = 10 + 0.1875 / 200 * 32768 == 41 + .sampFrac = + "0.0095", // from latest study - implement at level of reco hits rather than clusters + .readout = "HcalEndcapNHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapNMergedHits", {"HcalEndcapNRecHits"}, {"HcalEndcapNMergedHits"}, + {.readout = "HcalEndcapNHits", .fieldTransformations = {"layer:4", "slice:0"}}, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapNTruthProtoClusters", {"HcalEndcapNMergedHits", "HcalEndcapNHits"}, + {"HcalEndcapNTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapNIslandProtoClusters", {"HcalEndcapNMergedHits"}, + {"HcalEndcapNIslandProtoClusters"}, + { + .sectorDist = 5.0 * dd4hep::cm, + .localDistXY = {15 * dd4hep::cm, 15 * dd4hep::cm}, + .splitCluster = true, + .minClusterHitEdep = 0.0 * dd4hep::MeV, + .minClusterCenterEdep = 30.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "globalDistEtaPhi", + .transverseEnergyProfileScale = 1., + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapNTruthClusters", + {"HcalEndcapNTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "HcalEndcapNRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "HcalEndcapNRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "HcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection + "HcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"HcalEndcapNTruthClusters", // edm4eic::Cluster - "HcalEndcapNTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); + {"HcalEndcapNTruthClusters", // edm4eic::Cluster + "HcalEndcapNTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "HcalEndcapNClusters", - {"HcalEndcapNIslandProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapNClusters", + {"HcalEndcapNIslandProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "HcalEndcapNRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "HcalEndcapNRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "HcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection + "HcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"HcalEndcapNClusters", // edm4eic::Cluster - "HcalEndcapNClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .enableEtaBounds = false, - }, - app // TODO: Remove me once fixed - ) - ); + {"HcalEndcapNClusters", // edm4eic::Cluster + "HcalEndcapNClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + { + .energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 6.2, + .enableEtaBounds = false, + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "HcalEndcapNSplitMergeProtoClusters", - {"HcalEndcapNIslandProtoClusters", - "CalorimeterTrackProjections"}, - {"HcalEndcapNSplitMergeProtoClusters"}, - { - .idCalo = "HcalEndcapN_ID", - .minSigCut = -2.0, - .avgEP = 0.60, - .sigEP = 0.40, - .drAdd = 0.40, - .sampFrac = 1.0, - .transverseEnergyProfileScale = 1.0 - }, - app // TODO: remove me once fixed - ) - ); + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapNSplitMergeProtoClusters", + {"HcalEndcapNIslandProtoClusters", "CalorimeterTrackProjections"}, + {"HcalEndcapNSplitMergeProtoClusters"}, + {.idCalo = "HcalEndcapN_ID", + .minSigCut = -2.0, + .avgEP = 0.60, + .sigEP = 0.40, + .drAdd = 0.40, + .sampFrac = 1.0, + .transverseEnergyProfileScale = 1.0}, + app // TODO: remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "HcalEndcapNSplitMergeClusters", - {"HcalEndcapNSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection - "HcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection - {"HcalEndcapNSplitMergeClusters", // edm4eic::Cluster - "HcalEndcapNSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); - } + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapNSplitMergeClusters", + {"HcalEndcapNSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection + "HcalEndcapNHits"}, // edm4hep::SimCalorimeterHitCollection + {"HcalEndcapNSplitMergeClusters", // edm4eic::Cluster + "HcalEndcapNSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); +} } diff --git a/src/detectors/FEMC/FEMC.cc b/src/detectors/FEMC/FEMC.cc index 998e425285..0f3730d960 100644 --- a/src/detectors/FEMC/FEMC.cc +++ b/src/detectors/FEMC/FEMC.cc @@ -17,251 +17,227 @@ #include "factories/calorimetry/TrackClusterMergeSplitter_factory.h" extern "C" { - void InitPlugin(JApplication *app) { +void InitPlugin(JApplication* app) { - using namespace eicrecon; + using namespace eicrecon; - InitJANAPlugin(app); - // Make sure digi and reco use the same value - decltype(CalorimeterHitDigiConfig::capADC) EcalEndcapP_capADC = 16384; //16384, assuming 14 bits. For approximate HGCROC resolution use 65536 - decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalEndcapP_dyRangeADC = 3 * dd4hep::GeV; - decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalEndcapP_pedMeanADC = 200; - decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalEndcapP_pedSigmaADC = 2.4576; - decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalEndcapP_resolutionTDC = 10 * dd4hep::picosecond; - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapPRawHits", - {"EcalEndcapPHits"}, + InitJANAPlugin(app); + // Make sure digi and reco use the same value + decltype(CalorimeterHitDigiConfig::capADC) EcalEndcapP_capADC = + 16384; //16384, assuming 14 bits. For approximate HGCROC resolution use 65536 + decltype(CalorimeterHitDigiConfig::dyRangeADC) EcalEndcapP_dyRangeADC = 3 * dd4hep::GeV; + decltype(CalorimeterHitDigiConfig::pedMeanADC) EcalEndcapP_pedMeanADC = 200; + decltype(CalorimeterHitDigiConfig::pedSigmaADC) EcalEndcapP_pedSigmaADC = 2.4576; + decltype(CalorimeterHitDigiConfig::resolutionTDC) EcalEndcapP_resolutionTDC = + 10 * dd4hep::picosecond; + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPRawHits", {"EcalEndcapPHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"EcalEndcapPRawHits", "EcalEndcapPRawHitAssociations"}, + {"EcalEndcapPRawHits", "EcalEndcapPRawHitAssociations"}, #else - {"EcalEndcapPRawHits"}, + {"EcalEndcapPRawHits"}, #endif - { - .eRes = {0.11333 * sqrt(dd4hep::GeV), 0.03, 0.0 * dd4hep::GeV}, // (11.333% / sqrt(E)) \oplus 3% - .tRes = 0.0, - .threshold = 0.0, - // .threshold = 15 * dd4hep::MeV for a single tower, applied on ADC level - .capADC = EcalEndcapP_capADC, - .capTime = 100, // given in ns, 4 samples in HGCROC - .dyRangeADC = EcalEndcapP_dyRangeADC, - .pedMeanADC = EcalEndcapP_pedMeanADC, - .pedSigmaADC = EcalEndcapP_pedSigmaADC, - .resolutionTDC = EcalEndcapP_resolutionTDC, - .corrMeanScale = "0.03", - .readout = "EcalEndcapPHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapPRecHits", {"EcalEndcapPRawHits"}, {"EcalEndcapPRecHits"}, - { - .capADC = EcalEndcapP_capADC, - .dyRangeADC = EcalEndcapP_dyRangeADC, - .pedMeanADC = EcalEndcapP_pedMeanADC, - .pedSigmaADC = EcalEndcapP_pedSigmaADC, - .resolutionTDC = EcalEndcapP_resolutionTDC, - .thresholdFactor = 0.0, - .thresholdValue = 2, // The ADC of a 15 MeV particle is adc = 200 + 15 * 0.03 * ( 1.0 + 0) / 3000 * 16384 = 200 + 2.4576 - .sampFrac = "0.03", - .readout = "EcalEndcapPHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapPTruthProtoClusters", {"EcalEndcapPRecHits", "EcalEndcapPHits"}, {"EcalEndcapPTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapPIslandProtoClusters", {"EcalEndcapPRecHits"}, {"EcalEndcapPIslandProtoClusters"}, - { - .sectorDist = 5.0 * dd4hep::cm, - .dimScaledLocalDistXY = {1.5,1.5}, - .splitCluster = false, - .minClusterHitEdep = 0.0 * dd4hep::MeV, - .minClusterCenterEdep = 60.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "dimScaledLocalDistXY", - .transverseEnergyProfileScale = 1., - }, - app // TODO: Remove me once fixed - )); + { + .eRes = {0.11333 * sqrt(dd4hep::GeV), 0.03, + 0.0 * dd4hep::GeV}, // (11.333% / sqrt(E)) \oplus 3% + .tRes = 0.0, + .threshold = 0.0, + // .threshold = 15 * dd4hep::MeV for a single tower, applied on ADC level + .capADC = EcalEndcapP_capADC, + .capTime = 100, // given in ns, 4 samples in HGCROC + .dyRangeADC = EcalEndcapP_dyRangeADC, + .pedMeanADC = EcalEndcapP_pedMeanADC, + .pedSigmaADC = EcalEndcapP_pedSigmaADC, + .resolutionTDC = EcalEndcapP_resolutionTDC, + .corrMeanScale = "0.03", + .readout = "EcalEndcapPHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPRecHits", {"EcalEndcapPRawHits"}, {"EcalEndcapPRecHits"}, + { + .capADC = EcalEndcapP_capADC, + .dyRangeADC = EcalEndcapP_dyRangeADC, + .pedMeanADC = EcalEndcapP_pedMeanADC, + .pedSigmaADC = EcalEndcapP_pedSigmaADC, + .resolutionTDC = EcalEndcapP_resolutionTDC, + .thresholdFactor = 0.0, + .thresholdValue = + 2, // The ADC of a 15 MeV particle is adc = 200 + 15 * 0.03 * ( 1.0 + 0) / 3000 * 16384 = 200 + 2.4576 + .sampFrac = "0.03", + .readout = "EcalEndcapPHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPTruthProtoClusters", {"EcalEndcapPRecHits", "EcalEndcapPHits"}, + {"EcalEndcapPTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPIslandProtoClusters", {"EcalEndcapPRecHits"}, {"EcalEndcapPIslandProtoClusters"}, + { + .sectorDist = 5.0 * dd4hep::cm, + .dimScaledLocalDistXY = {1.5, 1.5}, + .splitCluster = false, + .minClusterHitEdep = 0.0 * dd4hep::MeV, + .minClusterCenterEdep = 60.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "dimScaledLocalDistXY", + .transverseEnergyProfileScale = 1., + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalEndcapPTruthClusters", - {"EcalEndcapPTruthProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPTruthClusters", + {"EcalEndcapPTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalEndcapPRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "EcalEndcapPRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "EcalEndcapPHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalEndcapPHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalEndcapPTruthClusters", // edm4eic::Cluster - "EcalEndcapPTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .enableEtaBounds = true - }, - app // TODO: Remove me once fixed - ) - ); + {"EcalEndcapPTruthClusters", // edm4eic::Cluster + "EcalEndcapPTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = true}, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalEndcapPClusters", - {"EcalEndcapPIslandProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPClusters", + {"EcalEndcapPIslandProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalEndcapPRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "EcalEndcapPRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "EcalEndcapPHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalEndcapPHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalEndcapPClusters", // edm4eic::Cluster - "EcalEndcapPClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 3.6, - .enableEtaBounds = false, - }, - app // TODO: Remove me once fixed - ) - ); + {"EcalEndcapPClusters", // edm4eic::Cluster + "EcalEndcapPClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + { + .energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 3.6, + .enableEtaBounds = false, + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalEndcapPSplitMergeProtoClusters", - {"EcalEndcapPIslandProtoClusters", - "CalorimeterTrackProjections"}, - {"EcalEndcapPSplitMergeProtoClusters"}, - { - .idCalo = "EcalEndcapP_ID", - .minSigCut = -2.0, - .avgEP = 1.0, - .sigEP = 0.10, - .drAdd = 0.30, - .sampFrac = 1.0, - .transverseEnergyProfileScale = 1.0 - }, - app // TODO: remove me once fixed - ) - ); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPSplitMergeProtoClusters", + {"EcalEndcapPIslandProtoClusters", "CalorimeterTrackProjections"}, + {"EcalEndcapPSplitMergeProtoClusters"}, + {.idCalo = "EcalEndcapP_ID", + .minSigCut = -2.0, + .avgEP = 1.0, + .sigEP = 0.10, + .drAdd = 0.30, + .sampFrac = 1.0, + .transverseEnergyProfileScale = 1.0}, + app // TODO: remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalEndcapPSplitMergeClusters", - {"EcalEndcapPSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection - "EcalEndcapPHits"}, // edm4hep::SimCalorimeterHitCollection - {"EcalEndcapPSplitMergeClusters", // edm4eic::Cluster - "EcalEndcapPSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 3.6, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPSplitMergeClusters", + {"EcalEndcapPSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection + "EcalEndcapPHits"}, // edm4hep::SimCalorimeterHitCollection + {"EcalEndcapPSplitMergeClusters", // edm4eic::Cluster + "EcalEndcapPSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 3.6, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); - // Insert is identical to regular Ecal - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapPInsertRawHits", - {"EcalEndcapPInsertHits"}, + // Insert is identical to regular Ecal + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPInsertRawHits", {"EcalEndcapPInsertHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"EcalEndcapPInsertRawHits", "EcalEndcapPInsertRawHitAssociations"}, + {"EcalEndcapPInsertRawHits", "EcalEndcapPInsertRawHitAssociations"}, #else - {"EcalEndcapPInsertRawHits"}, + {"EcalEndcapPInsertRawHits"}, #endif - { - .eRes = {0.11333 * sqrt(dd4hep::GeV), 0.03, 0.0 * dd4hep::GeV}, // (11.333% / sqrt(E)) \oplus 3% - .tRes = 0.0, - .threshold = 0.0, - // .threshold = 15 * dd4hep::MeV for a single tower, applied on ADC level - .capADC = EcalEndcapP_capADC, - .capTime = 100, // given in ns, 4 samples in HGCROC - .dyRangeADC = EcalEndcapP_dyRangeADC, - .pedMeanADC = EcalEndcapP_pedMeanADC, - .pedSigmaADC = EcalEndcapP_pedSigmaADC, - .resolutionTDC = EcalEndcapP_resolutionTDC, - .corrMeanScale = "0.03", - .readout = "EcalEndcapPInsertHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapPInsertRecHits", {"EcalEndcapPInsertRawHits"}, {"EcalEndcapPInsertRecHits"}, - { - .capADC = EcalEndcapP_capADC, - .dyRangeADC = EcalEndcapP_dyRangeADC, - .pedMeanADC = EcalEndcapP_pedMeanADC, - .pedSigmaADC = EcalEndcapP_pedSigmaADC, - .resolutionTDC = EcalEndcapP_resolutionTDC, - .thresholdFactor = 0.0, - .thresholdValue = 2, // The ADC of a 15 MeV particle is adc = 200 + 15 * 0.03 * ( 1.0 + 0) / 3000 * 16384 = 200 + 2.4576 - .sampFrac = "0.03", - .readout = "EcalEndcapPInsertHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapPInsertTruthProtoClusters", {"EcalEndcapPInsertRecHits", "EcalEndcapPInsertHits"}, {"EcalEndcapPInsertTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapPInsertIslandProtoClusters", {"EcalEndcapPInsertRecHits"}, {"EcalEndcapPInsertIslandProtoClusters"}, - { - .sectorDist = 5.0 * dd4hep::cm, - .dimScaledLocalDistXY = {1.5,1.5}, - .splitCluster = false, - .minClusterHitEdep = 0.0 * dd4hep::MeV, - .minClusterCenterEdep = 60.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "dimScaledLocalDistXY", - .transverseEnergyProfileScale = 1., - }, - app // TODO: Remove me once fixed - )); + { + .eRes = {0.11333 * sqrt(dd4hep::GeV), 0.03, + 0.0 * dd4hep::GeV}, // (11.333% / sqrt(E)) \oplus 3% + .tRes = 0.0, + .threshold = 0.0, + // .threshold = 15 * dd4hep::MeV for a single tower, applied on ADC level + .capADC = EcalEndcapP_capADC, + .capTime = 100, // given in ns, 4 samples in HGCROC + .dyRangeADC = EcalEndcapP_dyRangeADC, + .pedMeanADC = EcalEndcapP_pedMeanADC, + .pedSigmaADC = EcalEndcapP_pedSigmaADC, + .resolutionTDC = EcalEndcapP_resolutionTDC, + .corrMeanScale = "0.03", + .readout = "EcalEndcapPInsertHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPInsertRecHits", {"EcalEndcapPInsertRawHits"}, {"EcalEndcapPInsertRecHits"}, + { + .capADC = EcalEndcapP_capADC, + .dyRangeADC = EcalEndcapP_dyRangeADC, + .pedMeanADC = EcalEndcapP_pedMeanADC, + .pedSigmaADC = EcalEndcapP_pedSigmaADC, + .resolutionTDC = EcalEndcapP_resolutionTDC, + .thresholdFactor = 0.0, + .thresholdValue = + 2, // The ADC of a 15 MeV particle is adc = 200 + 15 * 0.03 * ( 1.0 + 0) / 3000 * 16384 = 200 + 2.4576 + .sampFrac = "0.03", + .readout = "EcalEndcapPInsertHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPInsertTruthProtoClusters", {"EcalEndcapPInsertRecHits", "EcalEndcapPInsertHits"}, + {"EcalEndcapPInsertTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPInsertIslandProtoClusters", {"EcalEndcapPInsertRecHits"}, + {"EcalEndcapPInsertIslandProtoClusters"}, + { + .sectorDist = 5.0 * dd4hep::cm, + .dimScaledLocalDistXY = {1.5, 1.5}, + .splitCluster = false, + .minClusterHitEdep = 0.0 * dd4hep::MeV, + .minClusterCenterEdep = 60.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "dimScaledLocalDistXY", + .transverseEnergyProfileScale = 1., + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalEndcapPInsertTruthClusters", - {"EcalEndcapPInsertTruthProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPInsertTruthClusters", + {"EcalEndcapPInsertTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalEndcapPInsertRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitCollection + "EcalEndcapPInsertRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitCollection #else - "EcalEndcapPInsertHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalEndcapPInsertHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalEndcapPInsertTruthClusters", // edm4eic::Cluster - "EcalEndcapPInsertTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .enableEtaBounds = true - }, - app // TODO: Remove me once fixed - ) - ); + {"EcalEndcapPInsertTruthClusters", // edm4eic::Cluster + "EcalEndcapPInsertTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 6.2, .enableEtaBounds = true}, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalEndcapPInsertClusters", - {"EcalEndcapPInsertIslandProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapPInsertClusters", + {"EcalEndcapPInsertIslandProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalEndcapPInsertRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitCollection + "EcalEndcapPInsertRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitCollection #else - "EcalEndcapPInsertHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalEndcapPInsertHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalEndcapPInsertClusters", // edm4eic::Cluster - "EcalEndcapPInsertClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 3.6, - .enableEtaBounds = false, - }, - app // TODO: Remove me once fixed - ) - ); - - } + {"EcalEndcapPInsertClusters", // edm4eic::Cluster + "EcalEndcapPInsertClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + { + .energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 3.6, + .enableEtaBounds = false, + }, + app // TODO: Remove me once fixed + )); +} } diff --git a/src/detectors/FHCAL/FHCAL.cc b/src/detectors/FHCAL/FHCAL.cc index 36f7fb4797..fd9d4c4ab4 100644 --- a/src/detectors/FHCAL/FHCAL.cc +++ b/src/detectors/FHCAL/FHCAL.cc @@ -28,311 +28,287 @@ #include "services/geometry/dd4hep/DD4hep_service.h" extern "C" { - void InitPlugin(JApplication *app) { +void InitPlugin(JApplication* app) { - using namespace eicrecon; + using namespace eicrecon; - InitJANAPlugin(app); + InitJANAPlugin(app); - // Make sure digi and reco use the same value - decltype(CalorimeterHitDigiConfig::capADC) HcalEndcapPInsert_capADC = 32768; - decltype(CalorimeterHitDigiConfig::dyRangeADC) HcalEndcapPInsert_dyRangeADC = 200 * dd4hep::MeV; - decltype(CalorimeterHitDigiConfig::pedMeanADC) HcalEndcapPInsert_pedMeanADC = 10; - decltype(CalorimeterHitDigiConfig::pedSigmaADC) HcalEndcapPInsert_pedSigmaADC = 2; - decltype(CalorimeterHitDigiConfig::resolutionTDC) HcalEndcapPInsert_resolutionTDC = 10 * dd4hep::picosecond; + // Make sure digi and reco use the same value + decltype(CalorimeterHitDigiConfig::capADC) HcalEndcapPInsert_capADC = 32768; + decltype(CalorimeterHitDigiConfig::dyRangeADC) HcalEndcapPInsert_dyRangeADC = 200 * dd4hep::MeV; + decltype(CalorimeterHitDigiConfig::pedMeanADC) HcalEndcapPInsert_pedMeanADC = 10; + decltype(CalorimeterHitDigiConfig::pedSigmaADC) HcalEndcapPInsert_pedSigmaADC = 2; + decltype(CalorimeterHitDigiConfig::resolutionTDC) HcalEndcapPInsert_resolutionTDC = + 10 * dd4hep::picosecond; - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapPInsertRawHits", - {"HcalEndcapPInsertHits"}, + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapPInsertRawHits", {"HcalEndcapPInsertHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"HcalEndcapPInsertRawHits", "HcalEndcapPInsertRawHitAssociations"}, + {"HcalEndcapPInsertRawHits", "HcalEndcapPInsertRawHitAssociations"}, #else - {"HcalEndcapPInsertRawHits"}, + {"HcalEndcapPInsertRawHits"}, #endif - { - .eRes = {}, - .tRes = 0.0 * dd4hep::ns, - .capADC = HcalEndcapPInsert_capADC, - .dyRangeADC = HcalEndcapPInsert_dyRangeADC, - .pedMeanADC = HcalEndcapPInsert_pedMeanADC, - .pedSigmaADC = HcalEndcapPInsert_pedSigmaADC, - .resolutionTDC = HcalEndcapPInsert_resolutionTDC, - .corrMeanScale = "1.0", - .readout = "HcalEndcapPInsertHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapPInsertRecHits", {"HcalEndcapPInsertRawHits"}, {"HcalEndcapPInsertRecHits"}, - { - .capADC = HcalEndcapPInsert_capADC, - .dyRangeADC = HcalEndcapPInsert_dyRangeADC, - .pedMeanADC = HcalEndcapPInsert_pedMeanADC, - .pedSigmaADC = HcalEndcapPInsert_pedSigmaADC, - .resolutionTDC = HcalEndcapPInsert_resolutionTDC, - .thresholdFactor = 0., - .thresholdValue = 41.0, // 0.25 MeV --> 0.25 / 200 * 32768 = 41 + { + .eRes = {}, + .tRes = 0.0 * dd4hep::ns, + .capADC = HcalEndcapPInsert_capADC, + .dyRangeADC = HcalEndcapPInsert_dyRangeADC, + .pedMeanADC = HcalEndcapPInsert_pedMeanADC, + .pedSigmaADC = HcalEndcapPInsert_pedSigmaADC, + .resolutionTDC = HcalEndcapPInsert_resolutionTDC, + .corrMeanScale = "1.0", + .readout = "HcalEndcapPInsertHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapPInsertRecHits", {"HcalEndcapPInsertRawHits"}, {"HcalEndcapPInsertRecHits"}, + { + .capADC = HcalEndcapPInsert_capADC, + .dyRangeADC = HcalEndcapPInsert_dyRangeADC, + .pedMeanADC = HcalEndcapPInsert_pedMeanADC, + .pedSigmaADC = HcalEndcapPInsert_pedSigmaADC, + .resolutionTDC = HcalEndcapPInsert_resolutionTDC, + .thresholdFactor = 0., + .thresholdValue = 41.0, // 0.25 MeV --> 0.25 / 200 * 32768 = 41 - .sampFrac = "1.0", - .readout = "HcalEndcapPInsertHits", - .layerField="layer", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapPInsertMergedHits", {"HcalEndcapPInsertRecHits"}, {"HcalEndcapPInsertMergedHits"}, - { - .readout = "HcalEndcapPInsertHits", - .fieldTransformations = {"layer:1", "slice:0"} - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapPInsertTruthProtoClusters", {"HcalEndcapPInsertMergedHits", "HcalEndcapPInsertHits"}, {"HcalEndcapPInsertTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); + .sampFrac = "1.0", + .readout = "HcalEndcapPInsertHits", + .layerField = "layer", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapPInsertMergedHits", {"HcalEndcapPInsertRecHits"}, {"HcalEndcapPInsertMergedHits"}, + {.readout = "HcalEndcapPInsertHits", .fieldTransformations = {"layer:1", "slice:0"}}, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapPInsertTruthProtoClusters", + {"HcalEndcapPInsertMergedHits", "HcalEndcapPInsertHits"}, + {"HcalEndcapPInsertTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapPInsertSubcellHits", {"HcalEndcapPInsertRecHits"}, {"HcalEndcapPInsertSubcellHits"}, - { - .MIP = 480. * dd4hep::keV, - .Emin_in_MIPs=0.5, - .tmax=162 * dd4hep::ns, //150 ns + (z at front face)/(speed of light) - }, - app // TODO: Remove me once fixed + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapPInsertSubcellHits", {"HcalEndcapPInsertRecHits"}, + {"HcalEndcapPInsertSubcellHits"}, + { + .MIP = 480. * dd4hep::keV, + .Emin_in_MIPs = 0.5, + .tmax = 162 * dd4hep::ns, //150 ns + (z at front face)/(speed of light) + }, + app // TODO: Remove me once fixed )); - // define the distance between neighbors in terms of the largest possible distance between subcell hits - auto detector = app->GetService()->detector(); - double side_length; - try { - side_length = std::max({detector->constant("HcalEndcapPInsertCellSizeLGRight"), detector->constant("HcalEndcapPInsertCellSizeLGLeft")}); - } catch (std::runtime_error&) { - side_length = 31. * dd4hep::mm; - } - app->Add(new JOmniFactoryGeneratorT( - "HcalEndcapPInsertImagingProtoClusters", {"HcalEndcapPInsertSubcellHits"}, {"HcalEndcapPInsertImagingProtoClusters"}, - { - .neighbourLayersRange = 1, - .localDistXY = {0.5*side_length, 0.5*side_length*sin(M_PI/3)}, - .layerDistXY = {0.25*side_length, 0.25*side_length*sin(M_PI/3)}, - .layerMode = eicrecon::ImagingTopoClusterConfig::ELayerMode::xy, - .sectorDist = 10.0 * dd4hep::cm, - .minClusterHitEdep = 5.0 * dd4hep::keV, - .minClusterCenterEdep = 3.0 * dd4hep::MeV, - .minClusterEdep = 11.0 * dd4hep::MeV, - .minClusterNhits = 100, - }, - app // TODO: Remove me once fixed + // define the distance between neighbors in terms of the largest possible distance between subcell hits + auto detector = app->GetService()->detector(); + double side_length; + try { + side_length = std::max({detector->constant("HcalEndcapPInsertCellSizeLGRight"), + detector->constant("HcalEndcapPInsertCellSizeLGLeft")}); + } catch (std::runtime_error&) { + side_length = 31. * dd4hep::mm; + } + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapPInsertImagingProtoClusters", {"HcalEndcapPInsertSubcellHits"}, + {"HcalEndcapPInsertImagingProtoClusters"}, + { + .neighbourLayersRange = 1, + .localDistXY = {0.5 * side_length, 0.5 * side_length * sin(M_PI / 3)}, + .layerDistXY = {0.25 * side_length, 0.25 * side_length * sin(M_PI / 3)}, + .layerMode = eicrecon::ImagingTopoClusterConfig::ELayerMode::xy, + .sectorDist = 10.0 * dd4hep::cm, + .minClusterHitEdep = 5.0 * dd4hep::keV, + .minClusterCenterEdep = 3.0 * dd4hep::MeV, + .minClusterEdep = 11.0 * dd4hep::MeV, + .minClusterNhits = 100, + }, + app // TODO: Remove me once fixed )); - app->Add( - new JOmniFactoryGeneratorT( - "HcalEndcapPInsertTruthClusters", - {"HcalEndcapPInsertTruthProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapPInsertTruthClusters", + {"HcalEndcapPInsertTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "HcalEndcapPInsertRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "HcalEndcapPInsertRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "HcalEndcapPInsertHits"}, // edm4hep::SimCalorimeterHitCollection + "HcalEndcapPInsertHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"HcalEndcapPInsertTruthClusters", // edm4eic::Cluster - "HcalEndcapPInsertTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 0.0257, - .logWeightBase = 3.6, - .longitudinalShowerInfoAvailable = true, - .enableEtaBounds = true - }, - app // TODO: Remove me once fixed - ) - ); + {"HcalEndcapPInsertTruthClusters", // edm4eic::Cluster + "HcalEndcapPInsertTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", + .sampFrac = 0.0257, + .logWeightBase = 3.6, + .longitudinalShowerInfoAvailable = true, + .enableEtaBounds = true}, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "HcalEndcapPInsertClusters", - {"HcalEndcapPInsertImagingProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "HcalEndcapPInsertClusters", + {"HcalEndcapPInsertImagingProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "HcalEndcapPInsertRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "HcalEndcapPInsertRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "HcalEndcapPInsertHits"}, // edm4hep::SimCalorimeterHitCollection + "HcalEndcapPInsertHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"HcalEndcapPInsertClusters", // edm4eic::Cluster - "HcalEndcapPInsertClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 0.0257, - .logWeightBase = 6.2, - .longitudinalShowerInfoAvailable = true, - .enableEtaBounds = false, - }, - app // TODO: Remove me once fixed - ) - ); + {"HcalEndcapPInsertClusters", // edm4eic::Cluster + "HcalEndcapPInsertClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + { + .energyWeight = "log", + .sampFrac = 0.0257, + .logWeightBase = 6.2, + .longitudinalShowerInfoAvailable = true, + .enableEtaBounds = false, + }, + app // TODO: Remove me once fixed + )); - // Make sure digi and reco use the same value - decltype(CalorimeterHitDigiConfig::capADC) LFHCAL_capADC = 65536; - decltype(CalorimeterHitDigiConfig::dyRangeADC) LFHCAL_dyRangeADC = 1 * dd4hep::GeV; - decltype(CalorimeterHitDigiConfig::pedMeanADC) LFHCAL_pedMeanADC = 50; - decltype(CalorimeterHitDigiConfig::pedSigmaADC) LFHCAL_pedSigmaADC = 10; - decltype(CalorimeterHitDigiConfig::resolutionTDC) LFHCAL_resolutionTDC = 10 * dd4hep::picosecond; + // Make sure digi and reco use the same value + decltype(CalorimeterHitDigiConfig::capADC) LFHCAL_capADC = 65536; + decltype(CalorimeterHitDigiConfig::dyRangeADC) LFHCAL_dyRangeADC = 1 * dd4hep::GeV; + decltype(CalorimeterHitDigiConfig::pedMeanADC) LFHCAL_pedMeanADC = 50; + decltype(CalorimeterHitDigiConfig::pedSigmaADC) LFHCAL_pedSigmaADC = 10; + decltype(CalorimeterHitDigiConfig::resolutionTDC) LFHCAL_resolutionTDC = 10 * dd4hep::picosecond; - app->Add(new JOmniFactoryGeneratorT( - "LFHCALRawHits", - {"LFHCALHits"}, + app->Add(new JOmniFactoryGeneratorT( + "LFHCALRawHits", {"LFHCALHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"LFHCALRawHits", "LFHCALRawHitAssociations"}, + {"LFHCALRawHits", "LFHCALRawHitAssociations"}, #else - {"LFHCALRawHits"}, + {"LFHCALRawHits"}, #endif - { - .eRes = {}, - .tRes = 0.0 * dd4hep::ns, - .capADC = LFHCAL_capADC, - .capTime = 100, - .dyRangeADC = LFHCAL_dyRangeADC, - .pedMeanADC = LFHCAL_pedMeanADC, - .pedSigmaADC = LFHCAL_pedSigmaADC, - .resolutionTDC = LFHCAL_resolutionTDC, - .corrMeanScale = "1.0", - .readout = "LFHCALHits", - .fields = {"layerz"}, - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "LFHCALRecHits", {"LFHCALRawHits"}, {"LFHCALRecHits"}, - { - .capADC = LFHCAL_capADC, - .dyRangeADC = LFHCAL_dyRangeADC, - .pedMeanADC = LFHCAL_pedMeanADC, - .pedSigmaADC = LFHCAL_pedSigmaADC, - .resolutionTDC = LFHCAL_resolutionTDC, - .thresholdFactor = 0.0, - .thresholdValue = 20, // 0.3 MeV deposition --> adc = 50 + 0.3 / 1000 * 65536 == 70 - .sampFrac = "(rlayerz == 0) ? 0.019 : 0.037", // 0.019 only in the 0-th tile - .readout = "LFHCALHits", - .layerField = "rlayerz", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "LFHCALTruthProtoClusters", {"LFHCALRecHits", "LFHCALHits"}, {"LFHCALTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); + { + .eRes = {}, + .tRes = 0.0 * dd4hep::ns, + .capADC = LFHCAL_capADC, + .capTime = 100, + .dyRangeADC = LFHCAL_dyRangeADC, + .pedMeanADC = LFHCAL_pedMeanADC, + .pedSigmaADC = LFHCAL_pedSigmaADC, + .resolutionTDC = LFHCAL_resolutionTDC, + .corrMeanScale = "1.0", + .readout = "LFHCALHits", + .fields = {"layerz"}, + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "LFHCALRecHits", {"LFHCALRawHits"}, {"LFHCALRecHits"}, + { + .capADC = LFHCAL_capADC, + .dyRangeADC = LFHCAL_dyRangeADC, + .pedMeanADC = LFHCAL_pedMeanADC, + .pedSigmaADC = LFHCAL_pedSigmaADC, + .resolutionTDC = LFHCAL_resolutionTDC, + .thresholdFactor = 0.0, + .thresholdValue = 20, // 0.3 MeV deposition --> adc = 50 + 0.3 / 1000 * 65536 == 70 + .sampFrac = "(rlayerz == 0) ? 0.019 : 0.037", // 0.019 only in the 0-th tile + .readout = "LFHCALHits", + .layerField = "rlayerz", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "LFHCALTruthProtoClusters", {"LFHCALRecHits", "LFHCALHits"}, {"LFHCALTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); - // Magic constants: - // 54 - number of modules in a row/column - // 2 - number of towers in a module - // sign for towerx and towery are *negative* to maintain linearity with global X and Y - std::string cellIdx_1 = "(54*2-moduleIDx_1*2-towerx_1)"; - std::string cellIdx_2 = "(54*2-moduleIDx_2*2-towerx_2)"; - std::string cellIdy_1 = "(54*2-moduleIDy_1*2-towery_1)"; - std::string cellIdy_2 = "(54*2-moduleIDy_2*2-towery_2)"; - std::string cellIdz_1 = "rlayerz_1"; - std::string cellIdz_2 = "rlayerz_2"; - std::string deltaX = Form("abs(%s-%s)", cellIdx_2.data(), cellIdx_1.data()); - std::string deltaY = Form("abs(%s-%s)", cellIdy_2.data(), cellIdy_1.data()); - std::string deltaZ = Form("abs(%s-%s)", cellIdz_2.data(), cellIdz_1.data()); - std::string neighbor = Form("(%s+%s+%s==1)", deltaX.data(), deltaY.data(), deltaZ.data()); - std::string corner2D = Form("((%s==0&&%s==1&&%s==1)||(%s==1&&%s==0&&%s==1)||(%s==1&&%s==1&&%s==0))", - deltaZ.data(), deltaX.data(), deltaY.data(), - deltaZ.data(), deltaX.data(), deltaY.data(), - deltaZ.data(), deltaX.data(), deltaY.data()); + // Magic constants: + // 54 - number of modules in a row/column + // 2 - number of towers in a module + // sign for towerx and towery are *negative* to maintain linearity with global X and Y + std::string cellIdx_1 = "(54*2-moduleIDx_1*2-towerx_1)"; + std::string cellIdx_2 = "(54*2-moduleIDx_2*2-towerx_2)"; + std::string cellIdy_1 = "(54*2-moduleIDy_1*2-towery_1)"; + std::string cellIdy_2 = "(54*2-moduleIDy_2*2-towery_2)"; + std::string cellIdz_1 = "rlayerz_1"; + std::string cellIdz_2 = "rlayerz_2"; + std::string deltaX = Form("abs(%s-%s)", cellIdx_2.data(), cellIdx_1.data()); + std::string deltaY = Form("abs(%s-%s)", cellIdy_2.data(), cellIdy_1.data()); + std::string deltaZ = Form("abs(%s-%s)", cellIdz_2.data(), cellIdz_1.data()); + std::string neighbor = Form("(%s+%s+%s==1)", deltaX.data(), deltaY.data(), deltaZ.data()); + std::string corner2D = + Form("((%s==0&&%s==1&&%s==1)||(%s==1&&%s==0&&%s==1)||(%s==1&&%s==1&&%s==0))", deltaZ.data(), + deltaX.data(), deltaY.data(), deltaZ.data(), deltaX.data(), deltaY.data(), deltaZ.data(), + deltaX.data(), deltaY.data()); - app->Add(new JOmniFactoryGeneratorT( - "LFHCALIslandProtoClusters", {"LFHCALRecHits"}, {"LFHCALIslandProtoClusters"}, - { - .adjacencyMatrix = Form("%s||%s", neighbor.data(), corner2D.data()), - .readout = "LFHCALHits", - .sectorDist = 0 * dd4hep::cm, - .splitCluster = false, - .minClusterHitEdep = 1 * dd4hep::MeV, - .minClusterCenterEdep = 100.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "globalDistEtaPhi", - .transverseEnergyProfileScale = 1., - }, - app // TODO: Remove me once fixed - )); + app->Add(new JOmniFactoryGeneratorT( + "LFHCALIslandProtoClusters", {"LFHCALRecHits"}, {"LFHCALIslandProtoClusters"}, + { + .adjacencyMatrix = Form("%s||%s", neighbor.data(), corner2D.data()), + .readout = "LFHCALHits", + .sectorDist = 0 * dd4hep::cm, + .splitCluster = false, + .minClusterHitEdep = 1 * dd4hep::MeV, + .minClusterCenterEdep = 100.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "globalDistEtaPhi", + .transverseEnergyProfileScale = 1., + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "LFHCALTruthClusters", - {"LFHCALTruthProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "LFHCALTruthClusters", + {"LFHCALTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "LFHCALRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "LFHCALRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "LFHCALHits"}, // edm4hep::SimCalorimeterHitCollection + "LFHCALHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"LFHCALTruthClusters", // edm4eic::Cluster - "LFHCALTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 4.5, - .longitudinalShowerInfoAvailable = true, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); + {"LFHCALTruthClusters", // edm4eic::Cluster + "LFHCALTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 4.5, + .longitudinalShowerInfoAvailable = true, + .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "LFHCALClusters", - {"LFHCALIslandProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "LFHCALClusters", + {"LFHCALIslandProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "LFHCALRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "LFHCALRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "LFHCALHits"}, // edm4hep::SimCalorimeterHitCollection + "LFHCALHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"LFHCALClusters", // edm4eic::Cluster - "LFHCALClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 4.5, - .longitudinalShowerInfoAvailable = true, - .enableEtaBounds = false, - }, - app // TODO: Remove me once fixed - ) - ); + {"LFHCALClusters", // edm4eic::Cluster + "LFHCALClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + { + .energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 4.5, + .longitudinalShowerInfoAvailable = true, + .enableEtaBounds = false, + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "LFHCALSplitMergeProtoClusters", - {"LFHCALIslandProtoClusters", - "CalorimeterTrackProjections"}, - {"LFHCALSplitMergeProtoClusters"}, - { - .idCalo = "LFHCAL_ID", - .minSigCut = -2.0, - .avgEP = 0.50, - .sigEP = 0.25, - .drAdd = 0.30, - .sampFrac = 1.0, - .transverseEnergyProfileScale = 1.0 - }, - app // TODO: remove me once fixed - ) - ); + app->Add(new JOmniFactoryGeneratorT( + "LFHCALSplitMergeProtoClusters", {"LFHCALIslandProtoClusters", "CalorimeterTrackProjections"}, + {"LFHCALSplitMergeProtoClusters"}, + {.idCalo = "LFHCAL_ID", + .minSigCut = -2.0, + .avgEP = 0.50, + .sigEP = 0.25, + .drAdd = 0.30, + .sampFrac = 1.0, + .transverseEnergyProfileScale = 1.0}, + app // TODO: remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "LFHCALSplitMergeClusters", - {"LFHCALSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection - "LFHCALHits"}, // edm4hep::SimCalorimeterHitCollection - {"LFHCALSplitMergeClusters", // edm4eic::Cluster - "LFHCALSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 4.5, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); - } + app->Add(new JOmniFactoryGeneratorT( + "LFHCALSplitMergeClusters", + {"LFHCALSplitMergeProtoClusters", // edm4eic::ProtoClusterCollection + "LFHCALHits"}, // edm4hep::SimCalorimeterHitCollection + {"LFHCALSplitMergeClusters", // edm4eic::Cluster + "LFHCALSplitMergeClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 4.5, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); +} } diff --git a/src/detectors/FOFFMTRK/FOFFMTRK.cc b/src/detectors/FOFFMTRK/FOFFMTRK.cc index 8fe4d34323..b6d80a8228 100644 --- a/src/detectors/FOFFMTRK/FOFFMTRK.cc +++ b/src/detectors/FOFFMTRK/FOFFMTRK.cc @@ -13,61 +13,50 @@ #include "factories/fardetectors/MatrixTransferStatic_factory.h" #include "factories/tracking/TrackerHitReconstruction_factory.h" - extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - using namespace eicrecon; - - MatrixTransferStaticConfig recon_cfg; - - //Digitized hits, especially for thresholds - app->Add(new JOmniFactoryGeneratorT( - "ForwardOffMTrackerRawHits", - { - "ForwardOffMTrackerHits" - }, - { - "ForwardOffMTrackerRawHits", - "ForwardOffMTrackerRawHitAssociations" - }, - { - .threshold = 10.0 * dd4hep::keV, - .timeResolution = 8, - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "ForwardOffMTrackerRecHits", - {"ForwardOffMTrackerRawHits"}, - {"ForwardOffMTrackerRecHits"}, - { - .timeResolution = 8, - }, - app - )); - - //Static transport matrix for Off Momentum detectors - recon_cfg.aX = {{1.6248, 12.966293}, - {0.1832, -2.8636535}}; - recon_cfg.aY = {{0.0001674, -28.6003}, - {0.0000837, -2.87985}}; - - recon_cfg.local_x_offset = -11.9872; // in mm --> this is from misalignment of the detector - recon_cfg.local_y_offset = -0.0146; // in mm --> this is from misalignment of the detector - recon_cfg.local_x_slope_offset = -14.75315; // in mrad - recon_cfg.local_y_slope_offset = -0.0073; // in mrad - recon_cfg.nomMomentum = 137.5; // in GEV --> exactly half of the top energy momentum (for proton spectators from deuteron breakup) - - recon_cfg.hit1minZ = 22499.0; - recon_cfg.hit1maxZ = 22522.0; - recon_cfg.hit2minZ = 24499.0; - recon_cfg.hit2maxZ = 24522.0; - - recon_cfg.readout = "ForwardOffMTrackerRecHits"; - - app->Add(new JOmniFactoryGeneratorT("ForwardOffMRecParticles",{"MCParticles","ForwardOffMTrackerRecHits"},{"ForwardOffMRecParticles"},recon_cfg,app)); - +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + using namespace eicrecon; + + MatrixTransferStaticConfig recon_cfg; + + //Digitized hits, especially for thresholds + app->Add(new JOmniFactoryGeneratorT( + "ForwardOffMTrackerRawHits", {"ForwardOffMTrackerHits"}, + {"ForwardOffMTrackerRawHits", "ForwardOffMTrackerRawHitAssociations"}, + { + .threshold = 10.0 * dd4hep::keV, + .timeResolution = 8, + }, + app)); + + app->Add(new JOmniFactoryGeneratorT( + "ForwardOffMTrackerRecHits", {"ForwardOffMTrackerRawHits"}, {"ForwardOffMTrackerRecHits"}, + { + .timeResolution = 8, + }, + app)); + + //Static transport matrix for Off Momentum detectors + recon_cfg.aX = {{1.6248, 12.966293}, {0.1832, -2.8636535}}; + recon_cfg.aY = {{0.0001674, -28.6003}, {0.0000837, -2.87985}}; + + recon_cfg.local_x_offset = -11.9872; // in mm --> this is from misalignment of the detector + recon_cfg.local_y_offset = -0.0146; // in mm --> this is from misalignment of the detector + recon_cfg.local_x_slope_offset = -14.75315; // in mrad + recon_cfg.local_y_slope_offset = -0.0073; // in mrad + recon_cfg.nomMomentum = + 137.5; // in GEV --> exactly half of the top energy momentum (for proton spectators from deuteron breakup) + + recon_cfg.hit1minZ = 22499.0; + recon_cfg.hit1maxZ = 22522.0; + recon_cfg.hit2minZ = 24499.0; + recon_cfg.hit2maxZ = 24522.0; + + recon_cfg.readout = "ForwardOffMTrackerRecHits"; + + app->Add(new JOmniFactoryGeneratorT( + "ForwardOffMRecParticles", {"MCParticles", "ForwardOffMTrackerRecHits"}, + {"ForwardOffMRecParticles"}, recon_cfg, app)); } } diff --git a/src/detectors/LOWQ2/LOWQ2.cc b/src/detectors/LOWQ2/LOWQ2.cc index 1b5feb86fc..4b296cc12b 100644 --- a/src/detectors/LOWQ2/LOWQ2.cc +++ b/src/detectors/LOWQ2/LOWQ2.cc @@ -27,133 +27,107 @@ #include "factories/meta/SubDivideCollection_factory.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - - using namespace eicrecon; - - std::string tracker_readout = "TaggerTrackerHits"; - - // Digitization of silicon hits - app->Add(new JOmniFactoryGeneratorT( - "TaggerTrackerRawHits", - { - "TaggerTrackerHits" - }, - { - "TaggerTrackerRawHits", - "TaggerTrackerRawHitAssociations" - }, - { - .threshold = 1.5 * dd4hep::keV, - .timeResolution = 2 * dd4hep::ns, - }, - app - )); - - // Divide collection based on geometry segmentation labels - // This should really be done before digitization as summing hits in the same cell couldn't even be mixed between layers. At the moment just prep for clustering. - std::string readout = "TaggerTrackerHits"; - std::vector geometryLabels {"module","layer"}; - std::vector moduleIDs{1,2}; - std::vector layerIDs {0,1,2,3}; - std::vector> geometryDivisions{}; - std::vector geometryDivisionCollectionNames; - std::vector outputClusterCollectionNames; - std::vector outputTrackTags; - std::vector> moduleClusterTags; - - for(int mod_id : moduleIDs){ - outputTrackTags.push_back(fmt::format("TaggerTrackerM{}Tracks",mod_id)); - moduleClusterTags.push_back({}); - for(int lay_id : layerIDs){ - geometryDivisions.push_back({mod_id,lay_id}); - geometryDivisionCollectionNames.push_back(fmt::format("TaggerTrackerM{}L{}RawHits",mod_id,lay_id)); - outputClusterCollectionNames.push_back(fmt::format("TaggerTrackerM{}L{}ClusterPositions",mod_id,lay_id)); - moduleClusterTags.back().push_back(outputClusterCollectionNames.back()); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + + using namespace eicrecon; + + std::string tracker_readout = "TaggerTrackerHits"; + + // Digitization of silicon hits + app->Add(new JOmniFactoryGeneratorT( + "TaggerTrackerRawHits", {"TaggerTrackerHits"}, + {"TaggerTrackerRawHits", "TaggerTrackerRawHitAssociations"}, + { + .threshold = 1.5 * dd4hep::keV, + .timeResolution = 2 * dd4hep::ns, + }, + app)); + + // Divide collection based on geometry segmentation labels + // This should really be done before digitization as summing hits in the same cell couldn't even be mixed between layers. At the moment just prep for clustering. + std::string readout = "TaggerTrackerHits"; + std::vector geometryLabels{"module", "layer"}; + std::vector moduleIDs{1, 2}; + std::vector layerIDs{0, 1, 2, 3}; + std::vector> geometryDivisions{}; + std::vector geometryDivisionCollectionNames; + std::vector outputClusterCollectionNames; + std::vector outputTrackTags; + std::vector> moduleClusterTags; + + for (int mod_id : moduleIDs) { + outputTrackTags.push_back(fmt::format("TaggerTrackerM{}Tracks", mod_id)); + moduleClusterTags.push_back({}); + for (int lay_id : layerIDs) { + geometryDivisions.push_back({mod_id, lay_id}); + geometryDivisionCollectionNames.push_back( + fmt::format("TaggerTrackerM{}L{}RawHits", mod_id, lay_id)); + outputClusterCollectionNames.push_back( + fmt::format("TaggerTrackerM{}L{}ClusterPositions", mod_id, lay_id)); + moduleClusterTags.back().push_back(outputClusterCollectionNames.back()); } + } - app->Add(new JOmniFactoryGeneratorT>( - "TaggerTrackerSplitHits", - {"TaggerTrackerRawHits"}, - geometryDivisionCollectionNames, - { - .function = GeometrySplit{geometryDivisions,readout,geometryLabels}, - }, - app - ) - ); - - - app->Add(new JOmniFactoryGeneratorT( - "TaggerTrackerClustering", - geometryDivisionCollectionNames, - outputClusterCollectionNames, - { - .readout = "TaggerTrackerHits", - .x_field = "x", - .y_field = "y", + app->Add(new JOmniFactoryGeneratorT>( + "TaggerTrackerSplitHits", {"TaggerTrackerRawHits"}, geometryDivisionCollectionNames, + { + .function = GeometrySplit{geometryDivisions, readout, geometryLabels}, + }, + app)); + + app->Add(new JOmniFactoryGeneratorT( + "TaggerTrackerClustering", geometryDivisionCollectionNames, outputClusterCollectionNames, + { + .readout = "TaggerTrackerHits", + .x_field = "x", + .y_field = "y", .hit_time_limit = 10 * edm4eic::unit::ns, - }, - app - )); + }, + app)); - // Linear tracking for each module, loop over modules - for(int i=0; i inputClusterTags = moduleClusterTags[i]; + // Linear tracking for each module, loop over modules + for (int i = 0; i < moduleIDs.size(); i++) { + std::string outputTrackTag = outputTrackTags[i]; + std::vector inputClusterTags = moduleClusterTags[i]; - app->Add(new JOmniFactoryGeneratorT( - outputTrackTag, - inputClusterTags, - {outputTrackTag}, - { - .layer_hits_max = 100, - .chi2_max = 0.001, - .n_layer = 4, - .restrict_direction = true, - .optimum_theta = -M_PI+0.026, - .optimum_phi = 0, - .step_angle_tolerance = 0.05, - }, - app - )); - } - - // Combine the tracks from each module into one collection - app->Add(new JOmniFactoryGeneratorT>( - "TaggerTrackerTrackSegments", - outputTrackTags, - {"TaggerTrackerTrackSegments"}, - app - ) - ); - - // Project tracks onto a plane - app->Add(new JOmniFactoryGeneratorT( - "TaggerTrackerProjectedTracks", - {"TaggerTrackerTrackSegments"}, - {"TaggerTrackerProjectedTracks"}, - { - .plane_position = {0.0,0.0,0.0}, - .plane_a = {0.0,1.0,0.0}, - .plane_b = {0.0,0.0,1.0}, - }, - app - )); - - // Vector reconstruction at origin - app->Add(new JOmniFactoryGeneratorT( - "TaggerTrackerTrajectories", - {"TaggerTrackerProjectedTracks","MCBeamElectrons"}, - {"TaggerTrackerTrajectories","TaggerTrackerTrackParameters","TaggerTrackerTracks"}, + app->Add(new JOmniFactoryGeneratorT( + outputTrackTag, inputClusterTags, {outputTrackTag}, { - .modelPath = "calibrations/tmva/LowQ2_DNN_CPU.weights.xml", - .methodName = "DNN_CPU", + .layer_hits_max = 100, + .chi2_max = 0.001, + .n_layer = 4, + .restrict_direction = true, + .optimum_theta = -M_PI + 0.026, + .optimum_phi = 0, + .step_angle_tolerance = 0.05, }, - app - )); - + app)); } + + // Combine the tracks from each module into one collection + app->Add(new JOmniFactoryGeneratorT>( + "TaggerTrackerTrackSegments", outputTrackTags, {"TaggerTrackerTrackSegments"}, app)); + + // Project tracks onto a plane + app->Add(new JOmniFactoryGeneratorT( + "TaggerTrackerProjectedTracks", {"TaggerTrackerTrackSegments"}, + {"TaggerTrackerProjectedTracks"}, + { + .plane_position = {0.0, 0.0, 0.0}, + .plane_a = {0.0, 1.0, 0.0}, + .plane_b = {0.0, 0.0, 1.0}, + }, + app)); + + // Vector reconstruction at origin + app->Add(new JOmniFactoryGeneratorT( + "TaggerTrackerTrajectories", {"TaggerTrackerProjectedTracks", "MCBeamElectrons"}, + {"TaggerTrackerTrajectories", "TaggerTrackerTrackParameters", "TaggerTrackerTracks"}, + { + .modelPath = "calibrations/tmva/LowQ2_DNN_CPU.weights.xml", + .methodName = "DNN_CPU", + }, + app)); +} } diff --git a/src/detectors/LUMISPECCAL/LUMISPECCAL.cc b/src/detectors/LUMISPECCAL/LUMISPECCAL.cc index 4e724e545e..60f983ebe9 100644 --- a/src/detectors/LUMISPECCAL/LUMISPECCAL.cc +++ b/src/detectors/LUMISPECCAL/LUMISPECCAL.cc @@ -18,107 +18,96 @@ #include "factories/calorimetry/CalorimeterTruthClustering_factory.h" extern "C" { - void InitPlugin(JApplication *app) { +void InitPlugin(JApplication* app) { - using namespace eicrecon; + using namespace eicrecon; - InitJANAPlugin(app); + InitJANAPlugin(app); - app->Add(new JOmniFactoryGeneratorT( - "EcalLumiSpecRawHits", - {"EcalLumiSpecHits"}, + app->Add(new JOmniFactoryGeneratorT( + "EcalLumiSpecRawHits", {"EcalLumiSpecHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"EcalLumiSpecRawHits", "EcalLumiSpecRawHitAssociations"}, + {"EcalLumiSpecRawHits", "EcalLumiSpecRawHitAssociations"}, #else - {"EcalLumiSpecRawHits"}, + {"EcalLumiSpecRawHits"}, #endif - { - .eRes = {0.0 * sqrt(dd4hep::GeV), 0.02, 0.0 * dd4hep::GeV}, // flat 2% - .tRes = 0.0 * dd4hep::ns, - .capADC = 16384, - .dyRangeADC = 20 * dd4hep::GeV, - .pedMeanADC = 100, - .pedSigmaADC = 1, - .resolutionTDC = 10 * dd4hep::picosecond, - .corrMeanScale = "1.0", - .readout = "EcalLumiSpecHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalLumiSpecRecHits", {"EcalLumiSpecRawHits"}, {"EcalLumiSpecRecHits"}, - { - .capADC = 16384, - .dyRangeADC = 20. * dd4hep::GeV, - .pedMeanADC = 100, - .pedSigmaADC = 1, - .resolutionTDC = 10 * dd4hep::picosecond, - .thresholdFactor = 0.0, - .thresholdValue = 2.0, - .sampFrac = "1.0", - .readout = "EcalLumiSpecHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalLumiSpecTruthProtoClusters", {"EcalLumiSpecRecHits", "EcalLumiSpecHits"}, {"EcalLumiSpecTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalLumiSpecIslandProtoClusters", {"EcalLumiSpecRecHits"}, {"EcalLumiSpecIslandProtoClusters"}, - { - .adjacencyMatrix = "(sector_1 == sector_2) && ((abs(floor(module_1 / 10) - floor(module_2 / 10)) + abs(fmod(module_1, 10) - fmod(module_2, 10))) == 1)", - .readout = "EcalLumiSpecHits", - .sectorDist = 0.0 * dd4hep::cm, - .splitCluster=true, - .minClusterHitEdep = 1.0 * dd4hep::MeV, - .minClusterCenterEdep = 30.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "localDistXY", - .transverseEnergyProfileScale = 10. * dd4hep::mm, - }, - app // TODO: Remove me once fixed - )); + { + .eRes = {0.0 * sqrt(dd4hep::GeV), 0.02, 0.0 * dd4hep::GeV}, // flat 2% + .tRes = 0.0 * dd4hep::ns, + .capADC = 16384, + .dyRangeADC = 20 * dd4hep::GeV, + .pedMeanADC = 100, + .pedSigmaADC = 1, + .resolutionTDC = 10 * dd4hep::picosecond, + .corrMeanScale = "1.0", + .readout = "EcalLumiSpecHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalLumiSpecRecHits", {"EcalLumiSpecRawHits"}, {"EcalLumiSpecRecHits"}, + { + .capADC = 16384, + .dyRangeADC = 20. * dd4hep::GeV, + .pedMeanADC = 100, + .pedSigmaADC = 1, + .resolutionTDC = 10 * dd4hep::picosecond, + .thresholdFactor = 0.0, + .thresholdValue = 2.0, + .sampFrac = "1.0", + .readout = "EcalLumiSpecHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalLumiSpecTruthProtoClusters", {"EcalLumiSpecRecHits", "EcalLumiSpecHits"}, + {"EcalLumiSpecTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalLumiSpecIslandProtoClusters", {"EcalLumiSpecRecHits"}, + {"EcalLumiSpecIslandProtoClusters"}, + { + .adjacencyMatrix = + "(sector_1 == sector_2) && ((abs(floor(module_1 / 10) - floor(module_2 / 10)) + " + "abs(fmod(module_1, 10) - fmod(module_2, 10))) == 1)", + .readout = "EcalLumiSpecHits", + .sectorDist = 0.0 * dd4hep::cm, + .splitCluster = true, + .minClusterHitEdep = 1.0 * dd4hep::MeV, + .minClusterCenterEdep = 30.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "localDistXY", + .transverseEnergyProfileScale = 10. * dd4hep::mm, + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalLumiSpecClusters", - {"EcalLumiSpecIslandProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "EcalLumiSpecClusters", + {"EcalLumiSpecIslandProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalLumiSpecRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "EcalLumiSpecRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "EcalLumiSpecHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalLumiSpecHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalLumiSpecClusters", // edm4eic::Cluster - "EcalLumiSpecClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 3.6, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); + {"EcalLumiSpecClusters", // edm4eic::Cluster + "EcalLumiSpecClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 3.6, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalLumiSpecTruthClusters", - {"EcalLumiSpecTruthProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "EcalLumiSpecTruthClusters", + {"EcalLumiSpecTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalLumiSpecRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "EcalLumiSpecRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "EcalLumiSpecHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalLumiSpecHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalLumiSpecTruthClusters", // edm4eic::Cluster - "EcalLumiSpecTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 4.6, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); - } + {"EcalLumiSpecTruthClusters", // edm4eic::Cluster + "EcalLumiSpecTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", .sampFrac = 1.0, .logWeightBase = 4.6, .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); +} } diff --git a/src/detectors/MPGD/MPGD.cc b/src/detectors/MPGD/MPGD.cc index ea29ae3c64..c9b2b20bfd 100644 --- a/src/detectors/MPGD/MPGD.cc +++ b/src/detectors/MPGD/MPGD.cc @@ -13,122 +13,85 @@ #include "factories/tracking/TrackerHitReconstruction_factory.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "MPGDBarrelRawHits", - { - "MPGDBarrelHits" - }, - { - "MPGDBarrelRawHits", - "MPGDBarrelRawHitAssociations" - }, - { - .threshold = 100 * dd4hep::eV, - .timeResolution = 10, - }, - app - )); + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "MPGDBarrelRawHits", {"MPGDBarrelHits"}, + {"MPGDBarrelRawHits", "MPGDBarrelRawHitAssociations"}, + { + .threshold = 100 * dd4hep::eV, + .timeResolution = 10, + }, + app)); - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "MPGDBarrelRecHits", - {"MPGDBarrelRawHits"}, // Input data collection tags - {"MPGDBarrelRecHits"}, // Output data tag - { - .timeResolution = 10, - }, - app - )); + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "MPGDBarrelRecHits", {"MPGDBarrelRawHits"}, // Input data collection tags + {"MPGDBarrelRecHits"}, // Output data tag + { + .timeResolution = 10, + }, + app)); - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "OuterMPGDBarrelRawHits", - { - "OuterMPGDBarrelHits" - }, - { - "OuterMPGDBarrelRawHits", - "OuterMPGDBarrelRawHitAssociations" - }, - { - .threshold = 100 * dd4hep::eV, - .timeResolution = 10, - }, - app - )); + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "OuterMPGDBarrelRawHits", {"OuterMPGDBarrelHits"}, + {"OuterMPGDBarrelRawHits", "OuterMPGDBarrelRawHitAssociations"}, + { + .threshold = 100 * dd4hep::eV, + .timeResolution = 10, + }, + app)); - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "OuterMPGDBarrelRecHits", - {"OuterMPGDBarrelRawHits"}, // Input data collection tags - {"OuterMPGDBarrelRecHits"}, // Output data tag - { - .timeResolution = 10, - }, - app - )); + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "OuterMPGDBarrelRecHits", {"OuterMPGDBarrelRawHits"}, // Input data collection tags + {"OuterMPGDBarrelRecHits"}, // Output data tag + { + .timeResolution = 10, + }, + app)); - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "BackwardMPGDEndcapRawHits", - { - "BackwardMPGDEndcapHits" - }, - { - "BackwardMPGDEndcapRawHits", - "BackwardMPGDEndcapRawHitAssociations" - }, - { - .threshold = 100 * dd4hep::eV, - .timeResolution = 10, - }, - app - )); + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "BackwardMPGDEndcapRawHits", {"BackwardMPGDEndcapHits"}, + {"BackwardMPGDEndcapRawHits", "BackwardMPGDEndcapRawHitAssociations"}, + { + .threshold = 100 * dd4hep::eV, + .timeResolution = 10, + }, + app)); - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "BackwardMPGDEndcapRecHits", - {"BackwardMPGDEndcapRawHits"}, // Input data collection tags - {"BackwardMPGDEndcapRecHits"}, // Output data tag - { - .timeResolution = 10, - }, - app - )); + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "BackwardMPGDEndcapRecHits", {"BackwardMPGDEndcapRawHits"}, // Input data collection tags + {"BackwardMPGDEndcapRecHits"}, // Output data tag + { + .timeResolution = 10, + }, + app)); - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "ForwardMPGDEndcapRawHits", - { - "ForwardMPGDEndcapHits" - }, - { - "ForwardMPGDEndcapRawHits", - "ForwardMPGDEndcapRawHitAssociations" - }, - { - .threshold = 100 * dd4hep::eV, - .timeResolution = 10, - }, - app - )); - - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "ForwardMPGDEndcapRecHits", - {"ForwardMPGDEndcapRawHits"}, // Input data collection tags - {"ForwardMPGDEndcapRecHits"}, // Output data tag - { - .timeResolution = 10, - }, - app - )); + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "ForwardMPGDEndcapRawHits", {"ForwardMPGDEndcapHits"}, + {"ForwardMPGDEndcapRawHits", "ForwardMPGDEndcapRawHitAssociations"}, + { + .threshold = 100 * dd4hep::eV, + .timeResolution = 10, + }, + app)); + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "ForwardMPGDEndcapRecHits", {"ForwardMPGDEndcapRawHits"}, // Input data collection tags + {"ForwardMPGDEndcapRecHits"}, // Output data tag + { + .timeResolution = 10, + }, + app)); } } // extern "C" diff --git a/src/detectors/PFRICH/PFRICH.cc b/src/detectors/PFRICH/PFRICH.cc index b88ce839a9..959bfba305 100644 --- a/src/detectors/PFRICH/PFRICH.cc +++ b/src/detectors/PFRICH/PFRICH.cc @@ -25,107 +25,88 @@ #include "services/geometry/dd4hep/DD4hep_service.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // configuration parameters /////////////////////////////////////////////// + // configuration parameters /////////////////////////////////////////////// - // digitization - PhotoMultiplierHitDigiConfig digi_cfg; - digi_cfg.seed = 5; // FIXME: set to 0 for a 'unique' seed, but - // that seems to delay the RNG from actually randomizing - digi_cfg.hitTimeWindow = 20.0; // [ns] - digi_cfg.timeResolution = 1/16.0; // [ns] - digi_cfg.speMean = 80.0; - digi_cfg.speError = 16.0; - digi_cfg.pedMean = 200.0; - digi_cfg.pedError = 3.0; - digi_cfg.enablePixelGaps = true; - digi_cfg.safetyFactor = 0.7; - digi_cfg.enableNoise = false; - digi_cfg.noiseRate = 20000; // [Hz] - digi_cfg.noiseTimeWindow = 20.0 * dd4hep::ns; // [ns] - digi_cfg.quantumEfficiency.clear(); - digi_cfg.quantumEfficiency = { // wavelength units are [nm] - {315, 0.00}, - {325, 0.04}, - {340, 0.10}, - {350, 0.20}, - {370, 0.30}, - {400, 0.35}, - {450, 0.40}, - {500, 0.38}, - {550, 0.35}, - {600, 0.27}, - {650, 0.20}, - {700, 0.15}, - {750, 0.12}, - {800, 0.08}, - {850, 0.06}, - {900, 0.04}, - {1000, 0.00} - }; + // digitization + PhotoMultiplierHitDigiConfig digi_cfg; + digi_cfg.seed = 5; // FIXME: set to 0 for a 'unique' seed, but + // that seems to delay the RNG from actually randomizing + digi_cfg.hitTimeWindow = 20.0; // [ns] + digi_cfg.timeResolution = 1 / 16.0; // [ns] + digi_cfg.speMean = 80.0; + digi_cfg.speError = 16.0; + digi_cfg.pedMean = 200.0; + digi_cfg.pedError = 3.0; + digi_cfg.enablePixelGaps = true; + digi_cfg.safetyFactor = 0.7; + digi_cfg.enableNoise = false; + digi_cfg.noiseRate = 20000; // [Hz] + digi_cfg.noiseTimeWindow = 20.0 * dd4hep::ns; // [ns] + digi_cfg.quantumEfficiency.clear(); + digi_cfg.quantumEfficiency = {// wavelength units are [nm] + {315, 0.00}, {325, 0.04}, {340, 0.10}, {350, 0.20}, {370, 0.30}, + {400, 0.35}, {450, 0.40}, {500, 0.38}, {550, 0.35}, {600, 0.27}, + {650, 0.20}, {700, 0.15}, {750, 0.12}, {800, 0.08}, {850, 0.06}, + {900, 0.04}, {1000, 0.00}}; - // digitization - app->Add(new JOmniFactoryGeneratorT( - "RICHEndcapNRawHits", - {"RICHEndcapNHits"}, - {"RICHEndcapNRawHits", "RICHEndcapNRawHitsAssociations"}, - digi_cfg, - app - )); + // digitization + app->Add(new JOmniFactoryGeneratorT( + "RICHEndcapNRawHits", {"RICHEndcapNHits"}, + {"RICHEndcapNRawHits", "RICHEndcapNRawHitsAssociations"}, digi_cfg, app)); - int BackwardRICH_ID = 0; - try { - auto detector = app->GetService()->detector(); - BackwardRICH_ID = detector->constant("BackwardRICH_ID"); - } catch(const std::runtime_error&) { - // Nothing - } - PIDLookupConfig pid_cfg { - .filename="calibrations/pfrich.lut", - .system=BackwardRICH_ID, - .pdg_values={11, 211, 321, 2212}, - .charge_values={1}, - .momentum_edges={0.4, 0.8, 1.2, 1.6, 2, 2.4, 2.8, 3.2, 3.6, 4, 4.4, 4.8, 5.2, 5.6, 6, 6.4, 6.8, 7.2, 7.6, 8, 8.4, 8.8, 9.2, 9.6, 10, 10.4, 10.8, 11.2, 11.6, 12, 12.4, 12.8, 13.2, 13.6, 14, 14.4, 14.8, 15.2}, - .polar_edges={2.65, 2.6725, 2.695, 2.7175, 2.74, 2.7625, 2.785, 2.8075, 2.83, 2.8525, 2.875, 2.8975, 2.92, 2.9425, 2.965, 2.9875, 3.01, 3.0325, 3.055, 3.0775}, - .azimuthal_binning={0., 2 * M_PI, 2 * M_PI / 120.}, // lower, upper, step - .azimuthal_bin_centers_in_lut=true, - .momentum_bin_centers_in_lut=true, - .polar_bin_centers_in_lut=true, - .use_radians=true, - }; + int BackwardRICH_ID = 0; + try { + auto detector = app->GetService()->detector(); + BackwardRICH_ID = detector->constant("BackwardRICH_ID"); + } catch (const std::runtime_error&) { + // Nothing + } + PIDLookupConfig pid_cfg{ + .filename = "calibrations/pfrich.lut", + .system = BackwardRICH_ID, + .pdg_values = {11, 211, 321, 2212}, + .charge_values = {1}, + .momentum_edges = {0.4, 0.8, 1.2, 1.6, 2, 2.4, 2.8, 3.2, 3.6, 4, 4.4, 4.8, 5.2, + 5.6, 6, 6.4, 6.8, 7.2, 7.6, 8, 8.4, 8.8, 9.2, 9.6, 10, 10.4, + 10.8, 11.2, 11.6, 12, 12.4, 12.8, 13.2, 13.6, 14, 14.4, 14.8, 15.2}, + .polar_edges = {2.65, 2.6725, 2.695, 2.7175, 2.74, 2.7625, 2.785, 2.8075, 2.83, 2.8525, + 2.875, 2.8975, 2.92, 2.9425, 2.965, 2.9875, 3.01, 3.0325, 3.055, 3.0775}, + .azimuthal_binning = {0., 2 * M_PI, 2 * M_PI / 120.}, // lower, upper, step + .azimuthal_bin_centers_in_lut = true, + .momentum_bin_centers_in_lut = true, + .polar_bin_centers_in_lut = true, + .use_radians = true, + }; - app->Add(new JOmniFactoryGeneratorT( - "RICHEndcapNTruthSeededLUTPID", - { + app->Add(new JOmniFactoryGeneratorT( + "RICHEndcapNTruthSeededLUTPID", + { "ReconstructedTruthSeededChargedWithoutPIDParticles", "ReconstructedTruthSeededChargedWithoutPIDParticleAssociations", - }, - { + }, + { "ReconstructedTruthSeededChargedWithPFRICHPIDParticles", "ReconstructedTruthSeededChargedWithPFRICHPIDParticleAssociations", "RICHEndcapNTruthSeededParticleIDs", - }, - pid_cfg, - app - )); + }, + pid_cfg, app)); - app->Add(new JOmniFactoryGeneratorT( - "RICHEndcapNLUTPID", - { + app->Add(new JOmniFactoryGeneratorT( + "RICHEndcapNLUTPID", + { "ReconstructedChargedWithoutPIDParticles", "ReconstructedChargedWithoutPIDParticleAssociations", - }, - { + }, + { "ReconstructedChargedWithPFRICHPIDParticles", "ReconstructedChargedWithPFRICHPIDParticleAssociations", "RICHEndcapNParticleIDs", - }, - pid_cfg, - app - )); - } + }, + pid_cfg, app)); +} } diff --git a/src/detectors/RPOTS/RPOTS.cc b/src/detectors/RPOTS/RPOTS.cc index c374f691dc..4279ffff60 100644 --- a/src/detectors/RPOTS/RPOTS.cc +++ b/src/detectors/RPOTS/RPOTS.cc @@ -13,62 +13,50 @@ #include "factories/fardetectors/MatrixTransferStatic_factory.h" #include "factories/tracking/TrackerHitReconstruction_factory.h" - extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - using namespace eicrecon; - - MatrixTransferStaticConfig recon_cfg; - - //Digitized hits, especially for thresholds - app->Add(new JOmniFactoryGeneratorT( - "ForwardRomanPotRawHits", - { - "ForwardRomanPotHits" - }, - { - "ForwardRomanPotRawHits", - "ForwardRomanPotRawHitAssociations" - }, - { - .threshold = 10.0 * dd4hep::keV, - .timeResolution = 8, - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "ForwardRomanPotRecHits", - {"ForwardRomanPotRawHits"}, - {"ForwardRomanPotRecHits"}, - { - .timeResolution = 8, - }, - app - )); - - - //Static transport matrix for Roman Pots detectors - recon_cfg.aX = {{2.102403743, 29.11067626}, - {0.186640381, 0.192604619}}; - recon_cfg.aY = {{0.0000159900, 3.94082098}, - {0.0000079946, -0.1402995}}; - - recon_cfg.local_x_offset = 0.0; // in mm --> this is from misalignment of the detector - recon_cfg.local_y_offset = 0.0; // in mm --> this is from misalignment of the detector - recon_cfg.local_x_slope_offset = -0.00622147; // in mrad - recon_cfg.local_y_slope_offset = -0.0451035; // in mrad - recon_cfg.nomMomentum = 275.0; // in GEV --> exactly half of the top energy momentum (for proton spectators from deuteron breakup) - - recon_cfg.hit1minZ = 32541.0; - recon_cfg.hit1maxZ = 32554.0; - recon_cfg.hit2minZ = 34239.0; - recon_cfg.hit2maxZ = 34252.0; - - recon_cfg.readout = "ForwardRomanPotRecHits"; - - app->Add(new JOmniFactoryGeneratorT("ForwardRomanPotRecParticles",{"MCParticles","ForwardRomanPotRecHits"},{"ForwardRomanPotRecParticles"},recon_cfg,app)); - +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + using namespace eicrecon; + + MatrixTransferStaticConfig recon_cfg; + + //Digitized hits, especially for thresholds + app->Add(new JOmniFactoryGeneratorT( + "ForwardRomanPotRawHits", {"ForwardRomanPotHits"}, + {"ForwardRomanPotRawHits", "ForwardRomanPotRawHitAssociations"}, + { + .threshold = 10.0 * dd4hep::keV, + .timeResolution = 8, + }, + app)); + + app->Add(new JOmniFactoryGeneratorT( + "ForwardRomanPotRecHits", {"ForwardRomanPotRawHits"}, {"ForwardRomanPotRecHits"}, + { + .timeResolution = 8, + }, + app)); + + //Static transport matrix for Roman Pots detectors + recon_cfg.aX = {{2.102403743, 29.11067626}, {0.186640381, 0.192604619}}; + recon_cfg.aY = {{0.0000159900, 3.94082098}, {0.0000079946, -0.1402995}}; + + recon_cfg.local_x_offset = 0.0; // in mm --> this is from misalignment of the detector + recon_cfg.local_y_offset = 0.0; // in mm --> this is from misalignment of the detector + recon_cfg.local_x_slope_offset = -0.00622147; // in mrad + recon_cfg.local_y_slope_offset = -0.0451035; // in mrad + recon_cfg.nomMomentum = + 275.0; // in GEV --> exactly half of the top energy momentum (for proton spectators from deuteron breakup) + + recon_cfg.hit1minZ = 32541.0; + recon_cfg.hit1maxZ = 32554.0; + recon_cfg.hit2minZ = 34239.0; + recon_cfg.hit2maxZ = 34252.0; + + recon_cfg.readout = "ForwardRomanPotRecHits"; + + app->Add(new JOmniFactoryGeneratorT( + "ForwardRomanPotRecParticles", {"MCParticles", "ForwardRomanPotRecHits"}, + {"ForwardRomanPotRecParticles"}, recon_cfg, app)); } } diff --git a/src/detectors/ZDC/ZDC.cc b/src/detectors/ZDC/ZDC.cc index 8a6d7954cc..9c8a5c5d66 100644 --- a/src/detectors/ZDC/ZDC.cc +++ b/src/detectors/ZDC/ZDC.cc @@ -20,270 +20,264 @@ #include "factories/calorimetry/ImagingTopoCluster_factory.h" extern "C" { - void InitPlugin(JApplication *app) { +void InitPlugin(JApplication* app) { - using namespace eicrecon; + using namespace eicrecon; - InitJANAPlugin(app); + InitJANAPlugin(app); - // LYSO part of the ZDC - app->Add(new JOmniFactoryGeneratorT( - "EcalFarForwardZDCRawHits", - {"EcalFarForwardZDCHits"}, + // LYSO part of the ZDC + app->Add(new JOmniFactoryGeneratorT( + "EcalFarForwardZDCRawHits", {"EcalFarForwardZDCHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"EcalFarForwardZDCRawHits", "EcalFarForwardZDCRawHitAssociations"}, + {"EcalFarForwardZDCRawHits", "EcalFarForwardZDCRawHitAssociations"}, #else - {"EcalFarForwardZDCRawHits"}, + {"EcalFarForwardZDCRawHits"}, #endif - { - .tRes = 0.0 * dd4hep::ns, - .capADC = 32768, - .dyRangeADC = 2000 * dd4hep::MeV, - .pedMeanADC = 400, - .pedSigmaADC = 3.2, - .resolutionTDC = 10 * dd4hep::picosecond, - .corrMeanScale = "1.0", - .readout = "EcalFarForwardZDCHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalFarForwardZDCRecHits", {"EcalFarForwardZDCRawHits"}, {"EcalFarForwardZDCRecHits"}, - { - .capADC = 32768, - .dyRangeADC = 2000. * dd4hep::MeV, - .pedMeanADC = 400, - .pedSigmaADC = 3.2, - .resolutionTDC = 10 * dd4hep::picosecond, - .thresholdFactor = 4.0, - .thresholdValue = 0.0, - .sampFrac = "1.0", - .readout = "EcalFarForwardZDCHits", - }, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalFarForwardZDCTruthProtoClusters", {"EcalFarForwardZDCRecHits", "EcalFarForwardZDCHits"}, {"EcalFarForwardZDCTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); - app->Add(new JOmniFactoryGeneratorT( - "EcalFarForwardZDCIslandProtoClusters", {"EcalFarForwardZDCRecHits"}, {"EcalFarForwardZDCIslandProtoClusters"}, - { - .sectorDist = 5.0 * dd4hep::cm, - .localDistXY = {50 * dd4hep::cm, 50 * dd4hep::cm}, - .splitCluster = true, - .minClusterHitEdep = 0.1 * dd4hep::MeV, - .minClusterCenterEdep = 3.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "globalDistEtaPhi", - .transverseEnergyProfileScale = 1., - }, - app // TODO: Remove me once fixed - )); + { + .tRes = 0.0 * dd4hep::ns, + .capADC = 32768, + .dyRangeADC = 2000 * dd4hep::MeV, + .pedMeanADC = 400, + .pedSigmaADC = 3.2, + .resolutionTDC = 10 * dd4hep::picosecond, + .corrMeanScale = "1.0", + .readout = "EcalFarForwardZDCHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalFarForwardZDCRecHits", {"EcalFarForwardZDCRawHits"}, {"EcalFarForwardZDCRecHits"}, + { + .capADC = 32768, + .dyRangeADC = 2000. * dd4hep::MeV, + .pedMeanADC = 400, + .pedSigmaADC = 3.2, + .resolutionTDC = 10 * dd4hep::picosecond, + .thresholdFactor = 4.0, + .thresholdValue = 0.0, + .sampFrac = "1.0", + .readout = "EcalFarForwardZDCHits", + }, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalFarForwardZDCTruthProtoClusters", {"EcalFarForwardZDCRecHits", "EcalFarForwardZDCHits"}, + {"EcalFarForwardZDCTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); + app->Add(new JOmniFactoryGeneratorT( + "EcalFarForwardZDCIslandProtoClusters", {"EcalFarForwardZDCRecHits"}, + {"EcalFarForwardZDCIslandProtoClusters"}, + { + .sectorDist = 5.0 * dd4hep::cm, + .localDistXY = {50 * dd4hep::cm, 50 * dd4hep::cm}, + .splitCluster = true, + .minClusterHitEdep = 0.1 * dd4hep::MeV, + .minClusterCenterEdep = 3.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "globalDistEtaPhi", + .transverseEnergyProfileScale = 1., + }, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalFarForwardZDCTruthClusters", - {"EcalFarForwardZDCTruthProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "EcalFarForwardZDCTruthClusters", + {"EcalFarForwardZDCTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoClusterHitAssociationCollection + "EcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoClusterHitAssociationCollection #else - "EcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalFarForwardZDCTruthClusters", // edm4eic::Cluster - "EcalFarForwardZDCTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 3.6, - .longitudinalShowerInfoAvailable = true, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); + {"EcalFarForwardZDCTruthClusters", // edm4eic::Cluster + "EcalFarForwardZDCTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 3.6, + .longitudinalShowerInfoAvailable = true, + .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); - app->Add( - new JOmniFactoryGeneratorT( - "EcalFarForwardZDCClusters", - {"EcalFarForwardZDCIslandProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "EcalFarForwardZDCClusters", + {"EcalFarForwardZDCIslandProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "EcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoClusterHitAssociationCollection + "EcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoClusterHitAssociationCollection #else - "EcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection + "EcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"EcalFarForwardZDCClusters", // edm4eic::Cluster - "EcalFarForwardZDCClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 6.2, - .longitudinalShowerInfoAvailable = true, - .enableEtaBounds = false, - }, - app // TODO: Remove me once fixed - ) - ); + {"EcalFarForwardZDCClusters", // edm4eic::Cluster + "EcalFarForwardZDCClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + { + .energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 6.2, + .longitudinalShowerInfoAvailable = true, + .enableEtaBounds = false, + }, + app // TODO: Remove me once fixed + )); - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCRawHits", - {"HcalFarForwardZDCHits"}, + app->Add(new JOmniFactoryGeneratorT( + "HcalFarForwardZDCRawHits", {"HcalFarForwardZDCHits"}, #if EDM4EIC_VERSION_MAJOR >= 7 - {"HcalFarForwardZDCRawHits", "HcalFarForwardZDCRawHitAssociations"}, + {"HcalFarForwardZDCRawHits", "HcalFarForwardZDCRawHitAssociations"}, #else - {"HcalFarForwardZDCRawHits"}, + {"HcalFarForwardZDCRawHits"}, #endif - { - .tRes = 0.0 * dd4hep::ns, - .capADC = 65536, - .dyRangeADC = 1000. * dd4hep::MeV, - .pedMeanADC = 400, - .pedSigmaADC = 2, - .resolutionTDC = 10 * dd4hep::picosecond, - .corrMeanScale = "1.0", - .readout = "HcalFarForwardZDCHits", - }, - app // TODO: Remove me once fixed - )); + { + .tRes = 0.0 * dd4hep::ns, + .capADC = 65536, + .dyRangeADC = 1000. * dd4hep::MeV, + .pedMeanADC = 400, + .pedSigmaADC = 2, + .resolutionTDC = 10 * dd4hep::picosecond, + .corrMeanScale = "1.0", + .readout = "HcalFarForwardZDCHits", + }, + app // TODO: Remove me once fixed + )); - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCRecHits", {"HcalFarForwardZDCRawHits"}, {"HcalFarForwardZDCRecHits"}, - { - .capADC = 65536, - .dyRangeADC = 1000. * dd4hep::MeV, - .pedMeanADC = 400, - .pedSigmaADC = 2, - .resolutionTDC = 10 * dd4hep::picosecond, - .thresholdFactor = 3.0, - .thresholdValue = 0.0, - .sampFrac = "1.0", - .readout = "HcalFarForwardZDCHits", - .layerField = "layer", - .sectorField = "system", - }, - app // TODO: Remove me once fixed - )); + app->Add(new JOmniFactoryGeneratorT( + "HcalFarForwardZDCRecHits", {"HcalFarForwardZDCRawHits"}, {"HcalFarForwardZDCRecHits"}, + { + .capADC = 65536, + .dyRangeADC = 1000. * dd4hep::MeV, + .pedMeanADC = 400, + .pedSigmaADC = 2, + .resolutionTDC = 10 * dd4hep::picosecond, + .thresholdFactor = 3.0, + .thresholdValue = 0.0, + .sampFrac = "1.0", + .readout = "HcalFarForwardZDCHits", + .layerField = "layer", + .sectorField = "system", + }, + app // TODO: Remove me once fixed + )); - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCSubcellHits", {"HcalFarForwardZDCRecHits"}, {"HcalFarForwardZDCSubcellHits"}, - { - .MIP = 472. * dd4hep::keV, - .Emin_in_MIPs=0.5, - .tmax=269 * dd4hep::ns, - }, - app // TODO: Remove me once fixed - )); + app->Add(new JOmniFactoryGeneratorT("HcalFarForwardZDCSubcellHits", + {"HcalFarForwardZDCRecHits"}, + {"HcalFarForwardZDCSubcellHits"}, + { + .MIP = 472. * dd4hep::keV, + .Emin_in_MIPs = 0.5, + .tmax = 269 * dd4hep::ns, + }, + app // TODO: Remove me once fixed + )); - double side_length=31.3 * dd4hep::mm; - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCImagingProtoClusters", {"HcalFarForwardZDCSubcellHits"}, {"HcalFarForwardZDCImagingProtoClusters"}, - { - .neighbourLayersRange = 1, - .localDistXY = {0.5*side_length, 0.5*side_length*sin(M_PI/3)}, - .layerDistXY = {0.25*side_length, 0.25*side_length*sin(M_PI/3)}, - .layerMode=eicrecon::ImagingTopoClusterConfig::ELayerMode::xy, - .sectorDist = 10.0 * dd4hep::cm, - .minClusterHitEdep = 100.0 * dd4hep::keV, - .minClusterCenterEdep = 3.0 * dd4hep::MeV, - .minClusterEdep = 11.0 * dd4hep::MeV, - .minClusterNhits = 100, - }, - app // TODO: Remove me once fixed - )); + double side_length = 31.3 * dd4hep::mm; + app->Add(new JOmniFactoryGeneratorT( + "HcalFarForwardZDCImagingProtoClusters", {"HcalFarForwardZDCSubcellHits"}, + {"HcalFarForwardZDCImagingProtoClusters"}, + { + .neighbourLayersRange = 1, + .localDistXY = {0.5 * side_length, 0.5 * side_length * sin(M_PI / 3)}, + .layerDistXY = {0.25 * side_length, 0.25 * side_length * sin(M_PI / 3)}, + .layerMode = eicrecon::ImagingTopoClusterConfig::ELayerMode::xy, + .sectorDist = 10.0 * dd4hep::cm, + .minClusterHitEdep = 100.0 * dd4hep::keV, + .minClusterCenterEdep = 3.0 * dd4hep::MeV, + .minClusterEdep = 11.0 * dd4hep::MeV, + .minClusterNhits = 100, + }, + app // TODO: Remove me once fixed + )); - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCIslandProtoClusters", {"HcalFarForwardZDCSubcellHits"}, {"HcalFarForwardZDCIslandProtoClusters"}, - { - .sectorDist = 1.5 * dd4hep::cm, - .localDistXY = {0.9*side_length, 0.76*side_length*sin(M_PI/3)}, - .splitCluster = false, - .minClusterHitEdep = 100.0 * dd4hep::keV, - .minClusterCenterEdep = 1.0 * dd4hep::MeV, - // .transverseEnergyProfileMetric = "globalDistEtaPhi", - // .transverseEnergyProfileScale = 1., - }, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "HcalFarForwardZDCIslandProtoClusters", {"HcalFarForwardZDCSubcellHits"}, + {"HcalFarForwardZDCIslandProtoClusters"}, + { + .sectorDist = 1.5 * dd4hep::cm, + .localDistXY = {0.9 * side_length, 0.76 * side_length * sin(M_PI / 3)}, + .splitCluster = false, + .minClusterHitEdep = 100.0 * dd4hep::keV, + .minClusterCenterEdep = 1.0 * dd4hep::MeV, + // .transverseEnergyProfileMetric = "globalDistEtaPhi", + // .transverseEnergyProfileScale = 1., + }, + app)); - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCClusters", - {"HcalFarForwardZDCImagingProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "HcalFarForwardZDCClusters", + {"HcalFarForwardZDCImagingProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "HcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "HcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "HcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection + "HcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"HcalFarForwardZDCClusters", // edm4eic::Cluster - "HcalFarForwardZDCClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 0.0203, - .logWeightBaseCoeffs={5.8,0.65,0.31}, - .logWeightBase_Eref=50*dd4hep::GeV, - .longitudinalShowerInfoAvailable = true, - }, - app // TODO: Remove me once fixed - )); + {"HcalFarForwardZDCClusters", // edm4eic::Cluster + "HcalFarForwardZDCClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + { + .energyWeight = "log", + .sampFrac = 0.0203, + .logWeightBaseCoeffs = {5.8, 0.65, 0.31}, + .logWeightBase_Eref = 50 * dd4hep::GeV, + .longitudinalShowerInfoAvailable = true, + }, + app // TODO: Remove me once fixed + )); - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCTruthProtoClusters", {"HcalFarForwardZDCRecHits", "HcalFarForwardZDCHits"}, {"HcalFarForwardZDCTruthProtoClusters"}, - app // TODO: Remove me once fixed - )); + app->Add(new JOmniFactoryGeneratorT( + "HcalFarForwardZDCTruthProtoClusters", {"HcalFarForwardZDCRecHits", "HcalFarForwardZDCHits"}, + {"HcalFarForwardZDCTruthProtoClusters"}, + app // TODO: Remove me once fixed + )); - //Clusters with the baseline algorithm (no HEXPLIT) - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCIslandProtoClustersBaseline", {"HcalFarForwardZDCRecHits"}, {"HcalFarForwardZDCIslandProtoClustersBaseline"}, - { - .sectorDist = 5.0 * dd4hep::cm, - .localDistXY = {50 * dd4hep::cm, 50 * dd4hep::cm}, - .splitCluster = true, - .minClusterHitEdep = 0.1 * dd4hep::MeV, - .minClusterCenterEdep = 3.0 * dd4hep::MeV, - .transverseEnergyProfileMetric = "globalDistEtaPhi", - .transverseEnergyProfileScale = 1., - }, - app // TODO: Remove me once fixed - )); + //Clusters with the baseline algorithm (no HEXPLIT) + app->Add(new JOmniFactoryGeneratorT( + "HcalFarForwardZDCIslandProtoClustersBaseline", {"HcalFarForwardZDCRecHits"}, + {"HcalFarForwardZDCIslandProtoClustersBaseline"}, + { + .sectorDist = 5.0 * dd4hep::cm, + .localDistXY = {50 * dd4hep::cm, 50 * dd4hep::cm}, + .splitCluster = true, + .minClusterHitEdep = 0.1 * dd4hep::MeV, + .minClusterCenterEdep = 3.0 * dd4hep::MeV, + .transverseEnergyProfileMetric = "globalDistEtaPhi", + .transverseEnergyProfileScale = 1., + }, + app // TODO: Remove me once fixed + )); - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCTruthClusters", - {"HcalFarForwardZDCTruthProtoClusters", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "HcalFarForwardZDCTruthClusters", + {"HcalFarForwardZDCTruthProtoClusters", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "HcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "HcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "HcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection + "HcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"HcalFarForwardZDCTruthClusters", // edm4eic::Cluster - "HcalFarForwardZDCTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 1.0, - .logWeightBase = 3.6, - .longitudinalShowerInfoAvailable = true, - .enableEtaBounds = false - }, - app // TODO: Remove me once fixed - ) - ); + {"HcalFarForwardZDCTruthClusters", // edm4eic::Cluster + "HcalFarForwardZDCTruthClusterAssociations"}, // edm4eic::MCRecoClusterParticleAssociation + {.energyWeight = "log", + .sampFrac = 1.0, + .logWeightBase = 3.6, + .longitudinalShowerInfoAvailable = true, + .enableEtaBounds = false}, + app // TODO: Remove me once fixed + )); - app->Add(new JOmniFactoryGeneratorT( - "HcalFarForwardZDCClustersBaseline", - {"HcalFarForwardZDCIslandProtoClustersBaseline", // edm4eic::ProtoClusterCollection + app->Add(new JOmniFactoryGeneratorT( + "HcalFarForwardZDCClustersBaseline", + {"HcalFarForwardZDCIslandProtoClustersBaseline", // edm4eic::ProtoClusterCollection #if EDM4EIC_VERSION_MAJOR >= 7 - "HcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection + "HcalFarForwardZDCRawHitAssociations"}, // edm4eic::MCRecoCalorimeterHitAssociationCollection #else - "HcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection + "HcalFarForwardZDCHits"}, // edm4hep::SimCalorimeterHitCollection #endif - {"HcalFarForwardZDCClustersBaseline", // edm4eic::Cluster - "HcalFarForwardZDCClusterAssociationsBaseline"}, // edm4eic::MCRecoClusterParticleAssociation - { - .energyWeight = "log", - .sampFrac = 0.0203, - .logWeightBase = 6.2, - .longitudinalShowerInfoAvailable = true, - .enableEtaBounds = false, - }, - app // TODO: Remove me once fixed - ) - ); - } + {"HcalFarForwardZDCClustersBaseline", // edm4eic::Cluster + "HcalFarForwardZDCClusterAssociationsBaseline"}, // edm4eic::MCRecoClusterParticleAssociation + { + .energyWeight = "log", + .sampFrac = 0.0203, + .logWeightBase = 6.2, + .longitudinalShowerInfoAvailable = true, + .enableEtaBounds = false, + }, + app // TODO: Remove me once fixed + )); +} } diff --git a/src/examples/track_matching/reco_particles_track_matching.cc b/src/examples/track_matching/reco_particles_track_matching.cc index c5a7c41f2b..25423715d1 100644 --- a/src/examples/track_matching/reco_particles_track_matching.cc +++ b/src/examples/track_matching/reco_particles_track_matching.cc @@ -13,48 +13,48 @@ #include #include -void reco_particles_track_matching(const std::string &file_name) { - auto *file = new TFile(file_name.c_str()); - auto *tree = (TTree *) file->Get("events"); - TTreeReader tree_reader(tree); // !the tree reader - tree->Print(); - - // Reconstructed particles pz array for each reconstructed particle - TTreeReaderArray reco_pz_array = {tree_reader, "ReconstructedChargedParticles.momentum.z"}; - - // MC particle pz array for each MC particle - TTreeReaderArray mc_pz_array = {tree_reader, "MCParticles.momentum.z"}; - - // Next arrays correspond to particle associations - // Each association has 2 ids - indexes in corresponding reco and MC arrays - TTreeReaderArray rec_id = {tree_reader, "ReconstructedChargedParticleAssociations.recID"}; - TTreeReaderArray sim_id = {tree_reader, "ReconstructedChargedParticleAssociations.simID"}; - - - // Read 100 events - tree_reader.SetEntriesRange(0, 100); - while (tree_reader.Next()) { - - // Number of mc particles, reco particles and associations may differ - fmt::print("New event. N reco particles: {}, N mc particles: {}, N assoc: {}\n", - reco_pz_array.GetSize(), mc_pz_array.GetSize(), rec_id.GetSize()); - - // Iterate over associations - for(unsigned int i=0; i < rec_id.GetSize(); i++) { - - // For each association pull index of reco and MC array - auto reco_array_index = rec_id[i]; - auto mc_array_index = sim_id[i]; - - float reco_pz = reco_pz_array[reco_array_index]; - float mc_pz = mc_pz_array[mc_array_index]; - fmt::print(" reco={:>10.4f} mc={:>10.4f}\n", reco_pz, mc_pz); - } +void reco_particles_track_matching(const std::string& file_name) { + auto* file = new TFile(file_name.c_str()); + auto* tree = (TTree*)file->Get("events"); + TTreeReader tree_reader(tree); // !the tree reader + tree->Print(); + + // Reconstructed particles pz array for each reconstructed particle + TTreeReaderArray reco_pz_array = {tree_reader, "ReconstructedChargedParticles.momentum.z"}; + + // MC particle pz array for each MC particle + TTreeReaderArray mc_pz_array = {tree_reader, "MCParticles.momentum.z"}; + + // Next arrays correspond to particle associations + // Each association has 2 ids - indexes in corresponding reco and MC arrays + TTreeReaderArray rec_id = {tree_reader, + "ReconstructedChargedParticleAssociations.recID"}; + TTreeReaderArray sim_id = {tree_reader, + "ReconstructedChargedParticleAssociations.simID"}; + + // Read 100 events + tree_reader.SetEntriesRange(0, 100); + while (tree_reader.Next()) { + + // Number of mc particles, reco particles and associations may differ + fmt::print("New event. N reco particles: {}, N mc particles: {}, N assoc: {}\n", + reco_pz_array.GetSize(), mc_pz_array.GetSize(), rec_id.GetSize()); + + // Iterate over associations + for (unsigned int i = 0; i < rec_id.GetSize(); i++) { + + // For each association pull index of reco and MC array + auto reco_array_index = rec_id[i]; + auto mc_array_index = sim_id[i]; + + float reco_pz = reco_pz_array[reco_array_index]; + float mc_pz = mc_pz_array[mc_array_index]; + fmt::print(" reco={:>10.4f} mc={:>10.4f}\n", reco_pz, mc_pz); } + } } - int main() { - reco_particles_track_matching("input.edm4eic.root"); - return 0; + reco_particles_track_matching("input.edm4eic.root"); + return 0; } diff --git a/src/extensions/jana/JOmniFactory.h b/src/extensions/jana/JOmniFactory.h index 873070d21b..6f841176b9 100644 --- a/src/extensions/jana/JOmniFactory.h +++ b/src/extensions/jana/JOmniFactory.h @@ -23,564 +23,525 @@ struct EmptyConfig {}; -template +template class JOmniFactory : public JMultifactory { public: + /// ======================== + /// Handle input collections + /// ======================== - /// ======================== - /// Handle input collections - /// ======================== + struct InputBase { + std::string type_name; + std::vector collection_names; + bool is_variadic = false; - struct InputBase { - std::string type_name; - std::vector collection_names; - bool is_variadic = false; + virtual void GetCollection(const JEvent& event) = 0; + }; - virtual void GetCollection(const JEvent& event) = 0; - }; - - template - class Input : public InputBase { - - std::vector m_data; - - public: - Input(JOmniFactory* owner, std::string default_tag="") { - owner->RegisterInput(this); - this->collection_names.push_back(default_tag); - this->type_name = JTypeInfo::demangle(); - } - - const std::vector& operator()() { return m_data; } - - private: - friend class JOmniFactory; + template class Input : public InputBase { - void GetCollection(const JEvent& event) { - m_data = event.Get(this->collection_names[0]); - } - }; - - - template - class PodioInput : public InputBase { + std::vector m_data; - const typename PodioTypeMap::collection_t* m_data; - - public: - - PodioInput(JOmniFactory* owner, std::string default_collection_name="") { - owner->RegisterInput(this); - this->collection_names.push_back(default_collection_name); - this->type_name = JTypeInfo::demangle(); - } + public: + Input(JOmniFactory* owner, std::string default_tag = "") { + owner->RegisterInput(this); + this->collection_names.push_back(default_tag); + this->type_name = JTypeInfo::demangle(); + } - const typename PodioTypeMap::collection_t* operator()() { - return m_data; - } + const std::vector& operator()() { return m_data; } - private: - friend class JOmniFactory; + private: + friend class JOmniFactory; - void GetCollection(const JEvent& event) { - m_data = event.GetCollection(this->collection_names[0]); - } - }; + void GetCollection(const JEvent& event) { m_data = event.Get(this->collection_names[0]); } + }; + template class PodioInput : public InputBase { - template - class VariadicPodioInput : public InputBase { + const typename PodioTypeMap::collection_t* m_data; - std::vector::collection_t*> m_data; - - public: - - VariadicPodioInput(JOmniFactory* owner, std::vector default_names = {}) { - owner->RegisterInput(this); - this->collection_names = default_names; - this->type_name = JTypeInfo::demangle(); - this->is_variadic = true; - } - - const std::vector::collection_t*> operator()() { - return m_data; - } + public: + PodioInput(JOmniFactory* owner, std::string default_collection_name = "") { + owner->RegisterInput(this); + this->collection_names.push_back(default_collection_name); + this->type_name = JTypeInfo::demangle(); + } - private: - friend class JOmniFactory; + const typename PodioTypeMap::collection_t* operator()() { return m_data; } - void GetCollection(const JEvent& event) { - m_data.clear(); - for (auto& coll_name : this->collection_names) { - m_data.push_back(event.GetCollection(coll_name)); - } - } - }; + private: + friend class JOmniFactory; - void RegisterInput(InputBase* input) { - m_inputs.push_back(input); + void GetCollection(const JEvent& event) { + m_data = event.GetCollection(this->collection_names[0]); } + }; + template class VariadicPodioInput : public InputBase { - /// ========================= - /// Handle output collections - /// ========================= + std::vector::collection_t*> m_data; - struct OutputBase { - std::string type_name; - std::vector collection_names; - bool is_variadic = false; + public: + VariadicPodioInput(JOmniFactory* owner, std::vector default_names = {}) { + owner->RegisterInput(this); + this->collection_names = default_names; + this->type_name = JTypeInfo::demangle(); + this->is_variadic = true; + } - virtual void CreateHelperFactory(JOmniFactory& fac) = 0; - virtual void SetCollection(JOmniFactory& fac) = 0; - virtual void Reset() = 0; - }; + const std::vector::collection_t*> operator()() { + return m_data; + } - template - class Output : public OutputBase { - std::vector m_data; + private: + friend class JOmniFactory; - public: - Output(JOmniFactory* owner, std::string default_tag_name="") { - owner->RegisterOutput(this); - this->collection_names.push_back(default_tag_name); - this->type_name = JTypeInfo::demangle(); - } + void GetCollection(const JEvent& event) { + m_data.clear(); + for (auto& coll_name : this->collection_names) { + m_data.push_back(event.GetCollection(coll_name)); + } + } + }; - std::vector& operator()() { return m_data; } + void RegisterInput(InputBase* input) { m_inputs.push_back(input); } - private: - friend class JOmniFactory; + /// ========================= + /// Handle output collections + /// ========================= - void CreateHelperFactory(JOmniFactory& fac) override { - fac.DeclareOutput(this->collection_names[0]); - } + struct OutputBase { + std::string type_name; + std::vector collection_names; + bool is_variadic = false; - void SetCollection(JOmniFactory& fac) override { - fac.SetData(this->collection_names[0], this->m_data); - } + virtual void CreateHelperFactory(JOmniFactory& fac) = 0; + virtual void SetCollection(JOmniFactory& fac) = 0; + virtual void Reset() = 0; + }; - void Reset() override { } - }; + template class Output : public OutputBase { + std::vector m_data; + public: + Output(JOmniFactory* owner, std::string default_tag_name = "") { + owner->RegisterOutput(this); + this->collection_names.push_back(default_tag_name); + this->type_name = JTypeInfo::demangle(); + } - template - class PodioOutput : public OutputBase { + std::vector& operator()() { return m_data; } - std::unique_ptr::collection_t> m_data; + private: + friend class JOmniFactory; - public: + void CreateHelperFactory(JOmniFactory& fac) override { + fac.DeclareOutput(this->collection_names[0]); + } - PodioOutput(JOmniFactory* owner, std::string default_collection_name="") { - owner->RegisterOutput(this); - this->collection_names.push_back(default_collection_name); - this->type_name = JTypeInfo::demangle(); - } + void SetCollection(JOmniFactory& fac) override { + fac.SetData(this->collection_names[0], this->m_data); + } - std::unique_ptr::collection_t>& operator()() { return m_data; } + void Reset() override {} + }; - private: - friend class JOmniFactory; + template class PodioOutput : public OutputBase { - void CreateHelperFactory(JOmniFactory& fac) override { - fac.DeclarePodioOutput(this->collection_names[0]); - } + std::unique_ptr::collection_t> m_data; - void SetCollection(JOmniFactory& fac) override { - if (m_data == nullptr) { - throw JException("JOmniFactory: SetCollection failed due to missing output collection '%s'", this->collection_names[0].c_str()); - // Otherwise this leads to a PODIO segfault - } - fac.SetCollection(this->collection_names[0], std::move(this->m_data)); - } + public: + PodioOutput(JOmniFactory* owner, std::string default_collection_name = "") { + owner->RegisterOutput(this); + this->collection_names.push_back(default_collection_name); + this->type_name = JTypeInfo::demangle(); + } - void Reset() override { - m_data = std::move(std::make_unique::collection_t>()); - } - }; + std::unique_ptr::collection_t>& operator()() { return m_data; } + private: + friend class JOmniFactory; - template - class VariadicPodioOutput : public OutputBase { + void CreateHelperFactory(JOmniFactory& fac) override { + fac.DeclarePodioOutput(this->collection_names[0]); + } - std::vector::collection_t>> m_data; + void SetCollection(JOmniFactory& fac) override { + if (m_data == nullptr) { + throw JException("JOmniFactory: SetCollection failed due to missing output collection '%s'", + this->collection_names[0].c_str()); + // Otherwise this leads to a PODIO segfault + } + fac.SetCollection(this->collection_names[0], std::move(this->m_data)); + } - public: + void Reset() override { + m_data = std::move(std::make_unique::collection_t>()); + } + }; - VariadicPodioOutput(JOmniFactory* owner, std::vector default_collection_names={}) { - owner->RegisterOutput(this); - this->collection_names = default_collection_names; - this->type_name = JTypeInfo::demangle(); - this->is_variadic = true; - } + template class VariadicPodioOutput : public OutputBase { - std::vector::collection_t>>& operator()() { return m_data; } + std::vector::collection_t>> m_data; - private: - friend class JOmniFactory; + public: + VariadicPodioOutput(JOmniFactory* owner, + std::vector default_collection_names = {}) { + owner->RegisterOutput(this); + this->collection_names = default_collection_names; + this->type_name = JTypeInfo::demangle(); + this->is_variadic = true; + } - void CreateHelperFactory(JOmniFactory& fac) override { - for (auto& coll_name : this->collection_names) { - fac.DeclarePodioOutput(coll_name); - } - } + std::vector::collection_t>>& operator()() { + return m_data; + } - void SetCollection(JOmniFactory& fac) override { - if (m_data.size() != this->collection_names.size()) { - throw JException("JOmniFactory: VariadicPodioOutput SetCollection failed: Declared %d collections, but provided %d.", this->collection_names.size(), m_data.size()); - // Otherwise this leads to a PODIO segfault - } - size_t i = 0; - for (auto& coll_name : this->collection_names) { - fac.SetCollection(coll_name, std::move(this->m_data[i++])); - } - } + private: + friend class JOmniFactory; - void Reset() override { - m_data.clear(); - for (auto& coll_name : this->collection_names) { - m_data.push_back(std::make_unique::collection_t>()); - } - } - }; + void CreateHelperFactory(JOmniFactory& fac) override { + for (auto& coll_name : this->collection_names) { + fac.DeclarePodioOutput(coll_name); + } + } - void RegisterOutput(OutputBase* output) { - m_outputs.push_back(output); + void SetCollection(JOmniFactory& fac) override { + if (m_data.size() != this->collection_names.size()) { + throw JException("JOmniFactory: VariadicPodioOutput SetCollection failed: Declared %d " + "collections, but provided %d.", + this->collection_names.size(), m_data.size()); + // Otherwise this leads to a PODIO segfault + } + size_t i = 0; + for (auto& coll_name : this->collection_names) { + fac.SetCollection(coll_name, std::move(this->m_data[i++])); + } } + void Reset() override { + m_data.clear(); + for (auto& coll_name : this->collection_names) { + m_data.push_back(std::make_unique::collection_t>()); + } + } + }; - // ================= - // Handle parameters - // ================= + void RegisterOutput(OutputBase* output) { m_outputs.push_back(output); } - struct ParameterBase { - std::string m_name; - std::string m_description; - virtual void Configure(JParameterManager& parman, const std::string& prefix) = 0; - virtual void Configure(std::map fields) = 0; - }; + // ================= + // Handle parameters + // ================= - template - class ParameterRef : public ParameterBase { + struct ParameterBase { + std::string m_name; + std::string m_description; + virtual void Configure(JParameterManager& parman, const std::string& prefix) = 0; + virtual void Configure(std::map fields) = 0; + }; - T* m_data; + template class ParameterRef : public ParameterBase { - public: - ParameterRef(JOmniFactory* owner, std::string name, T& slot, std::string description="") { - owner->RegisterParameter(this); - this->m_name = name; - this->m_description = description; - m_data = &slot; - } + T* m_data; - const T& operator()() { return *m_data; } + public: + ParameterRef(JOmniFactory* owner, std::string name, T& slot, std::string description = "") { + owner->RegisterParameter(this); + this->m_name = name; + this->m_description = description; + m_data = &slot; + } - private: - friend class JOmniFactory; + const T& operator()() { return *m_data; } - void Configure(JParameterManager& parman, const std::string& prefix) override { - parman.SetDefaultParameter(prefix + ":" + this->m_name, *m_data, this->m_description); - } - void Configure(std::map fields) override { - auto it = fields.find(this->m_name); - if (it != fields.end()) { - const auto& value_str = it->second; - if constexpr (10000 * JVersion::major - + 100 * JVersion::minor - + 1 * JVersion::patch < 20102) { - *m_data = JParameterManager::Parse(value_str); - } else { - JParameterManager::Parse(value_str, *m_data); - } - } - } - }; + private: + friend class JOmniFactory; - template - class Parameter : public ParameterBase { + void Configure(JParameterManager& parman, const std::string& prefix) override { + parman.SetDefaultParameter(prefix + ":" + this->m_name, *m_data, this->m_description); + } + void Configure(std::map fields) override { + auto it = fields.find(this->m_name); + if (it != fields.end()) { + const auto& value_str = it->second; + if constexpr (10000 * JVersion::major + 100 * JVersion::minor + 1 * JVersion::patch < + 20102) { + *m_data = JParameterManager::Parse(value_str); + } else { + JParameterManager::Parse(value_str, *m_data); + } + } + } + }; - T m_data; + template class Parameter : public ParameterBase { - public: - Parameter(JOmniFactory* owner, std::string name, T default_value, std::string description) { - owner->RegisterParameter(this); - this->m_name = name; - this->m_description = description; - m_data = default_value; - } + T m_data; - const T& operator()() { return m_data; } + public: + Parameter(JOmniFactory* owner, std::string name, T default_value, std::string description) { + owner->RegisterParameter(this); + this->m_name = name; + this->m_description = description; + m_data = default_value; + } - private: - friend class JOmniFactory; + const T& operator()() { return m_data; } - void Configure(JParameterManager& parman, const std::string& prefix) override { - parman.SetDefaultParameter(m_prefix + ":" + this->m_name, m_data, this->m_description); - } - void Configure(std::map fields) override { - auto it = fields.find(this->m_name); - if (it != fields.end()) { - const auto& value_str = it->second; - if constexpr (10000 * JVersion::major - + 100 * JVersion::minor - + 1 * JVersion::patch < 20102) { - m_data = JParameterManager::Parse(value_str); - } else { - JParameterManager::Parse(value_str, m_data); - } - } - } - }; + private: + friend class JOmniFactory; - void RegisterParameter(ParameterBase* parameter) { - m_parameters.push_back(parameter); + void Configure(JParameterManager& parman, const std::string& prefix) override { + parman.SetDefaultParameter(m_prefix + ":" + this->m_name, m_data, this->m_description); } - - void ConfigureAllParameters(std::map fields) { - for (auto* parameter : this->m_parameters) { - parameter->Configure(fields); - } + void Configure(std::map fields) override { + auto it = fields.find(this->m_name); + if (it != fields.end()) { + const auto& value_str = it->second; + if constexpr (10000 * JVersion::major + 100 * JVersion::minor + 1 * JVersion::patch < + 20102) { + m_data = JParameterManager::Parse(value_str); + } else { + JParameterManager::Parse(value_str, m_data); + } + } } + }; - // =============== - // Handle services - // =============== + void RegisterParameter(ParameterBase* parameter) { m_parameters.push_back(parameter); } - struct ServiceBase { - virtual void Init(JApplication* app) = 0; - }; + void ConfigureAllParameters(std::map fields) { + for (auto* parameter : this->m_parameters) { + parameter->Configure(fields); + } + } - template - class Service : public ServiceBase { + // =============== + // Handle services + // =============== - std::shared_ptr m_data; + struct ServiceBase { + virtual void Init(JApplication* app) = 0; + }; - public: + template class Service : public ServiceBase { - Service(JOmniFactory* owner) { - owner->RegisterService(this); - } + std::shared_ptr m_data; - ServiceT& operator()() { - return *m_data; - } + public: + Service(JOmniFactory* owner) { owner->RegisterService(this); } - private: + ServiceT& operator()() { return *m_data; } - friend class JOmniFactory; + private: + friend class JOmniFactory; - void Init(JApplication* app) { - m_data = app->GetService(); - } + void Init(JApplication* app) { m_data = app->GetService(); } + }; - }; + void RegisterService(ServiceBase* service) { m_services.push_back(service); } - void RegisterService(ServiceBase* service) { - m_services.push_back(service); - } + // ================ + // Handle resources + // ================ + struct ResourceBase { + virtual void ChangeRun(const JEvent& event) = 0; + }; - // ================ - // Handle resources - // ================ + template + class Resource : public ResourceBase { + ResourceT m_data; + LambdaT m_lambda; - struct ResourceBase { - virtual void ChangeRun(const JEvent& event) = 0; + public: + Resource(JOmniFactory* owner, LambdaT lambda) : m_lambda(lambda) { + owner->RegisterResource(this); }; - template - class Resource : public ResourceBase { - ResourceT m_data; - LambdaT m_lambda; - - public: - - Resource(JOmniFactory* owner, LambdaT lambda) : m_lambda(lambda) { - owner->RegisterResource(this); - }; - - const ResourceT& operator()() { return m_data; } - - private: - friend class JOmniFactory; + const ResourceT& operator()() { return m_data; } - void ChangeRun(const JEvent& event) { - auto run_nr = event.GetRunNumber(); - std::shared_ptr service = event.GetJApplication()->template GetService(); - m_data = m_lambda(service, run_nr); - } - }; + private: + friend class JOmniFactory; - void RegisterResource(ResourceBase* resource) { - m_resources.push_back(resource); + void ChangeRun(const JEvent& event) { + auto run_nr = event.GetRunNumber(); + std::shared_ptr service = event.GetJApplication()->template GetService(); + m_data = m_lambda(service, run_nr); } + }; + void RegisterResource(ResourceBase* resource) { m_resources.push_back(resource); } public: - std::vector m_inputs; - std::vector m_outputs; - std::vector m_parameters; - std::vector m_services; - std::vector m_resources; + std::vector m_inputs; + std::vector m_outputs; + std::vector m_parameters; + std::vector m_services; + std::vector m_resources; private: + // App belongs on JMultifactory, it is just missing temporarily + JApplication* m_app; - // App belongs on JMultifactory, it is just missing temporarily - JApplication* m_app; + // Plugin name belongs on JMultifactory, it is just missing temporarily + std::string m_plugin_name; - // Plugin name belongs on JMultifactory, it is just missing temporarily - std::string m_plugin_name; + // Prefix for parameters and loggers, derived from plugin name and tag in PreInit(). + std::string m_prefix; - // Prefix for parameters and loggers, derived from plugin name and tag in PreInit(). - std::string m_prefix; + /// Current logger + std::shared_ptr m_logger; - /// Current logger - std::shared_ptr m_logger; - - /// Configuration - ConfigT m_config; + /// Configuration + ConfigT m_config; public: - - size_t FindVariadicCollectionCount(size_t total_input_count, size_t variadic_input_count, size_t total_collection_count, bool is_input) { - - size_t variadic_collection_count = total_collection_count - (total_input_count - variadic_input_count); - - if (variadic_input_count == 0) { - // No variadic inputs: check that collection_name count matches input count exactly - if (total_input_count != total_collection_count) { - throw JException("JOmniFactory '%s': Wrong number of %s collection names: %d expected, %d found.", - m_prefix.c_str(), (is_input ? "input" : "output"), total_input_count, total_collection_count); - } - } - else { - // Variadic inputs: check that we have enough collection names for the non-variadic inputs - if (total_input_count-variadic_input_count > total_collection_count) { - throw JException("JOmniFactory '%s': Not enough %s collection names: %d needed, %d found.", - m_prefix.c_str(), (is_input ? "input" : "output"), total_input_count-variadic_input_count, total_collection_count); - } - - // Variadic inputs: check that the variadic collection names is evenly divided by the variadic input count - if (variadic_collection_count % variadic_input_count != 0) { - throw JException("JOmniFactory '%s': Wrong number of %s collection names: %d found total, but %d can't be distributed among %d variadic inputs evenly.", - m_prefix.c_str(), (is_input ? "input" : "output"), total_collection_count, variadic_collection_count, variadic_input_count); - } - } - return variadic_collection_count; + size_t FindVariadicCollectionCount(size_t total_input_count, size_t variadic_input_count, + size_t total_collection_count, bool is_input) { + + size_t variadic_collection_count = + total_collection_count - (total_input_count - variadic_input_count); + + if (variadic_input_count == 0) { + // No variadic inputs: check that collection_name count matches input count exactly + if (total_input_count != total_collection_count) { + throw JException( + "JOmniFactory '%s': Wrong number of %s collection names: %d expected, %d found.", + m_prefix.c_str(), (is_input ? "input" : "output"), total_input_count, + total_collection_count); + } + } else { + // Variadic inputs: check that we have enough collection names for the non-variadic inputs + if (total_input_count - variadic_input_count > total_collection_count) { + throw JException("JOmniFactory '%s': Not enough %s collection names: %d needed, %d found.", + m_prefix.c_str(), (is_input ? "input" : "output"), + total_input_count - variadic_input_count, total_collection_count); + } + + // Variadic inputs: check that the variadic collection names is evenly divided by the variadic input count + if (variadic_collection_count % variadic_input_count != 0) { + throw JException("JOmniFactory '%s': Wrong number of %s collection names: %d found total, " + "but %d can't be distributed among %d variadic inputs evenly.", + m_prefix.c_str(), (is_input ? "input" : "output"), total_collection_count, + variadic_collection_count, variadic_input_count); + } + } + return variadic_collection_count; + } + + inline void PreInit(std::string tag, std::vector default_input_collection_names, + std::vector default_output_collection_names) { + + m_prefix = (this->GetPluginName().empty()) ? tag : this->GetPluginName() + ":" + tag; + + // Obtain collection name overrides if provided. + // Priority = [JParameterManager, JOmniFactoryGenerator] + m_app->SetDefaultParameter(m_prefix + ":InputTags", default_input_collection_names, + "Input collection names"); + m_app->SetDefaultParameter(m_prefix + ":OutputTags", default_output_collection_names, + "Output collection names"); + + // Figure out variadic inputs + size_t variadic_input_count = 0; + for (auto* input : m_inputs) { + if (input->is_variadic) { + variadic_input_count += 1; + } + } + size_t variadic_input_collection_count = FindVariadicCollectionCount( + m_inputs.size(), variadic_input_count, default_input_collection_names.size(), true); + + // Set input collection names + for (size_t i = 0; auto* input : m_inputs) { + input->collection_names.clear(); + if (input->is_variadic) { + for (size_t j = 0; j < (variadic_input_collection_count / variadic_input_count); ++j) { + input->collection_names.push_back(default_input_collection_names[i++]); + } + } else { + input->collection_names.push_back(default_input_collection_names[i++]); + } } - inline void PreInit(std::string tag, - std::vector default_input_collection_names, - std::vector default_output_collection_names ) { - - m_prefix = (this->GetPluginName().empty()) ? tag : this->GetPluginName() + ":" + tag; - - // Obtain collection name overrides if provided. - // Priority = [JParameterManager, JOmniFactoryGenerator] - m_app->SetDefaultParameter(m_prefix + ":InputTags", default_input_collection_names, "Input collection names"); - m_app->SetDefaultParameter(m_prefix + ":OutputTags", default_output_collection_names, "Output collection names"); - - // Figure out variadic inputs - size_t variadic_input_count = 0; - for (auto* input : m_inputs) { - if (input->is_variadic) { - variadic_input_count += 1; - } - } - size_t variadic_input_collection_count = FindVariadicCollectionCount(m_inputs.size(), variadic_input_count, default_input_collection_names.size(), true); - - // Set input collection names - for (size_t i = 0; auto* input : m_inputs) { - input->collection_names.clear(); - if (input->is_variadic) { - for (size_t j = 0; j<(variadic_input_collection_count/variadic_input_count); ++j) { - input->collection_names.push_back(default_input_collection_names[i++]); - } - } - else { - input->collection_names.push_back(default_input_collection_names[i++]); - } - } + // Figure out variadic outputs + size_t variadic_output_count = 0; + for (auto* output : m_outputs) { + if (output->is_variadic) { + variadic_output_count += 1; + } + } + size_t variadic_output_collection_count = FindVariadicCollectionCount( + m_outputs.size(), variadic_output_count, default_output_collection_names.size(), true); + + // Set output collection names and create corresponding helper factories + for (size_t i = 0; auto* output : m_outputs) { + output->collection_names.clear(); + if (output->is_variadic) { + for (size_t j = 0; j < (variadic_output_collection_count / variadic_output_count); ++j) { + output->collection_names.push_back(default_output_collection_names[i++]); + } + } else { + output->collection_names.push_back(default_output_collection_names[i++]); + } + output->CreateHelperFactory(*this); + } - // Figure out variadic outputs - size_t variadic_output_count = 0; - for (auto* output : m_outputs) { - if (output->is_variadic) { - variadic_output_count += 1; - } - } - size_t variadic_output_collection_count = FindVariadicCollectionCount(m_outputs.size(), variadic_output_count, default_output_collection_names.size(), true); - - // Set output collection names and create corresponding helper factories - for (size_t i = 0; auto* output : m_outputs) { - output->collection_names.clear(); - if (output->is_variadic) { - for (size_t j = 0; j<(variadic_output_collection_count/variadic_output_count); ++j) { - output->collection_names.push_back(default_output_collection_names[i++]); - } - } - else { - output->collection_names.push_back(default_output_collection_names[i++]); - } - output->CreateHelperFactory(*this); - } + // Obtain logger (defines the parameter option) + m_logger = m_app->GetService()->logger(m_prefix); + } - // Obtain logger (defines the parameter option) - m_logger = m_app->GetService()->logger(m_prefix); + void Init() override { + auto app = GetApplication(); + for (auto* parameter : m_parameters) { + parameter->Configure(*(app->GetJParameterManager()), m_prefix); } - - void Init() override { - auto app = GetApplication(); - for (auto* parameter : m_parameters) { - parameter->Configure(*(app->GetJParameterManager()), m_prefix); - } - for (auto* service : m_services) { - service->Init(app); - } - static_cast(this)->Configure(); + for (auto* service : m_services) { + service->Init(app); } + static_cast(this)->Configure(); + } - void BeginRun(const std::shared_ptr& event) override { - for (auto* resource : m_resources) { - resource->ChangeRun(*event); - } - static_cast(this)->ChangeRun(event->GetRunNumber()); - } - - void Process(const std::shared_ptr &event) override { - try { - for (auto* input : m_inputs) { - input->GetCollection(*event); - } - for (auto* output : m_outputs) { - output->Reset(); - } - static_cast(this)->Process(event->GetRunNumber(), event->GetEventNumber()); - for (auto* output : m_outputs) { - output->SetCollection(*this); - } - } - catch(std::exception &e) { - throw JException(e.what()); - } + void BeginRun(const std::shared_ptr& event) override { + for (auto* resource : m_resources) { + resource->ChangeRun(*event); } + static_cast(this)->ChangeRun(event->GetRunNumber()); + } + + void Process(const std::shared_ptr& event) override { + try { + for (auto* input : m_inputs) { + input->GetCollection(*event); + } + for (auto* output : m_outputs) { + output->Reset(); + } + static_cast(this)->Process(event->GetRunNumber(), event->GetEventNumber()); + for (auto* output : m_outputs) { + output->SetCollection(*this); + } + } catch (std::exception& e) { + throw JException(e.what()); + } + } - using ConfigType = ConfigT; - - void SetApplication(JApplication* app) { m_app = app; } + using ConfigType = ConfigT; - JApplication* GetApplication() { return m_app; } + void SetApplication(JApplication* app) { m_app = app; } - void SetPluginName(std::string plugin_name) { m_plugin_name = plugin_name; } + JApplication* GetApplication() { return m_app; } - std::string GetPluginName() { return m_plugin_name; } + void SetPluginName(std::string plugin_name) { m_plugin_name = plugin_name; } - inline std::string GetPrefix() { return m_prefix; } + std::string GetPluginName() { return m_plugin_name; } - /// Retrieve reference to already-configured logger - std::shared_ptr &logger() { return m_logger; } + inline std::string GetPrefix() { return m_prefix; } - /// Retrieve reference to embedded config object - ConfigT& config() { return m_config; } + /// Retrieve reference to already-configured logger + std::shared_ptr& logger() { return m_logger; } + /// Retrieve reference to embedded config object + ConfigT& config() { return m_config; } }; diff --git a/src/extensions/jana/JOmniFactoryGeneratorT.h b/src/extensions/jana/JOmniFactoryGeneratorT.h index ff0ad25fe7..5e7d995c53 100644 --- a/src/extensions/jana/JOmniFactoryGeneratorT.h +++ b/src/extensions/jana/JOmniFactoryGeneratorT.h @@ -8,110 +8,91 @@ #include #include -template -class JOmniFactoryGeneratorT : public JFactoryGenerator { +template class JOmniFactoryGeneratorT : public JFactoryGenerator { public: - using FactoryConfigType = typename FactoryT::ConfigType; + using FactoryConfigType = typename FactoryT::ConfigType; private: - struct TypedWiring { - std::string m_tag; - std::vector m_default_input_tags; - std::vector m_default_output_tags; - FactoryConfigType m_default_cfg; /// Must be properly copyable! - }; - - struct UntypedWiring { - std::string m_tag; - std::vector m_default_input_tags; - std::vector m_default_output_tags; - std::map m_config_params; - }; + struct TypedWiring { + std::string m_tag; + std::vector m_default_input_tags; + std::vector m_default_output_tags; + FactoryConfigType m_default_cfg; /// Must be properly copyable! + }; + + struct UntypedWiring { + std::string m_tag; + std::vector m_default_input_tags; + std::vector m_default_output_tags; + std::map m_config_params; + }; public: - - - explicit JOmniFactoryGeneratorT(std::string tag, - std::vector default_input_tags, - std::vector default_output_tags, - FactoryConfigType cfg, - JApplication* app) { - m_app = app; - m_wirings.push_back({.m_tag=tag, - .m_default_input_tags=default_input_tags, - .m_default_output_tags=default_output_tags, - .m_default_cfg=cfg - }); - }; - - explicit JOmniFactoryGeneratorT(std::string tag, - std::vector default_input_tags, - std::vector default_output_tags, - JApplication* app) { - m_app = app; - m_wirings.push_back({.m_tag=tag, - .m_default_input_tags=default_input_tags, - .m_default_output_tags=default_output_tags - }); - - } - - explicit JOmniFactoryGeneratorT(JApplication* app) : m_app(app) { - } - - void AddWiring(std::string tag, - std::vector default_input_tags, - std::vector default_output_tags, - FactoryConfigType cfg) { - - m_wirings.push_back({.m_tag=tag, - .m_default_input_tags=default_input_tags, - .m_default_output_tags=default_output_tags, - .m_default_cfg=cfg - }); - } - - void AddWiring(std::string tag, - std::vector default_input_tags, - std::vector default_output_tags, - std::map config_params) { - - // Create throwaway factory so we can populate its config using our map. - FactoryT factory; - factory.ConfigureAllParameters(config_params); - auto config = factory.config(); - - m_wirings.push_back({.m_tag=tag, - .m_default_input_tags=default_input_tags, - .m_default_output_tags=default_output_tags, - .m_default_cfg=config - }); - - } - - void GenerateFactories(JFactorySet *factory_set) override { - - for (const auto& wiring : m_wirings) { - - - FactoryT *factory = new FactoryT; - factory->SetApplication(m_app); - factory->SetPluginName(this->GetPluginName()); - factory->SetFactoryName(JTypeInfo::demangle()); - factory->config() = wiring.m_default_cfg; - - // Set up all of the wiring prereqs so that Init() can do its thing - // Specifically, it needs valid input/output tags, a valid logger, and - // valid default values in its Config object - factory->PreInit(wiring.m_tag, wiring.m_default_input_tags, wiring.m_default_output_tags); - - // Factory is ready - factory_set->Add(factory); - } + explicit JOmniFactoryGeneratorT(std::string tag, std::vector default_input_tags, + std::vector default_output_tags, + FactoryConfigType cfg, JApplication* app) { + m_app = app; + m_wirings.push_back({.m_tag = tag, + .m_default_input_tags = default_input_tags, + .m_default_output_tags = default_output_tags, + .m_default_cfg = cfg}); + }; + + explicit JOmniFactoryGeneratorT(std::string tag, std::vector default_input_tags, + std::vector default_output_tags, JApplication* app) { + m_app = app; + m_wirings.push_back({.m_tag = tag, + .m_default_input_tags = default_input_tags, + .m_default_output_tags = default_output_tags}); + } + + explicit JOmniFactoryGeneratorT(JApplication* app) : m_app(app) {} + + void AddWiring(std::string tag, std::vector default_input_tags, + std::vector default_output_tags, FactoryConfigType cfg) { + + m_wirings.push_back({.m_tag = tag, + .m_default_input_tags = default_input_tags, + .m_default_output_tags = default_output_tags, + .m_default_cfg = cfg}); + } + + void AddWiring(std::string tag, std::vector default_input_tags, + std::vector default_output_tags, + std::map config_params) { + + // Create throwaway factory so we can populate its config using our map. + FactoryT factory; + factory.ConfigureAllParameters(config_params); + auto config = factory.config(); + + m_wirings.push_back({.m_tag = tag, + .m_default_input_tags = default_input_tags, + .m_default_output_tags = default_output_tags, + .m_default_cfg = config}); + } + + void GenerateFactories(JFactorySet* factory_set) override { + + for (const auto& wiring : m_wirings) { + + FactoryT* factory = new FactoryT; + factory->SetApplication(m_app); + factory->SetPluginName(this->GetPluginName()); + factory->SetFactoryName(JTypeInfo::demangle()); + factory->config() = wiring.m_default_cfg; + + // Set up all of the wiring prereqs so that Init() can do its thing + // Specifically, it needs valid input/output tags, a valid logger, and + // valid default values in its Config object + factory->PreInit(wiring.m_tag, wiring.m_default_input_tags, wiring.m_default_output_tags); + + // Factory is ready + factory_set->Add(factory); } + } private: - std::vector m_wirings; - JApplication* m_app; - + std::vector m_wirings; + JApplication* m_app; }; diff --git a/src/extensions/spdlog/SpdlogExtensions.h b/src/extensions/spdlog/SpdlogExtensions.h index aeaeb8117f..c6869af8e9 100644 --- a/src/extensions/spdlog/SpdlogExtensions.h +++ b/src/extensions/spdlog/SpdlogExtensions.h @@ -9,50 +9,58 @@ #include namespace eicrecon { - inline spdlog::level::level_enum ParseLogLevel(const std::string &input) { - - // Convert the source string to lower case - std::string lc_input; // Lower case input - lc_input.resize(input.size()); - std::transform(input.begin(), input.end(), lc_input.begin(), ::tolower); - - if(lc_input == "trace" || lc_input == std::to_string(SPDLOG_LEVEL_TRACE)) return spdlog::level::trace; - if(lc_input == "debug" || lc_input == std::to_string(SPDLOG_LEVEL_DEBUG)) return spdlog::level::debug; - if(lc_input == "info" || lc_input == std::to_string(SPDLOG_LEVEL_INFO)) return spdlog::level::info; - if(lc_input == "warn" || lc_input == "warning" || lc_input == std::to_string(SPDLOG_LEVEL_WARN)) return spdlog::level::warn; - if(lc_input == "err" || lc_input == "error" || lc_input == std::to_string(SPDLOG_LEVEL_ERROR)) return spdlog::level::err; - if(lc_input == "critical" || lc_input == std::to_string(SPDLOG_LEVEL_CRITICAL)) return spdlog::level::critical; - if(lc_input == "off" || lc_input == std::to_string(SPDLOG_LEVEL_OFF)) return spdlog::level::off; - - auto err_msg = fmt::format("ParseLogLevel can't parse input string: '{}'", input); - throw JException(err_msg); - } - - inline std::string LogLevelToString(spdlog::level::level_enum input) { - - // Convert the source string to lower case - switch (input) { - case spdlog::level::trace: - return "trace"; - case spdlog::level::debug: - return "debug"; - case spdlog::level::info: - return "info"; - case spdlog::level::warn: - return "warn"; - case spdlog::level::err: - return "error"; - case spdlog::level::critical: - return "critical"; - case spdlog::level::off: - return "off"; - case spdlog::level::n_levels: - [[fallthrough]]; - default: - break; - } - - auto err_msg = fmt::format("ParseLogLevel don't know this log level: '{}'", fmt::underlying(input)); - throw JException(err_msg); - } +inline spdlog::level::level_enum ParseLogLevel(const std::string& input) { + + // Convert the source string to lower case + std::string lc_input; // Lower case input + lc_input.resize(input.size()); + std::transform(input.begin(), input.end(), lc_input.begin(), ::tolower); + + if (lc_input == "trace" || lc_input == std::to_string(SPDLOG_LEVEL_TRACE)) + return spdlog::level::trace; + if (lc_input == "debug" || lc_input == std::to_string(SPDLOG_LEVEL_DEBUG)) + return spdlog::level::debug; + if (lc_input == "info" || lc_input == std::to_string(SPDLOG_LEVEL_INFO)) + return spdlog::level::info; + if (lc_input == "warn" || lc_input == "warning" || lc_input == std::to_string(SPDLOG_LEVEL_WARN)) + return spdlog::level::warn; + if (lc_input == "err" || lc_input == "error" || lc_input == std::to_string(SPDLOG_LEVEL_ERROR)) + return spdlog::level::err; + if (lc_input == "critical" || lc_input == std::to_string(SPDLOG_LEVEL_CRITICAL)) + return spdlog::level::critical; + if (lc_input == "off" || lc_input == std::to_string(SPDLOG_LEVEL_OFF)) + return spdlog::level::off; + + auto err_msg = fmt::format("ParseLogLevel can't parse input string: '{}'", input); + throw JException(err_msg); +} + +inline std::string LogLevelToString(spdlog::level::level_enum input) { + + // Convert the source string to lower case + switch (input) { + case spdlog::level::trace: + return "trace"; + case spdlog::level::debug: + return "debug"; + case spdlog::level::info: + return "info"; + case spdlog::level::warn: + return "warn"; + case spdlog::level::err: + return "error"; + case spdlog::level::critical: + return "critical"; + case spdlog::level::off: + return "off"; + case spdlog::level::n_levels: + [[fallthrough]]; + default: + break; + } + + auto err_msg = + fmt::format("ParseLogLevel don't know this log level: '{}'", fmt::underlying(input)); + throw JException(err_msg); } +} // namespace eicrecon diff --git a/src/extensions/spdlog/SpdlogFormatters.h b/src/extensions/spdlog/SpdlogFormatters.h index ab8ee94c58..d350410bc6 100644 --- a/src/extensions/spdlog/SpdlogFormatters.h +++ b/src/extensions/spdlog/SpdlogFormatters.h @@ -17,11 +17,11 @@ #if FMT_VERSION >= 90000 -template<> struct fmt::formatter : fmt::ostream_formatter {}; -template<> struct fmt::formatter : fmt::ostream_formatter {}; -template<> struct fmt::formatter : fmt::ostream_formatter {}; -template<> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; -template<> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; #endif // FMT_VERSION >= 90000 diff --git a/src/extensions/spdlog/SpdlogMixin.h b/src/extensions/spdlog/SpdlogMixin.h index b5781c0889..c0eedc22cb 100644 --- a/src/extensions/spdlog/SpdlogMixin.h +++ b/src/extensions/spdlog/SpdlogMixin.h @@ -11,8 +11,8 @@ #include "SpdlogExtensions.h" namespace eicrecon { - class SpdlogMixin { - /** Logger mixin +class SpdlogMixin { + /** Logger mixin * * @example: * class MyFactory : JFactory, SpdlogMixin { @@ -29,10 +29,10 @@ namespace eicrecon { * } * }; */ - public: - using level = Log_service::level; +public: + using level = Log_service::level; - /** + /** * Initializes logger through current LogService * @param app - JApplication pointer, as obtained from GetApplication() * @param param_prefix - name of both logger and user parameter @@ -50,18 +50,18 @@ namespace eicrecon { * * will create "BTRK:TrackerHits" logger and check -PBTRK:TrackerHits:LogLevel user parameter */ - void InitLogger(JApplication* app, const std::string ¶m_prefix, const level default_level = level::info) { + void InitLogger(JApplication* app, const std::string& param_prefix, + const level default_level = level::info) { - // Logger. Get plugin level sub-log - m_log = app->GetService()->logger(param_prefix, default_level); - } + // Logger. Get plugin level sub-log + m_log = app->GetService()->logger(param_prefix, default_level); + } - public: - std::shared_ptr &logger() { return m_log; } +public: + std::shared_ptr& logger() { return m_log; } - protected: // FIXME change to private - /// current logger - std::shared_ptr m_log; - - }; -} +protected: // FIXME change to private + /// current logger + std::shared_ptr m_log; +}; +} // namespace eicrecon diff --git a/src/extensions/spdlog/SpdlogToActs.h b/src/extensions/spdlog/SpdlogToActs.h index b3b5216e21..427abc8c38 100644 --- a/src/extensions/spdlog/SpdlogToActs.h +++ b/src/extensions/spdlog/SpdlogToActs.h @@ -27,19 +27,18 @@ namespace eicrecon { using namespace Acts::Logging; using SpdlogToActsLevel_t = boost::bimap; -static SpdlogToActsLevel_t kSpdlogToActsLevel = boost::assign::list_of - (spdlog::level::trace, Acts::Logging::VERBOSE) - (spdlog::level::debug, Acts::Logging::DEBUG) - (spdlog::level::info, Acts::Logging::INFO) - (spdlog::level::warn, Acts::Logging::WARNING) - (spdlog::level::err, Acts::Logging::ERROR) - (spdlog::level::critical, Acts::Logging::FATAL); +static SpdlogToActsLevel_t kSpdlogToActsLevel = + boost::assign::list_of( + spdlog::level::trace, Acts::Logging::VERBOSE)(spdlog::level::debug, Acts::Logging::DEBUG)( + spdlog::level::info, Acts::Logging::INFO)(spdlog::level::warn, Acts::Logging::WARNING)( + spdlog::level::err, Acts::Logging::ERROR)(spdlog::level::critical, Acts::Logging::FATAL); inline Acts::Logging::Level SpdlogToActsLevel(spdlog::level::level_enum input) { try { return kSpdlogToActsLevel.left.at(input); } catch (...) { - auto err_msg = fmt::format("SpdlogToActsLevel don't know this log level: '{}'", fmt::underlying(input)); + auto err_msg = + fmt::format("SpdlogToActsLevel don't know this log level: '{}'", fmt::underlying(input)); throw JException(err_msg); } } @@ -48,7 +47,8 @@ inline spdlog::level::level_enum ActsToSpdlogLevel(Acts::Logging::Level input) { try { return kSpdlogToActsLevel.right.at(input); } catch (...) { - auto err_msg = fmt::format("ActsToSpdlogLevel don't know this log level: '{}'", fmt::underlying(input)); + auto err_msg = + fmt::format("ActsToSpdlogLevel don't know this log level: '{}'", fmt::underlying(input)); throw JException(err_msg); } } @@ -58,95 +58,93 @@ inline spdlog::level::level_enum ActsToSpdlogLevel(Acts::Logging::Level input) { /// This class allows to print debug messages without further modifications to /// a specified output stream. class SpdlogPrintPolicy final : public Acts::Logging::OutputPrintPolicy { - public: - /// @brief constructor - /// - /// @param [in] out pointer to output stream object - /// - /// @pre @p out is non-zero - explicit SpdlogPrintPolicy(std::shared_ptr out, std::vector suppressions = {}) - : m_out(out) { - std::transform(suppressions.begin(), suppressions.end(), std::back_inserter(m_suppressions), - [](const std::string& supp_string) { - return std::make_tuple(supp_string, std::regex(supp_string), 0, Acts::Logging::INFO); - } - ); - } +public: + /// @brief constructor + /// + /// @param [in] out pointer to output stream object + /// + /// @pre @p out is non-zero + explicit SpdlogPrintPolicy(std::shared_ptr out, + std::vector suppressions = {}) + : m_out(out) { + std::transform(suppressions.begin(), suppressions.end(), std::back_inserter(m_suppressions), + [](const std::string& supp_string) { + return std::make_tuple(supp_string, std::regex(supp_string), 0, + Acts::Logging::INFO); + }); + } - /// @brief destructor - ~SpdlogPrintPolicy() { - for (const auto& [supp_string, supp_regex, supp_count, supp_level] : m_suppressions) { - if (supp_count > 0) { - m_out->log(ActsToSpdlogLevel(supp_level), "\"{}\" suppressed {} times", supp_string, supp_count); - } + /// @brief destructor + ~SpdlogPrintPolicy() { + for (const auto& [supp_string, supp_regex, supp_count, supp_level] : m_suppressions) { + if (supp_count > 0) { + m_out->log(ActsToSpdlogLevel(supp_level), "\"{}\" suppressed {} times", supp_string, + supp_count); } } + } - /// @brief flush the debug message to the destination stream - /// - /// @param [in] lvl debug level of debug message - /// @param [in] input text of debug message - void flush(const Level& lvl, const std::string& input) final { - for (auto& [supp_string, supp_regex, supp_count, supp_level] : m_suppressions) { - if (std::regex_search(input, supp_regex)) { - supp_count++; - supp_level = std::max(lvl, supp_level); - return; - } - } - m_out->log(ActsToSpdlogLevel(lvl), input); - if (lvl >= getFailureThreshold()) { - throw ThresholdFailure( - "Previous debug message exceeds the " - "ACTS_LOG_FAILURE_THRESHOLD=" + - std::string{levelName(getFailureThreshold())} + - " configuration, bailing out. See " - "https://acts.readthedocs.io/en/latest/core/" - "logging.html#logging-thresholds"); + /// @brief flush the debug message to the destination stream + /// + /// @param [in] lvl debug level of debug message + /// @param [in] input text of debug message + void flush(const Level& lvl, const std::string& input) final { + for (auto& [supp_string, supp_regex, supp_count, supp_level] : m_suppressions) { + if (std::regex_search(input, supp_regex)) { + supp_count++; + supp_level = std::max(lvl, supp_level); + return; } } + m_out->log(ActsToSpdlogLevel(lvl), input); + if (lvl >= getFailureThreshold()) { + throw ThresholdFailure("Previous debug message exceeds the " + "ACTS_LOG_FAILURE_THRESHOLD=" + + std::string{levelName(getFailureThreshold())} + + " configuration, bailing out. See " + "https://acts.readthedocs.io/en/latest/core/" + "logging.html#logging-thresholds"); + } + } - /// Fulfill @c OutputPrintPolicy interface. This policy doesn't actually have a - /// name, so the assumption is that somewhere in the decorator hierarchy, - /// there is something that returns a name without delegating to a wrappee, - /// before reaching this overload. - /// @note This method will throw an exception - /// @return the name, but it never returns - const std::string& name() const override { - throw std::runtime_error{ - "Default print policy doesn't have a name. Is there no named output in " - "the decorator chain?"}; - }; - - /// Make a copy of this print policy with a new name - /// @param name the new name - /// @return the copy - std::unique_ptr clone( - const std::string& name) const override { - (void)name; - return std::make_unique(m_out); - }; - - private: - /// pointer to destination output stream - std::shared_ptr m_out; - - /// regexes for messages to be suppressed - std::vector> m_suppressions; + /// Fulfill @c OutputPrintPolicy interface. This policy doesn't actually have a + /// name, so the assumption is that somewhere in the decorator hierarchy, + /// there is something that returns a name without delegating to a wrappee, + /// before reaching this overload. + /// @note This method will throw an exception + /// @return the name, but it never returns + const std::string& name() const override { + throw std::runtime_error{ + "Default print policy doesn't have a name. Is there no named output in " + "the decorator chain?"}; + }; + + /// Make a copy of this print policy with a new name + /// @param name the new name + /// @return the copy + std::unique_ptr clone(const std::string& name) const override { + (void)name; + return std::make_unique(m_out); + }; + +private: + /// pointer to destination output stream + std::shared_ptr m_out; + + /// regexes for messages to be suppressed + std::vector> + m_suppressions; }; -inline std::unique_ptr getSpdlogLogger( - const std::string& name, - std::shared_ptr log, - std::vector suppressions = {}) { +inline std::unique_ptr +getSpdlogLogger(const std::string& name, std::shared_ptr log, + std::vector suppressions = {}) { const Acts::Logging::Level lvl = SpdlogToActsLevel(log->level()); - auto output = std::make_unique( - std::make_unique(log, suppressions), - name); + auto output = std::make_unique( + std::make_unique(log, suppressions), name); auto print = std::make_unique(lvl); return std::make_unique(std::move(output), std::move(print)); } - -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/CalorimeterClusterRecoCoG_factory.h b/src/factories/calorimetry/CalorimeterClusterRecoCoG_factory.h index 7d8bd56eb6..eec2223b90 100644 --- a/src/factories/calorimetry/CalorimeterClusterRecoCoG_factory.h +++ b/src/factories/calorimetry/CalorimeterClusterRecoCoG_factory.h @@ -12,53 +12,56 @@ namespace eicrecon { -class CalorimeterClusterRecoCoG_factory : public JOmniFactory { +class CalorimeterClusterRecoCoG_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::CalorimeterClusterRecoCoG; + using AlgoT = eicrecon::CalorimeterClusterRecoCoG; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_proto_input {this}; + PodioInput m_proto_input{this}; #if EDM4EIC_VERSION_MAJOR >= 7 - PodioInput m_mchitassocs_input {this}; + PodioInput m_mchitassocs_input{this}; #else - PodioInput m_mchits_input {this}; + PodioInput m_mchits_input{this}; #endif + PodioOutput m_cluster_output{this}; + PodioOutput m_assoc_output{this}; - PodioOutput m_cluster_output {this}; - PodioOutput m_assoc_output {this}; - - ParameterRef m_energyWeight {this, "energyWeight", config().energyWeight}; - ParameterRef m_samplingFraction {this, "samplingFraction", config().sampFrac}; - ParameterRef m_logWeightBase {this, "logWeightBase", config().logWeightBase}; - ParameterRef> m_logWeightBaseCoeffs {this, "logWeightBaseCoeffs", config().logWeightBaseCoeffs}; - ParameterRef m_logWeightBase_Eref {this, "logWeightBase_Eref", config().logWeightBase_Eref}; - ParameterRef m_longitudinalShowerInfoAvailable {this, "longitudinalShowerInfoAvailable", config().longitudinalShowerInfoAvailable}; - ParameterRef m_enableEtaBounds {this, "enableEtaBounds", config().enableEtaBounds}; + ParameterRef m_energyWeight{this, "energyWeight", config().energyWeight}; + ParameterRef m_samplingFraction{this, "samplingFraction", config().sampFrac}; + ParameterRef m_logWeightBase{this, "logWeightBase", config().logWeightBase}; + ParameterRef> m_logWeightBaseCoeffs{this, "logWeightBaseCoeffs", + config().logWeightBaseCoeffs}; + ParameterRef m_logWeightBase_Eref{this, "logWeightBase_Eref", + config().logWeightBase_Eref}; + ParameterRef m_longitudinalShowerInfoAvailable{this, "longitudinalShowerInfoAvailable", + config().longitudinalShowerInfoAvailable}; + ParameterRef m_enableEtaBounds{this, "enableEtaBounds", config().enableEtaBounds}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { + void Process(int64_t run_number, uint64_t event_number) { #if EDM4EIC_VERSION_MAJOR >= 7 - m_algo->process({m_proto_input(), m_mchitassocs_input()}, + m_algo->process({m_proto_input(), m_mchitassocs_input()}, #else - m_algo->process({m_proto_input(), m_mchits_input()}, + m_algo->process({m_proto_input(), m_mchits_input()}, #endif - {m_cluster_output().get(), m_assoc_output().get()}); - } + {m_cluster_output().get(), m_assoc_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/CalorimeterHitDigi_factory.h b/src/factories/calorimetry/CalorimeterHitDigi_factory.h index 1fc28bc2da..03dc56c003 100644 --- a/src/factories/calorimetry/CalorimeterHitDigi_factory.h +++ b/src/factories/calorimetry/CalorimeterHitDigi_factory.h @@ -11,50 +11,51 @@ namespace eicrecon { -class CalorimeterHitDigi_factory : public JOmniFactory { +class CalorimeterHitDigi_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::CalorimeterHitDigi; + using AlgoT = eicrecon::CalorimeterHitDigi; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_hits_input {this}; - PodioOutput m_hits_output {this}; + PodioInput m_hits_input{this}; + PodioOutput m_hits_output{this}; #if EDM4EIC_VERSION_MAJOR >= 7 - PodioOutput m_hit_assocs_output {this}; + PodioOutput m_hit_assocs_output{this}; #endif - ParameterRef> m_energyResolutions {this, "energyResolutions", config().eRes}; - ParameterRef m_timeResolution {this, "timeResolution", config().tRes}; - ParameterRef m_capADC {this, "capacityADC", config().capADC}; - ParameterRef m_dyRangeADC {this, "dynamicRangeADC", config().dyRangeADC}; - ParameterRef m_pedMeanADC {this, "pedestalMean", config().pedMeanADC}; - ParameterRef m_pedSigmaADC {this, "pedestalSigma", config().pedSigmaADC}; - ParameterRef m_resolutionTDC {this, "resolutionTDC", config().resolutionTDC}; - ParameterRef m_corrMeanScale {this, "scaleResponse", config().corrMeanScale}; - ParameterRef> m_fields {this, "signalSumFields", config().fields}; - ParameterRef m_readout {this, "readoutClass", config().readout}; + ParameterRef> m_energyResolutions{this, "energyResolutions", config().eRes}; + ParameterRef m_timeResolution{this, "timeResolution", config().tRes}; + ParameterRef m_capADC{this, "capacityADC", config().capADC}; + ParameterRef m_dyRangeADC{this, "dynamicRangeADC", config().dyRangeADC}; + ParameterRef m_pedMeanADC{this, "pedestalMean", config().pedMeanADC}; + ParameterRef m_pedSigmaADC{this, "pedestalSigma", config().pedSigmaADC}; + ParameterRef m_resolutionTDC{this, "resolutionTDC", config().resolutionTDC}; + ParameterRef m_corrMeanScale{this, "scaleResponse", config().corrMeanScale}; + ParameterRef> m_fields{this, "signalSumFields", config().fields}; + ParameterRef m_readout{this, "readoutClass", config().readout}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_nr, uint64_t event_nr) { + void Process(int64_t run_nr, uint64_t event_nr) { #if EDM4EIC_VERSION_MAJOR >= 7 - m_algo->process({m_hits_input()}, {m_hits_output().get(), m_hit_assocs_output().get()}); + m_algo->process({m_hits_input()}, {m_hits_output().get(), m_hit_assocs_output().get()}); #else - m_algo->process({m_hits_input()}, {m_hits_output().get()}); + m_algo->process({m_hits_input()}, {m_hits_output().get()}); #endif - } + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/CalorimeterHitReco_factory.h b/src/factories/calorimetry/CalorimeterHitReco_factory.h index f059e367a6..e738996073 100644 --- a/src/factories/calorimetry/CalorimeterHitReco_factory.h +++ b/src/factories/calorimetry/CalorimeterHitReco_factory.h @@ -7,50 +7,51 @@ #include "services/algorithms_init/AlgorithmsInit_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { -class CalorimeterHitReco_factory : public JOmniFactory { +class CalorimeterHitReco_factory + : public JOmniFactory { private: public: - using AlgoT = eicrecon::CalorimeterHitReco; + using AlgoT = eicrecon::CalorimeterHitReco; + private: - std::unique_ptr m_algo; - - PodioInput m_raw_hits_input {this}; - PodioOutput m_rec_hits_output {this}; - - ParameterRef m_capADC {this, "capacityADC", config().capADC}; - ParameterRef m_dyRangeADC {this, "dynamicRangeADC", config().dyRangeADC}; - ParameterRef m_pedMeanADC {this, "pedestalMean", config().pedMeanADC}; - ParameterRef m_pedSigmaADC {this, "pedestalSigma", config().pedSigmaADC}; - ParameterRef m_resolutionTDC {this, "resolutionTDC", config().resolutionTDC}; - ParameterRef m_thresholdFactor {this, "thresholdFactor", config().thresholdFactor}; - ParameterRef m_thresholdValue {this, "thresholdValue", config().thresholdValue}; - ParameterRef m_samplingFraction {this, "samplingFraction", config().sampFrac}; - ParameterRef m_readout {this, "readout", config().readout}; - ParameterRef m_layerField {this, "layerField", config().layerField}; - ParameterRef m_sectorField {this, "sectorField", config().sectorField}; - ParameterRef m_localDetElement {this, "localDetElement", config().localDetElement}; - ParameterRef> m_localDetFields {this, "localDetFields", config().localDetFields}; - - Service m_algorithmsInit {this}; + std::unique_ptr m_algo; + + PodioInput m_raw_hits_input{this}; + PodioOutput m_rec_hits_output{this}; + + ParameterRef m_capADC{this, "capacityADC", config().capADC}; + ParameterRef m_dyRangeADC{this, "dynamicRangeADC", config().dyRangeADC}; + ParameterRef m_pedMeanADC{this, "pedestalMean", config().pedMeanADC}; + ParameterRef m_pedSigmaADC{this, "pedestalSigma", config().pedSigmaADC}; + ParameterRef m_resolutionTDC{this, "resolutionTDC", config().resolutionTDC}; + ParameterRef m_thresholdFactor{this, "thresholdFactor", config().thresholdFactor}; + ParameterRef m_thresholdValue{this, "thresholdValue", config().thresholdValue}; + ParameterRef m_samplingFraction{this, "samplingFraction", config().sampFrac}; + ParameterRef m_readout{this, "readout", config().readout}; + ParameterRef m_layerField{this, "layerField", config().layerField}; + ParameterRef m_sectorField{this, "sectorField", config().sectorField}; + ParameterRef m_localDetElement{this, "localDetElement", config().localDetElement}; + ParameterRef> m_localDetFields{this, "localDetFields", + config().localDetFields}; + + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_raw_hits_input()}, {m_rec_hits_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_raw_hits_input()}, {m_rec_hits_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/CalorimeterHitsMerger_factory.h b/src/factories/calorimetry/CalorimeterHitsMerger_factory.h index 7105376532..faa19d43ca 100644 --- a/src/factories/calorimetry/CalorimeterHitsMerger_factory.h +++ b/src/factories/calorimetry/CalorimeterHitsMerger_factory.h @@ -9,35 +9,37 @@ namespace eicrecon { -class CalorimeterHitsMerger_factory : public JOmniFactory { +class CalorimeterHitsMerger_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::CalorimeterHitsMerger; + using AlgoT = eicrecon::CalorimeterHitsMerger; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_hits_input {this}; - PodioOutput m_hits_output {this}; + PodioInput m_hits_input{this}; + PodioOutput m_hits_output{this}; - ParameterRef m_readout {this, "readout", config().readout}; - ParameterRef> m_field_transformations {this, "fieldTransformations", config().fieldTransformations}; + ParameterRef m_readout{this, "readout", config().readout}; + ParameterRef> m_field_transformations{this, "fieldTransformations", + config().fieldTransformations}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_hits_input()}, {m_hits_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_hits_input()}, {m_hits_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/CalorimeterIslandCluster_factory.h b/src/factories/calorimetry/CalorimeterIslandCluster_factory.h index 69de873e2f..d02487624d 100644 --- a/src/factories/calorimetry/CalorimeterIslandCluster_factory.h +++ b/src/factories/calorimetry/CalorimeterIslandCluster_factory.h @@ -7,54 +7,58 @@ #include "services/algorithms_init/AlgorithmsInit_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { -class CalorimeterIslandCluster_factory : public JOmniFactory { +class CalorimeterIslandCluster_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::CalorimeterIslandCluster; + using AlgoT = eicrecon::CalorimeterIslandCluster; + private: - std::unique_ptr m_algo; - - PodioInput m_calo_hit_input {this}; - PodioOutput m_proto_cluster_output {this}; - - ParameterRef m_sectorDist {this, "sectorDist", config().sectorDist}; - ParameterRef> m_localDistXY {this, "localDistXY", config().localDistXY}; - ParameterRef> m_localDistXZ {this, "localDistXZ", config().localDistXZ}; - ParameterRef> m_localDistYZ {this, "localDistYZ", config().localDistYZ}; - ParameterRef> m_globallDistRPhi {this, "globalDistRPhi", config().globalDistRPhi}; - ParameterRef> m_globalDistEtaPhi {this, "globalDistEtaPhi", config().globalDistEtaPhi}; - ParameterRef> m_dimScalledLocalDistXY {this, "dimScaledLocalDistXY", config().dimScaledLocalDistXY}; - ParameterRef m_adjacencyMatrix {this, "adjacencyMatrix", config().adjacencyMatrix}; - ParameterRef m_readout {this, "readoutClass", config().readout}; - ParameterRef m_splitCluster {this, "splitCluster", config().splitCluster}; - ParameterRef m_minClusterHitEdep {this, "minClusterHitEdep", config().minClusterHitEdep}; - ParameterRef m_minClusterCenterEdep {this, "minClusterCenterEdep", config().minClusterCenterEdep}; - ParameterRef m_tepm {this, "transverseEnergyProfileMetric", config().transverseEnergyProfileMetric}; - ParameterRef m_teps {this, "transverseEnergyProfileScale", config().transverseEnergyProfileScale}; - - Service m_algorithmsInit {this}; + std::unique_ptr m_algo; -public: + PodioInput m_calo_hit_input{this}; + PodioOutput m_proto_cluster_output{this}; - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - // Remove spaces from adjacency matrix - // cfg.adjacencyMatrix.erase( - // std::remove_if(cfg.adjacencyMatrix.begin(), cfg.adjacencyMatrix.end(), ::isspace), cfg.adjacencyMatrix.end()); - m_algo->applyConfig(config()); - m_algo->init(); - } + ParameterRef m_sectorDist{this, "sectorDist", config().sectorDist}; + ParameterRef> m_localDistXY{this, "localDistXY", config().localDistXY}; + ParameterRef> m_localDistXZ{this, "localDistXZ", config().localDistXZ}; + ParameterRef> m_localDistYZ{this, "localDistYZ", config().localDistYZ}; + ParameterRef> m_globallDistRPhi{this, "globalDistRPhi", + config().globalDistRPhi}; + ParameterRef> m_globalDistEtaPhi{this, "globalDistEtaPhi", + config().globalDistEtaPhi}; + ParameterRef> m_dimScalledLocalDistXY{this, "dimScaledLocalDistXY", + config().dimScaledLocalDistXY}; + ParameterRef m_adjacencyMatrix{this, "adjacencyMatrix", config().adjacencyMatrix}; + ParameterRef m_readout{this, "readoutClass", config().readout}; + ParameterRef m_splitCluster{this, "splitCluster", config().splitCluster}; + ParameterRef m_minClusterHitEdep{this, "minClusterHitEdep", config().minClusterHitEdep}; + ParameterRef m_minClusterCenterEdep{this, "minClusterCenterEdep", + config().minClusterCenterEdep}; + ParameterRef m_tepm{this, "transverseEnergyProfileMetric", + config().transverseEnergyProfileMetric}; + ParameterRef m_teps{this, "transverseEnergyProfileScale", + config().transverseEnergyProfileScale}; - void ChangeRun(int64_t run_number) { - } + Service m_algorithmsInit{this}; + +public: + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + // Remove spaces from adjacency matrix + // cfg.adjacencyMatrix.erase( + // std::remove_if(cfg.adjacencyMatrix.begin(), cfg.adjacencyMatrix.end(), ::isspace), cfg.adjacencyMatrix.end()); + m_algo->applyConfig(config()); + m_algo->init(); + } - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_calo_hit_input()}, {m_proto_cluster_output().get()}); - } + void ChangeRun(int64_t run_number) {} + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_calo_hit_input()}, {m_proto_cluster_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/CalorimeterParticleIDPostML_factory.h b/src/factories/calorimetry/CalorimeterParticleIDPostML_factory.h index 51769c13c0..2c5f8c75b9 100644 --- a/src/factories/calorimetry/CalorimeterParticleIDPostML_factory.h +++ b/src/factories/calorimetry/CalorimeterParticleIDPostML_factory.h @@ -7,39 +7,40 @@ #include "services/algorithms_init/AlgorithmsInit_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { -class CalorimeterParticleIDPostML_factory : public JOmniFactory { +class CalorimeterParticleIDPostML_factory + : public JOmniFactory { public: using AlgoT = eicrecon::CalorimeterParticleIDPostML; + private: std::unique_ptr m_algo; - PodioInput m_cluster_input {this}; - PodioInput m_cluster_assoc_input {this}; - PodioInput m_prediction_tensor_input {this}; + PodioInput m_cluster_input{this}; + PodioInput m_cluster_assoc_input{this}; + PodioInput m_prediction_tensor_input{this}; - PodioOutput m_cluster_output {this}; - PodioOutput m_cluster_assoc_output {this}; - PodioOutput m_particle_id_output {this}; + PodioOutput m_cluster_output{this}; + PodioOutput m_cluster_assoc_output{this}; + PodioOutput m_particle_id_output{this}; public: void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_cluster_input(), m_cluster_assoc_input(), m_prediction_tensor_input()}, - {m_cluster_output().get(), m_cluster_assoc_output().get(), m_particle_id_output().get()}); + m_algo->process( + {m_cluster_input(), m_cluster_assoc_input(), m_prediction_tensor_input()}, + {m_cluster_output().get(), m_cluster_assoc_output().get(), m_particle_id_output().get()}); } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/CalorimeterParticleIDPreML_factory.h b/src/factories/calorimetry/CalorimeterParticleIDPreML_factory.h index 253abf1f69..107d224883 100644 --- a/src/factories/calorimetry/CalorimeterParticleIDPreML_factory.h +++ b/src/factories/calorimetry/CalorimeterParticleIDPreML_factory.h @@ -7,37 +7,37 @@ #include "services/algorithms_init/AlgorithmsInit_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { -class CalorimeterParticleIDPreML_factory : public JOmniFactory { +class CalorimeterParticleIDPreML_factory + : public JOmniFactory { public: using AlgoT = eicrecon::CalorimeterParticleIDPreML; + private: std::unique_ptr m_algo; - PodioInput m_cluster_input {this}; - PodioInput m_cluster_assoc_input {this}; + PodioInput m_cluster_input{this}; + PodioInput m_cluster_assoc_input{this}; - PodioOutput m_feature_tensor_output {this}; - PodioOutput m_target_tensor_output {this}; + PodioOutput m_feature_tensor_output{this}; + PodioOutput m_target_tensor_output{this}; public: void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_cluster_input(), m_cluster_assoc_input()}, - {m_feature_tensor_output().get(), m_target_tensor_output().get()}); + m_algo->process({m_cluster_input(), m_cluster_assoc_input()}, + {m_feature_tensor_output().get(), m_target_tensor_output().get()}); } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/CalorimeterTruthClustering_factory.h b/src/factories/calorimetry/CalorimeterTruthClustering_factory.h index 880494a276..1ebe20382e 100644 --- a/src/factories/calorimetry/CalorimeterTruthClustering_factory.h +++ b/src/factories/calorimetry/CalorimeterTruthClustering_factory.h @@ -8,33 +8,31 @@ #include "services/algorithms_init/AlgorithmsInit_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { class CalorimeterTruthClustering_factory : public JOmniFactory { public: - using AlgoT = eicrecon::CalorimeterTruthClustering; + using AlgoT = eicrecon::CalorimeterTruthClustering; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_rc_hits_input {this}; - PodioInput m_mc_hits_input {this}; - PodioOutput m_proto_clusters_output {this}; + PodioInput m_rc_hits_input{this}; + PodioInput m_mc_hits_input{this}; + PodioOutput m_proto_clusters_output{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_rc_hits_input(), m_mc_hits_input()}, - {m_proto_clusters_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_rc_hits_input(), m_mc_hits_input()}, {m_proto_clusters_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/EnergyPositionClusterMerger_factory.h b/src/factories/calorimetry/EnergyPositionClusterMerger_factory.h index d92109b650..31d9194c21 100644 --- a/src/factories/calorimetry/EnergyPositionClusterMerger_factory.h +++ b/src/factories/calorimetry/EnergyPositionClusterMerger_factory.h @@ -7,47 +7,47 @@ #include "extensions/jana/JOmniFactory.h" #include "services/algorithms_init/AlgorithmsInit_service.h" - namespace eicrecon { -class EnergyPositionClusterMerger_factory : - public JOmniFactory { +class EnergyPositionClusterMerger_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::EnergyPositionClusterMerger; + using AlgoT = eicrecon::EnergyPositionClusterMerger; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_energy_cluster_input {this}; - PodioInput m_energy_assoc_input {this}; - PodioInput m_position_cluster_input {this}; - PodioInput m_position_assoc_input {this}; + PodioInput m_energy_cluster_input{this}; + PodioInput m_energy_assoc_input{this}; + PodioInput m_position_cluster_input{this}; + PodioInput m_position_assoc_input{this}; - PodioOutput m_cluster_output {this}; - PodioOutput m_assoc_output {this}; + PodioOutput m_cluster_output{this}; + PodioOutput m_assoc_output{this}; - ParameterRef m_energyRelTolerance {this, "energyRelTolerance", config().energyRelTolerance}; - ParameterRef m_phiTolerance {this, "phiTolerance", config().phiTolerance}; - ParameterRef m_etaTolerance {this, "etaTolerance", config().etaTolerance}; + ParameterRef m_energyRelTolerance{this, "energyRelTolerance", + config().energyRelTolerance}; + ParameterRef m_phiTolerance{this, "phiTolerance", config().phiTolerance}; + ParameterRef m_etaTolerance{this, "etaTolerance", config().etaTolerance}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_energy_cluster_input(), m_energy_assoc_input(), - m_position_cluster_input(), m_position_assoc_input()}, - {m_cluster_output().get(), m_assoc_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_energy_cluster_input(), m_energy_assoc_input(), m_position_cluster_input(), + m_position_assoc_input()}, + {m_cluster_output().get(), m_assoc_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/HEXPLIT_factory.h b/src/factories/calorimetry/HEXPLIT_factory.h index c7a9321572..a4630833d3 100644 --- a/src/factories/calorimetry/HEXPLIT_factory.h +++ b/src/factories/calorimetry/HEXPLIT_factory.h @@ -7,37 +7,36 @@ #include "services/algorithms_init/AlgorithmsInit_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { class HEXPLIT_factory : public JOmniFactory { - using AlgoT = eicrecon::HEXPLIT; - private: - std::unique_ptr m_algo; - PodioInput m_rec_hits_input {this}; - PodioOutput m_subcell_hits_output {this}; + using AlgoT = eicrecon::HEXPLIT; + +private: + std::unique_ptr m_algo; + PodioInput m_rec_hits_input{this}; + PodioOutput m_subcell_hits_output{this}; - ParameterRef m_MIP {this, "MIP", config().MIP}; - ParameterRef m_Emin_in_MIPs {this, "Emin_in_MIPs", config().Emin_in_MIPs}; - ParameterRef m_tmax {this, "tmax", config().tmax}; + ParameterRef m_MIP{this, "MIP", config().MIP}; + ParameterRef m_Emin_in_MIPs{this, "Emin_in_MIPs", config().Emin_in_MIPs}; + ParameterRef m_tmax{this, "tmax", config().tmax}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_rec_hits_input()},{m_subcell_hits_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_rec_hits_input()}, {m_subcell_hits_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/ImagingClusterReco_factory.h b/src/factories/calorimetry/ImagingClusterReco_factory.h index 2246f40743..f30b525beb 100644 --- a/src/factories/calorimetry/ImagingClusterReco_factory.h +++ b/src/factories/calorimetry/ImagingClusterReco_factory.h @@ -9,48 +9,48 @@ namespace eicrecon { -class ImagingClusterReco_factory : - public JOmniFactory { +class ImagingClusterReco_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::ImagingClusterReco; + using AlgoT = eicrecon::ImagingClusterReco; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_protos_input {this}; + PodioInput m_protos_input{this}; #if EDM4EIC_VERSION_MAJOR >= 7 - PodioInput m_mchitassocs_input {this}; + PodioInput m_mchitassocs_input{this}; #else - PodioInput m_mchits_input {this}; + PodioInput m_mchits_input{this}; #endif - PodioOutput m_clusters_output {this}; - PodioOutput m_assocs_output {this}; - PodioOutput m_layers_output {this}; + PodioOutput m_clusters_output{this}; + PodioOutput m_assocs_output{this}; + PodioOutput m_layers_output{this}; - ParameterRef m_trackStopLayer {this, "trackStopLayer", config().trackStopLayer}; + ParameterRef m_trackStopLayer{this, "trackStopLayer", config().trackStopLayer}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { + void Process(int64_t run_number, uint64_t event_number) { #if EDM4EIC_VERSION_MAJOR >= 7 - m_algo->process({m_protos_input(), m_mchitassocs_input()}, + m_algo->process({m_protos_input(), m_mchitassocs_input()}, #else - m_algo->process({m_protos_input(), m_mchits_input()}, + m_algo->process({m_protos_input(), m_mchits_input()}, #endif - {m_clusters_output().get(), m_assocs_output().get(), m_layers_output().get()}); - } + {m_clusters_output().get(), m_assocs_output().get(), m_layers_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/calorimetry/ImagingTopoCluster_factory.h b/src/factories/calorimetry/ImagingTopoCluster_factory.h index c46782203c..aa1c1f5395 100644 --- a/src/factories/calorimetry/ImagingTopoCluster_factory.h +++ b/src/factories/calorimetry/ImagingTopoCluster_factory.h @@ -9,43 +9,45 @@ namespace eicrecon { -class ImagingTopoCluster_factory : public JOmniFactory { +class ImagingTopoCluster_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::ImagingTopoCluster; + using AlgoT = eicrecon::ImagingTopoCluster; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_hits_input {this}; - PodioOutput m_protos_output {this}; + PodioInput m_hits_input{this}; + PodioOutput m_protos_output{this}; - ParameterRef> m_ldxy {this, "localDistXY", config().localDistXY}; - ParameterRef> m_ldep {this, "layerDistEtaPhi", config().layerDistEtaPhi}; - ParameterRef> m_ldxy_adjacent {this, "layerDistXY", config().layerDistXY}; - ParameterRef m_laymode {this, "layerMode", config().layerMode}; - ParameterRef m_nlr {this, "neighbourLayersRange", config().neighbourLayersRange}; - ParameterRef m_sd {this, "sectorDist", config().sectorDist}; - ParameterRef m_mched {this, "minClusterHitEdep", config().minClusterHitEdep}; - ParameterRef m_mcced {this, "minClusterCenterEdep", config().minClusterCenterEdep}; - ParameterRef m_mced {this, "minClusterEdep", config().minClusterEdep}; - ParameterRef m_mcnh {this, "minClusterNhits", config().minClusterNhits}; + ParameterRef> m_ldxy{this, "localDistXY", config().localDistXY}; + ParameterRef> m_ldep{this, "layerDistEtaPhi", config().layerDistEtaPhi}; + ParameterRef> m_ldxy_adjacent{this, "layerDistXY", config().layerDistXY}; + ParameterRef m_laymode{this, "layerMode", + config().layerMode}; + ParameterRef m_nlr{this, "neighbourLayersRange", config().neighbourLayersRange}; + ParameterRef m_sd{this, "sectorDist", config().sectorDist}; + ParameterRef m_mched{this, "minClusterHitEdep", config().minClusterHitEdep}; + ParameterRef m_mcced{this, "minClusterCenterEdep", config().minClusterCenterEdep}; + ParameterRef m_mced{this, "minClusterEdep", config().minClusterEdep}; + ParameterRef m_mcnh{this, "minClusterNhits", config().minClusterNhits}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_hits_input()}, {m_protos_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_hits_input()}, {m_protos_output().get()}); + } }; } // namespace eicrecon diff --git a/src/factories/calorimetry/TrackClusterMergeSplitter_factory.h b/src/factories/calorimetry/TrackClusterMergeSplitter_factory.h index e5d6daec9c..05416a6fac 100644 --- a/src/factories/calorimetry/TrackClusterMergeSplitter_factory.h +++ b/src/factories/calorimetry/TrackClusterMergeSplitter_factory.h @@ -15,56 +15,51 @@ namespace eicrecon { - class TrackClusterMergeSplitter_factory : public JOmniFactory { - - public: - - using AlgoT = eicrecon::TrackClusterMergeSplitter; - - private: - - // algorithm to run - std::unique_ptr m_algo; - - // input collections - PodioInput m_protoclusters_input {this}; - PodioInput m_track_projections_input {this}; - - // output collections - PodioOutput m_protoclusters_output {this}; - - // parameter bindings - ParameterRef m_idCalo {this, "idCalo", config().idCalo}; - ParameterRef m_minSigCut {this, "minSigCut", config().minSigCut}; - ParameterRef m_avgEP {this, "avgEP", config().avgEP}; - ParameterRef m_sigEP {this, "sigEP", config().sigEP}; - ParameterRef m_drAdd {this, "drAdd", config().drAdd}; - ParameterRef m_sampFrac {this, "sampFrac", config().sampFrac}; - ParameterRef m_transverseEnergyProfileScale {this, "transverseEnergyProfileScale", config().transverseEnergyProfileScale}; - - // services - Service m_geoSvc {this}; - Service m_algoInitSvc {this}; - - public: - - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->applyConfig( config() ); - m_algo->init(m_geoSvc().detector()); - } - - void ChangeRun(int64_t run_number) { - /* nothing to do here */ - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process( - {m_protoclusters_input(), m_track_projections_input()}, - {m_protoclusters_output().get()} - ); - } - - }; // end TrackClusterMergeSplitter_factory - -} // end eicrecon namespace +class TrackClusterMergeSplitter_factory + : public JOmniFactory { + +public: + using AlgoT = eicrecon::TrackClusterMergeSplitter; + +private: + // algorithm to run + std::unique_ptr m_algo; + + // input collections + PodioInput m_protoclusters_input{this}; + PodioInput m_track_projections_input{this}; + + // output collections + PodioOutput m_protoclusters_output{this}; + + // parameter bindings + ParameterRef m_idCalo{this, "idCalo", config().idCalo}; + ParameterRef m_minSigCut{this, "minSigCut", config().minSigCut}; + ParameterRef m_avgEP{this, "avgEP", config().avgEP}; + ParameterRef m_sigEP{this, "sigEP", config().sigEP}; + ParameterRef m_drAdd{this, "drAdd", config().drAdd}; + ParameterRef m_sampFrac{this, "sampFrac", config().sampFrac}; + ParameterRef m_transverseEnergyProfileScale{this, "transverseEnergyProfileScale", + config().transverseEnergyProfileScale}; + + // services + Service m_geoSvc{this}; + Service m_algoInitSvc{this}; + +public: + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->applyConfig(config()); + m_algo->init(m_geoSvc().detector()); + } + + void ChangeRun(int64_t run_number) { /* nothing to do here */ } + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_protoclusters_input(), m_track_projections_input()}, + {m_protoclusters_output().get()}); + } + +}; // end TrackClusterMergeSplitter_factory + +} // namespace eicrecon diff --git a/src/factories/calorimetry/TruthEnergyPositionClusterMerger_factory.h b/src/factories/calorimetry/TruthEnergyPositionClusterMerger_factory.h index 46ff519eb7..55cc156ca5 100644 --- a/src/factories/calorimetry/TruthEnergyPositionClusterMerger_factory.h +++ b/src/factories/calorimetry/TruthEnergyPositionClusterMerger_factory.h @@ -9,40 +9,39 @@ namespace eicrecon { -class TruthEnergyPositionClusterMerger_factory : public JOmniFactory { +class TruthEnergyPositionClusterMerger_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::TruthEnergyPositionClusterMerger; + using AlgoT = eicrecon::TruthEnergyPositionClusterMerger; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_mcparticles_input {this}; - PodioInput m_energy_clusters_input {this}; - PodioInput m_energy_assocs_input {this}; - PodioInput m_position_clusters_input {this}; - PodioInput m_position_assocs_input {this}; + PodioInput m_mcparticles_input{this}; + PodioInput m_energy_clusters_input{this}; + PodioInput m_energy_assocs_input{this}; + PodioInput m_position_clusters_input{this}; + PodioInput m_position_assocs_input{this}; - PodioOutput m_clusters_output {this}; - PodioOutput m_assocs_output {this}; + PodioOutput m_clusters_output{this}; + PodioOutput m_assocs_output{this}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process( - {m_mcparticles_input(), - m_energy_clusters_input(), m_energy_assocs_input(), - m_position_clusters_input(), m_position_assocs_input()}, - {m_clusters_output().get(), m_assocs_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_mcparticles_input(), m_energy_clusters_input(), m_energy_assocs_input(), + m_position_clusters_input(), m_position_assocs_input()}, + {m_clusters_output().get(), m_assocs_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/digi/SiliconTrackerDigi_factory.h b/src/factories/digi/SiliconTrackerDigi_factory.h index a708b3335c..40fa7502c0 100644 --- a/src/factories/digi/SiliconTrackerDigi_factory.h +++ b/src/factories/digi/SiliconTrackerDigi_factory.h @@ -7,39 +7,38 @@ #include "services/algorithms_init/AlgorithmsInit_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { -class SiliconTrackerDigi_factory : public JOmniFactory { +class SiliconTrackerDigi_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::SiliconTrackerDigi; + using AlgoT = eicrecon::SiliconTrackerDigi; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_sim_hits_input {this}; + PodioInput m_sim_hits_input{this}; - PodioOutput m_raw_hits_output {this}; - PodioOutput m_assoc_output {this}; + PodioOutput m_raw_hits_output{this}; + PodioOutput m_assoc_output{this}; - ParameterRef m_threshold {this, "threshold", config().threshold}; - ParameterRef m_timeResolution {this, "timeResolution", config().timeResolution}; + ParameterRef m_threshold{this, "threshold", config().threshold}; + ParameterRef m_timeResolution{this, "timeResolution", config().timeResolution}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_sim_hits_input()}, - {m_raw_hits_output().get(),m_assoc_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_sim_hits_input()}, {m_raw_hits_output().get(), m_assoc_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/fardetectors/FarDetectorLinearProjection_factory.h b/src/factories/fardetectors/FarDetectorLinearProjection_factory.h index ebaeab6539..72bb5ec9a5 100644 --- a/src/factories/fardetectors/FarDetectorLinearProjection_factory.h +++ b/src/factories/fardetectors/FarDetectorLinearProjection_factory.h @@ -11,35 +11,35 @@ namespace eicrecon { -class FarDetectorLinearProjection_factory : -public JOmniFactory { +class FarDetectorLinearProjection_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::FarDetectorLinearProjection; + using AlgoT = eicrecon::FarDetectorLinearProjection; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_hits_input {this}; - PodioOutput m_tracks_output {this}; + PodioInput m_hits_input{this}; + PodioOutput m_tracks_output{this}; - ParameterRef> plane_position {this, "planePosition", config().plane_position }; - ParameterRef> plane_a {this, "planeA", config().plane_a }; - ParameterRef> plane_b {this, "planeB", config().plane_b }; + ParameterRef> plane_position{this, "planePosition", config().plane_position}; + ParameterRef> plane_a{this, "planeA", config().plane_a}; + ParameterRef> plane_b{this, "planeB", config().plane_b}; - public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } +public: + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_hits_input()}, {m_tracks_output().get()}); - } - }; + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_hits_input()}, {m_tracks_output().get()}); + } +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/fardetectors/FarDetectorLinearTracking_factory.h b/src/factories/fardetectors/FarDetectorLinearTracking_factory.h index 5611e1fc26..efbaf046d0 100644 --- a/src/factories/fardetectors/FarDetectorLinearTracking_factory.h +++ b/src/factories/fardetectors/FarDetectorLinearTracking_factory.h @@ -13,47 +13,45 @@ namespace eicrecon { -class FarDetectorLinearTracking_factory : - public JOmniFactory { +class FarDetectorLinearTracking_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::FarDetectorLinearTracking; -private: - std::unique_ptr m_algo; - - VariadicPodioInput m_hits_input {this}; - PodioOutput m_tracks_output {this}; - - ParameterRef n_layer {this, "numLayers", config().n_layer }; - ParameterRef layer_hits_max {this, "layerHitsMax", config().layer_hits_max }; - ParameterRef chi2_max {this, "chi2Max", config().chi2_max }; - - public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } + using AlgoT = eicrecon::FarDetectorLinearTracking; - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { +private: + std::unique_ptr m_algo; - try { - std::vector> hits; - for( const auto& hit : m_hits_input() ) { - hits.push_back(gsl::not_null{hit}); - } + VariadicPodioInput m_hits_input{this}; + PodioOutput m_tracks_output{this}; - m_algo->process(hits, {m_tracks_output().get()}); - } - catch(std::exception &e) { - throw JException(e.what()); - } + ParameterRef n_layer{this, "numLayers", config().n_layer}; + ParameterRef layer_hits_max{this, "layerHitsMax", config().layer_hits_max}; + ParameterRef chi2_max{this, "chi2Max", config().chi2_max}; +public: + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + + try { + std::vector> hits; + for (const auto& hit : m_hits_input()) { + hits.push_back(gsl::not_null{hit}); + } + + m_algo->process(hits, {m_tracks_output().get()}); + } catch (std::exception& e) { + throw JException(e.what()); } - }; + } +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/fardetectors/FarDetectorMLReconstruction_factory.h b/src/factories/fardetectors/FarDetectorMLReconstruction_factory.h index 2134c064b2..406ae4ef4b 100644 --- a/src/factories/fardetectors/FarDetectorMLReconstruction_factory.h +++ b/src/factories/fardetectors/FarDetectorMLReconstruction_factory.h @@ -17,39 +17,39 @@ namespace eicrecon { -class FarDetectorMLReconstruction_factory : - public JOmniFactory { +class FarDetectorMLReconstruction_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::FarDetectorMLReconstruction; -private: - std::unique_ptr m_algo; - - PodioInput m_trackparam_input {this}; - PodioInput m_beamelectrons_input {this}; - PodioOutput m_trajectory_output {this}; - PodioOutput m_trackparam_output {this}; - PodioOutput m_track_output {this}; + using AlgoT = eicrecon::FarDetectorMLReconstruction; +private: + std::unique_ptr m_algo; - ParameterRef m_modelPath {this, "modelPath", config().modelPath }; - ParameterRef m_methodName {this, "methodName", config().methodName }; + PodioInput m_trackparam_input{this}; + PodioInput m_beamelectrons_input{this}; + PodioOutput m_trajectory_output{this}; + PodioOutput m_trackparam_output{this}; + PodioOutput m_track_output{this}; + ParameterRef m_modelPath{this, "modelPath", config().modelPath}; + ParameterRef m_methodName{this, "methodName", config().methodName}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_trackparam_input(),m_beamelectrons_input()}, {m_trajectory_output().get(), m_trackparam_output().get(), m_track_output().get()}); - } - }; - -} // eicrecon + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process( + {m_trackparam_input(), m_beamelectrons_input()}, + {m_trajectory_output().get(), m_trackparam_output().get(), m_track_output().get()}); + } +}; + +} // namespace eicrecon diff --git a/src/factories/fardetectors/FarDetectorTrackerCluster_factory.h b/src/factories/fardetectors/FarDetectorTrackerCluster_factory.h index fa4b400d63..367a7f1065 100644 --- a/src/factories/fardetectors/FarDetectorTrackerCluster_factory.h +++ b/src/factories/fardetectors/FarDetectorTrackerCluster_factory.h @@ -9,26 +9,26 @@ namespace eicrecon { -class FarDetectorTrackerCluster_factory : -public JOmniFactory { +class FarDetectorTrackerCluster_factory + : public JOmniFactory { public: using AlgoT = eicrecon::FarDetectorTrackerCluster; + private: std::unique_ptr m_algo; - VariadicPodioInput m_raw_hits_input {this}; - VariadicPodioOutput m_clustered_hits_output {this}; + VariadicPodioInput m_raw_hits_input{this}; + VariadicPodioOutput m_clustered_hits_output{this}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; - ParameterRef m_readout {this, "readoutClass", config().readout}; - ParameterRef m_x_field {this, "xField", config().x_field}; - ParameterRef m_y_field {this, "yField", config().y_field}; - ParameterRef m_hit_time_limit {this, "hitTimeLimit", config().hit_time_limit}; + ParameterRef m_readout{this, "readoutClass", config().readout}; + ParameterRef m_x_field{this, "xField", config().x_field}; + ParameterRef m_y_field{this, "yField", config().y_field}; + ParameterRef m_hit_time_limit{this, "hitTimeLimit", config().hit_time_limit}; public: - /** One time initialization **/ void Configure() { @@ -37,27 +37,23 @@ public JOmniFactoryapplyConfig(config()); m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} void Process(int64_t run_number, uint64_t event_number) { std::vector> clustered_collections; for (const auto& clustered : m_clustered_hits_output()) { - clustered_collections.push_back(gsl::not_null(clustered.get())); + clustered_collections.push_back( + gsl::not_null(clustered.get())); } auto in1 = m_raw_hits_input(); std::vector> in2; std::copy(in1.cbegin(), in1.cend(), std::back_inserter(in2)); - m_algo->process(in2, clustered_collections); } - }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/fardetectors/MatrixTransferStatic_factory.h b/src/factories/fardetectors/MatrixTransferStatic_factory.h index f2bfd6943f..fd6c6f6440 100644 --- a/src/factories/fardetectors/MatrixTransferStatic_factory.h +++ b/src/factories/fardetectors/MatrixTransferStatic_factory.h @@ -17,59 +17,60 @@ namespace eicrecon { -class MatrixTransferStatic_factory : - public JOmniFactory { +class MatrixTransferStatic_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::MatrixTransferStatic; + using AlgoT = eicrecon::MatrixTransferStatic; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_mcparts_input {this}; - PodioInput m_hits_input {this}; - PodioOutput m_tracks_output {this}; + PodioInput m_mcparts_input{this}; + PodioInput m_hits_input{this}; + PodioOutput m_tracks_output{this}; - Service m_geoSvc {this}; + Service m_geoSvc{this}; - ParameterRef partMass {this, "partMass", config().partMass}; - ParameterRef partCharge{this, "partCharge", config().partCharge}; - ParameterRef partPDG {this, "partPDG", config().partPDG}; + ParameterRef partMass{this, "partMass", config().partMass}; + ParameterRef partCharge{this, "partCharge", config().partCharge}; + ParameterRef partPDG{this, "partPDG", config().partPDG}; - ParameterRef local_x_offset {this, "local_x_offset", config().local_x_offset}; - ParameterRef local_y_offset {this, "local_y_offset", config().local_y_offset}; - ParameterRef local_x_slope_offset{this, "local_x_slope_offset", config().local_x_slope_offset}; - ParameterRef local_y_slope_offset{this, "local_y_slope_offset", config().local_y_slope_offset}; - ParameterRef crossingAngle {this, "crossingAngle", config().crossingAngle}; - ParameterRef nomMomentum {this, "nomMomentum", config().nomMomentum}; + ParameterRef local_x_offset{this, "local_x_offset", config().local_x_offset}; + ParameterRef local_y_offset{this, "local_y_offset", config().local_y_offset}; + ParameterRef local_x_slope_offset{this, "local_x_slope_offset", + config().local_x_slope_offset}; + ParameterRef local_y_slope_offset{this, "local_y_slope_offset", + config().local_y_slope_offset}; + ParameterRef crossingAngle{this, "crossingAngle", config().crossingAngle}; + ParameterRef nomMomentum{this, "nomMomentum", config().nomMomentum}; - // FIXME JANA2 does not support vector of vector - //ParameterRef>> aX {this, "aX", config().aX}; - //ParameterRef>> aY {this, "aY", config().aY}; + // FIXME JANA2 does not support vector of vector + //ParameterRef>> aX {this, "aX", config().aX}; + //ParameterRef>> aY {this, "aY", config().aY}; - ParameterRef hit1minZ {this, "hit1minZ", config().hit1minZ}; - ParameterRef hit1maxZ {this, "hit1maxZ", config().hit1maxZ}; - ParameterRef hit2minZ {this, "hit2minZ", config().hit2minZ}; - ParameterRef hit2maxZ {this, "hit2maxZ", config().hit2maxZ}; + ParameterRef hit1minZ{this, "hit1minZ", config().hit1minZ}; + ParameterRef hit1maxZ{this, "hit1maxZ", config().hit1maxZ}; + ParameterRef hit2minZ{this, "hit2minZ", config().hit2minZ}; + ParameterRef hit2maxZ{this, "hit2maxZ", config().hit2maxZ}; - ParameterRef readout {this, "readout", config().readout}; + ParameterRef readout{this, "readout", config().readout}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_mcparts_input(), m_hits_input()}, {m_tracks_output().get()}); - } - + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_mcparts_input(), m_hits_input()}, {m_tracks_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/meta/CollectionCollector_factory.h b/src/factories/meta/CollectionCollector_factory.h index 50d484b311..38bd246c1d 100644 --- a/src/factories/meta/CollectionCollector_factory.h +++ b/src/factories/meta/CollectionCollector_factory.h @@ -6,38 +6,35 @@ namespace eicrecon { - template - class CollectionCollector_factory : public JOmniFactory> { +template +class CollectionCollector_factory : public JOmniFactory> { public: - using AlgoT = eicrecon::CollectionCollector; + using AlgoT = eicrecon::CollectionCollector; private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - typename JOmniFactory>::template VariadicPodioInput m_inputs {this}; - typename JOmniFactory>::template PodioOutput m_output {this}; + typename JOmniFactory>::template VariadicPodioInput m_inputs{ + this}; + typename JOmniFactory>::template PodioOutput m_output{this}; public: - - void Configure() { - m_algo = std::make_unique(this->GetPrefix()); - m_algo->level(static_cast(this->logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { + void Configure() { + m_algo = std::make_unique(this->GetPrefix()); + m_algo->level(static_cast(this->logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + std::vector> in_collections; + for (const auto& in_collection : m_inputs()) { + in_collections.push_back(gsl::not_null{in_collection}); } + typename T::collection_type* merged_collection = m_output().get(); + m_algo->process(in_collections, merged_collection); + }; +}; - void Process(int64_t run_number, uint64_t event_number) { - std::vector> in_collections; - for (const auto& in_collection : m_inputs()) { - in_collections.push_back(gsl::not_null{in_collection}); - } - typename T::collection_type* merged_collection = m_output().get(); - m_algo->process(in_collections, merged_collection); - - }; - - }; - -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/meta/FilterMatching_factory.h b/src/factories/meta/FilterMatching_factory.h index bc1ef180d9..912d4624ce 100644 --- a/src/factories/meta/FilterMatching_factory.h +++ b/src/factories/meta/FilterMatching_factory.h @@ -8,34 +8,38 @@ namespace eicrecon { -template -class FilterMatching_factory : public JOmniFactory> { - - public: - using AlgoT = eicrecon::FilterMatching; - using FactoryT = JOmniFactory>; - - private: - - std::unique_ptr m_algo; - - typename FactoryT::template PodioInput m_collection_input {this}; - typename FactoryT::template PodioInput m_matched_input {this}; - typename FactoryT::template PodioOutput m_is_matched_output {this}; - typename FactoryT::template PodioOutput m_is_not_matched_output {this}; - - public: - void Configure() { - m_algo = std::make_unique(this->GetPrefix()); - m_algo->level(static_cast(this->logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_collection_input(),m_matched_input()},{m_is_matched_output().get(),m_is_not_matched_output().get()}); - }; +template +class FilterMatching_factory + : public JOmniFactory> { + +public: + using AlgoT = eicrecon::FilterMatching; + using FactoryT = JOmniFactory>; + +private: + std::unique_ptr m_algo; + + typename FactoryT::template PodioInput m_collection_input{this}; + typename FactoryT::template PodioInput m_matched_input{this}; + typename FactoryT::template PodioOutput m_is_matched_output{this}; + typename FactoryT::template PodioOutput m_is_not_matched_output{this}; + +public: + void Configure() { + m_algo = std::make_unique(this->GetPrefix()); + m_algo->level(static_cast(this->logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_collection_input(), m_matched_input()}, + {m_is_matched_output().get(), m_is_not_matched_output().get()}); + }; }; // FilterByAssociations_factory -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/meta/ONNXInference_factory.h b/src/factories/meta/ONNXInference_factory.h index 6837783518..7af575cfde 100644 --- a/src/factories/meta/ONNXInference_factory.h +++ b/src/factories/meta/ONNXInference_factory.h @@ -7,49 +7,47 @@ #include "services/algorithms_init/AlgorithmsInit_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { class ONNXInference_factory : public JOmniFactory { public: - using AlgoT = eicrecon::ONNXInference; + using AlgoT = eicrecon::ONNXInference; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - VariadicPodioInput m_input_tensors {this}; + VariadicPodioInput m_input_tensors{this}; - VariadicPodioOutput m_output_tensors {this}; + VariadicPodioOutput m_output_tensors{this}; - ParameterRef m_modelPath {this, "modelPath", config().modelPath}; + ParameterRef m_modelPath{this, "modelPath", config().modelPath}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + std::vector> in_collections; + for (const auto& in_collection : m_input_tensors()) { + in_collections.push_back(gsl::not_null{in_collection}); } - void ChangeRun(int64_t run_number) { + std::vector> out_collections; + for (const auto& out_collection : m_output_tensors()) { + out_collections.push_back(gsl::not_null{out_collection.get()}); } - void Process(int64_t run_number, uint64_t event_number) { - std::vector> in_collections; - for (const auto& in_collection : m_input_tensors()) { - in_collections.push_back(gsl::not_null{in_collection}); - } - - std::vector> out_collections; - for (const auto& out_collection : m_output_tensors()) { - out_collections.push_back(gsl::not_null{out_collection.get()}); - } - - m_algo->process(in_collections, - out_collections); - } + m_algo->process(in_collections, out_collections); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/meta/SubDivideCollection_factory.h b/src/factories/meta/SubDivideCollection_factory.h index 67894e40e8..e7ea2b39bb 100644 --- a/src/factories/meta/SubDivideCollection_factory.h +++ b/src/factories/meta/SubDivideCollection_factory.h @@ -10,40 +10,38 @@ namespace eicrecon { template -class SubDivideCollection_factory : public JOmniFactory, SubDivideCollectionConfig> { +class SubDivideCollection_factory + : public JOmniFactory, SubDivideCollectionConfig> { - public: - using AlgoT = eicrecon::SubDivideCollection; - using FactoryT = JOmniFactory, SubDivideCollectionConfig>; - - private: +public: + using AlgoT = eicrecon::SubDivideCollection; + using FactoryT = JOmniFactory, SubDivideCollectionConfig>; - std::unique_ptr m_algo; +private: + std::unique_ptr m_algo; - typename FactoryT::template PodioInput m_input {this}; - typename FactoryT::template VariadicPodioOutput m_split_output {this}; + typename FactoryT::template PodioInput m_input{this}; + typename FactoryT::template VariadicPodioOutput m_split_output{this}; - typename FactoryT::template Service m_algorithmsInit {this}; + typename FactoryT::template Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(this->GetPrefix()); - m_algo->level(static_cast(this->logger()->level())); - m_algo->applyConfig(this->config()); - m_algo->init(); - } + void Configure() { + m_algo = std::make_unique(this->GetPrefix()); + m_algo->level(static_cast(this->logger()->level())); + m_algo->applyConfig(this->config()); + m_algo->init(); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { + void Process(int64_t run_number, uint64_t event_number) { std::vector> split_collections; for (const auto& split : m_split_output()) { split_collections.push_back(gsl::not_null(split.get())); } - m_algo->process(m_input(),split_collections); - -}; + m_algo->process(m_input(), split_collections); + }; }; // SplitGeometry_factory -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/reco/FarForwardNeutronReconstruction_factory.h b/src/factories/reco/FarForwardNeutronReconstruction_factory.h index 680d2ffb84..a3cf00b176 100644 --- a/src/factories/reco/FarForwardNeutronReconstruction_factory.h +++ b/src/factories/reco/FarForwardNeutronReconstruction_factory.h @@ -8,36 +8,40 @@ #include "services/algorithms_init/AlgorithmsInit_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { - class FarForwardNeutronReconstruction_factory : public JOmniFactory { +class FarForwardNeutronReconstruction_factory + : public JOmniFactory { + + using AlgoT = eicrecon::FarForwardNeutronReconstruction; - using AlgoT = eicrecon::FarForwardNeutronReconstruction; - private: - std::unique_ptr m_algo; - PodioInput m_clusters_hcal_input {this}; - PodioInput m_clusters_ecal_input {this}; - PodioOutput m_neutrons_output {this}; - ParameterRef> m_scale_corr_coeff_hcal {this, "scale_corr_coeff_hcal", config().scale_corr_coeff_hcal}; - ParameterRef> m_scale_corr_coeff_ecal {this, "scale_corr_coeff_ecal", config().scale_corr_coeff_ecal}; - Service m_algorithmsInit {this}; +private: + std::unique_ptr m_algo; + PodioInput m_clusters_hcal_input{this}; + PodioInput m_clusters_ecal_input{this}; + PodioOutput m_neutrons_output{this}; + ParameterRef> m_scale_corr_coeff_hcal{this, "scale_corr_coeff_hcal", + config().scale_corr_coeff_hcal}; + ParameterRef> m_scale_corr_coeff_ecal{this, "scale_corr_coeff_ecal", + config().scale_corr_coeff_ecal}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level((algorithms::LogLevel)logger()->level()); + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level((algorithms::LogLevel)logger()->level()); - m_algo->applyConfig(config()); - m_algo->init(); - } + m_algo->applyConfig(config()); + m_algo->init(); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_clusters_hcal_input(), m_clusters_ecal_input()},{m_neutrons_output().get()}); - } + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_clusters_hcal_input(), m_clusters_ecal_input()}, + {m_neutrons_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/reco/HadronicFinalState_factory.h b/src/factories/reco/HadronicFinalState_factory.h index 10f7bf6905..5ac40fad40 100644 --- a/src/factories/reco/HadronicFinalState_factory.h +++ b/src/factories/reco/HadronicFinalState_factory.h @@ -16,36 +16,36 @@ namespace eicrecon { template -class HadronicFinalState_factory : - public JOmniFactory> { +class HadronicFinalState_factory : public JOmniFactory> { public: - using FactoryT = JOmniFactory>; + using FactoryT = JOmniFactory>; private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - typename FactoryT::template PodioInput m_mc_particles_input {this}; - typename FactoryT::template PodioInput m_rc_particles_input {this}; - typename FactoryT::template PodioInput m_rc_particles_assoc_input {this}; - typename FactoryT::template PodioOutput m_hadronic_final_state_output {this}; + typename FactoryT::template PodioInput m_mc_particles_input{this}; + typename FactoryT::template PodioInput m_rc_particles_input{this}; + typename FactoryT::template PodioInput + m_rc_particles_assoc_input{this}; + typename FactoryT::template PodioOutput + m_hadronic_final_state_output{this}; - typename FactoryT::template Service m_algorithmsInit {this}; + typename FactoryT::template Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(this->GetPrefix()); - m_algo->level(static_cast(this->logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_mc_particles_input(), m_rc_particles_input(), m_rc_particles_assoc_input()}, - {m_hadronic_final_state_output().get()}); - } + void Configure() { + m_algo = std::make_unique(this->GetPrefix()); + m_algo->level(static_cast(this->logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_mc_particles_input(), m_rc_particles_input(), m_rc_particles_assoc_input()}, + {m_hadronic_final_state_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/reco/InclusiveKinematicsML_factory.h b/src/factories/reco/InclusiveKinematicsML_factory.h index 78343cfbd9..71f02a73f5 100644 --- a/src/factories/reco/InclusiveKinematicsML_factory.h +++ b/src/factories/reco/InclusiveKinematicsML_factory.h @@ -15,34 +15,35 @@ namespace eicrecon { -class InclusiveKinematicsML_factory : - public JOmniFactory { +class InclusiveKinematicsML_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::InclusiveKinematicsML; + using AlgoT = eicrecon::InclusiveKinematicsML; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_inclusive_kinematics_electron_input {this}; - PodioInput m_inclusive_kinematics_da_input {this}; - PodioOutput m_inclusive_kinematics_output {this}; + PodioInput m_inclusive_kinematics_electron_input{this}; + PodioInput m_inclusive_kinematics_da_input{this}; + PodioOutput m_inclusive_kinematics_output{this}; - ParameterRef m_modelPath {this, "modelPath", config().modelPath}; + ParameterRef m_modelPath{this, "modelPath", config().modelPath}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_inclusive_kinematics_electron_input(), m_inclusive_kinematics_da_input()}, {m_inclusive_kinematics_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_inclusive_kinematics_electron_input(), m_inclusive_kinematics_da_input()}, + {m_inclusive_kinematics_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/reco/InclusiveKinematicsReconstructed_factory.h b/src/factories/reco/InclusiveKinematicsReconstructed_factory.h index dbc7e922e4..987539c3cb 100644 --- a/src/factories/reco/InclusiveKinematicsReconstructed_factory.h +++ b/src/factories/reco/InclusiveKinematicsReconstructed_factory.h @@ -16,36 +16,39 @@ namespace eicrecon { template -class InclusiveKinematicsReconstructed_factory : - public JOmniFactory> { +class InclusiveKinematicsReconstructed_factory + : public JOmniFactory> { public: - using FactoryT = JOmniFactory>; + using FactoryT = JOmniFactory>; private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - typename FactoryT::template PodioInput m_mc_particles_input {this}; - typename FactoryT::template PodioInput m_scattered_electron_input {this}; - typename FactoryT::template PodioInput m_hadronic_final_state_input {this}; - typename FactoryT::template PodioOutput m_inclusive_kinematics_output {this}; + typename FactoryT::template PodioInput m_mc_particles_input{this}; + typename FactoryT::template PodioInput m_scattered_electron_input{ + this}; + typename FactoryT::template PodioInput m_hadronic_final_state_input{ + this}; + typename FactoryT::template PodioOutput + m_inclusive_kinematics_output{this}; - typename FactoryT::template Service m_algorithmsInit {this}; + typename FactoryT::template Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(this->GetPrefix()); - m_algo->level(static_cast(this->logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_mc_particles_input(), m_scattered_electron_input(), m_hadronic_final_state_input()}, - {m_inclusive_kinematics_output().get()}); - } + void Configure() { + m_algo = std::make_unique(this->GetPrefix()); + m_algo->level(static_cast(this->logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process( + {m_mc_particles_input(), m_scattered_electron_input(), m_hadronic_final_state_input()}, + {m_inclusive_kinematics_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/reco/InclusiveKinematicsTruth_factory.h b/src/factories/reco/InclusiveKinematicsTruth_factory.h index 52adcd7d0f..7b7d3e36dd 100644 --- a/src/factories/reco/InclusiveKinematicsTruth_factory.h +++ b/src/factories/reco/InclusiveKinematicsTruth_factory.h @@ -16,32 +16,31 @@ namespace eicrecon { -class InclusiveKinematicsTruth_factory : - public JOmniFactory { +class InclusiveKinematicsTruth_factory : public JOmniFactory { public: - using AlgoT = eicrecon::InclusiveKinematicsTruth; + using AlgoT = eicrecon::InclusiveKinematicsTruth; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_mc_particles_input {this}; - PodioOutput m_inclusive_kinematics_output {this}; + PodioInput m_mc_particles_input{this}; + PodioOutput m_inclusive_kinematics_output{this}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_mc_particles_input()}, {m_inclusive_kinematics_output().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_mc_particles_input()}, {m_inclusive_kinematics_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/reco/JetReconstruction_factory.h b/src/factories/reco/JetReconstruction_factory.h index 6919ae5d08..ece6aee57d 100644 --- a/src/factories/reco/JetReconstruction_factory.h +++ b/src/factories/reco/JetReconstruction_factory.h @@ -10,56 +10,60 @@ namespace eicrecon { - template - class JetReconstruction_factory : public JOmniFactory, JetReconstructionConfig> { +template +class JetReconstruction_factory + : public JOmniFactory, JetReconstructionConfig> { - public: - // algorithm to run - using Algo = eicrecon::JetReconstruction; - using FactoryT = JOmniFactory, JetReconstructionConfig>; +public: + // algorithm to run + using Algo = eicrecon::JetReconstruction; + using FactoryT = JOmniFactory, JetReconstructionConfig>; - private: - std::unique_ptr m_algo; +private: + std::unique_ptr m_algo; - // input collection - typename FactoryT::template PodioInput m_input {this}; + // input collection + typename FactoryT::template PodioInput m_input{this}; - // output collection - typename FactoryT::template PodioOutput m_output {this}; + // output collection + typename FactoryT::template PodioOutput m_output{this}; - // parameter bindings - typename FactoryT::template ParameterRef m_rJet {this, "rJet", FactoryT::config().rJet}; - typename FactoryT::template ParameterRef m_pJet {this, "pJet", FactoryT::config().pJet}; - typename FactoryT::template ParameterRef m_minCstPt {this, "minCstPt", FactoryT::config().minCstPt}; - typename FactoryT::template ParameterRef m_maxCstPt {this, "maxCstPt", FactoryT::config().maxCstPt}; - typename FactoryT::template ParameterRef m_minJetPt {this, "minJetPt", FactoryT::config().minJetPt}; - typename FactoryT::template ParameterRef m_ghostMaxRap {this, "ghostMaxRap", FactoryT::config().ghostMaxRap}; - typename FactoryT::template ParameterRef m_ghostArea {this, "ghostArea", FactoryT::config().ghostArea}; - typename FactoryT::template ParameterRef m_numGhostRepeat {this, "numGhostRepeat", FactoryT::config().numGhostRepeat}; - typename FactoryT::template ParameterRef m_jetAlgo {this, "jetAlgo", FactoryT::config().jetAlgo}; - typename FactoryT::template ParameterRef m_recombScheme {this, "recombScheme", FactoryT::config().recombScheme}; - typename FactoryT::template ParameterRef m_areaType {this, "areaType", FactoryT::config().areaType}; + // parameter bindings + typename FactoryT::template ParameterRef m_rJet{this, "rJet", FactoryT::config().rJet}; + typename FactoryT::template ParameterRef m_pJet{this, "pJet", FactoryT::config().pJet}; + typename FactoryT::template ParameterRef m_minCstPt{this, "minCstPt", + FactoryT::config().minCstPt}; + typename FactoryT::template ParameterRef m_maxCstPt{this, "maxCstPt", + FactoryT::config().maxCstPt}; + typename FactoryT::template ParameterRef m_minJetPt{this, "minJetPt", + FactoryT::config().minJetPt}; + typename FactoryT::template ParameterRef m_ghostMaxRap{this, "ghostMaxRap", + FactoryT::config().ghostMaxRap}; + typename FactoryT::template ParameterRef m_ghostArea{this, "ghostArea", + FactoryT::config().ghostArea}; + typename FactoryT::template ParameterRef m_numGhostRepeat{this, "numGhostRepeat", + FactoryT::config().numGhostRepeat}; + typename FactoryT::template ParameterRef m_jetAlgo{this, "jetAlgo", + FactoryT::config().jetAlgo}; + typename FactoryT::template ParameterRef m_recombScheme{ + this, "recombScheme", FactoryT::config().recombScheme}; + typename FactoryT::template ParameterRef m_areaType{this, "areaType", + FactoryT::config().areaType}; - public: +public: + void Configure() { + m_algo = std::make_unique(this->GetPrefix()); + m_algo->level(static_cast(this->logger()->level())); + m_algo->applyConfig(FactoryT::config()); + m_algo->init(); + } - void Configure() { - m_algo = std::make_unique(this->GetPrefix()); - m_algo->level(static_cast(this->logger()->level())); - m_algo->applyConfig(FactoryT::config()); - m_algo->init(); - } + void ChangeRun(int64_t run_number) { /* nothing to do */ } - void ChangeRun(int64_t run_number) { - /* nothing to do */ - } + void Process(int64_t run_number, int64_t event_number) { + m_algo->process({m_input()}, {m_output().get()}); + } - void Process(int64_t run_number, int64_t event_number) { - m_algo->process( - {m_input()}, - {m_output().get()} - ); - } +}; // end JetReconstruction_factory definition - }; // end JetReconstruction_factory definition - -} // end eicrecon namespace +} // namespace eicrecon diff --git a/src/factories/reco/TransformBreitFrame_factory.h b/src/factories/reco/TransformBreitFrame_factory.h index ce1ee17d5d..944360ef2e 100644 --- a/src/factories/reco/TransformBreitFrame_factory.h +++ b/src/factories/reco/TransformBreitFrame_factory.h @@ -18,43 +18,38 @@ namespace eicrecon { - class TransformBreitFrame_factory : public JOmniFactory { +class TransformBreitFrame_factory : public JOmniFactory { - public: - // algorithm to run - using Algo = eicrecon::TransformBreitFrame; - private: - std::unique_ptr m_algo; +public: + // algorithm to run + using Algo = eicrecon::TransformBreitFrame; - // input collection - PodioInput m_in_mcpart {this}; - PodioInput m_in_kine {this}; - PodioInput m_in_part {this}; +private: + std::unique_ptr m_algo; - // output collection - PodioOutput m_out_part {this}; + // input collection + PodioInput m_in_mcpart{this}; + PodioInput m_in_kine{this}; + PodioInput m_in_part{this}; - Service m_algorithmsInit {this}; + // output collection + PodioOutput m_out_part{this}; - public: + Service m_algorithmsInit{this}; - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } +public: + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } - void ChangeRun(int64_t run_number) { - /* nothing to do */ - } + void ChangeRun(int64_t run_number) { /* nothing to do */ } - void Process(int64_t run_number, int64_t event_number) { - m_algo->process( - {m_in_mcpart(),m_in_kine(),m_in_part()}, - {m_out_part().get()} - ); - } + void Process(int64_t run_number, int64_t event_number) { + m_algo->process({m_in_mcpart(), m_in_kine(), m_in_part()}, {m_out_part().get()}); + } - }; // end TransfromBreitFrame_factory definition +}; // end TransfromBreitFrame_factory definition -} // end eicrecon namespace +} // namespace eicrecon diff --git a/src/factories/reco/UndoAfterBurnerMCParticles_factory.h b/src/factories/reco/UndoAfterBurnerMCParticles_factory.h index 544aea00eb..6623d3b2b0 100644 --- a/src/factories/reco/UndoAfterBurnerMCParticles_factory.h +++ b/src/factories/reco/UndoAfterBurnerMCParticles_factory.h @@ -14,37 +14,36 @@ namespace eicrecon { -class UndoAfterBurnerMCParticles_factory : - public JOmniFactory { +class UndoAfterBurnerMCParticles_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::UndoAfterBurner; -private: - std::unique_ptr m_algo; + using AlgoT = eicrecon::UndoAfterBurner; - PodioInput m_mcparts_input {this}; - PodioOutput m_postburn_output {this}; +private: + std::unique_ptr m_algo; - ParameterRef m_pid_assume_pion_mass {this, "m_pid_assume_pion_mass", config().m_pid_assume_pion_mass}; - ParameterRef m_crossing_angle {this, "m_crossing_angle", config().m_crossing_angle}; - ParameterRef m_pid_purity {this, "m_pid_purity", config().m_pid_purity}; - ParameterRef m_correct_beam_FX {this, "m_correct_beam_FX", config().m_correct_beam_FX}; - ParameterRef m_pid_use_MC_truth {this, "m_pid_use_MC_truth", config().m_pid_use_MC_truth}; + PodioInput m_mcparts_input{this}; + PodioOutput m_postburn_output{this}; + ParameterRef m_pid_assume_pion_mass{this, "m_pid_assume_pion_mass", + config().m_pid_assume_pion_mass}; + ParameterRef m_crossing_angle{this, "m_crossing_angle", config().m_crossing_angle}; + ParameterRef m_pid_purity{this, "m_pid_purity", config().m_pid_purity}; + ParameterRef m_correct_beam_FX{this, "m_correct_beam_FX", config().m_correct_beam_FX}; + ParameterRef m_pid_use_MC_truth{this, "m_pid_use_MC_truth", config().m_pid_use_MC_truth}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->applyConfig(config()); - } - - void ChangeRun(int64_t run_number) { - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->applyConfig(config()); + } - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_mcparts_input()}, {m_postburn_output().get()}); - } + void ChangeRun(int64_t run_number) {} + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_mcparts_input()}, {m_postburn_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/factories/tracking/TrackerHitReconstruction_factory.h b/src/factories/tracking/TrackerHitReconstruction_factory.h index ad59096931..25fddbdfa5 100644 --- a/src/factories/tracking/TrackerHitReconstruction_factory.h +++ b/src/factories/tracking/TrackerHitReconstruction_factory.h @@ -7,33 +7,31 @@ #include "services/geometry/dd4hep/DD4hep_service.h" #include "extensions/jana/JOmniFactory.h" - namespace eicrecon { -class TrackerHitReconstruction_factory : -public JOmniFactory { +class TrackerHitReconstruction_factory + : public JOmniFactory { - TrackerHitReconstruction m_algo; + TrackerHitReconstruction m_algo; - PodioInput m_raw_hits_input {this}; - PodioOutput m_rec_hits_output {this}; + PodioInput m_raw_hits_input{this}; + PodioOutput m_rec_hits_output{this}; - ParameterRef m_timeResolution {this, "timeResolution", config().timeResolution}; + ParameterRef m_timeResolution{this, "timeResolution", config().timeResolution}; - Service m_geoSvc {this}; + Service m_geoSvc{this}; public: - void Configure() { - m_algo.applyConfig(config()); - m_algo.init(m_geoSvc().converter(), logger()); - } + void Configure() { + m_algo.applyConfig(config()); + m_algo.init(m_geoSvc().converter(), logger()); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { - m_rec_hits_output() = m_algo.process(*m_raw_hits_input()); - } + void Process(int64_t run_number, uint64_t event_number) { + m_rec_hits_output() = m_algo.process(*m_raw_hits_input()); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/beam/beam.cc b/src/global/beam/beam.cc index 62435fa0a6..1b3dc06eb3 100644 --- a/src/global/beam/beam.cc +++ b/src/global/beam/beam.cc @@ -17,34 +17,29 @@ #include "factories/meta/SubDivideCollection_factory.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - - using namespace eicrecon; - - // Divide MCParticle collection based on generator status and PDG - std::vector outCollections{"MCBeamElectrons","MCBeamProtons","MCBeamNeutrons","MCScatteredElectrons","MCScatteredProtons","MCScatteredNeutrons"}; - std::vector> values{{4,11},{4,2212},{4,2112},{1,11},{1,2212},{1,2112}}; - - app->Add(new JOmniFactoryGeneratorT>( - "BeamParticles", - {"MCParticles"}, - outCollections, - { - .function = ValueSplit<&edm4hep::MCParticle::getGeneratorStatus,&edm4hep::MCParticle::getPDG>{values}, - }, - app - ) - ); - - // Combine beam protons and neutrons into beam hadrons - app->Add(new JOmniFactoryGeneratorT>( - "MCBeamHadrons", - {"MCBeamProtons","MCBeamNeutrons"}, - {"MCBeamHadrons"}, - app - ) - ); - - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + + using namespace eicrecon; + + // Divide MCParticle collection based on generator status and PDG + std::vector outCollections{"MCBeamElectrons", "MCBeamProtons", + "MCBeamNeutrons", "MCScatteredElectrons", + "MCScatteredProtons", "MCScatteredNeutrons"}; + std::vector> values{{4, 11}, {4, 2212}, {4, 2112}, + {1, 11}, {1, 2212}, {1, 2112}}; + + app->Add(new JOmniFactoryGeneratorT>( + "BeamParticles", {"MCParticles"}, outCollections, + { + .function = + ValueSplit<&edm4hep::MCParticle::getGeneratorStatus, &edm4hep::MCParticle::getPDG>{ + values}, + }, + app)); + + // Combine beam protons and neutrons into beam hadrons + app->Add(new JOmniFactoryGeneratorT>( + "MCBeamHadrons", {"MCBeamProtons", "MCBeamNeutrons"}, {"MCBeamHadrons"}, app)); +} } diff --git a/src/global/digi/PhotoMultiplierHitDigi_factory.h b/src/global/digi/PhotoMultiplierHitDigi_factory.h index 5a4990423e..6b241c1f15 100644 --- a/src/global/digi/PhotoMultiplierHitDigi_factory.h +++ b/src/global/digi/PhotoMultiplierHitDigi_factory.h @@ -24,62 +24,65 @@ namespace eicrecon { -class PhotoMultiplierHitDigi_factory : - public JOmniFactory { +class PhotoMultiplierHitDigi_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::PhotoMultiplierHitDigi; + using AlgoT = eicrecon::PhotoMultiplierHitDigi; + private: - std::unique_ptr m_algo; - - PodioInput m_sim_hits_input {this}; - PodioOutput m_raw_hits_output {this}; - PodioOutput m_raw_assocs_output {this}; - - ParameterRef m_seed {this, "seed", config().seed, "random number generator seed"}; - ParameterRef m_hitTimeWindow {this, "hitTimeWindow", config().hitTimeWindow, ""}; - ParameterRef m_timeResolution {this, "timeResolution", config().timeResolution, ""}; - ParameterRef m_speMean {this, "speMean", config().speMean, ""}; - ParameterRef m_speError {this, "speError", config().speError, ""}; - ParameterRef m_pedMean {this, "pedMean", config().pedMean, ""}; - ParameterRef m_pedError {this, "pedError", config().pedError, ""}; - ParameterRef m_enablePixelGaps {this, "enablePixelGaps", config().enablePixelGaps, "enable/disable removal of hits in gaps between pixels"}; - ParameterRef m_safetyFactor {this, "safetyFactor", config().safetyFactor, "overall safety factor"}; - ParameterRef m_enableNoise {this, "enableNoise", config().enableNoise, ""}; - ParameterRef m_noiseRate {this, "noiseRate", config().noiseRate, ""}; - ParameterRef m_noiseTimeWindow {this, "noiseTimeWindow", config().noiseTimeWindow, ""}; - //ParameterRef>> m_quantumEfficiency {this, "quantumEfficiency", config().quantumEfficiency, ""}; - - Service m_algorithmsInit {this}; - Service m_RichGeoSvc {this}; + std::unique_ptr m_algo; + + PodioInput m_sim_hits_input{this}; + PodioOutput m_raw_hits_output{this}; + PodioOutput m_raw_assocs_output{this}; + + ParameterRef m_seed{this, "seed", config().seed, "random number generator seed"}; + ParameterRef m_hitTimeWindow{this, "hitTimeWindow", config().hitTimeWindow, ""}; + ParameterRef m_timeResolution{this, "timeResolution", config().timeResolution, ""}; + ParameterRef m_speMean{this, "speMean", config().speMean, ""}; + ParameterRef m_speError{this, "speError", config().speError, ""}; + ParameterRef m_pedMean{this, "pedMean", config().pedMean, ""}; + ParameterRef m_pedError{this, "pedError", config().pedError, ""}; + ParameterRef m_enablePixelGaps{this, "enablePixelGaps", config().enablePixelGaps, + "enable/disable removal of hits in gaps between pixels"}; + ParameterRef m_safetyFactor{this, "safetyFactor", config().safetyFactor, + "overall safety factor"}; + ParameterRef m_enableNoise{this, "enableNoise", config().enableNoise, ""}; + ParameterRef m_noiseRate{this, "noiseRate", config().noiseRate, ""}; + ParameterRef m_noiseTimeWindow{this, "noiseTimeWindow", config().noiseTimeWindow, ""}; + //ParameterRef>> m_quantumEfficiency {this, "quantumEfficiency", config().quantumEfficiency, ""}; + + Service m_algorithmsInit{this}; + Service m_RichGeoSvc{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - - // Initialize richgeo ReadoutGeo and set random CellID visitor lambda (if a RICH) - if (GetPluginName() == "DRICH" || GetPluginName() == "PFRICH") { - m_RichGeoSvc().GetReadoutGeo(GetPluginName())->SetSeed(config().seed); - m_algo->SetVisitRngCellIDs( - [this] (std::function lambda, float p) { m_RichGeoSvc().GetReadoutGeo(GetPluginName())->VisitAllRngPixels(lambda, p); } - ); - m_algo->SetPixelGapMask( - [this] (PhotoMultiplierHitDigi::CellIDType cellID, dd4hep::Position pos) { return m_RichGeoSvc().GetReadoutGeo(GetPluginName())->PixelGapMask(cellID, pos); } - ); - } - - m_algo->applyConfig(config()); - m_algo->init(); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); - void ChangeRun(int64_t run_number) { + // Initialize richgeo ReadoutGeo and set random CellID visitor lambda (if a RICH) + if (GetPluginName() == "DRICH" || GetPluginName() == "PFRICH") { + m_RichGeoSvc().GetReadoutGeo(GetPluginName())->SetSeed(config().seed); + m_algo->SetVisitRngCellIDs( + [this](std::function lambda, float p) { + m_RichGeoSvc().GetReadoutGeo(GetPluginName())->VisitAllRngPixels(lambda, p); + }); + m_algo->SetPixelGapMask( + [this](PhotoMultiplierHitDigi::CellIDType cellID, dd4hep::Position pos) { + return m_RichGeoSvc().GetReadoutGeo(GetPluginName())->PixelGapMask(cellID, pos); + }); } - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_sim_hits_input()}, - {m_raw_hits_output().get(), m_raw_assocs_output().get()}); - } + m_algo->applyConfig(config()); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_sim_hits_input()}, {m_raw_hits_output().get(), m_raw_assocs_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/pid/IrtCherenkovParticleID_factory.h b/src/global/pid/IrtCherenkovParticleID_factory.h index 15018ee7d3..cfc51fdeb7 100644 --- a/src/global/pid/IrtCherenkovParticleID_factory.h +++ b/src/global/pid/IrtCherenkovParticleID_factory.h @@ -20,66 +20,62 @@ namespace eicrecon { -class IrtCherenkovParticleID_factory : - public JOmniFactory { +class IrtCherenkovParticleID_factory + : public JOmniFactory { private: - using AlgoT = eicrecon::IrtCherenkovParticleID; - std::unique_ptr m_algo; - - PodioInput m_aerogel_tracks_input {this}; - PodioInput m_gas_tracks_input {this}; - PodioInput m_merged_tracks_input {this}; - PodioInput m_raw_hits_input {this}; - PodioInput m_raw_hit_assoc_input {this}; - PodioOutput m_aerogel_particleIDs_output {this}; - PodioOutput m_gas_particleIDs_output {this}; - - ParameterRef m_numRIndexBins {this, "numRIndexBins", config().numRIndexBins, ""}; - ParameterRef> m_pdgList {this, "pdgList", config().pdgList, ""}; - - ParameterRef m_aerogel_referenceRIndex {this, "aerogel:referenceRIndex", config().radiators["Aerogel"].referenceRIndex, ""}; - ParameterRef m_aerogel_attenuation {this, "aerogel:attenuation", config().radiators["Aerogel"].attenuation, ""}; - ParameterRef m_aerogel_smearingMode {this, "aerogel:smearingMode", config().radiators["Aerogel"].smearingMode, ""}; - ParameterRef m_aerogel_smearing {this, "aerogel:smearing", config().radiators["Aerogel"].smearing, ""}; - - ParameterRef m_gas_referenceRIndex {this, "gas:referenceRIndex", config().radiators["Gas"].referenceRIndex, ""}; - ParameterRef m_gas_attenuation {this, "gas:attenuation", config().radiators["Gas"].attenuation, ""}; - ParameterRef m_gas_smearingMode {this, "gas:smearingMode", config().radiators["Gas"].smearingMode, ""}; - ParameterRef m_gas_smearing {this, "gas:smearing", config().radiators["Gas"].smearing, ""}; - - ParameterRef m_cheatPhotonVertex {this, "cheatPhotonVertex", config().cheatPhotonVertex, ""}; - ParameterRef m_cheatTrueRadiator {this, "cheatTrueRadiator", config().cheatTrueRadiator, ""}; - - Service m_algorithmsInit {this}; - Service m_RichGeoSvc {this}; + using AlgoT = eicrecon::IrtCherenkovParticleID; + std::unique_ptr m_algo; + + PodioInput m_aerogel_tracks_input{this}; + PodioInput m_gas_tracks_input{this}; + PodioInput m_merged_tracks_input{this}; + PodioInput m_raw_hits_input{this}; + PodioInput m_raw_hit_assoc_input{this}; + PodioOutput m_aerogel_particleIDs_output{this}; + PodioOutput m_gas_particleIDs_output{this}; + + ParameterRef m_numRIndexBins{this, "numRIndexBins", config().numRIndexBins, ""}; + ParameterRef> m_pdgList{this, "pdgList", config().pdgList, ""}; + + ParameterRef m_aerogel_referenceRIndex{this, "aerogel:referenceRIndex", + config().radiators["Aerogel"].referenceRIndex, ""}; + ParameterRef m_aerogel_attenuation{this, "aerogel:attenuation", + config().radiators["Aerogel"].attenuation, ""}; + ParameterRef m_aerogel_smearingMode{this, "aerogel:smearingMode", + config().radiators["Aerogel"].smearingMode, ""}; + ParameterRef m_aerogel_smearing{this, "aerogel:smearing", + config().radiators["Aerogel"].smearing, ""}; + + ParameterRef m_gas_referenceRIndex{this, "gas:referenceRIndex", + config().radiators["Gas"].referenceRIndex, ""}; + ParameterRef m_gas_attenuation{this, "gas:attenuation", + config().radiators["Gas"].attenuation, ""}; + ParameterRef m_gas_smearingMode{this, "gas:smearingMode", + config().radiators["Gas"].smearingMode, ""}; + ParameterRef m_gas_smearing{this, "gas:smearing", config().radiators["Gas"].smearing, ""}; + + ParameterRef m_cheatPhotonVertex{this, "cheatPhotonVertex", config().cheatPhotonVertex, ""}; + ParameterRef m_cheatTrueRadiator{this, "cheatTrueRadiator", config().cheatTrueRadiator, ""}; + + Service m_algorithmsInit{this}; + Service m_RichGeoSvc{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(m_RichGeoSvc().GetIrtGeo("DRICH")->GetIrtDetectorCollection(), logger()); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process( - { - m_aerogel_tracks_input(), - m_gas_tracks_input(), - m_merged_tracks_input(), - m_raw_hits_input(), - m_raw_hit_assoc_input() - }, - { - m_aerogel_particleIDs_output().get(), - m_gas_particleIDs_output().get() - } - ); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(m_RichGeoSvc().GetIrtGeo("DRICH")->GetIrtDetectorCollection(), logger()); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_aerogel_tracks_input(), m_gas_tracks_input(), m_merged_tracks_input(), + m_raw_hits_input(), m_raw_hit_assoc_input()}, + {m_aerogel_particleIDs_output().get(), m_gas_particleIDs_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/pid/MatchToRICHPID_factory.h b/src/global/pid/MatchToRICHPID_factory.h index 2bb4363d31..98ca5f4c01 100644 --- a/src/global/pid/MatchToRICHPID_factory.h +++ b/src/global/pid/MatchToRICHPID_factory.h @@ -38,8 +38,9 @@ class MatchToRICHPID_factory : public JOmniFactoryprocess({m_recoparticles_input(), m_assocs_input(), m_cherenkov_particle_ids_input()}, - {m_recoparticles_output().get(), m_assocs_output().get(), m_pids_output().get()}); + m_algo->process( + {m_recoparticles_input(), m_assocs_input(), m_cherenkov_particle_ids_input()}, + {m_recoparticles_output().get(), m_assocs_output().get(), m_pids_output().get()}); } }; diff --git a/src/global/pid/MergeCherenkovParticleID_factory.h b/src/global/pid/MergeCherenkovParticleID_factory.h index 590ad4a333..b38d0c4ebd 100644 --- a/src/global/pid/MergeCherenkovParticleID_factory.h +++ b/src/global/pid/MergeCherenkovParticleID_factory.h @@ -19,40 +19,38 @@ namespace eicrecon { -class MergeCherenkovParticleID_factory : - public JOmniFactory { +class MergeCherenkovParticleID_factory + : public JOmniFactory { private: + // Underlying algorithm + using AlgoT = eicrecon::MergeParticleID; + std::unique_ptr m_algo; - // Underlying algorithm - using AlgoT = eicrecon::MergeParticleID; - std::unique_ptr m_algo; + // Declare inputs + VariadicPodioInput m_particleID_input{this}; - // Declare inputs - VariadicPodioInput m_particleID_input {this}; + // Declare outputs + PodioOutput m_particleID_output{this}; - // Declare outputs - PodioOutput m_particleID_output {this}; - - // Declare parameters - ParameterRef m_mergeMode {this, "mergeMode", config().mergeMode}; + // Declare parameters + ParameterRef m_mergeMode{this, "mergeMode", config().mergeMode}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->applyConfig(config()); - m_algo->init(logger()); - } - - void ChangeRun(int64_t run_number) { } - - void Process(int64_t run_number, uint64_t event_number) { - auto in1 = m_particleID_input(); - std::vector> in2; - std::copy(in1.cbegin(), in1.cend(), std::back_inserter(in2)); - m_algo->process({in2}, {m_particleID_output().get()}); - } - - }; -} + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->applyConfig(config()); + m_algo->init(logger()); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + auto in1 = m_particleID_input(); + std::vector> in2; + std::copy(in1.cbegin(), in1.cend(), std::back_inserter(in2)); + m_algo->process({in2}, {m_particleID_output().get()}); + } +}; +} // namespace eicrecon diff --git a/src/global/pid/MergeTrack_factory.h b/src/global/pid/MergeTrack_factory.h index c59f4250ba..f0bd15ce11 100644 --- a/src/global/pid/MergeTrack_factory.h +++ b/src/global/pid/MergeTrack_factory.h @@ -19,32 +19,30 @@ namespace eicrecon { class MergeTrack_factory : public JOmniFactory { private: + // Underlying algorithm + std::unique_ptr m_algo; - // Underlying algorithm - std::unique_ptr m_algo; + // Declare inputs + VariadicPodioInput m_track_segments_input{this}; - // Declare inputs - VariadicPodioInput m_track_segments_input {this}; - - // Declare outputs - PodioOutput m_track_segments_output {this}; + // Declare outputs + PodioOutput m_track_segments_output{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { } - - void Process(int64_t run_number, uint64_t event_number) { - auto in1 = m_track_segments_input(); - std::vector> in2; - std::copy(in1.cbegin(), in1.cend(), std::back_inserter(in2)); - - m_algo->process({in2}, {m_track_segments_output().get()}); - } - - }; -} + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + auto in1 = m_track_segments_input(); + std::vector> in2; + std::copy(in1.cbegin(), in1.cend(), std::back_inserter(in2)); + + m_algo->process({in2}, {m_track_segments_output().get()}); + } +}; +} // namespace eicrecon diff --git a/src/global/pid/RichTrack_factory.h b/src/global/pid/RichTrack_factory.h index 8fd0255c93..5073e390dc 100644 --- a/src/global/pid/RichTrack_factory.h +++ b/src/global/pid/RichTrack_factory.h @@ -23,41 +23,38 @@ namespace eicrecon { -class RichTrack_factory : - public JOmniFactory { +class RichTrack_factory : public JOmniFactory { private: - using AlgoT = eicrecon::TrackPropagation; - std::unique_ptr m_algo; + using AlgoT = eicrecon::TrackPropagation; + std::unique_ptr m_algo; - PodioInput m_tracks_input {this}; - Input m_acts_trajectories_input {this}; - Input m_acts_tracks_input {this}; - PodioOutput m_track_segments_output {this}; + PodioInput m_tracks_input{this}; + Input m_acts_trajectories_input{this}; + Input m_acts_tracks_input{this}; + PodioOutput m_track_segments_output{this}; - Service m_GeoSvc {this}; - Service m_ACTSGeoSvc {this}; + Service m_GeoSvc{this}; + Service m_ACTSGeoSvc{this}; public: - void Configure() { - m_algo = std::make_unique(); - m_algo->applyConfig(config()); + void Configure() { + m_algo = std::make_unique(); + m_algo->applyConfig(config()); - if (config().filter_surfaces.empty()) - throw JException("cannot find filter surface for RICH track propagation"); + if (config().filter_surfaces.empty()) + throw JException("cannot find filter surface for RICH track propagation"); - m_algo->init(m_GeoSvc().detector(), m_ACTSGeoSvc().actsGeoProvider(), logger()); - } + m_algo->init(m_GeoSvc().detector(), m_ACTSGeoSvc().actsGeoProvider(), logger()); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { - m_algo->propagateToSurfaceList( - {*m_tracks_input(), m_acts_trajectories_input(), m_acts_tracks_input()}, - {m_track_segments_output().get()} - ); - } + void Process(int64_t run_number, uint64_t event_number) { + m_algo->propagateToSurfaceList( + {*m_tracks_input(), m_acts_trajectories_input(), m_acts_tracks_input()}, + {m_track_segments_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/pid/pid.cc b/src/global/pid/pid.cc index 612bf4fae3..5873044a81 100644 --- a/src/global/pid/pid.cc +++ b/src/global/pid/pid.cc @@ -1,7 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2022, 2023, Christopher Dilks - #include #include @@ -11,13 +10,13 @@ #include "global/pid/MatchToRICHPID_factory.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // wiring between factories and data /////////////////////////////////////// - // clang-format off + // wiring between factories and data /////////////////////////////////////// + // clang-format off // link charged particles to PID and to MC truth app->Add(new JOmniFactoryGeneratorT( diff --git a/src/global/pid_lut/PIDLookup_factory.h b/src/global/pid_lut/PIDLookup_factory.h index 6c56275941..0bde7162e5 100644 --- a/src/global/pid_lut/PIDLookup_factory.h +++ b/src/global/pid_lut/PIDLookup_factory.h @@ -31,7 +31,7 @@ class PIDLookup_factory : public JOmniFactory m_system{this, "system", config().system, "For the ParticleID record"}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: void Configure() { @@ -45,7 +45,8 @@ class PIDLookup_factory : public JOmniFactoryprocess({m_recoparticles_input(), m_recoparticle_assocs_input()}, - {m_recoparticles_output().get(), m_recoparticle_assocs_output().get(), m_particleids_output().get()}); + {m_recoparticles_output().get(), m_recoparticle_assocs_output().get(), + m_particleids_output().get()}); } }; diff --git a/src/global/reco/ChargedMCParticleSelector_factory.h b/src/global/reco/ChargedMCParticleSelector_factory.h index 8bfbd8c531..a8c30944f8 100644 --- a/src/global/reco/ChargedMCParticleSelector_factory.h +++ b/src/global/reco/ChargedMCParticleSelector_factory.h @@ -8,34 +8,30 @@ namespace eicrecon { - class ChargedMCParticleSelector_factory : public JOmniFactory { +class ChargedMCParticleSelector_factory + : public JOmniFactory { - private: +private: + // algorithm + std::unique_ptr m_algo; - // algorithm - std::unique_ptr m_algo; + // input collection + PodioInput m_pars_in{this, "GeneratedParticles"}; - // input collection - PodioInput m_pars_in {this, "GeneratedParticles"}; + // output collection + PodioOutput m_pars_out{this}; - // output collection - PodioOutput m_pars_out {this}; +public: + void Configure() { + m_algo = std::make_unique(); + m_algo->init(logger()); + } - public: + void ChangeRun(int64_t run_number) { /* nothing to do */ } - void Configure() { - m_algo = std::make_unique(); - m_algo->init(logger()); - } + void Process(int64_t run_number, int64_t event_number) { + m_pars_out() = m_algo->process(m_pars_in()); + } +}; - void ChangeRun(int64_t run_number) { - /* nothing to do */ - } - - void Process(int64_t run_number, int64_t event_number) { - m_pars_out() = m_algo->process(m_pars_in()); - } - - }; - -} // end eicrecon namespace +} // namespace eicrecon diff --git a/src/global/reco/ChargedReconstructedParticleSelector_factory.h b/src/global/reco/ChargedReconstructedParticleSelector_factory.h index 249f306e51..a9850376b6 100644 --- a/src/global/reco/ChargedReconstructedParticleSelector_factory.h +++ b/src/global/reco/ChargedReconstructedParticleSelector_factory.h @@ -8,34 +8,30 @@ namespace eicrecon { - class ChargedReconstructedParticleSelector_factory : public JOmniFactory { +class ChargedReconstructedParticleSelector_factory + : public JOmniFactory { - private: +private: + // algorithm + std::unique_ptr m_algo; - // algorithm - std::unique_ptr m_algo; + // input collection + PodioInput m_pars_in{this, "GeneratedParticles"}; - // input collection - PodioInput m_pars_in {this, "GeneratedParticles"}; + // output collection + PodioOutput m_pars_out{this}; - // output collection - PodioOutput m_pars_out {this}; +public: + void Configure() { + m_algo = std::make_unique(); + m_algo->init(logger()); + } - public: + void ChangeRun(int64_t run_number) { /* nothing to do */ } - void Configure() { - m_algo = std::make_unique(); - m_algo->init(logger()); - } + void Process(int64_t run_number, int64_t event_number) { + m_pars_out() = m_algo->process(m_pars_in()); + } +}; - void ChangeRun(int64_t run_number) { - /* nothing to do */ - } - - void Process(int64_t run_number, int64_t event_number) { - m_pars_out() = m_algo->process(m_pars_in()); - } - - }; - -} // end eicrecon namespace +} // namespace eicrecon diff --git a/src/global/reco/MC2SmearedParticle_factory.h b/src/global/reco/MC2SmearedParticle_factory.h index a1aee66d7f..9ea2c74d0f 100644 --- a/src/global/reco/MC2SmearedParticle_factory.h +++ b/src/global/reco/MC2SmearedParticle_factory.h @@ -16,28 +16,26 @@ namespace eicrecon { -class MC2SmearedParticle_factory : - public JOmniFactory { +class MC2SmearedParticle_factory : public JOmniFactory { private: - using AlgoT = eicrecon::MC2SmearedParticle; - std::unique_ptr m_algo; + using AlgoT = eicrecon::MC2SmearedParticle; + std::unique_ptr m_algo; - PodioInput m_mc_particles_input {this}; - PodioOutput m_rc_particles_output {this}; + PodioInput m_mc_particles_input{this}; + PodioOutput m_rc_particles_output{this}; public: - void Configure() { - m_algo = std::make_unique(); - m_algo->init(logger()); - } + void Configure() { + m_algo = std::make_unique(); + m_algo->init(logger()); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { - m_rc_particles_output() = m_algo->produce(m_mc_particles_input()); - } + void Process(int64_t run_number, uint64_t event_number) { + m_rc_particles_output() = m_algo->produce(m_mc_particles_input()); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/reco/MatchClusters_factory.h b/src/global/reco/MatchClusters_factory.h index abde06beac..bebf5f806d 100644 --- a/src/global/reco/MatchClusters_factory.h +++ b/src/global/reco/MatchClusters_factory.h @@ -22,48 +22,45 @@ namespace eicrecon { class MatchClusters_factory : public JOmniFactory { private: + // Underlying algorithm + std::unique_ptr m_algo; - // Underlying algorithm - std::unique_ptr m_algo; + // Declare inputs + PodioInput m_mc_parts_input{this}; + PodioInput m_rec_parts_input{this}; + PodioInput m_rec_assocs_input{this}; + PodioInput m_clusters_input{this}; + PodioInput m_cluster_assocs_input{this}; - // Declare inputs - PodioInput m_mc_parts_input {this}; - PodioInput m_rec_parts_input {this}; - PodioInput m_rec_assocs_input {this}; - PodioInput m_clusters_input {this}; - PodioInput m_cluster_assocs_input {this}; + // Declare outputs + PodioOutput m_rec_parts_output{this}; + PodioOutput m_rec_assocs_output{this}; - // Declare outputs - PodioOutput m_rec_parts_output {this}; - PodioOutput m_rec_assocs_output {this}; - - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process( - { - m_mc_parts_input(), - m_rec_parts_input(), - m_rec_assocs_input(), - m_clusters_input(), - m_cluster_assocs_input(), - }, - { - m_rec_parts_output().get(), - m_rec_assocs_output().get(), - } - ); - } + void ChangeRun(int64_t run_number) {} - }; + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process( + { + m_mc_parts_input(), + m_rec_parts_input(), + m_rec_assocs_input(), + m_clusters_input(), + m_cluster_assocs_input(), + }, + { + m_rec_parts_output().get(), + m_rec_assocs_output().get(), + }); + } +}; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/reco/PrimaryVertices_factory.h b/src/global/reco/PrimaryVertices_factory.h index d325c6b9f1..737cfeee8d 100644 --- a/src/global/reco/PrimaryVertices_factory.h +++ b/src/global/reco/PrimaryVertices_factory.h @@ -16,36 +16,36 @@ namespace eicrecon { -class PrimaryVertices_factory : - public JOmniFactory { +class PrimaryVertices_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::PrimaryVertices; + using AlgoT = eicrecon::PrimaryVertices; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_rc_vertices_input {this}; + PodioInput m_rc_vertices_input{this}; - // Declare outputs - PodioOutput m_primary_vertices_output {this}; + // Declare outputs + PodioOutput m_primary_vertices_output{this}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level((algorithms::LogLevel)logger()->level()); + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level((algorithms::LogLevel)logger()->level()); - m_algo->applyConfig(config()); - m_algo->init(); - } + m_algo->applyConfig(config()); + m_algo->init(); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_rc_vertices_input()}, {m_primary_vertices_output().get()}); - } + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_rc_vertices_input()}, {m_primary_vertices_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/reco/ReconstructedElectrons_factory.h b/src/global/reco/ReconstructedElectrons_factory.h index 3996a937fd..982419a01e 100644 --- a/src/global/reco/ReconstructedElectrons_factory.h +++ b/src/global/reco/ReconstructedElectrons_factory.h @@ -7,64 +7,63 @@ #include "algorithms/reco/ElectronReconstruction.h" - namespace eicrecon { -class ReconstructedElectrons_factory : public JOmniFactory { +class ReconstructedElectrons_factory + : public JOmniFactory { private: + // Underlying algorithm + std::unique_ptr m_algo; - // Underlying algorithm - std::unique_ptr m_algo; - - // Declare inputs - PodioInput m_in_rc_particles {this, "ReconstructedParticles"}; - + // Declare inputs + PodioInput m_in_rc_particles{this, "ReconstructedParticles"}; - // Declare outputs - PodioOutput m_out_reco_particles {this}; + // Declare outputs + PodioOutput m_out_reco_particles{this}; - // Declare parameters - ParameterRef m_min_energy_over_momentum {this, "minEnergyOverMomentum", config().min_energy_over_momentum}; - ParameterRef m_max_energy_over_momentum {this, "maxEnergyOverMomentum", config().max_energy_over_momentum}; + // Declare parameters + ParameterRef m_min_energy_over_momentum{this, "minEnergyOverMomentum", + config().min_energy_over_momentum}; + ParameterRef m_max_energy_over_momentum{this, "maxEnergyOverMomentum", + config().max_energy_over_momentum}; - // Declare services here, e.g. - // Service m_geoSvc {this}; + // Declare services here, e.g. + // Service m_geoSvc {this}; public: - void Configure() { - // This is called when the factory is instantiated. - // Use this callback to make sure the algorithm is configured. - // The logger, parameters, and services have all been fetched before this is called - m_algo = std::make_unique(); - - // Pass config object to algorithm - m_algo->applyConfig(config()); - - // If we needed geometry, we'd obtain it like so - // m_algo->init(m_geoSvc().detector(), m_geoSvc().converter(), logger()); - - m_algo->init(logger()); - } - - void ChangeRun(int64_t run_number) { - // This is called whenever the run number is changed. - // Use this callback to retrieve state that is keyed off of run number. - // This state should usually be managed by a Service. - // Note: You usually don't need this, because you can declare a Resource instead. - } - - void Process(int64_t run_number, uint64_t event_number) { - // This is called on every event. - // Use this callback to call your Algorithm using all inputs and outputs - // The inputs will have already been fetched for you at this point. - auto output = m_algo->execute( - m_in_rc_particles() - ); - - logger()->debug( "Event {}: Found {} reconstructed electron candidates", event_number, output->size() ); - - m_out_reco_particles() = std::move(output); - // JANA will take care of publishing the outputs for you. - } + void Configure() { + // This is called when the factory is instantiated. + // Use this callback to make sure the algorithm is configured. + // The logger, parameters, and services have all been fetched before this is called + m_algo = std::make_unique(); + + // Pass config object to algorithm + m_algo->applyConfig(config()); + + // If we needed geometry, we'd obtain it like so + // m_algo->init(m_geoSvc().detector(), m_geoSvc().converter(), logger()); + + m_algo->init(logger()); + } + + void ChangeRun(int64_t run_number) { + // This is called whenever the run number is changed. + // Use this callback to retrieve state that is keyed off of run number. + // This state should usually be managed by a Service. + // Note: You usually don't need this, because you can declare a Resource instead. + } + + void Process(int64_t run_number, uint64_t event_number) { + // This is called on every event. + // Use this callback to call your Algorithm using all inputs and outputs + // The inputs will have already been fetched for you at this point. + auto output = m_algo->execute(m_in_rc_particles()); + + logger()->debug("Event {}: Found {} reconstructed electron candidates", event_number, + output->size()); + + m_out_reco_particles() = std::move(output); + // JANA will take care of publishing the outputs for you. + } }; } // namespace eicrecon diff --git a/src/global/reco/ScatteredElectronsEMinusPz_factory.h b/src/global/reco/ScatteredElectronsEMinusPz_factory.h index 87ae54f26d..4f31d58c74 100644 --- a/src/global/reco/ScatteredElectronsEMinusPz_factory.h +++ b/src/global/reco/ScatteredElectronsEMinusPz_factory.h @@ -15,36 +15,36 @@ namespace eicrecon { -class ScatteredElectronsEMinusPz_factory : - public JOmniFactory { +class ScatteredElectronsEMinusPz_factory + : public JOmniFactory { public: - using AlgoT = eicrecon::ScatteredElectronsEMinusPz; + using AlgoT = eicrecon::ScatteredElectronsEMinusPz; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_rc_particles_input {this}; - PodioInput m_rc_electrons_input {this}; + PodioInput m_rc_particles_input{this}; + PodioInput m_rc_electrons_input{this}; - // Declare outputs - PodioOutput m_out_reco_particles {this}; + // Declare outputs + PodioOutput m_out_reco_particles{this}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_rc_particles_input(), m_rc_electrons_input()}, - {m_out_reco_particles().get()}); - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_rc_particles_input(), m_rc_electrons_input()}, + {m_out_reco_particles().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/reco/ScatteredElectronsTruth_factory.h b/src/global/reco/ScatteredElectronsTruth_factory.h index 3da9040f83..88dac5fee4 100644 --- a/src/global/reco/ScatteredElectronsTruth_factory.h +++ b/src/global/reco/ScatteredElectronsTruth_factory.h @@ -15,38 +15,36 @@ namespace eicrecon { -class ScatteredElectronsTruth_factory : - public JOmniFactory { +class ScatteredElectronsTruth_factory : public JOmniFactory { public: - using AlgoT = eicrecon::ScatteredElectronsTruth; + using AlgoT = eicrecon::ScatteredElectronsTruth; + private: - std::unique_ptr m_algo; + std::unique_ptr m_algo; - PodioInput m_mc_particles_input {this}; - PodioInput m_rc_particles_input {this}; - PodioInput m_rc_particles_assoc_input {this}; + PodioInput m_mc_particles_input{this}; + PodioInput m_rc_particles_input{this}; + PodioInput m_rc_particles_assoc_input{this}; - // Declare outputs - PodioOutput m_out_reco_particles {this}; + // Declare outputs + PodioOutput m_out_reco_particles{this}; - Service m_algorithmsInit {this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process({m_mc_particles_input(), m_rc_particles_input(), m_rc_particles_assoc_input()}, - {m_out_reco_particles().get()}); - - } + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({m_mc_particles_input(), m_rc_particles_input(), m_rc_particles_assoc_input()}, + {m_out_reco_particles().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/reco/reco.cc b/src/global/reco/reco.cc index 0c8e373bcc..937891877c 100644 --- a/src/global/reco/reco.cc +++ b/src/global/reco/reco.cc @@ -1,7 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2022 - 2024, Dmitry Romanov, Nathan Brei, Tooba Ali, Wouter Deconinck, Dmitry Kalinkin, John Lajoie, Simon Gardner, Tristan Protzman, Daniel Brandenburg, Derek M Anderson, Sebouh Paul, Tyler Kutz, Alex Jentsch, Jihee Kim, Brian Page - #include #include #include @@ -51,354 +50,187 @@ #include "global/reco/ScatteredElectronsTruth_factory.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - // Finds associations matched to initial scattered electrons - app->Add(new JOmniFactoryGeneratorTgetSim().getObjectID();}, - edm4hep::MCParticle, - [](auto* obj) { return obj->getObjectID(); }>>( + // Finds associations matched to initial scattered electrons + app->Add( + new JOmniFactoryGeneratorTgetSim().getObjectID(); }, + edm4hep::MCParticle, [](auto* obj) { return obj->getObjectID(); }>>( "MCScatteredElectronAssociations", - {"ReconstructedChargedParticleAssociations","MCScatteredElectrons"}, - {"MCScatteredElectronAssociations","MCNonScatteredElectronAssociations"}, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "GeneratedParticles", - {"MCParticles"}, - {"GeneratedParticles"}, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "EcalClusters", - { + {"ReconstructedChargedParticleAssociations", "MCScatteredElectrons"}, + {"MCScatteredElectronAssociations", "MCNonScatteredElectronAssociations"}, app)); + + app->Add(new JOmniFactoryGeneratorT( + "GeneratedParticles", {"MCParticles"}, {"GeneratedParticles"}, app)); + + app->Add(new JOmniFactoryGeneratorT>( + "EcalClusters", + { "EcalEndcapNClusters", "EcalBarrelScFiClusters", "EcalEndcapPClusters", - }, - {"EcalClusters"}, - app)); + }, + {"EcalClusters"}, app)); - app->Add(new JOmniFactoryGeneratorT>( - "EcalClusterAssociations", - { + app->Add(new JOmniFactoryGeneratorT< + CollectionCollector_factory>( + "EcalClusterAssociations", + { "EcalEndcapNClusterAssociations", "EcalBarrelScFiClusterAssociations", "EcalEndcapPClusterAssociations", - }, - {"EcalClusterAssociations"}, - app)); + }, + {"EcalClusterAssociations"}, app)); - app->Add(new JOmniFactoryGeneratorT( - "ReconstructedParticlesWithAssoc", - { + app->Add(new JOmniFactoryGeneratorT( + "ReconstructedParticlesWithAssoc", + { "MCParticles", "ReconstructedChargedParticles", "ReconstructedChargedParticleAssociations", "EcalClusters", "EcalClusterAssociations", - }, - { "ReconstructedParticles", // edm4eic::ReconstructedParticle + }, + { + "ReconstructedParticles", // edm4eic::ReconstructedParticle "ReconstructedParticleAssociations" // edm4eic::MCRecoParticleAssociation - }, - app - )); - - - app->Add(new JOmniFactoryGeneratorT( - "InclusiveKinematicsTruth", - { - "MCParticles" - }, - { - "InclusiveKinematicsTruth" - }, - app - )); + }, + app)); + + app->Add(new JOmniFactoryGeneratorT( + "InclusiveKinematicsTruth", {"MCParticles"}, {"InclusiveKinematicsTruth"}, app)); #if EDM4EIC_VERSION_MAJOR >= 6 - app->Add(new JOmniFactoryGeneratorT>( - "InclusiveKinematicsElectron", - { - "MCParticles", - "ScatteredElectronsTruth", - "HadronicFinalState" - }, - { - "InclusiveKinematicsElectron" - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "InclusiveKinematicsJB", - { - "MCParticles", - "ScatteredElectronsTruth", - "HadronicFinalState" - }, - { - "InclusiveKinematicsJB" - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "InclusiveKinematicsDA", - { - "MCParticles", - "ScatteredElectronsTruth", - "HadronicFinalState" - }, - { - "InclusiveKinematicsDA" - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "InclusiveKinematicsESigma", - { - "MCParticles", - "ScatteredElectronsTruth", - "HadronicFinalState" - }, - { - "InclusiveKinematicsESigma" - }, - app - )); - - // InclusiveKinematicseSigma is deprecated and will be removed, use InclusiveKinematicsESigma instead - app->Add(new JOmniFactoryGeneratorT>( - "InclusiveKinematicseSigma_legacy", - { - "InclusiveKinematicsESigma" - }, - { - "InclusiveKinematicseSigma" - }, - app - )); - - - app->Add(new JOmniFactoryGeneratorT>( - "InclusiveKinematicsSigma", - { - "MCParticles", - "ScatteredElectronsTruth", - "HadronicFinalState" - }, - { - "InclusiveKinematicsSigma" - }, - app - )); + app->Add(new JOmniFactoryGeneratorT< + InclusiveKinematicsReconstructed_factory>( + "InclusiveKinematicsElectron", + {"MCParticles", "ScatteredElectronsTruth", "HadronicFinalState"}, + {"InclusiveKinematicsElectron"}, app)); + + app->Add( + new JOmniFactoryGeneratorT>( + "InclusiveKinematicsJB", {"MCParticles", "ScatteredElectronsTruth", "HadronicFinalState"}, + {"InclusiveKinematicsJB"}, app)); + + app->Add( + new JOmniFactoryGeneratorT>( + "InclusiveKinematicsDA", {"MCParticles", "ScatteredElectronsTruth", "HadronicFinalState"}, + {"InclusiveKinematicsDA"}, app)); + + app->Add(new JOmniFactoryGeneratorT< + InclusiveKinematicsReconstructed_factory>( + "InclusiveKinematicsESigma", {"MCParticles", "ScatteredElectronsTruth", "HadronicFinalState"}, + {"InclusiveKinematicsESigma"}, app)); + + // InclusiveKinematicseSigma is deprecated and will be removed, use InclusiveKinematicsESigma instead + app->Add(new JOmniFactoryGeneratorT>( + "InclusiveKinematicseSigma_legacy", {"InclusiveKinematicsESigma"}, + {"InclusiveKinematicseSigma"}, app)); + + app->Add(new JOmniFactoryGeneratorT< + InclusiveKinematicsReconstructed_factory>( + "InclusiveKinematicsSigma", {"MCParticles", "ScatteredElectronsTruth", "HadronicFinalState"}, + {"InclusiveKinematicsSigma"}, app)); #ifdef USE_ONNX - app->Add(new JOmniFactoryGeneratorT( - "InclusiveKinematicsML", - { - "InclusiveKinematicsElectron", - "InclusiveKinematicsDA" - }, - { - "InclusiveKinematicsML" - }, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "InclusiveKinematicsML", {"InclusiveKinematicsElectron", "InclusiveKinematicsDA"}, + {"InclusiveKinematicsML"}, app)); #endif #endif - app->Add(new JOmniFactoryGeneratorT( - "ReconstructedElectrons", - {"ReconstructedParticles"}, - {"ReconstructedElectrons"}, - {}, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "ReconstructedElectronsForDIS", - {"ReconstructedParticles"}, - {"ReconstructedElectronsForDIS"}, - { + app->Add(new JOmniFactoryGeneratorT( + "ReconstructedElectrons", {"ReconstructedParticles"}, {"ReconstructedElectrons"}, {}, app)); + + app->Add(new JOmniFactoryGeneratorT( + "ReconstructedElectronsForDIS", {"ReconstructedParticles"}, {"ReconstructedElectronsForDIS"}, + { .min_energy_over_momentum = 0.7, // GeV .max_energy_over_momentum = 1.3 // GeV - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "GeneratedJets", - {"GeneratedParticles"}, - {"GeneratedJets"}, - {}, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "ReconstructedJets", - {"ReconstructedParticles"}, - {"ReconstructedJets"}, - {}, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "GeneratedChargedParticles", - {"GeneratedParticles"}, - {"GeneratedChargedParticles"}, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "GeneratedChargedJets", - {"GeneratedChargedParticles"}, - {"GeneratedChargedJets"}, - {}, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "ReconstructedChargedJets", - {"ReconstructedChargedParticles"}, - {"ReconstructedChargedJets"}, - {}, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "ScatteredElectronsTruth", - { - "MCParticles", - "ReconstructedChargedParticles", - "ReconstructedChargedParticleAssociations" - }, - { - "ScatteredElectronsTruth" - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "ScatteredElectronsEMinusPz", - { - "ReconstructedChargedParticles", - "ReconstructedElectronsForDIS" - }, - { - "ScatteredElectronsEMinusPz" - }, - { - .minEMinusPz = 0, // GeV + }, + app)); + + app->Add(new JOmniFactoryGeneratorT>( + "GeneratedJets", {"GeneratedParticles"}, {"GeneratedJets"}, {}, app)); + + app->Add(new JOmniFactoryGeneratorT>( + "ReconstructedJets", {"ReconstructedParticles"}, {"ReconstructedJets"}, {}, app)); + + app->Add(new JOmniFactoryGeneratorT( + "GeneratedChargedParticles", {"GeneratedParticles"}, {"GeneratedChargedParticles"}, app)); + + app->Add(new JOmniFactoryGeneratorT>( + "GeneratedChargedJets", {"GeneratedChargedParticles"}, {"GeneratedChargedJets"}, {}, app)); + + app->Add(new JOmniFactoryGeneratorT>( + "ReconstructedChargedJets", {"ReconstructedChargedParticles"}, {"ReconstructedChargedJets"}, + {}, app)); + + app->Add(new JOmniFactoryGeneratorT( + "ScatteredElectronsTruth", + {"MCParticles", "ReconstructedChargedParticles", "ReconstructedChargedParticleAssociations"}, + {"ScatteredElectronsTruth"}, app)); + + app->Add(new JOmniFactoryGeneratorT( + "ScatteredElectronsEMinusPz", + {"ReconstructedChargedParticles", "ReconstructedElectronsForDIS"}, + {"ScatteredElectronsEMinusPz"}, + { + .minEMinusPz = 0, // GeV .maxEMinusPz = 10000000.0 // GeV - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "ReconstructedBreitFrameParticles", - {"MCParticles","InclusiveKinematicsElectron","ReconstructedParticles"}, - {"ReconstructedBreitFrameParticles"}, - {}, - app - )); - app->Add(new JOmniFactoryGeneratorT( - "ReconstructedFarForwardZDCNeutrons", - {"HcalFarForwardZDCClusters","EcalFarForwardZDCClusters"}, // edm4eic::ClusterCollection - {"ReconstructedFarForwardZDCNeutrons"}, // edm4eic::ReconstrutedParticleCollection, - { - .scale_corr_coeff_hcal={-0.0756, -1.91, 2.30}, - .scale_corr_coeff_ecal={-0.352, -1.34, 1.61} - }, - app // TODO: Remove me once fixed - )); + }, + app)); + + app->Add(new JOmniFactoryGeneratorT( + "ReconstructedBreitFrameParticles", + {"MCParticles", "InclusiveKinematicsElectron", "ReconstructedParticles"}, + {"ReconstructedBreitFrameParticles"}, {}, app)); + app->Add(new JOmniFactoryGeneratorT( + "ReconstructedFarForwardZDCNeutrons", + {"HcalFarForwardZDCClusters", "EcalFarForwardZDCClusters"}, // edm4eic::ClusterCollection + {"ReconstructedFarForwardZDCNeutrons"}, // edm4eic::ReconstrutedParticleCollection, + {.scale_corr_coeff_hcal = {-0.0756, -1.91, 2.30}, + .scale_corr_coeff_ecal = {-0.352, -1.34, 1.61}}, + app // TODO: Remove me once fixed + )); #if EDM4EIC_VERSION_MAJOR >= 6 - app->Add(new JOmniFactoryGeneratorT>( - "HadronicFinalState", - { - "MCParticles", - "ReconstructedParticles", - "ReconstructedParticleAssociations" - }, - { - "HadronicFinalState" - }, - app - )); + app->Add(new JOmniFactoryGeneratorT>( + "HadronicFinalState", + {"MCParticles", "ReconstructedParticles", "ReconstructedParticleAssociations"}, + {"HadronicFinalState"}, app)); #endif - app->Add(new JOmniFactoryGeneratorT( - "GeneratedBreitFrameParticles", - {"MCParticles","InclusiveKinematicsElectron","GeneratedParticles"}, - {"GeneratedBreitFrameParticles"}, - {}, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "GeneratedCentauroJets", - {"GeneratedBreitFrameParticles"}, - {"GeneratedCentauroJets"}, - { - .rJet = 0.8, - .jetAlgo = "plugin_algorithm", - .jetContribAlgo = "Centauro" - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT>( - "ReconstructedCentauroJets", - {"ReconstructedBreitFrameParticles"}, - {"ReconstructedCentauroJets"}, - { - .rJet = 0.8, - .jetAlgo = "plugin_algorithm", - .jetContribAlgo = "Centauro" - }, - app - )); - - - //Full correction for MCParticles --> MCParticlesHeadOnFrame - app->Add(new JOmniFactoryGeneratorT( - "MCParticlesHeadOnFrameNoBeamFX", - { - "MCParticles" - }, - { - "MCParticlesHeadOnFrameNoBeamFX" - }, - { - .m_pid_assume_pion_mass = false, - .m_crossing_angle = -0.025 * dd4hep::rad, - .m_pid_purity = 0.51, //dummy value for MC truth information - .m_correct_beam_FX = true, - .m_pid_use_MC_truth = true, - }, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "PrimaryVertices", - { - "CentralTrackVertices" - }, - { - "PrimaryVertices" - }, - { - }, - app - )); - - + app->Add(new JOmniFactoryGeneratorT( + "GeneratedBreitFrameParticles", + {"MCParticles", "InclusiveKinematicsElectron", "GeneratedParticles"}, + {"GeneratedBreitFrameParticles"}, {}, app)); + + app->Add(new JOmniFactoryGeneratorT>( + "GeneratedCentauroJets", {"GeneratedBreitFrameParticles"}, {"GeneratedCentauroJets"}, + {.rJet = 0.8, .jetAlgo = "plugin_algorithm", .jetContribAlgo = "Centauro"}, app)); + + app->Add(new JOmniFactoryGeneratorT>( + "ReconstructedCentauroJets", {"ReconstructedBreitFrameParticles"}, + {"ReconstructedCentauroJets"}, + {.rJet = 0.8, .jetAlgo = "plugin_algorithm", .jetContribAlgo = "Centauro"}, app)); + + //Full correction for MCParticles --> MCParticlesHeadOnFrame + app->Add(new JOmniFactoryGeneratorT( + "MCParticlesHeadOnFrameNoBeamFX", {"MCParticles"}, {"MCParticlesHeadOnFrameNoBeamFX"}, + { + .m_pid_assume_pion_mass = false, + .m_crossing_angle = -0.025 * dd4hep::rad, + .m_pid_purity = 0.51, //dummy value for MC truth information + .m_correct_beam_FX = true, + .m_pid_use_MC_truth = true, + }, + app)); + + app->Add(new JOmniFactoryGeneratorT( + "PrimaryVertices", {"CentralTrackVertices"}, {"PrimaryVertices"}, {}, app)); } } // extern "C" diff --git a/src/global/tracking/ActsToTracks_factory.h b/src/global/tracking/ActsToTracks_factory.h index 97bb4caf71..88f1f2444f 100644 --- a/src/global/tracking/ActsToTracks_factory.h +++ b/src/global/tracking/ActsToTracks_factory.h @@ -10,21 +10,20 @@ namespace eicrecon { -class ActsToTracks_factory - : public JOmniFactory { +class ActsToTracks_factory : public JOmniFactory { public: using AlgoT = eicrecon::ActsToTracks; private: std::unique_ptr m_algo; - PodioInput m_measurements_input {this}; - Input m_acts_trajectories_input {this}; - PodioInput m_raw_hit_assocs_input {this}; - PodioOutput m_trajectories_output {this}; - PodioOutput m_parameters_output {this}; - PodioOutput m_tracks_output {this}; - PodioOutput m_track_assocs_output {this}; + PodioInput m_measurements_input{this}; + Input m_acts_trajectories_input{this}; + PodioInput m_raw_hit_assocs_input{this}; + PodioOutput m_trajectories_output{this}; + PodioOutput m_parameters_output{this}; + PodioOutput m_tracks_output{this}; + PodioOutput m_track_assocs_output{this}; public: void Configure() { @@ -36,23 +35,22 @@ class ActsToTracks_factory void ChangeRun(int64_t run_number) {}; void Process(int64_t run_number, uint64_t event_number) { - std::vector> acts_trajectories_input; + std::vector> acts_trajectories_input; for (auto acts_traj : m_acts_trajectories_input()) { acts_trajectories_input.push_back(acts_traj); } m_algo->process( - { - m_measurements_input(), - acts_trajectories_input, - m_raw_hit_assocs_input(), - }, - { - m_trajectories_output().get(), - m_parameters_output().get(), - m_tracks_output().get(), - m_track_assocs_output().get(), - } - ); + { + m_measurements_input(), + acts_trajectories_input, + m_raw_hit_assocs_input(), + }, + { + m_trajectories_output().get(), + m_parameters_output().get(), + m_tracks_output().get(), + m_track_assocs_output().get(), + }); } }; diff --git a/src/global/tracking/AmbiguitySolver_factory.h b/src/global/tracking/AmbiguitySolver_factory.h index a72dad6db0..a63912c372 100644 --- a/src/global/tracking/AmbiguitySolver_factory.h +++ b/src/global/tracking/AmbiguitySolver_factory.h @@ -22,15 +22,16 @@ class AmbiguitySolver_factory using AlgoT = eicrecon::AmbiguitySolver; std::unique_ptr m_algo; - Input m_acts_tracks_input {this}; - PodioInput m_measurements_input {this}; - Output m_acts_tracks_output {this}; - Output m_acts_trajectories_output {this}; - - ParameterRef m_maximumSharedHits{this, "maximumSharedHits", config().maximum_shared_hits, - "Maximum number of shared hits allowed"}; - ParameterRef m_maximumIterations{this, "maximumIterations", config().maximum_iterations, - "Maximum number of iterations"}; + Input m_acts_tracks_input{this}; + PodioInput m_measurements_input{this}; + Output m_acts_tracks_output{this}; + Output m_acts_trajectories_output{this}; + + ParameterRef m_maximumSharedHits{this, "maximumSharedHits", + config().maximum_shared_hits, + "Maximum number of shared hits allowed"}; + ParameterRef m_maximumIterations{ + this, "maximumIterations", config().maximum_iterations, "Maximum number of iterations"}; ParameterRef m_nMeasurementsMin{ this, "nMeasurementsMin", config().n_measurements_min, "Number of measurements required for further reconstruction"}; @@ -45,8 +46,9 @@ class AmbiguitySolver_factory void ChangeRun(int64_t run_number) {} void Process(int64_t run_number, uint64_t event_number) { - std::tie(m_acts_tracks_output(),m_acts_trajectories_output()) = m_algo->process(m_acts_tracks_input(),*m_measurements_input()); + std::tie(m_acts_tracks_output(), m_acts_trajectories_output()) = + m_algo->process(m_acts_tracks_input(), *m_measurements_input()); } -} ; +}; } // namespace eicrecon diff --git a/src/global/tracking/CKFTracking_factory.h b/src/global/tracking/CKFTracking_factory.h index ba17ca3ca6..70b8d629dc 100644 --- a/src/global/tracking/CKFTracking_factory.h +++ b/src/global/tracking/CKFTracking_factory.h @@ -21,43 +21,40 @@ namespace eicrecon { -class CKFTracking_factory : - public JOmniFactory { +class CKFTracking_factory : public JOmniFactory { private: - using AlgoT = eicrecon::CKFTracking; - std::unique_ptr m_algo; + using AlgoT = eicrecon::CKFTracking; + std::unique_ptr m_algo; - PodioInput m_parameters_input {this}; - PodioInput m_measurements_input {this}; - Output m_acts_trajectories_output {this}; - Output m_acts_tracks_output {this}; + PodioInput m_parameters_input{this}; + PodioInput m_measurements_input{this}; + Output m_acts_trajectories_output{this}; + Output m_acts_tracks_output{this}; - ParameterRef> m_etaBins {this, "EtaBins", config().etaBins, "Eta Bins for ACTS CKF tracking reco"}; - ParameterRef> m_chi2CutOff {this, "Chi2CutOff", config().chi2CutOff, "Chi2 Cut Off for ACTS CKF tracking"}; - ParameterRef> m_numMeasurementsCutOff {this, "NumMeasurementsCutOff", config().numMeasurementsCutOff, "Number of measurements Cut Off for ACTS CKF tracking"}; + ParameterRef> m_etaBins{this, "EtaBins", config().etaBins, + "Eta Bins for ACTS CKF tracking reco"}; + ParameterRef> m_chi2CutOff{this, "Chi2CutOff", config().chi2CutOff, + "Chi2 Cut Off for ACTS CKF tracking"}; + ParameterRef> m_numMeasurementsCutOff{ + this, "NumMeasurementsCutOff", config().numMeasurementsCutOff, + "Number of measurements Cut Off for ACTS CKF tracking"}; - Service m_ACTSGeoSvc {this}; + Service m_ACTSGeoSvc{this}; public: - void Configure() { - m_algo = std::make_unique(); - m_algo->applyConfig(config()); - m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - std::tie( - m_acts_trajectories_output(), - m_acts_tracks_output() - ) = m_algo->process( - *m_parameters_input(), - *m_measurements_input() - ); - } + void Configure() { + m_algo = std::make_unique(); + m_algo->applyConfig(config()); + m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + std::tie(m_acts_trajectories_output(), m_acts_tracks_output()) = + m_algo->process(*m_parameters_input(), *m_measurements_input()); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/tracking/IterativeVertexFinder_factory.h b/src/global/tracking/IterativeVertexFinder_factory.h index 6f981db1ab..a5e54302ce 100644 --- a/src/global/tracking/IterativeVertexFinder_factory.h +++ b/src/global/tracking/IterativeVertexFinder_factory.h @@ -19,38 +19,38 @@ namespace eicrecon { -class IterativeVertexFinder_factory : - public JOmniFactory { +class IterativeVertexFinder_factory + : public JOmniFactory { private: - using AlgoT = eicrecon::IterativeVertexFinder; - std::unique_ptr m_algo; + using AlgoT = eicrecon::IterativeVertexFinder; + std::unique_ptr m_algo; - Input m_acts_trajectories_input {this}; - PodioInput m_edm4eic_reconParticles_input {this}; - PodioOutput m_vertices_output {this}; + Input m_acts_trajectories_input{this}; + PodioInput m_edm4eic_reconParticles_input{this}; + PodioOutput m_vertices_output{this}; - ParameterRef m_maxVertices {this, "maxVertices", config().maxVertices, - "Maximum num vertices that can be found"}; - ParameterRef m_reassignTracksAfterFirstFit {this, "reassignTracksAfterFirstFit", - config().reassignTracksAfterFirstFit, - "Whether or not to reassign tracks after first fit"}; + ParameterRef m_maxVertices{this, "maxVertices", config().maxVertices, + "Maximum num vertices that can be found"}; + ParameterRef m_reassignTracksAfterFirstFit{ + this, "reassignTracksAfterFirstFit", config().reassignTracksAfterFirstFit, + "Whether or not to reassign tracks after first fit"}; - Service m_ACTSGeoSvc {this}; + Service m_ACTSGeoSvc{this}; public: - void Configure() { - m_algo = std::make_unique(); - m_algo->applyConfig(config()); - m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_vertices_output() = m_algo->produce(m_acts_trajectories_input(), m_edm4eic_reconParticles_input()); - } + void Configure() { + m_algo = std::make_unique(); + m_algo->applyConfig(config()); + m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_vertices_output() = + m_algo->produce(m_acts_trajectories_input(), m_edm4eic_reconParticles_input()); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/tracking/TrackParamTruthInit_factory.h b/src/global/tracking/TrackParamTruthInit_factory.h index 09bd09dda3..33f95cf547 100644 --- a/src/global/tracking/TrackParamTruthInit_factory.h +++ b/src/global/tracking/TrackParamTruthInit_factory.h @@ -19,40 +19,49 @@ namespace eicrecon { -class TrackParamTruthInit_factory : - public JOmniFactory { +class TrackParamTruthInit_factory + : public JOmniFactory { private: - using AlgoT = eicrecon::TrackParamTruthInit; - std::unique_ptr m_algo; + using AlgoT = eicrecon::TrackParamTruthInit; + std::unique_ptr m_algo; - PodioInput m_particles_input {this}; - PodioOutput m_parameters_output {this}; + PodioInput m_particles_input{this}; + PodioOutput m_parameters_output{this}; - ParameterRef m_maxVertexX {this, "MaxVertexX", config().maxVertexX , "Maximum abs(vertex x) for truth tracks turned into seed"}; - ParameterRef m_maxVertexY {this, "MaxVertexY", config().maxVertexY , "Maximum abs(vertex y) for truth tracks turned into seed"}; - ParameterRef m_maxVertexZ {this, "MaxVertexZ", config().maxVertexZ , "Maximum abs(vertex z) for truth tracks turned into seed"}; - ParameterRef m_minMomentum {this, "MinMomentum", config().minMomentum , "Minimum momentum for truth tracks turned into seed"}; - ParameterRef m_maxEtaForward {this, "MaxEtaForward", config().maxEtaForward , "Maximum forward abs(eta) for truth tracks turned into seed"}; - ParameterRef m_maxEtaBackward {this, "MaxEtaBackward", config().maxEtaBackward , "Maximum backward abs(eta) for truth tracks turned into seed"}; - ParameterRef m_momentumSmear {this, "MomentumSmear", config().momentumSmear, "Momentum magnitude fraction to use as width of gaussian smearing"}; + ParameterRef m_maxVertexX{this, "MaxVertexX", config().maxVertexX, + "Maximum abs(vertex x) for truth tracks turned into seed"}; + ParameterRef m_maxVertexY{this, "MaxVertexY", config().maxVertexY, + "Maximum abs(vertex y) for truth tracks turned into seed"}; + ParameterRef m_maxVertexZ{this, "MaxVertexZ", config().maxVertexZ, + "Maximum abs(vertex z) for truth tracks turned into seed"}; + ParameterRef m_minMomentum{this, "MinMomentum", config().minMomentum, + "Minimum momentum for truth tracks turned into seed"}; + ParameterRef m_maxEtaForward{ + this, "MaxEtaForward", config().maxEtaForward, + "Maximum forward abs(eta) for truth tracks turned into seed"}; + ParameterRef m_maxEtaBackward{ + this, "MaxEtaBackward", config().maxEtaBackward, + "Maximum backward abs(eta) for truth tracks turned into seed"}; + ParameterRef m_momentumSmear{ + this, "MomentumSmear", config().momentumSmear, + "Momentum magnitude fraction to use as width of gaussian smearing"}; - Service m_ACTSGeoSvc {this}; - Service m_algorithmsInit {this}; + Service m_ACTSGeoSvc{this}; + Service m_algorithmsInit{this}; public: - void Configure() { - m_algo = std::make_unique(); - m_algo->applyConfig(config()); - m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_parameters_output() = m_algo->produce(m_particles_input()); - } + void Configure() { + m_algo = std::make_unique(); + m_algo->applyConfig(config()); + m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_parameters_output() = m_algo->produce(m_particles_input()); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/tracking/TrackProjector_factory.h b/src/global/tracking/TrackProjector_factory.h index df40444054..5a9479ca67 100644 --- a/src/global/tracking/TrackProjector_factory.h +++ b/src/global/tracking/TrackProjector_factory.h @@ -17,30 +17,28 @@ namespace eicrecon { -class TrackProjector_factory : - public JOmniFactory { +class TrackProjector_factory : public JOmniFactory { private: - using AlgoT = eicrecon::TrackProjector; - std::unique_ptr m_algo; + using AlgoT = eicrecon::TrackProjector; + std::unique_ptr m_algo; - Input m_acts_trajectories_input {this}; - PodioOutput m_segments_output {this}; + Input m_acts_trajectories_input{this}; + PodioOutput m_segments_output{this}; - Service m_ACTSGeoSvc {this}; + Service m_ACTSGeoSvc{this}; public: - void Configure() { - m_algo = std::make_unique(); - m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); - } + void Configure() { + m_algo = std::make_unique(); + m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { - m_segments_output() = m_algo->execute(m_acts_trajectories_input()); - } + void Process(int64_t run_number, uint64_t event_number) { + m_segments_output() = m_algo->execute(m_acts_trajectories_input()); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/tracking/TrackPropagation_factory.h b/src/global/tracking/TrackPropagation_factory.h index 35143d2a71..10d6940091 100644 --- a/src/global/tracking/TrackPropagation_factory.h +++ b/src/global/tracking/TrackPropagation_factory.h @@ -20,37 +20,34 @@ namespace eicrecon { -class TrackPropagation_factory : - public JOmniFactory { +class TrackPropagation_factory + : public JOmniFactory { private: - using AlgoT = eicrecon::TrackPropagation; - std::unique_ptr m_algo; + using AlgoT = eicrecon::TrackPropagation; + std::unique_ptr m_algo; - PodioInput m_tracks_input {this}; - Input m_acts_trajectories_input {this}; - Input m_acts_tracks_input {this}; - PodioOutput m_track_segments_output {this}; + PodioInput m_tracks_input{this}; + Input m_acts_trajectories_input{this}; + Input m_acts_tracks_input{this}; + PodioOutput m_track_segments_output{this}; - Service m_GeoSvc {this}; - Service m_ACTSGeoSvc {this}; + Service m_GeoSvc{this}; + Service m_ACTSGeoSvc{this}; public: - void Configure() { - m_algo = std::make_unique(); - m_algo->applyConfig(config()); - m_algo->init(m_GeoSvc().detector(), m_ACTSGeoSvc().actsGeoProvider(), logger()); - } - - void ChangeRun(int64_t run_number) { - } - - void Process(int64_t run_number, uint64_t event_number) { - m_algo->process( - {*m_tracks_input(), m_acts_trajectories_input(), m_acts_tracks_input()}, - {m_track_segments_output().get()} - ); - } + void Configure() { + m_algo = std::make_unique(); + m_algo->applyConfig(config()); + m_algo->init(m_GeoSvc().detector(), m_ACTSGeoSvc().actsGeoProvider(), logger()); + } + + void ChangeRun(int64_t run_number) {} + + void Process(int64_t run_number, uint64_t event_number) { + m_algo->process({*m_tracks_input(), m_acts_trajectories_input(), m_acts_tracks_input()}, + {m_track_segments_output().get()}); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/tracking/TrackSeeding_factory.h b/src/global/tracking/TrackSeeding_factory.h index 12695bc721..cbbb4d6ca9 100644 --- a/src/global/tracking/TrackSeeding_factory.h +++ b/src/global/tracking/TrackSeeding_factory.h @@ -18,61 +18,101 @@ namespace eicrecon { -class TrackSeeding_factory : - public JOmniFactory { +class TrackSeeding_factory + : public JOmniFactory { private: - using AlgoT = eicrecon::TrackSeeding; - std::unique_ptr m_algo; + using AlgoT = eicrecon::TrackSeeding; + std::unique_ptr m_algo; - PodioInput m_hits_input {this}; - PodioOutput m_parameters_output {this}; + PodioInput m_hits_input{this}; + PodioOutput m_parameters_output{this}; + ParameterRef m_rMax{this, "rMax", config().rMax, + "max measurement radius for Acts::OrthogonalSeedFinder"}; + ParameterRef m_rMin{this, "rMin", config().rMin, + "min measurement radius for Acts::OrthogonalSeedFinder"}; + ParameterRef m_deltaRMinTopSP{this, "deltaRMinTopSP", config().deltaRMinTopSP, + "min distance in r between middle and top space point in " + "one seed for Acts::OrthogonalSeedFinder"}; + ParameterRef m_deltaRMaxTopSP{this, "deltaRMaxTopSP", config().deltaRMaxTopSP, + "max distance in r between middle and top space point in " + "one seed for Acts::OrthogonalSeedFinder"}; + ParameterRef m_deltaRMinBottomSP{this, "deltaRMinBottomSP", config().deltaRMinBottomSP, + "min distance in r between bottom and middle space point " + "in one seed for Acts::OrthogonalSeedFinder"}; + ParameterRef m_deltaRMaxBottomSP{this, "deltaRMaxBottomSP", config().deltaRMaxBottomSP, + "max distance in r between bottom and middle space point " + "in one seed for Acts::OrthogonalSeedFinder"}; + ParameterRef m_collisionRegionMin{ + this, "collisionRegionMin", config().collisionRegionMin, + "min location in z for collision region for Acts::OrthogonalSeedFinder"}; + ParameterRef m_collisionRegionMax{ + this, "collisionRegionMax", config().collisionRegionMax, + "max location in z for collision region for Acts::OrthogonalSeedFinder"}; + ParameterRef m_zMax{this, "zMax", config().zMax, + "Max z location for measurements for Acts::OrthogonalSeedFinder"}; + ParameterRef m_zMin{this, "zMin", config().zMin, + "Min z location for measurements for Acts::OrthogonalSeedFinder"}; + ParameterRef m_maxSeedsPerSpM{this, "maxSeedsPerSpM", config().maxSeedsPerSpM, + "Maximum number of seeds one space point can be the " + "middle of for Acts::OrthogonalSeedFinder"}; + ParameterRef m_cotThetaMax{this, "cotThetaMax", config().cotThetaMax, + "cot of maximum theta angle for Acts::OrthogonalSeedFinder"}; + ParameterRef m_sigmaScattering{ + this, "sigmaScattering", config().sigmaScattering, + "number of sigmas of scattering angle to consider for Acts::OrthogonalSeedFinder"}; + ParameterRef m_radLengthPerSeed{ + this, "radLengthPerSeed", config().radLengthPerSeed, + "Approximate number of radiation lengths one seed traverses for Acts::OrthogonalSeedFinder"}; + ParameterRef m_minPt{this, "minPt", config().minPt, + "Minimum pT to search for for Acts::OrthogonalSeedFinder"}; + ParameterRef m_bFieldInZ{ + this, "bFieldInZ", config().bFieldInZ, + "Value of B Field to use in kiloTesla for Acts::OrthogonalSeedFinder"}; + ParameterRef m_beamPosX{this, "beamPosX", config().beamPosX, + "Beam position in x for Acts::OrthogonalSeedFinder"}; + ParameterRef m_beamPosY{this, "beamPosY", config().beamPosY, + "Beam position in y for Acts::OrthogonalSeedFinder"}; + ParameterRef m_impactMax{ + this, "impactMax", config().impactMax, + "maximum impact parameter allowed for seeds for Acts::OrthogonalSeedFinder. rMin should be " + "larger than impactMax."}; + ParameterRef m_rMinMiddle{ + this, "rMinMiddle", config().rMinMiddle, + "min radius for middle space point for Acts::OrthogonalSeedFinder"}; + ParameterRef m_rMaxMiddle{ + this, "rMaxMiddle", config().rMaxMiddle, + "max radius for middle space point for Acts::OrthogonalSeedFinder"}; + ParameterRef m_deltaPhiMax{this, "deltaPhiMax", config().deltaPhiMax, + "Max phi difference between middle and top/bottom space point"}; + ParameterRef m_locaError{this, "loc_a_Error", config().locaError, + "Error on Loc a for Acts::OrthogonalSeedFinder"}; + ParameterRef m_locbError{this, "loc_b_Error", config().locbError, + "Error on Loc b for Acts::OrthogonalSeedFinder"}; + ParameterRef m_phiError{this, "phi_Error", config().phiError, + "Error on phi for Acts::OrthogonalSeedFinder"}; + ParameterRef m_thetaError{this, "theta_Error", config().thetaError, + "Error on theta for Acts::OrthogonalSeedFinder"}; + ParameterRef m_qOverPError{this, "qOverP_Error", config().qOverPError, + "Error on q/p for Acts::OrthogonalSeedFinder"}; + ParameterRef m_timeError{this, "time_Error", config().timeError, + "Error on time for Acts::OrthogonalSeedFinder"}; - ParameterRef m_rMax {this, "rMax", config().rMax, "max measurement radius for Acts::OrthogonalSeedFinder"}; - ParameterRef m_rMin {this, "rMin", config().rMin, "min measurement radius for Acts::OrthogonalSeedFinder"}; - ParameterRef m_deltaRMinTopSP {this, "deltaRMinTopSP", config().deltaRMinTopSP, "min distance in r between middle and top space point in one seed for Acts::OrthogonalSeedFinder"}; - ParameterRef m_deltaRMaxTopSP {this, "deltaRMaxTopSP", config().deltaRMaxTopSP, "max distance in r between middle and top space point in one seed for Acts::OrthogonalSeedFinder"}; - ParameterRef m_deltaRMinBottomSP {this, "deltaRMinBottomSP", config().deltaRMinBottomSP, "min distance in r between bottom and middle space point in one seed for Acts::OrthogonalSeedFinder"}; - ParameterRef m_deltaRMaxBottomSP {this, "deltaRMaxBottomSP", config().deltaRMaxBottomSP, "max distance in r between bottom and middle space point in one seed for Acts::OrthogonalSeedFinder"}; - ParameterRef m_collisionRegionMin {this, "collisionRegionMin", config().collisionRegionMin, "min location in z for collision region for Acts::OrthogonalSeedFinder"}; - ParameterRef m_collisionRegionMax {this, "collisionRegionMax", config().collisionRegionMax, "max location in z for collision region for Acts::OrthogonalSeedFinder"}; - ParameterRef m_zMax {this, "zMax", config().zMax, "Max z location for measurements for Acts::OrthogonalSeedFinder"}; - ParameterRef m_zMin {this, "zMin", config().zMin, "Min z location for measurements for Acts::OrthogonalSeedFinder"}; - ParameterRef m_maxSeedsPerSpM {this, "maxSeedsPerSpM", config().maxSeedsPerSpM, "Maximum number of seeds one space point can be the middle of for Acts::OrthogonalSeedFinder"}; - ParameterRef m_cotThetaMax {this, "cotThetaMax", config().cotThetaMax, "cot of maximum theta angle for Acts::OrthogonalSeedFinder"}; - ParameterRef m_sigmaScattering {this, "sigmaScattering", config().sigmaScattering, "number of sigmas of scattering angle to consider for Acts::OrthogonalSeedFinder"}; - ParameterRef m_radLengthPerSeed {this, "radLengthPerSeed", config().radLengthPerSeed, "Approximate number of radiation lengths one seed traverses for Acts::OrthogonalSeedFinder"}; - ParameterRef m_minPt {this, "minPt", config().minPt, "Minimum pT to search for for Acts::OrthogonalSeedFinder"}; - ParameterRef m_bFieldInZ {this, "bFieldInZ", config().bFieldInZ, "Value of B Field to use in kiloTesla for Acts::OrthogonalSeedFinder"}; - ParameterRef m_beamPosX {this, "beamPosX", config().beamPosX, "Beam position in x for Acts::OrthogonalSeedFinder"}; - ParameterRef m_beamPosY {this, "beamPosY", config().beamPosY, "Beam position in y for Acts::OrthogonalSeedFinder"}; - ParameterRef m_impactMax {this, "impactMax", config().impactMax, "maximum impact parameter allowed for seeds for Acts::OrthogonalSeedFinder. rMin should be larger than impactMax."}; - ParameterRef m_rMinMiddle {this, "rMinMiddle", config().rMinMiddle, "min radius for middle space point for Acts::OrthogonalSeedFinder"}; - ParameterRef m_rMaxMiddle {this, "rMaxMiddle", config().rMaxMiddle, "max radius for middle space point for Acts::OrthogonalSeedFinder"}; - ParameterRef m_deltaPhiMax {this, "deltaPhiMax", config().deltaPhiMax, "Max phi difference between middle and top/bottom space point"}; - ParameterRef m_locaError {this, "loc_a_Error", config().locaError, "Error on Loc a for Acts::OrthogonalSeedFinder"}; - ParameterRef m_locbError {this, "loc_b_Error", config().locbError, "Error on Loc b for Acts::OrthogonalSeedFinder"}; - ParameterRef m_phiError {this, "phi_Error", config().phiError, "Error on phi for Acts::OrthogonalSeedFinder"}; - ParameterRef m_thetaError {this, "theta_Error", config().thetaError, "Error on theta for Acts::OrthogonalSeedFinder"}; - ParameterRef m_qOverPError {this, "qOverP_Error", config().qOverPError, "Error on q/p for Acts::OrthogonalSeedFinder"}; - ParameterRef m_timeError {this, "time_Error", config().timeError, "Error on time for Acts::OrthogonalSeedFinder"}; - - Service m_ACTSGeoSvc {this}; + Service m_ACTSGeoSvc{this}; public: - void Configure() { - m_algo = std::make_unique(); - m_algo->applyConfig(config()); - m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); - } + void Configure() { + m_algo = std::make_unique(); + m_algo->applyConfig(config()); + m_algo->init(m_ACTSGeoSvc().actsGeoProvider(), logger()); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { - m_parameters_output() = m_algo->produce(*m_hits_input()); - } + void Process(int64_t run_number, uint64_t event_number) { + m_parameters_output() = m_algo->produce(*m_hits_input()); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/tracking/TrackerMeasurementFromHits_factory.h b/src/global/tracking/TrackerMeasurementFromHits_factory.h index d63f160b7d..b736a51740 100644 --- a/src/global/tracking/TrackerMeasurementFromHits_factory.h +++ b/src/global/tracking/TrackerMeasurementFromHits_factory.h @@ -19,31 +19,30 @@ namespace eicrecon { -class TrackerMeasurementFromHits_factory : - public JOmniFactory { +class TrackerMeasurementFromHits_factory : public JOmniFactory { private: - using AlgoT = eicrecon::TrackerMeasurementFromHits; - std::unique_ptr m_algo; + using AlgoT = eicrecon::TrackerMeasurementFromHits; + std::unique_ptr m_algo; - PodioInput m_hits_input {this}; - PodioOutput m_measurements_output {this}; + PodioInput m_hits_input{this}; + PodioOutput m_measurements_output{this}; - Service m_DD4hepSvc {this}; - Service m_ACTSGeoSvc {this}; + Service m_DD4hepSvc{this}; + Service m_ACTSGeoSvc{this}; public: - void Configure() { - m_algo = std::make_unique(); - m_algo->init(m_DD4hepSvc().detector(), m_DD4hepSvc().converter(), m_ACTSGeoSvc().actsGeoProvider(), logger()); - } + void Configure() { + m_algo = std::make_unique(); + m_algo->init(m_DD4hepSvc().detector(), m_DD4hepSvc().converter(), + m_ACTSGeoSvc().actsGeoProvider(), logger()); + } - void ChangeRun(int64_t run_number) { - } + void ChangeRun(int64_t run_number) {} - void Process(int64_t run_number, uint64_t event_number) { - m_measurements_output() = m_algo->produce(*m_hits_input()); - } + void Process(int64_t run_number, uint64_t event_number) { + m_measurements_output() = m_algo->produce(*m_hits_input()); + } }; -} // eicrecon +} // namespace eicrecon diff --git a/src/global/tracking/TracksToParticles_factory.h b/src/global/tracking/TracksToParticles_factory.h index a0e82741cb..8ce0792176 100644 --- a/src/global/tracking/TracksToParticles_factory.h +++ b/src/global/tracking/TracksToParticles_factory.h @@ -13,8 +13,7 @@ namespace eicrecon { -class TracksToParticles_factory - : public JOmniFactory { +class TracksToParticles_factory : public JOmniFactory { public: using AlgoT = eicrecon::TracksToParticles; diff --git a/src/global/tracking/tracking.cc b/src/global/tracking/tracking.cc index eeef3016e1..32f5e7f47f 100644 --- a/src/global/tracking/tracking.cc +++ b/src/global/tracking/tracking.cc @@ -32,287 +32,237 @@ // extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); - using namespace eicrecon; + using namespace eicrecon; - app->Add(new JOmniFactoryGeneratorT( - "InitTrackParams", - {"MCParticles"}, - {"InitTrackParams"}, - {}, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "InitTrackParams", {"MCParticles"}, {"InitTrackParams"}, {}, app)); - // Possible collections from arches, brycecanyon and craterlake configurations - std::vector> possible_collections = { - {"SiBarrelHits", "SiBarrelRawHits", "SiBarrelRawHitAssociations", "SiBarrelTrackerRecHits"}, - {"VertexBarrelHits", "SiBarrelVertexRawHits", "SiBarrelVertexRawHitAssociations", "SiBarrelVertexRecHits"}, - {"TrackerEndcapHits", "SiEndcapTrackerRawHits", "SiEndcapTrackerRawHitAssociations", "SiEndcapTrackerRecHits"}, - {"TOFBarrelHits", "TOFBarrelRawHits", "TOFBarrelRawHitAssociations", "TOFBarrelRecHits"}, - {"TOFEndcapHits", "TOFEndcapRawHits", "TOFEndcapRawHitAssociations", "TOFEndcapRecHits"}, - {"MPGDBarrelHits", "MPGDBarrelRawHits", "MPGDBarrelRawHitAssociations", "MPGDBarrelRecHits"}, - {"OuterMPGDBarrelHits", "OuterMPGDBarrelRawHits", "OuterMPGDBarrelRawHitAssociations", "OuterMPGDBarrelRecHits"}, - {"BackwardMPGDEndcapHits", "BackwardMPGDEndcapRawHits", "BackwardMPGDEndcapRawHitAssociations", "BackwardMPGDEndcapRecHits"}, - {"ForwardMPGDEndcapHits", "ForwardMPGDEndcapRawHits", "ForwardMPGDEndcapRawHitAssociations", "ForwardMPGDEndcapRecHits"}, - {"B0TrackerHits", "B0TrackerRawHits", "B0TrackerRawHitAssociations", "B0TrackerRecHits"} - }; + // Possible collections from arches, brycecanyon and craterlake configurations + std::vector> possible_collections = + {{"SiBarrelHits", "SiBarrelRawHits", "SiBarrelRawHitAssociations", "SiBarrelTrackerRecHits"}, + {"VertexBarrelHits", "SiBarrelVertexRawHits", "SiBarrelVertexRawHitAssociations", + "SiBarrelVertexRecHits"}, + {"TrackerEndcapHits", "SiEndcapTrackerRawHits", "SiEndcapTrackerRawHitAssociations", + "SiEndcapTrackerRecHits"}, + {"TOFBarrelHits", "TOFBarrelRawHits", "TOFBarrelRawHitAssociations", "TOFBarrelRecHits"}, + {"TOFEndcapHits", "TOFEndcapRawHits", "TOFEndcapRawHitAssociations", "TOFEndcapRecHits"}, + {"MPGDBarrelHits", "MPGDBarrelRawHits", "MPGDBarrelRawHitAssociations", "MPGDBarrelRecHits"}, + {"OuterMPGDBarrelHits", "OuterMPGDBarrelRawHits", "OuterMPGDBarrelRawHitAssociations", + "OuterMPGDBarrelRecHits"}, + {"BackwardMPGDEndcapHits", "BackwardMPGDEndcapRawHits", + "BackwardMPGDEndcapRawHitAssociations", "BackwardMPGDEndcapRecHits"}, + {"ForwardMPGDEndcapHits", "ForwardMPGDEndcapRawHits", "ForwardMPGDEndcapRawHitAssociations", + "ForwardMPGDEndcapRecHits"}, + {"B0TrackerHits", "B0TrackerRawHits", "B0TrackerRawHitAssociations", "B0TrackerRecHits"}}; - // Filter out collections that are not present in the current configuration - std::vector input_rec_collections; - std::vector input_raw_assoc_collections; - auto readouts = app->GetService()->detector()->readouts(); - for (const auto& [hit_collection, raw_collection, raw_assoc_collection, rec_collection] : possible_collections) { - if (readouts.find(hit_collection) != readouts.end()) { - // Add the collection to the list of input collections - input_rec_collections.push_back(rec_collection); - input_raw_assoc_collections.push_back(raw_assoc_collection); - } + // Filter out collections that are not present in the current configuration + std::vector input_rec_collections; + std::vector input_raw_assoc_collections; + auto readouts = app->GetService()->detector()->readouts(); + for (const auto& [hit_collection, raw_collection, raw_assoc_collection, rec_collection] : + possible_collections) { + if (readouts.find(hit_collection) != readouts.end()) { + // Add the collection to the list of input collections + input_rec_collections.push_back(rec_collection); + input_raw_assoc_collections.push_back(raw_assoc_collection); } + } - // Tracker hits collector - app->Add(new JOmniFactoryGeneratorT>( - "CentralTrackingRecHits", - input_rec_collections, - {"CentralTrackingRecHits"}, // Output collection name - app)); + // Tracker hits collector + app->Add(new JOmniFactoryGeneratorT>( + "CentralTrackingRecHits", input_rec_collections, + {"CentralTrackingRecHits"}, // Output collection name + app)); - // Tracker hit associations collector - app->Add(new JOmniFactoryGeneratorT>( - "CentralTrackingRawHitAssociations", - input_raw_assoc_collections, - {"CentralTrackingRawHitAssociations"}, // Output collection name - app)); + // Tracker hit associations collector + app->Add( + new JOmniFactoryGeneratorT>( + "CentralTrackingRawHitAssociations", input_raw_assoc_collections, + {"CentralTrackingRawHitAssociations"}, // Output collection name + app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralTrackerMeasurements", - {"CentralTrackingRecHits"}, - {"CentralTrackerMeasurements"}, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "CentralTrackerMeasurements", {"CentralTrackingRecHits"}, {"CentralTrackerMeasurements"}, + app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralCKFTruthSeededTrajectories", - { - "InitTrackParams", - "CentralTrackerMeasurements" - }, - { - "CentralCKFTruthSeededActsTrajectoriesUnfiltered", - "CentralCKFTruthSeededActsTracksUnfiltered", - }, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "CentralCKFTruthSeededTrajectories", {"InitTrackParams", "CentralTrackerMeasurements"}, + { + "CentralCKFTruthSeededActsTrajectoriesUnfiltered", + "CentralCKFTruthSeededActsTracksUnfiltered", + }, + app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralCKFTruthSeededTracksUnfiltered", - { - "CentralTrackerMeasurements", - "CentralCKFTruthSeededActsTrajectoriesUnfiltered", - "CentralTrackingRawHitAssociations", - }, - { - "CentralCKFTruthSeededTrajectoriesUnfiltered", - "CentralCKFTruthSeededTrackParametersUnfiltered", - "CentralCKFTruthSeededTracksUnfiltered", - "CentralCKFTruthSeededTrackUnfilteredAssociations", - }, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "CentralCKFTruthSeededTracksUnfiltered", + { + "CentralTrackerMeasurements", + "CentralCKFTruthSeededActsTrajectoriesUnfiltered", + "CentralTrackingRawHitAssociations", + }, + { + "CentralCKFTruthSeededTrajectoriesUnfiltered", + "CentralCKFTruthSeededTrackParametersUnfiltered", + "CentralCKFTruthSeededTracksUnfiltered", + "CentralCKFTruthSeededTrackUnfilteredAssociations", + }, + app)); - app->Add(new JOmniFactoryGeneratorT( - "TruthSeededAmbiguityResolutionSolver", - { - "CentralCKFTruthSeededActsTracksUnfiltered", - "CentralTrackerMeasurements" - }, - { - "CentralCKFTruthSeededActsTracks", - "CentralCKFTruthSeededActsTrajectories", - }, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "TruthSeededAmbiguityResolutionSolver", + {"CentralCKFTruthSeededActsTracksUnfiltered", "CentralTrackerMeasurements"}, + { + "CentralCKFTruthSeededActsTracks", + "CentralCKFTruthSeededActsTrajectories", + }, + app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralCKFTruthSeededTracks", - { - "CentralTrackerMeasurements", - "CentralCKFTruthSeededActsTrajectories", - "CentralTrackingRawHitAssociations", - }, - { - "CentralCKFTruthSeededTrajectories", - "CentralCKFTruthSeededTrackParameters", - "CentralCKFTruthSeededTracks", - "CentralCKFTruthSeededTrackAssociations", - }, - app - )); + app->Add( + new JOmniFactoryGeneratorT("CentralCKFTruthSeededTracks", + { + "CentralTrackerMeasurements", + "CentralCKFTruthSeededActsTrajectories", + "CentralTrackingRawHitAssociations", + }, + { + "CentralCKFTruthSeededTrajectories", + "CentralCKFTruthSeededTrackParameters", + "CentralCKFTruthSeededTracks", + "CentralCKFTruthSeededTrackAssociations", + }, + app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralTrackSeedingResults", - {"CentralTrackingRecHits"}, - {"CentralTrackSeedingResults"}, - {}, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "CentralTrackSeedingResults", {"CentralTrackingRecHits"}, {"CentralTrackSeedingResults"}, {}, + app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralCKFTrajectories", - { - "CentralTrackSeedingResults", - "CentralTrackerMeasurements" - }, - { - "CentralCKFActsTrajectoriesUnfiltered", - "CentralCKFActsTracksUnfiltered", - }, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "CentralCKFTrajectories", {"CentralTrackSeedingResults", "CentralTrackerMeasurements"}, + { + "CentralCKFActsTrajectoriesUnfiltered", + "CentralCKFActsTracksUnfiltered", + }, + app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralCKFTracksUnfiltered", - { - "CentralTrackerMeasurements", - "CentralCKFActsTrajectoriesUnfiltered", - "CentralTrackingRawHitAssociations", - }, - { - "CentralCKFTrajectoriesUnfiltered", - "CentralCKFTrackParametersUnfiltered", - "CentralCKFTracksUnfiltered", - "CentralCKFTrackUnfilteredAssociations", - }, - app - )); + app->Add( + new JOmniFactoryGeneratorT("CentralCKFTracksUnfiltered", + { + "CentralTrackerMeasurements", + "CentralCKFActsTrajectoriesUnfiltered", + "CentralTrackingRawHitAssociations", + }, + { + "CentralCKFTrajectoriesUnfiltered", + "CentralCKFTrackParametersUnfiltered", + "CentralCKFTracksUnfiltered", + "CentralCKFTrackUnfilteredAssociations", + }, + app)); - app->Add(new JOmniFactoryGeneratorT( - "AmbiguityResolutionSolver", - { - "CentralCKFActsTracksUnfiltered", - "CentralTrackerMeasurements" - }, - { - "CentralCKFActsTracks", - "CentralCKFActsTrajectories", - }, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "AmbiguityResolutionSolver", {"CentralCKFActsTracksUnfiltered", "CentralTrackerMeasurements"}, + { + "CentralCKFActsTracks", + "CentralCKFActsTrajectories", + }, + app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralCKFTracks", - { - "CentralTrackerMeasurements", - "CentralCKFActsTrajectories", - "CentralTrackingRawHitAssociations", - }, - { - "CentralCKFTrajectories", - "CentralCKFTrackParameters", - "CentralCKFTracks", - "CentralCKFTrackAssociations", - }, - app - )); + app->Add(new JOmniFactoryGeneratorT("CentralCKFTracks", + { + "CentralTrackerMeasurements", + "CentralCKFActsTrajectories", + "CentralTrackingRawHitAssociations", + }, + { + "CentralCKFTrajectories", + "CentralCKFTrackParameters", + "CentralCKFTracks", + "CentralCKFTrackAssociations", + }, + app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralTrackSegments", - {"CentralCKFActsTrajectories"}, - {"CentralTrackSegments"}, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "CentralTrackSegments", {"CentralCKFActsTrajectories"}, {"CentralTrackSegments"}, app)); - app->Add(new JOmniFactoryGeneratorT( - "CentralTrackVertices", - {"CentralCKFActsTrajectories","ReconstructedChargedParticles"}, - {"CentralTrackVertices"}, - {}, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "CentralTrackVertices", {"CentralCKFActsTrajectories", "ReconstructedChargedParticles"}, + {"CentralTrackVertices"}, {}, app)); - app->Add(new JOmniFactoryGeneratorT( - "CalorimeterTrackPropagator", - {"CentralCKFTracks", "CentralCKFActsTrajectories", "CentralCKFActsTracks"}, - {"CalorimeterTrackProjections"}, - { - .target_surfaces{ - // Ecal - eicrecon::DiscSurfaceConfig{"EcalEndcapN_ID", "- EcalEndcapN_zmin", 0., "1.1*EcalEndcapN_rmax"}, - eicrecon::DiscSurfaceConfig{"EcalEndcapN_ID", "- EcalEndcapN_zmin - 50*mm", 0., "1.1*EcalEndcapN_rmax"}, - eicrecon::CylinderSurfaceConfig{"EcalBarrel_ID", "EcalBarrel_rmin", - "- 1.1*max(EcalBarrelBackward_zmax,EcalBarrelForward_zmax)", - "1.1*max(EcalBarrelBackward_zmax,EcalBarrelForward_zmax)" - }, - eicrecon::CylinderSurfaceConfig{"EcalBarrel_ID", "EcalBarrel_rmin + 50*mm", - "- 1.1*max(EcalBarrelBackward_zmax,EcalBarrelForward_zmax)", - "1.1*max(EcalBarrelBackward_zmax,EcalBarrelForward_zmax)" - }, - eicrecon::DiscSurfaceConfig{"EcalEndcapP_ID", "EcalEndcapP_zmin", 0., "1.1*EcalEndcapP_rmax"}, - eicrecon::DiscSurfaceConfig{"EcalEndcapP_ID", "EcalEndcapP_zmin + 50*mm", 0., "1.1*EcalEndcapP_rmax"}, - // Hcal - eicrecon::DiscSurfaceConfig{"HcalEndcapN_ID", "- HcalEndcapN_zmin", 0., "1.1*HcalEndcapN_rmax"}, - eicrecon::DiscSurfaceConfig{"HcalEndcapN_ID", "- HcalEndcapN_zmin - 150*mm", 0., "1.1*HcalEndcapN_rmax"}, - eicrecon::CylinderSurfaceConfig{"HcalBarrel_ID", "HcalBarrel_rmin", - "- 1.1*max(HcalBarrelBackward_zmax,HcalBarrelForward_zmax)", - "1.1*max(HcalBarrelBackward_zmax,HcalBarrelForward_zmax)" - }, - eicrecon::CylinderSurfaceConfig{"HcalBarrel_ID", "HcalBarrel_rmin + 150*mm", - "- 1.1*max(HcalBarrelBackward_zmax,HcalBarrelForward_zmax)", - "1.1*max(HcalBarrelBackward_zmax,HcalBarrelForward_zmax)" - }, - eicrecon::DiscSurfaceConfig{"LFHCAL_ID", "LFHCAL_zmin", 0., "1.1*LFHCAL_rmax"}, - eicrecon::DiscSurfaceConfig{"LFHCAL_ID", "LFHCAL_zmin + 150*mm", 0., "1.1*LFHCAL_rmax"}, - } - }, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "CalorimeterTrackPropagator", + {"CentralCKFTracks", "CentralCKFActsTrajectories", "CentralCKFActsTracks"}, + {"CalorimeterTrackProjections"}, + {.target_surfaces{ + // Ecal + eicrecon::DiscSurfaceConfig{"EcalEndcapN_ID", "- EcalEndcapN_zmin", 0., + "1.1*EcalEndcapN_rmax"}, + eicrecon::DiscSurfaceConfig{"EcalEndcapN_ID", "- EcalEndcapN_zmin - 50*mm", 0., + "1.1*EcalEndcapN_rmax"}, + eicrecon::CylinderSurfaceConfig{ + "EcalBarrel_ID", "EcalBarrel_rmin", + "- 1.1*max(EcalBarrelBackward_zmax,EcalBarrelForward_zmax)", + "1.1*max(EcalBarrelBackward_zmax,EcalBarrelForward_zmax)"}, + eicrecon::CylinderSurfaceConfig{ + "EcalBarrel_ID", "EcalBarrel_rmin + 50*mm", + "- 1.1*max(EcalBarrelBackward_zmax,EcalBarrelForward_zmax)", + "1.1*max(EcalBarrelBackward_zmax,EcalBarrelForward_zmax)"}, + eicrecon::DiscSurfaceConfig{"EcalEndcapP_ID", "EcalEndcapP_zmin", 0., + "1.1*EcalEndcapP_rmax"}, + eicrecon::DiscSurfaceConfig{"EcalEndcapP_ID", "EcalEndcapP_zmin + 50*mm", 0., + "1.1*EcalEndcapP_rmax"}, + // Hcal + eicrecon::DiscSurfaceConfig{"HcalEndcapN_ID", "- HcalEndcapN_zmin", 0., + "1.1*HcalEndcapN_rmax"}, + eicrecon::DiscSurfaceConfig{"HcalEndcapN_ID", "- HcalEndcapN_zmin - 150*mm", 0., + "1.1*HcalEndcapN_rmax"}, + eicrecon::CylinderSurfaceConfig{ + "HcalBarrel_ID", "HcalBarrel_rmin", + "- 1.1*max(HcalBarrelBackward_zmax,HcalBarrelForward_zmax)", + "1.1*max(HcalBarrelBackward_zmax,HcalBarrelForward_zmax)"}, + eicrecon::CylinderSurfaceConfig{ + "HcalBarrel_ID", "HcalBarrel_rmin + 150*mm", + "- 1.1*max(HcalBarrelBackward_zmax,HcalBarrelForward_zmax)", + "1.1*max(HcalBarrelBackward_zmax,HcalBarrelForward_zmax)"}, + eicrecon::DiscSurfaceConfig{"LFHCAL_ID", "LFHCAL_zmin", 0., "1.1*LFHCAL_rmax"}, + eicrecon::DiscSurfaceConfig{"LFHCAL_ID", "LFHCAL_zmin + 150*mm", 0., "1.1*LFHCAL_rmax"}, + }}, + app)); + std::vector input_track_collections; + //Check size of input_rec_collections to determine if CentralCKFTracks should be added to the input_track_collections + if (input_rec_collections.size() > 0) { + input_track_collections.push_back("CentralCKFTracks"); + } + //Check if the TaggerTracker readout is present in the current configuration + if (readouts.find("TaggerTrackerHits") != readouts.end()) { + input_track_collections.push_back("TaggerTrackerTracks"); + } + // Add central and other tracks + app->Add(new JOmniFactoryGeneratorT>( + "CombinedTracks", input_track_collections, {"CombinedTracks"}, app)); - std::vector input_track_collections; - //Check size of input_rec_collections to determine if CentralCKFTracks should be added to the input_track_collections - if (input_rec_collections.size() > 0) { - input_track_collections.push_back("CentralCKFTracks"); - } - //Check if the TaggerTracker readout is present in the current configuration - if (readouts.find("TaggerTrackerHits") != readouts.end()) { - input_track_collections.push_back("TaggerTrackerTracks"); - } - - // Add central and other tracks - app->Add(new JOmniFactoryGeneratorT>( - "CombinedTracks", - input_track_collections, - {"CombinedTracks"}, - app - )); - - app->Add(new JOmniFactoryGeneratorT( - "ChargedTruthSeededParticlesWithAssociations", - { - "CentralCKFTruthSeededTracks", - "CentralCKFTruthSeededTrackAssociations", - }, - {"ReconstructedTruthSeededChargedWithoutPIDParticles", - "ReconstructedTruthSeededChargedWithoutPIDParticleAssociations" - }, - {}, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "ChargedTruthSeededParticlesWithAssociations", + { + "CentralCKFTruthSeededTracks", + "CentralCKFTruthSeededTrackAssociations", + }, + {"ReconstructedTruthSeededChargedWithoutPIDParticles", + "ReconstructedTruthSeededChargedWithoutPIDParticleAssociations"}, + {}, app)); - app->Add(new JOmniFactoryGeneratorT( - "ChargedParticlesWithAssociations", - { - "CombinedTracks", - "CentralCKFTrackAssociations", - }, - { - "ReconstructedChargedWithoutPIDParticles", - "ReconstructedChargedWithoutPIDParticleAssociations" - }, - {}, - app - )); + app->Add(new JOmniFactoryGeneratorT( + "ChargedParticlesWithAssociations", + { + "CombinedTracks", + "CentralCKFTrackAssociations", + }, + {"ReconstructedChargedWithoutPIDParticles", + "ReconstructedChargedWithoutPIDParticleAssociations"}, + {}, app)); } } // extern "C" diff --git a/src/services/algorithms_init/AlgorithmsInit_service.h b/src/services/algorithms_init/AlgorithmsInit_service.h index 10b68adcff..a2018ce9f6 100644 --- a/src/services/algorithms_init/AlgorithmsInit_service.h +++ b/src/services/algorithms_init/AlgorithmsInit_service.h @@ -3,7 +3,6 @@ #pragma once - #include #include #include @@ -20,66 +19,65 @@ /** * The AlgorithmsInit_service centralizes use of ServiceSvc */ -class AlgorithmsInit_service : public JService -{ - public: - AlgorithmsInit_service(JApplication *app) { }; - virtual ~AlgorithmsInit_service() { }; +class AlgorithmsInit_service : public JService { +public: + AlgorithmsInit_service(JApplication* app) {}; + virtual ~AlgorithmsInit_service() {}; - void acquire_services(JServiceLocator *srv_locator) override { - auto& serviceSvc = algorithms::ServiceSvc::instance(); + void acquire_services(JServiceLocator* srv_locator) override { + auto& serviceSvc = algorithms::ServiceSvc::instance(); - // Get services - m_log_service = srv_locator->get(); - m_dd4hep_service = srv_locator->get(); + // Get services + m_log_service = srv_locator->get(); + m_dd4hep_service = srv_locator->get(); - // Logger for ServiceSvc - m_log = m_log_service->logger("AlgorithmsInit"); + // Logger for ServiceSvc + m_log = m_log_service->logger("AlgorithmsInit"); - // Register DD4hep_service as algorithms::GeoSvc - [[maybe_unused]] auto& geoSvc = algorithms::GeoSvc::instance(); - serviceSvc.setInit([this](auto&& g) { - this->m_log->debug("Initializing algorithms::GeoSvc"); - g.init(const_cast(this->m_dd4hep_service->detector().get())); - }); + // Register DD4hep_service as algorithms::GeoSvc + [[maybe_unused]] auto& geoSvc = algorithms::GeoSvc::instance(); + serviceSvc.setInit([this](auto&& g) { + this->m_log->debug("Initializing algorithms::GeoSvc"); + g.init(const_cast(this->m_dd4hep_service->detector().get())); + }); - // Register Log_service as algorithms::LogSvc - const algorithms::LogLevel level{ - static_cast(m_log->level())}; - serviceSvc.setInit([this,level](auto&& logger) { - this->m_log->debug("Initializing algorithms::LogSvc"); - logger.init([this](const algorithms::LogLevel l, std::string_view caller, std::string_view msg){ - static std::mutex m; - std::lock_guard lock(m); - // storing the string_view is unsafe since it can become invalid - static std::map> loggers; - if (! loggers.contains(std::string(caller))) { - this->m_log->debug("Initializing algorithms::LogSvc logger {}", caller); - loggers[std::string(caller)] = this->m_log_service->logger(std::string(caller)); - } - loggers[std::string(caller)]->log(static_cast(l), msg); - }); - logger.defaultLevel(level); - }); + // Register Log_service as algorithms::LogSvc + const algorithms::LogLevel level{static_cast(m_log->level())}; + serviceSvc.setInit([this, level](auto&& logger) { + this->m_log->debug("Initializing algorithms::LogSvc"); + logger.init( + [this](const algorithms::LogLevel l, std::string_view caller, std::string_view msg) { + static std::mutex m; + std::lock_guard lock(m); + // storing the string_view is unsafe since it can become invalid + static std::map> loggers; + if (!loggers.contains(std::string(caller))) { + this->m_log->debug("Initializing algorithms::LogSvc logger {}", caller); + loggers[std::string(caller)] = this->m_log_service->logger(std::string(caller)); + } + loggers[std::string(caller)]->log(static_cast(l), msg); + }); + logger.defaultLevel(level); + }); - // Register a random service (JANA2 does not have one) - [[maybe_unused]] auto& randomSvc = algorithms::RandomSvc::instance(); - serviceSvc.setInit([this](auto&& r) { - this->m_log->debug("Initializing algorithms::RandomSvc"); - r.setProperty("seed", static_cast(1)); - r.init(); - }); + // Register a random service (JANA2 does not have one) + [[maybe_unused]] auto& randomSvc = algorithms::RandomSvc::instance(); + serviceSvc.setInit([this](auto&& r) { + this->m_log->debug("Initializing algorithms::RandomSvc"); + r.setProperty("seed", static_cast(1)); + r.init(); + }); - // Register a particle service - [[maybe_unused]] auto& particleSvc = algorithms::ParticleSvc::instance(); + // Register a particle service + [[maybe_unused]] auto& particleSvc = algorithms::ParticleSvc::instance(); - // Finally, initialize the ServiceSvc - serviceSvc.init(); - } + // Finally, initialize the ServiceSvc + serviceSvc.init(); + } - private: - AlgorithmsInit_service() = default; - std::shared_ptr m_log_service; - std::shared_ptr m_dd4hep_service; - std::shared_ptr m_log; +private: + AlgorithmsInit_service() = default; + std::shared_ptr m_log_service; + std::shared_ptr m_dd4hep_service; + std::shared_ptr m_log; }; diff --git a/src/services/algorithms_init/algorithms_init.cc b/src/services/algorithms_init/algorithms_init.cc index e2863d59b7..2c4633e95f 100644 --- a/src/services/algorithms_init/algorithms_init.cc +++ b/src/services/algorithms_init/algorithms_init.cc @@ -6,10 +6,9 @@ #include "AlgorithmsInit_service.h" - extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->ProvideService(std::make_shared(app)); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->ProvideService(std::make_shared(app)); } } diff --git a/src/services/evaluator/evaluator.cc b/src/services/evaluator/evaluator.cc index 5e7ef26554..5bfbd687ac 100644 --- a/src/services/evaluator/evaluator.cc +++ b/src/services/evaluator/evaluator.cc @@ -11,7 +11,7 @@ extern "C" { void InitPlugin(JApplication* app) { InitJANAPlugin(app); - auto& serviceSvc = algorithms::ServiceSvc::instance(); + auto& serviceSvc = algorithms::ServiceSvc::instance(); auto& evaluatorSvc = eicrecon::EvaluatorSvc::instance(); serviceSvc.add(&evaluatorSvc); } diff --git a/src/services/geometry/acts/ACTSGeo_service.cc b/src/services/geometry/acts/ACTSGeo_service.cc index 00010b7c0a..c3ac8f0864 100644 --- a/src/services/geometry/acts/ACTSGeo_service.cc +++ b/src/services/geometry/acts/ACTSGeo_service.cc @@ -29,85 +29,85 @@ ACTSGeo_service::~ACTSGeo_service() {}; //---------------------------------------------------------------- std::shared_ptr ACTSGeo_service::actsGeoProvider() { - try{ - std::call_once(m_init_flag, [this](){ - // Assemble everything on the first call - - if(!m_dd4hepGeo) { - throw JException("ACTSGeo_service m_dd4hepGeo==null which should never be!"); - } - - // Get material map from user parameter - std::string material_map_file; - try { - material_map_file = m_dd4hepGeo->constant("material-map"); - } catch (const std::runtime_error& e) { - material_map_file = "calibrations/materials-map.cbor"; - } - m_app->SetDefaultParameter("acts:MaterialMap", material_map_file, "JSON/CBOR material map file path"); - - // Reading the geometry may take a long time and if the JANA ticker is enabled, it will keep printing - // while no other output is coming which makes it look like something is wrong. Disable the ticker - // while parsing and loading the geometry - auto tickerEnabled = m_app->IsTickerEnabled(); - m_app->SetTicker(false); - - // Create default m_acts_provider - m_acts_provider = std::make_shared(); - - // Set ActsGeometryProvider parameters - bool objWriteIt = m_acts_provider->getObjWriteIt(); - bool plyWriteIt = m_acts_provider->getPlyWriteIt(); - m_app->SetDefaultParameter("acts:WriteObj", objWriteIt, "Write tracking geometry as obj files"); - m_app->SetDefaultParameter("acts:WritePly", plyWriteIt, "Write tracking geometry as ply files"); - m_acts_provider->setObjWriteIt(objWriteIt); - m_acts_provider->setPlyWriteIt(plyWriteIt); - - std::string outputTag = m_acts_provider->getOutputTag(); - std::string outputDir = m_acts_provider->getOutputDir(); - m_app->SetDefaultParameter("acts:OutputTag", outputTag, "Obj and ply output file tag"); - m_app->SetDefaultParameter("acts:OutputDir", outputDir, "Obj and ply output file dir"); - m_acts_provider->setOutputTag(outputTag); - m_acts_provider->setOutputDir(outputDir); - - std::array containerView = m_acts_provider->getContainerView().color; - std::array volumeView = m_acts_provider->getVolumeView().color; - std::array sensitiveView = m_acts_provider->getSensitiveView().color; - std::array passiveView = m_acts_provider->getPassiveView().color; - std::array gridView = m_acts_provider->getGridView().color; - m_app->SetDefaultParameter("acts:ContainerView", containerView, "RGB for container views"); - m_app->SetDefaultParameter("acts:VolumeView", volumeView, "RGB for volume views"); - m_app->SetDefaultParameter("acts:SensitiveView", sensitiveView, "RGB for sensitive views"); - m_app->SetDefaultParameter("acts:PassiveView", passiveView, "RGB for passive views"); - m_app->SetDefaultParameter("acts:GridView", gridView, "RGB for grid views"); - m_acts_provider->setContainerView(containerView); - m_acts_provider->setVolumeView(volumeView); - m_acts_provider->setSensitiveView(sensitiveView); - m_acts_provider->setPassiveView(passiveView); - m_acts_provider->setGridView(gridView); - - // Initialize m_acts_provider - m_acts_provider->initialize(m_dd4hepGeo, material_map_file, m_log, m_log); - - // Enable ticker back - m_app->SetTicker(tickerEnabled); - }); - } - catch (std::exception &ex) { - throw JException(ex.what()); - } - - return m_acts_provider; + try { + std::call_once(m_init_flag, [this]() { + // Assemble everything on the first call + + if (!m_dd4hepGeo) { + throw JException("ACTSGeo_service m_dd4hepGeo==null which should never be!"); + } + + // Get material map from user parameter + std::string material_map_file; + try { + material_map_file = m_dd4hepGeo->constant("material-map"); + } catch (const std::runtime_error& e) { + material_map_file = "calibrations/materials-map.cbor"; + } + m_app->SetDefaultParameter("acts:MaterialMap", material_map_file, + "JSON/CBOR material map file path"); + + // Reading the geometry may take a long time and if the JANA ticker is enabled, it will keep printing + // while no other output is coming which makes it look like something is wrong. Disable the ticker + // while parsing and loading the geometry + auto tickerEnabled = m_app->IsTickerEnabled(); + m_app->SetTicker(false); + + // Create default m_acts_provider + m_acts_provider = std::make_shared(); + + // Set ActsGeometryProvider parameters + bool objWriteIt = m_acts_provider->getObjWriteIt(); + bool plyWriteIt = m_acts_provider->getPlyWriteIt(); + m_app->SetDefaultParameter("acts:WriteObj", objWriteIt, + "Write tracking geometry as obj files"); + m_app->SetDefaultParameter("acts:WritePly", plyWriteIt, + "Write tracking geometry as ply files"); + m_acts_provider->setObjWriteIt(objWriteIt); + m_acts_provider->setPlyWriteIt(plyWriteIt); + + std::string outputTag = m_acts_provider->getOutputTag(); + std::string outputDir = m_acts_provider->getOutputDir(); + m_app->SetDefaultParameter("acts:OutputTag", outputTag, "Obj and ply output file tag"); + m_app->SetDefaultParameter("acts:OutputDir", outputDir, "Obj and ply output file dir"); + m_acts_provider->setOutputTag(outputTag); + m_acts_provider->setOutputDir(outputDir); + + std::array containerView = m_acts_provider->getContainerView().color; + std::array volumeView = m_acts_provider->getVolumeView().color; + std::array sensitiveView = m_acts_provider->getSensitiveView().color; + std::array passiveView = m_acts_provider->getPassiveView().color; + std::array gridView = m_acts_provider->getGridView().color; + m_app->SetDefaultParameter("acts:ContainerView", containerView, "RGB for container views"); + m_app->SetDefaultParameter("acts:VolumeView", volumeView, "RGB for volume views"); + m_app->SetDefaultParameter("acts:SensitiveView", sensitiveView, "RGB for sensitive views"); + m_app->SetDefaultParameter("acts:PassiveView", passiveView, "RGB for passive views"); + m_app->SetDefaultParameter("acts:GridView", gridView, "RGB for grid views"); + m_acts_provider->setContainerView(containerView); + m_acts_provider->setVolumeView(volumeView); + m_acts_provider->setSensitiveView(sensitiveView); + m_acts_provider->setPassiveView(passiveView); + m_acts_provider->setGridView(gridView); + + // Initialize m_acts_provider + m_acts_provider->initialize(m_dd4hepGeo, material_map_file, m_log, m_log); + + // Enable ticker back + m_app->SetTicker(tickerEnabled); + }); + } catch (std::exception& ex) { + throw JException(ex.what()); + } + + return m_acts_provider; } +void ACTSGeo_service::acquire_services(JServiceLocator* srv_locator) { + auto log_service = srv_locator->get(); + m_log = log_service->logger("acts"); -void ACTSGeo_service::acquire_services(JServiceLocator * srv_locator) { - - auto log_service = srv_locator->get(); - m_log = log_service->logger("acts"); - - // DD4Hep geometry - auto dd4hep_service = srv_locator->get(); - m_dd4hepGeo = dd4hep_service->detector(); + // DD4Hep geometry + auto dd4hep_service = srv_locator->get(); + m_dd4hepGeo = dd4hep_service->detector(); } diff --git a/src/services/geometry/acts/ACTSGeo_service.h b/src/services/geometry/acts/ACTSGeo_service.h index 1822a762a8..445825cfcc 100644 --- a/src/services/geometry/acts/ACTSGeo_service.h +++ b/src/services/geometry/acts/ACTSGeo_service.h @@ -12,27 +12,23 @@ #include "algorithms/tracking/ActsGeometryProvider.h" - -class ACTSGeo_service : public JService -{ +class ACTSGeo_service : public JService { public: - ACTSGeo_service( JApplication *app ) : m_app(app) {} - virtual ~ACTSGeo_service(); + ACTSGeo_service(JApplication* app) : m_app(app) {} + virtual ~ACTSGeo_service(); - virtual std::shared_ptr actsGeoProvider(); + virtual std::shared_ptr actsGeoProvider(); protected: - - private: - ACTSGeo_service()=default; - void acquire_services(JServiceLocator *) override; + ACTSGeo_service() = default; + void acquire_services(JServiceLocator*) override; - std::once_flag m_init_flag; - JApplication *m_app = nullptr; - const dd4hep::Detector* m_dd4hepGeo = nullptr; - std::shared_ptr m_acts_provider; + std::once_flag m_init_flag; + JApplication* m_app = nullptr; + const dd4hep::Detector* m_dd4hepGeo = nullptr; + std::shared_ptr m_acts_provider; - // General acts log - std::shared_ptr m_log; + // General acts log + std::shared_ptr m_log; }; diff --git a/src/services/geometry/acts/acts.cc b/src/services/geometry/acts/acts.cc index a0e9c7f104..271136c222 100644 --- a/src/services/geometry/acts/acts.cc +++ b/src/services/geometry/acts/acts.cc @@ -9,8 +9,8 @@ #include "ACTSGeo_service.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->ProvideService(std::make_shared(app) ); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->ProvideService(std::make_shared(app)); } } diff --git a/src/services/geometry/dd4hep/DD4hep_service.cc b/src/services/geometry/dd4hep/DD4hep_service.cc index 73eb0a42ae..b13b4e08c4 100644 --- a/src/services/geometry/dd4hep/DD4hep_service.cc +++ b/src/services/geometry/dd4hep/DD4hep_service.cc @@ -23,28 +23,31 @@ //---------------------------------------------------------------- // Services //---------------------------------------------------------------- -void DD4hep_service::acquire_services(JServiceLocator *srv_locator) { - // logging service - auto log_service = srv_locator->get(); - m_log = log_service->logger("dd4hep"); - - // Set the DD4hep print level to be quieter by default, but let user adjust it - std::string print_level_str{"WARNING"}; - m_app->SetDefaultParameter("dd4hep:print_level", print_level_str, "Set DD4hep print level (see DD4hep/Printout.h)"); - dd4hep::setPrintLevel(dd4hep::decodePrintLevel(print_level_str)); - - // Set the TGeoManager verbose level (lower dd4hep level is more verbose) - TGeoManager::SetVerboseLevel(dd4hep::printLevel() <= dd4hep::PrintLevel::INFO ? 1 : 0); +void DD4hep_service::acquire_services(JServiceLocator* srv_locator) { + // logging service + auto log_service = srv_locator->get(); + m_log = log_service->logger("dd4hep"); + + // Set the DD4hep print level to be quieter by default, but let user adjust it + std::string print_level_str{"WARNING"}; + m_app->SetDefaultParameter("dd4hep:print_level", print_level_str, + "Set DD4hep print level (see DD4hep/Printout.h)"); + dd4hep::setPrintLevel(dd4hep::decodePrintLevel(print_level_str)); + + // Set the TGeoManager verbose level (lower dd4hep level is more verbose) + TGeoManager::SetVerboseLevel(dd4hep::printLevel() <= dd4hep::PrintLevel::INFO ? 1 : 0); } //---------------------------------------------------------------- // destructor //---------------------------------------------------------------- -DD4hep_service::~DD4hep_service(){ - try { - if(m_dd4hepGeo) m_dd4hepGeo->destroyInstance(); - m_dd4hepGeo = nullptr; - } catch (...) {} +DD4hep_service::~DD4hep_service() { + try { + if (m_dd4hepGeo) + m_dd4hepGeo->destroyInstance(); + m_dd4hepGeo = nullptr; + } catch (...) { + } } //---------------------------------------------------------------- @@ -53,10 +56,9 @@ DD4hep_service::~DD4hep_service(){ /// Return pointer to the dd4hep::Detector object. /// Call Initialize if needed. //---------------------------------------------------------------- -gsl::not_null -DD4hep_service::detector() { - std::call_once(init_flag, &DD4hep_service::Initialize, this); - return m_dd4hepGeo.get(); +gsl::not_null DD4hep_service::detector() { + std::call_once(init_flag, &DD4hep_service::Initialize, this); + return m_dd4hepGeo.get(); } //---------------------------------------------------------------- @@ -65,10 +67,9 @@ DD4hep_service::detector() { /// Return pointer to the cellIDPositionConverter object. /// Call Initialize if needed. //---------------------------------------------------------------- -gsl::not_null -DD4hep_service::converter() { - std::call_once(init_flag, &DD4hep_service::Initialize, this); - return m_cellid_converter.get(); +gsl::not_null DD4hep_service::converter() { + std::call_once(init_flag, &DD4hep_service::Initialize, this); + return m_cellid_converter.get(); } //---------------------------------------------------------------- @@ -81,100 +82,108 @@ DD4hep_service::converter() { //---------------------------------------------------------------- void DD4hep_service::Initialize() { - if (m_dd4hepGeo) { - m_log->warn("DD4hep_service already initialized!"); + if (m_dd4hepGeo) { + m_log->warn("DD4hep_service already initialized!"); + } + + // The current recommended way of getting the XML file is to use the environment variables + // DETECTOR_PATH and DETECTOR_CONFIG. + // Look for those first, so we can use it for the default + // config parameter. + auto* detector_config_env = std::getenv("DETECTOR_CONFIG"); + auto* detector_path_env = std::getenv("DETECTOR_PATH"); + + std::string detector_config; + // Check if detector_config_env is set + if (detector_config_env != nullptr) { + detector_config = detector_config_env; + } + + // do we have default file name + if (!detector_config.empty()) { + m_xml_files.push_back(std::string(detector_path_env ? detector_path_env : ".") + "/" + + detector_config + ".xml"); + } + + // User may specify multiple geometry files via the config. parameter. Normally, this + // will be a single file which itself has includes for other files. + m_app->SetDefaultParameter("dd4hep:xml_files", m_xml_files, + "Comma separated list of XML files describing the DD4hep geometry. " + "(Defaults to ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml using envars.)"); + + if (m_xml_files.empty()) { + m_log->error("No dd4hep XML file specified for the geometry!"); + m_log->error("Set your DETECTOR_PATH and DETECTOR_CONFIG environment variables"); + m_log->error("(the latter is typically done by sourcing the thisepic.sh"); + m_log->error("script the epic directory.)"); + throw std::runtime_error("No dd4hep XML file specified."); + } + + // Reading the geometry may take a long time and if the JANA ticker is enabled, it will keep printing + // while no other output is coming which makes it look like something is wrong. Disable the ticker + // while parsing and loading the geometry + auto tickerEnabled = m_app->IsTickerEnabled(); + m_app->SetTicker(false); + + // load geometry + auto detector = dd4hep::Detector::make_unique(""); + try { + m_log->info("Loading DD4hep geometry from {} files", m_xml_files.size()); + for (auto& filename : m_xml_files) { + + auto resolved_filename = resolveFileName(filename, detector_path_env); + + m_log->info(" - loading geometry file: '{}' (patience ....)", resolved_filename); + try { + detector->fromCompact(resolved_filename); + } catch ( + std::runtime_error& e) { // dd4hep throws std::runtime_error, no way to detail further + throw JException(e.what()); + } } - - // The current recommended way of getting the XML file is to use the environment variables - // DETECTOR_PATH and DETECTOR_CONFIG. - // Look for those first, so we can use it for the default - // config parameter. - auto *detector_config_env = std::getenv("DETECTOR_CONFIG"); - auto *detector_path_env = std::getenv("DETECTOR_PATH"); - - std::string detector_config; - // Check if detector_config_env is set - if(detector_config_env != nullptr) { - detector_config = detector_config_env; - } - - // do we have default file name - if(!detector_config.empty()) { - m_xml_files.push_back(std::string(detector_path_env ? detector_path_env : ".") + "/" + detector_config + ".xml"); - } - - // User may specify multiple geometry files via the config. parameter. Normally, this - // will be a single file which itself has includes for other files. - m_app->SetDefaultParameter("dd4hep:xml_files", m_xml_files, "Comma separated list of XML files describing the DD4hep geometry. (Defaults to ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml using envars.)"); - - if( m_xml_files.empty() ){ - m_log->error("No dd4hep XML file specified for the geometry!"); - m_log->error("Set your DETECTOR_PATH and DETECTOR_CONFIG environment variables"); - m_log->error("(the latter is typically done by sourcing the thisepic.sh"); - m_log->error("script the epic directory.)"); - throw std::runtime_error("No dd4hep XML file specified."); - } - - // Reading the geometry may take a long time and if the JANA ticker is enabled, it will keep printing - // while no other output is coming which makes it look like something is wrong. Disable the ticker - // while parsing and loading the geometry - auto tickerEnabled = m_app->IsTickerEnabled(); - m_app->SetTicker( false ); - - // load geometry - auto detector = dd4hep::Detector::make_unique(""); - try { - m_log->info("Loading DD4hep geometry from {} files", m_xml_files.size()); - for (auto &filename : m_xml_files) { - - auto resolved_filename = resolveFileName(filename, detector_path_env); - - m_log->info(" - loading geometry file: '{}' (patience ....)", resolved_filename); - try { - detector->fromCompact(resolved_filename); - } catch(std::runtime_error &e) { // dd4hep throws std::runtime_error, no way to detail further - throw JException(e.what()); - } - } - detector->volumeManager(); - detector->apply("DD4hepVolumeManager", 0, nullptr); - m_cellid_converter = std::make_unique(*detector); - m_dd4hepGeo = std::move(detector); // const - - m_log->info("Geometry successfully loaded."); - } catch(std::exception &e) { - m_log->error("Problem loading geometry: {}", e.what()); - throw std::runtime_error(fmt::format("Problem loading geometry: {}", e.what())); - } - - // Restore the ticker setting - m_app->SetTicker( tickerEnabled ); + detector->volumeManager(); + detector->apply("DD4hepVolumeManager", 0, nullptr); + m_cellid_converter = std::make_unique(*detector); + m_dd4hepGeo = std::move(detector); // const + + m_log->info("Geometry successfully loaded."); + } catch (std::exception& e) { + m_log->error("Problem loading geometry: {}", e.what()); + throw std::runtime_error(fmt::format("Problem loading geometry: {}", e.what())); + } + + // Restore the ticker setting + m_app->SetTicker(tickerEnabled); } -std::string DD4hep_service::resolveFileName(const std::string &filename, char *detector_path_env) { - - std::string result(filename); - - // Check that this XML file actually exists. - if( ! std::filesystem::exists(result) ){ - - // filename does not exist, maybe DETECTOR_PATH/filename is meant? - if(detector_path_env) { - - // Try looking filename in DETECTOR_PATH - result = std::string(detector_path_env) + "/" + filename; - - if( ! std::filesystem::exists(result) ) { - // Here we go against the standard practice of throwing an error and print - // the message and exit immediately. This is because we want the last message - // on the screen to be that this file doesn't exist. - auto mess = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), "ERROR: "); - mess += fmt::format(fmt::emphasis::bold, "file: {} does not exist!", filename); - mess += "\nCheck that your DETECTOR_PATH and DETECTOR_CONFIG environment variables are set correctly."; - std::cerr << std::endl << std::endl << mess << std::endl << std::endl; // TODO standard log here! - std::_Exit(EXIT_FAILURE); - } - } +std::string DD4hep_service::resolveFileName(const std::string& filename, char* detector_path_env) { + + std::string result(filename); + + // Check that this XML file actually exists. + if (!std::filesystem::exists(result)) { + + // filename does not exist, maybe DETECTOR_PATH/filename is meant? + if (detector_path_env) { + + // Try looking filename in DETECTOR_PATH + result = std::string(detector_path_env) + "/" + filename; + + if (!std::filesystem::exists(result)) { + // Here we go against the standard practice of throwing an error and print + // the message and exit immediately. This is because we want the last message + // on the screen to be that this file doesn't exist. + auto mess = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), "ERROR: "); + mess += fmt::format(fmt::emphasis::bold, "file: {} does not exist!", filename); + mess += "\nCheck that your DETECTOR_PATH and DETECTOR_CONFIG environment variables are set " + "correctly."; + std::cerr << std::endl + << std::endl + << mess << std::endl + << std::endl; // TODO standard log here! + std::_Exit(EXIT_FAILURE); + } } - return result; + } + return result; } diff --git a/src/services/geometry/dd4hep/DD4hep_service.h b/src/services/geometry/dd4hep/DD4hep_service.h index e71a976be0..57baf36fba 100644 --- a/src/services/geometry/dd4hep/DD4hep_service.h +++ b/src/services/geometry/dd4hep/DD4hep_service.h @@ -15,30 +15,29 @@ #include #include -class DD4hep_service : public JService -{ +class DD4hep_service : public JService { public: - DD4hep_service( JApplication *app ) : m_app(app) {} - virtual ~DD4hep_service(); + DD4hep_service(JApplication* app) : m_app(app) {} + virtual ~DD4hep_service(); - virtual gsl::not_null detector(); - virtual gsl::not_null converter(); + virtual gsl::not_null detector(); + virtual gsl::not_null converter(); protected: - void Initialize(); + void Initialize(); private: - DD4hep_service() = default; - void acquire_services(JServiceLocator *) override; + DD4hep_service() = default; + void acquire_services(JServiceLocator*) override; - std::once_flag init_flag; - JApplication *m_app = nullptr; - std::unique_ptr m_dd4hepGeo = nullptr; - std::unique_ptr m_cellid_converter = nullptr; - std::vector m_xml_files; + std::once_flag init_flag; + JApplication* m_app = nullptr; + std::unique_ptr m_dd4hepGeo = nullptr; + std::unique_ptr m_cellid_converter = nullptr; + std::vector m_xml_files; - /// Ensures there is a geometry file that should be opened - std::string resolveFileName(const std::string &filename, char *detector_path_env); + /// Ensures there is a geometry file that should be opened + std::string resolveFileName(const std::string& filename, char* detector_path_env); - std::shared_ptr m_log; + std::shared_ptr m_log; }; diff --git a/src/services/geometry/dd4hep/dd4hep.cc b/src/services/geometry/dd4hep/dd4hep.cc index 90ef62bfbc..72d9f69333 100644 --- a/src/services/geometry/dd4hep/dd4hep.cc +++ b/src/services/geometry/dd4hep/dd4hep.cc @@ -9,8 +9,8 @@ #include "DD4hep_service.h" extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->ProvideService(std::make_shared(app) ); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->ProvideService(std::make_shared(app)); } } diff --git a/src/services/geometry/richgeo/ActsGeo.cc b/src/services/geometry/richgeo/ActsGeo.cc index 74706fa37d..0c22ac051c 100644 --- a/src/services/geometry/richgeo/ActsGeo.cc +++ b/src/services/geometry/richgeo/ActsGeo.cc @@ -17,9 +17,9 @@ #include "services/geometry/richgeo/RichGeo.h" // constructor -richgeo::ActsGeo::ActsGeo(std::string detName_, gsl::not_null det_, std::shared_ptr log_) - : m_detName(detName_), m_det(det_), m_log(log_) -{ +richgeo::ActsGeo::ActsGeo(std::string detName_, gsl::not_null det_, + std::shared_ptr log_) + : m_detName(detName_), m_det(det_), m_log(log_) { // capitalize m_detName std::transform(m_detName.begin(), m_detName.end(), m_detName.begin(), ::toupper); } @@ -31,7 +31,7 @@ std::vector richgeo::ActsGeo::TrackingPlanes(int radiat std::vector discs; // dRICH DD4hep-ACTS bindings -------------------------------------------------------------------- - if(m_detName=="DRICH") { + if (m_detName == "DRICH") { // vessel constants auto zmin = m_det->constant("DRICH_zmin"); @@ -57,26 +57,28 @@ std::vector richgeo::ActsGeo::TrackingPlanes(int radiat // get z and radial limits where we will expect charged particles in the RICH double trackZmin, trackZmax; std::function trackRmin, trackRmax; - switch(radiator) { - case kAerogel: - trackZmin = aerogelZpos - aerogelThickness/2; - trackZmax = aerogelZpos + aerogelThickness/2; - trackRmax = [&] (auto z) { return rmax0 + snoutSlope * (z - zmin); }; - break; - case kGas: - trackZmin = filterZpos + filterThickness/2; - trackZmax = zmax - window_thickness; - trackRmax = [&] (auto z) { - auto z0 = z - zmin; - if(z0 < snoutLength) return rmax0 + snoutSlope * z0; - else return rmax2; - }; - break; - default: - m_log->error("unknown radiator number {}",numPlanes); - return discs; + switch (radiator) { + case kAerogel: + trackZmin = aerogelZpos - aerogelThickness / 2; + trackZmax = aerogelZpos + aerogelThickness / 2; + trackRmax = [&](auto z) { return rmax0 + snoutSlope * (z - zmin); }; + break; + case kGas: + trackZmin = filterZpos + filterThickness / 2; + trackZmax = zmax - window_thickness; + trackRmax = [&](auto z) { + auto z0 = z - zmin; + if (z0 < snoutLength) + return rmax0 + snoutSlope * z0; + else + return rmax2; + }; + break; + default: + m_log->error("unknown radiator number {}", numPlanes); + return discs; } - trackRmin = [&] (auto z) { return rmin0 + boreSlope * (z - zmin); }; + trackRmin = [&](auto z) { return rmin0 + boreSlope * (z - zmin); }; // define discs: `numPlanes` z-equidistant planes *within* the radiator; /* NOTE: do not allow planes to be at radiator boundary @@ -103,24 +105,25 @@ std::vector richgeo::ActsGeo::TrackingPlanes(int radiat * trackZStep */ m_log->debug("Define ACTS disks for {} radiator: {} disks in z=[ {}, {} ]", - RadiatorName(radiator), numPlanes, trackZmin, trackZmax); - double trackZstep = std::abs(trackZmax-trackZmin) / (numPlanes+1); - for(int i=0; idebug(" disk {}: z={} r=[ {}, {} ]", i, z, rmin, rmax); } } // pfRICH DD4hep-ACTS bindings -------------------------------------------------------------------- - else if(m_detName=="PFRICH") { + else if (m_detName == "PFRICH") { m_log->error("TODO: pfRICH DD4hep-ACTS bindings have not yet been implemented"); } // ------------------------------------------------------------------------------------------------ - else m_log->error("ActsGeo is not defined for detector '{}'",m_detName); + else + m_log->error("ActsGeo is not defined for detector '{}'", m_detName); return discs; } @@ -130,27 +133,22 @@ std::function richgeo::ActsGeo::TrackPointCut(int rad // reject track points in dRICH gas that are beyond the dRICH mirrors // FIXME: assumes the full mirror spheres are much bigger than the dRICH // FIXME: needs to be generalized for dual or multi-mirror (per sector) design - if(m_detName=="DRICH" && radiator==kGas) { + if (m_detName == "DRICH" && radiator == kGas) { // get sphere centers std::vector mirror_centers; - for(int isec = 0; isec < m_det->constant("DRICH_num_sectors"); isec++) + for (int isec = 0; isec < m_det->constant("DRICH_num_sectors"); isec++) mirror_centers.emplace_back( m_det->constant("DRICH_mirror_center_x_sec" + std::to_string(isec)) / dd4hep::mm, m_det->constant("DRICH_mirror_center_y_sec" + std::to_string(isec)) / dd4hep::mm, - m_det->constant("DRICH_mirror_center_z_sec" + std::to_string(isec)) / dd4hep::mm - ); + m_det->constant("DRICH_mirror_center_z_sec" + std::to_string(isec)) / dd4hep::mm); auto mirror_radius = m_det->constant("DRICH_mirror_radius") / dd4hep::mm; // beyond the mirror cut - return [mirror_centers, mirror_radius] (edm4eic::TrackPoint p) { - for(const auto& c : mirror_centers) { - auto dist = std::hypot( - c.x() - p.position.x, - c.y() - p.position.y, - c.z() - p.position.z - ); - if(dist < mirror_radius) + return [mirror_centers, mirror_radius](edm4eic::TrackPoint p) { + for (const auto& c : mirror_centers) { + auto dist = std::hypot(c.x() - p.position.x, c.y() - p.position.y, c.z() - p.position.z); + if (dist < mirror_radius) return true; } return false; @@ -158,6 +156,5 @@ std::function richgeo::ActsGeo::TrackPointCut(int rad } // otherwise return a cut which always passes - return [] (edm4eic::TrackPoint p) { return true; }; - + return [](edm4eic::TrackPoint p) { return true; }; } diff --git a/src/services/geometry/richgeo/ActsGeo.h b/src/services/geometry/richgeo/ActsGeo.h index 7fcf4e4324..abd13ad50c 100644 --- a/src/services/geometry/richgeo/ActsGeo.h +++ b/src/services/geometry/richgeo/ActsGeo.h @@ -16,26 +16,24 @@ #include "algorithms/tracking/TrackPropagationConfig.h" namespace richgeo { - class ActsGeo { - public: - - // constructor and destructor - ActsGeo(std::string detName_, gsl::not_null det_, std::shared_ptr log_); - ~ActsGeo() {} - - // generate list ACTS disc surfaces, for a given radiator - std::vector TrackingPlanes(int radiator, int numPlanes); - - // generate a cut to remove any track points that should not be used - std::function TrackPointCut(int radiator); - - protected: - - std::string m_detName; - gsl::not_null m_det; - std::shared_ptr m_log; - - private: - - }; -} +class ActsGeo { +public: + // constructor and destructor + ActsGeo(std::string detName_, gsl::not_null det_, + std::shared_ptr log_); + ~ActsGeo() {} + + // generate list ACTS disc surfaces, for a given radiator + std::vector TrackingPlanes(int radiator, int numPlanes); + + // generate a cut to remove any track points that should not be used + std::function TrackPointCut(int radiator); + +protected: + std::string m_detName; + gsl::not_null m_det; + std::shared_ptr m_log; + +private: +}; +} // namespace richgeo diff --git a/src/services/geometry/richgeo/IrtGeo.cc b/src/services/geometry/richgeo/IrtGeo.cc index f2a1f7fce1..4d1d568445 100644 --- a/src/services/geometry/richgeo/IrtGeo.cc +++ b/src/services/geometry/richgeo/IrtGeo.cc @@ -21,9 +21,10 @@ #include "services/geometry/richgeo/RichGeo.h" // constructor: creates IRT-DD4hep bindings using main `Detector` handle `*det_` -richgeo::IrtGeo::IrtGeo(std::string detName_, gsl::not_null det_, gsl::not_null conv_, std::shared_ptr log_) : - m_detName(detName_), m_det(det_), m_converter(conv_), m_log(log_) -{ +richgeo::IrtGeo::IrtGeo(std::string detName_, gsl::not_null det_, + gsl::not_null conv_, + std::shared_ptr log_) + : m_detName(detName_), m_det(det_), m_converter(conv_), m_log(log_) { Bind(); } @@ -36,54 +37,55 @@ void richgeo::IrtGeo::Bind() { // IRT geometry handles m_irtDetectorCollection = new CherenkovDetectorCollection(); - m_irtDetector = m_irtDetectorCollection->AddNewDetector(m_detName.c_str()); + m_irtDetector = m_irtDetectorCollection->AddNewDetector(m_detName.c_str()); } // ------------------------------------------------ // define the `cell ID -> pixel position` converter, correcting to sensor surface void richgeo::IrtGeo::SetReadoutIDToPositionLambda() { - m_irtDetector->m_ReadoutIDToPosition = [ - &m_log = this->m_log, // capture logger by reference - // capture instance members by value, so those owned by `this` are not mutable here - cell_mask = this->m_irtDetector->GetReadoutCellMask(), - converter = this->m_converter, - sensor_info = this->m_sensor_info - ] (auto cell_id) { - // decode cell ID to get the sensor ID and pixel volume centroid - auto sensor_id = cell_id & cell_mask; - auto pixel_volume_centroid = (1/dd4hep::mm) * converter->position(cell_id); - // get sensor info - auto sensor_info_it = sensor_info.find(sensor_id); - if(sensor_info_it == sensor_info.end()) { - m_log->warn("cannot find sensor ID {} in IrtGeo; using pixel volume centroid instead",sensor_id); - return TVector3( pixel_volume_centroid.x(), pixel_volume_centroid.y(), pixel_volume_centroid.z()); - } - auto sensor_obj = sensor_info_it->second; - // get pixel surface centroid, given sensor surface offset w.r.t centroid - auto pixel_surface_centroid = pixel_volume_centroid + sensor_obj.surface_offset; - // cross check: make sure pixel and sensor surface centroids are close enough - auto dist = sqrt((pixel_surface_centroid - sensor_obj.surface_centroid).Mag2()); - if( dist > sensor_obj.size / sqrt(2) ) - m_log->warn("dist(pixel,sensor) is too large: {} mm",dist); - return TVector3( pixel_surface_centroid.x(), pixel_surface_centroid.y(), pixel_surface_centroid.z()); - }; - + m_irtDetector->m_ReadoutIDToPosition = + [&m_log = this->m_log, // capture logger by reference + // capture instance members by value, so those owned by `this` are not mutable here + cell_mask = this->m_irtDetector->GetReadoutCellMask(), converter = this->m_converter, + sensor_info = this->m_sensor_info](auto cell_id) { + // decode cell ID to get the sensor ID and pixel volume centroid + auto sensor_id = cell_id & cell_mask; + auto pixel_volume_centroid = (1 / dd4hep::mm) * converter->position(cell_id); + // get sensor info + auto sensor_info_it = sensor_info.find(sensor_id); + if (sensor_info_it == sensor_info.end()) { + m_log->warn("cannot find sensor ID {} in IrtGeo; using pixel volume centroid instead", + sensor_id); + return TVector3(pixel_volume_centroid.x(), pixel_volume_centroid.y(), + pixel_volume_centroid.z()); + } + auto sensor_obj = sensor_info_it->second; + // get pixel surface centroid, given sensor surface offset w.r.t centroid + auto pixel_surface_centroid = pixel_volume_centroid + sensor_obj.surface_offset; + // cross check: make sure pixel and sensor surface centroids are close enough + auto dist = sqrt((pixel_surface_centroid - sensor_obj.surface_centroid).Mag2()); + if (dist > sensor_obj.size / sqrt(2)) + m_log->warn("dist(pixel,sensor) is too large: {} mm", dist); + return TVector3(pixel_surface_centroid.x(), pixel_surface_centroid.y(), + pixel_surface_centroid.z()); + }; } // ------------------------------------------------ // fill table of refractive indices void richgeo::IrtGeo::SetRefractiveIndexTable() { - m_log->debug("{:-^60}"," Refractive Index Tables "); - for(auto rad_obj : m_irtDetector->Radiators()) { + m_log->debug("{:-^60}", " Refractive Index Tables "); + for (auto rad_obj : m_irtDetector->Radiators()) { m_log->debug("{}:", rad_obj.first.Data()); - auto *const rad = rad_obj.second; - const auto *rindex_matrix = m_det->material(rad->GetAlternativeMaterialName()).property("RINDEX"); - for(unsigned row=0; rowGetRows(); row++) { - auto energy = rindex_matrix->Get(row,0) / dd4hep::eV; - auto rindex = rindex_matrix->Get(row,1); + auto* const rad = rad_obj.second; + const auto* rindex_matrix = + m_det->material(rad->GetAlternativeMaterialName()).property("RINDEX"); + for (unsigned row = 0; row < rindex_matrix->GetRows(); row++) { + auto energy = rindex_matrix->Get(row, 0) / dd4hep::eV; + auto rindex = rindex_matrix->Get(row, 1); m_log->debug(" {:>5} eV {:<}", energy, rindex); - rad->m_ri_lookup_table.emplace_back(energy,rindex); + rad->m_ri_lookup_table.emplace_back(energy, rindex); } } } diff --git a/src/services/geometry/richgeo/IrtGeo.h b/src/services/geometry/richgeo/IrtGeo.h index 8d930b081e..802f1e1c50 100644 --- a/src/services/geometry/richgeo/IrtGeo.h +++ b/src/services/geometry/richgeo/IrtGeo.h @@ -23,50 +23,51 @@ #include "RichGeo.h" namespace richgeo { - class IrtGeo { - public: +class IrtGeo { +public: + // constructor: creates IRT-DD4hep bindings using main `Detector` handle `*det_` + IrtGeo(std::string detName_, gsl::not_null det_, + gsl::not_null conv_, + std::shared_ptr log_); + virtual ~IrtGeo(); - // constructor: creates IRT-DD4hep bindings using main `Detector` handle `*det_` - IrtGeo(std::string detName_, gsl::not_null det_, gsl::not_null conv_, std::shared_ptr log_); - virtual ~IrtGeo(); + // access the full IRT geometry + CherenkovDetectorCollection* GetIrtDetectorCollection() { return m_irtDetectorCollection; } - // access the full IRT geometry - CherenkovDetectorCollection *GetIrtDetectorCollection() { return m_irtDetectorCollection; } +protected: + // protected methods + virtual void DD4hep_to_IRT() = 0; // given DD4hep geometry, produce IRT geometry + void + SetReadoutIDToPositionLambda(); // define the `cell ID -> pixel position` converter, correcting to sensor surface + void SetRefractiveIndexTable(); // fill table of refractive indices + // read `VariantParameters` for a vector + template + VecT GetVectorFromVariantParameters(dd4hep::rec::VariantParameters* pars, std::string key) { + return VecT(pars->get(key + "_x"), pars->get(key + "_y"), + pars->get(key + "_z")); + } - protected: + // inputs + std::string m_detName; - // protected methods - virtual void DD4hep_to_IRT() = 0; // given DD4hep geometry, produce IRT geometry - void SetReadoutIDToPositionLambda(); // define the `cell ID -> pixel position` converter, correcting to sensor surface - void SetRefractiveIndexTable(); // fill table of refractive indices - // read `VariantParameters` for a vector - template - VecT GetVectorFromVariantParameters(dd4hep::rec::VariantParameters *pars, std::string key) { - return VecT(pars->get(key+"_x"), pars->get(key+"_y"), pars->get(key+"_z")); - } + // DD4hep geometry handles + gsl::not_null m_det; + dd4hep::DetElement m_detRich; + dd4hep::Position m_posRich; - // inputs - std::string m_detName; + // cell ID conversion + gsl::not_null m_converter; + std::unordered_map m_sensor_info; // sensor ID -> sensor info - // DD4hep geometry handles - gsl::not_null m_det; - dd4hep::DetElement m_detRich; - dd4hep::Position m_posRich; + // IRT geometry handles + CherenkovDetectorCollection* m_irtDetectorCollection; + CherenkovDetector* m_irtDetector; - // cell ID conversion - gsl::not_null m_converter; - std::unordered_map m_sensor_info; // sensor ID -> sensor info + // logger + std::shared_ptr m_log; - // IRT geometry handles - CherenkovDetectorCollection *m_irtDetectorCollection; - CherenkovDetector *m_irtDetector; - - // logger - std::shared_ptr m_log; - - private: - - // set all geometry handles - void Bind(); - }; -} +private: + // set all geometry handles + void Bind(); +}; +} // namespace richgeo diff --git a/src/services/geometry/richgeo/IrtGeoDRICH.cc b/src/services/geometry/richgeo/IrtGeoDRICH.cc index d6f4cf1848..e21fc1901d 100644 --- a/src/services/geometry/richgeo/IrtGeoDRICH.cc +++ b/src/services/geometry/richgeo/IrtGeoDRICH.cc @@ -36,31 +36,31 @@ void richgeo::IrtGeoDRICH::DD4hep_to_IRT() { auto vesselZmin = m_det->constant("DRICH_zmin") / dd4hep::mm; auto vesselWindowThickness = m_det->constant("DRICH_window_thickness") / dd4hep::mm; auto gasvolMaterial = m_det->constant("DRICH_gasvol_material"); - TVector3 normX(1, 0, 0); // normal vectors + TVector3 normX(1, 0, 0); // normal vectors TVector3 normY(0, -1, 0); - m_surfEntrance = new FlatSurface(TVector3(0, 0, vesselZmin + vesselWindowThickness), normX, normY); - for (int isec=0; isecSetContainerVolume( + m_surfEntrance = + new FlatSurface(TVector3(0, 0, vesselZmin + vesselWindowThickness), normX, normY); + for (int isec = 0; isec < nSectors; isec++) { + auto* cv = m_irtDetectorCollection->SetContainerVolume( m_irtDetector, // Cherenkov detector RadiatorName(kGas).c_str(), // name isec, // path (G4LogicalVolume*)(0x0), // G4LogicalVolume (inaccessible? use an integer instead) nullptr, // G4RadiatorMaterial (inaccessible?) m_surfEntrance // surface - ); + ); cv->SetAlternativeMaterialName(gasvolMaterial.c_str()); } // photon detector // - FIXME: args (G4Solid,G4Material) inaccessible? - auto cellMask = uint64_t(std::stoull(m_det->constant("DRICH_cell_mask"))); + auto cellMask = uint64_t(std::stoull(m_det->constant("DRICH_cell_mask"))); m_irtPhotonDetector = new CherenkovPhotonDetector(nullptr, nullptr); m_irtDetector->SetReadoutCellMask(cellMask); - m_irtDetectorCollection->AddPhotonDetector( - m_irtDetector, // Cherenkov detector - nullptr, // G4LogicalVolume (inaccessible?) - m_irtPhotonDetector // photon detector - ); + m_irtDetectorCollection->AddPhotonDetector(m_irtDetector, // Cherenkov detector + nullptr, // G4LogicalVolume (inaccessible?) + m_irtPhotonDetector // photon detector + ); m_log->debug("cellMask = {:#X}", cellMask); // aerogel + filter @@ -76,9 +76,9 @@ void richgeo::IrtGeoDRICH::DD4hep_to_IRT() { auto filterThickness = m_det->constant("DRICH_filter_thickness") / dd4hep::mm; auto filterMaterial = m_det->constant("DRICH_filter_material"); m_aerogelFlatSurface = new FlatSurface(TVector3(0, 0, aerogelZpos), normX, normY); - m_filterFlatSurface = new FlatSurface(TVector3(0, 0, filterZpos), normX, normY); + m_filterFlatSurface = new FlatSurface(TVector3(0, 0, filterZpos), normX, normY); for (int isec = 0; isec < nSectors; isec++) { - auto *aerogelFlatRadiator = m_irtDetectorCollection->AddFlatRadiator( + auto* aerogelFlatRadiator = m_irtDetectorCollection->AddFlatRadiator( m_irtDetector, // Cherenkov detector RadiatorName(kAerogel).c_str(), // name isec, // path @@ -86,8 +86,8 @@ void richgeo::IrtGeoDRICH::DD4hep_to_IRT() { nullptr, // G4RadiatorMaterial m_aerogelFlatSurface, // surface aerogelThickness // surface thickness - ); - auto *filterFlatRadiator = m_irtDetectorCollection->AddFlatRadiator( + ); + auto* filterFlatRadiator = m_irtDetectorCollection->AddFlatRadiator( m_irtDetector, // Cherenkov detector "Filter", // name isec, // path @@ -95,7 +95,7 @@ void richgeo::IrtGeoDRICH::DD4hep_to_IRT() { nullptr, // G4RadiatorMaterial m_filterFlatSurface, // surface filterThickness // surface thickness - ); + ); aerogelFlatRadiator->SetAlternativeMaterialName(aerogelMaterial.c_str()); filterFlatRadiator->SetAlternativeMaterialName(filterMaterial.c_str()); } @@ -110,15 +110,15 @@ void richgeo::IrtGeoDRICH::DD4hep_to_IRT() { // mirrors auto mirrorRadius = m_det->constant("DRICH_mirror_radius") / dd4hep::mm; dd4hep::Position mirrorCenter( - m_det->constant("DRICH_mirror_center_x_"+secName) / dd4hep::mm, - m_det->constant("DRICH_mirror_center_y_"+secName) / dd4hep::mm, - m_det->constant("DRICH_mirror_center_z_"+secName) / dd4hep::mm - ); - m_mirrorSphericalSurface = new SphericalSurface(TVector3(mirrorCenter.x(), mirrorCenter.y(), mirrorCenter.z()), mirrorRadius); - m_mirrorOpticalBoundary = new OpticalBoundary( - m_irtDetector->GetContainerVolume(), // CherenkovRadiator radiator - m_mirrorSphericalSurface, // surface - false // bool refractive + m_det->constant("DRICH_mirror_center_x_" + secName) / dd4hep::mm, + m_det->constant("DRICH_mirror_center_y_" + secName) / dd4hep::mm, + m_det->constant("DRICH_mirror_center_z_" + secName) / dd4hep::mm); + m_mirrorSphericalSurface = new SphericalSurface( + TVector3(mirrorCenter.x(), mirrorCenter.y(), mirrorCenter.z()), mirrorRadius); + m_mirrorOpticalBoundary = + new OpticalBoundary(m_irtDetector->GetContainerVolume(), // CherenkovRadiator radiator + m_mirrorSphericalSurface, // surface + false // bool refractive ); m_irtDetector->AddOpticalBoundary(isec, m_mirrorOpticalBoundary); m_log->debug(""); @@ -130,58 +130,60 @@ void richgeo::IrtGeoDRICH::DD4hep_to_IRT() { // complete the radiator volume description; this is the rear side of the container gas volume auto rad = m_irtDetector->GetRadiator(RadiatorName(kGas).c_str()); - if(rad) rad->m_Borders[isec].second = m_mirrorSphericalSurface; - else throw std::runtime_error("Gas radiator not built in IrtGeo"); + if (rad) + rad->m_Borders[isec].second = m_mirrorSphericalSurface; + else + throw std::runtime_error("Gas radiator not built in IrtGeo"); // sensor modules: search the detector tree for sensors for this sector m_log->trace(" SENSORS:"); - m_log->trace("--------------------------------------------------------------------------------------"); - m_log->trace("name ID sector pos_x pos_y pos_z normX_x normX_y normX_z normY_x normY_y normY_z"); - m_log->trace("--------------------------------------------------------------------------------------"); + m_log->trace( + "--------------------------------------------------------------------------------------"); + m_log->trace( + "name ID sector pos_x pos_y pos_z normX_x normX_y normX_z normY_x normY_y normY_z"); + m_log->trace( + "--------------------------------------------------------------------------------------"); auto sensorThickness = m_det->constant("DRICH_sensor_thickness") / dd4hep::mm; auto sensorSize = m_det->constant("DRICH_sensor_size") / dd4hep::mm; - for(auto const& [de_name, detSensor] : m_detRich.children()) { - if(de_name.find("sensor_de_"+secName)!=std::string::npos) { + for (auto const& [de_name, detSensor] : m_detRich.children()) { + if (de_name.find("sensor_de_" + secName) != std::string::npos) { // get sensor info const auto sensorID = detSensor.id(); const auto detSensorPars = detSensor.extension(true); - if(detSensorPars==nullptr) - throw std::runtime_error(fmt::format("sensor '{}' does not have VariantParameters", de_name)); + if (detSensorPars == nullptr) + throw std::runtime_error( + fmt::format("sensor '{}' does not have VariantParameters", de_name)); // - sensor surface position - auto posSensor = GetVectorFromVariantParameters(detSensorPars, "pos") / dd4hep::mm; + auto posSensor = + GetVectorFromVariantParameters(detSensorPars, "pos") / dd4hep::mm; // - sensor orientation auto normXdir = GetVectorFromVariantParameters(detSensorPars, "normX"); auto normYdir = GetVectorFromVariantParameters(detSensorPars, "normY"); auto normZdir = normXdir.Cross(normYdir); // sensor surface normal // - surface offset, used to convert sensor volume centroid to sensor surface centroid - auto surfaceOffset = normZdir.Unit() * (0.5*sensorThickness); + auto surfaceOffset = normZdir.Unit() * (0.5 * sensorThickness); // add sensor info to `m_sensor_info` map richgeo::Sensor sensor_info; sensor_info.size = sensorSize; sensor_info.surface_centroid = posSensor; sensor_info.surface_offset = surfaceOffset; - m_sensor_info.insert({ sensorID, sensor_info }); + m_sensor_info.insert({sensorID, sensor_info}); // create the optical surface - m_sensorFlatSurface = new FlatSurface( - TVector3(posSensor.x(), posSensor.y(), posSensor.z()), - TVector3(normXdir.x(), normXdir.y(), normXdir.z()), - TVector3(normYdir.x(), normYdir.y(), normYdir.z()) - ); - m_irtDetector->CreatePhotonDetectorInstance( - isec, // sector - m_irtPhotonDetector, // CherenkovPhotonDetector - sensorID, // copy number - m_sensorFlatSurface // surface - ); - m_log->trace( - "{} {:#X} {} {:5.2f} {:5.2f} {:5.2f} {:5.2f} {:5.2f} {:5.2f} {:5.2f} {:5.2f} {:5.2f}", - de_name, sensorID, isec, - posSensor.x(), posSensor.y(), posSensor.z(), - normXdir.x(), normXdir.y(), normXdir.z(), - normYdir.x(), normYdir.y(), normYdir.z() - ); + m_sensorFlatSurface = new FlatSurface(TVector3(posSensor.x(), posSensor.y(), posSensor.z()), + TVector3(normXdir.x(), normXdir.y(), normXdir.z()), + TVector3(normYdir.x(), normYdir.y(), normYdir.z())); + m_irtDetector->CreatePhotonDetectorInstance(isec, // sector + m_irtPhotonDetector, // CherenkovPhotonDetector + sensorID, // copy number + m_sensorFlatSurface // surface + ); + m_log->trace("{} {:#X} {} {:5.2f} {:5.2f} {:5.2f} {:5.2f} {:5.2f} {:5.2f} {:5.2f} " + "{:5.2f} {:5.2f}", + de_name, sensorID, isec, posSensor.x(), posSensor.y(), posSensor.z(), + normXdir.x(), normXdir.y(), normXdir.z(), normYdir.x(), normYdir.y(), + normYdir.z()); } } // search for sensors @@ -189,9 +191,9 @@ void richgeo::IrtGeoDRICH::DD4hep_to_IRT() { // set reference refractive indices // NOTE: numbers may be overridden externally std::map rIndices; - rIndices.insert({RadiatorName(kGas), 1.00076}); + rIndices.insert({RadiatorName(kGas), 1.00076}); rIndices.insert({RadiatorName(kAerogel), 1.0190}); - rIndices.insert({"Filter", 1.5017}); + rIndices.insert({"Filter", 1.5017}); for (auto const& [rName, rIndex] : rIndices) { auto rad = m_irtDetector->GetRadiator(rName.c_str()); if (rad) @@ -204,20 +206,19 @@ void richgeo::IrtGeoDRICH::DD4hep_to_IRT() { // define the `cell ID -> pixel position` converter SetReadoutIDToPositionLambda(); } -TVector3 richgeo::IrtGeoDRICH::GetSensorSurfaceNorm(CellIDType id){ +TVector3 richgeo::IrtGeoDRICH::GetSensorSurfaceNorm(CellIDType id) { TVector3 sensorNorm; - auto cellMask = uint64_t(std::stoull(m_det->constant("DRICH_cell_mask"))); - auto sensor_info = this->m_sensor_info; - auto sID = id & cellMask; + auto cellMask = uint64_t(std::stoull(m_det->constant("DRICH_cell_mask"))); + auto sensor_info = this->m_sensor_info; + auto sID = id & cellMask; auto sensor_info_it = sensor_info.find(sID); - if(sensor_info_it!=sensor_info.end()){ + if (sensor_info_it != sensor_info.end()) { auto sensor_obj = sensor_info_it->second; - auto normZdir = sensor_obj.surface_offset.Unit(); + auto normZdir = sensor_obj.surface_offset.Unit(); sensorNorm.SetX(static_cast(normZdir.x())); sensorNorm.SetY(static_cast(normZdir.y())); sensorNorm.SetZ(static_cast(normZdir.z())); - } - else{ + } else { m_log->error("Cannot find sensor {} in IrtGeoDRICH::GetSensorSurface", id); throw std::runtime_error("sensor not found in IrtGeoDRIC::GetSensorSurfaceNormal"); } diff --git a/src/services/geometry/richgeo/IrtGeoDRICH.h b/src/services/geometry/richgeo/IrtGeoDRICH.h index 23d86f37c5..22433c8e2e 100644 --- a/src/services/geometry/richgeo/IrtGeoDRICH.h +++ b/src/services/geometry/richgeo/IrtGeoDRICH.h @@ -18,25 +18,29 @@ #include "services/geometry/richgeo/RichGeo.h" namespace richgeo { - class IrtGeoDRICH : public IrtGeo { +class IrtGeoDRICH : public IrtGeo { - public: - IrtGeoDRICH(gsl::not_null det_, gsl::not_null conv_, std::shared_ptr log_) : - IrtGeo("DRICH",det_,conv_,log_) { DD4hep_to_IRT(); } - ~IrtGeoDRICH(); - TVector3 GetSensorSurfaceNorm(CellIDType); - protected: - void DD4hep_to_IRT() override; +public: + IrtGeoDRICH(gsl::not_null det_, + gsl::not_null conv_, + std::shared_ptr log_) + : IrtGeo("DRICH", det_, conv_, log_) { + DD4hep_to_IRT(); + } + ~IrtGeoDRICH(); + TVector3 GetSensorSurfaceNorm(CellIDType); - private: - // FIXME: should be smart pointers, but IRT methods sometimes assume ownership of such raw pointers - FlatSurface* m_surfEntrance; - CherenkovPhotonDetector* m_irtPhotonDetector; - FlatSurface* m_aerogelFlatSurface; - FlatSurface* m_filterFlatSurface; - SphericalSurface* m_mirrorSphericalSurface; - OpticalBoundary* m_mirrorOpticalBoundary; - FlatSurface* m_sensorFlatSurface; +protected: + void DD4hep_to_IRT() override; - }; -} +private: + // FIXME: should be smart pointers, but IRT methods sometimes assume ownership of such raw pointers + FlatSurface* m_surfEntrance; + CherenkovPhotonDetector* m_irtPhotonDetector; + FlatSurface* m_aerogelFlatSurface; + FlatSurface* m_filterFlatSurface; + SphericalSurface* m_mirrorSphericalSurface; + OpticalBoundary* m_mirrorOpticalBoundary; + FlatSurface* m_sensorFlatSurface; +}; +} // namespace richgeo diff --git a/src/services/geometry/richgeo/IrtGeoPFRICH.cc b/src/services/geometry/richgeo/IrtGeoPFRICH.cc index 55dde3d8eb..a69ee107d0 100644 --- a/src/services/geometry/richgeo/IrtGeoPFRICH.cc +++ b/src/services/geometry/richgeo/IrtGeoPFRICH.cc @@ -37,44 +37,43 @@ void richgeo::IrtGeoPFRICH::DD4hep_to_IRT() { */ auto vesselZmin = m_det->constant("PFRICH_zmin") / dd4hep::mm; auto gasvolMaterial = m_det->constant("PFRICH_gasvol_material"); - TVector3 normX(1, 0, 0); // normal vectors + TVector3 normX(1, 0, 0); // normal vectors TVector3 normY(0, 1, 0); m_surfEntrance = new FlatSurface(TVector3(0, 0, vesselZmin), normX, normY); - auto cv = m_irtDetectorCollection->SetContainerVolume( + auto cv = m_irtDetectorCollection->SetContainerVolume( m_irtDetector, // Cherenkov detector RadiatorName(kGas).c_str(), // name 0, // path (G4LogicalVolume*)(0x0), // G4LogicalVolume (inaccessible? use an integer instead) nullptr, // G4RadiatorMaterial (inaccessible?) m_surfEntrance // surface - ); + ); cv->SetAlternativeMaterialName(gasvolMaterial.c_str()); // photon detector // - FIXME: args (G4Solid,G4Material) inaccessible? - auto cellMask = uint64_t(std::stoull(m_det->constant("PFRICH_cell_mask"))); + auto cellMask = uint64_t(std::stoull(m_det->constant("PFRICH_cell_mask"))); m_irtPhotonDetector = new CherenkovPhotonDetector(nullptr, nullptr); m_irtDetector->SetReadoutCellMask(cellMask); - m_irtDetectorCollection->AddPhotonDetector( - m_irtDetector, // Cherenkov detector - nullptr, // G4LogicalVolume (inaccessible?) - m_irtPhotonDetector // photon detector - ); + m_irtDetectorCollection->AddPhotonDetector(m_irtDetector, // Cherenkov detector + nullptr, // G4LogicalVolume (inaccessible?) + m_irtPhotonDetector // photon detector + ); m_log->debug("cellMask = {:#X}", cellMask); // aerogel + filter /* AddFlatRadiator will create a pair of flat refractive surfaces internally; * FIXME: should make a small gas gap at the upstream end of the gas volume; */ - auto aerogelZpos = m_det->constant("PFRICH_aerogel_zpos") / dd4hep::mm; - auto aerogelThickness = m_det->constant("PFRICH_aerogel_thickness") / dd4hep::mm; - auto aerogelMaterial = m_det->constant("PFRICH_aerogel_material"); - auto filterZpos = m_det->constant("PFRICH_filter_zpos") / dd4hep::mm; - auto filterThickness = m_det->constant("PFRICH_filter_thickness") / dd4hep::mm; - auto filterMaterial = m_det->constant("PFRICH_filter_material"); - m_aerogelFlatSurface = new FlatSurface(TVector3(0, 0, aerogelZpos), normX, normY); - m_filterFlatSurface = new FlatSurface(TVector3(0, 0, filterZpos), normX, normY); - auto *aerogelFlatRadiator = m_irtDetectorCollection->AddFlatRadiator( + auto aerogelZpos = m_det->constant("PFRICH_aerogel_zpos") / dd4hep::mm; + auto aerogelThickness = m_det->constant("PFRICH_aerogel_thickness") / dd4hep::mm; + auto aerogelMaterial = m_det->constant("PFRICH_aerogel_material"); + auto filterZpos = m_det->constant("PFRICH_filter_zpos") / dd4hep::mm; + auto filterThickness = m_det->constant("PFRICH_filter_thickness") / dd4hep::mm; + auto filterMaterial = m_det->constant("PFRICH_filter_material"); + m_aerogelFlatSurface = new FlatSurface(TVector3(0, 0, aerogelZpos), normX, normY); + m_filterFlatSurface = new FlatSurface(TVector3(0, 0, filterZpos), normX, normY); + auto* aerogelFlatRadiator = m_irtDetectorCollection->AddFlatRadiator( m_irtDetector, // Cherenkov detector RadiatorName(kAerogel).c_str(), // name 0, // path @@ -82,8 +81,8 @@ void richgeo::IrtGeoPFRICH::DD4hep_to_IRT() { nullptr, // G4RadiatorMaterial m_aerogelFlatSurface, // surface aerogelThickness // surface thickness - ); - auto *filterFlatRadiator = m_irtDetectorCollection->AddFlatRadiator( + ); + auto* filterFlatRadiator = m_irtDetectorCollection->AddFlatRadiator( m_irtDetector, // Cherenkov detector "Filter", // name 0, // path @@ -91,7 +90,7 @@ void richgeo::IrtGeoPFRICH::DD4hep_to_IRT() { nullptr, // G4RadiatorMaterial m_filterFlatSurface, // surface filterThickness // surface thickness - ); + ); aerogelFlatRadiator->SetAlternativeMaterialName(aerogelMaterial.c_str()); filterFlatRadiator->SetAlternativeMaterialName(filterMaterial.c_str()); m_log->debug("aerogelZpos = {:f} mm", aerogelZpos); @@ -100,32 +99,36 @@ void richgeo::IrtGeoPFRICH::DD4hep_to_IRT() { m_log->debug("filter thickness = {:f} mm", filterThickness); // sensor modules: search the detector tree for sensors - auto sensorThickness = m_det->constant("PFRICH_sensor_thickness") / dd4hep::mm; - auto sensorSize = m_det->constant("PFRICH_sensor_size") / dd4hep::mm; - bool firstSensor = true; - for(auto const& [de_name, detSensor] : m_detRich.children()) { - if(de_name.find("sensor_de")!=std::string::npos) { + auto sensorThickness = m_det->constant("PFRICH_sensor_thickness") / dd4hep::mm; + auto sensorSize = m_det->constant("PFRICH_sensor_size") / dd4hep::mm; + bool firstSensor = true; + for (auto const& [de_name, detSensor] : m_detRich.children()) { + if (de_name.find("sensor_de") != std::string::npos) { // get sensor info auto imod = detSensor.id(); // - get sensor centroid position auto pvSensor = detSensor.placement(); - auto posSensor = (1/dd4hep::mm) * (m_posRich + pvSensor.position()); + auto posSensor = (1 / dd4hep::mm) * (m_posRich + pvSensor.position()); // - get sensor surface position - dd4hep::Direction sensorNorm(0,0,1); // FIXME: generalize; this assumes planar layout, with norm along +z axis (toward IP) - auto surfaceOffset = sensorNorm.Unit() * (0.5*sensorThickness); + dd4hep::Direction sensorNorm( + 0, 0, + 1); // FIXME: generalize; this assumes planar layout, with norm along +z axis (toward IP) + auto surfaceOffset = sensorNorm.Unit() * (0.5 * sensorThickness); auto posSensorSurface = posSensor + surfaceOffset; // - add to `m_sensor_info` map richgeo::Sensor sensor_info; sensor_info.size = sensorSize; sensor_info.surface_centroid = posSensorSurface; sensor_info.surface_offset = surfaceOffset; - m_sensor_info.insert({ imod, sensor_info }); + m_sensor_info.insert({imod, sensor_info}); // - get surface normal and in-plane vectors double sensorLocalNormX[3] = {1.0, 0.0, 0.0}; double sensorLocalNormY[3] = {0.0, 1.0, 0.0}; double sensorGlobalNormX[3], sensorGlobalNormY[3]; - pvSensor.ptr()->LocalToMasterVect(sensorLocalNormX, sensorGlobalNormX); // ignore vessel transformation, since it is a pure translation + pvSensor.ptr()->LocalToMasterVect( + sensorLocalNormX, + sensorGlobalNormX); // ignore vessel transformation, since it is a pure translation pvSensor.ptr()->LocalToMasterVect(sensorLocalNormY, sensorGlobalNormY); // validate sensor position and normal @@ -133,43 +136,39 @@ void richgeo::IrtGeoPFRICH::DD4hep_to_IRT() { dd4hep::Direction normXdir, normYdir; normXdir.SetCoordinates(sensorGlobalNormX); normYdir.SetCoordinates(sensorGlobalNormY); - auto normZdir = normXdir.Cross(normYdir); // sensor surface normal, given derived GlobalNormX,Y - auto testOrtho = normXdir.Dot(normYdir); // should be zero, if normX and normY are orthogonal - auto testRadial = sensorNorm.Cross(normZdir).Mag2(); // should be zero, if sensor surface normal is as expected - if(abs(testOrtho)>1e-6 || abs(testRadial)>1e-6) { + auto normZdir = + normXdir.Cross(normYdir); // sensor surface normal, given derived GlobalNormX,Y + auto testOrtho = normXdir.Dot(normYdir); // should be zero, if normX and normY are orthogonal + auto testRadial = sensorNorm.Cross(normZdir) + .Mag2(); // should be zero, if sensor surface normal is as expected + if (abs(testOrtho) > 1e-6 || abs(testRadial) > 1e-6) { m_log->error( "sensor normal is wrong: normX.normY = {:f} |sensorNorm x normZdir|^2 = {:f}", - testOrtho, - testRadial - ); + testOrtho, testRadial); return; } // create the optical surface m_sensorFlatSurface = new FlatSurface( TVector3(posSensorSurface.x(), posSensorSurface.y(), posSensorSurface.z()), - TVector3(sensorGlobalNormX), - TVector3(sensorGlobalNormY) - ); - m_irtDetector->CreatePhotonDetectorInstance( - 0, // sector - m_irtPhotonDetector, // CherenkovPhotonDetector - imod, // copy number - m_sensorFlatSurface // surface - ); - m_log->trace( - "sensor: id={:#08X} pos=({:5.2f}, {:5.2f}, {:5.2f}) normX=({:5.2f}, {:5.2f}, {:5.2f}) normY=({:5.2f}, {:5.2f}, {:5.2f})", - imod, - posSensorSurface.x(), posSensorSurface.y(), posSensorSurface.z(), - normXdir.x(), normXdir.y(), normXdir.z(), - normYdir.x(), normYdir.y(), normYdir.z() - ); + TVector3(sensorGlobalNormX), TVector3(sensorGlobalNormY)); + m_irtDetector->CreatePhotonDetectorInstance(0, // sector + m_irtPhotonDetector, // CherenkovPhotonDetector + imod, // copy number + m_sensorFlatSurface // surface + ); + m_log->trace("sensor: id={:#08X} pos=({:5.2f}, {:5.2f}, {:5.2f}) normX=({:5.2f}, {:5.2f}, " + "{:5.2f}) normY=({:5.2f}, {:5.2f}, {:5.2f})", + imod, posSensorSurface.x(), posSensorSurface.y(), posSensorSurface.z(), + normXdir.x(), normXdir.y(), normXdir.z(), normYdir.x(), normYdir.y(), + normYdir.z()); // complete the radiator volume description; this is the rear side of the container gas volume // Yes, since there are no mirrors in this detector, just close the gas radiator volume by hand (once), // assuming that all the sensors will be sitting at roughly the same location along the beam line anyway; - if(firstSensor) { - m_irtDetector->GetRadiator(RadiatorName(kGas).c_str())->m_Borders[0].second = dynamic_cast(m_sensorFlatSurface); + if (firstSensor) { + m_irtDetector->GetRadiator(RadiatorName(kGas).c_str())->m_Borders[0].second = + dynamic_cast(m_sensorFlatSurface); firstSensor = false; } @@ -178,9 +177,9 @@ void richgeo::IrtGeoPFRICH::DD4hep_to_IRT() { // set reference refractive indices // NOTE: numbers may be overridden externally std::map rIndices; - rIndices.insert({RadiatorName(kGas).c_str(), 1.0013}); + rIndices.insert({RadiatorName(kGas).c_str(), 1.0013}); rIndices.insert({RadiatorName(kAerogel).c_str(), 1.0190}); - rIndices.insert({"Filter", 1.5017}); + rIndices.insert({"Filter", 1.5017}); for (auto const& [rName, rIndex] : rIndices) { auto rad = m_irtDetector->GetRadiator(rName); if (rad) diff --git a/src/services/geometry/richgeo/IrtGeoPFRICH.h b/src/services/geometry/richgeo/IrtGeoPFRICH.h index 35aa449b73..0592d572c3 100644 --- a/src/services/geometry/richgeo/IrtGeoPFRICH.h +++ b/src/services/geometry/richgeo/IrtGeoPFRICH.h @@ -15,22 +15,26 @@ #include "IrtGeo.h" namespace richgeo { - class IrtGeoPFRICH : public IrtGeo { +class IrtGeoPFRICH : public IrtGeo { - public: - IrtGeoPFRICH(gsl::not_null det_, gsl::not_null conv_, std::shared_ptr log_) : - IrtGeo("PFRICH",det_,conv_,log_) { DD4hep_to_IRT(); } - ~IrtGeoPFRICH(); +public: + IrtGeoPFRICH(gsl::not_null det_, + gsl::not_null conv_, + std::shared_ptr log_) + : IrtGeo("PFRICH", det_, conv_, log_) { + DD4hep_to_IRT(); + } + ~IrtGeoPFRICH(); - protected: - void DD4hep_to_IRT() override; +protected: + void DD4hep_to_IRT() override; - private: - // FIXME: should be smart pointers, but IRT methods sometimes assume ownership of such raw pointers - FlatSurface* m_surfEntrance; - CherenkovPhotonDetector* m_irtPhotonDetector; - FlatSurface* m_aerogelFlatSurface; - FlatSurface* m_filterFlatSurface; - FlatSurface* m_sensorFlatSurface; - }; -} +private: + // FIXME: should be smart pointers, but IRT methods sometimes assume ownership of such raw pointers + FlatSurface* m_surfEntrance; + CherenkovPhotonDetector* m_irtPhotonDetector; + FlatSurface* m_aerogelFlatSurface; + FlatSurface* m_filterFlatSurface; + FlatSurface* m_sensorFlatSurface; +}; +} // namespace richgeo diff --git a/src/services/geometry/richgeo/ReadoutGeo.cc b/src/services/geometry/richgeo/ReadoutGeo.cc index 0bdebc13ad..36c239f578 100644 --- a/src/services/geometry/richgeo/ReadoutGeo.cc +++ b/src/services/geometry/richgeo/ReadoutGeo.cc @@ -24,9 +24,10 @@ #include "services/geometry/richgeo/RichGeo.h" // constructor -richgeo::ReadoutGeo::ReadoutGeo(std::string detName_, gsl::not_null det_, gsl::not_null conv_, std::shared_ptr log_) - : m_detName(detName_), m_det(det_), m_conv(conv_), m_log(log_) -{ +richgeo::ReadoutGeo::ReadoutGeo(std::string detName_, gsl::not_null det_, + gsl::not_null conv_, + std::shared_ptr log_) + : m_detName(detName_), m_det(det_), m_conv(conv_), m_log(log_) { // capitalize m_detName std::transform(m_detName.begin(), m_detName.end(), m_detName.begin(), ::toupper); @@ -34,18 +35,18 @@ richgeo::ReadoutGeo::ReadoutGeo(std::string detName_, gsl::not_null lambda) { return; }; + m_loopCellIDs = [](std::function lambda) { return; }; // default (empty) cellID rng generator - m_rngCellIDs = [] (std::function lambda, float p) { return; }; + m_rngCellIDs = [](std::function lambda, float p) { return; }; // common objects - m_readoutCoder = m_det->readout(m_detName+"Hits").idSpec().decoder(); + m_readoutCoder = m_det->readout(m_detName + "Hits").idSpec().decoder(); m_detRich = m_det->detector(m_detName); m_systemID = m_detRich.id(); // dRICH readout -------------------------------------------------------------------- - if(m_detName=="DRICH") { + if (m_detName == "DRICH") { // get constants from geometry m_num_sec = m_det->constant("DRICH_num_sectors"); @@ -55,12 +56,12 @@ richgeo::ReadoutGeo::ReadoutGeo(std::string detName_, gsl::not_nullconstant("DRICH_pixel_size") / dd4hep::mm; // define cellID looper - m_loopCellIDs = [this] (std::function lambda) { + m_loopCellIDs = [this](std::function lambda) { m_log->trace("call VisitAllReadoutPixels for systemID = {} = {}", m_systemID, m_detName); // loop over sensors (for all sectors) - for(auto const& [deName, detSensor] : m_detRich.children()) { - if(deName.find("sensor_de_sec")!=std::string::npos) { + for (auto const& [deName, detSensor] : m_detRich.children()) { + if (deName.find("sensor_de_sec") != std::string::npos) { // decode `sensorID` to module number and sector number auto sensorID = detSensor.id(); @@ -84,17 +85,17 @@ richgeo::ReadoutGeo::ReadoutGeo(std::string detName_, gsl::not_null lambda, float p) { + m_rngCellIDs = [this](std::function lambda, float p) { m_log->trace("call RngReadoutPixels for systemID = {} = {}", m_systemID, m_detName); int k = p * m_num_sec * m_num_pdus * m_num_sipms_per_pdu * m_num_px * m_num_px; for (int i = 0; i < k; i++) { - int isec = m_random.Uniform(0., m_num_sec); - int ipdu = m_random.Uniform(0., m_num_pdus); + int isec = m_random.Uniform(0., m_num_sec); + int ipdu = m_random.Uniform(0., m_num_pdus); int isipm = m_random.Uniform(0., m_num_sipms_per_pdu); - int x = m_random.Uniform(0., m_num_px); - int y = m_random.Uniform(0., m_num_px); + int x = m_random.Uniform(0., m_num_px); + int y = m_random.Uniform(0., m_num_px); auto cellID = cellIDEncoding(isec, ipdu, isipm, x, y); @@ -105,32 +106,31 @@ richgeo::ReadoutGeo::ReadoutGeo(std::string detName_, gsl::not_nullerror("TODO: pfRICH readout bindings have not yet been implemented"); } // ------------------------------------------------------------------------------------------------ - else m_log->error("ReadoutGeo is not defined for detector '{}'",m_detName); - + else + m_log->error("ReadoutGeo is not defined for detector '{}'", m_detName); } - // pixel gap mask // FIXME: generalize; this assumes the segmentation is `CartesianGridXY` bool richgeo::ReadoutGeo::PixelGapMask(CellIDType cellID, dd4hep::Position pos_hit_global) { auto pos_pixel_global = m_conv->position(cellID); auto pos_pixel_local = GetSensorLocalPosition(cellID, pos_pixel_global); auto pos_hit_local = GetSensorLocalPosition(cellID, pos_hit_global); - return ! ( - std::abs( pos_hit_local.x()/dd4hep::mm - pos_pixel_local.x()/dd4hep::mm ) > m_pixel_size/2 || - std::abs( pos_hit_local.y()/dd4hep::mm - pos_pixel_local.y()/dd4hep::mm ) > m_pixel_size/2 - ); + return !(std::abs(pos_hit_local.x() / dd4hep::mm - pos_pixel_local.x() / dd4hep::mm) > + m_pixel_size / 2 || + std::abs(pos_hit_local.y() / dd4hep::mm - pos_pixel_local.y() / dd4hep::mm) > + m_pixel_size / 2); } - // transform global position `pos` to sensor `cellID` frame position // IMPORTANT NOTE: this has only been tested for the dRICH; if you use it, test it carefully... -dd4hep::Position richgeo::ReadoutGeo::GetSensorLocalPosition(CellIDType cellID, dd4hep::Position pos) { +dd4hep::Position richgeo::ReadoutGeo::GetSensorLocalPosition(CellIDType cellID, + dd4hep::Position pos) { // get the VolumeManagerContext for this sensitive detector auto context = m_conv->findContext(cellID); diff --git a/src/services/geometry/richgeo/ReadoutGeo.h b/src/services/geometry/richgeo/ReadoutGeo.h index 00c952a10e..e0976b1bc9 100644 --- a/src/services/geometry/richgeo/ReadoutGeo.h +++ b/src/services/geometry/richgeo/ReadoutGeo.h @@ -24,70 +24,69 @@ #include "RichGeo.h" namespace richgeo { - class ReadoutGeo { - public: - - // constructor - ReadoutGeo(std::string detName_, gsl::not_null det_, gsl::not_null conv_, std::shared_ptr log_); - ~ReadoutGeo() {} - - // define cellID encoding - CellIDType cellIDEncoding(int isec, int ipdu, int isipm, int x, int y) - { - // encode cellID - dd4hep::rec::CellID cellID_dd4hep; - m_readoutCoder->set(cellID_dd4hep, "system", m_systemID); - m_readoutCoder->set(cellID_dd4hep, "sector", isec); - m_readoutCoder->set(cellID_dd4hep, "pdu", ipdu); - m_readoutCoder->set(cellID_dd4hep, "sipm", isipm); - m_readoutCoder->set(cellID_dd4hep, "x", x); - m_readoutCoder->set(cellID_dd4hep, "y", y); - CellIDType cellID(cellID_dd4hep); // in case DD4hep CellID type differs from EDM type - return cellID; - // m_log->trace(" x={:<2} y={:<2} => cellID={:#018X}", x, y, cellID); - } - - // loop over readout pixels, executing `lambda(cellID)` on each - void VisitAllReadoutPixels(std::function lambda) { m_loopCellIDs(lambda); } - - // generated k rng cell IDs, executing `lambda(cellID)` on each - void VisitAllRngPixels(std::function lambda, float p) { m_rngCellIDs(lambda, p); } - - // pixel gap mask - bool PixelGapMask(CellIDType cellID, dd4hep::Position pos_hit_global); - - // transform global position `pos` to sensor `id` frame position - // IMPORTANT NOTE: this has only been tested for the dRICH; if you use it, test it carefully... - dd4hep::Position GetSensorLocalPosition(CellIDType id, dd4hep::Position pos); - - // set RNG seed - void SetSeed(unsigned long seed) { m_random.SetSeed(seed); } - - protected: - - // common objects - std::shared_ptr m_log; - std::string m_detName; - gsl::not_null m_det; - gsl::not_null m_conv; - dd4hep::DetElement m_detRich; - dd4hep::BitFieldCoder* m_readoutCoder; - int m_systemID; - int m_num_sec; - int m_num_pdus; - int m_num_sipms_per_pdu; - int m_num_px; - double m_pixel_size; - - // local function to loop over cellIDs; defined in initialization and called by `VisitAllReadoutPixels` - std::function< void(std::function) > m_loopCellIDs; - // local function to generate rng cellIDs; defined in initialization and called by `VisitAllRngPixels` - std::function< void(std::function, float) > m_rngCellIDs; - - private: - - // random number generators - TRandomMixMax m_random; - - }; -} +class ReadoutGeo { +public: + // constructor + ReadoutGeo(std::string detName_, gsl::not_null det_, + gsl::not_null conv_, + std::shared_ptr log_); + ~ReadoutGeo() {} + + // define cellID encoding + CellIDType cellIDEncoding(int isec, int ipdu, int isipm, int x, int y) { + // encode cellID + dd4hep::rec::CellID cellID_dd4hep; + m_readoutCoder->set(cellID_dd4hep, "system", m_systemID); + m_readoutCoder->set(cellID_dd4hep, "sector", isec); + m_readoutCoder->set(cellID_dd4hep, "pdu", ipdu); + m_readoutCoder->set(cellID_dd4hep, "sipm", isipm); + m_readoutCoder->set(cellID_dd4hep, "x", x); + m_readoutCoder->set(cellID_dd4hep, "y", y); + CellIDType cellID(cellID_dd4hep); // in case DD4hep CellID type differs from EDM type + return cellID; + // m_log->trace(" x={:<2} y={:<2} => cellID={:#018X}", x, y, cellID); + } + + // loop over readout pixels, executing `lambda(cellID)` on each + void VisitAllReadoutPixels(std::function lambda) { m_loopCellIDs(lambda); } + + // generated k rng cell IDs, executing `lambda(cellID)` on each + void VisitAllRngPixels(std::function lambda, float p) { + m_rngCellIDs(lambda, p); + } + + // pixel gap mask + bool PixelGapMask(CellIDType cellID, dd4hep::Position pos_hit_global); + + // transform global position `pos` to sensor `id` frame position + // IMPORTANT NOTE: this has only been tested for the dRICH; if you use it, test it carefully... + dd4hep::Position GetSensorLocalPosition(CellIDType id, dd4hep::Position pos); + + // set RNG seed + void SetSeed(unsigned long seed) { m_random.SetSeed(seed); } + +protected: + // common objects + std::shared_ptr m_log; + std::string m_detName; + gsl::not_null m_det; + gsl::not_null m_conv; + dd4hep::DetElement m_detRich; + dd4hep::BitFieldCoder* m_readoutCoder; + int m_systemID; + int m_num_sec; + int m_num_pdus; + int m_num_sipms_per_pdu; + int m_num_px; + double m_pixel_size; + + // local function to loop over cellIDs; defined in initialization and called by `VisitAllReadoutPixels` + std::function)> m_loopCellIDs; + // local function to generate rng cellIDs; defined in initialization and called by `VisitAllRngPixels` + std::function, float)> m_rngCellIDs; + +private: + // random number generators + TRandomMixMax m_random; +}; +} // namespace richgeo diff --git a/src/services/geometry/richgeo/RichGeo.h b/src/services/geometry/richgeo/RichGeo.h index f8f38d7d02..dea41c33ee 100644 --- a/src/services/geometry/richgeo/RichGeo.h +++ b/src/services/geometry/richgeo/RichGeo.h @@ -11,69 +11,79 @@ namespace richgeo { - using CellIDType = decltype(edm4hep::SimTrackerHitData::cellID); +using CellIDType = decltype(edm4hep::SimTrackerHitData::cellID); - // sensors - // ----------------------------------------------------------------------- - /* keep track of information for a sensor +// sensors +// ----------------------------------------------------------------------- +/* keep track of information for a sensor */ - class Sensor { - public: - Sensor() {}; - ~Sensor() {}; - double size; - dd4hep::Position surface_centroid; - dd4hep::Direction surface_offset; // surface centroid = volume centroid + `surface_offset` - }; +class Sensor { +public: + Sensor() {}; + ~Sensor() {}; + double size; + dd4hep::Position surface_centroid; + dd4hep::Direction surface_offset; // surface centroid = volume centroid + `surface_offset` +}; - // radiators - // ----------------------------------------------------------------------- - /* in many places in the reconstruction, we need to track which radiator +// radiators +// ----------------------------------------------------------------------- +/* in many places in the reconstruction, we need to track which radiator * we are referring to; these are common methods to enumerate them */ - enum radiator_enum { - kAerogel, - kGas, - nRadiators - }; +enum radiator_enum { kAerogel, kGas, nRadiators }; - // return radiator name associated with index - static std::string RadiatorName(int num, std::shared_ptr m_log = nullptr) { - if(num==kAerogel) return "Aerogel"; - else if(num==kGas) return "Gas"; - else { - if (m_log) m_log->error("unknown radiator number {}", num); - else std::cerr << "ERROR: unknown radiator number " << num << std::endl; - return "UNKNOWN_RADIATOR"; - } +// return radiator name associated with index +static std::string RadiatorName(int num, std::shared_ptr m_log = nullptr) { + if (num == kAerogel) + return "Aerogel"; + else if (num == kGas) + return "Gas"; + else { + if (m_log) + m_log->error("unknown radiator number {}", num); + else + std::cerr << "ERROR: unknown radiator number " << num << std::endl; + return "UNKNOWN_RADIATOR"; } +} - // return radiator index associated with name - static int RadiatorNum(std::string name, std::shared_ptr m_log = nullptr) { - if(name=="Aerogel") return kAerogel; - else if(name=="Gas") return kGas; - else { - if (m_log) m_log->error("unknown radiator name {}", name); - else std::cerr << "ERROR: unknown radiator name " << name << std::endl; - return -1; - } +// return radiator index associated with name +static int RadiatorNum(std::string name, std::shared_ptr m_log = nullptr) { + if (name == "Aerogel") + return kAerogel; + else if (name == "Gas") + return kGas; + else { + if (m_log) + m_log->error("unknown radiator name {}", name); + else + std::cerr << "ERROR: unknown radiator name " << name << std::endl; + return -1; } +} - static int RadiatorNum(const char * name, std::shared_ptr m_log = nullptr) { - return RadiatorNum(std::string(name), m_log); - } +static int RadiatorNum(const char* name, std::shared_ptr m_log = nullptr) { + return RadiatorNum(std::string(name), m_log); +} - // search string `input` for a radiator name; return corresponding index - static int ParseRadiatorName(std::string input, std::shared_ptr m_log = nullptr) { - if (input.find("aerogel")!=std::string::npos) return kAerogel; - else if (input.find("Aerogel")!=std::string::npos) return kAerogel; - else if (input.find("gas")!=std::string::npos) return kGas; - else if (input.find("Gas")!=std::string::npos) return kGas; - else { - if (m_log) m_log->error("failed to parse '{}' for radiator name", input); - else std::cerr << "ERROR: failed to parse '" << input << "' for radiator name" << std::endl; - return -1; - } +// search string `input` for a radiator name; return corresponding index +static int ParseRadiatorName(std::string input, std::shared_ptr m_log = nullptr) { + if (input.find("aerogel") != std::string::npos) + return kAerogel; + else if (input.find("Aerogel") != std::string::npos) + return kAerogel; + else if (input.find("gas") != std::string::npos) + return kGas; + else if (input.find("Gas") != std::string::npos) + return kGas; + else { + if (m_log) + m_log->error("failed to parse '{}' for radiator name", input); + else + std::cerr << "ERROR: failed to parse '" << input << "' for radiator name" << std::endl; + return -1; } - } + +} // namespace richgeo diff --git a/src/services/geometry/richgeo/RichGeo_service.cc b/src/services/geometry/richgeo/RichGeo_service.cc index ee45c3f9c4..be19b29432 100644 --- a/src/services/geometry/richgeo/RichGeo_service.cc +++ b/src/services/geometry/richgeo/RichGeo_service.cc @@ -19,36 +19,39 @@ #include "services/log/Log_service.h" // Services ---------------------------------------------------------- -void RichGeo_service::acquire_services(JServiceLocator *srv_locator) { +void RichGeo_service::acquire_services(JServiceLocator* srv_locator) { // logging service auto log_service = srv_locator->get(); - m_log = log_service->logger("richgeo"); + m_log = log_service->logger("richgeo"); // DD4Hep geometry service auto dd4hep_service = srv_locator->get(); - m_dd4hepGeo = dd4hep_service->detector(); - m_converter = dd4hep_service->converter(); + m_dd4hepGeo = dd4hep_service->detector(); + m_converter = dd4hep_service->converter(); } // IrtGeo ----------------------------------------------------------- -richgeo::IrtGeo *RichGeo_service::GetIrtGeo(std::string detector_name) { +richgeo::IrtGeo* RichGeo_service::GetIrtGeo(std::string detector_name) { // initialize, if not yet initialized try { m_log->debug("Call RichGeo_service::GetIrtGeo initializer"); - auto initialize = [this,&detector_name] () { - if(!m_dd4hepGeo) throw JException("RichGeo_service m_dd4hepGeo==null which should never be!"); + auto initialize = [this, &detector_name]() { + if (!m_dd4hepGeo) + throw JException("RichGeo_service m_dd4hepGeo==null which should never be!"); // instantiate IrtGeo-derived object, depending on detector auto which_rich = detector_name; std::transform(which_rich.begin(), which_rich.end(), which_rich.begin(), ::toupper); - if ( which_rich=="DRICH" ) m_irtGeo = new richgeo::IrtGeoDRICH(m_dd4hepGeo, m_converter, m_log); - else if( which_rich=="PFRICH" ) m_irtGeo = new richgeo::IrtGeoPFRICH(m_dd4hepGeo, m_converter, m_log); - else throw JException(fmt::format("IrtGeo is not defined for detector '{}'",detector_name)); + if (which_rich == "DRICH") + m_irtGeo = new richgeo::IrtGeoDRICH(m_dd4hepGeo, m_converter, m_log); + else if (which_rich == "PFRICH") + m_irtGeo = new richgeo::IrtGeoPFRICH(m_dd4hepGeo, m_converter, m_log); + else + throw JException(fmt::format("IrtGeo is not defined for detector '{}'", detector_name)); }; std::call_once(m_init_irt, initialize); - } - catch (std::exception &ex) { + } catch (std::exception& ex) { throw JException(ex.what()); } @@ -56,17 +59,17 @@ richgeo::IrtGeo *RichGeo_service::GetIrtGeo(std::string detector_name) { } // ActsGeo ----------------------------------------------------------- -richgeo::ActsGeo *RichGeo_service::GetActsGeo(std::string detector_name) { +richgeo::ActsGeo* RichGeo_service::GetActsGeo(std::string detector_name) { // initialize, if not yet initialized try { m_log->debug("Call RichGeo_service::GetActsGeo initializer"); - auto initialize = [this,&detector_name] () { - if(!m_dd4hepGeo) throw JException("RichGeo_service m_dd4hepGeo==null which should never be!"); + auto initialize = [this, &detector_name]() { + if (!m_dd4hepGeo) + throw JException("RichGeo_service m_dd4hepGeo==null which should never be!"); m_actsGeo = new richgeo::ActsGeo(detector_name, m_dd4hepGeo, m_log); }; std::call_once(m_init_acts, initialize); - } - catch (std::exception &ex) { + } catch (std::exception& ex) { throw JException(ex.what()); } return m_actsGeo; @@ -77,13 +80,14 @@ std::shared_ptr RichGeo_service::GetReadoutGeo(std::string // initialize, if not yet initialized try { m_log->debug("Call RichGeo_service::GetReadoutGeo initializer"); - auto initialize = [this,&detector_name] () { - if(!m_dd4hepGeo) throw JException("RichGeo_service m_dd4hepGeo==null which should never be!"); - m_readoutGeo = std::make_shared(detector_name, m_dd4hepGeo, m_converter, m_log); + auto initialize = [this, &detector_name]() { + if (!m_dd4hepGeo) + throw JException("RichGeo_service m_dd4hepGeo==null which should never be!"); + m_readoutGeo = + std::make_shared(detector_name, m_dd4hepGeo, m_converter, m_log); }; std::call_once(m_init_readout, initialize); - } - catch (std::exception &ex) { + } catch (std::exception& ex) { throw JException(ex.what()); } return m_readoutGeo; @@ -94,5 +98,6 @@ RichGeo_service::~RichGeo_service() { try { delete m_irtGeo; delete m_actsGeo; - } catch (...) {} + } catch (...) { + } } diff --git a/src/services/geometry/richgeo/RichGeo_service.h b/src/services/geometry/richgeo/RichGeo_service.h index 1cb7c04551..0d920b70bb 100644 --- a/src/services/geometry/richgeo/RichGeo_service.h +++ b/src/services/geometry/richgeo/RichGeo_service.h @@ -18,31 +18,31 @@ #include "ReadoutGeo.h" class RichGeo_service : public JService { - public: - RichGeo_service(JApplication *app) : m_app(app) {} - virtual ~RichGeo_service(); - - // return pointer to the main DD4hep Detector - virtual const dd4hep::Detector* GetDD4hepGeo() { return m_dd4hepGeo; }; - - // return pointers to geometry bindings; initializes the bindings upon the first time called - virtual richgeo::IrtGeo *GetIrtGeo(std::string detector_name); - virtual richgeo::ActsGeo *GetActsGeo(std::string detector_name); - virtual std::shared_ptr GetReadoutGeo(std::string detector_name); - - private: - RichGeo_service() = default; - void acquire_services(JServiceLocator *) override; - - std::once_flag m_init_irt; - std::once_flag m_init_acts; - std::once_flag m_init_readout; - JApplication *m_app = nullptr; - const dd4hep::Detector* m_dd4hepGeo = nullptr; - const dd4hep::rec::CellIDPositionConverter* m_converter = nullptr; - richgeo::IrtGeo *m_irtGeo = nullptr; - richgeo::ActsGeo *m_actsGeo = nullptr; - std::shared_ptr m_readoutGeo; - - std::shared_ptr m_log; +public: + RichGeo_service(JApplication* app) : m_app(app) {} + virtual ~RichGeo_service(); + + // return pointer to the main DD4hep Detector + virtual const dd4hep::Detector* GetDD4hepGeo() { return m_dd4hepGeo; }; + + // return pointers to geometry bindings; initializes the bindings upon the first time called + virtual richgeo::IrtGeo* GetIrtGeo(std::string detector_name); + virtual richgeo::ActsGeo* GetActsGeo(std::string detector_name); + virtual std::shared_ptr GetReadoutGeo(std::string detector_name); + +private: + RichGeo_service() = default; + void acquire_services(JServiceLocator*) override; + + std::once_flag m_init_irt; + std::once_flag m_init_acts; + std::once_flag m_init_readout; + JApplication* m_app = nullptr; + const dd4hep::Detector* m_dd4hepGeo = nullptr; + const dd4hep::rec::CellIDPositionConverter* m_converter = nullptr; + richgeo::IrtGeo* m_irtGeo = nullptr; + richgeo::ActsGeo* m_actsGeo = nullptr; + std::shared_ptr m_readoutGeo; + + std::shared_ptr m_log; }; diff --git a/src/services/geometry/richgeo/richgeo.cc b/src/services/geometry/richgeo/richgeo.cc index da7a90f7aa..aeb1d22585 100644 --- a/src/services/geometry/richgeo/richgeo.cc +++ b/src/services/geometry/richgeo/richgeo.cc @@ -9,8 +9,8 @@ #include "RichGeo_service.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->ProvideService(std::make_shared(app) ); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->ProvideService(std::make_shared(app)); +} } diff --git a/src/services/io/podio/JEventProcessorPODIO.cc b/src/services/io/podio/JEventProcessorPODIO.cc index 1d6cbf5d4e..535bd3240c 100644 --- a/src/services/io/podio/JEventProcessorPODIO.cc +++ b/src/services/io/podio/JEventProcessorPODIO.cc @@ -21,550 +21,529 @@ #include "services/log/Log_service.h" - JEventProcessorPODIO::JEventProcessorPODIO() { - SetTypeName(NAME_OF_THIS); // Provide JANA with this class's name - - japp->SetDefaultParameter( - "podio:output_file", - m_output_file, - "Name of EDM4hep/podio output file to write to. Setting this will cause the output file to be created and written to." - ); - - // Allow user to set PODIO:OUTPUT_FILE to "1" to specify using the default name. - if( m_output_file == "1" ){ - auto param = japp->GetJParameterManager()->FindParameter("podio:output_file" ); - if(param) { - param->SetValue( param->GetDefault() ); - m_output_file = param->GetDefault(); - } + SetTypeName(NAME_OF_THIS); // Provide JANA with this class's name + + japp->SetDefaultParameter("podio:output_file", m_output_file, + "Name of EDM4hep/podio output file to write to. Setting this will " + "cause the output file to be created and written to."); + + // Allow user to set PODIO:OUTPUT_FILE to "1" to specify using the default name. + if (m_output_file == "1") { + auto param = japp->GetJParameterManager()->FindParameter("podio:output_file"); + if (param) { + param->SetValue(param->GetDefault()); + m_output_file = param->GetDefault(); } - - // Get the output directory path for creating a second copy of the output file at the end of processing. - // (this is duplicating similar functionality in Juggler/Gaudi so assume it is useful). - japp->SetDefaultParameter( - "podio:output_file_copy_dir", - m_output_file_copy_dir, - "Directory name to make an additional copy of the output file to. Copy will be done at end of processing. Default is empty string which means do not make a copy. No check is made on path existing." - ); - - // Get the list of output collections to include/exclude - std::vector output_collections={ - // Header and other metadata - "EventHeader", - - // Truth record - "MCParticles", - "MCBeamElectrons", - "MCBeamProtons", - "MCScatteredElectrons", - "MCScatteredProtons", - "MCParticlesHeadOnFrameNoBeamFX", - - // All tracking hits combined - "CentralTrackingRecHits", - "CentralTrackingRawHitAssociations", - "CentralTrackSeedingResults", - "CentralTrackerMeasurements", - - // Si tracker hits - "SiBarrelTrackerRecHits", - "SiBarrelVertexRecHits", - "SiEndcapTrackerRecHits", - - "SiBarrelRawHits", - "SiBarrelVertexRawHits", - "SiEndcapTrackerRawHits", - - "SiBarrelHits", - "VertexBarrelHits", - "TrackerEndcapHits", - - "SiBarrelRawHitAssociations", - "SiBarrelVertexRawHitAssociations", - "SiEndcapTrackerRawHitAssociations", - - // TOF - "TOFBarrelRecHits", - "TOFEndcapRecHits", - - "TOFBarrelRawHits", - "TOFEndcapRawHits", - - "TOFBarrelHits", - "TOFEndcapHits", - - "TOFBarrelRawHitAssociations", - "TOFEndcapRawHitAssociations", - - "CombinedTOFTruthSeededParticleIDs", - "CombinedTOFParticleIDs", - - // DRICH - "DRICHRawHits", - "DRICHRawHitsAssociations", - "DRICHAerogelTracks", - "DRICHGasTracks", - "DRICHAerogelIrtCherenkovParticleID", - "DRICHGasIrtCherenkovParticleID", - "DRICHTruthSeededParticleIDs", - "DRICHParticleIDs", - - // PFRICH - "RICHEndcapNRawHits", - "RICHEndcapNRawHitsAssociations", - "RICHEndcapNTruthSeededParticleIDs", - "RICHEndcapNParticleIDs", - - // MPGD - "MPGDBarrelRecHits", - "OuterMPGDBarrelRecHits", - "BackwardMPGDEndcapRecHits", - "ForwardMPGDEndcapRecHits", - - "MPGDBarrelRawHits", - "OuterMPGDBarrelRawHits", - "BackwardMPGDEndcapRawHits", - "ForwardMPGDEndcapRawHits", - - "MPGDBarrelHits", - "OuterMPGDBarrelHits", - "BackwardMPGDEndcapHits", - "ForwardMPGDEndcapHits", - - "MPGDBarrelRawHitAssociations", - "OuterMPGDBarrelRawHitAssociations", - "BackwardMPGDEndcapRawHitAssociations", - "ForwardMPGDEndcapRawHitAssociations", - - // LOWQ2 hits - "TaggerTrackerRawHits", - "TaggerTrackerRawHitAssociations", - "TaggerTrackerM1L0ClusterPositions", - "TaggerTrackerM1L1ClusterPositions", - "TaggerTrackerM1L2ClusterPositions", - "TaggerTrackerM1L3ClusterPositions", - "TaggerTrackerM2L0ClusterPositions", - "TaggerTrackerM2L1ClusterPositions", - "TaggerTrackerM2L2ClusterPositions", - "TaggerTrackerM2L3ClusterPositions", - "TaggerTrackerM1Tracks", - "TaggerTrackerM2Tracks", - "TaggerTrackerProjectedTracks", - "TaggerTrackerTracks", - "TaggerTrackerTrajectories", - "TaggerTrackerTrackParameters", - - // Forward & Far forward hits - "B0TrackerRecHits", - "B0TrackerRawHits", - "B0TrackerHits", - "B0TrackerRawHitAssociations", - - "ForwardRomanPotRecHits", - "ForwardOffMTrackerRecHits", - - "ForwardRomanPotRecParticles", - "ForwardOffMRecParticles", - - "ForwardRomanPotRawHitAssociations", - "ForwardOffMTrackerRawHitAssociations", - - // Reconstructed data - "GeneratedParticles", - "GeneratedBreitFrameParticles", - "ReconstructedParticles", - "ReconstructedParticleAssociations", - "ReconstructedTruthSeededChargedParticles", - "ReconstructedTruthSeededChargedParticleAssociations", - "ReconstructedChargedRealPIDParticles", - "ReconstructedChargedParticles", - "ReconstructedChargedParticleAssociations", - "MCScatteredElectronAssociations", // Remove if/when used internally - "MCNonScatteredElectronAssociations", // Remove if/when used internally - "ReconstructedChargedParticleIDs", - "ReconstructedBreitFrameParticles", - "CentralTrackSegments", - "CentralTrackVertices", - "CentralCKFTruthSeededTrajectories", - "CentralCKFTruthSeededTracks", - "CentralCKFTruthSeededTrackAssociations", - "CentralCKFTruthSeededTrackParameters", - "CentralCKFTrajectories", - "CentralCKFTracks", - "CentralCKFTrackAssociations", - "CentralCKFTrackParameters", - //tracking properties - true seeding - "CentralCKFTruthSeededTrajectoriesUnfiltered", - "CentralCKFTruthSeededTracksUnfiltered", - "CentralCKFTruthSeededTrackUnfilteredAssociations", - "CentralCKFTruthSeededTrackParametersUnfiltered", - //tracking properties - realistic seeding - "CentralCKFTrajectoriesUnfiltered", - "CentralCKFTracksUnfiltered", - "CentralCKFTrackUnfilteredAssociations", - "CentralCKFTrackParametersUnfiltered", - "InclusiveKinematicsDA", - "InclusiveKinematicsJB", - "InclusiveKinematicsML", - "InclusiveKinematicsSigma", - "InclusiveKinematicseSigma", // Deprecated, use ESigma - "InclusiveKinematicsESigma", - "InclusiveKinematicsElectron", - "InclusiveKinematicsTruth", - "GeneratedJets", - "GeneratedChargedJets", - "GeneratedCentauroJets", - "ReconstructedJets", - "ReconstructedChargedJets", - "ReconstructedCentauroJets", - "ReconstructedElectrons", - "ScatteredElectronsTruth", - "ScatteredElectronsEMinusPz", - "PrimaryVertices", + } + + // Get the output directory path for creating a second copy of the output file at the end of processing. + // (this is duplicating similar functionality in Juggler/Gaudi so assume it is useful). + japp->SetDefaultParameter("podio:output_file_copy_dir", m_output_file_copy_dir, + "Directory name to make an additional copy of the output file to. Copy " + "will be done at end of processing. Default is empty string which " + "means do not make a copy. No check is made on path existing."); + + // Get the list of output collections to include/exclude + std::vector output_collections = { + // Header and other metadata + "EventHeader", + + // Truth record + "MCParticles", + "MCBeamElectrons", + "MCBeamProtons", + "MCScatteredElectrons", + "MCScatteredProtons", + "MCParticlesHeadOnFrameNoBeamFX", + + // All tracking hits combined + "CentralTrackingRecHits", + "CentralTrackingRawHitAssociations", + "CentralTrackSeedingResults", + "CentralTrackerMeasurements", + + // Si tracker hits + "SiBarrelTrackerRecHits", + "SiBarrelVertexRecHits", + "SiEndcapTrackerRecHits", + + "SiBarrelRawHits", + "SiBarrelVertexRawHits", + "SiEndcapTrackerRawHits", + + "SiBarrelHits", + "VertexBarrelHits", + "TrackerEndcapHits", + + "SiBarrelRawHitAssociations", + "SiBarrelVertexRawHitAssociations", + "SiEndcapTrackerRawHitAssociations", + + // TOF + "TOFBarrelRecHits", + "TOFEndcapRecHits", + + "TOFBarrelRawHits", + "TOFEndcapRawHits", + + "TOFBarrelHits", + "TOFEndcapHits", + + "TOFBarrelRawHitAssociations", + "TOFEndcapRawHitAssociations", + + "CombinedTOFTruthSeededParticleIDs", + "CombinedTOFParticleIDs", + + // DRICH + "DRICHRawHits", + "DRICHRawHitsAssociations", + "DRICHAerogelTracks", + "DRICHGasTracks", + "DRICHAerogelIrtCherenkovParticleID", + "DRICHGasIrtCherenkovParticleID", + "DRICHTruthSeededParticleIDs", + "DRICHParticleIDs", + + // PFRICH + "RICHEndcapNRawHits", + "RICHEndcapNRawHitsAssociations", + "RICHEndcapNTruthSeededParticleIDs", + "RICHEndcapNParticleIDs", + + // MPGD + "MPGDBarrelRecHits", + "OuterMPGDBarrelRecHits", + "BackwardMPGDEndcapRecHits", + "ForwardMPGDEndcapRecHits", + + "MPGDBarrelRawHits", + "OuterMPGDBarrelRawHits", + "BackwardMPGDEndcapRawHits", + "ForwardMPGDEndcapRawHits", + + "MPGDBarrelHits", + "OuterMPGDBarrelHits", + "BackwardMPGDEndcapHits", + "ForwardMPGDEndcapHits", + + "MPGDBarrelRawHitAssociations", + "OuterMPGDBarrelRawHitAssociations", + "BackwardMPGDEndcapRawHitAssociations", + "ForwardMPGDEndcapRawHitAssociations", + + // LOWQ2 hits + "TaggerTrackerRawHits", + "TaggerTrackerRawHitAssociations", + "TaggerTrackerM1L0ClusterPositions", + "TaggerTrackerM1L1ClusterPositions", + "TaggerTrackerM1L2ClusterPositions", + "TaggerTrackerM1L3ClusterPositions", + "TaggerTrackerM2L0ClusterPositions", + "TaggerTrackerM2L1ClusterPositions", + "TaggerTrackerM2L2ClusterPositions", + "TaggerTrackerM2L3ClusterPositions", + "TaggerTrackerM1Tracks", + "TaggerTrackerM2Tracks", + "TaggerTrackerProjectedTracks", + "TaggerTrackerTracks", + "TaggerTrackerTrajectories", + "TaggerTrackerTrackParameters", + + // Forward & Far forward hits + "B0TrackerRecHits", + "B0TrackerRawHits", + "B0TrackerHits", + "B0TrackerRawHitAssociations", + + "ForwardRomanPotRecHits", + "ForwardOffMTrackerRecHits", + + "ForwardRomanPotRecParticles", + "ForwardOffMRecParticles", + + "ForwardRomanPotRawHitAssociations", + "ForwardOffMTrackerRawHitAssociations", + + // Reconstructed data + "GeneratedParticles", + "GeneratedBreitFrameParticles", + "ReconstructedParticles", + "ReconstructedParticleAssociations", + "ReconstructedTruthSeededChargedParticles", + "ReconstructedTruthSeededChargedParticleAssociations", + "ReconstructedChargedRealPIDParticles", + "ReconstructedChargedParticles", + "ReconstructedChargedParticleAssociations", + "MCScatteredElectronAssociations", // Remove if/when used internally + "MCNonScatteredElectronAssociations", // Remove if/when used internally + "ReconstructedChargedParticleIDs", + "ReconstructedBreitFrameParticles", + "CentralTrackSegments", + "CentralTrackVertices", + "CentralCKFTruthSeededTrajectories", + "CentralCKFTruthSeededTracks", + "CentralCKFTruthSeededTrackAssociations", + "CentralCKFTruthSeededTrackParameters", + "CentralCKFTrajectories", + "CentralCKFTracks", + "CentralCKFTrackAssociations", + "CentralCKFTrackParameters", + //tracking properties - true seeding + "CentralCKFTruthSeededTrajectoriesUnfiltered", + "CentralCKFTruthSeededTracksUnfiltered", + "CentralCKFTruthSeededTrackUnfilteredAssociations", + "CentralCKFTruthSeededTrackParametersUnfiltered", + //tracking properties - realistic seeding + "CentralCKFTrajectoriesUnfiltered", + "CentralCKFTracksUnfiltered", + "CentralCKFTrackUnfilteredAssociations", + "CentralCKFTrackParametersUnfiltered", + "InclusiveKinematicsDA", + "InclusiveKinematicsJB", + "InclusiveKinematicsML", + "InclusiveKinematicsSigma", + "InclusiveKinematicseSigma", // Deprecated, use ESigma + "InclusiveKinematicsESigma", + "InclusiveKinematicsElectron", + "InclusiveKinematicsTruth", + "GeneratedJets", + "GeneratedChargedJets", + "GeneratedCentauroJets", + "ReconstructedJets", + "ReconstructedChargedJets", + "ReconstructedCentauroJets", + "ReconstructedElectrons", + "ScatteredElectronsTruth", + "ScatteredElectronsEMinusPz", + "PrimaryVertices", #if EDM4EIC_VERSION_MAJOR >= 6 - "HadronicFinalState", + "HadronicFinalState", #endif - // Track projections - "CalorimeterTrackProjections", - - // Ecal stuff - "EcalEndcapNRawHits", - "EcalEndcapNRecHits", - "EcalEndcapNTruthClusters", - "EcalEndcapNTruthClusterAssociations", - "EcalEndcapNClusters", - "EcalEndcapNClusterAssociations", - "EcalEndcapNSplitMergeClusters", - "EcalEndcapNSplitMergeClusterAssociations", - "EcalEndcapPRawHits", - "EcalEndcapPRecHits", - "EcalEndcapPTruthClusters", - "EcalEndcapPTruthClusterAssociations", - "EcalEndcapPClusters", - "EcalEndcapPClusterAssociations", - "EcalEndcapPSplitMergeClusters", - "EcalEndcapPSplitMergeClusterAssociations", - "EcalEndcapPInsertRawHits", - "EcalEndcapPInsertRecHits", - "EcalEndcapPInsertTruthClusters", - "EcalEndcapPInsertTruthClusterAssociations", - "EcalEndcapPInsertClusters", - "EcalEndcapPInsertClusterAssociations", - "EcalBarrelClusters", - "EcalBarrelClusterAssociations", - "EcalBarrelTruthClusters", - "EcalBarrelTruthClusterAssociations", - "EcalBarrelImagingRawHits", - "EcalBarrelImagingRecHits", - "EcalBarrelImagingClusters", - "EcalBarrelImagingClusterAssociations", - "EcalBarrelScFiRawHits", - "EcalBarrelScFiRecHits", - "EcalBarrelScFiClusters", - "EcalBarrelScFiClusterAssociations", - "EcalLumiSpecRawHits", - "EcalLumiSpecRecHits", - "EcalLumiSpecTruthClusters", - "EcalLumiSpecTruthClusterAssociations", - "EcalLumiSpecClusters", - "EcalLumiSpecClusterAssociations", - "HcalEndcapNRawHits", - "HcalEndcapNRecHits", - "HcalEndcapNMergedHits", - "HcalEndcapNClusters", - "HcalEndcapNClusterAssociations", - "HcalEndcapNSplitMergeClusters", - "HcalEndcapNSplitMergeClusterAssociations", - "HcalEndcapPInsertRawHits", - "HcalEndcapPInsertRecHits", - "HcalEndcapPInsertMergedHits", - "HcalEndcapPInsertClusters", - "HcalEndcapPInsertClusterAssociations", - "LFHCALRawHits", - "LFHCALRecHits", - "LFHCALClusters", - "LFHCALClusterAssociations", - "LFHCALSplitMergeClusters", - "LFHCALSplitMergeClusterAssociations", - "HcalBarrelRawHits", - "HcalBarrelRecHits", - "HcalBarrelMergedHits", - "HcalBarrelClusters", - "HcalBarrelClusterAssociations", - "HcalBarrelSplitMergeClusters", - "HcalBarrelSplitMergeClusterAssociations", - "B0ECalRawHits", - "B0ECalRecHits", - "B0ECalClusters", - "B0ECalClusterAssociations", - "HcalEndcapNTruthClusters", - "HcalEndcapNTruthClusterAssociations", - "HcalBarrelTruthClusters", - "HcalBarrelTruthClusterAssociations", - - //ZDC Ecal - "EcalFarForwardZDCRawHits", - "EcalFarForwardZDCRecHits", - "EcalFarForwardZDCClusters", - "EcalFarForwardZDCClusterAssociations", - "EcalFarForwardZDCTruthClusters", - "EcalFarForwardZDCTruthClusterAssociations", - - //ZDC HCal - "HcalFarForwardZDCRawHits", - "HcalFarForwardZDCRecHits", - "HcalFarForwardZDCSubcellHits", - "HcalFarForwardZDCClusters", - "HcalFarForwardZDCClusterAssociations", - "HcalFarForwardZDCClustersBaseline", - "HcalFarForwardZDCClusterAssociationsBaseline", - "HcalFarForwardZDCTruthClusters", - "HcalFarForwardZDCTruthClusterAssociations", - "ReconstructedFarForwardZDCNeutrons", - - // DIRC - "DIRCRawHits", - "DIRCPID", - "DIRCTruthSeededParticleIDs", - "DIRCParticleIDs", + // Track projections + "CalorimeterTrackProjections", + + // Ecal stuff + "EcalEndcapNRawHits", + "EcalEndcapNRecHits", + "EcalEndcapNTruthClusters", + "EcalEndcapNTruthClusterAssociations", + "EcalEndcapNClusters", + "EcalEndcapNClusterAssociations", + "EcalEndcapNSplitMergeClusters", + "EcalEndcapNSplitMergeClusterAssociations", + "EcalEndcapPRawHits", + "EcalEndcapPRecHits", + "EcalEndcapPTruthClusters", + "EcalEndcapPTruthClusterAssociations", + "EcalEndcapPClusters", + "EcalEndcapPClusterAssociations", + "EcalEndcapPSplitMergeClusters", + "EcalEndcapPSplitMergeClusterAssociations", + "EcalEndcapPInsertRawHits", + "EcalEndcapPInsertRecHits", + "EcalEndcapPInsertTruthClusters", + "EcalEndcapPInsertTruthClusterAssociations", + "EcalEndcapPInsertClusters", + "EcalEndcapPInsertClusterAssociations", + "EcalBarrelClusters", + "EcalBarrelClusterAssociations", + "EcalBarrelTruthClusters", + "EcalBarrelTruthClusterAssociations", + "EcalBarrelImagingRawHits", + "EcalBarrelImagingRecHits", + "EcalBarrelImagingClusters", + "EcalBarrelImagingClusterAssociations", + "EcalBarrelScFiRawHits", + "EcalBarrelScFiRecHits", + "EcalBarrelScFiClusters", + "EcalBarrelScFiClusterAssociations", + "EcalLumiSpecRawHits", + "EcalLumiSpecRecHits", + "EcalLumiSpecTruthClusters", + "EcalLumiSpecTruthClusterAssociations", + "EcalLumiSpecClusters", + "EcalLumiSpecClusterAssociations", + "HcalEndcapNRawHits", + "HcalEndcapNRecHits", + "HcalEndcapNMergedHits", + "HcalEndcapNClusters", + "HcalEndcapNClusterAssociations", + "HcalEndcapNSplitMergeClusters", + "HcalEndcapNSplitMergeClusterAssociations", + "HcalEndcapPInsertRawHits", + "HcalEndcapPInsertRecHits", + "HcalEndcapPInsertMergedHits", + "HcalEndcapPInsertClusters", + "HcalEndcapPInsertClusterAssociations", + "LFHCALRawHits", + "LFHCALRecHits", + "LFHCALClusters", + "LFHCALClusterAssociations", + "LFHCALSplitMergeClusters", + "LFHCALSplitMergeClusterAssociations", + "HcalBarrelRawHits", + "HcalBarrelRecHits", + "HcalBarrelMergedHits", + "HcalBarrelClusters", + "HcalBarrelClusterAssociations", + "HcalBarrelSplitMergeClusters", + "HcalBarrelSplitMergeClusterAssociations", + "B0ECalRawHits", + "B0ECalRecHits", + "B0ECalClusters", + "B0ECalClusterAssociations", + "HcalEndcapNTruthClusters", + "HcalEndcapNTruthClusterAssociations", + "HcalBarrelTruthClusters", + "HcalBarrelTruthClusterAssociations", + + //ZDC Ecal + "EcalFarForwardZDCRawHits", + "EcalFarForwardZDCRecHits", + "EcalFarForwardZDCClusters", + "EcalFarForwardZDCClusterAssociations", + "EcalFarForwardZDCTruthClusters", + "EcalFarForwardZDCTruthClusterAssociations", + + //ZDC HCal + "HcalFarForwardZDCRawHits", + "HcalFarForwardZDCRecHits", + "HcalFarForwardZDCSubcellHits", + "HcalFarForwardZDCClusters", + "HcalFarForwardZDCClusterAssociations", + "HcalFarForwardZDCClustersBaseline", + "HcalFarForwardZDCClusterAssociationsBaseline", + "HcalFarForwardZDCTruthClusters", + "HcalFarForwardZDCTruthClusterAssociations", + "ReconstructedFarForwardZDCNeutrons", + + // DIRC + "DIRCRawHits", + "DIRCPID", + "DIRCTruthSeededParticleIDs", + "DIRCParticleIDs", #if EDM4EIC_VERSION_MAJOR >= 7 - "B0ECalRawHitAssociations", - "EcalBarrelScFiRawHitAssociations", - "EcalBarrelImagingRawHitAssociations", - "HcalBarrelRawHitAssociations", - "EcalEndcapNRawHitAssociations", - "HcalEndcapNRawHitAssociations", - "EcalEndcapPRawHitAssociations", - "EcalEndcapPInsertRawHitAssociations", - "HcalEndcapPInsertRawHitAssociations", - "LFHCALRawHitAssociations", - "EcalLumiSpecRawHitAssociations", - "EcalFarForwardZDCRawHitAssociations", - "HcalFarForwardZDCRawHitAssociations", + "B0ECalRawHitAssociations", + "EcalBarrelScFiRawHitAssociations", + "EcalBarrelImagingRawHitAssociations", + "HcalBarrelRawHitAssociations", + "EcalEndcapNRawHitAssociations", + "HcalEndcapNRawHitAssociations", + "EcalEndcapPRawHitAssociations", + "EcalEndcapPInsertRawHitAssociations", + "HcalEndcapPInsertRawHitAssociations", + "LFHCALRawHitAssociations", + "EcalLumiSpecRawHitAssociations", + "EcalFarForwardZDCRawHitAssociations", + "HcalFarForwardZDCRawHitAssociations", #endif - }; - std::vector output_exclude_collections; // need to get as vector, then convert to set - std::string output_include_collections = "DEPRECATED"; - japp->SetDefaultParameter( - "podio:output_include_collections", - output_include_collections, - "DEPRECATED. Use podio:output_collections instead." - ); - if (output_include_collections != "DEPRECATED") { - output_collections.clear(); - JParameterManager::Parse(output_include_collections, output_collections); - m_output_include_collections_set = true; - } - japp->SetDefaultParameter( - "podio:output_collections", - output_collections, - "Comma separated list of collection names to write out. If not set, all collections will be written (including ones from input file). Don't set this and use PODIO:OUTPUT_EXCLUDE_COLLECTIONS to write everything except a selection." - ); - japp->SetDefaultParameter( - "podio:output_exclude_collections", - output_exclude_collections, - "Comma separated list of collection names to not write out." - ); - japp->SetDefaultParameter( - "podio:print_collections", - m_collections_to_print, - "Comma separated list of collection names to print to screen, e.g. for debugging." - ); - - m_output_collections = std::set(output_collections.begin(), - output_collections.end()); - m_output_exclude_collections = std::set(output_exclude_collections.begin(), - output_exclude_collections.end()); - + }; + std::vector output_exclude_collections; // need to get as vector, then convert to set + std::string output_include_collections = "DEPRECATED"; + japp->SetDefaultParameter("podio:output_include_collections", output_include_collections, + "DEPRECATED. Use podio:output_collections instead."); + if (output_include_collections != "DEPRECATED") { + output_collections.clear(); + JParameterManager::Parse(output_include_collections, output_collections); + m_output_include_collections_set = true; + } + japp->SetDefaultParameter( + "podio:output_collections", output_collections, + "Comma separated list of collection names to write out. If not set, all collections will be " + "written (including ones from input file). Don't set this and use " + "PODIO:OUTPUT_EXCLUDE_COLLECTIONS to write everything except a selection."); + japp->SetDefaultParameter("podio:output_exclude_collections", output_exclude_collections, + "Comma separated list of collection names to not write out."); + japp->SetDefaultParameter( + "podio:print_collections", m_collections_to_print, + "Comma separated list of collection names to print to screen, e.g. for debugging."); + + m_output_collections = + std::set(output_collections.begin(), output_collections.end()); + m_output_exclude_collections = + std::set(output_exclude_collections.begin(), output_exclude_collections.end()); } - void JEventProcessorPODIO::Init() { - auto *app = GetApplication(); - m_log = app->GetService()->logger("JEventProcessorPODIO"); + auto* app = GetApplication(); + m_log = app->GetService()->logger("JEventProcessorPODIO"); #if podio_VERSION >= PODIO_VERSION(0, 99, 0) - m_writer = std::make_unique(m_output_file); + m_writer = std::make_unique(m_output_file); #else - m_writer = std::make_unique(m_output_file); + m_writer = std::make_unique(m_output_file); #endif - // TODO: NWB: Verify that output file is writable NOW, rather than after event processing completes. - // I definitely don't trust PODIO to do this for me. - - if (m_output_include_collections_set) { - m_log->error("The podio:output_include_collections was provided, but is deprecated. Use podio:output_collections instead. Address this to remove the 10 second delay."); - // Adding a delay to ensure users notice the deprecation warning. - using namespace std::chrono_literals; - std::this_thread::sleep_for(10s); - } - + // TODO: NWB: Verify that output file is writable NOW, rather than after event processing completes. + // I definitely don't trust PODIO to do this for me. + + if (m_output_include_collections_set) { + m_log->error("The podio:output_include_collections was provided, but is deprecated. Use " + "podio:output_collections instead. Address this to remove the 10 second delay."); + // Adding a delay to ensure users notice the deprecation warning. + using namespace std::chrono_literals; + std::this_thread::sleep_for(10s); + } } - void JEventProcessorPODIO::FindCollectionsToWrite(const std::shared_ptr& event) { - // Set up the set of collections_to_write. - std::vector all_collections = event->GetAllCollectionNames(); + // Set up the set of collections_to_write. + std::vector all_collections = event->GetAllCollectionNames(); - if (m_output_collections.empty()) { - // User has not specified an include list, so we include _all_ PODIO collections present in the first event. - for (const std::string& col : all_collections) { - if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) { - m_collections_to_write.push_back(col); - m_log->info("Persisting collection '{}'", col); - } - } + if (m_output_collections.empty()) { + // User has not specified an include list, so we include _all_ PODIO collections present in the first event. + for (const std::string& col : all_collections) { + if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) { + m_collections_to_write.push_back(col); + m_log->info("Persisting collection '{}'", col); + } } - else { - m_log->debug("Persisting podio types from includes list"); - m_user_included_collections = true; - - // We match up the include list with what is actually present in the event - std::set all_collections_set = std::set(all_collections.begin(), all_collections.end()); - - for (const auto& col : m_output_collections) { - if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) { - // Included and not excluded - if (all_collections_set.find(col) == all_collections_set.end()) { - // Included, but not a valid PODIO type - m_log->warn("Explicitly included collection '{}' not present in factory set, omitting.", col); - } - else { - // Included, not excluded, and a valid PODIO type - m_collections_to_write.push_back(col); - m_log->info("Persisting collection '{}'", col); - } - } + } else { + m_log->debug("Persisting podio types from includes list"); + m_user_included_collections = true; + + // We match up the include list with what is actually present in the event + std::set all_collections_set = + std::set(all_collections.begin(), all_collections.end()); + + for (const auto& col : m_output_collections) { + if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) { + // Included and not excluded + if (all_collections_set.find(col) == all_collections_set.end()) { + // Included, but not a valid PODIO type + m_log->warn("Explicitly included collection '{}' not present in factory set, omitting.", + col); + } else { + // Included, not excluded, and a valid PODIO type + m_collections_to_write.push_back(col); + m_log->info("Persisting collection '{}'", col); } + } } - + } } -void JEventProcessorPODIO::Process(const std::shared_ptr &event) { - - std::lock_guard lock(m_mutex); - if (m_is_first_event) { - FindCollectionsToWrite(event); +void JEventProcessorPODIO::Process(const std::shared_ptr& event) { + + std::lock_guard lock(m_mutex); + if (m_is_first_event) { + FindCollectionsToWrite(event); + } + + // Trigger all collections once to fix the collection IDs + // TODO: WDC: This should not be necessary, but while we await collection IDs + // that are determined by hash, we have to ensure they are reproducible + // even if the collections are filled in unpredictable order (or not at + // all). See also below, at "TODO: NWB:". + for (const auto& coll_name : m_collections_to_write) { + try { + [[maybe_unused]] + const auto* coll_ptr = event->GetCollectionBase(coll_name); + } catch (std::exception& e) { + // chomp } - - // Trigger all collections once to fix the collection IDs - // TODO: WDC: This should not be necessary, but while we await collection IDs - // that are determined by hash, we have to ensure they are reproducible - // even if the collections are filled in unpredictable order (or not at - // all). See also below, at "TODO: NWB:". - for (const auto& coll_name : m_collections_to_write) { - try { - [[maybe_unused]] - const auto* coll_ptr = event->GetCollectionBase(coll_name); - } - catch(std::exception &e) { - // chomp - } - } - - // Print the contents of some collections, just for debugging purposes - // Do this before writing just in case writing crashes - if (!m_collections_to_print.empty()) { - LOG << "========================================" << LOG_END; - LOG << "JEventProcessorPODIO: Event " << event->GetEventNumber() << LOG_END; - } - for (const auto& coll_name : m_collections_to_print) { - LOG << "------------------------------" << LOG_END; - LOG << coll_name << LOG_END; - try { - const auto* coll_ptr = event->GetCollectionBase(coll_name); - if (coll_ptr == nullptr) { - LOG << "missing" << LOG_END; - } else { - coll_ptr->print(); - } - } - catch(std::exception &e) { - LOG << "missing" << LOG_END; - } + } + + // Print the contents of some collections, just for debugging purposes + // Do this before writing just in case writing crashes + if (!m_collections_to_print.empty()) { + LOG << "========================================" << LOG_END; + LOG << "JEventProcessorPODIO: Event " << event->GetEventNumber() << LOG_END; + } + for (const auto& coll_name : m_collections_to_print) { + LOG << "------------------------------" << LOG_END; + LOG << coll_name << LOG_END; + try { + const auto* coll_ptr = event->GetCollectionBase(coll_name); + if (coll_ptr == nullptr) { + LOG << "missing" << LOG_END; + } else { + coll_ptr->print(); + } + } catch (std::exception& e) { + LOG << "missing" << LOG_END; } - - m_log->trace("=================================="); - m_log->trace("Event #{}", event->GetEventNumber()); - - - // Make sure that all factories get called that need to be written into the frame. - // We need to do this for _all_ factories unless we've constrained it by using includes/excludes. - // Note that all collections need to be present in the first event, as podio::RootFrameWriter constrains us to write one event at a time, so there - // is no way to add a new branch after the first event. - - // If we get an exception below while trying to add a factory for any - // reason then mark that factory as bad and don't try running it again. - // This is motivated by trying to write EcalBarrelSciGlass objects for - // data simulated using the imaging calorimeter. In that case, it will - // always throw an exception, but DD4hep also prints its own error message. - // Thus, to prevent that error message every event, we must avoid calling - // it. - - // Activate factories. - // TODO: NWB: For now we run every factory every time, swallowing exceptions if necessary. - // We do this so that we always have the same collections created in the same order. - // This means that the collection IDs are stable so the writer doesn't segfault. - // The better fix is to maintain a map of collection IDs, or just wait for PODIO to fix the bug. - std::vector successful_collections; - static std::set failed_collections; - for (const std::string& coll : m_collections_to_write) { - try { - m_log->trace("Ensuring factory for collection '{}' has been called.", coll); - const auto* coll_ptr = event->GetCollectionBase(coll); - if (coll_ptr == nullptr) { - // If a collection is missing from the frame, the podio root writer will segfault. - // To avoid this, we treat this as a failing collection and omit from this point onwards. - // However, this code path is expected to be unreachable because any missing collection will be - // replaced with an empty collection in JFactoryPodioTFixed::Create. - if (failed_collections.count(coll) == 0) { - m_log->error("Omitting PODIO collection '{}' because it is null", coll); - failed_collections.insert(coll); - } - } - else { - m_log->trace("Including PODIO collection '{}'", coll); - successful_collections.push_back(coll); - } - } - catch(std::exception &e) { - // Limit printing warning to just once per factory - if (failed_collections.count(coll) == 0) { - m_log->error("Omitting PODIO collection '{}' due to exception: {}.", coll, e.what()); - failed_collections.insert(coll); - } + } + + m_log->trace("=================================="); + m_log->trace("Event #{}", event->GetEventNumber()); + + // Make sure that all factories get called that need to be written into the frame. + // We need to do this for _all_ factories unless we've constrained it by using includes/excludes. + // Note that all collections need to be present in the first event, as podio::RootFrameWriter constrains us to write one event at a time, so there + // is no way to add a new branch after the first event. + + // If we get an exception below while trying to add a factory for any + // reason then mark that factory as bad and don't try running it again. + // This is motivated by trying to write EcalBarrelSciGlass objects for + // data simulated using the imaging calorimeter. In that case, it will + // always throw an exception, but DD4hep also prints its own error message. + // Thus, to prevent that error message every event, we must avoid calling + // it. + + // Activate factories. + // TODO: NWB: For now we run every factory every time, swallowing exceptions if necessary. + // We do this so that we always have the same collections created in the same order. + // This means that the collection IDs are stable so the writer doesn't segfault. + // The better fix is to maintain a map of collection IDs, or just wait for PODIO to fix the bug. + std::vector successful_collections; + static std::set failed_collections; + for (const std::string& coll : m_collections_to_write) { + try { + m_log->trace("Ensuring factory for collection '{}' has been called.", coll); + const auto* coll_ptr = event->GetCollectionBase(coll); + if (coll_ptr == nullptr) { + // If a collection is missing from the frame, the podio root writer will segfault. + // To avoid this, we treat this as a failing collection and omit from this point onwards. + // However, this code path is expected to be unreachable because any missing collection will be + // replaced with an empty collection in JFactoryPodioTFixed::Create. + if (failed_collections.count(coll) == 0) { + m_log->error("Omitting PODIO collection '{}' because it is null", coll); + failed_collections.insert(coll); } + } else { + m_log->trace("Including PODIO collection '{}'", coll); + successful_collections.push_back(coll); + } + } catch (std::exception& e) { + // Limit printing warning to just once per factory + if (failed_collections.count(coll) == 0) { + m_log->error("Omitting PODIO collection '{}' due to exception: {}.", coll, e.what()); + failed_collections.insert(coll); + } } - m_collections_to_write = successful_collections; + } + m_collections_to_write = successful_collections; - // Frame will contain data from all Podio factories that have been triggered, - // including by the `event->GetCollectionBase(coll);` above. - // Note that collections MUST be present in frame. If a collection is null, the writer will segfault. - const auto* frame = event->GetSingle(); + // Frame will contain data from all Podio factories that have been triggered, + // including by the `event->GetCollectionBase(coll);` above. + // Note that collections MUST be present in frame. If a collection is null, the writer will segfault. + const auto* frame = event->GetSingle(); - // TODO: NWB: We need to actively stabilize podio collections. Until then, keep this around in case - // the writer starts segfaulting, so we can quickly see whether the problem is unstable collection IDs. - /* + // TODO: NWB: We need to actively stabilize podio collections. Until then, keep this around in case + // the writer starts segfaulting, so we can quickly see whether the problem is unstable collection IDs. + /* m_log->info("Event {}: Writing {} collections", event->GetEventNumber(), m_collections_to_write.size()); for (const std::string& collname : m_collections_to_write) { m_log->info("Writing collection '{}' with id {}", collname, frame->get(collname)->getID()); } */ - m_writer->writeFrame(*frame, "events", m_collections_to_write); - m_is_first_event = false; - + m_writer->writeFrame(*frame, "events", m_collections_to_write); + m_is_first_event = false; } void JEventProcessorPODIO::Finish() { - if (m_output_include_collections_set) { - m_log->error("The podio:output_include_collections was provided, but is deprecated. Use podio:output_collections instead. Address this to remove the 10 second delay."); - // Adding a delay to ensure users notice the deprecation warning. - using namespace std::chrono_literals; - std::this_thread::sleep_for(10s); - } - - m_writer->finish(); + if (m_output_include_collections_set) { + m_log->error("The podio:output_include_collections was provided, but is deprecated. Use " + "podio:output_collections instead. Address this to remove the 10 second delay."); + // Adding a delay to ensure users notice the deprecation warning. + using namespace std::chrono_literals; + std::this_thread::sleep_for(10s); + } + + m_writer->finish(); } diff --git a/src/services/io/podio/JEventProcessorPODIO.h b/src/services/io/podio/JEventProcessorPODIO.h index 5b59f291dc..67b424d08c 100644 --- a/src/services/io/podio/JEventProcessorPODIO.h +++ b/src/services/io/podio/JEventProcessorPODIO.h @@ -16,36 +16,33 @@ #include #include - class JEventProcessorPODIO : public JEventProcessor { public: + JEventProcessorPODIO(); + virtual ~JEventProcessorPODIO() = default; - JEventProcessorPODIO(); - virtual ~JEventProcessorPODIO() = default; - - void Init() override; - void Process(const std::shared_ptr& event) override; - void Finish() override; + void Init() override; + void Process(const std::shared_ptr& event) override; + void Finish() override; - void FindCollectionsToWrite(const std::shared_ptr& event); + void FindCollectionsToWrite(const std::shared_ptr& event); #if podio_VERSION >= PODIO_VERSION(0, 99, 0) - std::unique_ptr m_writer; + std::unique_ptr m_writer; #else - std::unique_ptr m_writer; + std::unique_ptr m_writer; #endif - std::mutex m_mutex; - bool m_is_first_event = true; - bool m_user_included_collections = false; - std::shared_ptr m_log; - bool m_output_include_collections_set = false; - - std::string m_output_file = "podio_output.root"; - std::string m_output_file_copy_dir = ""; - std::set m_output_collections; // config. parameter - std::set m_output_exclude_collections; // config. parameter - std::vector m_collections_to_write; // derived from above config. parameters - std::vector m_collections_to_print; - + std::mutex m_mutex; + bool m_is_first_event = true; + bool m_user_included_collections = false; + std::shared_ptr m_log; + bool m_output_include_collections_set = false; + + std::string m_output_file = "podio_output.root"; + std::string m_output_file_copy_dir = ""; + std::set m_output_collections; // config. parameter + std::set m_output_exclude_collections; // config. parameter + std::vector m_collections_to_write; // derived from above config. parameters + std::vector m_collections_to_print; }; diff --git a/src/services/io/podio/JEventSourcePODIO.cc b/src/services/io/podio/JEventSourcePODIO.cc index 8a93d39bc8..7312874a7b 100644 --- a/src/services/io/podio/JEventSourcePODIO.cc +++ b/src/services/io/podio/JEventSourcePODIO.cc @@ -30,7 +30,6 @@ #include "services/io/podio/datamodel_glue.h" #include "services/io/podio/datamodel_includes.h" // IWYU pragma: keep - //------------------------------------------------------------------------------ // InsertingVisitor // @@ -43,20 +42,19 @@ /// \param collection_name name of the collection which will be used as the factory tag for these objects //------------------------------------------------------------------------------ struct InsertingVisitor { - JEvent& m_event; - const std::string& m_collection_name; + JEvent& m_event; + const std::string& m_collection_name; - InsertingVisitor(JEvent& event, const std::string& collection_name) : m_event(event), m_collection_name(collection_name){}; + InsertingVisitor(JEvent& event, const std::string& collection_name) + : m_event(event), m_collection_name(collection_name) {}; - template - void operator() (const T& collection) { + template void operator()(const T& collection) { - using ContentsT = decltype(collection[0]); - m_event.InsertCollectionAlreadyInFrame(&collection, m_collection_name); - } + using ContentsT = decltype(collection[0]); + m_event.InsertCollectionAlreadyInFrame(&collection, m_collection_name); + } }; - //------------------------------------------------------------------------------ // Constructor // @@ -64,33 +62,28 @@ struct InsertingVisitor { /// \param resource_name Name of root file to open (n.b. file is not opened until Open() is called) /// \param app JApplication //------------------------------------------------------------------------------ -JEventSourcePODIO::JEventSourcePODIO(std::string resource_name, JApplication* app) : JEventSource(resource_name, app) { - SetTypeName(NAME_OF_THIS); // Provide JANA with class name +JEventSourcePODIO::JEventSourcePODIO(std::string resource_name, JApplication* app) + : JEventSource(resource_name, app) { + SetTypeName(NAME_OF_THIS); // Provide JANA with class name #if JANA_NEW_CALLBACK_STYLE - SetCallbackStyle(CallbackStyle::ExpertMode); // Use new, exception-free Emit() callback + SetCallbackStyle(CallbackStyle::ExpertMode); // Use new, exception-free Emit() callback #endif - // Tell JANA that we want it to call the FinishEvent() method. - // EnableFinishEvent(); + // Tell JANA that we want it to call the FinishEvent() method. + // EnableFinishEvent(); - // Allow user to specify to recycle events forever - GetApplication()->SetDefaultParameter( - "podio:run_forever", - m_run_forever, - "set to true to recycle through events continuously" - ); + // Allow user to specify to recycle events forever + GetApplication()->SetDefaultParameter("podio:run_forever", m_run_forever, + "set to true to recycle through events continuously"); - bool print_type_table = false; - GetApplication()->SetDefaultParameter( - "podio:print_type_table", - print_type_table, - "Print list of collection names and their types" - ); + bool print_type_table = false; + GetApplication()->SetDefaultParameter("podio:print_type_table", print_type_table, + "Print list of collection names and their types"); - // Hopefully we won't need to reimplement background event merging. Using podio frames, it looks like we would - // have to do a deep copy of all data in order to insert it into the same frame, which would probably be - // quite inefficient. - /* + // Hopefully we won't need to reimplement background event merging. Using podio frames, it looks like we would + // have to do a deep copy of all data in order to insert it into the same frame, which would probably be + // quite inefficient. + /* std::string background_filename; GetApplication()->SetDefaultParameter( "podio:background_filename", @@ -111,7 +104,7 @@ JEventSourcePODIO::JEventSourcePODIO(std::string resource_name, JApplication* ap // Destructor //------------------------------------------------------------------------------ JEventSourcePODIO::~JEventSourcePODIO() { - LOG << "Closing Event Source for " << GetResourceName() << LOG_END; + LOG << "Closing Event Source for " << GetResourceName() << LOG_END; } //------------------------------------------------------------------------------ @@ -121,37 +114,40 @@ JEventSourcePODIO::~JEventSourcePODIO() { //------------------------------------------------------------------------------ void JEventSourcePODIO::Open() { - bool print_type_table = GetApplication()->GetParameterValue("podio:print_type_table"); - // std::string background_filename = GetApplication()->GetParameterValue("podio:background_filename");; - // int num_background_events = GetApplication()->GetParameterValue("podio:num_background_events");; + bool print_type_table = GetApplication()->GetParameterValue("podio:print_type_table"); + // std::string background_filename = GetApplication()->GetParameterValue("podio:background_filename");; + // int num_background_events = GetApplication()->GetParameterValue("podio:num_background_events");; - // Open primary events file - try { + // Open primary events file + try { - m_reader.openFile( GetResourceName() ); + m_reader.openFile(GetResourceName()); - auto version = m_reader.currentFileVersion(); - bool version_mismatch = version.major > podio::version::build_version.major; - version_mismatch |= (version.major == podio::version::build_version.major) && (version.minor>podio::version::build_version.minor); - if( version_mismatch ) { - std::stringstream ss; - ss << "Mismatch in PODIO versions! " << version << " > " << podio::version::build_version; - // FIXME: The podio ROOTReader is somehow failing to read in the correct version numbers from the file -// throw JException(ss.str()); - } + auto version = m_reader.currentFileVersion(); + bool version_mismatch = version.major > podio::version::build_version.major; + version_mismatch |= (version.major == podio::version::build_version.major) && + (version.minor > podio::version::build_version.minor); + if (version_mismatch) { + std::stringstream ss; + ss << "Mismatch in PODIO versions! " << version << " > " << podio::version::build_version; + // FIXME: The podio ROOTReader is somehow failing to read in the correct version numbers from the file + // throw JException(ss.str()); + } - LOG << "PODIO version: file=" << version << " (executable=" << podio::version::build_version << ")" << LOG_END; + LOG << "PODIO version: file=" << version << " (executable=" << podio::version::build_version + << ")" << LOG_END; - Nevents_in_file = m_reader.getEntries("events"); - LOG << "Opened PODIO Frame file \"" << GetResourceName() << "\" with " << Nevents_in_file << " events" << LOG_END; + Nevents_in_file = m_reader.getEntries("events"); + LOG << "Opened PODIO Frame file \"" << GetResourceName() << "\" with " << Nevents_in_file + << " events" << LOG_END; - if( print_type_table ) PrintCollectionTypeTable(); - - }catch (std::exception &e ){ - LOG_ERROR(default_cerr_logger) << e.what() << LOG_END; - throw JException( fmt::format( "Problem opening file \"{}\"", GetResourceName() ) ); - } + if (print_type_table) + PrintCollectionTypeTable(); + } catch (std::exception& e) { + LOG_ERROR(default_cerr_logger) << e.what() << LOG_END; + throw JException(fmt::format("Problem opening file \"{}\"", GetResourceName())); + } } //------------------------------------------------------------------------------ @@ -162,11 +158,10 @@ void JEventSourcePODIO::Open() { /// \param event //------------------------------------------------------------------------------ void JEventSourcePODIO::Close() { - // m_reader.close(); - // TODO: ROOTReader does not appear to have a close() method. + // m_reader.close(); + // TODO: ROOTReader does not appear to have a close() method. } - //------------------------------------------------------------------------------ // GetEvent // @@ -178,52 +173,54 @@ void JEventSourcePODIO::Close() { JEventSourcePODIO::Result JEventSourcePODIO::Emit(JEvent& event) { #else void JEventSourcePODIO::GetEvent(std::shared_ptr _event) { - auto &event = *_event; + auto& event = *_event; #endif - /// Calls to GetEvent are synchronized with each other, which means they can - /// read and write state on the JEventSource without causing race conditions. + /// Calls to GetEvent are synchronized with each other, which means they can + /// read and write state on the JEventSource without causing race conditions. - // Check if we have exhausted events from file - if( Nevents_read >= Nevents_in_file ) { - if( m_run_forever ){ - Nevents_read = 0; - } else { + // Check if we have exhausted events from file + if (Nevents_read >= Nevents_in_file) { + if (m_run_forever) { + Nevents_read = 0; + } else { #if JANA_NEW_CALLBACK_STYLE - return Result::FailureFinished; + return Result::FailureFinished; #else - throw RETURN_STATUS::kNO_MORE_EVENTS; + throw RETURN_STATUS::kNO_MORE_EVENTS; #endif - } } - - auto frame_data = m_reader.readEntry("events", Nevents_read); - auto frame = std::make_unique(std::move(frame_data)); - - if(m_use_event_headers){ - const auto& event_headers = frame->get("EventHeader"); - if (event_headers.size() != 1) { - LOG_WARN(default_cerr_logger) << "Missing or bad event headers: Entry " << Nevents_read << " contains " << event_headers.size() << " items, but 1 expected. Will not use event and run numbers from header" << LOG_END; - m_use_event_headers = false; - } - else { - event.SetEventNumber(event_headers[0].getEventNumber()); - event.SetRunNumber(event_headers[0].getRunNumber()); - } - } - - // Insert contents odf frame into JFactories - VisitPodioCollection visit; - for (const std::string& coll_name : frame->getAvailableCollections()) { - const podio::CollectionBase* collection = frame->get(coll_name); - InsertingVisitor visitor(event, coll_name); - visit(visitor, *collection); + } + + auto frame_data = m_reader.readEntry("events", Nevents_read); + auto frame = std::make_unique(std::move(frame_data)); + + if (m_use_event_headers) { + const auto& event_headers = frame->get("EventHeader"); + if (event_headers.size() != 1) { + LOG_WARN(default_cerr_logger) + << "Missing or bad event headers: Entry " << Nevents_read << " contains " + << event_headers.size() + << " items, but 1 expected. Will not use event and run numbers from header" << LOG_END; + m_use_event_headers = false; + } else { + event.SetEventNumber(event_headers[0].getEventNumber()); + event.SetRunNumber(event_headers[0].getRunNumber()); } - - event.Insert(frame.release()); // Transfer ownership from unique_ptr to JFactoryT - Nevents_read += 1; + } + + // Insert contents odf frame into JFactories + VisitPodioCollection visit; + for (const std::string& coll_name : frame->getAvailableCollections()) { + const podio::CollectionBase* collection = frame->get(coll_name); + InsertingVisitor visitor(event, coll_name); + visit(visitor, *collection); + } + + event.Insert(frame.release()); // Transfer ownership from unique_ptr to JFactoryT + Nevents_read += 1; #if JANA_NEW_CALLBACK_STYLE - return Result::Success; + return Result::Success; #endif } @@ -232,8 +229,8 @@ void JEventSourcePODIO::GetEvent(std::shared_ptr _event) { //------------------------------------------------------------------------------ std::string JEventSourcePODIO::GetDescription() { - /// GetDescription() helps JANA explain to the user what is going on - return "PODIO root file (Frames, podio >= v0.16.3)"; + /// GetDescription() helps JANA explain to the user what is going on + return "PODIO root file (Frames, podio >= v0.16.3)"; } //------------------------------------------------------------------------------ @@ -251,20 +248,23 @@ std::string JEventSourcePODIO::GetDescription() { template <> double JEventSourceGeneratorT::CheckOpenable(std::string resource_name) { - // PODIO Frame reader gets slightly higher precedence than PODIO Legacy reader, but only if the file - // contains a 'podio_metadata' TTree. If the file doesn't exist, this will return 0. The "file not found" - // error will hopefully be generated by the PODIO legacy reader instead. - if (resource_name.find(".root") == std::string::npos ) return 0.0; - - // PODIO FrameReader segfaults on legacy input files, so we use ROOT to validate beforehand. Of course, - // we can't validate if ROOT can't read the file. - std::unique_ptr file = std::unique_ptr{TFile::Open(resource_name.c_str())}; - if (!file || file->IsZombie()) return 0.0; - - // We test the format the same way that PODIO's python API does. See python/podio/reading.py - TObject* tree = file->Get("podio_metadata"); - if (tree == nullptr) return 0.0; - return 0.03; + // PODIO Frame reader gets slightly higher precedence than PODIO Legacy reader, but only if the file + // contains a 'podio_metadata' TTree. If the file doesn't exist, this will return 0. The "file not found" + // error will hopefully be generated by the PODIO legacy reader instead. + if (resource_name.find(".root") == std::string::npos) + return 0.0; + + // PODIO FrameReader segfaults on legacy input files, so we use ROOT to validate beforehand. Of course, + // we can't validate if ROOT can't read the file. + std::unique_ptr file = std::unique_ptr{TFile::Open(resource_name.c_str())}; + if (!file || file->IsZombie()) + return 0.0; + + // We test the format the same way that PODIO's python API does. See python/podio/reading.py + TObject* tree = file->Get("podio_metadata"); + if (tree == nullptr) + return 0.0; + return 0.03; } //------------------------------------------------------------------------------ @@ -276,35 +276,36 @@ double JEventSourceGeneratorT::CheckOpenable(std::string reso //------------------------------------------------------------------------------ void JEventSourcePODIO::PrintCollectionTypeTable(void) { - // Read the zeroth entry. This assumes that m_reader has already been initialized with a valid filename - auto frame_data = m_reader.readEntry("events", 0); - auto frame = std::make_unique(std::move(frame_data)); - - std::map collectionNames; - size_t max_name_len = 0; - size_t max_type_len = 0; - - // Record all (collection name, value type name) pairs - // Record the maximum length of both strings so that we can print nicely aligned columns. - for (const std::string& name : frame->getAvailableCollections()) { - const podio::CollectionBase* coll = frame->get(name); - const auto type = coll->getTypeName(); - max_name_len = std::max(max_name_len, name.length()); - max_type_len = std::max(max_type_len, type.length()); - collectionNames[name] = std::string(type); - } - - // Print table - std::cout << std::endl; - std::cout << "Available Collections" << std::endl; - std::cout << std::endl; - std::cout << "Collection Name" << std::string(max_name_len + 2 - std::string("Collection Name").length(), ' ') - << "Data Type" << std::endl; - std::cout << std::string(max_name_len, '-') << " " << std::string(max_name_len, '-') << std::endl; - for (auto &[name, type] : collectionNames) { - std::cout << name + std::string(max_name_len + 2 - name.length(), ' '); - std::cout << type << std::endl; - } - std::cout << std::endl; - + // Read the zeroth entry. This assumes that m_reader has already been initialized with a valid filename + auto frame_data = m_reader.readEntry("events", 0); + auto frame = std::make_unique(std::move(frame_data)); + + std::map collectionNames; + size_t max_name_len = 0; + size_t max_type_len = 0; + + // Record all (collection name, value type name) pairs + // Record the maximum length of both strings so that we can print nicely aligned columns. + for (const std::string& name : frame->getAvailableCollections()) { + const podio::CollectionBase* coll = frame->get(name); + const auto type = coll->getTypeName(); + max_name_len = std::max(max_name_len, name.length()); + max_type_len = std::max(max_type_len, type.length()); + collectionNames[name] = std::string(type); + } + + // Print table + std::cout << std::endl; + std::cout << "Available Collections" << std::endl; + std::cout << std::endl; + std::cout << "Collection Name" + << std::string(max_name_len + 2 - std::string("Collection Name").length(), ' ') + << "Data Type" << std::endl; + std::cout << std::string(max_name_len, '-') << " " << std::string(max_name_len, '-') + << std::endl; + for (auto& [name, type] : collectionNames) { + std::cout << name + std::string(max_name_len + 2 - name.length(), ' '); + std::cout << type << std::endl; + } + std::cout << std::endl; } diff --git a/src/services/io/podio/JEventSourcePODIO.h b/src/services/io/podio/JEventSourcePODIO.h index eef243d012..503f44f920 100644 --- a/src/services/io/podio/JEventSourcePODIO.h +++ b/src/services/io/podio/JEventSourcePODIO.h @@ -26,38 +26,36 @@ class JEventSourcePODIO : public JEventSource { public: - JEventSourcePODIO(std::string resource_name, JApplication* app); + JEventSourcePODIO(std::string resource_name, JApplication* app); - virtual ~JEventSourcePODIO(); + virtual ~JEventSourcePODIO(); - void Open() override; + void Open() override; - void Close() override; + void Close() override; #if JANA_NEW_CALLBACK_STYLE - Result Emit(JEvent& event) override; + Result Emit(JEvent& event) override; #else - void GetEvent(std::shared_ptr) override; + void GetEvent(std::shared_ptr) override; #endif - static std::string GetDescription(); + static std::string GetDescription(); - void PrintCollectionTypeTable(void); + void PrintCollectionTypeTable(void); protected: #if podio_VERSION >= PODIO_VERSION(0, 99, 0) - podio::ROOTReader m_reader; + podio::ROOTReader m_reader; #else - podio::ROOTFrameReader m_reader; + podio::ROOTFrameReader m_reader; #endif - size_t Nevents_in_file = 0; - size_t Nevents_read = 0; - - bool m_run_forever=false; - bool m_use_event_headers=true; + size_t Nevents_in_file = 0; + size_t Nevents_read = 0; + bool m_run_forever = false; + bool m_use_event_headers = true; }; -template <> -double JEventSourceGeneratorT::CheckOpenable(std::string); +template <> double JEventSourceGeneratorT::CheckOpenable(std::string); diff --git a/src/services/io/podio/podio.cc b/src/services/io/podio/podio.cc index 829527f104..96465e03a6 100644 --- a/src/services/io/podio/podio.cc +++ b/src/services/io/podio/podio.cc @@ -9,21 +9,20 @@ #include "JEventProcessorPODIO.h" #include "JEventSourcePODIO.h" - // Make this a JANA plugin extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->Add(new JEventSourceGeneratorT()); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new JEventSourceGeneratorT()); - // Disable this behavior for now so one can run eicrecon with only the - // input file as an argument. - // Only add a EICRootWriter if the user has specified a configuration parameter relevant to writing -// if( app->GetJParameterManager()->Exists("podio:output_file") -// || app->GetJParameterManager()->Exists("podio:output_file_copy_dir") -// || app->GetJParameterManager()->Exists("podio:output_include_collections") -// || app->GetJParameterManager()->Exists("podio:output_exclude_collections") ){ - app->Add(new JEventProcessorPODIO()); -// } + // Disable this behavior for now so one can run eicrecon with only the + // input file as an argument. + // Only add a EICRootWriter if the user has specified a configuration parameter relevant to writing + // if( app->GetJParameterManager()->Exists("podio:output_file") + // || app->GetJParameterManager()->Exists("podio:output_file_copy_dir") + // || app->GetJParameterManager()->Exists("podio:output_include_collections") + // || app->GetJParameterManager()->Exists("podio:output_exclude_collections") ){ + app->Add(new JEventProcessorPODIO()); + // } } } diff --git a/src/services/log/Log_service.cc b/src/services/log/Log_service.cc index d57ca11576..4ba9ea3ec0 100644 --- a/src/services/log/Log_service.cc +++ b/src/services/log/Log_service.cc @@ -10,53 +10,55 @@ #include "extensions/spdlog/SpdlogExtensions.h" +Log_service::Log_service(JApplication* app) { + // Here one could add centralized documentation for spdlog::default_logger() + // All subsequent loggers are cloned from the spdlog::default_logger() + m_application = app; -Log_service::Log_service(JApplication *app) { - // Here one could add centralized documentation for spdlog::default_logger() - // All subsequent loggers are cloned from the spdlog::default_logger() - m_application = app; + m_log_level_str = "info"; + m_application->SetDefaultParameter("eicrecon:LogLevel", m_log_level_str, + "log_level: trace, debug, info, warn, error, critical, off"); + spdlog::default_logger()->set_level(eicrecon::ParseLogLevel(m_log_level_str)); - m_log_level_str = "info"; - m_application->SetDefaultParameter("eicrecon:LogLevel", m_log_level_str, "log_level: trace, debug, info, warn, error, critical, off"); - spdlog::default_logger()->set_level(eicrecon::ParseLogLevel(m_log_level_str)); - - m_log_format_str = "[%n] [%^%l%$] %v"; - m_application->SetDefaultParameter("eicrecon:LogFormat", m_log_level_str, "spdlog pattern string"); - spdlog::set_pattern(m_log_format_str); + m_log_format_str = "[%n] [%^%l%$] %v"; + m_application->SetDefaultParameter("eicrecon:LogFormat", m_log_level_str, + "spdlog pattern string"); + spdlog::set_pattern(m_log_format_str); } - // Virtual destructor implementation to pin vtable and typeinfo to this // translation unit Log_service::~Log_service() {}; +std::shared_ptr Log_service::logger(const std::string& name, + const std::optional default_level) { -std::shared_ptr Log_service::logger( - const std::string &name, - const std::optional default_level) { - - try { - std::lock_guard locker(m_lock); + try { + std::lock_guard locker(m_lock); - // Try to get existing logger - auto logger = spdlog::get(name); - if(!logger) { - // or create a new one with current configuration - logger = spdlog::default_logger()->clone(name); + // Try to get existing logger + auto logger = spdlog::get(name); + if (!logger) { + // or create a new one with current configuration + logger = spdlog::default_logger()->clone(name); - // Set log level for this named logger allowing user to specify as config. parameter - // e.g. EcalEndcapPRecHits:LogLevel - std::string log_level_str = default_level ? eicrecon::LogLevelToString(default_level.value()) : m_log_level_str; - m_application->SetDefaultParameter(name+":LogLevel", log_level_str, "log_level for "+name+": trace, debug, info, warn, error, critical, off"); - logger->set_level(eicrecon::ParseLogLevel(log_level_str)); - } - return logger; - } - catch(const std::exception & exception) { - throw JException(exception.what()); + // Set log level for this named logger allowing user to specify as config. parameter + // e.g. EcalEndcapPRecHits:LogLevel + std::string log_level_str = + default_level ? eicrecon::LogLevelToString(default_level.value()) : m_log_level_str; + m_application->SetDefaultParameter(name + ":LogLevel", log_level_str, + "log_level for " + name + + ": trace, debug, info, warn, error, critical, off"); + logger->set_level(eicrecon::ParseLogLevel(log_level_str)); } + return logger; + } catch (const std::exception& exception) { + throw JException(exception.what()); + } } -Log_service::level Log_service::getDefaultLevel() {return spdlog::default_logger()->level();} +Log_service::level Log_service::getDefaultLevel() { return spdlog::default_logger()->level(); } -std::string Log_service::getDefaultLevelStr() {return eicrecon::LogLevelToString(getDefaultLevel());} +std::string Log_service::getDefaultLevelStr() { + return eicrecon::LogLevelToString(getDefaultLevel()); +} diff --git a/src/services/log/Log_service.h b/src/services/log/Log_service.h index 9a5a55d8e8..e4810de599 100644 --- a/src/services/log/Log_service.h +++ b/src/services/log/Log_service.h @@ -1,6 +1,5 @@ #pragma once - #include #include #include @@ -13,34 +12,31 @@ /** * The Service centralizes use of spdlog */ -class Log_service : public JService -{ +class Log_service : public JService { public: - using level = spdlog::level::level_enum; + using level = spdlog::level::level_enum; public: - explicit Log_service(JApplication *app); - ~Log_service(); + explicit Log_service(JApplication* app); + ~Log_service(); - /** Get a named logger with optional level + /** Get a named logger with optional level * When no level is specified, the service default is used **/ - virtual std::shared_ptr logger( - const std::string &name, - const std::optional default_level = std::nullopt); + virtual std::shared_ptr + logger(const std::string& name, const std::optional default_level = std::nullopt); - /** Gets the default level for all loggers + /** Gets the default level for all loggers * The log level is set from user parameters or is 'info'**/ - virtual level getDefaultLevel(); + virtual level getDefaultLevel(); - /** Gets std::string version of the default log level **/ - virtual std::string getDefaultLevelStr(); + /** Gets std::string version of the default log level **/ + virtual std::string getDefaultLevelStr(); private: + Log_service() = default; - Log_service()=default; - - std::recursive_mutex m_lock; - JApplication* m_application; - std::string m_log_level_str; - std::string m_log_format_str; + std::recursive_mutex m_lock; + JApplication* m_application; + std::string m_log_level_str; + std::string m_log_format_str; }; diff --git a/src/services/log/log.cc b/src/services/log/log.cc index b1f6db3d37..42a34160dc 100644 --- a/src/services/log/log.cc +++ b/src/services/log/log.cc @@ -8,10 +8,9 @@ #include "Log_service.h" - extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->ProvideService(std::make_shared(app) ); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->ProvideService(std::make_shared(app)); } } diff --git a/src/services/pid_lut/PIDLookupTable.cc b/src/services/pid_lut/PIDLookupTable.cc index f4566192ff..eb5236025a 100644 --- a/src/services/pid_lut/PIDLookupTable.cc +++ b/src/services/pid_lut/PIDLookupTable.cc @@ -23,123 +23,113 @@ namespace bh = boost::histogram; namespace eicrecon { -const PIDLookupTable::Entry* PIDLookupTable::Lookup(int pdg, int charge, double momentum, double theta_deg, double phi_deg) const { - // Our lookup table expects _unsigned_ PDGs. The charge information is passed separately. - pdg = std::abs(pdg); - - if (m_symmetrizing_charges) { - charge = std::abs(charge); - } - - return &m_hist[ - decltype(m_hist)::multi_index_type { - m_hist.axis(0).index(pdg), - m_hist.axis(1).index(charge), - m_hist.axis(2).index(momentum), - m_hist.axis(3).index(theta_deg), - m_hist.axis(4).index(phi_deg) - } - ]; +const PIDLookupTable::Entry* PIDLookupTable::Lookup(int pdg, int charge, double momentum, + double theta_deg, double phi_deg) const { + // Our lookup table expects _unsigned_ PDGs. The charge information is passed separately. + pdg = std::abs(pdg); + + if (m_symmetrizing_charges) { + charge = std::abs(charge); + } + + return &m_hist[decltype(m_hist)::multi_index_type{ + m_hist.axis(0).index(pdg), m_hist.axis(1).index(charge), m_hist.axis(2).index(momentum), + m_hist.axis(3).index(theta_deg), m_hist.axis(4).index(phi_deg)}]; } -void PIDLookupTable::load_file(const std::string& filename, const PIDLookupTable::Binning &binning) { - bool is_compressed = filename.substr(filename.length() - 3) == ".gz"; - - std::ios_base::openmode mode = std::ios_base::in; - if (is_compressed) { - mode |= std::ios_base::binary; - } - - std::ifstream file(filename, mode); - if (!file) { - throw std::runtime_error("Unable to open LUT file!"); - } - boost::iostreams::filtering_istream in; - if (is_compressed) { - in.push(boost::iostreams::gzip_decompressor()); - } - in.push(file); - - std::string line; - std::istringstream iss; - double step; - - const double angle_fudge = binning.use_radians ? 180. / M_PI : 1.; +void PIDLookupTable::load_file(const std::string& filename, + const PIDLookupTable::Binning& binning) { + bool is_compressed = filename.substr(filename.length() - 3) == ".gz"; + + std::ios_base::openmode mode = std::ios_base::in; + if (is_compressed) { + mode |= std::ios_base::binary; + } + + std::ifstream file(filename, mode); + if (!file) { + throw std::runtime_error("Unable to open LUT file!"); + } + boost::iostreams::filtering_istream in; + if (is_compressed) { + in.push(boost::iostreams::gzip_decompressor()); + } + in.push(file); + + std::string line; + std::istringstream iss; + double step; + + const double angle_fudge = binning.use_radians ? 180. / M_PI : 1.; + + bh::axis::category pdg_bins(binning.pdg_values); + bh::axis::category charge_bins(binning.charge_values); + bh::axis::variable<> momentum_bins(binning.momentum_edges); + std::vector polar_edges = binning.polar_edges; + for (double& edge : polar_edges) { + edge *= angle_fudge; + } + bh::axis::variable<> polar_bins(polar_edges); + bh::axis::circular<> azimuthal_bins(bh::axis::step(binning.azimuthal_binning.at(2) * angle_fudge), + binning.azimuthal_binning.at(0) * angle_fudge, + binning.azimuthal_binning.at(1) * angle_fudge); + + m_hist = bh::make_histogram_with(bh::dense_storage(), pdg_bins, + charge_bins, momentum_bins, polar_bins, azimuthal_bins); + + m_symmetrizing_charges = binning.charge_values.size() == 1; + + while (std::getline(in, line)) { + Entry entry; + if (line.empty() || line[0] == '#' || + std::all_of(std::begin(line), std::end(line), + [](unsigned char c) { return std::isspace(c); })) + continue; + + iss.str(line); + iss.clear(); + double pdg, charge, momentum, eta, phi, prob_electron, prob_pion, prob_kaon, prob_proton; + // Read each field from the line and assign to Entry struct members + if ((bool)(iss >> pdg >> charge >> momentum >> eta >> phi) && + (binning.missing_electron_prob || (bool)(iss >> prob_electron)) && + (bool)(iss >> prob_pion >> prob_kaon >> prob_proton)) { + + if (m_symmetrizing_charges) { + charge = std::abs(charge); + } - bh::axis::category pdg_bins(binning.pdg_values); - bh::axis::category charge_bins(binning.charge_values); - bh::axis::variable<> momentum_bins(binning.momentum_edges); - std::vector polar_edges = binning.polar_edges; - for (double &edge : polar_edges) { - edge *= angle_fudge; + // operator() here allows to lookup mutable entry and increases the access counter + auto& entry = *m_hist( + pdg, charge, + momentum + + (binning.momentum_bin_centers_in_lut ? 0. : (momentum_bins.bin(0).width() / 2)), + eta * angle_fudge + + (binning.polar_bin_centers_in_lut ? 0. : (polar_bins.bin(0).width() / 2)), + phi * angle_fudge + (binning.azimuthal_bin_centers_in_lut + ? 0. + : (azimuthal_bins.bin(0).width() / + 2))); // N.B. bin(0) may not be of a correct width + entry.prob_electron = prob_electron; + entry.prob_pion = prob_pion; + entry.prob_kaon = prob_kaon; + entry.prob_proton = prob_proton; + } else { + error("Unable to parse LUT file!"); + throw std::runtime_error("Unable to parse LUT file!"); } - bh::axis::variable<> polar_bins(polar_edges); - bh::axis::circular<> azimuthal_bins(bh::axis::step(binning.azimuthal_binning.at(2) * angle_fudge), binning.azimuthal_binning.at(0) * angle_fudge, binning.azimuthal_binning.at(1) * angle_fudge); - - m_hist = bh::make_histogram_with(bh::dense_storage(), pdg_bins, charge_bins, momentum_bins, polar_bins, azimuthal_bins); - - m_symmetrizing_charges = binning.charge_values.size() == 1; - - while (std::getline(in, line)) { - Entry entry; - if (line.empty() || line[0] == '#' || std::all_of(std::begin(line), std::end(line), [](unsigned char c) { return std::isspace(c); })) continue; - - iss.str(line); - iss.clear(); - double pdg, charge, momentum, eta, phi, prob_electron, prob_pion, prob_kaon, prob_proton; - // Read each field from the line and assign to Entry struct members - if ((bool)(iss >> pdg - >> charge - >> momentum - >> eta - >> phi) && (binning.missing_electron_prob || (bool)(iss - >> prob_electron)) && (bool)(iss - >> prob_pion - >> prob_kaon - >> prob_proton)) { - - if (m_symmetrizing_charges) { - charge = std::abs(charge); - } - - // operator() here allows to lookup mutable entry and increases the access counter - auto &entry = *m_hist( - pdg, - charge, - momentum + (binning.momentum_bin_centers_in_lut ? 0. : (momentum_bins.bin(0).width() / 2)), - eta * angle_fudge + (binning.polar_bin_centers_in_lut ? 0. : (polar_bins.bin(0).width() / 2)), - phi * angle_fudge + (binning.azimuthal_bin_centers_in_lut ? 0. : (azimuthal_bins.bin(0).width() / 2)) - ); // N.B. bin(0) may not be of a correct width - entry.prob_electron = prob_electron; - entry.prob_pion = prob_pion; - entry.prob_kaon = prob_kaon; - entry.prob_proton = prob_proton; - } - else { - error("Unable to parse LUT file!"); - throw std::runtime_error("Unable to parse LUT file!"); - } + } + + for (auto&& b : bh::indexed(m_hist)) { + if (b->value() != 1) { + error("Bin {} {} {}:{} {}:{} {}:{} is defined {} times in the PID table", b.bin(0).lower(), + b.bin(1).lower(), b.bin(2).lower(), b.bin(2).upper(), b.bin(3).lower() / angle_fudge, + b.bin(3).upper() / angle_fudge, b.bin(4).lower() / angle_fudge, + b.bin(4).upper() / angle_fudge, b->value()); } + } - for (auto&& b : bh::indexed(m_hist)) { - if (b->value() != 1) { - error( - "Bin {} {} {}:{} {}:{} {}:{} is defined {} times in the PID table", - b.bin(0).lower(), - b.bin(1).lower(), - b.bin(2).lower(), - b.bin(2).upper(), - b.bin(3).lower() / angle_fudge, - b.bin(3).upper() / angle_fudge, - b.bin(4).lower() / angle_fudge, - b.bin(4).upper() / angle_fudge, - b->value() - ); - } - } - - boost::iostreams::close(in); - file.close(); + boost::iostreams::close(in); + file.close(); } -} +} // namespace eicrecon diff --git a/src/services/pid_lut/PIDLookupTable.h b/src/services/pid_lut/PIDLookupTable.h index 2d1f6fe93c..5d0b035c5f 100644 --- a/src/services/pid_lut/PIDLookupTable.h +++ b/src/services/pid_lut/PIDLookupTable.h @@ -15,44 +15,39 @@ namespace eicrecon { class PIDLookupTable : public algorithms::LoggerMixin { public: - /// The histogram entry with access counter, where the probabilities are stored in metadata - struct Entry : public boost::histogram::accumulators::count { - double prob_electron, prob_pion, prob_kaon, prob_proton; - }; - - struct Binning { - std::vector pdg_values; - std::vector charge_values; - std::vector momentum_edges; - std::vector polar_edges; - std::vector azimuthal_binning; - bool azimuthal_bin_centers_in_lut; - bool momentum_bin_centers_in_lut; - bool polar_bin_centers_in_lut; - bool use_radians; - bool missing_electron_prob; - }; + /// The histogram entry with access counter, where the probabilities are stored in metadata + struct Entry : public boost::histogram::accumulators::count { + double prob_electron, prob_pion, prob_kaon, prob_proton; + }; + + struct Binning { + std::vector pdg_values; + std::vector charge_values; + std::vector momentum_edges; + std::vector polar_edges; + std::vector azimuthal_binning; + bool azimuthal_bin_centers_in_lut; + bool momentum_bin_centers_in_lut; + bool polar_bin_centers_in_lut; + bool use_radians; + bool missing_electron_prob; + }; private: - boost::histogram::histogram< - std::tuple< - boost::histogram::axis::category, - boost::histogram::axis::category, - boost::histogram::axis::variable<>, - boost::histogram::axis::variable<>, - boost::histogram::axis::circular<> - > - , boost::histogram::dense_storage - > m_hist; - bool m_symmetrizing_charges; + boost::histogram::histogram< + std::tuple, boost::histogram::axis::category, + boost::histogram::axis::variable<>, boost::histogram::axis::variable<>, + boost::histogram::axis::circular<>>, + boost::histogram::dense_storage> + m_hist; + bool m_symmetrizing_charges; public: + PIDLookupTable() : algorithms::LoggerMixin("PIDLookupTable") {}; - PIDLookupTable() : algorithms::LoggerMixin("PIDLookupTable") {}; + const Entry* Lookup(int pdg, int charge, double momentum, double theta_deg, double phi_deg) const; - const Entry* Lookup(int pdg, int charge, double momentum, double theta_deg, double phi_deg) const; - - void load_file(const std::string& filename, const Binning &binning); + void load_file(const std::string& filename, const Binning& binning); }; -} +} // namespace eicrecon diff --git a/src/services/pid_lut/PIDLookupTableSvc.h b/src/services/pid_lut/PIDLookupTableSvc.h index 9aa735d1bd..8bb3eee768 100644 --- a/src/services/pid_lut/PIDLookupTableSvc.h +++ b/src/services/pid_lut/PIDLookupTableSvc.h @@ -14,35 +14,34 @@ namespace eicrecon { class PIDLookupTableSvc : public algorithms::LoggedService { public: - void init() {}; - - const PIDLookupTable* load(std::string filename, const PIDLookupTable::Binning &binning) { - std::lock_guard lock(m_mutex); - auto pair = m_cache.find(filename); - if (pair == m_cache.end()) { - auto lut = std::make_unique(); - info("Loading PID lookup table \"{}\"", filename); - - if (!std::filesystem::exists(filename)) { - error("PID lookup table \"{}\" not found", filename); - return nullptr; - } - - lut->load_file(filename, binning); // load_file can except - auto result_ptr = lut.get(); - m_cache.insert({filename, std::move(lut)}); - return result_ptr; - } - else { - return pair->second.get(); - } + void init() {}; + + const PIDLookupTable* load(std::string filename, const PIDLookupTable::Binning& binning) { + std::lock_guard lock(m_mutex); + auto pair = m_cache.find(filename); + if (pair == m_cache.end()) { + auto lut = std::make_unique(); + info("Loading PID lookup table \"{}\"", filename); + + if (!std::filesystem::exists(filename)) { + error("PID lookup table \"{}\" not found", filename); + return nullptr; + } + + lut->load_file(filename, binning); // load_file can except + auto result_ptr = lut.get(); + m_cache.insert({filename, std::move(lut)}); + return result_ptr; + } else { + return pair->second.get(); } + } private: - std::mutex m_mutex; - std::map> m_cache; + std::mutex m_mutex; + std::map> m_cache; - ALGORITHMS_DEFINE_LOGGED_SERVICE(PIDLookupTableSvc); + ALGORITHMS_DEFINE_LOGGED_SERVICE(PIDLookupTableSvc); }; -} +} // namespace eicrecon diff --git a/src/services/pid_lut/pid_lut.cc b/src/services/pid_lut/pid_lut.cc index cf5e0b8e19..71f9c53254 100644 --- a/src/services/pid_lut/pid_lut.cc +++ b/src/services/pid_lut/pid_lut.cc @@ -11,7 +11,7 @@ extern "C" { void InitPlugin(JApplication* app) { InitJANAPlugin(app); - auto& serviceSvc = algorithms::ServiceSvc::instance(); + auto& serviceSvc = algorithms::ServiceSvc::instance(); auto& pidLookupTableSvc = eicrecon::PIDLookupTableSvc::instance(); serviceSvc.add(&pidLookupTableSvc); } diff --git a/src/services/rootfile/RootFile_service.h b/src/services/rootfile/RootFile_service.h index ab80456c2a..cefbbd9275 100644 --- a/src/services/rootfile/RootFile_service.h +++ b/src/services/rootfile/RootFile_service.h @@ -1,6 +1,5 @@ #pragma once - #include #include #include @@ -16,90 +15,88 @@ /** * This Service centralizes creation of a root file for histograms */ -class RootFile_service : public JService -{ +class RootFile_service : public JService { public: - explicit RootFile_service(JApplication *app ):m_app(app){} - ~RootFile_service() override { CloseHistFile(); } + explicit RootFile_service(JApplication* app) : m_app(app) {} + ~RootFile_service() override { CloseHistFile(); } - void acquire_services(JServiceLocator *locater) override { - auto log_service = m_app->GetService(); - m_log = log_service->logger("RootFile"); - } + void acquire_services(JServiceLocator* locater) override { + auto log_service = m_app->GetService(); + m_log = log_service->logger("RootFile"); + } - /// This will return a pointer to the top-level directory of the - /// common output root file for histograms. If create_if_needed - /// is true and the root file has not already been created, then - /// one will be created. If create_if_needed is false, the pointer - /// to the existing file will be returned or nullptr if it does - /// not already exist. - /// - /// NOTE: This should only be called by a thread already holding - /// the global root lock. The root lock will already be held if - /// calling from JEventProcessorSequentialRoot. For pretty much - /// everyplace else, the lock should be acquired manually. - /// e.g. - /// - /// auto rootfile_service = japp->GetService(); - /// auto globalRootLock = japp->GetService(); - /// globalRootLock->acquire_write_lock(); - /// auto rootfile = rootfile_service->GetHistFile(); - /// globalWriteLock->release_lock(); - /// - /// \param create_if_needed create file if not already created - /// \return - TDirectory* GetHistFile(bool create_if_needed=true){ + /// This will return a pointer to the top-level directory of the + /// common output root file for histograms. If create_if_needed + /// is true and the root file has not already been created, then + /// one will be created. If create_if_needed is false, the pointer + /// to the existing file will be returned or nullptr if it does + /// not already exist. + /// + /// NOTE: This should only be called by a thread already holding + /// the global root lock. The root lock will already be held if + /// calling from JEventProcessorSequentialRoot. For pretty much + /// everyplace else, the lock should be acquired manually. + /// e.g. + /// + /// auto rootfile_service = japp->GetService(); + /// auto globalRootLock = japp->GetService(); + /// globalRootLock->acquire_write_lock(); + /// auto rootfile = rootfile_service->GetHistFile(); + /// globalWriteLock->release_lock(); + /// + /// \param create_if_needed create file if not already created + /// \return + TDirectory* GetHistFile(bool create_if_needed = true) { - if( create_if_needed ) { - std::call_once(init_flag, &RootFile_service::CreateHistFile, this); - } - return m_histfile; + if (create_if_needed) { + std::call_once(init_flag, &RootFile_service::CreateHistFile, this); } + return m_histfile; + } - /// Close the histogram file. If no histogram file was opened, - /// then this does nothing. - /// - /// This should generally never be called by anything other than - /// the destructor so that it is - /// automatically closed when the service is destructed at - /// the end of processing. This is only here for use in - /// execptional circumstances like the program is suffering - /// a fatal crash and we want to try and save the work by - /// closing the file cleanly. - void CloseHistFile(){ - if( m_histfile){ - std::string filename = m_histfile->GetName(); - m_histfile->Write(); - delete m_histfile; - m_log->info("Closed user histogram file: {}" , filename); - } - m_histfile = nullptr; + /// Close the histogram file. If no histogram file was opened, + /// then this does nothing. + /// + /// This should generally never be called by anything other than + /// the destructor so that it is + /// automatically closed when the service is destructed at + /// the end of processing. This is only here for use in + /// execptional circumstances like the program is suffering + /// a fatal crash and we want to try and save the work by + /// closing the file cleanly. + void CloseHistFile() { + if (m_histfile) { + std::string filename = m_histfile->GetName(); + m_histfile->Write(); + delete m_histfile; + m_log->info("Closed user histogram file: {}", filename); } + m_histfile = nullptr; + } private: - - /// Create the output rootfile. This will be called only once - /// which will happen the first time GetHistFile is called. - void CreateHistFile(){ - // Get root file name - std::string filename = "eicrecon.root"; - m_app->SetDefaultParameter("histsfile", filename, - "Name of root file to be created for plugin histograms/trees"); - if (!m_histfile) { - try { - m_histfile = new TFile(filename.c_str(), "RECREATE", "user histograms/trees"); - m_log->info("Created file: {} for user histograms", filename); - } catch (std::exception &ex) { - m_log->error("Problem opening root file for histograms: {}", ex.what()); - throw ex; - } - } + /// Create the output rootfile. This will be called only once + /// which will happen the first time GetHistFile is called. + void CreateHistFile() { + // Get root file name + std::string filename = "eicrecon.root"; + m_app->SetDefaultParameter("histsfile", filename, + "Name of root file to be created for plugin histograms/trees"); + if (!m_histfile) { + try { + m_histfile = new TFile(filename.c_str(), "RECREATE", "user histograms/trees"); + m_log->info("Created file: {} for user histograms", filename); + } catch (std::exception& ex) { + m_log->error("Problem opening root file for histograms: {}", ex.what()); + throw ex; + } } + } - RootFile_service()=default; + RootFile_service() = default; - JApplication *m_app=nullptr; - std::shared_ptr m_log; - TFile *m_histfile = nullptr; - std::once_flag init_flag; + JApplication* m_app = nullptr; + std::shared_ptr m_log; + TFile* m_histfile = nullptr; + std::once_flag init_flag; }; diff --git a/src/services/rootfile/rootfile.cc b/src/services/rootfile/rootfile.cc index 01499013cd..67919280e7 100644 --- a/src/services/rootfile/rootfile.cc +++ b/src/services/rootfile/rootfile.cc @@ -8,10 +8,9 @@ #include "RootFile_service.h" - extern "C" { -void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->ProvideService(std::make_shared(app) ); +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->ProvideService(std::make_shared(app)); } } diff --git a/src/tests/algorithms_test/algorithmsInit.cc b/src/tests/algorithms_test/algorithmsInit.cc index 357e928001..818e18e1e9 100644 --- a/src/tests/algorithms_test/algorithmsInit.cc +++ b/src/tests/algorithms_test/algorithmsInit.cc @@ -38,7 +38,8 @@ class algorithmsInitListener : public Catch::EventListenerBase { dd4hep::Readout readoutTracker(std::string("MockTrackerHits")); dd4hep::IDDescriptor id_desc_tracker("MockTrackerHits", "system:8,layer:8,x:8,y:8"); //Create segmentation with 1x1 mm pixels - dd4hep::Segmentation segmentation("CartesianGridXY","TrackerHitsSeg", id_desc_tracker.decoder()); + dd4hep::Segmentation segmentation("CartesianGridXY", "TrackerHitsSeg", + id_desc_tracker.decoder()); readoutTracker.setIDDescriptor(id_desc_tracker); readoutTracker.setSegmentation(segmentation); detector->add(id_desc_tracker); @@ -46,14 +47,12 @@ class algorithmsInitListener : public Catch::EventListenerBase { m_detector = std::move(detector); - auto& serviceSvc = algorithms::ServiceSvc::instance(); + auto& serviceSvc = algorithms::ServiceSvc::instance(); [[maybe_unused]] auto& geoSvc = algorithms::GeoSvc::instance(); - serviceSvc.setInit([this](auto&& g) { - g.init(this->m_detector.get()); - }); + serviceSvc.setInit([this](auto&& g) { g.init(this->m_detector.get()); }); [[maybe_unused]] auto& randomSvc = algorithms::RandomSvc::instance(); - auto seed = Catch::Generators::Detail::getSeed(); + auto seed = Catch::Generators::Detail::getSeed(); serviceSvc.setInit([seed](auto&& r) { r.setProperty("seed", static_cast(seed)); r.init(); diff --git a/src/tests/algorithms_test/calorimetry_CalorimeterClusterRecoCoG.cc b/src/tests/algorithms_test/calorimetry_CalorimeterClusterRecoCoG.cc index 4d79c63fb2..0d289858b6 100644 --- a/src/tests/algorithms_test/calorimetry_CalorimeterClusterRecoCoG.cc +++ b/src/tests/algorithms_test/calorimetry_CalorimeterClusterRecoCoG.cc @@ -1,11 +1,10 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2024, Sebouh Paul - -#include // for AssertionHandler, operator""_catch_sr, StringRef, REQUIRE, operator<, operator==, operator>, TEST_CASE +#include // for AssertionHandler, operator""_catch_sr, StringRef, REQUIRE, operator<, operator==, operator>, TEST_CASE #include #include -#include // for CalorimeterHitCollection, MutableCalorimeterHit, CalorimeterHitMutableCollectionIterator +#include // for CalorimeterHitCollection, MutableCalorimeterHit, CalorimeterHitMutableCollectionIterator #include #include #include @@ -22,37 +21,37 @@ #include #include #include -#include // for level_enum -#include // for logger -#include // for default_logger -#include // for allocator, unique_ptr, make_unique, shared_ptr, __shared_ptr_access +#include // for level_enum +#include // for logger +#include // for default_logger +#include // for allocator, unique_ptr, make_unique, shared_ptr, __shared_ptr_access #include #include -#include "algorithms/calorimetry/CalorimeterClusterRecoCoG.h" // for CalorimeterClusterRecoCoG -#include "algorithms/calorimetry/CalorimeterClusterRecoCoGConfig.h" // for CalorimeterClusterRecoCoGConfig +#include "algorithms/calorimetry/CalorimeterClusterRecoCoG.h" // for CalorimeterClusterRecoCoG +#include "algorithms/calorimetry/CalorimeterClusterRecoCoGConfig.h" // for CalorimeterClusterRecoCoGConfig using eicrecon::CalorimeterClusterRecoCoG; using eicrecon::CalorimeterClusterRecoCoGConfig; using edm4eic::CalorimeterHit; -TEST_CASE( "the calorimeter CoG algorithm runs", "[CalorimeterClusterRecoCoG]" ) { +TEST_CASE("the calorimeter CoG algorithm runs", "[CalorimeterClusterRecoCoG]") { const float EPSILON = 1e-5; CalorimeterClusterRecoCoG algo("CalorimeterClusterRecoCoG"); - std::shared_ptr logger = spdlog::default_logger()->clone("CalorimeterClusterRecoCoG"); + std::shared_ptr logger = + spdlog::default_logger()->clone("CalorimeterClusterRecoCoG"); logger->set_level(spdlog::level::trace); CalorimeterClusterRecoCoGConfig cfg; - cfg.energyWeight = "log"; - cfg.sampFrac = 0.0203; - cfg.logWeightBaseCoeffs = {5.0,0.65,0.31}; - cfg.logWeightBase_Eref = 50 * edm4eic::unit::GeV; + cfg.energyWeight = "log"; + cfg.sampFrac = 0.0203; + cfg.logWeightBaseCoeffs = {5.0, 0.65, 0.31}; + cfg.logWeightBase_Eref = 50 * edm4eic::unit::GeV; cfg.longitudinalShowerInfoAvailable = true; - algo.applyConfig(cfg); algo.init(); @@ -81,7 +80,7 @@ TEST_CASE( "the calorimeter CoG algorithm runs", "[CalorimeterClusterRecoCoG]" ) hit1.setTime(0); hit1.setTimeError(0); hit1.setPosition(position); - hit1.setDimension({0,0,0}); + hit1.setDimension({0, 0, 0}); hit1.setLocal(position); #if EDM4EIC_VERSION_MAJOR >= 7 hit1.setRawHit(rawhit1); @@ -89,51 +88,48 @@ TEST_CASE( "the calorimeter CoG algorithm runs", "[CalorimeterClusterRecoCoG]" ) pclust.addToHits(hit1); pclust.addToWeights(1); - auto mcpart11 = mcparts_coll.create( - 11, // std::int32_t PDG - 1, // std::int32_t generatorStatus - 0, // std::int32_t simulatorStatus - -1., // float charge - 0., // float time - 0., // double mass - edm4hep::Vector3d(), // edm4hep::Vector3d vertex - edm4hep::Vector3d(), // edm4hep::Vector3d endpoint - edm4hep::Vector3f(), // edm4hep::Vector3f momentum - edm4hep::Vector3f(), // edm4hep::Vector3f momentumAtEndpoint - edm4hep::Vector3f(), // edm4hep::Vector3f spin - edm4hep::Vector2i() // edm4hep::Vector2i colorFlow + auto mcpart11 = mcparts_coll.create(11, // std::int32_t PDG + 1, // std::int32_t generatorStatus + 0, // std::int32_t simulatorStatus + -1., // float charge + 0., // float time + 0., // double mass + edm4hep::Vector3d(), // edm4hep::Vector3d vertex + edm4hep::Vector3d(), // edm4hep::Vector3d endpoint + edm4hep::Vector3f(), // edm4hep::Vector3f momentum + edm4hep::Vector3f(), // edm4hep::Vector3f momentumAtEndpoint + edm4hep::Vector3f(), // edm4hep::Vector3f spin + edm4hep::Vector2i() // edm4hep::Vector2i colorFlow ); auto mcpart12 = mcparts_coll.create( - 22, // std::int32_t PDG - 0, // std::int32_t generatorStatus - (0x1 << edm4hep::MCParticle::BITCreatedInSimulation), // std::int32_t simulatorStatus - 0., // float charge - 0., // float time - 0., // double mass - edm4hep::Vector3d(), // edm4hep::Vector3d vertex - edm4hep::Vector3d(), // edm4hep::Vector3d endpoint - edm4hep::Vector3f(), // edm4hep::Vector3f momentum - edm4hep::Vector3f(), // edm4hep::Vector3f momentumAtEndpoint - edm4hep::Vector3f(), // edm4hep::Vector3f spin - edm4hep::Vector2i() // edm4hep::Vector2i colorFlow + 22, // std::int32_t PDG + 0, // std::int32_t generatorStatus + (0x1 << edm4hep::MCParticle::BITCreatedInSimulation), // std::int32_t simulatorStatus + 0., // float charge + 0., // float time + 0., // double mass + edm4hep::Vector3d(), // edm4hep::Vector3d vertex + edm4hep::Vector3d(), // edm4hep::Vector3d endpoint + edm4hep::Vector3f(), // edm4hep::Vector3f momentum + edm4hep::Vector3f(), // edm4hep::Vector3f momentumAtEndpoint + edm4hep::Vector3f(), // edm4hep::Vector3f spin + edm4hep::Vector2i() // edm4hep::Vector2i colorFlow ); mcpart12.addToParents(mcpart11); mcpart11.addToDaughters(mcpart12); - auto contrib11 = contribs_coll.create( - 0, // int32_t PDG - 0.05 * edm4eic::unit::GeV, // float energy - 0.0, // float time - edm4hep::Vector3f() // edm4hep::Vector3f stepPosition + auto contrib11 = contribs_coll.create(0, // int32_t PDG + 0.05 * edm4eic::unit::GeV, // float energy + 0.0, // float time + edm4hep::Vector3f() // edm4hep::Vector3f stepPosition ); contrib11.setParticle(mcpart11); - auto contrib12 = contribs_coll.create( - 0, // int32_t PDG - 0.05 * edm4eic::unit::GeV, // float energy - 0.0, // float time - edm4hep::Vector3f() // edm4hep::Vector3f stepPosition + auto contrib12 = contribs_coll.create(0, // int32_t PDG + 0.05 * edm4eic::unit::GeV, // float energy + 0.0, // float time + edm4hep::Vector3f() // edm4hep::Vector3f stepPosition ); contrib12.setParticle(mcpart12); @@ -152,7 +148,7 @@ TEST_CASE( "the calorimeter CoG algorithm runs", "[CalorimeterClusterRecoCoG]" ) auto rawhit2 = rawhits_coll.create(); - position={-1 * edm4eic::unit::mm, 0, 2 * edm4eic::unit::mm}; + position = {-1 * edm4eic::unit::mm, 0, 2 * edm4eic::unit::mm}; auto hit2 = hits_coll.create(); hit2.setCellID(1); hit2.setEnergy(0.1 * edm4eic::unit::GeV); @@ -160,7 +156,7 @@ TEST_CASE( "the calorimeter CoG algorithm runs", "[CalorimeterClusterRecoCoG]" ) hit2.setTime(0); hit2.setTimeError(0); hit2.setPosition(position); - hit2.setDimension({0,0,0}); + hit2.setDimension({0, 0, 0}); hit2.setLocal(position); #if EDM4EIC_VERSION_MAJOR >= 7 hit2.setRawHit(rawhit2); @@ -169,25 +165,24 @@ TEST_CASE( "the calorimeter CoG algorithm runs", "[CalorimeterClusterRecoCoG]" ) pclust.addToWeights(1); auto mcpart2 = mcparts_coll.create( - 211, // std::int32_t PDG - 0, // std::int32_t generatorStatus - (0x1 << edm4hep::MCParticle::BITCreatedInSimulation), // std::int32_t simulatorStatus - 0., // float charge - 0., // float time - 0., // double mass - edm4hep::Vector3d(), // edm4hep::Vector3d vertex - edm4hep::Vector3d(), // edm4hep::Vector3d endpoint - edm4hep::Vector3f(), // edm4hep::Vector3f momentum - edm4hep::Vector3f(), // edm4hep::Vector3f momentumAtEndpoint - edm4hep::Vector3f(), // edm4hep::Vector3f spin - edm4hep::Vector2i() // edm4hep::Vector2i colorFlow + 211, // std::int32_t PDG + 0, // std::int32_t generatorStatus + (0x1 << edm4hep::MCParticle::BITCreatedInSimulation), // std::int32_t simulatorStatus + 0., // float charge + 0., // float time + 0., // double mass + edm4hep::Vector3d(), // edm4hep::Vector3d vertex + edm4hep::Vector3d(), // edm4hep::Vector3d endpoint + edm4hep::Vector3f(), // edm4hep::Vector3f momentum + edm4hep::Vector3f(), // edm4hep::Vector3f momentumAtEndpoint + edm4hep::Vector3f(), // edm4hep::Vector3f spin + edm4hep::Vector2i() // edm4hep::Vector2i colorFlow ); - auto contrib2 = contribs_coll.create( - 0, // int32_t PDG - 0.1 * edm4eic::unit::GeV, // float energy - 0.0, // float time - edm4hep::Vector3f() // edm4hep::Vector3f stepPosition + auto contrib2 = contribs_coll.create(0, // int32_t PDG + 0.1 * edm4eic::unit::GeV, // float energy + 0.0, // float time + edm4hep::Vector3f() // edm4hep::Vector3f stepPosition ); contrib2.setParticle(mcpart2); @@ -203,7 +198,7 @@ TEST_CASE( "the calorimeter CoG algorithm runs", "[CalorimeterClusterRecoCoG]" ) hitassoc2.setSimHit(simhit2); #endif - // Constructing input and output as per the algorithm's expected signature + // Constructing input and output as per the algorithm's expected signature #if EDM4EIC_VERSION_MAJOR >= 7 auto input = std::make_tuple(&pclust_coll, &hitassocs_coll); #else @@ -230,5 +225,4 @@ TEST_CASE( "the calorimeter CoG algorithm runs", "[CalorimeterClusterRecoCoG]" ) REQUIRE_THAT((*assoc_coll)[1].getWeight(), Catch::Matchers::WithinAbs(0.5, EPSILON)); REQUIRE((*assoc_coll)[1].getRec() == clust); REQUIRE((*assoc_coll)[1].getSim() == mcpart2); - } diff --git a/src/tests/algorithms_test/calorimetry_CalorimeterHitDigi.cc b/src/tests/algorithms_test/calorimetry_CalorimeterHitDigi.cc index 32fdd6436f..f49266b8d6 100644 --- a/src/tests/algorithms_test/calorimetry_CalorimeterHitDigi.cc +++ b/src/tests/algorithms_test/calorimetry_CalorimeterHitDigi.cc @@ -31,53 +31,53 @@ using eicrecon::CalorimeterHitDigi; using eicrecon::CalorimeterHitDigiConfig; -TEST_CASE( "the clustering algorithm runs", "[CalorimeterHitDigi]" ) { +TEST_CASE("the clustering algorithm runs", "[CalorimeterHitDigi]") { std::shared_ptr logger = spdlog::default_logger()->clone("CalorimeterHitDigi"); logger->set_level(spdlog::level::trace); auto detector = algorithms::GeoSvc::instance().detector(); - auto id_desc = detector->readout("MockCalorimeterHits").idSpec(); + auto id_desc = detector->readout("MockCalorimeterHits").idSpec(); CalorimeterHitDigi algo("test"); CalorimeterHitDigiConfig cfg; - cfg.threshold = 0. /* GeV */; + cfg.threshold = 0. /* GeV */; cfg.corrMeanScale = "1."; // Keep smearing parameters at zero cfg.pedSigmaADC = 0; - cfg.tRes = 0. * dd4hep::ns; - cfg.eRes = {0. * sqrt(dd4hep::GeV), 0., 0. * dd4hep::GeV}; - cfg.readout = "MockCalorimeterHits"; + cfg.tRes = 0. * dd4hep::ns; + cfg.eRes = {0. * sqrt(dd4hep::GeV), 0., 0. * dd4hep::GeV}; + cfg.readout = "MockCalorimeterHits"; - SECTION( "single hit with couple contributions" ) { - cfg.capADC = 555; - cfg.dyRangeADC = 5.0 /* GeV */; - cfg.pedMeanADC = 123; + SECTION("single hit with couple contributions") { + cfg.capADC = 555; + cfg.dyRangeADC = 5.0 /* GeV */; + cfg.pedMeanADC = 123; cfg.resolutionTDC = 1.0 * dd4hep::ns; algo.level(algorithms::LogLevel(spdlog::level::trace)); algo.applyConfig(cfg); algo.init(); auto calohits = std::make_unique(); - auto simhits = std::make_unique(); - auto mhit = simhits->create( - id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, - 1.0 /* GeV */, // float energy - edm4hep::Vector3f({0. /* mm */, 0. /* mm */, 0. /* mm */}) // edm4hep::Vector3f position + auto simhits = std::make_unique(); + auto mhit = simhits->create( + id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, + 1.0 /* GeV */, // float energy + edm4hep::Vector3f({0. /* mm */, 0. /* mm */, 0. /* mm */}) // edm4hep::Vector3f position ); mhit.addToContributions(calohits->create( - 0, // std::int32_t PDG - 0.5 /* GeV */, // float energy - 7.0 /* ns */, // float time - edm4hep::Vector3f({0. /* mm */, 0. /* mm */, 0. /* mm */}) // edm4hep::Vector3f stepPosition - )); + 0, // std::int32_t PDG + 0.5 /* GeV */, // float energy + 7.0 /* ns */, // float time + edm4hep::Vector3f({0. /* mm */, 0. /* mm */, 0. /* mm */}) // edm4hep::Vector3f stepPosition + )); mhit.addToContributions(calohits->create( - 0, // std::int32_t PDG - 0.5 /* GeV */, // float energy - 9.0 /* ns */, // float time - edm4hep::Vector3f({0. /* mm */, 0. /* mm */, 0. /* mm */}) // edm4hep::Vector3f stepPosition - )); + 0, // std::int32_t PDG + 0.5 /* GeV */, // float energy + 9.0 /* ns */, // float time + edm4hep::Vector3f({0. /* mm */, 0. /* mm */, 0. /* mm */}) // edm4hep::Vector3f stepPosition + )); auto rawhits = std::make_unique(); #if EDM4EIC_VERSION_MAJOR >= 7 @@ -87,15 +87,15 @@ TEST_CASE( "the clustering algorithm runs", "[CalorimeterHitDigi]" ) { algo.process({simhits.get()}, {rawhits.get()}); #endif - REQUIRE( (*rawhits).size() == 1 ); - REQUIRE( (*rawhits)[0].getCellID() == id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}})); - REQUIRE( (*rawhits)[0].getAmplitude() == 123 + 111 ); - REQUIRE( (*rawhits)[0].getTimeStamp() == 7 ); // currently, earliest contribution is returned + REQUIRE((*rawhits).size() == 1); + REQUIRE((*rawhits)[0].getCellID() == id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}})); + REQUIRE((*rawhits)[0].getAmplitude() == 123 + 111); + REQUIRE((*rawhits)[0].getTimeStamp() == 7); // currently, earliest contribution is returned #if EDM4EIC_VERSION_MAJOR >= 7 - REQUIRE( (*rawassocs).size() == 1 ); - REQUIRE( (*rawassocs)[0].getSimHit() == (*simhits)[0] ); - REQUIRE( (*rawassocs)[0].getRawHit() == (*rawhits)[0] ); + REQUIRE((*rawassocs).size() == 1); + REQUIRE((*rawassocs)[0].getSimHit() == (*simhits)[0]); + REQUIRE((*rawassocs)[0].getRawHit() == (*rawhits)[0]); #endif } } diff --git a/src/tests/algorithms_test/calorimetry_CalorimeterIslandCluster.cc b/src/tests/algorithms_test/calorimetry_CalorimeterIslandCluster.cc index 5b09d41259..63b310201c 100644 --- a/src/tests/algorithms_test/calorimetry_CalorimeterIslandCluster.cc +++ b/src/tests/algorithms_test/calorimetry_CalorimeterIslandCluster.cc @@ -29,125 +29,124 @@ using eicrecon::CalorimeterIslandCluster; using eicrecon::CalorimeterIslandClusterConfig; -TEST_CASE( "the clustering algorithm runs", "[CalorimeterIslandCluster]" ) { +TEST_CASE("the clustering algorithm runs", "[CalorimeterIslandCluster]") { CalorimeterIslandCluster algo("CalorimeterIslandCluster"); - std::shared_ptr logger = spdlog::default_logger()->clone("CalorimeterIslandCluster"); + std::shared_ptr logger = + spdlog::default_logger()->clone("CalorimeterIslandCluster"); logger->set_level(spdlog::level::trace); CalorimeterIslandClusterConfig cfg; - cfg.minClusterHitEdep = 0. * dd4hep::GeV; + cfg.minClusterHitEdep = 0. * dd4hep::GeV; cfg.minClusterCenterEdep = 0. * dd4hep::GeV; auto detector = algorithms::GeoSvc::instance().detector(); - auto id_desc = detector->readout("MockCalorimeterHits").idSpec(); + auto id_desc = detector->readout("MockCalorimeterHits").idSpec(); - SECTION( "without splitting" ) { + SECTION("without splitting") { bool use_adjacencyMatrix = GENERATE(false, true); - cfg.splitCluster = false; + cfg.splitCluster = false; if (use_adjacencyMatrix) { cfg.adjacencyMatrix = "abs(x_1 - x_2) + abs(y_1 - y_2) == 1"; - cfg.readout = "MockCalorimeterHits"; + cfg.readout = "MockCalorimeterHits"; } else { cfg.localDistXY = {1 * dd4hep::mm, 1 * dd4hep::mm}; } algo.applyConfig(cfg); algo.init(); - SECTION( "on a single cell" ) { + SECTION("on a single cell") { edm4eic::CalorimeterHitCollection hits_coll; hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local ); auto protoclust_coll = std::make_unique(); algo.process({&hits_coll}, {protoclust_coll.get()}); - REQUIRE( (*protoclust_coll).size() == 1 ); - REQUIRE( (*protoclust_coll)[0].hits_size() == 1 ); - REQUIRE( (*protoclust_coll)[0].weights_size() == 1 ); + REQUIRE((*protoclust_coll).size() == 1); + REQUIRE((*protoclust_coll)[0].hits_size() == 1); + REQUIRE((*protoclust_coll)[0].weights_size() == 1); } - SECTION( "on two separated cells" ) { + SECTION("on two separated cells") { edm4eic::CalorimeterHitCollection hits_coll; - hits_coll.create( - 0, // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + hits_coll.create(0, // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local ); - hits_coll.create( - 1, // std::uint64_t cellID, - 6.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(1.1 /* mm */, 1.1 /* mm */, 0.0) // edm4hep::Vector3f local + hits_coll.create(1, // std::uint64_t cellID, + 6.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(1.1 /* mm */, 1.1 /* mm */, 0.0) // edm4hep::Vector3f local ); auto protoclust_coll = std::make_unique(); algo.process({&hits_coll}, {protoclust_coll.get()}); - REQUIRE( (*protoclust_coll).size() == 2 ); - REQUIRE( (*protoclust_coll)[0].hits_size() == 1 ); - REQUIRE( (*protoclust_coll)[0].weights_size() == 1 ); - REQUIRE( (*protoclust_coll)[1].hits_size() == 1 ); - REQUIRE( (*protoclust_coll)[1].weights_size() == 1 ); + REQUIRE((*protoclust_coll).size() == 2); + REQUIRE((*protoclust_coll)[0].hits_size() == 1); + REQUIRE((*protoclust_coll)[0].weights_size() == 1); + REQUIRE((*protoclust_coll)[1].hits_size() == 1); + REQUIRE((*protoclust_coll)[1].weights_size() == 1); } - SECTION( "on two adjacent cells" ) { + SECTION("on two adjacent cells") { edm4eic::CalorimeterHitCollection hits_coll; hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local ); hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}), // std::uint64_t cellID, - 6.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local + id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}), // std::uint64_t cellID, + 6.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local ); auto protoclust_coll = std::make_unique(); algo.process({&hits_coll}, {protoclust_coll.get()}); - REQUIRE( (*protoclust_coll).size() == 1 ); - REQUIRE( (*protoclust_coll)[0].hits_size() == 2 ); - REQUIRE( (*protoclust_coll)[0].weights_size() == 2 ); + REQUIRE((*protoclust_coll).size() == 1); + REQUIRE((*protoclust_coll)[0].hits_size() == 2); + REQUIRE((*protoclust_coll)[0].weights_size() == 2); } } - SECTION( "run on three adjacent cells" ) { + SECTION("run on three adjacent cells") { bool use_adjacencyMatrix = GENERATE(false, true); if (use_adjacencyMatrix) { cfg.adjacencyMatrix = "abs(x_1 - x_2) + abs(y_1 - y_2) == 1"; @@ -165,36 +164,35 @@ TEST_CASE( "the clustering algorithm runs", "[CalorimeterIslandCluster]" ) { cfg.splitCluster = GENERATE(false, true); if (cfg.splitCluster) { cfg.transverseEnergyProfileMetric = "localDistXY"; - cfg.transverseEnergyProfileScale = std::numeric_limits::infinity(); + cfg.transverseEnergyProfileScale = + std::numeric_limits::infinity(); } cfg.localDistXY = {1 * dd4hep::mm, 1 * dd4hep::mm}; algo.applyConfig(cfg); algo.init(); edm4eic::CalorimeterHitCollection hits_coll; - hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + hits_coll.create(id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local ); - hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}), // std::uint64_t cellID, - 1.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local + hits_coll.create(id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}), // std::uint64_t cellID, + 1.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local ); bool test_diagonal_cluster = GENERATE(false, true); @@ -206,16 +204,18 @@ TEST_CASE( "the clustering algorithm runs", "[CalorimeterIslandCluster]" ) { // The idea is to test whether peakNeighbourhoodMatrix allows increasing // peak resolution threshold while keeping the Island algorithm the same. hits_coll.create( - id_desc.encode({{"system", 255}, {"x", test_diagonal_cluster ? 1 : 2}, {"y", test_diagonal_cluster ? 1 : 0}}), // std::uint64_t cellID, - 6.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(1.8 /* mm */, 1.8 /* mm */, 0.0) // edm4hep::Vector3f local + id_desc.encode({{"system", 255}, + {"x", test_diagonal_cluster ? 1 : 2}, + {"y", test_diagonal_cluster ? 1 : 0}}), // std::uint64_t cellID, + 6.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(1.8 /* mm */, 1.8 /* mm */, 0.0) // edm4hep::Vector3f local ); auto protoclust_coll = std::make_unique(); algo.process({&hits_coll}, {protoclust_coll.get()}); @@ -225,23 +225,25 @@ TEST_CASE( "the clustering algorithm runs", "[CalorimeterIslandCluster]" ) { expect_two_peaks = not test_diagonal_cluster; } if (expect_two_peaks) { - REQUIRE( (*protoclust_coll).size() == 2 ); - REQUIRE( (*protoclust_coll)[0].hits_size() == 3 ); - REQUIRE( (*protoclust_coll)[0].weights_size() == 3 ); + REQUIRE((*protoclust_coll).size() == 2); + REQUIRE((*protoclust_coll)[0].hits_size() == 3); + REQUIRE((*protoclust_coll)[0].weights_size() == 3); for (double weight : (*protoclust_coll)[0].getWeights()) { - double energy_fraction = hits_coll[0].getEnergy() / (hits_coll[0].getEnergy() + hits_coll[2].getEnergy()); - REQUIRE_THAT( weight, Catch::Matchers::WithinAbs(energy_fraction, 1e-5) ); + double energy_fraction = + hits_coll[0].getEnergy() / (hits_coll[0].getEnergy() + hits_coll[2].getEnergy()); + REQUIRE_THAT(weight, Catch::Matchers::WithinAbs(energy_fraction, 1e-5)); } - REQUIRE( (*protoclust_coll)[1].hits_size() == 3 ); - REQUIRE( (*protoclust_coll)[1].weights_size() == 3 ); + REQUIRE((*protoclust_coll)[1].hits_size() == 3); + REQUIRE((*protoclust_coll)[1].weights_size() == 3); for (double weight : (*protoclust_coll)[1].getWeights()) { - double energy_fraction = hits_coll[2].getEnergy() / (hits_coll[0].getEnergy() + hits_coll[2].getEnergy()); - REQUIRE_THAT( weight, Catch::Matchers::WithinAbs(energy_fraction, 1e-5) ); + double energy_fraction = + hits_coll[2].getEnergy() / (hits_coll[0].getEnergy() + hits_coll[2].getEnergy()); + REQUIRE_THAT(weight, Catch::Matchers::WithinAbs(energy_fraction, 1e-5)); } } else { - REQUIRE( (*protoclust_coll).size() == 1 ); - REQUIRE( (*protoclust_coll)[0].hits_size() == 3 ); - REQUIRE( (*protoclust_coll)[0].weights_size() == 3 ); + REQUIRE((*protoclust_coll).size() == 1); + REQUIRE((*protoclust_coll)[0].hits_size() == 3); + REQUIRE((*protoclust_coll)[0].weights_size() == 3); } } } diff --git a/src/tests/algorithms_test/calorimetry_HEXPLIT.cc b/src/tests/algorithms_test/calorimetry_HEXPLIT.cc index 911de1f8ef..9ee0717009 100644 --- a/src/tests/algorithms_test/calorimetry_HEXPLIT.cc +++ b/src/tests/algorithms_test/calorimetry_HEXPLIT.cc @@ -1,50 +1,50 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2024, Sebouh Paul -#include // for Detector -#include // for IDDescriptor -#include // for Readout -#include // for MeV, mm, keV, ns +#include // for Detector +#include // for IDDescriptor +#include // for Readout +#include // for MeV, mm, keV, ns #include -#include // for AssertionHandler, operator""_catch_sr, StringRef, REQUIRE, operator<, operator==, operator>, TEST_CASE -#include // for CalorimeterHitCollection, MutableCalorimeterHit, CalorimeterHitMutableCollectionIterator -#include // for Vector3f -#include // for level_enum -#include // for logger -#include // for default_logger -#include // for size_t -#include // for array -#include // for sqrt, abs +#include // for AssertionHandler, operator""_catch_sr, StringRef, REQUIRE, operator<, operator==, operator>, TEST_CASE +#include // for CalorimeterHitCollection, MutableCalorimeterHit, CalorimeterHitMutableCollectionIterator +#include // for Vector3f +#include // for level_enum +#include // for logger +#include // for default_logger +#include // for size_t +#include // for array +#include // for sqrt, abs #include -#include // for allocator, unique_ptr, make_unique, shared_ptr, __shared_ptr_access -#include // for pair +#include // for allocator, unique_ptr, make_unique, shared_ptr, __shared_ptr_access +#include // for pair -#include "algorithms/calorimetry/HEXPLIT.h" // for HEXPLIT -#include "algorithms/calorimetry/HEXPLITConfig.h" // for HEXPLITConfig +#include "algorithms/calorimetry/HEXPLIT.h" // for HEXPLIT +#include "algorithms/calorimetry/HEXPLITConfig.h" // for HEXPLITConfig using eicrecon::HEXPLIT; using eicrecon::HEXPLITConfig; -TEST_CASE( "the subcell-splitting algorithm runs", "[HEXPLIT]" ) { +TEST_CASE("the subcell-splitting algorithm runs", "[HEXPLIT]") { HEXPLIT algo("HEXPLIT"); std::shared_ptr logger = spdlog::default_logger()->clone("HEXPLIT"); logger->set_level(spdlog::level::trace); HEXPLITConfig cfg; - cfg.MIP = 472. * dd4hep::keV; + cfg.MIP = 472. * dd4hep::keV; cfg.tmax = 1000. * dd4hep::ns; auto detector = algorithms::GeoSvc::instance().detector(); - auto id_desc = detector->readout("MockCalorimeterHits").idSpec(); + auto id_desc = detector->readout("MockCalorimeterHits").idSpec(); //create a geometry for the fake detector. - double side_length=31.3*dd4hep::mm; - double layer_spacing=25.1*dd4hep::mm; - double thickness=3*dd4hep::mm; + double side_length = 31.3 * dd4hep::mm; + double layer_spacing = 25.1 * dd4hep::mm; + double thickness = 3 * dd4hep::mm; //dimension of a cell - auto dimension = edm4hep::Vector3f(2*side_length, sqrt(3)*side_length, thickness); + auto dimension = edm4hep::Vector3f(2 * side_length, sqrt(3) * side_length, thickness); algo.applyConfig(cfg); algo.init(); @@ -53,48 +53,47 @@ TEST_CASE( "the subcell-splitting algorithm runs", "[HEXPLIT]" ) { //create a set of 5 hits in consecutive layers, all of which overlap in a single rhombus, // centered at (3/8, sqrt(3)/8)*side_length - std::array layer={0,1,2,3,4}; - std::array x={0,0.75*side_length,0,0.75*side_length,0}; - std::array y={sqrt(3)/2*side_length,-0.25*sqrt(3)*side_length,0,0.25*sqrt(3)*side_length,sqrt(3)/2*side_length}; - std::array E={50*dd4hep::MeV,50*dd4hep::MeV,50*dd4hep::MeV,50*dd4hep::MeV,50*dd4hep::MeV}; - for(size_t i=0; i<5; i++){ + std::array layer = {0, 1, 2, 3, 4}; + std::array x = {0, 0.75 * side_length, 0, 0.75 * side_length, 0}; + std::array y = {sqrt(3) / 2 * side_length, -0.25 * sqrt(3) * side_length, 0, + 0.25 * sqrt(3) * side_length, sqrt(3) / 2 * side_length}; + std::array E = {50 * dd4hep::MeV, 50 * dd4hep::MeV, 50 * dd4hep::MeV, 50 * dd4hep::MeV, + 50 * dd4hep::MeV}; + for (size_t i = 0; i < 5; i++) { hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, - E[i], // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(x[i], y[i], layer[i]*layer_spacing), // edm4hep::Vector3f position, - dimension, // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - layer[i], // std::int32_t layer, - edm4hep::Vector3f(x[i], y[i], layer[i]*layer_spacing) // edm4hep::Vector3f local - ); + id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, + E[i], // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(x[i], y[i], layer[i] * layer_spacing), // edm4hep::Vector3f position, + dimension, // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + layer[i], // std::int32_t layer, + edm4hep::Vector3f(x[i], y[i], layer[i] * layer_spacing) // edm4hep::Vector3f local + ); } auto subcellhits_coll = std::make_unique(); algo.process({&hits_coll}, {subcellhits_coll.get()}); - //the number of subcell hits should be equal to the //number of subcells per cell (12) times the number of cells (5) - REQUIRE( (*subcellhits_coll).size() == 60); + REQUIRE((*subcellhits_coll).size() == 60); //next check that the sum of the hit energies equals the energy that I gave the hits - double tol=0.001; - double Esum=0; - int i=0; - for (auto subcell : *subcellhits_coll){ - Esum+=subcell.getEnergy(); + double tol = 0.001; + double Esum = 0; + int i = 0; + for (auto subcell : *subcellhits_coll) { + Esum += subcell.getEnergy(); i++; - if (i%12==0){ - REQUIRE(abs(Esum-E[i/12-1])/E[i/12-1]0.95); - - + REQUIRE((*subcellhits_coll)[35].getEnergy() / E[2] > 0.95); } diff --git a/src/tests/algorithms_test/calorimetry_ImagingTopoCluster.cc b/src/tests/algorithms_test/calorimetry_ImagingTopoCluster.cc index 4db2abc783..1188f2f16f 100644 --- a/src/tests/algorithms_test/calorimetry_ImagingTopoCluster.cc +++ b/src/tests/algorithms_test/calorimetry_ImagingTopoCluster.cc @@ -24,122 +24,126 @@ using eicrecon::ImagingTopoCluster; using eicrecon::ImagingTopoClusterConfig; -TEST_CASE( "the clustering algorithm runs", "[ImagingTopoCluster]" ) { +TEST_CASE("the clustering algorithm runs", "[ImagingTopoCluster]") { ImagingTopoCluster algo("ImagingTopoCluster"); std::shared_ptr logger = spdlog::default_logger()->clone("ImagingTopoCluster"); logger->set_level(spdlog::level::trace); ImagingTopoClusterConfig cfg; - cfg.layerMode =eicrecon::ImagingTopoClusterConfig::ELayerMode::xy; - cfg.minClusterHitEdep = 0. * dd4hep::GeV; + cfg.layerMode = eicrecon::ImagingTopoClusterConfig::ELayerMode::xy; + cfg.minClusterHitEdep = 0. * dd4hep::GeV; cfg.minClusterCenterEdep = 0. * dd4hep::GeV; - cfg.localDistXY = {1.0* dd4hep::mm, 1.0* dd4hep::mm}; //mm - cfg.layerDistXY = {1.0* dd4hep::mm, 1.0* dd4hep::mm}; //mm - cfg.minClusterEdep = 9 * dd4hep::MeV; - // minimum number of hits (to save this cluster) + cfg.localDistXY = {1.0 * dd4hep::mm, 1.0 * dd4hep::mm}; //mm + cfg.layerDistXY = {1.0 * dd4hep::mm, 1.0 * dd4hep::mm}; //mm + cfg.minClusterEdep = 9 * dd4hep::MeV; + // minimum number of hits (to save this cluster) cfg.minClusterNhits = 1; - auto detector = algorithms::GeoSvc::instance().detector(); - auto id_desc = detector->readout("MockCalorimeterHits").idSpec(); + auto detector = algorithms::GeoSvc::instance().detector(); + auto id_desc = detector->readout("MockCalorimeterHits").idSpec(); - SECTION( "without splitting" ) { + SECTION("without splitting") { algo.applyConfig(cfg); algo.init(); - SECTION( "on a single cell" ) { + SECTION("on a single cell") { edm4eic::CalorimeterHitCollection hits_coll; hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}, {"layer", 0}}), // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + id_desc.encode( + {{"system", 255}, {"x", 0}, {"y", 0}, {"layer", 0}}), // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local ); auto protoclust_coll = std::make_unique(); algo.process({&hits_coll}, {protoclust_coll.get()}); - REQUIRE( (*protoclust_coll).size() == 1 ); - REQUIRE( (*protoclust_coll)[0].hits_size() == 1 ); - REQUIRE( (*protoclust_coll)[0].weights_size() == 1 ); + REQUIRE((*protoclust_coll).size() == 1); + REQUIRE((*protoclust_coll)[0].hits_size() == 1); + REQUIRE((*protoclust_coll)[0].weights_size() == 1); } - SECTION( "on two separated cells" ) { + SECTION("on two separated cells") { edm4eic::CalorimeterHitCollection hits_coll; hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}, {"layer", 0}}), // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + id_desc.encode( + {{"system", 255}, {"x", 0}, {"y", 0}, {"layer", 0}}), // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local ); hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 2}, {"y", 2}, {"layer", 0}}), // std::uint64_t cellID, - 6.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(1.1, 1.1, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(1.1 /* mm */, 1.1 /* mm */, 0.0) // edm4hep::Vector3f local + id_desc.encode( + {{"system", 255}, {"x", 2}, {"y", 2}, {"layer", 0}}), // std::uint64_t cellID, + 6.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(1.1, 1.1, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(1.1 /* mm */, 1.1 /* mm */, 0.0) // edm4hep::Vector3f local ); auto protoclust_coll = std::make_unique(); algo.process({&hits_coll}, {protoclust_coll.get()}); - REQUIRE( (*protoclust_coll).size() == 2 ); - REQUIRE( (*protoclust_coll)[0].hits_size() == 1 ); - REQUIRE( (*protoclust_coll)[0].weights_size() == 1 ); - REQUIRE( (*protoclust_coll)[1].hits_size() == 1 ); - REQUIRE( (*protoclust_coll)[1].weights_size() == 1 ); + REQUIRE((*protoclust_coll).size() == 2); + REQUIRE((*protoclust_coll)[0].hits_size() == 1); + REQUIRE((*protoclust_coll)[0].weights_size() == 1); + REQUIRE((*protoclust_coll)[1].hits_size() == 1); + REQUIRE((*protoclust_coll)[1].weights_size() == 1); } - SECTION( "on two adjacent cells (same layer)" ) { + SECTION("on two adjacent cells (same layer)") { edm4eic::CalorimeterHitCollection hits_coll; hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}), // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local ); hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}), // std::uint64_t cellID, - 6.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.9, 0.9, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local + id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}), // std::uint64_t cellID, + 6.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.9, 0.9, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local ); auto protoclust_coll = std::make_unique(); algo.process({&hits_coll}, {protoclust_coll.get()}); - REQUIRE( (*protoclust_coll).size() == 1 ); - REQUIRE( (*protoclust_coll)[0].hits_size() == 2 ); - REQUIRE( (*protoclust_coll)[0].weights_size() == 2 ); + REQUIRE((*protoclust_coll).size() == 1); + REQUIRE((*protoclust_coll)[0].hits_size() == 2); + REQUIRE((*protoclust_coll)[0].weights_size() == 2); } } - SECTION( "run on three cells, two of which are on the same layer, and there is a third one on another layer acting as a bridge between them" ) { + SECTION("run on three cells, two of which are on the same layer, and there is a third one on " + "another layer acting as a bridge between them") { cfg.localDistXY = {1 * dd4hep::mm, 1 * dd4hep::mm}; algo.applyConfig(cfg); @@ -147,48 +151,49 @@ TEST_CASE( "the clustering algorithm runs", "[ImagingTopoCluster]" ) { edm4eic::CalorimeterHitCollection hits_coll; hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}, {"layer", 0}}), // std::uint64_t cellID, - 5.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local + id_desc.encode( + {{"system", 255}, {"x", 0}, {"y", 0}, {"layer", 0}}), // std::uint64_t cellID, + 5.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.0, 0.0, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(0.0, 0.0, 0.0) // edm4hep::Vector3f local ); hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}, {"layer",1}}), // std::uint64_t cellID, - 1.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(0.9, 0.9, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 1, // std::int32_t layer, - edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local + id_desc.encode( + {{"system", 255}, {"x", 1}, {"y", 0}, {"layer", 1}}), // std::uint64_t cellID, + 1.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(0.9, 0.9, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 1, // std::int32_t layer, + edm4hep::Vector3f(0.9 /* mm */, 0.9 /* mm */, 0.0) // edm4hep::Vector3f local ); hits_coll.create( - id_desc.encode({{"system", 255}, {"x", 2}, {"y", 0},{"layer",0}}), // std::uint64_t cellID, - 6.0, // float energy, - 0.0, // float energyError, - 0.0, // float time, - 0.0, // float timeError, - edm4hep::Vector3f(1.8, 1.8, 0.0), // edm4hep::Vector3f position, - edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, - 0, // std::int32_t sector, - 0, // std::int32_t layer, - edm4hep::Vector3f(1.8 /* mm */, 1.8 /* mm */, 0.0) // edm4hep::Vector3f local + id_desc.encode( + {{"system", 255}, {"x", 2}, {"y", 0}, {"layer", 0}}), // std::uint64_t cellID, + 6.0, // float energy, + 0.0, // float energyError, + 0.0, // float time, + 0.0, // float timeError, + edm4hep::Vector3f(1.8, 1.8, 0.0), // edm4hep::Vector3f position, + edm4hep::Vector3f(1.0, 1.0, 0.0), // edm4hep::Vector3f dimension, + 0, // std::int32_t sector, + 0, // std::int32_t layer, + edm4hep::Vector3f(1.8 /* mm */, 1.8 /* mm */, 0.0) // edm4hep::Vector3f local ); auto protoclust_coll = std::make_unique(); algo.process({&hits_coll}, {protoclust_coll.get()}); - - REQUIRE( (*protoclust_coll).size() == 1 ); - REQUIRE( (*protoclust_coll)[0].hits_size() == 3 ); - REQUIRE( (*protoclust_coll)[0].weights_size() == 3 ); - + REQUIRE((*protoclust_coll).size() == 1); + REQUIRE((*protoclust_coll)[0].hits_size() == 3); + REQUIRE((*protoclust_coll)[0].weights_size() == 3); } } diff --git a/src/tests/algorithms_test/pid_MergeParticleID.cc b/src/tests/algorithms_test/pid_MergeParticleID.cc index 1a19fac787..85873925f8 100644 --- a/src/tests/algorithms_test/pid_MergeParticleID.cc +++ b/src/tests/algorithms_test/pid_MergeParticleID.cc @@ -33,7 +33,7 @@ TEST_CASE("the PID MergeParticleID algorithm runs", "[MergeParticleID]") { * since `MergeParticleID` matches tracks by ID */ auto tracks = std::make_unique(); - for(int i=0; i<2; i++) + for (int i = 0; i < 2; i++) tracks->create(); // Cherenkov PID inputs @@ -42,7 +42,7 @@ TEST_CASE("the PID MergeParticleID algorithm runs", "[MergeParticleID]") { * 2 or 3 possible PID hypotheses for each */ - edm4eic::MutableCherenkovParticleID pid; + edm4eic::MutableCherenkovParticleID pid; edm4eic::CherenkovParticleIDHypothesis pid_hyp; // collection 1 ------ @@ -61,8 +61,8 @@ TEST_CASE("the PID MergeParticleID algorithm runs", "[MergeParticleID]") { pid_hyp.npe = 8; pid_hyp.weight = 80; pid.addToHypotheses(pid_hyp); - for(int i=0; i<=pid.getNpe(); i++) - pid.addToThetaPhiPhotons(edm4hep::Vector2f{M_PI/4, 0}); + for (int i = 0; i <= pid.getNpe(); i++) + pid.addToThetaPhiPhotons(edm4hep::Vector2f{M_PI / 4, 0}); pid = coll_cherenkov_1->create(); pid.setChargedParticle(tracks->at(1)); @@ -77,8 +77,8 @@ TEST_CASE("the PID MergeParticleID algorithm runs", "[MergeParticleID]") { pid_hyp.npe = 10; pid_hyp.weight = 80; pid.addToHypotheses(pid_hyp); - for(int i=0; i<=pid.getNpe(); i++) - pid.addToThetaPhiPhotons(edm4hep::Vector2f{-M_PI/4, 0}); + for (int i = 0; i <= pid.getNpe(); i++) + pid.addToThetaPhiPhotons(edm4hep::Vector2f{-M_PI / 4, 0}); // collection 2 ------ auto coll_cherenkov_2 = std::make_unique(); @@ -96,8 +96,8 @@ TEST_CASE("the PID MergeParticleID algorithm runs", "[MergeParticleID]") { pid_hyp.npe = 2; pid_hyp.weight = 90; pid.addToHypotheses(pid_hyp); - for(int i=0; i<=pid.getNpe(); i++) - pid.addToThetaPhiPhotons(edm4hep::Vector2f{M_PI/4, 0}); + for (int i = 0; i <= pid.getNpe(); i++) + pid.addToThetaPhiPhotons(edm4hep::Vector2f{M_PI / 4, 0}); pid = coll_cherenkov_2->create(); pid.setChargedParticle(tracks->at(0)); @@ -116,25 +116,24 @@ TEST_CASE("the PID MergeParticleID algorithm runs", "[MergeParticleID]") { pid_hyp.npe = 1; pid_hyp.weight = 60; pid.addToHypotheses(pid_hyp); - for(int i=0; i<=pid.getNpe(); i++) - pid.addToThetaPhiPhotons(edm4hep::Vector2f{-M_PI/4, 0}); + for (int i = 0; i <= pid.getNpe(); i++) + pid.addToThetaPhiPhotons(edm4hep::Vector2f{-M_PI / 4, 0}); // Cherenkov PID tests //---------------------------------------------------------- std::vector> coll_cherenkov_list = { - coll_cherenkov_1.get(), - coll_cherenkov_2.get() - }; + coll_cherenkov_1.get(), coll_cherenkov_2.get()}; - auto find_cherenkov_pid_for_track = [] (const auto& coll, auto trk) { - for(auto obj : *coll) { - if(obj.getChargedParticle().id() == trk.id()) + auto find_cherenkov_pid_for_track = [](const auto& coll, auto trk) { + for (auto obj : *coll) { + if (obj.getChargedParticle().id() == trk.id()) return obj; } FAIL("ERROR: cannot find CherenkovParticleID given track"); - if(coll->size() == 0) - throw std::runtime_error("empty collection used in pid_MergeParticleID::find_cherenkov_pid_for_track"); + if (coll->size() == 0) + throw std::runtime_error( + "empty collection used in pid_MergeParticleID::find_cherenkov_pid_for_track"); return coll->at(0); }; @@ -149,54 +148,57 @@ TEST_CASE("the PID MergeParticleID algorithm runs", "[MergeParticleID]") { auto result = std::make_unique(); algo.process({coll_cherenkov_list}, {result.get()}); - auto pid_0 = find_cherenkov_pid_for_track(result, tracks->at(0)); - auto pid_1 = find_cherenkov_pid_for_track(result, tracks->at(1)); + auto pid_0 = find_cherenkov_pid_for_track(result, tracks->at(0)); + auto pid_1 = find_cherenkov_pid_for_track(result, tracks->at(1)); - REQUIRE_THAT( pid_0.getNpe(), Catch::Matchers::WithinAbs(10+6, EPSILON) ); - REQUIRE_THAT( pid_1.getNpe(), Catch::Matchers::WithinAbs(11+4, EPSILON) ); + REQUIRE_THAT(pid_0.getNpe(), Catch::Matchers::WithinAbs(10 + 6, EPSILON)); + REQUIRE_THAT(pid_1.getNpe(), Catch::Matchers::WithinAbs(11 + 4, EPSILON)); - REQUIRE_THAT( pid_0.getRefractiveIndex(), Catch::Matchers::WithinAbs((10*1.05+6*1.3)/(10+6), EPSILON) ); - REQUIRE_THAT( pid_1.getRefractiveIndex(), Catch::Matchers::WithinAbs((11*1.06+4*1.5)/(11+4), EPSILON) ); + REQUIRE_THAT(pid_0.getRefractiveIndex(), + Catch::Matchers::WithinAbs((10 * 1.05 + 6 * 1.3) / (10 + 6), EPSILON)); + REQUIRE_THAT(pid_1.getRefractiveIndex(), + Catch::Matchers::WithinAbs((11 * 1.06 + 4 * 1.5) / (11 + 4), EPSILON)); - REQUIRE_THAT( pid_0.getPhotonEnergy(), Catch::Matchers::WithinAbs((10*3e-9+6*4e-9)/(10+6), EPSILON) ); - REQUIRE_THAT( pid_1.getPhotonEnergy(), Catch::Matchers::WithinAbs((11*4e-9+4*3e-9)/(11+4), EPSILON) ); + REQUIRE_THAT(pid_0.getPhotonEnergy(), + Catch::Matchers::WithinAbs((10 * 3e-9 + 6 * 4e-9) / (10 + 6), EPSILON)); + REQUIRE_THAT(pid_1.getPhotonEnergy(), + Catch::Matchers::WithinAbs((11 * 4e-9 + 4 * 3e-9) / (11 + 4), EPSILON)); REQUIRE(pid_0.hypotheses_size() == 3); - for(auto hyp : pid_0.getHypotheses()) { - switch(hyp.PDG) { - case 211: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(10+1, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(100+80, EPSILON) ); - break; - case 321: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(8+4, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(80+70, EPSILON) ); - break; - case 11: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(1, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(60, EPSILON) ); - break; - default: - FAIL("untested PDG hypothesis"); + for (auto hyp : pid_0.getHypotheses()) { + switch (hyp.PDG) { + case 211: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(10 + 1, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(100 + 80, EPSILON)); + break; + case 321: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(8 + 4, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(80 + 70, EPSILON)); + break; + case 11: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(1, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(60, EPSILON)); + break; + default: + FAIL("untested PDG hypothesis"); } } REQUIRE(pid_1.hypotheses_size() == 2); - for(auto hyp : pid_1.getHypotheses()) { - switch(hyp.PDG) { - case 211: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(10+3, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(80+200, EPSILON) ); - break; - case 321: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(10+2, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(100+90, EPSILON) ); - break; - default: - FAIL("untested PDG hypothesis"); + for (auto hyp : pid_1.getHypotheses()) { + switch (hyp.PDG) { + case 211: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(10 + 3, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(80 + 200, EPSILON)); + break; + case 321: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(10 + 2, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(100 + 90, EPSILON)); + break; + default: + FAIL("untested PDG hypothesis"); } } - } // multiplicative weights @@ -214,52 +216,54 @@ TEST_CASE("the PID MergeParticleID algorithm runs", "[MergeParticleID]") { auto result = std::make_unique(); algo.process({coll_cherenkov_list}, {result.get()}); - auto pid_0 = find_cherenkov_pid_for_track(result, tracks->at(0)); - auto pid_1 = find_cherenkov_pid_for_track(result, tracks->at(1)); - - REQUIRE_THAT( pid_0.getNpe(), Catch::Matchers::WithinAbs(10+6, EPSILON) ); - REQUIRE_THAT( pid_1.getNpe(), Catch::Matchers::WithinAbs(11+4, EPSILON) ); - - REQUIRE_THAT( pid_0.getRefractiveIndex(), Catch::Matchers::WithinAbs((10*1.05+6*1.3)/(10+6), EPSILON) ); - REQUIRE_THAT( pid_1.getRefractiveIndex(), Catch::Matchers::WithinAbs((11*1.06+4*1.5)/(11+4), EPSILON) ); - - REQUIRE_THAT( pid_0.getPhotonEnergy(), Catch::Matchers::WithinAbs((10*3e-9+6*4e-9)/(10+6), EPSILON) ); - REQUIRE_THAT( pid_1.getPhotonEnergy(), Catch::Matchers::WithinAbs((11*4e-9+4*3e-9)/(11+4), EPSILON) ); - - for(auto hyp : pid_0.getHypotheses()) { - switch(hyp.PDG) { - case 211: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(10+1, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(100*80, EPSILON) ); - break; - case 321: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(8+4, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(80*70, EPSILON) ); - break; - case 11: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(1, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(60, EPSILON) ); - break; - default: - FAIL("untested PDG hypothesis"); + auto pid_0 = find_cherenkov_pid_for_track(result, tracks->at(0)); + auto pid_1 = find_cherenkov_pid_for_track(result, tracks->at(1)); + + REQUIRE_THAT(pid_0.getNpe(), Catch::Matchers::WithinAbs(10 + 6, EPSILON)); + REQUIRE_THAT(pid_1.getNpe(), Catch::Matchers::WithinAbs(11 + 4, EPSILON)); + + REQUIRE_THAT(pid_0.getRefractiveIndex(), + Catch::Matchers::WithinAbs((10 * 1.05 + 6 * 1.3) / (10 + 6), EPSILON)); + REQUIRE_THAT(pid_1.getRefractiveIndex(), + Catch::Matchers::WithinAbs((11 * 1.06 + 4 * 1.5) / (11 + 4), EPSILON)); + + REQUIRE_THAT(pid_0.getPhotonEnergy(), + Catch::Matchers::WithinAbs((10 * 3e-9 + 6 * 4e-9) / (10 + 6), EPSILON)); + REQUIRE_THAT(pid_1.getPhotonEnergy(), + Catch::Matchers::WithinAbs((11 * 4e-9 + 4 * 3e-9) / (11 + 4), EPSILON)); + + for (auto hyp : pid_0.getHypotheses()) { + switch (hyp.PDG) { + case 211: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(10 + 1, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(100 * 80, EPSILON)); + break; + case 321: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(8 + 4, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(80 * 70, EPSILON)); + break; + case 11: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(1, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(60, EPSILON)); + break; + default: + FAIL("untested PDG hypothesis"); } } - for(auto hyp : pid_1.getHypotheses()) { - switch(hyp.PDG) { - case 211: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(10+3, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(80*200, EPSILON) ); - break; - case 321: - REQUIRE_THAT( hyp.npe, Catch::Matchers::WithinAbs(10+2, EPSILON) ); - REQUIRE_THAT( hyp.weight, Catch::Matchers::WithinAbs(100*90, EPSILON) ); - break; - default: - FAIL("untested PDG hypothesis"); + for (auto hyp : pid_1.getHypotheses()) { + switch (hyp.PDG) { + case 211: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(10 + 3, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(80 * 200, EPSILON)); + break; + case 321: + REQUIRE_THAT(hyp.npe, Catch::Matchers::WithinAbs(10 + 2, EPSILON)); + REQUIRE_THAT(hyp.weight, Catch::Matchers::WithinAbs(100 * 90, EPSILON)); + break; + default: + FAIL("untested PDG hypothesis"); } } - } - } diff --git a/src/tests/algorithms_test/pid_lut_PIDLookup.cc b/src/tests/algorithms_test/pid_lut_PIDLookup.cc index 0bfc8db7f9..b6298821d0 100644 --- a/src/tests/algorithms_test/pid_lut_PIDLookup.cc +++ b/src/tests/algorithms_test/pid_lut_PIDLookup.cc @@ -21,68 +21,67 @@ using eicrecon::PIDLookup; using eicrecon::PIDLookupConfig; -TEST_CASE( "particles acquire PID", "[PIDLookup]" ) { +TEST_CASE("particles acquire PID", "[PIDLookup]") { PIDLookup algo("test"); - PIDLookupConfig cfg { - .filename="/dev/null", - .system=0xFF, - .pdg_values={11}, - .charge_values={1}, - .momentum_edges={0., 1., 2.}, - .polar_edges={0., M_PI}, - .azimuthal_binning={0., 2 * M_PI, 2 * M_PI}, // lower, upper, step - .momentum_bin_centers_in_lut=true, - .polar_bin_centers_in_lut=true, - .use_radians=true, + PIDLookupConfig cfg{ + .filename = "/dev/null", + .system = 0xFF, + .pdg_values = {11}, + .charge_values = {1}, + .momentum_edges = {0., 1., 2.}, + .polar_edges = {0., M_PI}, + .azimuthal_binning = {0., 2 * M_PI, 2 * M_PI}, // lower, upper, step + .momentum_bin_centers_in_lut = true, + .polar_bin_centers_in_lut = true, + .use_radians = true, }; - SECTION( "single hit with couple contributions" ) { + SECTION("single hit with couple contributions") { algo.level(algorithms::LogLevel(spdlog::level::trace)); algo.applyConfig(cfg); algo.init(); - auto parts_in = std::make_unique(); + auto parts_in = std::make_unique(); auto assocs_in = std::make_unique(); - auto mcparts = std::make_unique(); + auto mcparts = std::make_unique(); - parts_in->create( - 0, // std::int32_t type - 0.5, // float energy - edm4hep::Vector3f({0.5, 0., 0.}), // edm4hep::Vector3f momentum - edm4hep::Vector3f({0., 0., 0.}), // edm4hep::Vector3f referencePoint - 1., // float charge - 0., // float mass - 0., // float goodnessOfPID - edm4eic::Cov4f(), // edm4eic::Cov4f covMatrix - 0 // std::int32_t PDG + parts_in->create(0, // std::int32_t type + 0.5, // float energy + edm4hep::Vector3f({0.5, 0., 0.}), // edm4hep::Vector3f momentum + edm4hep::Vector3f({0., 0., 0.}), // edm4hep::Vector3f referencePoint + 1., // float charge + 0., // float mass + 0., // float goodnessOfPID + edm4eic::Cov4f(), // edm4eic::Cov4f covMatrix + 0 // std::int32_t PDG ); - mcparts->create( - 11, // std::int32_t PDG - 0, // std::int32_t generatorStatus - 0, // std::int32_t simulatorStatus - 0., // float charge - 0., // float time - 0., // double mass - edm4hep::Vector3d(), // edm4hep::Vector3d vertex - edm4hep::Vector3d(), // edm4hep::Vector3d endpoint - edm4hep::Vector3f(), // edm4hep::Vector3f momentum - edm4hep::Vector3f(), // edm4hep::Vector3f momentumAtEndpoint - edm4hep::Vector3f(), // edm4hep::Vector3f spin - edm4hep::Vector2i() // edm4hep::Vector2i colorFlow + mcparts->create(11, // std::int32_t PDG + 0, // std::int32_t generatorStatus + 0, // std::int32_t simulatorStatus + 0., // float charge + 0., // float time + 0., // double mass + edm4hep::Vector3d(), // edm4hep::Vector3d vertex + edm4hep::Vector3d(), // edm4hep::Vector3d endpoint + edm4hep::Vector3f(), // edm4hep::Vector3f momentum + edm4hep::Vector3f(), // edm4hep::Vector3f momentumAtEndpoint + edm4hep::Vector3f(), // edm4hep::Vector3f spin + edm4hep::Vector2i() // edm4hep::Vector2i colorFlow ); auto assoc_in = assocs_in->create(); assoc_in.setRec((*parts_in)[0]); assoc_in.setSim((*mcparts)[0]); - auto parts_out = std::make_unique(); - auto assocs_out = std::make_unique(); + auto parts_out = std::make_unique(); + auto assocs_out = std::make_unique(); auto partids_out = std::make_unique(); - algo.process({parts_in.get(), assocs_in.get()}, {parts_out.get(), assocs_out.get(), partids_out.get()}); + algo.process({parts_in.get(), assocs_in.get()}, + {parts_out.get(), assocs_out.get(), partids_out.get()}); - REQUIRE( (*parts_in).size() == (*parts_out).size() ); - REQUIRE( (*assocs_in).size() == (*assocs_out).size() ); - REQUIRE( (*partids_out).size() == (*partids_out).size() ); + REQUIRE((*parts_in).size() == (*parts_out).size()); + REQUIRE((*assocs_in).size() == (*assocs_out).size()); + REQUIRE((*partids_out).size() == (*partids_out).size()); } } diff --git a/src/tests/algorithms_test/reco_FarForwardNeutronReconstruction.cc b/src/tests/algorithms_test/reco_FarForwardNeutronReconstruction.cc index 24e4b3a3f4..53c7a5a5ef 100644 --- a/src/tests/algorithms_test/reco_FarForwardNeutronReconstruction.cc +++ b/src/tests/algorithms_test/reco_FarForwardNeutronReconstruction.cc @@ -1,20 +1,20 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2024, Sebouh Paul -#include // for MeV, mm, keV, ns -#include // for AssertionHandler, operator""_catch_sr, StringRef, REQUIRE, operator<, operator==, operator>, TEST_CASE +#include // for MeV, mm, keV, ns +#include // for AssertionHandler, operator""_catch_sr, StringRef, REQUIRE, operator<, operator==, operator>, TEST_CASE #include #include -#include // for Vector3f -#include // for level_enum -#include // for logger -#include // for default_logger -#include // for size_t +#include // for Vector3f +#include // for level_enum +#include // for logger +#include // for default_logger +#include // for size_t #include -#include // for array -#include // for sqrt, abs +#include // for array +#include // for sqrt, abs #include -#include // for allocator, unique_ptr, make_unique, shared_ptr, __shared_ptr_access +#include // for allocator, unique_ptr, make_unique, shared_ptr, __shared_ptr_access #include #include "algorithms/reco/FarForwardNeutronReconstruction.h" @@ -23,53 +23,55 @@ using eicrecon::FarForwardNeutronReconstruction; using eicrecon::FarForwardNeutronReconstructionConfig; -TEST_CASE( "the cluster merging algorithm runs", "[FarForwardNeutronReconstruction]" ) { +TEST_CASE("the cluster merging algorithm runs", "[FarForwardNeutronReconstruction]") { FarForwardNeutronReconstruction algo("FarForwardNeutronReconstruction"); - std::shared_ptr logger = spdlog::default_logger()->clone("FarForwardNeutronReconstruction"); + std::shared_ptr logger = + spdlog::default_logger()->clone("FarForwardNeutronReconstruction"); logger->set_level(spdlog::level::trace); FarForwardNeutronReconstructionConfig cfg; - std::vector corr_parameters={-0.0756, -1.91, 2.30}; - cfg.scale_corr_coeff_hcal=corr_parameters; - cfg.scale_corr_coeff_ecal=corr_parameters; + std::vector corr_parameters = {-0.0756, -1.91, 2.30}; + cfg.scale_corr_coeff_hcal = corr_parameters; + cfg.scale_corr_coeff_ecal = corr_parameters; algo.applyConfig(cfg); algo.init(); edm4eic::ClusterCollection clust_coll_hcal; - std::array x={30*dd4hep::mm,90*dd4hep::mm,0}; - std::array y={-30*dd4hep::mm,0*dd4hep::mm, -90*dd4hep::mm}; - std::array z={30*dd4hep::m,30*dd4hep::m, 30*dd4hep::m}; - std::array E={80*dd4hep::GeV,5*dd4hep::GeV,5*dd4hep::GeV}; - float sumEnergies=0; - for(size_t i=0; i<3; i++){ - auto cluster=clust_coll_hcal.create(); + std::array x = {30 * dd4hep::mm, 90 * dd4hep::mm, 0}; + std::array y = {-30 * dd4hep::mm, 0 * dd4hep::mm, -90 * dd4hep::mm}; + std::array z = {30 * dd4hep::m, 30 * dd4hep::m, 30 * dd4hep::m}; + std::array E = {80 * dd4hep::GeV, 5 * dd4hep::GeV, 5 * dd4hep::GeV}; + float sumEnergies = 0; + for (size_t i = 0; i < 3; i++) { + auto cluster = clust_coll_hcal.create(); cluster.setEnergy(E[i]); cluster.setPosition({x[i], y[i], z[i]}); - } edm4eic::ClusterCollection clust_coll_ecal; - auto ecal_cluster=clust_coll_ecal.create(); + auto ecal_cluster = clust_coll_ecal.create(); ecal_cluster.setEnergy(2); - ecal_cluster.setPosition({0, 0, 25*dd4hep::m}); + ecal_cluster.setPosition({0, 0, 25 * dd4hep::m}); auto neutroncand_coll = std::make_unique(); algo.process({&clust_coll_hcal, &clust_coll_ecal}, {neutroncand_coll.get()}); - REQUIRE( (*neutroncand_coll).size() == 1); + REQUIRE((*neutroncand_coll).size() == 1); - double corr=algo.calc_corr(92, corr_parameters); - double tol=0.001; - double E_expected=92*dd4hep::GeV*1/(1+corr); - double Px_expected=0.09199*1/(1+corr); - double Py_expected=-0.09199*1/(1+corr); - double Pz_expected=91.99*1/(1+corr); + double corr = algo.calc_corr(92, corr_parameters); + double tol = 0.001; + double E_expected = 92 * dd4hep::GeV * 1 / (1 + corr); + double Px_expected = 0.09199 * 1 / (1 + corr); + double Py_expected = -0.09199 * 1 / (1 + corr); + double Pz_expected = 91.99 * 1 / (1 + corr); //check that the correct energy and momenta are being obtained - std::cout << "E, px, py, pz = " << (*neutroncand_coll)[0].getEnergy() <<" " << (*neutroncand_coll)[0].getMomentum().x << " " << (*neutroncand_coll)[0].getMomentum().y << " " << (*neutroncand_coll)[0].getMomentum().z << std::endl; - REQUIRE( abs((*neutroncand_coll)[0].getEnergy()-E_expected)/E_expectedGetService(); + // Get JANA application + auto* app = GetApplication(); - // Get TDirectory for histograms root file - auto globalRootLock = app->GetService(); - globalRootLock->acquire_write_lock(); - auto *file = root_file_service->GetHistFile(); - globalRootLock->release_lock(); + // Ask service locator a file to write histograms to + auto root_file_service = app->GetService(); - // Create a directory for this plugin. And subdirectories for series of histograms - m_dir_main = file->mkdir(plugin_name.c_str()); + // Get TDirectory for histograms root file + auto globalRootLock = app->GetService(); + globalRootLock->acquire_write_lock(); + auto* file = root_file_service->GetHistFile(); + globalRootLock->release_lock(); - // Get log level from user parameter or default - InitLogger(app, plugin_name); + // Create a directory for this plugin. And subdirectories for series of histograms + m_dir_main = file->mkdir(plugin_name.c_str()); - auto acts_service = GetApplication()->GetService(); + // Get log level from user parameter or default + InitLogger(app, plugin_name); + auto acts_service = GetApplication()->GetService(); } +void GeometryNavigationSteps_processor::Process(const std::shared_ptr& event) {} -void GeometryNavigationSteps_processor::Process(const std::shared_ptr& event) -{ -} - -void GeometryNavigationSteps_processor::Finish() -{ -} +void GeometryNavigationSteps_processor::Finish() {} diff --git a/src/tests/geometry_navigation_test/GeometryNavigationSteps_processor.h b/src/tests/geometry_navigation_test/GeometryNavigationSteps_processor.h index 26cbbeeec0..2f115d2793 100644 --- a/src/tests/geometry_navigation_test/GeometryNavigationSteps_processor.h +++ b/src/tests/geometry_navigation_test/GeometryNavigationSteps_processor.h @@ -11,46 +11,44 @@ #include "extensions/spdlog/SpdlogMixin.h" -class GeometryNavigationSteps_processor: - public JEventProcessor, - public eicrecon::SpdlogMixin // this automates proper log initialization +class GeometryNavigationSteps_processor + : public JEventProcessor, + public eicrecon::SpdlogMixin // this automates proper log initialization { public: - explicit GeometryNavigationSteps_processor(JApplication *); - ~GeometryNavigationSteps_processor() override = default; - - //---------------------------- - // Init - // - // This is called once before the first call to the Process method - // below. You may, for example, want to open an output file here. - // Only one thread will call this. - void Init() override; - - //---------------------------- - // Process - // - // This is called for every event. Multiple threads may call this - // simultaneously. If you write something to an output file here - // then make sure to protect it with a mutex or similar mechanism. - // Minimize what is done while locked since that directly affects - // the multi-threaded performance. - void Process(const std::shared_ptr& event) override; - - //---------------------------- - // Finish - // - // This is called once after all events have been processed. You may, - // for example, want to close an output file here. - // Only one thread will call this. - void Finish() override; + explicit GeometryNavigationSteps_processor(JApplication*); + ~GeometryNavigationSteps_processor() override = default; + + //---------------------------- + // Init + // + // This is called once before the first call to the Process method + // below. You may, for example, want to open an output file here. + // Only one thread will call this. + void Init() override; + + //---------------------------- + // Process + // + // This is called for every event. Multiple threads may call this + // simultaneously. If you write something to an output file here + // then make sure to protect it with a mutex or similar mechanism. + // Minimize what is done while locked since that directly affects + // the multi-threaded performance. + void Process(const std::shared_ptr& event) override; + + //---------------------------- + // Finish + // + // This is called once after all events have been processed. You may, + // for example, want to close an output file here. + // Only one thread will call this. + void Finish() override; private: - - /// Directory to store histograms to - TDirectory *m_dir_main{}; - Acts::GeometryContext m_geoContext; - Acts::MagneticFieldContext m_fieldContext; - std::shared_ptr m_log; - + /// Directory to store histograms to + TDirectory* m_dir_main{}; + Acts::GeometryContext m_geoContext; + Acts::MagneticFieldContext m_fieldContext; + std::shared_ptr m_log; }; diff --git a/src/tests/geometry_navigation_test/geometry_navigation_test.cc b/src/tests/geometry_navigation_test/geometry_navigation_test.cc index e451412ee9..b378ed0d59 100644 --- a/src/tests/geometry_navigation_test/geometry_navigation_test.cc +++ b/src/tests/geometry_navigation_test/geometry_navigation_test.cc @@ -7,14 +7,13 @@ #include "GeometryNavigationSteps_processor.h" - extern "C" { - void InitPlugin(JApplication *app) { +void InitPlugin(JApplication* app) { - // Initializes this plugin - InitJANAPlugin(app); + // Initializes this plugin + InitJANAPlugin(app); - // Adds our processor to JANA2 to execute - app->Add(new GeometryNavigationSteps_processor(app)); - } + // Adds our processor to JANA2 to execute + app->Add(new GeometryNavigationSteps_processor(app)); +} } diff --git a/src/tests/omnifactory_test/JOmniFactoryTests.cc b/src/tests/omnifactory_test/JOmniFactoryTests.cc index b9ca6b6b4e..9b3238b1a4 100644 --- a/src/tests/omnifactory_test/JOmniFactoryTests.cc +++ b/src/tests/omnifactory_test/JOmniFactoryTests.cc @@ -22,401 +22,413 @@ #include "extensions/jana/JOmniFactoryGeneratorT.h" struct BasicTestAlgConfig { - int bucket_count = 42; - double threshold = 7.6; + int bucket_count = 42; + double threshold = 7.6; }; struct BasicTestAlg : public JOmniFactory { - PodioOutput output_hits_left {this, "output_hits_left"}; - PodioOutput output_hits_right {this, "output_hits_right"}; - Output output_vechits {this, "output_vechits"}; - - ParameterRef bucket_count {this, "bucket_count", config().bucket_count, "The total number of buckets [dimensionless]"}; - ParameterRef threshold {this, "threshold", config().threshold, "The max cutoff threshold [V * A * kg^-1 * m^-2 * sec^-3]"}; - - std::vector GetOutputs() { return this->m_outputs; } - - int m_init_call_count = 0; - int m_changerun_call_count = 0; - int m_process_call_count = 0; - - void Configure() { - m_init_call_count++; - logger()->info("Calling BasicTestAlg::Configure"); - } - - void ChangeRun(int64_t run_number) { - m_changerun_call_count++; - logger()->info("Calling BasicTestAlg::ChangeRun"); - } - - // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) - void Process(int64_t run_number, uint64_t event_number) { - m_process_call_count++; - logger()->info("Calling BasicTestAlg::Process with bucket_count={}, threshold={}", config().bucket_count, config().threshold); - // Provide empty collections (as opposed to nulls) so that PODIO doesn't crash - output_hits_left() = std::make_unique(); - output_hits_right() = std::make_unique(); - output_vechits().push_back(new edm4hep::SimCalorimeterHit()); - } + PodioOutput output_hits_left{this, "output_hits_left"}; + PodioOutput output_hits_right{this, "output_hits_right"}; + Output output_vechits{this, "output_vechits"}; + + ParameterRef bucket_count{this, "bucket_count", config().bucket_count, + "The total number of buckets [dimensionless]"}; + ParameterRef threshold{this, "threshold", config().threshold, + "The max cutoff threshold [V * A * kg^-1 * m^-2 * sec^-3]"}; + + std::vector GetOutputs() { return this->m_outputs; } + + int m_init_call_count = 0; + int m_changerun_call_count = 0; + int m_process_call_count = 0; + + void Configure() { + m_init_call_count++; + logger()->info("Calling BasicTestAlg::Configure"); + } + + void ChangeRun(int64_t run_number) { + m_changerun_call_count++; + logger()->info("Calling BasicTestAlg::ChangeRun"); + } + + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + void Process(int64_t run_number, uint64_t event_number) { + m_process_call_count++; + logger()->info("Calling BasicTestAlg::Process with bucket_count={}, threshold={}", + config().bucket_count, config().threshold); + // Provide empty collections (as opposed to nulls) so that PODIO doesn't crash + output_hits_left() = std::make_unique(); + output_hits_right() = std::make_unique(); + output_vechits().push_back(new edm4hep::SimCalorimeterHit()); + } }; template MultifactoryT* RetrieveMultifactory(JFactorySet* facset, std::string output_collection_name) { - auto fac = facset->GetFactory(JTypeInfo::demangle(), output_collection_name); - REQUIRE(fac != nullptr); - auto helper = dynamic_cast*>(fac); - REQUIRE(helper != nullptr); - auto multifactory = helper->GetMultifactory(); - REQUIRE(multifactory != nullptr); - auto typed = dynamic_cast(multifactory); - REQUIRE(typed != nullptr); - return typed; + auto fac = facset->GetFactory(JTypeInfo::demangle(), output_collection_name); + REQUIRE(fac != nullptr); + auto helper = dynamic_cast*>(fac); + REQUIRE(helper != nullptr); + auto multifactory = helper->GetMultifactory(); + REQUIRE(multifactory != nullptr); + auto typed = dynamic_cast(multifactory); + REQUIRE(typed != nullptr); + return typed; } TEST_CASE("Registering Podio outputs works") { - BasicTestAlg alg; - REQUIRE(alg.GetOutputs().size() == 3); - REQUIRE(alg.GetOutputs()[0]->collection_names[0] == "output_hits_left"); - REQUIRE(alg.GetOutputs()[0]->type_name == "edm4hep::SimCalorimeterHit"); - REQUIRE(alg.GetOutputs()[1]->collection_names[0] == "output_hits_right"); - REQUIRE(alg.GetOutputs()[1]->type_name == "edm4hep::SimCalorimeterHit"); - REQUIRE(alg.GetOutputs()[2]->collection_names[0] == "output_vechits"); - REQUIRE(alg.GetOutputs()[2]->type_name == "edm4hep::SimCalorimeterHit"); + BasicTestAlg alg; + REQUIRE(alg.GetOutputs().size() == 3); + REQUIRE(alg.GetOutputs()[0]->collection_names[0] == "output_hits_left"); + REQUIRE(alg.GetOutputs()[0]->type_name == "edm4hep::SimCalorimeterHit"); + REQUIRE(alg.GetOutputs()[1]->collection_names[0] == "output_hits_right"); + REQUIRE(alg.GetOutputs()[1]->type_name == "edm4hep::SimCalorimeterHit"); + REQUIRE(alg.GetOutputs()[2]->collection_names[0] == "output_vechits"); + REQUIRE(alg.GetOutputs()[2]->type_name == "edm4hep::SimCalorimeterHit"); } TEST_CASE("Configuration object is correctly wired from untyped wiring data") { - JApplication app; - app.AddPlugin("log"); - app.Initialize(); - JOmniFactoryGeneratorT facgen (&app); - facgen.AddWiring("ECalTestAlg", {}, {"ECalLeftHits", "ECalRightHits", "ECalVecHits"}, {{"threshold", "6.1"}, {"bucket_count", "22"}}); + JApplication app; + app.AddPlugin("log"); + app.Initialize(); + JOmniFactoryGeneratorT facgen(&app); + facgen.AddWiring("ECalTestAlg", {}, {"ECalLeftHits", "ECalRightHits", "ECalVecHits"}, + {{"threshold", "6.1"}, {"bucket_count", "22"}}); - JFactorySet facset; - facgen.GenerateFactories(&facset); - // for (auto* fac : facset.GetAllFactories()) { - // std::cout << "typename=" << fac->GetFactoryName() << ", tag=" << fac->GetTag() << std::endl; - // } + JFactorySet facset; + facgen.GenerateFactories(&facset); + // for (auto* fac : facset.GetAllFactories()) { + // std::cout << "typename=" << fac->GetFactoryName() << ", tag=" << fac->GetTag() << std::endl; + // } - auto basictestalg = RetrieveMultifactory(&facset, "ECalLeftHits"); + auto basictestalg = + RetrieveMultifactory(&facset, "ECalLeftHits"); - REQUIRE(basictestalg->threshold() == 6.1); - REQUIRE(basictestalg->bucket_count() == 22); + REQUIRE(basictestalg->threshold() == 6.1); + REQUIRE(basictestalg->bucket_count() == 22); - REQUIRE(basictestalg->config().threshold == 6.1); - REQUIRE(basictestalg->config().bucket_count == 22); + REQUIRE(basictestalg->config().threshold == 6.1); + REQUIRE(basictestalg->config().bucket_count == 22); - REQUIRE(basictestalg->m_init_call_count == 0); + REQUIRE(basictestalg->m_init_call_count == 0); } TEST_CASE("Multiple configuration objects are correctly wired from untyped wiring data") { - JApplication app; - app.AddPlugin("log"); - app.Initialize(); - JOmniFactoryGeneratorT facgen (&app); - facgen.AddWiring("BCalTestAlg", {}, {"BCalLeftHits", "BCalRightHits", "BCalVecHits"}, {{"threshold", "6.1"}, {"bucket_count", "22"}}); - facgen.AddWiring("CCalTestAlg", {}, {"CCalLeftHits", "CCalRightHits", "CCalVecHits"}, {{"threshold", "9.0"}, {"bucket_count", "27"}}); - facgen.AddWiring("ECalTestAlg", {}, {"ECalLeftHits", "ECalRightHits", "ECalVecHits"}, {{"threshold", "16.25"}, {"bucket_count", "49"}}); - - JFactorySet facset; - facgen.GenerateFactories(&facset); - // for (auto* fac : facset.GetAllFactories()) { - // std::cout << "typename=" << fac->GetFactoryName() << ", tag=" << fac->GetTag() << std::endl; - // } - auto b = RetrieveMultifactory(&facset, "BCalLeftHits"); - auto c = RetrieveMultifactory(&facset, "CCalLeftHits"); - auto e = RetrieveMultifactory(&facset, "ECalLeftHits"); - - REQUIRE(b->threshold() == 6.1); - REQUIRE(b->bucket_count() == 22); - REQUIRE(b->config().threshold == 6.1); - REQUIRE(b->config().bucket_count == 22); - - REQUIRE(c->threshold() == 9.0); - REQUIRE(c->bucket_count() == 27); - REQUIRE(c->config().threshold == 9.0); - REQUIRE(c->config().bucket_count == 27); - - REQUIRE(e->threshold() == 16.25); - REQUIRE(e->bucket_count() == 49); - REQUIRE(e->config().threshold == 16.25); - REQUIRE(e->config().bucket_count == 49); - - REQUIRE(b->m_init_call_count == 0); - REQUIRE(c->m_init_call_count == 0); - REQUIRE(e->m_init_call_count == 0); + JApplication app; + app.AddPlugin("log"); + app.Initialize(); + JOmniFactoryGeneratorT facgen(&app); + facgen.AddWiring("BCalTestAlg", {}, {"BCalLeftHits", "BCalRightHits", "BCalVecHits"}, + {{"threshold", "6.1"}, {"bucket_count", "22"}}); + facgen.AddWiring("CCalTestAlg", {}, {"CCalLeftHits", "CCalRightHits", "CCalVecHits"}, + {{"threshold", "9.0"}, {"bucket_count", "27"}}); + facgen.AddWiring("ECalTestAlg", {}, {"ECalLeftHits", "ECalRightHits", "ECalVecHits"}, + {{"threshold", "16.25"}, {"bucket_count", "49"}}); + + JFactorySet facset; + facgen.GenerateFactories(&facset); + // for (auto* fac : facset.GetAllFactories()) { + // std::cout << "typename=" << fac->GetFactoryName() << ", tag=" << fac->GetTag() << std::endl; + // } + auto b = RetrieveMultifactory(&facset, "BCalLeftHits"); + auto c = RetrieveMultifactory(&facset, "CCalLeftHits"); + auto e = RetrieveMultifactory(&facset, "ECalLeftHits"); + + REQUIRE(b->threshold() == 6.1); + REQUIRE(b->bucket_count() == 22); + REQUIRE(b->config().threshold == 6.1); + REQUIRE(b->config().bucket_count == 22); + + REQUIRE(c->threshold() == 9.0); + REQUIRE(c->bucket_count() == 27); + REQUIRE(c->config().threshold == 9.0); + REQUIRE(c->config().bucket_count == 27); + + REQUIRE(e->threshold() == 16.25); + REQUIRE(e->bucket_count() == 49); + REQUIRE(e->config().threshold == 16.25); + REQUIRE(e->config().bucket_count == 49); + + REQUIRE(b->m_init_call_count == 0); + REQUIRE(c->m_init_call_count == 0); + REQUIRE(e->m_init_call_count == 0); } -TEST_CASE("JParameterManager correctly understands which values are defaulted and which are overridden") { - JApplication app; - app.AddPlugin("log"); +TEST_CASE( + "JParameterManager correctly understands which values are defaulted and which are overridden") { + JApplication app; + app.AddPlugin("log"); - auto facgen = new JOmniFactoryGeneratorT(&app); - facgen->AddWiring("FunTest", {}, {"BCalLeftHits", "BCalRightHits", "BCalVecHits"}, {{"threshold", "6.1"}, {"bucket_count", "22"}}); - app.Add(facgen); + auto facgen = new JOmniFactoryGeneratorT(&app); + facgen->AddWiring("FunTest", {}, {"BCalLeftHits", "BCalRightHits", "BCalVecHits"}, + {{"threshold", "6.1"}, {"bucket_count", "22"}}); + app.Add(facgen); - app.GetJParameterManager()->SetParameter("FunTest:threshold", 12.0); - app.Initialize(); + app.GetJParameterManager()->SetParameter("FunTest:threshold", 12.0); + app.Initialize(); - auto event = std::make_shared(); - app.GetService()->configure_event(*event); + auto event = std::make_shared(); + app.GetService()->configure_event(*event); - // for (auto* fac : event->GetFactorySet()->GetAllFactories()) { - // std::cout << "typename=" << fac->GetFactoryName() << ", tag=" << fac->GetTag() << std::endl; - // } + // for (auto* fac : event->GetFactorySet()->GetAllFactories()) { + // std::cout << "typename=" << fac->GetFactoryName() << ", tag=" << fac->GetTag() << std::endl; + // } - // Retrieve multifactory - auto b = RetrieveMultifactory(event->GetFactorySet(), "BCalLeftHits"); + // Retrieve multifactory + auto b = RetrieveMultifactory(event->GetFactorySet(), + "BCalLeftHits"); - // Overrides won't happen until factory gets Init()ed. However, defaults will be applied immediately - REQUIRE(b->threshold() == 6.1); - REQUIRE(b->config().threshold == 6.1); + // Overrides won't happen until factory gets Init()ed. However, defaults will be applied immediately + REQUIRE(b->threshold() == 6.1); + REQUIRE(b->config().threshold == 6.1); - // Trigger JMF::Execute(), in order to trigger Init(), in order to Configure()s all Parameter fields... - auto lefthits = event->Get("BCalLeftHits"); + // Trigger JMF::Execute(), in order to trigger Init(), in order to Configure()s all Parameter fields... + auto lefthits = event->Get("BCalLeftHits"); - REQUIRE(b->threshold() == 12.0); - REQUIRE(b->config().threshold == 12.0); + REQUIRE(b->threshold() == 12.0); + REQUIRE(b->config().threshold == 12.0); - std::cout << "Showing the full table of config parameters" << std::endl; - app.GetJParameterManager()->PrintParameters(2, 1); // verbosity, strictness - - std::cout << "Showing only overridden config parameters" << std::endl; - app.GetJParameterManager()->PrintParameters(1, 1); // verbosity, strictness + std::cout << "Showing the full table of config parameters" << std::endl; + app.GetJParameterManager()->PrintParameters(2, 1); // verbosity, strictness + std::cout << "Showing only overridden config parameters" << std::endl; + app.GetJParameterManager()->PrintParameters(1, 1); // verbosity, strictness } TEST_CASE("Wiring itself is correctly defaulted") { - JApplication app; - app.AddPlugin("log"); - - auto facgen = new JOmniFactoryGeneratorT(&app); - facgen->AddWiring("FunTest", {}, {"BCalLeftHits", "BCalRightHits", "BCalVecHits"}, {{"threshold", "6.1"}}); - app.Add(facgen); - app.Initialize(); + JApplication app; + app.AddPlugin("log"); - auto event = std::make_shared(); - app.GetService()->configure_event(*event); + auto facgen = new JOmniFactoryGeneratorT(&app); + facgen->AddWiring("FunTest", {}, {"BCalLeftHits", "BCalRightHits", "BCalVecHits"}, + {{"threshold", "6.1"}}); + app.Add(facgen); + app.Initialize(); - // Retrieve multifactory - auto b = RetrieveMultifactory(event->GetFactorySet(), "BCalLeftHits"); + auto event = std::make_shared(); + app.GetService()->configure_event(*event); - // Overrides won't happen until factory gets Init()ed. However, defaults will be applied immediately - REQUIRE(b->bucket_count() == 42); // Not provided by wiring - REQUIRE(b->config().bucket_count == 42); // Not provided by wiring + // Retrieve multifactory + auto b = RetrieveMultifactory(event->GetFactorySet(), + "BCalLeftHits"); - REQUIRE(b->threshold() == 6.1); // Provided by wiring - REQUIRE(b->config().threshold == 6.1); // Provided by wiring + // Overrides won't happen until factory gets Init()ed. However, defaults will be applied immediately + REQUIRE(b->bucket_count() == 42); // Not provided by wiring + REQUIRE(b->config().bucket_count == 42); // Not provided by wiring - // Trigger JMF::Execute(), in order to trigger Init(), in order to Configure()s all Parameter fields... - auto lefthits = event->Get("BCalLeftHits"); + REQUIRE(b->threshold() == 6.1); // Provided by wiring + REQUIRE(b->config().threshold == 6.1); // Provided by wiring - // We didn't override the config values via the parameter manager, so all of these should be the same - REQUIRE(b->bucket_count() == 42); // Not provided by wiring - REQUIRE(b->config().bucket_count == 42); // Not provided by wiring + // Trigger JMF::Execute(), in order to trigger Init(), in order to Configure()s all Parameter fields... + auto lefthits = event->Get("BCalLeftHits"); - REQUIRE(b->threshold() == 6.1); // Provided by wiring - REQUIRE(b->config().threshold == 6.1); // Provided by wiring + // We didn't override the config values via the parameter manager, so all of these should be the same + REQUIRE(b->bucket_count() == 42); // Not provided by wiring + REQUIRE(b->config().bucket_count == 42); // Not provided by wiring + REQUIRE(b->threshold() == 6.1); // Provided by wiring + REQUIRE(b->config().threshold == 6.1); // Provided by wiring - b->logger()->info("Showing the full table of config parameters"); - app.GetJParameterManager()->PrintParameters(2,1); // verbosity, strictness + b->logger()->info("Showing the full table of config parameters"); + app.GetJParameterManager()->PrintParameters(2, 1); // verbosity, strictness - b->logger()->info("Showing only overridden config parameters"); - // Should be empty because everything is defaulted - app.GetJParameterManager()->PrintParameters(1,1); // verbosity, strictness + b->logger()->info("Showing only overridden config parameters"); + // Should be empty because everything is defaulted + app.GetJParameterManager()->PrintParameters(1, 1); // verbosity, strictness } struct VariadicTestAlg : public JOmniFactory { - PodioInput m_hits_in {this}; - VariadicPodioInput m_variadic_hits_in {this}; - PodioOutput m_hits_out {this}; - - std::vector GetOutputs() { return this->m_outputs; } - - int m_init_call_count = 0; - int m_changerun_call_count = 0; - int m_process_call_count = 0; - - void Configure() { - m_init_call_count++; - logger()->info("Calling VariadicTestAlg::Configure"); - } - - void ChangeRun(int64_t run_number) { - m_changerun_call_count++; - logger()->info("Calling VariadicTestAlg::ChangeRun"); - } - - // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) - void Process(int64_t run_number, uint64_t event_number) { - m_process_call_count++; - logger()->info("Calling VariadicTestAlg::Process with bucket_count={}, threshold={}", config().bucket_count, config().threshold); - - REQUIRE(m_hits_in()->size() == 3); - REQUIRE(m_variadic_hits_in().size() == 2); - REQUIRE(m_variadic_hits_in()[0]->size() == 1); - REQUIRE(m_variadic_hits_in()[1]->size() == 2); - - m_hits_out() = std::make_unique(); - m_hits_out()->create(); - m_hits_out()->create(); - m_hits_out()->create(); - m_hits_out()->create(); - } + PodioInput m_hits_in{this}; + VariadicPodioInput m_variadic_hits_in{this}; + PodioOutput m_hits_out{this}; + + std::vector GetOutputs() { return this->m_outputs; } + + int m_init_call_count = 0; + int m_changerun_call_count = 0; + int m_process_call_count = 0; + + void Configure() { + m_init_call_count++; + logger()->info("Calling VariadicTestAlg::Configure"); + } + + void ChangeRun(int64_t run_number) { + m_changerun_call_count++; + logger()->info("Calling VariadicTestAlg::ChangeRun"); + } + + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + void Process(int64_t run_number, uint64_t event_number) { + m_process_call_count++; + logger()->info("Calling VariadicTestAlg::Process with bucket_count={}, threshold={}", + config().bucket_count, config().threshold); + + REQUIRE(m_hits_in()->size() == 3); + REQUIRE(m_variadic_hits_in().size() == 2); + REQUIRE(m_variadic_hits_in()[0]->size() == 1); + REQUIRE(m_variadic_hits_in()[1]->size() == 2); + + m_hits_out() = std::make_unique(); + m_hits_out()->create(); + m_hits_out()->create(); + m_hits_out()->create(); + m_hits_out()->create(); + } }; TEST_CASE("VariadicOmniFactoryTests") { - VariadicTestAlg alg; - JApplication app; - app.AddPlugin("log"); + VariadicTestAlg alg; + JApplication app; + app.AddPlugin("log"); - auto facgen = new JOmniFactoryGeneratorT("VariadicTest", {"main_hits","fun_hits","funner_hits"}, {"processed_hits"}, &app); - app.Add(facgen); - app.Initialize(); + auto facgen = new JOmniFactoryGeneratorT( + "VariadicTest", {"main_hits", "fun_hits", "funner_hits"}, {"processed_hits"}, &app); + app.Add(facgen); + app.Initialize(); - auto event = std::make_shared(); - app.GetService()->configure_event(*event); + auto event = std::make_shared(); + app.GetService()->configure_event(*event); - edm4hep::SimCalorimeterHitCollection mains; - edm4hep::SimCalorimeterHitCollection funs; - edm4hep::SimCalorimeterHitCollection funners; + edm4hep::SimCalorimeterHitCollection mains; + edm4hep::SimCalorimeterHitCollection funs; + edm4hep::SimCalorimeterHitCollection funners; - mains.create(); - mains.create(); - mains.create(); + mains.create(); + mains.create(); + mains.create(); - funs.create(); - funners.create(); - funners.create(); + funs.create(); + funners.create(); + funners.create(); - event->InsertCollection(std::move(mains), "main_hits"); - event->InsertCollection(std::move(funs), "fun_hits"); - event->InsertCollection(std::move(funners), "funner_hits"); + event->InsertCollection(std::move(mains), "main_hits"); + event->InsertCollection(std::move(funs), "fun_hits"); + event->InsertCollection(std::move(funners), "funner_hits"); - auto processed = event->GetCollection("processed_hits"); - REQUIRE(processed->size() == 4); + auto processed = event->GetCollection("processed_hits"); + REQUIRE(processed->size() == 4); } struct SubsetTestAlg : public JOmniFactory { - VariadicPodioInput m_left_hits_in {this}; - PodioInput m_center_hits_in {this}; - VariadicPodioInput m_right_hits_in {this}; - PodioOutput m_hits_out {this}; + VariadicPodioInput m_left_hits_in{this}; + PodioInput m_center_hits_in{this}; + VariadicPodioInput m_right_hits_in{this}; + PodioOutput m_hits_out{this}; - std::vector GetOutputs() { return this->m_outputs; } + std::vector GetOutputs() { return this->m_outputs; } - void Configure() {} + void Configure() {} - void ChangeRun(int64_t run_number) {} + void ChangeRun(int64_t run_number) {} - // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) - void Process(int64_t run_number, uint64_t event_number) { + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + void Process(int64_t run_number, uint64_t event_number) { - // Variadic collection count constrained to be same size - REQUIRE(m_left_hits_in().size() == 1); - REQUIRE(m_right_hits_in().size() == 1); + // Variadic collection count constrained to be same size + REQUIRE(m_left_hits_in().size() == 1); + REQUIRE(m_right_hits_in().size() == 1); - REQUIRE(m_left_hits_in()[0]->size() == 2); - REQUIRE(m_right_hits_in()[0]->size() == 1); + REQUIRE(m_left_hits_in()[0]->size() == 2); + REQUIRE(m_right_hits_in()[0]->size() == 1); - REQUIRE(m_center_hits_in()->size() == 3); + REQUIRE(m_center_hits_in()->size() == 3); - m_hits_out() = std::make_unique(); - m_hits_out()->setSubsetCollection(); + m_hits_out() = std::make_unique(); + m_hits_out()->setSubsetCollection(); - auto* lhi = m_left_hits_in()[0]; - for (const auto& hit : *lhi) { - m_hits_out()->push_back(hit); - } - for (const auto& hit : *m_center_hits_in()) { - m_hits_out()->push_back(hit); - } + auto* lhi = m_left_hits_in()[0]; + for (const auto& hit : *lhi) { + m_hits_out()->push_back(hit); + } + for (const auto& hit : *m_center_hits_in()) { + m_hits_out()->push_back(hit); } + } }; - TEST_CASE("SubsetOmniFactoryTests") { - JApplication app; - app.AddPlugin("log"); + JApplication app; + app.AddPlugin("log"); - auto facgen = new JOmniFactoryGeneratorT("SubsetTest", {"left","center","right"}, {"processed_hits"}, &app); - app.Add(facgen); - app.Initialize(); + auto facgen = new JOmniFactoryGeneratorT("SubsetTest", {"left", "center", "right"}, + {"processed_hits"}, &app); + app.Add(facgen); + app.Initialize(); - auto event = std::make_shared(); - app.GetService()->configure_event(*event); + auto event = std::make_shared(); + app.GetService()->configure_event(*event); - edm4hep::SimCalorimeterHitCollection left; - edm4hep::SimCalorimeterHitCollection center; - edm4hep::SimCalorimeterHitCollection right; + edm4hep::SimCalorimeterHitCollection left; + edm4hep::SimCalorimeterHitCollection center; + edm4hep::SimCalorimeterHitCollection right; - left.create(); - left.create(); - right.create(); + left.create(); + left.create(); + right.create(); - center.create(); - center.create(); - center.create(); + center.create(); + center.create(); + center.create(); - event->InsertCollection(std::move(left), "left"); - event->InsertCollection(std::move(center), "center"); - event->InsertCollection(std::move(right), "right"); + event->InsertCollection(std::move(left), "left"); + event->InsertCollection(std::move(center), "center"); + event->InsertCollection(std::move(right), "right"); - auto processed = event->GetCollection("processed_hits"); - REQUIRE(processed->size() == 5); + auto processed = event->GetCollection("processed_hits"); + REQUIRE(processed->size() == 5); } struct VariadicOutputTestAlg : public JOmniFactory { - PodioInput m_hits_in {this}; + PodioInput m_hits_in{this}; - VariadicPodioOutput m_hits_out {this}; + VariadicPodioOutput m_hits_out{this}; - void Configure() {} - void ChangeRun(int64_t run_number) {} + void Configure() {} + void ChangeRun(int64_t run_number) {} - // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) - void Process(int64_t run_number, uint64_t event_number) { + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + void Process(int64_t run_number, uint64_t event_number) { - REQUIRE(m_hits_out().size() == 2); - m_hits_out()[0]->setSubsetCollection(); - m_hits_out()[1]->setSubsetCollection(); + REQUIRE(m_hits_out().size() == 2); + m_hits_out()[0]->setSubsetCollection(); + m_hits_out()[1]->setSubsetCollection(); - int i = 0; - for (const auto& hit : *(m_hits_in())) { - m_hits_out()[i]->push_back(hit); - i = (i == 1) ? 0 : 1; - } + int i = 0; + for (const auto& hit : *(m_hits_in())) { + m_hits_out()[i]->push_back(hit); + i = (i == 1) ? 0 : 1; } + } }; - - TEST_CASE("VariadicPodioOutputTests") { - JApplication app; - app.AddPlugin("log"); + JApplication app; + app.AddPlugin("log"); - auto facgen = new JOmniFactoryGeneratorT("VariadicOutputTest", {"all_hits"}, {"left_hits", "right_hits"}, &app); - app.Add(facgen); - app.Initialize(); + auto facgen = new JOmniFactoryGeneratorT( + "VariadicOutputTest", {"all_hits"}, {"left_hits", "right_hits"}, &app); + app.Add(facgen); + app.Initialize(); - auto event = std::make_shared(); - app.GetService()->configure_event(*event); + auto event = std::make_shared(); + app.GetService()->configure_event(*event); - edm4hep::SimCalorimeterHitCollection all_hits; + edm4hep::SimCalorimeterHitCollection all_hits; - all_hits.create(); - all_hits.create(); - all_hits.create(); + all_hits.create(); + all_hits.create(); + all_hits.create(); - event->InsertCollection(std::move(all_hits), "all_hits"); + event->InsertCollection(std::move(all_hits), "all_hits"); - auto left_hits = event->GetCollection("left_hits"); - auto right_hits = event->GetCollection("right_hits"); - REQUIRE(left_hits->size() == 2); - REQUIRE(right_hits->size() == 1); + auto left_hits = event->GetCollection("left_hits"); + auto right_hits = event->GetCollection("right_hits"); + REQUIRE(left_hits->size() == 2); + REQUIRE(right_hits->size() == 1); } diff --git a/src/tests/track_propagation_test/TrackPropagationTest_processor.cc b/src/tests/track_propagation_test/TrackPropagationTest_processor.cc index d504c570f5..40f61d818b 100644 --- a/src/tests/track_propagation_test/TrackPropagationTest_processor.cc +++ b/src/tests/track_propagation_test/TrackPropagationTest_processor.cc @@ -26,105 +26,94 @@ #include "services/geometry/dd4hep/DD4hep_service.h" #include "services/rootfile/RootFile_service.h" - - - //------------------ // OccupancyAnalysis (Constructor) //------------------ -TrackPropagationTest_processor::TrackPropagationTest_processor(JApplication *app) : - JEventProcessor(app) -{ -} +TrackPropagationTest_processor::TrackPropagationTest_processor(JApplication* app) + : JEventProcessor(app) {} //------------------ // Init //------------------ -void TrackPropagationTest_processor::Init() -{ - std::string plugin_name=("track_propagation_test"); +void TrackPropagationTest_processor::Init() { + std::string plugin_name = ("track_propagation_test"); - // Get JANA application - auto *app = GetApplication(); + // Get JANA application + auto* app = GetApplication(); - // Ask service locator a file to write histograms to - auto root_file_service = app->GetService(); + // Ask service locator a file to write histograms to + auto root_file_service = app->GetService(); - // Get TDirectory for histograms root file - auto globalRootLock = app->GetService(); - globalRootLock->acquire_write_lock(); - auto *file = root_file_service->GetHistFile(); - globalRootLock->release_lock(); + // Get TDirectory for histograms root file + auto globalRootLock = app->GetService(); + globalRootLock->acquire_write_lock(); + auto* file = root_file_service->GetHistFile(); + globalRootLock->release_lock(); - // Create a directory for this plugin. And subdirectories for series of histograms - m_dir_main = file->mkdir(plugin_name.c_str()); + // Create a directory for this plugin. And subdirectories for series of histograms + m_dir_main = file->mkdir(plugin_name.c_str()); - // Get log level from user parameter or default - InitLogger(app, plugin_name); + // Get log level from user parameter or default + InitLogger(app, plugin_name); - auto dd4hep_service = GetApplication()->GetService(); - auto acts_service = GetApplication()->GetService(); + auto dd4hep_service = GetApplication()->GetService(); + auto acts_service = GetApplication()->GetService(); - m_propagation_algo.init(dd4hep_service->detector(), acts_service->actsGeoProvider(), logger()); + m_propagation_algo.init(dd4hep_service->detector(), acts_service->actsGeoProvider(), logger()); - // Create HCal surface that will be used for propagation - auto transform = Acts::Transform3::Identity(); + // Create HCal surface that will be used for propagation + auto transform = Acts::Transform3::Identity(); - // make a reference disk to mimic electron-endcap HCal - const auto hcalEndcapNZ = -3322.; - const auto hcalEndcapNMinR = 83.01; - const auto hcalEndcapNMaxR = 950; - auto hcalEndcapNBounds = std::make_shared(hcalEndcapNMinR, hcalEndcapNMaxR); - auto hcalEndcapNTrf = transform * Acts::Translation3(Acts::Vector3(0, 0, hcalEndcapNZ)); - m_hcal_surface = Acts::Surface::makeShared(hcalEndcapNTrf, hcalEndcapNBounds); + // make a reference disk to mimic electron-endcap HCal + const auto hcalEndcapNZ = -3322.; + const auto hcalEndcapNMinR = 83.01; + const auto hcalEndcapNMaxR = 950; + auto hcalEndcapNBounds = std::make_shared(hcalEndcapNMinR, hcalEndcapNMaxR); + auto hcalEndcapNTrf = transform * Acts::Translation3(Acts::Vector3(0, 0, hcalEndcapNZ)); + m_hcal_surface = Acts::Surface::makeShared(hcalEndcapNTrf, hcalEndcapNBounds); } - //------------------ // Process //------------------ // This function is called every event -void TrackPropagationTest_processor::Process(const std::shared_ptr& event) -{ - m_log->trace("TrackPropagationTest_processor event"); - - // Get trajectories from tracking - auto trajectories = event->Get("CentralCKFActsTrajectories"); - - // Iterate over trajectories - m_log->debug("Propagating through {} trajectories", trajectories.size()); - for (size_t traj_index = 0; traj_index < trajectories.size(); traj_index++) { - auto &trajectory = trajectories[traj_index]; - m_log->trace(" -- trajectory {} --", traj_index); - - std::unique_ptr projection_point; - try { - // >>> try to propagate to surface <<< - projection_point = m_propagation_algo.propagate(edm4eic::Track{}, trajectory, m_hcal_surface); - } - catch(std::exception &e) { - throw JException(e.what()); - } - - if(!projection_point) { - m_log->trace(" could not propagate!", traj_index); - continue; - } - - // Now go through reconstructed tracks points - - auto pos = projection_point->position; - auto length = projection_point->pathlength; - m_log->trace(" {:>10} {:>10.2f} {:>10.2f} {:>10.2f} {:>10.2f}", traj_index, pos.x, pos.y, pos.z, length); +void TrackPropagationTest_processor::Process(const std::shared_ptr& event) { + m_log->trace("TrackPropagationTest_processor event"); + + // Get trajectories from tracking + auto trajectories = event->Get("CentralCKFActsTrajectories"); + + // Iterate over trajectories + m_log->debug("Propagating through {} trajectories", trajectories.size()); + for (size_t traj_index = 0; traj_index < trajectories.size(); traj_index++) { + auto& trajectory = trajectories[traj_index]; + m_log->trace(" -- trajectory {} --", traj_index); + + std::unique_ptr projection_point; + try { + // >>> try to propagate to surface <<< + projection_point = m_propagation_algo.propagate(edm4eic::Track{}, trajectory, m_hcal_surface); + } catch (std::exception& e) { + throw JException(e.what()); } -} + if (!projection_point) { + m_log->trace(" could not propagate!", traj_index); + continue; + } + + // Now go through reconstructed tracks points + + auto pos = projection_point->position; + auto length = projection_point->pathlength; + m_log->trace(" {:>10} {:>10.2f} {:>10.2f} {:>10.2f} {:>10.2f}", traj_index, pos.x, pos.y, + pos.z, length); + } +} //------------------ // Finish //------------------ -void TrackPropagationTest_processor::Finish() -{ -// m_log->trace("TrackPropagationTest_processor finished\n"); - +void TrackPropagationTest_processor::Finish() { + // m_log->trace("TrackPropagationTest_processor finished\n"); } diff --git a/src/tests/track_propagation_test/TrackPropagationTest_processor.h b/src/tests/track_propagation_test/TrackPropagationTest_processor.h index 0a54647352..e589665050 100644 --- a/src/tests/track_propagation_test/TrackPropagationTest_processor.h +++ b/src/tests/track_propagation_test/TrackPropagationTest_processor.h @@ -10,48 +10,47 @@ #include "algorithms/tracking/TrackPropagation.h" #include "extensions/spdlog/SpdlogMixin.h" -class TrackPropagationTest_processor: - public JEventProcessor, - public eicrecon::SpdlogMixin // this automates proper log initialization +class TrackPropagationTest_processor + : public JEventProcessor, + public eicrecon::SpdlogMixin // this automates proper log initialization { public: - explicit TrackPropagationTest_processor(JApplication *); - ~TrackPropagationTest_processor() override = default; - - //---------------------------- - // Init - // - // This is called once before the first call to the Process method - // below. You may, for example, want to open an output file here. - // Only one thread will call this. - void Init() override; - - //---------------------------- - // Process - // - // This is called for every event. Multiple threads may call this - // simultaneously. If you write something to an output file here - // then make sure to protect it with a mutex or similar mechanism. - // Minimize what is done while locked since that directly affects - // the multi-threaded performance. - void Process(const std::shared_ptr& event) override; - - //---------------------------- - // Finish - // - // This is called once after all events have been processed. You may, - // for example, want to close an output file here. - // Only one thread will call this. - void Finish() override; + explicit TrackPropagationTest_processor(JApplication*); + ~TrackPropagationTest_processor() override = default; + + //---------------------------- + // Init + // + // This is called once before the first call to the Process method + // below. You may, for example, want to open an output file here. + // Only one thread will call this. + void Init() override; + + //---------------------------- + // Process + // + // This is called for every event. Multiple threads may call this + // simultaneously. If you write something to an output file here + // then make sure to protect it with a mutex or similar mechanism. + // Minimize what is done while locked since that directly affects + // the multi-threaded performance. + void Process(const std::shared_ptr& event) override; + + //---------------------------- + // Finish + // + // This is called once after all events have been processed. You may, + // for example, want to close an output file here. + // Only one thread will call this. + void Finish() override; private: + /// Directory to store histograms to + TDirectory* m_dir_main{}; - /// Directory to store histograms to - TDirectory *m_dir_main{}; + /// Tracking propagation algorithm + eicrecon::TrackPropagation m_propagation_algo; - /// Tracking propagation algorithm - eicrecon::TrackPropagation m_propagation_algo; - - /// A surface to propagate to - std::shared_ptr m_hcal_surface; + /// A surface to propagate to + std::shared_ptr m_hcal_surface; }; diff --git a/src/tests/track_propagation_test/track_propagation_test.cc b/src/tests/track_propagation_test/track_propagation_test.cc index d43b59a782..a4e3006fb6 100644 --- a/src/tests/track_propagation_test/track_propagation_test.cc +++ b/src/tests/track_propagation_test/track_propagation_test.cc @@ -7,14 +7,13 @@ #include "TrackPropagationTest_processor.h" - extern "C" { - void InitPlugin(JApplication *app) { +void InitPlugin(JApplication* app) { - // Initializes this plugin - InitJANAPlugin(app); + // Initializes this plugin + InitJANAPlugin(app); - // Adds our processor to JANA2 to execute - app->Add(new TrackPropagationTest_processor(app)); - } + // Adds our processor to JANA2 to execute + app->Add(new TrackPropagationTest_processor(app)); +} } diff --git a/src/tests/tracking_test/TrackingTest_processor.cc b/src/tests/tracking_test/TrackingTest_processor.cc index 20b55b6882..faa03aa37f 100644 --- a/src/tests/tracking_test/TrackingTest_processor.cc +++ b/src/tests/tracking_test/TrackingTest_processor.cc @@ -29,138 +29,135 @@ using namespace fmt; //------------------ // OccupancyAnalysis (Constructor) //------------------ -TrackingTest_processor::TrackingTest_processor(JApplication *app) : - JEventProcessor(app) -{ -} +TrackingTest_processor::TrackingTest_processor(JApplication* app) : JEventProcessor(app) {} //------------------ // Init //------------------ -void TrackingTest_processor::Init() -{ - std::string plugin_name=("tracking_test"); - - // Get JANA application - auto *app = GetApplication(); - - // Ask service locator a file to write histograms to - auto root_file_service = app->GetService(); - - // Get TDirectory for histograms root file - auto globalRootLock = app->GetService(); - globalRootLock->acquire_write_lock(); - auto *file = root_file_service->GetHistFile(); - globalRootLock->release_lock(); - - // Create a directory for this plugin. And subdirectories for series of histograms - m_dir_main = file->mkdir(plugin_name.c_str()); - - // Get log level from user parameter or default - m_log = app->GetService()->logger(plugin_name); - for(auto pair: app->GetJParameterManager()->GetAllParameters()) { - m_log->info("{:<20} | {}", pair.first, pair.second->GetDescription()); - } -} +void TrackingTest_processor::Init() { + std::string plugin_name = ("tracking_test"); + + // Get JANA application + auto* app = GetApplication(); + // Ask service locator a file to write histograms to + auto root_file_service = app->GetService(); + + // Get TDirectory for histograms root file + auto globalRootLock = app->GetService(); + globalRootLock->acquire_write_lock(); + auto* file = root_file_service->GetHistFile(); + globalRootLock->release_lock(); + + // Create a directory for this plugin. And subdirectories for series of histograms + m_dir_main = file->mkdir(plugin_name.c_str()); + + // Get log level from user parameter or default + m_log = app->GetService()->logger(plugin_name); + for (auto pair : app->GetJParameterManager()->GetAllParameters()) { + m_log->info("{:<20} | {}", pair.first, pair.second->GetDescription()); + } +} //------------------ // Process //------------------ -void TrackingTest_processor::Process(const std::shared_ptr& event) -{ - m_log->debug("---- TrackingTest_processor {} ----", event->GetEventNumber()); +void TrackingTest_processor::Process(const std::shared_ptr& event) { + m_log->debug("---- TrackingTest_processor {} ----", event->GetEventNumber()); - ProcessTrackingMatching(event); + ProcessTrackingMatching(event); } - //------------------ // Finish //------------------ -void TrackingTest_processor::Finish() -{ - fmt::print("OccupancyAnalysis::Finish() called\n"); - -} - -void TrackingTest_processor::ProcessTrackingResults(const std::shared_ptr &event) { - const auto *reco_particles = event->GetCollection("outputParticles"); - - m_log->debug("Tracking reconstructed particles N={}: ", reco_particles->size()); - m_log->debug(" {:<5} {:>8} {:>8} {:>8} {:>8} {:>8}","[i]", "[px]", "[py]", "[pz]", "[P]", "[P*3]"); - - for(size_t i=0; i < reco_particles->size(); i++) { - auto particle = (*reco_particles)[i]; - - double px = particle.getMomentum().x; - double py = particle.getMomentum().y; - double pz = particle.getMomentum().z; - // ROOT::Math::PxPyPzM4D p4v(px, py, pz, particle.getMass()); - ROOT::Math::Cartesian3D p(px, py, pz); - m_log->debug(" {:<5} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f}", i, px, py, pz, p.R(), p.R()*3); - } - - auto mc_particles = event->Get("MCParticles"); - - m_log->debug("MC particles N={}: ", mc_particles.size()); - m_log->debug(" {:<5} {:<6} {:<7} {:>8} {:>8} {:>8} {:>8}","[i]", "status", "[PDG]", "[px]", "[py]", "[pz]", "[P]"); - for(size_t i=0; i < mc_particles.size(); i++) { - - const auto *particle=mc_particles[i]; - - if(particle->getGeneratorStatus() != 1) continue; -// - double px = particle->getMomentum().x; - double py = particle->getMomentum().y; - double pz = particle->getMomentum().z; - ROOT::Math::PxPyPzM4D p4v(px, py, pz, particle->getMass()); - ROOT::Math::Cartesian3D p(px, py, pz); - if(p.R()<1) continue; - - m_log->debug(" {:<5} {:<6} {:<7} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f}", i, particle->getGeneratorStatus(), particle->getPDG(), px, py, pz, p.R()); - } - +void TrackingTest_processor::Finish() { fmt::print("OccupancyAnalysis::Finish() called\n"); } + +void TrackingTest_processor::ProcessTrackingResults(const std::shared_ptr& event) { + const auto* reco_particles = + event->GetCollection("outputParticles"); + + m_log->debug("Tracking reconstructed particles N={}: ", reco_particles->size()); + m_log->debug(" {:<5} {:>8} {:>8} {:>8} {:>8} {:>8}", "[i]", "[px]", "[py]", "[pz]", "[P]", + "[P*3]"); + + for (size_t i = 0; i < reco_particles->size(); i++) { + auto particle = (*reco_particles)[i]; + + double px = particle.getMomentum().x; + double py = particle.getMomentum().y; + double pz = particle.getMomentum().z; + // ROOT::Math::PxPyPzM4D p4v(px, py, pz, particle.getMass()); + ROOT::Math::Cartesian3D p(px, py, pz); + m_log->debug(" {:<5} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f}", i, px, py, pz, p.R(), + p.R() * 3); + } + + auto mc_particles = event->Get("MCParticles"); + + m_log->debug("MC particles N={}: ", mc_particles.size()); + m_log->debug(" {:<5} {:<6} {:<7} {:>8} {:>8} {:>8} {:>8}", "[i]", "status", "[PDG]", "[px]", + "[py]", "[pz]", "[P]"); + for (size_t i = 0; i < mc_particles.size(); i++) { + + const auto* particle = mc_particles[i]; + + if (particle->getGeneratorStatus() != 1) + continue; + // + double px = particle->getMomentum().x; + double py = particle->getMomentum().y; + double pz = particle->getMomentum().z; + ROOT::Math::PxPyPzM4D p4v(px, py, pz, particle->getMass()); + ROOT::Math::Cartesian3D p(px, py, pz); + if (p.R() < 1) + continue; + + m_log->debug(" {:<5} {:<6} {:<7} {:>8.2f} {:>8.2f} {:>8.2f} {:>8.2f}", i, + particle->getGeneratorStatus(), particle->getPDG(), px, py, pz, p.R()); + } } -void TrackingTest_processor::ProcessTrackingMatching(const std::shared_ptr &event) { - m_log->debug("Associations [simId] [recID] [simE] [recE] [simPDG] [recPDG]"); - - const auto *associations = event->GetCollection("ReconstructedChargedParticleAssociations"); - - for(auto assoc: *associations) { - auto sim = assoc.getSim(); - auto rec = assoc.getRec(); - - m_log->debug(" {:<6} {:<6} {:>8d} {:>8d}", assoc.getSim().getObjectID().index, assoc.getRec().getObjectID().index, sim.getPDG(), rec.getPDG()); - } - -// m_log->debug("Particles [objID] [PDG] [simE] [recE] [simPDG] [recPDG]"); -// auto prt_with_assoc = event->GetSingle("ChargedParticlesWithAssociations"); -// for(auto part: prt_with_assoc->particles()) { -// -// // auto sim = assoc->getSim(); -// // auto rec = assoc->getRec(); -// -// m_log->debug(" {:<6} {:<6} {:>8.2f} {:>8.2f}", part->getObjectID().index, part->getPDG(), part->getCharge(), part->getEnergy()); -// -// } -// -// -// m_log->debug("ReconstructedChargedParticles [objID] [PDG] [charge] [energy]"); -// auto reco_charged_particles = event->Get("ReconstructedChargedParticles"); -// for(auto part: reco_charged_particles) { -// m_log->debug(" {:<6} {:<6} {:>8.2f} {:>8.2f}", part->getObjectID().index, part->getPDG(), part->getCharge(), part->getEnergy()); -// } - +void TrackingTest_processor::ProcessTrackingMatching(const std::shared_ptr& event) { + m_log->debug("Associations [simId] [recID] [simE] [recE] [simPDG] [recPDG]"); + + const auto* associations = event->GetCollection( + "ReconstructedChargedParticleAssociations"); + + for (auto assoc : *associations) { + auto sim = assoc.getSim(); + auto rec = assoc.getRec(); + + m_log->debug(" {:<6} {:<6} {:>8d} {:>8d}", assoc.getSim().getObjectID().index, + assoc.getRec().getObjectID().index, sim.getPDG(), rec.getPDG()); + } + + // m_log->debug("Particles [objID] [PDG] [simE] [recE] [simPDG] [recPDG]"); + // auto prt_with_assoc = event->GetSingle("ChargedParticlesWithAssociations"); + // for(auto part: prt_with_assoc->particles()) { + // + // // auto sim = assoc->getSim(); + // // auto rec = assoc->getRec(); + // + // m_log->debug(" {:<6} {:<6} {:>8.2f} {:>8.2f}", part->getObjectID().index, part->getPDG(), part->getCharge(), part->getEnergy()); + // + // } + // + // + // m_log->debug("ReconstructedChargedParticles [objID] [PDG] [charge] [energy]"); + // auto reco_charged_particles = event->Get("ReconstructedChargedParticles"); + // for(auto part: reco_charged_particles) { + // m_log->debug(" {:<6} {:<6} {:>8.2f} {:>8.2f}", part->getObjectID().index, part->getPDG(), part->getCharge(), part->getEnergy()); + // } } -void TrackingTest_processor::ProcessGloablMatching(const std::shared_ptr &event) { - - m_log->debug("ReconstructedParticles (FINAL) [objID] [PDG] [charge] [energy]"); - auto final_reco_particles = event->Get("ReconstructedParticlesWithAssoc"); - for(const auto *part: final_reco_particles) { - m_log->debug(" {:<6} {:<6} {:>8.2f} {:>8.2f}", part->getObjectID().index, part->getPDG(), part->getCharge(), part->getEnergy()); - } +void TrackingTest_processor::ProcessGloablMatching(const std::shared_ptr& event) { + m_log->debug("ReconstructedParticles (FINAL) [objID] [PDG] [charge] [energy]"); + auto final_reco_particles = + event->Get("ReconstructedParticlesWithAssoc"); + for (const auto* part : final_reco_particles) { + m_log->debug(" {:<6} {:<6} {:>8.2f} {:>8.2f}", part->getObjectID().index, part->getPDG(), + part->getCharge(), part->getEnergy()); + } } diff --git a/src/tests/tracking_test/TrackingTest_processor.h b/src/tests/tracking_test/TrackingTest_processor.h index 6abcf13859..250f152eff 100644 --- a/src/tests/tracking_test/TrackingTest_processor.h +++ b/src/tests/tracking_test/TrackingTest_processor.h @@ -7,49 +7,46 @@ #include #include -class TrackingTest_processor:public JEventProcessor -{ +class TrackingTest_processor : public JEventProcessor { public: - explicit TrackingTest_processor(JApplication *); - ~TrackingTest_processor() override = default; - - //---------------------------- - // Init - // - // This is called once before the first call to the Process method - // below. You may, for example, want to open an output file here. - // Only one thread will call this. - void Init() override; - - //---------------------------- - // Process - // - // This is called for every event. Multiple threads may call this - // simultaneously. If you write something to an output file here - // then make sure to protect it with a mutex or similar mechanism. - // Minimize what is done while locked since that directly affects - // the multi-threaded performance. - void Process(const std::shared_ptr& event) override; - - //---------------------------- - // Finish - // - // This is called once after all events have been processed. You may, - // for example, want to close an output file here. - // Only one thread will call this. - void Finish() override; + explicit TrackingTest_processor(JApplication*); + ~TrackingTest_processor() override = default; + + //---------------------------- + // Init + // + // This is called once before the first call to the Process method + // below. You may, for example, want to open an output file here. + // Only one thread will call this. + void Init() override; + + //---------------------------- + // Process + // + // This is called for every event. Multiple threads may call this + // simultaneously. If you write something to an output file here + // then make sure to protect it with a mutex or similar mechanism. + // Minimize what is done while locked since that directly affects + // the multi-threaded performance. + void Process(const std::shared_ptr& event) override; + + //---------------------------- + // Finish + // + // This is called once after all events have been processed. You may, + // for example, want to close an output file here. + // Only one thread will call this. + void Finish() override; private: + //---------------------------- + // Test imminent tracking output + void ProcessTrackingResults(const std::shared_ptr& event); - //---------------------------- - // Test imminent tracking output - void ProcessTrackingResults(const std::shared_ptr& event); + void ProcessTrackingMatching(const std::shared_ptr& event); - void ProcessTrackingMatching(const std::shared_ptr& event); + void ProcessGloablMatching(const std::shared_ptr& event); - void ProcessGloablMatching(const std::shared_ptr& event); - - - std::shared_ptr m_log; - TDirectory *m_dir_main; + std::shared_ptr m_log; + TDirectory* m_dir_main; }; diff --git a/src/tests/tracking_test/tracking_test.cc b/src/tests/tracking_test/tracking_test.cc index d81de9dfcf..9664cbbc92 100644 --- a/src/tests/tracking_test/tracking_test.cc +++ b/src/tests/tracking_test/tracking_test.cc @@ -10,10 +10,10 @@ //#include "JFactory_RawCalorimeterHit_EcalBarrelRawCalorimeterHits.h.bck" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->Add(new TrackingTest_processor(app)); - //app->Add(new JFactoryGeneratorT()); - //app->Add(new JFactoryGeneratorT()); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new TrackingTest_processor(app)); + //app->Add(new JFactoryGeneratorT()); + //app->Add(new JFactoryGeneratorT()); +} } diff --git a/src/utilities/dump_flags/DumpFlags_processor.cc b/src/utilities/dump_flags/DumpFlags_processor.cc index 0cf6ea7c70..3876e56884 100644 --- a/src/utilities/dump_flags/DumpFlags_processor.cc +++ b/src/utilities/dump_flags/DumpFlags_processor.cc @@ -13,139 +13,124 @@ #include #include - using namespace fmt; //------------------ // DefaultFlags_processor (Constructor) //------------------ -DumpFlags_processor::DumpFlags_processor(JApplication *app) : - JEventProcessor(app) -{ -} +DumpFlags_processor::DumpFlags_processor(JApplication* app) : JEventProcessor(app) {} //------------------ // Init //------------------ -void DumpFlags_processor::Init() -{ - // Ask service locator a file to write to - - auto *app = GetApplication(); - app->SetDefaultParameter("dump_flags:python", m_python_file_name, "If not empty, a python file to generate"); - app->SetDefaultParameter("dump_flags:markdown", m_markdown_file_name, "If not empty, a markdown file to generate"); - app->SetDefaultParameter("dump_flags:json", m_json_file_name, "If not empty, a json file to generate"); - app->SetDefaultParameter("dump_flags:screen", m_print_to_screen, "If not empty, print summary to screen at end of job"); - - - InitLogger(app, "dump_flags", level::info); +void DumpFlags_processor::Init() { + // Ask service locator a file to write to + + auto* app = GetApplication(); + app->SetDefaultParameter("dump_flags:python", m_python_file_name, + "If not empty, a python file to generate"); + app->SetDefaultParameter("dump_flags:markdown", m_markdown_file_name, + "If not empty, a markdown file to generate"); + app->SetDefaultParameter("dump_flags:json", m_json_file_name, + "If not empty, a json file to generate"); + app->SetDefaultParameter("dump_flags:screen", m_print_to_screen, + "If not empty, print summary to screen at end of job"); + + InitLogger(app, "dump_flags", level::info); } - //------------------ // Process //------------------ -void DumpFlags_processor::Process(const std::shared_ptr& event) -{ - -} - +void DumpFlags_processor::Process(const std::shared_ptr& event) {} //------------------ // Finish //------------------ -void DumpFlags_processor::Finish() -{ - auto *pm = GetApplication()->GetJParameterManager(); - - // Find longest strings in names and values - size_t max_name_len = 0; - size_t max_default_val_len = 0; - for(auto [name,param]: pm->GetAllParameters()) { - if(max_name_len < strlen(name.c_str())) { - max_name_len = strlen(name.c_str()); - } - - if(max_default_val_len < strlen(param->GetDefault().c_str())) { - max_default_val_len = strlen(param->GetDefault().c_str()); - } +void DumpFlags_processor::Finish() { + auto* pm = GetApplication()->GetJParameterManager(); + + // Find longest strings in names and values + size_t max_name_len = 0; + size_t max_default_val_len = 0; + for (auto [name, param] : pm->GetAllParameters()) { + if (max_name_len < strlen(name.c_str())) { + max_name_len = strlen(name.c_str()); } - // Found longest values? - spdlog::info("max_name_len={} max_default_val_len={}", max_name_len, max_default_val_len); - - // Start generating - std::string python_content ="# format [ (flag_name, default_val, description), ...]\neicrecon_flags=[\n"; - std::string json_content = "[\n"; - - // iterate over parameters - size_t line_num = 0; - for(auto [name,param]: pm->GetAllParameters()) - { - // form python content string - std::string python_escaped_descr = param->GetDescription(); - std::replace(python_escaped_descr.begin(), python_escaped_descr.end(), '\'', '`'); - python_content += fmt::format(" ({:{}} {:{}} '{}'),\n", - fmt::format("'{}',", param->GetKey()), - max_name_len + 3, - fmt::format("'{}',", param->GetDefault()), - max_default_val_len + 3, - python_escaped_descr - ); - - // form json content string - std::string json_escaped_descr = param->GetDescription(); - std::replace(json_escaped_descr.begin(), json_escaped_descr.end(), '"', '\''); - json_content += fmt::format(" {}[\"{}\", \"{}\", \"{}\", \"{}\"]\n", - line_num++==0?' ': ',', - param->GetKey(), - param->GetValue(), - param->GetDefault(), - json_escaped_descr); - - // Print on screen - if( m_print_to_screen ) fmt::print(" {:{}} : {}\n", param->GetKey(), max_name_len + 3, param->GetValue()); + if (max_default_val_len < strlen(param->GetDefault().c_str())) { + max_default_val_len = strlen(param->GetDefault().c_str()); } - - // Finalizing - python_content+="]\n\n"; - json_content+="]\n\n"; - - // Save python file - if(!m_python_file_name.empty()) { - try{ - std::ofstream ofs(m_python_file_name); - ofs << python_content; - m_log->info("Created python file with flags: '{}'", m_python_file_name); - } - catch(std::exception ex) { - m_log->error("Can't open file '{}' for write", m_python_file_name); // TODO personal logger - throw JException(ex.what()); - } + } + + // Found longest values? + spdlog::info("max_name_len={} max_default_val_len={}", max_name_len, max_default_val_len); + + // Start generating + std::string python_content = + "# format [ (flag_name, default_val, description), ...]\neicrecon_flags=[\n"; + std::string json_content = "[\n"; + + // iterate over parameters + size_t line_num = 0; + for (auto [name, param] : pm->GetAllParameters()) { + // form python content string + std::string python_escaped_descr = param->GetDescription(); + std::replace(python_escaped_descr.begin(), python_escaped_descr.end(), '\'', '`'); + python_content += fmt::format( + " ({:{}} {:{}} '{}'),\n", fmt::format("'{}',", param->GetKey()), max_name_len + 3, + fmt::format("'{}',", param->GetDefault()), max_default_val_len + 3, python_escaped_descr); + + // form json content string + std::string json_escaped_descr = param->GetDescription(); + std::replace(json_escaped_descr.begin(), json_escaped_descr.end(), '"', '\''); + json_content += + fmt::format(" {}[\"{}\", \"{}\", \"{}\", \"{}\"]\n", line_num++ == 0 ? ' ' : ',', + param->GetKey(), param->GetValue(), param->GetDefault(), json_escaped_descr); + + // Print on screen + if (m_print_to_screen) + fmt::print(" {:{}} : {}\n", param->GetKey(), max_name_len + 3, param->GetValue()); + } + + // Finalizing + python_content += "]\n\n"; + json_content += "]\n\n"; + + // Save python file + if (!m_python_file_name.empty()) { + try { + std::ofstream ofs(m_python_file_name); + ofs << python_content; + m_log->info("Created python file with flags: '{}'", m_python_file_name); + } catch (std::exception ex) { + m_log->error("Can't open file '{}' for write", m_python_file_name); // TODO personal logger + throw JException(ex.what()); } - - // Save json file - if(!m_json_file_name.empty()) { - try{ - std::ofstream ofs(m_json_file_name); - ofs << json_content; - m_log->info("Created json file with flags: '{}'", m_json_file_name); - m_log->info("Json records format is: [name, value, default-value, comment]", m_json_file_name); - } - catch(std::exception ex) { - m_log->error("Can't open file '{}' for write", m_json_file_name); // TODO personal logger - throw JException(ex.what()); - } + } + + // Save json file + if (!m_json_file_name.empty()) { + try { + std::ofstream ofs(m_json_file_name); + ofs << json_content; + m_log->info("Created json file with flags: '{}'", m_json_file_name); + m_log->info("Json records format is: [name, value, default-value, comment]", + m_json_file_name); + } catch (std::exception ex) { + m_log->error("Can't open file '{}' for write", m_json_file_name); // TODO personal logger + throw JException(ex.what()); } - - // Save JANA simple key-value file - if(!m_janaconfig_file_name.empty()) { - try{ - pm->WriteConfigFile(m_janaconfig_file_name); - } - catch(std::exception ex) { - m_log->error("Can't open file '{}' for write", m_janaconfig_file_name); // TODO personal logger - throw JException(ex.what()); - } + } + + // Save JANA simple key-value file + if (!m_janaconfig_file_name.empty()) { + try { + pm->WriteConfigFile(m_janaconfig_file_name); + } catch (std::exception ex) { + m_log->error("Can't open file '{}' for write", + m_janaconfig_file_name); // TODO personal logger + throw JException(ex.what()); } + } } diff --git a/src/utilities/dump_flags/DumpFlags_processor.h b/src/utilities/dump_flags/DumpFlags_processor.h index 27fd20500e..29ef89310a 100644 --- a/src/utilities/dump_flags/DumpFlags_processor.h +++ b/src/utilities/dump_flags/DumpFlags_processor.h @@ -11,121 +11,112 @@ #include "extensions/spdlog/SpdlogMixin.h" -class DumpFlags_processor: public JEventProcessor, public eicrecon::SpdlogMixin -{ +class DumpFlags_processor : public JEventProcessor, public eicrecon::SpdlogMixin { public: - explicit DumpFlags_processor(JApplication *); - ~DumpFlags_processor() override = default; - - //---------------------------- - // Init - // - // This is called once before the first call to the Process method - // below. You may, for example, want to open an output file here. - // Only one thread will call this. - void Init() override; - - //---------------------------- - // Process - // - // This is called for every event. Multiple threads may call this - // simultaneously. If you write something to an output file here - // then make sure to protect it with a mutex or similar mechanism. - // Minimize what is done while locked since that directly affects - // the multi-threaded performance. - void Process(const std::shared_ptr& event) override; - - //---------------------------- - // Finish - // - // This is called once after all events have been processed. You may, - // for example, want to close an output file here. - // Only one thread will call this. - void Finish() override; + explicit DumpFlags_processor(JApplication*); + ~DumpFlags_processor() override = default; + + //---------------------------- + // Init + // + // This is called once before the first call to the Process method + // below. You may, for example, want to open an output file here. + // Only one thread will call this. + void Init() override; + + //---------------------------- + // Process + // + // This is called for every event. Multiple threads may call this + // simultaneously. If you write something to an output file here + // then make sure to protect it with a mutex or similar mechanism. + // Minimize what is done while locked since that directly affects + // the multi-threaded performance. + void Process(const std::shared_ptr& event) override; + + //---------------------------- + // Finish + // + // This is called once after all events have been processed. You may, + // for example, want to close an output file here. + // Only one thread will call this. + void Finish() override; private: - /// If not empty, a python eicrecon run file is created - std::string m_python_file_name = ""; - - /// If not null, such markdown file is created - std::string m_markdown_file_name = ""; - - /// If not null, such json file is created - std::string m_json_file_name = ""; - - /// If not null, such jana configuration file is created - std::string m_janaconfig_file_name = "jana.conf"; - - /// Print parameter summary to screen at end of job - bool m_print_to_screen = true; - - /// Print only reconstruction flags - bool m_only_reco = true; - - /// Prefixes of flags that belongs to reconstruction parameters - std::vector m_reco_prefixes = { - "B0TRK", - "BEMC", - "DRICH", - "BTRK", - "BVTX", - "ECTRK", - "EEMC", - "FOFFMTRK", - "HCAL", - "MPGD", - "RPOTS", - "LOWQ2", - "ZDC", - "Tracking", - "Reco", - "Digi", - "Calorimetry" - }; - - /// Checks if flags starts with one of m_reco_prefixes - bool isReconstructionFlag(std::string flag_name) { // (!) copy value is important here! don't do const& NOLINT(performance-unnecessary-value-param) - - // convert flag_name to lower - std::transform(flag_name.begin(), flag_name.end(), flag_name.begin(), static_cast(&std::tolower)); - - for(auto subsystem: m_reco_prefixes) { // (!) copy value is important here! don't do auto& - - // Convert subsystem to lower - std::transform(subsystem.begin(), subsystem.end(), subsystem.begin(), static_cast(&std::tolower)); - - // if not sure, read this - // https://stackoverflow.com/questions/1878001/how-do-i-check-if-a-c-stdstring-starts-with-a-certain-string-and-convert-a - if (flag_name.rfind(subsystem, 0) == 0) { // pos=0 limits the search to the prefix - // s starts with prefix - return true; - } - } - - // flag prefix is not in list - return false; + /// If not empty, a python eicrecon run file is created + std::string m_python_file_name = ""; + + /// If not null, such markdown file is created + std::string m_markdown_file_name = ""; + + /// If not null, such json file is created + std::string m_json_file_name = ""; + + /// If not null, such jana configuration file is created + std::string m_janaconfig_file_name = "jana.conf"; + + /// Print parameter summary to screen at end of job + bool m_print_to_screen = true; + + /// Print only reconstruction flags + bool m_only_reco = true; + + /// Prefixes of flags that belongs to reconstruction parameters + std::vector m_reco_prefixes = { + "B0TRK", "BEMC", "DRICH", "BTRK", "BVTX", "ECTRK", "EEMC", "FOFFMTRK", "HCAL", + "MPGD", "RPOTS", "LOWQ2", "ZDC", "Tracking", "Reco", "Digi", "Calorimetry"}; + + /// Checks if flags starts with one of m_reco_prefixes + bool isReconstructionFlag( + std::string + flag_name) { // (!) copy value is important here! don't do const& NOLINT(performance-unnecessary-value-param) + + // convert flag_name to lower + std::transform(flag_name.begin(), flag_name.end(), flag_name.begin(), + static_cast(&std::tolower)); + + for (auto subsystem : m_reco_prefixes) { // (!) copy value is important here! don't do auto& + + // Convert subsystem to lower + std::transform(subsystem.begin(), subsystem.end(), subsystem.begin(), + static_cast(&std::tolower)); + + // if not sure, read this + // https://stackoverflow.com/questions/1878001/how-do-i-check-if-a-c-stdstring-starts-with-a-certain-string-and-convert-a + if (flag_name.rfind(subsystem, 0) == 0) { // pos=0 limits the search to the prefix + // s starts with prefix + return true; + } } - std::string findCategory(std::string flag_name) { // (!) copy value is important here! don't do const& NOLINT(performance-unnecessary-value-param) + // flag prefix is not in list + return false; + } - // convert flag_name to lower - std::transform(flag_name.begin(), flag_name.end(), flag_name.begin(), static_cast(&std::tolower)); + std::string findCategory( + std::string + flag_name) { // (!) copy value is important here! don't do const& NOLINT(performance-unnecessary-value-param) - for(auto subsystem: m_reco_prefixes) { // (!) copy value is important here! don't do auto& + // convert flag_name to lower + std::transform(flag_name.begin(), flag_name.end(), flag_name.begin(), + static_cast(&std::tolower)); - // Convert subsystem to lower - std::string original_subsystem_name = subsystem; - std::transform(subsystem.begin(), subsystem.end(), subsystem.begin(), static_cast(&std::tolower)); + for (auto subsystem : m_reco_prefixes) { // (!) copy value is important here! don't do auto& - // if not sure, read this - // https://stackoverflow.com/questions/1878001/how-do-i-check-if-a-c-stdstring-starts-with-a-certain-string-and-convert-a - if (flag_name.rfind(subsystem, 0) == 0) { // pos=0 limits the search to the prefix - // s starts with prefix - return original_subsystem_name; - } - } + // Convert subsystem to lower + std::string original_subsystem_name = subsystem; + std::transform(subsystem.begin(), subsystem.end(), subsystem.begin(), + static_cast(&std::tolower)); - // flag prefix is not in list - return ""; + // if not sure, read this + // https://stackoverflow.com/questions/1878001/how-do-i-check-if-a-c-stdstring-starts-with-a-certain-string-and-convert-a + if (flag_name.rfind(subsystem, 0) == 0) { // pos=0 limits the search to the prefix + // s starts with prefix + return original_subsystem_name; + } } + + // flag prefix is not in list + return ""; + } }; diff --git a/src/utilities/dump_flags/dump_flags.cc b/src/utilities/dump_flags/dump_flags.cc index a5fec81ee2..4189b87563 100644 --- a/src/utilities/dump_flags/dump_flags.cc +++ b/src/utilities/dump_flags/dump_flags.cc @@ -7,10 +7,9 @@ #include "DumpFlags_processor.h" - extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->Add(new DumpFlags_processor(app)); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new DumpFlags_processor(app)); +} } diff --git a/src/utilities/eicrecon/eicrecon.cc b/src/utilities/eicrecon/eicrecon.cc index e8c75c6948..e1adf566b2 100644 --- a/src/utilities/eicrecon/eicrecon.cc +++ b/src/utilities/eicrecon/eicrecon.cc @@ -12,60 +12,60 @@ /// The default plugins /// Add new default plugin names here and the main() will do JApplication::AddPlugin() for you. std::vector EICRECON_DEFAULT_PLUGINS = { - - "log", - "dd4hep", - "acts", - "algorithms_init", - "evaluator", - "pid_lut", - "richgeo", - "rootfile", - "beam", - "reco", - "tracking", - "pid", - "EEMC", - "BEMC", - "FEMC", - "EHCAL", - "BHCAL", - "FHCAL", - "B0ECAL", - "ZDC", - "BTRK", - "BVTX", - "PFRICH", - "DIRC", - "DRICH", - "ECTRK", - "MPGD", - "B0TRK", - "RPOTS", - "FOFFMTRK", - "BTOF", - "ECTOF", - "LOWQ2", - "LUMISPECCAL", - "podio", - "janatop", + // clang-format off + "log", + "dd4hep", + "acts", + "algorithms_init", + "evaluator", + "pid_lut", + "richgeo", + "rootfile", + "beam", + "reco", + "tracking", + "pid", + "EEMC", + "BEMC", + "FEMC", + "EHCAL", + "BHCAL", + "FHCAL", + "B0ECAL", + "ZDC", + "BTRK", + "BVTX", + "PFRICH", + "DIRC", + "DRICH", + "ECTRK", + "MPGD", + "B0TRK", + "RPOTS", + "FOFFMTRK", + "BTOF", + "ECTOF", + "LOWQ2", + "LUMISPECCAL", + "podio", + "janatop", + // clang-format on }; -int main( int narg, char **argv) -{ - std::vector default_plugins = EICRECON_DEFAULT_PLUGINS; +int main(int narg, char** argv) { + std::vector default_plugins = EICRECON_DEFAULT_PLUGINS; - auto options = jana::GetCliOptions(narg, argv, false); + auto options = jana::GetCliOptions(narg, argv, false); - if (jana::HasPrintOnlyCliOptions(options, default_plugins)) - return -1; + if (jana::HasPrintOnlyCliOptions(options, default_plugins)) + return -1; - AddAvailablePluginsToOptionParams(options, default_plugins); + AddAvailablePluginsToOptionParams(options, default_plugins); - japp = jana::CreateJApplication(options); + japp = jana::CreateJApplication(options); - auto exit_code = jana::Execute(japp, options); + auto exit_code = jana::Execute(japp, options); - delete japp; - return exit_code; + delete japp; + return exit_code; } diff --git a/src/utilities/eicrecon/eicrecon_cli.cpp b/src/utilities/eicrecon/eicrecon_cli.cpp index eaabf77fb3..971cb4a792 100644 --- a/src/utilities/eicrecon/eicrecon_cli.cpp +++ b/src/utilities/eicrecon/eicrecon_cli.cpp @@ -404,7 +404,8 @@ int Execute(JApplication* app, UserOptions& options) { // TODO: more elegant processing here PrintPodioCollections(app); } else { - if ((JVersion::GetMajorNumber() == 2) && (JVersion::GetMinorNumber() == 3) && (JVersion::GetPatchNumber() <= 1)) { + if ((JVersion::GetMajorNumber() == 2) && (JVersion::GetMinorNumber() == 3) && + (JVersion::GetPatchNumber() <= 1)) { // JANA2 2.3.x has a bug with not filtering default-state parameters, which causes enormous printouts if (not app->GetJParameterManager()->Exists("jana:parameter_verbosity")) { app->GetJParameterManager()->SetParameter("jana:parameter_verbosity", 0); diff --git a/src/utilities/eicrecon/eicrecon_cli.h b/src/utilities/eicrecon/eicrecon_cli.h index 6909c2cd4a..1af8896b13 100644 --- a/src/utilities/eicrecon/eicrecon_cli.h +++ b/src/utilities/eicrecon/eicrecon_cli.h @@ -16,70 +16,72 @@ namespace jana { - enum Flag { - Unknown, - ShowUsage, - ShowVersion, - ShowJANAVersion, - ShowDefaultPlugins, - ShowAvailablePlugins, - ShowConfigs, - LoadConfigs, - DumpConfigs, - Benchmark, - ListFactories - }; - - struct UserOptions { - /// Code representation of all user options. - /// This lets us cleanly separate args parsing from execution. - - std::map flags; - std::map params; - std::vector eventSources; - std::string load_config_file; - std::string dump_config_file; - }; - - /// Read the user options from the command line and initialize @param options. - /// If there are certain flags, mark them as true. - /// Push the event source strings to @param options.eventSources. - /// Push the parameter strings to @param options.params as key-value pairs. - /// If the user option is to load or dump a config file, initialize @param options.load/dump_config_file - UserOptions GetCliOptions(int nargs, char *argv[], bool expect_extra=true); - - /// If the user option contains print only flags, print the info ann return true; otherwise return false. - /// The print only flags include: "-v", "-h", "-L", "--list_default_plugins", "--list_available_plugins". - /// When the info is shown, the application will exit immediately. - bool HasPrintOnlyCliOptions(UserOptions& options, std::vector const& default_plugins); - - void PrintUsage(); - void PrintVersion(); - - /// List the @param default_plugins in a table. - /// @param default_plugins is given at the top of the eicrecon.cc. - void PrintDefaultPlugins(std::vector const& default_plugins); - - /// List all the available plugins at @env_var $JANA_PLUGIN_PATH and @env_var $EICrecon_MY/plugins. - /// @note Does not guarantee the effectiveness of the plugins. - /// @note The plugins can be override if they use the same name under different locations. - void PrintAvailablePlugins(std::vector const& default_plugins); - - /// Add the default plugins and the plugins at $EICrecon_MY/plugins to @param options.params. - /// It comes before creating the @class JApplication. - void AddAvailablePluginsToOptionParams(UserOptions& options, std::vector const& default_plugins); - - void AddDefaultPluginsToJApplication(JApplication* app, std::vector const& default_plugins); - - void PrintFactories(JApplication* app); - void PrintPodioCollections(JApplication* app); - - /// Copy the @param options params (from the cli or the config file) to a JParameterManager @var para_mgr. - /// Create an empty JApplication @var app. - /// Add the event sources got from the cli input to @var app, and then return. - /// @note The cli -Pkey=value pairs are not processed when the function returns. They are processed, - /// or, added to @var app at calling JApplication::Initialize(). - JApplication* CreateJApplication(UserOptions& options); - int Execute(JApplication* app, UserOptions& options); - -} +enum Flag { + Unknown, + ShowUsage, + ShowVersion, + ShowJANAVersion, + ShowDefaultPlugins, + ShowAvailablePlugins, + ShowConfigs, + LoadConfigs, + DumpConfigs, + Benchmark, + ListFactories +}; + +struct UserOptions { + /// Code representation of all user options. + /// This lets us cleanly separate args parsing from execution. + + std::map flags; + std::map params; + std::vector eventSources; + std::string load_config_file; + std::string dump_config_file; +}; + +/// Read the user options from the command line and initialize @param options. +/// If there are certain flags, mark them as true. +/// Push the event source strings to @param options.eventSources. +/// Push the parameter strings to @param options.params as key-value pairs. +/// If the user option is to load or dump a config file, initialize @param options.load/dump_config_file +UserOptions GetCliOptions(int nargs, char* argv[], bool expect_extra = true); + +/// If the user option contains print only flags, print the info ann return true; otherwise return false. +/// The print only flags include: "-v", "-h", "-L", "--list_default_plugins", "--list_available_plugins". +/// When the info is shown, the application will exit immediately. +bool HasPrintOnlyCliOptions(UserOptions& options, std::vector const& default_plugins); + +void PrintUsage(); +void PrintVersion(); + +/// List the @param default_plugins in a table. +/// @param default_plugins is given at the top of the eicrecon.cc. +void PrintDefaultPlugins(std::vector const& default_plugins); + +/// List all the available plugins at @env_var $JANA_PLUGIN_PATH and @env_var $EICrecon_MY/plugins. +/// @note Does not guarantee the effectiveness of the plugins. +/// @note The plugins can be override if they use the same name under different locations. +void PrintAvailablePlugins(std::vector const& default_plugins); + +/// Add the default plugins and the plugins at $EICrecon_MY/plugins to @param options.params. +/// It comes before creating the @class JApplication. +void AddAvailablePluginsToOptionParams(UserOptions& options, + std::vector const& default_plugins); + +void AddDefaultPluginsToJApplication(JApplication* app, + std::vector const& default_plugins); + +void PrintFactories(JApplication* app); +void PrintPodioCollections(JApplication* app); + +/// Copy the @param options params (from the cli or the config file) to a JParameterManager @var para_mgr. +/// Create an empty JApplication @var app. +/// Add the event sources got from the cli input to @var app, and then return. +/// @note The cli -Pkey=value pairs are not processed when the function returns. They are processed, +/// or, added to @var app at calling JApplication::Initialize(). +JApplication* CreateJApplication(UserOptions& options); +int Execute(JApplication* app, UserOptions& options); + +} // namespace jana diff --git a/src/utilities/eicrecon/print_info.h b/src/utilities/eicrecon/print_info.h index 67676988d2..c7b0ff0118 100644 --- a/src/utilities/eicrecon/print_info.h +++ b/src/utilities/eicrecon/print_info.h @@ -9,27 +9,27 @@ #include void printFactoryTable(JComponentSummary const& cs) { - JTablePrinter factory_table; - factory_table.AddColumn("Plugin"); - factory_table.AddColumn("Object name"); - factory_table.AddColumn("Tag"); - for (const auto& factory : cs.factories) { - factory_table | factory.plugin_name | factory.object_name | factory.factory_tag; - } + JTablePrinter factory_table; + factory_table.AddColumn("Plugin"); + factory_table.AddColumn("Object name"); + factory_table.AddColumn("Tag"); + for (const auto& factory : cs.factories) { + factory_table | factory.plugin_name | factory.object_name | factory.factory_tag; + } - std::ostringstream ss; - factory_table.Render(ss); - std::cout << ss.str() << std::endl; + std::ostringstream ss; + factory_table.Render(ss); + std::cout << ss.str() << std::endl; } void printPluginNames(std::vector const& plugin_names) { - JTablePrinter plugin_table; - plugin_table.AddColumn("Plugin name"); - for (const auto& plugin_name : plugin_names) { - plugin_table | plugin_name; - } + JTablePrinter plugin_table; + plugin_table.AddColumn("Plugin name"); + for (const auto& plugin_name : plugin_names) { + plugin_table | plugin_name; + } - std::ostringstream ss; - plugin_table.Render(ss); - std::cout << ss.str() << std::endl; + std::ostringstream ss; + plugin_table.Render(ss); + std::cout << ss.str() << std::endl; } diff --git a/src/utilities/janatop/JEventProcessorJANATOP.h b/src/utilities/janatop/JEventProcessorJANATOP.h index 70311ef301..1b8a274baa 100644 --- a/src/utilities/janatop/JEventProcessorJANATOP.h +++ b/src/utilities/janatop/JEventProcessorJANATOP.h @@ -6,258 +6,253 @@ #include #include -class JEventProcessorJANATOP : public JEventProcessor -{ - private: - enum node_type { - kDefault, - kProcessor, - kFactory, - kCache, - kSource - }; - - class CallLink { - public: - std::string caller_name; - std::string caller_tag; - std::string callee_name; - std::string callee_tag; - - bool operator<(const CallLink &link) const { - if (this->caller_name != link.caller_name) - return this->caller_name < link.caller_name; - if (this->callee_name != link.callee_name) - return this->callee_name < link.callee_name; - if (this->caller_tag != link.caller_tag) - return this->caller_tag < link.caller_tag; - return this->callee_tag < link.callee_tag; - } - }; - - class CallStats { - public: - CallStats(void) { - from_cache_ms = 0; - from_source_ms = 0; - from_factory_ms = 0; - data_not_available_ms = 0; - Nfrom_cache = 0; - Nfrom_source = 0; - Nfrom_factory = 0; - Ndata_not_available = 0; - } - double from_cache_ms; - double from_source_ms; - double from_factory_ms; - double data_not_available_ms; - unsigned int Nfrom_cache; - unsigned int Nfrom_source; - unsigned int Nfrom_factory; - unsigned int Ndata_not_available; - }; +class JEventProcessorJANATOP : public JEventProcessor { +private: + enum node_type { kDefault, kProcessor, kFactory, kCache, kSource }; - class FactoryCallStats{ - public: - FactoryCallStats(void) { - type = kDefault; - time_waited_on = 0.0; - time_waiting = 0.0; - Nfrom_factory = 0; - Nfrom_source = 0; - Nfrom_cache = 0; - } - node_type type; - double time_waited_on; // time other factories spent waiting on this factory - double time_waiting; // time this factory spent waiting on other factories - unsigned int Nfrom_factory; - unsigned int Nfrom_source; - unsigned int Nfrom_cache; - }; + class CallLink { + public: + std::string caller_name; + std::string caller_tag; + std::string callee_name; + std::string callee_tag; + + bool operator<(const CallLink& link) const { + if (this->caller_name != link.caller_name) + return this->caller_name < link.caller_name; + if (this->callee_name != link.callee_name) + return this->callee_name < link.callee_name; + if (this->caller_tag != link.caller_tag) + return this->caller_tag < link.caller_tag; + return this->callee_tag < link.callee_tag; + } + }; + class CallStats { + public: + CallStats(void) { + from_cache_ms = 0; + from_source_ms = 0; + from_factory_ms = 0; + data_not_available_ms = 0; + Nfrom_cache = 0; + Nfrom_source = 0; + Nfrom_factory = 0; + Ndata_not_available = 0; + } + double from_cache_ms; + double from_source_ms; + double from_factory_ms; + double data_not_available_ms; + unsigned int Nfrom_cache; + unsigned int Nfrom_source; + unsigned int Nfrom_factory; + unsigned int Ndata_not_available; + }; + + class FactoryCallStats { public: + FactoryCallStats(void) { + type = kDefault; + time_waited_on = 0.0; + time_waiting = 0.0; + Nfrom_factory = 0; + Nfrom_source = 0; + Nfrom_cache = 0; + } + node_type type; + double time_waited_on; // time other factories spent waiting on this factory + double time_waiting; // time this factory spent waiting on other factories + unsigned int Nfrom_factory; + unsigned int Nfrom_source; + unsigned int Nfrom_cache; + }; + +public: + JEventProcessorJANATOP() : JEventProcessor() { + SetTypeName("JEventProcessorJANATOP"); + auto app = japp; + }; + + void Init() override {}; + + void BeginRun(const std::shared_ptr& event) override {}; + + void Process(const std::shared_ptr& event) override { + // Get the call stack for ths event and add the results to our stats + auto stack = event->GetJCallGraphRecorder()->GetCallGraph(); + + // Lock mutex in case we are running with multiple threads + std::lock_guard lck(mutex); + + // Loop over the call stack elements and add in the values + for (unsigned int i = 0; i < stack.size(); i++) { + + // Keep track of total time each factory spent waiting and being waited on + std::string nametag1 = MakeNametag(stack[i].caller_name, stack[i].caller_tag); + std::string nametag2 = MakeNametag(stack[i].callee_name, stack[i].callee_tag); + + FactoryCallStats& fcallstats1 = factory_stats[nametag1]; + FactoryCallStats& fcallstats2 = factory_stats[nametag2]; + + auto delta_t_ms = std::chrono::duration_cast(stack[i].end_time - + stack[i].start_time) + .count(); + fcallstats1.time_waiting += delta_t_ms; + fcallstats2.time_waited_on += delta_t_ms; + + // Get pointer to CallStats object representing this calling pair + CallLink link; + link.caller_name = stack[i].caller_name; + link.caller_tag = stack[i].caller_tag; + link.callee_name = stack[i].callee_name; + link.callee_tag = stack[i].callee_tag; + CallStats& stats = + call_links[link]; // get pointer to stats object or create if it doesn't exist + + switch (stack[i].data_source) { + case JCallGraphRecorder::DATA_NOT_AVAILABLE: + stats.Ndata_not_available++; + stats.data_not_available_ms += delta_t_ms; + break; + case JCallGraphRecorder::DATA_FROM_CACHE: + fcallstats2.Nfrom_cache++; + stats.Nfrom_cache++; + stats.from_cache_ms += delta_t_ms; + break; + case JCallGraphRecorder::DATA_FROM_SOURCE: + fcallstats2.Nfrom_source++; + stats.Nfrom_source++; + stats.from_source_ms += delta_t_ms; + break; + case JCallGraphRecorder::DATA_FROM_FACTORY: + fcallstats2.Nfrom_factory++; + stats.Nfrom_factory++; + stats.from_factory_ms += delta_t_ms; + break; + } + } + }; + + void EndRun() override {}; + + void Finish() override { + // In order to get the total time we have to first get a list of + // the event processors (i.e. top-level callers). We can tell + // this just by looking for callers that never show up as callees + std::set callers; + std::set callees; + for (auto iter = call_links.begin(); iter != call_links.end(); iter++) { + const CallLink& link = iter->first; + std::string caller = MakeNametag(link.caller_name, link.caller_tag); + std::string callee = MakeNametag(link.callee_name, link.callee_tag); + callers.insert(caller); + callees.insert(callee); + } - JEventProcessorJANATOP(): JEventProcessor() { - SetTypeName("JEventProcessorJANATOP"); - auto app = japp; + // Loop over list a second time so we can get the total ticks for + // the process in order to add the percentage to the label below + double total_ms = 0.0; + for (auto iter = call_links.begin(); iter != call_links.end(); iter++) { + const CallLink& link = iter->first; + const CallStats& stats = iter->second; + std::string caller = MakeNametag(link.caller_name, link.caller_tag); + std::string callee = MakeNametag(link.callee_name, link.callee_tag); + if (callees.find(caller) == callees.end()) { + total_ms += stats.from_factory_ms + stats.from_source_ms + stats.from_cache_ms + + stats.data_not_available_ms; + } + } + if (total_ms == 0.0) + total_ms = 1.0; + + // Loop over call links + std::cout << "Links:" << std::endl; + std::vector> call_links_vector{ + std::make_move_iterator(std::begin(call_links)), + std::make_move_iterator(std::end(call_links))}; + [[maybe_unused]] auto call_links_compare_time = [](const auto& a, const auto& b) { + return ((a.second.from_factory_ms + a.second.from_source_ms + a.second.from_cache_ms) < + (b.second.from_factory_ms + b.second.from_source_ms + b.second.from_cache_ms)); }; - - void Init() override { }; - - void BeginRun(const std::shared_ptr& event) override { }; - - void Process(const std::shared_ptr& event) override { - // Get the call stack for ths event and add the results to our stats - auto stack = event->GetJCallGraphRecorder()->GetCallGraph(); - - // Lock mutex in case we are running with multiple threads - std::lock_guard lck(mutex); - - // Loop over the call stack elements and add in the values - for (unsigned int i = 0; i < stack.size(); i++) { - - // Keep track of total time each factory spent waiting and being waited on - std::string nametag1 = MakeNametag(stack[i].caller_name, stack[i].caller_tag); - std::string nametag2 = MakeNametag(stack[i].callee_name, stack[i].callee_tag); - - FactoryCallStats &fcallstats1 = factory_stats[nametag1]; - FactoryCallStats &fcallstats2 = factory_stats[nametag2]; - - auto delta_t_ms = std::chrono::duration_cast(stack[i].end_time - stack[i].start_time).count(); - fcallstats1.time_waiting += delta_t_ms; - fcallstats2.time_waited_on += delta_t_ms; - - // Get pointer to CallStats object representing this calling pair - CallLink link; - link.caller_name = stack[i].caller_name; - link.caller_tag = stack[i].caller_tag; - link.callee_name = stack[i].callee_name; - link.callee_tag = stack[i].callee_tag; - CallStats &stats = call_links[link]; // get pointer to stats object or create if it doesn't exist - - switch(stack[i].data_source){ - case JCallGraphRecorder::DATA_NOT_AVAILABLE: - stats.Ndata_not_available++; - stats.data_not_available_ms += delta_t_ms; - break; - case JCallGraphRecorder::DATA_FROM_CACHE: - fcallstats2.Nfrom_cache++; - stats.Nfrom_cache++; - stats.from_cache_ms += delta_t_ms; - break; - case JCallGraphRecorder::DATA_FROM_SOURCE: - fcallstats2.Nfrom_source++; - stats.Nfrom_source++; - stats.from_source_ms += delta_t_ms; - break; - case JCallGraphRecorder::DATA_FROM_FACTORY: - fcallstats2.Nfrom_factory++; - stats.Nfrom_factory++; - stats.from_factory_ms += delta_t_ms; - break; - } - } + [[maybe_unused]] auto call_links_compare_N = [](const auto& a, const auto& b) { + return ((a.second.Nfrom_factory + a.second.Nfrom_source + a.second.Nfrom_cache) < + (b.second.Nfrom_factory + b.second.Nfrom_source + b.second.Nfrom_cache)); }; + std::sort(call_links_vector.begin(), call_links_vector.end(), call_links_compare_time); + for (auto iter = call_links_vector.end() - std::min(call_links_vector.size(), 10ul); + iter != call_links_vector.end(); iter++) { + const CallLink& link = iter->first; + const CallStats& stats = iter->second; + + unsigned int Ntotal = stats.Nfrom_cache + stats.Nfrom_source + stats.Nfrom_factory; + + std::string nametag1 = MakeNametag(link.caller_name, link.caller_tag); + std::string nametag2 = MakeNametag(link.callee_name, link.callee_tag); + + double this_ms = stats.from_factory_ms + stats.from_source_ms + stats.from_cache_ms; + std::string timestr = MakeTimeString(stats.from_factory_ms); + double percent = 100.0 * this_ms / total_ms; + char percentstr[32]; + snprintf(percentstr, 32, "%5.1f%%", percent); + + std::cout << Ntotal << " calls, " << timestr << " (" << percentstr << ") "; + std::cout << nametag1 << " -> " << nametag2; + std::cout << std::endl; + } - void EndRun() override { }; - - void Finish() override { - // In order to get the total time we have to first get a list of - // the event processors (i.e. top-level callers). We can tell - // this just by looking for callers that never show up as callees - std::set callers; - std::set callees; - for (auto iter = call_links.begin(); iter != call_links.end(); iter++) { - const CallLink &link = iter->first; - std::string caller = MakeNametag(link.caller_name, link.caller_tag); - std::string callee = MakeNametag(link.callee_name, link.callee_tag); - callers.insert(caller); - callees.insert(callee); - } - - // Loop over list a second time so we can get the total ticks for - // the process in order to add the percentage to the label below - double total_ms = 0.0; - for (auto iter = call_links.begin(); iter != call_links.end(); iter++) { - const CallLink &link = iter->first; - const CallStats &stats = iter->second; - std::string caller = MakeNametag(link.caller_name, link.caller_tag); - std::string callee = MakeNametag(link.callee_name, link.callee_tag); - if (callees.find(caller) == callees.end()){ - total_ms += stats.from_factory_ms + stats.from_source_ms + stats.from_cache_ms + stats.data_not_available_ms; - } - } - if (total_ms == 0.0) total_ms = 1.0; - - // Loop over call links - std::cout << "Links:" << std::endl; - std::vector> call_links_vector{ - std::make_move_iterator(std::begin(call_links)), - std::make_move_iterator(std::end(call_links)) - }; - [[maybe_unused]] auto call_links_compare_time = [](const auto& a, const auto& b) { - return ((a.second.from_factory_ms + a.second.from_source_ms + a.second.from_cache_ms) - < (b.second.from_factory_ms + b.second.from_source_ms + b.second.from_cache_ms)); - }; - [[maybe_unused]] auto call_links_compare_N = [](const auto& a, const auto& b) { - return ((a.second.Nfrom_factory + a.second.Nfrom_source + a.second.Nfrom_cache) - < (b.second.Nfrom_factory + b.second.Nfrom_source + b.second.Nfrom_cache)); - }; - std::sort(call_links_vector.begin(), call_links_vector.end(), call_links_compare_time); - for (auto iter = call_links_vector.end() - std::min(call_links_vector.size(), 10ul); - iter != call_links_vector.end(); iter++) { - const CallLink &link = iter->first; - const CallStats &stats = iter->second; - - unsigned int Ntotal = stats.Nfrom_cache + stats.Nfrom_source + stats.Nfrom_factory; - - std::string nametag1 = MakeNametag(link.caller_name, link.caller_tag); - std::string nametag2 = MakeNametag(link.callee_name, link.callee_tag); - - double this_ms = stats.from_factory_ms + stats.from_source_ms + stats.from_cache_ms; - std::string timestr = MakeTimeString(stats.from_factory_ms); - double percent = 100.0 * this_ms / total_ms; - char percentstr[32]; - snprintf(percentstr, 32, "%5.1f%%", percent); - - std::cout << Ntotal << " calls, " << timestr << " (" << percentstr << ") "; - std::cout << nametag1 << " -> " << nametag2; - std::cout << std::endl; - } - - // Loop over factories - std::cout << "Factories:" << std::endl; - std::vector> factory_stats_vector{ - std::make_move_iterator(std::begin(factory_stats)), - std::make_move_iterator(std::end(factory_stats)) - }; - auto factory_stats_compare = [](const auto& a, const auto& b) { - return ((a.second.time_waited_on - a.second.time_waiting) - < (b.second.time_waited_on - b.second.time_waiting)); - }; - std::sort(factory_stats_vector.begin(), factory_stats_vector.end(), factory_stats_compare); - for (auto iter = factory_stats_vector.end() - std::min(factory_stats_vector.size(), 10ul); - iter != factory_stats_vector.end(); iter++) { - FactoryCallStats &fcall_stats = iter->second; - std::string nodename = iter->first; - - // Get time spent in this factory proper - double time_spent_in_factory = fcall_stats.time_waited_on - fcall_stats.time_waiting; - std::string timestr = MakeTimeString(time_spent_in_factory); - double percent = 100.0 * time_spent_in_factory / total_ms; - char percentstr[32]; - snprintf(percentstr, 32, "%5.1f%%", percent); - - std::cout << timestr << " (" << percentstr << ") "; - std::cout << nodename; - std::cout << std::endl; - } + // Loop over factories + std::cout << "Factories:" << std::endl; + std::vector> factory_stats_vector{ + std::make_move_iterator(std::begin(factory_stats)), + std::make_move_iterator(std::end(factory_stats))}; + auto factory_stats_compare = [](const auto& a, const auto& b) { + return ((a.second.time_waited_on - a.second.time_waiting) < + (b.second.time_waited_on - b.second.time_waiting)); }; - - private: - - std::mutex mutex; - - std::map call_links; - std::map factory_stats; - - std::string MakeTimeString(double time_in_ms) { - double order = log10(time_in_ms); - std::stringstream ss; - ss << std::fixed << std::setprecision(2); - if (order < 0) { - ss << time_in_ms*1000.0 << " us"; - } else if (order <= 2.0) { - ss << time_in_ms << " ms"; - } else { - ss << time_in_ms / 1000.0 << " s"; - } - return ss.str(); + std::sort(factory_stats_vector.begin(), factory_stats_vector.end(), factory_stats_compare); + for (auto iter = factory_stats_vector.end() - std::min(factory_stats_vector.size(), 10ul); + iter != factory_stats_vector.end(); iter++) { + FactoryCallStats& fcall_stats = iter->second; + std::string nodename = iter->first; + + // Get time spent in this factory proper + double time_spent_in_factory = fcall_stats.time_waited_on - fcall_stats.time_waiting; + std::string timestr = MakeTimeString(time_spent_in_factory); + double percent = 100.0 * time_spent_in_factory / total_ms; + char percentstr[32]; + snprintf(percentstr, 32, "%5.1f%%", percent); + + std::cout << timestr << " (" << percentstr << ") "; + std::cout << nodename; + std::cout << std::endl; } - - std::string MakeNametag(const std::string &name, const std::string &tag) { - std::string nametag = name; - if (tag.size() > 0) nametag += ":" + tag; - return nametag; + }; + +private: + std::mutex mutex; + + std::map call_links; + std::map factory_stats; + + std::string MakeTimeString(double time_in_ms) { + double order = log10(time_in_ms); + std::stringstream ss; + ss << std::fixed << std::setprecision(2); + if (order < 0) { + ss << time_in_ms * 1000.0 << " us"; + } else if (order <= 2.0) { + ss << time_in_ms << " ms"; + } else { + ss << time_in_ms / 1000.0 << " s"; } + return ss.str(); + } + + std::string MakeNametag(const std::string& name, const std::string& tag) { + std::string nametag = name; + if (tag.size() > 0) + nametag += ":" + tag; + return nametag; + } }; diff --git a/src/utilities/janatop/janatop.cc b/src/utilities/janatop/janatop.cc index c2d07ed9be..191af39310 100644 --- a/src/utilities/janatop/janatop.cc +++ b/src/utilities/janatop/janatop.cc @@ -10,9 +10,9 @@ #include "JEventProcessorJANATOP.h" extern "C" { - void InitPlugin(JApplication *app) { - InitJANAPlugin(app); - app->Add(new JEventProcessorJANATOP()); - app->GetJParameterManager()->SetParameter("RECORD_CALL_STACK", true); - } +void InitPlugin(JApplication* app) { + InitJANAPlugin(app); + app->Add(new JEventProcessorJANATOP()); + app->GetJParameterManager()->SetParameter("RECORD_CALL_STACK", true); +} }