diff --git a/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTracksterLinks_cfi.py b/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTracksterLinks_cfi.py
index 568d8e70d88ce..396c3d3c8f11f 100644
--- a/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTracksterLinks_cfi.py
+++ b/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTracksterLinks_cfi.py
@@ -2,14 +2,9 @@
hltTiclTracksterLinks = cms.EDProducer("TracksterLinksProducer",
detector = cms.string('HGCAL'),
- eid_input_name = cms.string('input'),
- eid_min_cluster_energy = cms.double(2.5),
- eid_n_clusters = cms.int32(10),
- eid_n_layers = cms.int32(50),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
layer_clusters = cms.InputTag("hltHgcalMergeLayerClusters"),
layer_clustersTime = cms.InputTag("hltHgcalMergeLayerClusters","timeLayerCluster"),
+ inferenceAlgo = cms.string('TracksterInferenceByDNN'),
linkingPSet = cms.PSet(
algo_verbosity = cms.int32(0),
cylinder_radius_sqr = cms.vdouble(9, 9),
@@ -25,10 +20,25 @@
type = cms.string('Skeletons'),
wind = cms.double(0.036)
),
+ pluginInferenceAlgoTracksterInferenceByDNN = cms.PSet(
+ algo_verbosity = cms.int32(0),
+ onnxPIDModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv5/onnx_models/linking/id_v0.onnx'),
+ onnxEnergyModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv5/onnx_models/linking/energy_v0.onnx'),
+ inputNames = cms.vstring('input'),
+ output_en = cms.vstring('enreg_output'),
+ output_id = cms.vstring('pid_output'),
+ eid_min_cluster_energy = cms.double(1),
+ eid_n_layers = cms.int32(50),
+ eid_n_clusters = cms.int32(10),
+ doPID = cms.int32(1),
+ doRegression = cms.int32(1),
+ type = cms.string('TracksterInferenceByDNN')
+ ),
mightGet = cms.optional.untracked.vstring,
original_masks = cms.VInputTag("hltHgcalMergeLayerClusters:InitialLayerClustersMask"),
propagator = cms.string('PropagatorWithMaterial'),
regressionAndPid = cms.bool(True),
- tfDnnLabel = cms.string('tracksterSelectionTf'),
tracksters_collections = cms.VInputTag("hltTiclTrackstersCLUE3DHigh", "hltTiclTrackstersPassthrough")
)
+
+
diff --git a/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersCLUE3DHighL1Seeded_cfi.py b/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersCLUE3DHighL1Seeded_cfi.py
index 673f0d83e7d1d..4a5bd170978a7 100644
--- a/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersCLUE3DHighL1Seeded_cfi.py
+++ b/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersCLUE3DHighL1Seeded_cfi.py
@@ -10,14 +10,9 @@
mightGet = cms.optional.untracked.vstring,
original_mask = cms.InputTag("hltHgcalMergeLayerClustersL1Seeded","InitialLayerClustersMask"),
patternRecognitionBy = cms.string('CLUE3D'),
+ inferenceAlgo = cms.string('TracksterInferenceByCNNv4'),
pluginPatternRecognitionByCA = cms.PSet(
algo_verbosity = cms.int32(0),
- eid_input_name = cms.string('input'),
- eid_min_cluster_energy = cms.double(1),
- eid_n_clusters = cms.int32(10),
- eid_n_layers = cms.int32(50),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
energy_em_over_total_threshold = cms.double(-1),
etaLimitIncreaseWindow = cms.double(2.1),
filter_on_categories = cms.vint32(0),
@@ -100,34 +95,51 @@
2,
2
),
- eid_input_name = cms.string('input'),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
- eid_min_cluster_energy = cms.double(1),
- eid_n_layers = cms.int32(50),
- eid_n_clusters = cms.int32(10),
computeLocalTime = cms.bool(False),
doPidCut = cms.bool(True),
cutHadProb = cms.double(999.),
type = cms.string('CLUE3D')
-
),
pluginPatternRecognitionByFastJet = cms.PSet(
algo_verbosity = cms.int32(0),
antikt_radius = cms.double(0.09),
- eid_input_name = cms.string('input'),
+ minNumLayerCluster = cms.int32(5),
+ type = cms.string('FastJet')
+ ),
+ pluginInferenceAlgoTracksterInferenceByCNNv4 = cms.PSet(
+ algo_verbosity = cms.int32(0),
+ onnxModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv4/onnx_models/energy_id_v0.onnx'),
+ inputNames = cms.vstring('input:0'),
+ outputNames = cms.vstring("output/regressed_energy:0", "output/id_probabilities:0"),
eid_min_cluster_energy = cms.double(1),
+ eid_n_layers = cms.int32(50),
eid_n_clusters = cms.int32(10),
+ doPID = cms.int32(1),
+ doRegression = cms.int32(0),
+ type = cms.string('TracksterInferenceByCNNv4')
+ ),
+ pluginInferenceAlgoTracksterInferenceByDNN = cms.PSet(
+ algo_verbosity = cms.int32(0),
+ onnxPIDModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv5/onnx_models/patternrecognition/id_v0.onnx'),
+ onnxEnergyModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv5/onnx_models/patternrecognition/energy_v0.onnx'),
+ inputNames = cms.vstring('input'),
+ output_en = cms.vstring('enreg_output'),
+ output_id = cms.vstring('pid_output'),
eid_n_layers = cms.int32(50),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
- minNumLayerCluster = cms.int32(5),
- type = cms.string('FastJet')
+ eid_n_clusters = cms.int32(10),
+ doPID = cms.int32(1),
+ doRegression = cms.int32(0),
+ type = cms.string('TracksterInferenceByDNN')
+ ),
+ pluginInferenceAlgoTracksterInferenceByANN = cms.PSet(
+ algo_verbosity = cms.int32(0),
+ type = cms.string('TracksterInferenceByANN')
+
),
seeding_regions = cms.InputTag("hltTiclSeedingL1"),
- tfDnnLabel = cms.string('tracksterSelectionTf'),
- time_layerclusters = cms.InputTag("hltHgcalMergeLayerClustersL1Seeded","timeLayerCluster")
+ time_layerclusters = cms.InputTag("hltHgcalMergeLayerClustersL1Seeded","timeLayerCluster"),
)
from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5
ticl_v5.toModify(hltTiclTrackstersCLUE3DHighL1Seeded.pluginPatternRecognitionByCLUE3D, computeLocalTime = cms.bool(True), doPidCut = cms.bool(False))
+ticl_v5.toModify(hltTiclTrackstersCLUE3DHighL1Seeded.inferenceAlgo, type = cms.string('TracksterInferenceByDNN'))
diff --git a/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersCLUE3DHigh_cfi.py b/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersCLUE3DHigh_cfi.py
index 57436cfbfbd87..88b4cd7b7ab84 100644
--- a/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersCLUE3DHigh_cfi.py
+++ b/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersCLUE3DHigh_cfi.py
@@ -10,14 +10,9 @@
mightGet = cms.optional.untracked.vstring,
original_mask = cms.InputTag("hltHgcalMergeLayerClusters","InitialLayerClustersMask"),
patternRecognitionBy = cms.string('CLUE3D'),
+ inferenceAlgo = cms.string('TracksterInferenceByCNNv4'),
pluginPatternRecognitionByCA = cms.PSet(
algo_verbosity = cms.int32(0),
- eid_input_name = cms.string('input'),
- eid_min_cluster_energy = cms.double(1),
- eid_n_clusters = cms.int32(10),
- eid_n_layers = cms.int32(50),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
energy_em_over_total_threshold = cms.double(-1),
etaLimitIncreaseWindow = cms.double(2.1),
filter_on_categories = cms.vint32(0),
@@ -100,12 +95,6 @@
2,
2
),
- eid_input_name = cms.string('input'),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
- eid_min_cluster_energy = cms.double(1),
- eid_n_layers = cms.int32(50),
- eid_n_clusters = cms.int32(10),
computeLocalTime = cms.bool(False),
doPidCut = cms.bool(True),
cutHadProb = cms.double(999.),
@@ -115,19 +104,43 @@
pluginPatternRecognitionByFastJet = cms.PSet(
algo_verbosity = cms.int32(0),
antikt_radius = cms.double(0.09),
- eid_input_name = cms.string('input'),
+ minNumLayerCluster = cms.int32(5),
+ type = cms.string('FastJet')
+ ),
+ pluginInferenceAlgoTracksterInferenceByCNNv4 = cms.PSet(
+ algo_verbosity = cms.int32(0),
+ onnxModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv4/onnx_models/energy_id_v0.onnx'),
+ inputNames = cms.vstring('input:0'),
+ outputNames = cms.vstring("output/regressed_energy:0", "output/id_probabilities:0"),
eid_min_cluster_energy = cms.double(1),
+ eid_n_layers = cms.int32(50),
eid_n_clusters = cms.int32(10),
+ doPID = cms.int32(1),
+ doRegression = cms.int32(0),
+ type = cms.string('TracksterInferenceByCNNv4')
+ ),
+ pluginInferenceAlgoTracksterInferenceByDNN = cms.PSet(
+ algo_verbosity = cms.int32(0),
+ onnxPIDModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv5/onnx_models/patternrecognition/id_v0.onnx'),
+ onnxEnergyModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv5/onnx_models/patternrecognition/energy_v0.onnx'),
+ inputNames = cms.vstring('input'),
+ output_en = cms.vstring('enreg_output'),
+ output_id = cms.vstring('pid_output'),
eid_n_layers = cms.int32(50),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
- minNumLayerCluster = cms.int32(5),
- type = cms.string('FastJet')
+ eid_n_clusters = cms.int32(10),
+ doPID = cms.int32(1),
+ doRegression = cms.int32(0),
+ type = cms.string('TracksterInferenceByDNN')
+ ),
+ pluginInferenceAlgoTracksterInferenceByANN = cms.PSet(
+ algo_verbosity = cms.int32(0),
+ type = cms.string('TracksterInferenceByANN')
+
),
seeding_regions = cms.InputTag("hltTiclSeedingGlobal"),
- tfDnnLabel = cms.string('tracksterSelectionTf'),
time_layerclusters = cms.InputTag("hltHgcalMergeLayerClusters","timeLayerCluster")
-)
-
+ )
+
from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5
ticl_v5.toModify(hltTiclTrackstersCLUE3DHigh.pluginPatternRecognitionByCLUE3D, computeLocalTime = cms.bool(True), doPidCut = cms.bool(False))
+ticl_v5.toModify(hltTiclTrackstersCLUE3DHigh.inferenceAlgo, type = cms.string('TracksterInferenceByDNN'))
diff --git a/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersPassthrough_cfi.py b/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersPassthrough_cfi.py
index 4fedc0e0b1d41..aa34abef3f2f4 100644
--- a/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersPassthrough_cfi.py
+++ b/HLTrigger/Configuration/python/HLT_75e33/modules/hltTiclTrackstersPassthrough_cfi.py
@@ -10,15 +10,10 @@
mightGet = cms.optional.untracked.vstring,
original_mask = cms.InputTag("hltTiclTrackstersCLUE3DHigh"),
patternRecognitionBy = cms.string('Passthrough'),
+ inferenceAlgo = cms.string('TracksterInferenceByDNN'),
pluginPatternRecognitionByCA = cms.PSet(
algo_verbosity = cms.int32(0),
computeLocalTime = cms.bool(True),
- eid_input_name = cms.string('input'),
- eid_min_cluster_energy = cms.double(1),
- eid_n_clusters = cms.int32(10),
- eid_n_layers = cms.int32(50),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
energy_em_over_total_threshold = cms.double(-1),
etaLimitIncreaseWindow = cms.double(2.1),
filter_on_categories = cms.vint32(0),
@@ -53,12 +48,6 @@
densitySiblingLayers = cms.vint32(3, 3, 3),
densityXYDistanceSqr = cms.vdouble(3.24, 3.24, 3.24),
doPidCut = cms.bool(False),
- eid_input_name = cms.string('input'),
- eid_min_cluster_energy = cms.double(1),
- eid_n_clusters = cms.int32(10),
- eid_n_layers = cms.int32(50),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
kernelDensityFactor = cms.vdouble(0.2, 0.2, 0.2),
minNumLayerCluster = cms.vint32(2, 2, 2),
nearestHigherOnSameLayer = cms.bool(False),
@@ -72,12 +61,6 @@
algo_verbosity = cms.int32(0),
antikt_radius = cms.double(0.09),
computeLocalTime = cms.bool(True),
- eid_input_name = cms.string('input'),
- eid_min_cluster_energy = cms.double(1),
- eid_n_clusters = cms.int32(10),
- eid_n_layers = cms.int32(50),
- eid_output_name_energy = cms.string('output/regressed_energy'),
- eid_output_name_id = cms.string('output/id_probabilities'),
minNumLayerCluster = cms.int32(5),
type = cms.string('FastJet')
),
@@ -85,7 +68,26 @@
algo_verbosity = cms.int32(0),
type = cms.string('Passthrough')
),
+
+ pluginInferenceAlgoTracksterInferenceByDNN = cms.PSet(
+ algo_verbosity = cms.int32(0),
+ onnxPIDModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv5/onnx_models/patternrecognition/id_v0.onnx'),
+ onnxEnergyModelPath = cms.FileInPath('RecoHGCal/TICL/data/ticlv5/onnx_models/patternrecognition/energy_v0.onnx'),
+ inputNames = cms.vstring('input'),
+ output_en = cms.vstring('enreg_output'),
+ output_id = cms.vstring('pid_output'),
+ eid_min_cluster_energy = cms.double(1),
+ eid_n_layers = cms.int32(50),
+ eid_n_clusters = cms.int32(10),
+ doPID = cms.int32(0),
+ doRegression = cms.int32(0),
+ type = cms.string('TracksterInferenceByDNN')
+ ),
+ pluginInferenceAlgoTracksterInferenceByANN = cms.PSet(
+ algo_verbosity = cms.int32(0),
+ type = cms.string('TracksterInferenceByANN')
+
+ ),
seeding_regions = cms.InputTag("hltTiclSeedingGlobal"),
- tfDnnLabel = cms.string('tracksterSelectionTf'),
time_layerclusters = cms.InputTag("hltHgcalMergeLayerClusters","timeLayerCluster")
)
diff --git a/RecoHGCal/TICL/BuildFile.xml b/RecoHGCal/TICL/BuildFile.xml
index fc31796e1bd74..75a12c12c5e41 100644
--- a/RecoHGCal/TICL/BuildFile.xml
+++ b/RecoHGCal/TICL/BuildFile.xml
@@ -4,6 +4,7 @@
+
diff --git a/RecoHGCal/TICL/interface/PatternRecognitionAlgoBase.h b/RecoHGCal/TICL/interface/PatternRecognitionAlgoBase.h
index 2658443104721..fd337ed71df29 100644
--- a/RecoHGCal/TICL/interface/PatternRecognitionAlgoBase.h
+++ b/RecoHGCal/TICL/interface/PatternRecognitionAlgoBase.h
@@ -6,6 +6,8 @@
#include
#include
+#include
+#include
#include "DataFormats/CaloRecHit/interface/CaloCluster.h"
#include "DataFormats/HGCalReco/interface/Trackster.h"
#include "DataFormats/HGCalReco/interface/TICLLayerTile.h"
@@ -28,7 +30,7 @@ namespace ticl {
public:
PatternRecognitionAlgoBaseT(const edm::ParameterSet& conf, edm::ConsumesCollector)
: algo_verbosity_(conf.getParameter("algo_verbosity")) {}
- virtual ~PatternRecognitionAlgoBaseT(){};
+ virtual ~PatternRecognitionAlgoBaseT() {};
struct Inputs {
const edm::Event& ev;
@@ -38,23 +40,25 @@ namespace ticl {
const edm::ValueMap>& layerClustersTime;
const TILES& tiles;
const std::vector& regions;
- const tensorflow::Session* tfSession;
-
Inputs(const edm::Event& eV,
const edm::EventSetup& eS,
const std::vector& lC,
const std::vector& mS,
const edm::ValueMap>& lT,
const TILES& tL,
- const std::vector& rG,
- const tensorflow::Session* tS)
- : ev(eV), es(eS), layerClusters(lC), mask(mS), layerClustersTime(lT), tiles(tL), regions(rG), tfSession(tS) {}
+ const std::vector& rG)
+ : ev(eV), es(eS), layerClusters(lC), mask(mS), layerClustersTime(lT), tiles(tL), regions(rG) {}
};
virtual void makeTracksters(const Inputs& input,
std::vector& result,
std::unordered_map>& seedToTracksterAssociation) = 0;
+ virtual void filter(std::vector& output,
+ const std::vector& inTracksters,
+ const Inputs& input,
+ std::unordered_map>& seedToTracksterAssociation) = 0;
+
protected:
int algo_verbosity_;
};
diff --git a/RecoHGCal/TICL/interface/TracksterInferenceAlgoBase.h b/RecoHGCal/TICL/interface/TracksterInferenceAlgoBase.h
new file mode 100644
index 0000000000000..f4ec06b87f11b
--- /dev/null
+++ b/RecoHGCal/TICL/interface/TracksterInferenceAlgoBase.h
@@ -0,0 +1,38 @@
+// Author: Felice Pantaleo - felice.pantaleo@cern.ch
+// Date: 07/2024
+
+#ifndef RecoHGCal_TICL_TracksterInferenceAlgo_H__
+#define RecoHGCal_TICL_TracksterInferenceAlgo_H__
+
+#include
+#include "DataFormats/HGCalReco/interface/Trackster.h"
+#include "FWCore/ParameterSet/interface/ParameterSet.h"
+#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
+#include "FWCore/Framework/interface/Event.h"
+#include "FWCore/Framework/interface/EventSetup.h"
+
+#include "DataFormats/Candidate/interface/Candidate.h"
+#include "DataFormats/VertexReco/interface/Vertex.h"
+#include "DataFormats/CaloRecHit/interface/CaloCluster.h"
+#include "DataFormats/HGCalReco/interface/TICLCandidate.h"
+#include "FWCore/Framework/interface/ConsumesCollector.h"
+#include "PhysicsTools/ONNXRuntime/interface/ONNXRuntime.h"
+#include "FWCore/PluginManager/interface/PluginFactory.h"
+
+namespace ticl {
+ class TracksterInferenceAlgoBase {
+ public:
+ explicit TracksterInferenceAlgoBase(const edm::ParameterSet& conf)
+ : algo_verbosity_(conf.getParameter("algo_verbosity")) {}
+ virtual ~TracksterInferenceAlgoBase() {}
+
+ virtual void inputData(const std::vector& layerClusters, std::vector& tracksters) = 0;
+ virtual void runInference(std::vector& tracksters) = 0;
+ static void fillPSetDescription(edm::ParameterSetDescription& desc) { desc.add("algo_verbosity", 0); };
+
+ protected:
+ int algo_verbosity_;
+ };
+} // namespace ticl
+
+#endif
diff --git a/RecoHGCal/TICL/interface/TracksterInferenceAlgoFactory.h b/RecoHGCal/TICL/interface/TracksterInferenceAlgoFactory.h
new file mode 100644
index 0000000000000..9ad204ce647b3
--- /dev/null
+++ b/RecoHGCal/TICL/interface/TracksterInferenceAlgoFactory.h
@@ -0,0 +1,15 @@
+// Author: Felice Pantaleo - felice.pantaleo@cern.ch
+// Date: 07/2024
+
+#ifndef RecoHGCal_TICL_TracksterInferenceAlgoFactory_H__
+#define RecoHGCal_TICL_TracksterInferenceAlgoFactory_H__
+
+#include "FWCore/PluginManager/interface/PluginFactory.h"
+#include "FWCore/ParameterSet/interface/ParameterSet.h"
+#include "PhysicsTools/ONNXRuntime/interface/ONNXRuntime.h"
+#include "RecoHGCal/TICL/interface/TracksterInferenceAlgoBase.h"
+
+typedef edmplugin::PluginFactory
+ TracksterInferenceAlgoFactory;
+
+#endif
diff --git a/RecoHGCal/TICL/interface/TracksterInferenceByANN.h b/RecoHGCal/TICL/interface/TracksterInferenceByANN.h
new file mode 100644
index 0000000000000..e323d5f3d35c5
--- /dev/null
+++ b/RecoHGCal/TICL/interface/TracksterInferenceByANN.h
@@ -0,0 +1,19 @@
+#ifndef RecoHGCal_TICL_TracksterInferenceByANN_H__
+#define RecoHGCal_TICL_TracksterInferenceByANN_H__
+
+#include "RecoHGCal/TICL/interface/TracksterInferenceAlgoBase.h"
+
+namespace ticl {
+ class TracksterInferenceByANN : public TracksterInferenceAlgoBase {
+ public:
+ explicit TracksterInferenceByANN(const edm::ParameterSet& conf);
+ void inputData(const std::vector& layerClusters, std::vector& tracksters) override;
+ void runInference(std::vector& tracksters) override;
+
+ private:
+ const cms::Ort::ONNXRuntime* onnxPIDSession_;
+ const cms::Ort::ONNXRuntime* onnxEnergySession_;
+ };
+} // namespace ticl
+
+#endif
diff --git a/RecoHGCal/TICL/interface/TracksterInferenceByCNNv4.h b/RecoHGCal/TICL/interface/TracksterInferenceByCNNv4.h
new file mode 100644
index 0000000000000..db12d1006af4b
--- /dev/null
+++ b/RecoHGCal/TICL/interface/TracksterInferenceByCNNv4.h
@@ -0,0 +1,38 @@
+#ifndef RecoHGCal_TICL_TracksterInferenceByCNNv4_H__
+#define RecoHGCal_TICL_TracksterInferenceByCNNv4_H__
+
+#include "RecoHGCal/TICL/interface/TracksterInferenceAlgoBase.h"
+#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h"
+
+namespace ticl {
+
+ class TracksterInferenceByCNNv4 : public TracksterInferenceAlgoBase {
+ public:
+ explicit TracksterInferenceByCNNv4(const edm::ParameterSet& conf);
+ void inputData(const std::vector& layerClusters, std::vector& tracksters) override;
+ void runInference(std::vector& tracksters) override;
+
+ static void fillPSetDescription(edm::ParameterSetDescription& iDesc);
+
+ private:
+ const cms::Ort::ONNXRuntime* onnxSession_;
+
+ const std::string modelPath_;
+ const std::vector inputNames_;
+ const std::vector outputNames_;
+ const float eidMinClusterEnergy_;
+ const int eidNLayers_;
+ const int eidNClusters_;
+ static constexpr int eidNFeatures_ = 3;
+ int doPID_;
+ int doRegression_;
+
+ hgcal::RecHitTools rhtools_;
+ std::vector> input_shapes_;
+ std::vector tracksterIndices_;
+ std::vector> input_Data_;
+ int batchSize_;
+ };
+} // namespace ticl
+
+#endif // RecoHGCal_TICL_TracksterInferenceByDNN_H__
diff --git a/RecoHGCal/TICL/interface/TracksterInferenceByDNN.h b/RecoHGCal/TICL/interface/TracksterInferenceByDNN.h
new file mode 100644
index 0000000000000..9a1723b37bdb5
--- /dev/null
+++ b/RecoHGCal/TICL/interface/TracksterInferenceByDNN.h
@@ -0,0 +1,41 @@
+#ifndef RecoHGCal_TICL_TracksterInferenceByDNN_H__
+#define RecoHGCal_TICL_TracksterInferenceByDNN_H__
+
+#include "RecoHGCal/TICL/interface/TracksterInferenceAlgoBase.h"
+#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h"
+
+namespace ticl {
+
+ class TracksterInferenceByDNN : public TracksterInferenceAlgoBase {
+ public:
+ explicit TracksterInferenceByDNN(const edm::ParameterSet& conf);
+ void inputData(const std::vector& layerClusters, std::vector& tracksters) override;
+ void runInference(std::vector& tracksters) override;
+
+ static void fillPSetDescription(edm::ParameterSetDescription& iDesc);
+
+ private:
+ const cms::Ort::ONNXRuntime* onnxPIDSession_;
+ const cms::Ort::ONNXRuntime* onnxEnergySession_;
+
+ const std::string id_modelPath_;
+ const std::string en_modelPath_;
+ const std::vector inputNames_;
+ const std::vector output_en_;
+ const std::vector output_id_;
+ const float eidMinClusterEnergy_;
+ const int eidNLayers_;
+ const int eidNClusters_;
+ static constexpr int eidNFeatures_ = 3;
+ int doPID_;
+ int doRegression_;
+
+ hgcal::RecHitTools rhtools_;
+ std::vector> input_shapes_;
+ std::vector tracksterIndices_;
+ std::vector> input_Data_;
+ int batchSize_;
+ };
+} // namespace ticl
+
+#endif // RecoHGCal_TICL_TracksterInferenceByDNN_H__
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc
index 11500c7597a29..83b0a98ef4b00 100644
--- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc
@@ -40,12 +40,6 @@ PatternRecognitionbyCA::PatternRecognitionbyCA(const edm::ParameterSet &c
max_longitudinal_sigmaPCA_(conf.getParameter("max_longitudinal_sigmaPCA")),
min_clusters_per_ntuplet_(min_layers_per_trackster_),
max_delta_time_(conf.getParameter("max_delta_time")),
- eidInputName_(conf.getParameter("eid_input_name")),
- eidOutputNameEnergy_(conf.getParameter("eid_output_name_energy")),
- eidOutputNameId_(conf.getParameter("eid_output_name_id")),
- eidMinClusterEnergy_(conf.getParameter("eid_min_cluster_energy")),
- eidNLayers_(conf.getParameter("eid_n_layers")),
- eidNClusters_(conf.getParameter("eid_n_clusters")),
computeLocalTime_(conf.getParameter("computeLocalTime")),
siblings_maxRSquared_(conf.getParameter>("siblings_maxRSquared")){};
@@ -75,7 +69,6 @@ void PatternRecognitionbyCA::makeTracksters(
constexpr int nEtaBin = TILES::constants_type_t::nEtaBins;
constexpr int nPhiBin = TILES::constants_type_t::nPhiBins;
- bool isRegionalIter = (input.regions[0].index != -1);
std::vector foundNtuplets;
std::vector seedIndices;
std::vector layer_cluster_usage(input.layerClusters.size(), 0);
@@ -105,8 +98,7 @@ void PatternRecognitionbyCA::makeTracksters(
int tracksterId = -1;
// container for holding tracksters before selection
- std::vector tmpTracksters;
- tmpTracksters.reserve(foundNtuplets.size());
+ result.reserve(foundNtuplets.size());
for (auto const &ntuplet : foundNtuplets) {
tracksterId++;
@@ -177,25 +169,25 @@ void PatternRecognitionbyCA::makeTracksters(
tmp.setSeed(input.regions[0].collectionID, seedIndices[tracksterId]);
std::copy(std::begin(effective_cluster_idx), std::end(effective_cluster_idx), std::back_inserter(tmp.vertices()));
- tmpTracksters.push_back(tmp);
+ result.push_back(tmp);
}
}
- ticl::assignPCAtoTracksters(tmpTracksters,
+ ticl::assignPCAtoTracksters(result,
input.layerClusters,
input.layerClustersTime,
rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z(),
rhtools_,
computeLocalTime_);
- // run energy regression and ID
- energyRegressionAndID(input.layerClusters, input.tfSession, tmpTracksters);
- // Filter results based on PID criteria or EM/Total energy ratio.
- // We want to **keep** tracksters whose cumulative
- // probability summed up over the selected categories
- // is greater than the chosen threshold. Therefore
- // the filtering function should **discard** all
- // tracksters **below** the threshold.
- auto filter_on_pids = [&](Trackster &t) -> bool {
+ theGraph_->clear();
+}
+
+template
+void PatternRecognitionbyCA::filter(std::vector &output,
+ const std::vector &inTracksters,
+ const typename PatternRecognitionAlgoBaseT::Inputs &input,
+ std::unordered_map> &seedToTracksterAssociation) {
+ auto filter_on_pids = [&](const ticl::Trackster &t) -> bool {
auto cumulative_prob = 0.;
for (auto index : filter_on_categories_) {
cumulative_prob += t.id_probabilities(index);
@@ -205,62 +197,37 @@ void PatternRecognitionbyCA::makeTracksters(
};
std::vector selectedTrackstersIds;
- for (unsigned i = 0; i < tmpTracksters.size(); ++i) {
- if (!filter_on_pids(tmpTracksters[i]) and tmpTracksters[i].sigmasPCA()[0] < max_longitudinal_sigmaPCA_) {
+ for (unsigned i = 0; i < inTracksters.size(); ++i) {
+ auto &t = inTracksters[i];
+ if (!filter_on_pids(t) and t.sigmasPCA()[0] < max_longitudinal_sigmaPCA_) {
selectedTrackstersIds.push_back(i);
}
}
-
- result.reserve(selectedTrackstersIds.size());
-
+ output.reserve(selectedTrackstersIds.size());
+ bool isRegionalIter = (input.regions[0].index != -1);
for (unsigned i = 0; i < selectedTrackstersIds.size(); ++i) {
- const auto &t = tmpTracksters[selectedTrackstersIds[i]];
- for (auto const lcId : t.vertices()) {
- layer_cluster_usage[lcId]++;
- if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Basic)
- LogDebug("HGCPatternRecoByCA") << "LayerID: " << lcId << " count: " << (int)layer_cluster_usage[lcId]
- << std::endl;
- }
+ const auto &t = inTracksters[selectedTrackstersIds[i]];
if (isRegionalIter) {
seedToTracksterAssociation[t.seedIndex()].push_back(i);
}
- result.push_back(t);
+ output.push_back(t);
}
- for (auto &trackster : result) {
- assert(trackster.vertices().size() <= trackster.vertex_multiplicity().size());
- for (size_t i = 0; i < trackster.vertices().size(); ++i) {
- trackster.vertex_multiplicity()[i] = layer_cluster_usage[trackster.vertices(i)];
- if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Basic)
- LogDebug("HGCPatternRecoByCA") << "LayerID: " << trackster.vertices(i)
- << " count: " << (int)trackster.vertex_multiplicity(i) << std::endl;
- }
- }
// Now decide if the tracksters from the track-based iterations have to be merged
if (oneTracksterPerTrackSeed_) {
std::vector tmp;
- mergeTrackstersTRK(result, input.layerClusters, tmp, seedToTracksterAssociation);
- tmp.swap(result);
+ mergeTrackstersTRK(output, input.layerClusters, tmp, seedToTracksterAssociation);
+ tmp.swap(output);
}
- ticl::assignPCAtoTracksters(result,
- input.layerClusters,
- input.layerClustersTime,
- rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z(),
- rhtools_,
- computeLocalTime_);
-
- // run energy regression and ID
- energyRegressionAndID(input.layerClusters, input.tfSession, result);
-
// now adding dummy tracksters from seeds not connected to any shower in the result collection
// these are marked as charged hadrons with probability 1.
if (promoteEmptyRegionToTrackster_) {
- emptyTrackstersFromSeedsTRK(result, seedToTracksterAssociation, input.regions[0].collectionID);
+ emptyTrackstersFromSeedsTRK(output, seedToTracksterAssociation, input.regions[0].collectionID);
}
if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Advanced) {
- for (auto &trackster : result) {
+ for (auto &trackster : output) {
LogDebug("HGCPatternRecoByCA") << "Trackster characteristics: " << std::endl;
LogDebug("HGCPatternRecoByCA") << "Size: " << trackster.vertices().size() << std::endl;
auto counter = 0;
@@ -269,9 +236,7 @@ void PatternRecognitionbyCA::makeTracksters(
}
}
}
- theGraph_->clear();
}
-
template
void PatternRecognitionbyCA::mergeTrackstersTRK(
const std::vector &input,
@@ -347,146 +312,6 @@ void PatternRecognitionbyCA::emptyTrackstersFromSeedsTRK(
}
}
-template
-void PatternRecognitionbyCA::energyRegressionAndID(const std::vector &layerClusters,
- const tensorflow::Session *eidSession,
- std::vector &tracksters) {
- // Energy regression and particle identification strategy:
- //
- // 1. Set default values for regressed energy and particle id for each trackster.
- // 2. Store indices of tracksters whose total sum of cluster energies is above the
- // eidMinClusterEnergy_ (GeV) threshold. Inference is not applied for soft tracksters.
- // 3. When no trackster passes the selection, return.
- // 4. Create input and output tensors. The batch dimension is determined by the number of
- // selected tracksters.
- // 5. Fill input tensors with layer cluster features. Per layer, clusters are ordered descending
- // by energy. Given that tensor data is contiguous in memory, we can use pointer arithmetic to
- // fill values, even with batching.
- // 6. Zero-fill features for empty clusters in each layer.
- // 7. Batched inference.
- // 8. Assign the regressed energy and id probabilities to each trackster.
- //
- // Indices used throughout this method:
- // i -> batch element / trackster
- // j -> layer
- // k -> cluster
- // l -> feature
-
- // set default values per trackster, determine if the cluster energy threshold is passed,
- // and store indices of hard tracksters
- std::vector tracksterIndices;
- for (int i = 0; i < (int)tracksters.size(); i++) {
- // calculate the cluster energy sum (2)
- // note: after the loop, sumClusterEnergy might be just above the threshold which is enough to
- // decide whether to run inference for the trackster or not
- float sumClusterEnergy = 0.;
- for (const unsigned int &vertex : tracksters[i].vertices()) {
- sumClusterEnergy += (float)layerClusters[vertex].energy();
- // there might be many clusters, so try to stop early
- if (sumClusterEnergy >= eidMinClusterEnergy_) {
- // set default values (1)
- tracksters[i].setRegressedEnergy(0.f);
- tracksters[i].zeroProbabilities();
- tracksterIndices.push_back(i);
- break;
- }
- }
- }
-
- // do nothing when no trackster passes the selection (3)
- int batchSize = (int)tracksterIndices.size();
- if (batchSize == 0) {
- return;
- }
-
- // create input and output tensors (4)
- tensorflow::TensorShape shape({batchSize, eidNLayers_, eidNClusters_, eidNFeatures_});
- tensorflow::Tensor input(tensorflow::DT_FLOAT, shape);
- tensorflow::NamedTensorList inputList = {{eidInputName_, input}};
-
- std::vector outputs;
- std::vector outputNames;
- if (!eidOutputNameEnergy_.empty()) {
- outputNames.push_back(eidOutputNameEnergy_);
- }
- if (!eidOutputNameId_.empty()) {
- outputNames.push_back(eidOutputNameId_);
- }
-
- // fill input tensor (5)
- for (int i = 0; i < batchSize; i++) {
- const Trackster &trackster = tracksters[tracksterIndices[i]];
-
- // per layer, we only consider the first eidNClusters_ clusters in terms of energy, so in order
- // to avoid creating large / nested structures to do the sorting for an unknown number of total
- // clusters, create a sorted list of layer cluster indices to keep track of the filled clusters
- std::vector clusterIndices(trackster.vertices().size());
- for (int k = 0; k < (int)trackster.vertices().size(); k++) {
- clusterIndices[k] = k;
- }
- sort(clusterIndices.begin(), clusterIndices.end(), [&layerClusters, &trackster](const int &a, const int &b) {
- return layerClusters[trackster.vertices(a)].energy() > layerClusters[trackster.vertices(b)].energy();
- });
-
- // keep track of the number of seen clusters per layer
- std::vector seenClusters(eidNLayers_);
-
- // loop through clusters by descending energy
- for (const int &k : clusterIndices) {
- // get features per layer and cluster and store the values directly in the input tensor
- const reco::CaloCluster &cluster = layerClusters[trackster.vertices(k)];
- int j = rhtools_.getLayerWithOffset(cluster.hitsAndFractions()[0].first) - 1;
- if (j < eidNLayers_ && seenClusters[j] < eidNClusters_) {
- // get the pointer to the first feature value for the current batch, layer and cluster
- float *features = &input.tensor()(i, j, seenClusters[j], 0);
-
- // fill features
- *(features++) = float(cluster.energy() / float(trackster.vertex_multiplicity(k)));
- *(features++) = float(std::abs(cluster.eta()));
- *(features) = float(cluster.phi());
-
- // increment seen clusters
- seenClusters[j]++;
- }
- }
-
- // zero-fill features of empty clusters in each layer (6)
- for (int j = 0; j < eidNLayers_; j++) {
- for (int k = seenClusters[j]; k < eidNClusters_; k++) {
- float *features = &input.tensor()(i, j, k, 0);
- for (int l = 0; l < eidNFeatures_; l++) {
- *(features++) = 0.f;
- }
- }
- }
- }
-
- // run the inference (7)
- tensorflow::run(eidSession, inputList, outputNames, &outputs);
-
- // store regressed energy per trackster (8)
- if (!eidOutputNameEnergy_.empty()) {
- // get the pointer to the energy tensor, dimension is batch x 1
- float *energy = outputs[0].flat().data();
-
- for (const int &i : tracksterIndices) {
- tracksters[i].setRegressedEnergy(*(energy++));
- }
- }
-
- // store id probabilities per trackster (8)
- if (!eidOutputNameId_.empty()) {
- // get the pointer to the id probability tensor, dimension is batch x id_probabilities.size()
- int probsIdx = eidOutputNameEnergy_.empty() ? 0 : 1;
- float *probs = outputs[probsIdx].flat().data();
-
- for (const int &i : tracksterIndices) {
- tracksters[i].setProbabilities(probs);
- probs += tracksters[i].id_probabilities().size();
- }
- }
-}
-
template
void PatternRecognitionbyCA::fillPSetDescription(edm::ParameterSetDescription &iDesc) {
iDesc.add("algo_verbosity", 0);
@@ -508,12 +333,6 @@ void PatternRecognitionbyCA::fillPSetDescription(edm::ParameterSetDescrip
->setComment("make default such that no filtering is applied");
iDesc.add("max_longitudinal_sigmaPCA", 9999);
iDesc.add("max_delta_time", 3.)->setComment("nsigma");
- iDesc.add("eid_input_name", "input");
- iDesc.add("eid_output_name_energy", "output/regressed_energy");
- iDesc.add("eid_output_name_id", "output/id_probabilities");
- iDesc.add("eid_min_cluster_energy", 1.);
- iDesc.add("eid_n_layers", 50);
- iDesc.add("eid_n_clusters", 10);
iDesc.add("computeLocalTime", false);
iDesc.add>("siblings_maxRSquared", {6e-4, 6e-4, 6e-4});
}
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h
index 90bcddf06eabf..0a4eed44f0680 100644
--- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h
@@ -20,6 +20,11 @@ namespace ticl {
std::vector& result,
std::unordered_map>& seedToTracksterAssociation) override;
+ void filter(std::vector& output,
+ const std::vector& inTracksters,
+ const typename PatternRecognitionAlgoBaseT::Inputs& input,
+ std::unordered_map>& seedToTracksterAssociation) override;
+
void energyRegressionAndID(const std::vector& layerClusters,
const tensorflow::Session*,
std::vector& result);
@@ -58,16 +63,10 @@ namespace ticl {
const std::string eidInputName_;
const std::string eidOutputNameEnergy_;
const std::string eidOutputNameId_;
- const float eidMinClusterEnergy_;
- const int eidNLayers_;
- const int eidNClusters_;
const bool computeLocalTime_;
hgcal::RecHitTools rhtools_;
- tensorflow::Session* eidSession_;
const std::vector siblings_maxRSquared_;
-
- static const int eidNFeatures_ = 3;
};
} // namespace ticl
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.cc
index ec809b813e6a6..e55e463129cd4 100644
--- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.cc
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.cc
@@ -39,15 +39,8 @@ PatternRecognitionbyCLUE3D::PatternRecognitionbyCLUE3D(const edm::Paramet
minNumLayerCluster_(conf.getParameter>("minNumLayerCluster")),
doPidCut_(conf.getParameter("doPidCut")),
cutHadProb_(conf.getParameter("cutHadProb")),
- eidInputName_(conf.getParameter("eid_input_name")),
- eidOutputNameEnergy_(conf.getParameter("eid_output_name_energy")),
- eidOutputNameId_(conf.getParameter("eid_output_name_id")),
- eidMinClusterEnergy_(conf.getParameter("eid_min_cluster_energy")),
- eidNLayers_(conf.getParameter("eid_n_layers")),
- eidNClusters_(conf.getParameter("eid_n_clusters")),
computeLocalTime_(conf.getParameter("computeLocalTime")),
usePCACleaning_(conf.getParameter("usePCACleaning")){};
-
template
void PatternRecognitionbyCLUE3D::dumpTiles(const TILES &tiles) const {
constexpr int nEtaBin = TILES::constants_type_t::nEtaBins;
@@ -330,18 +323,7 @@ void PatternRecognitionbyCLUE3D::makeTracksters(
minNumLayerCluster_[tracksterSeedAlgoId_[tracksterIndex++]];
}),
result.end());
- if (doPidCut_) {
- energyRegressionAndID(input.layerClusters, input.tfSession, result);
- result.erase(std::remove_if(std::begin(result),
- std::end(result),
- [&](auto const &v) {
- auto const &hadProb =
- v.id_probability(ticl::Trackster::ParticleType::charged_hadron) +
- v.id_probability(ticl::Trackster::ParticleType::neutral_hadron);
- return hadProb >= cutHadProb_;
- }),
- result.end());
- }
+
result.shrink_to_fit();
ticl::assignPCAtoTracksters(result,
@@ -373,144 +355,25 @@ void PatternRecognitionbyCLUE3D::makeTracksters(
edm::LogVerbatim("PatternRecognitionbyCLUE3D") << std::endl;
}
}
-
template
-void PatternRecognitionbyCLUE3D::energyRegressionAndID(const std::vector &layerClusters,
- const tensorflow::Session *eidSession,
- std::vector &tracksters) {
- // Energy regression and particle identification strategy:
- //
- // 1. Set default values for regressed energy and particle id for each trackster.
- // 2. Store indices of tracksters whose total sum of cluster energies is above the
- // eidMinClusterEnergy_ (GeV) threshold. Inference is not applied for soft tracksters.
- // 3. When no trackster passes the selection, return.
- // 4. Create input and output tensors. The batch dimension is determined by the number of
- // selected tracksters.
- // 5. Fill input tensors with layer cluster features. Per layer, clusters are ordered descending
- // by energy. Given that tensor data is contiguous in memory, we can use pointer arithmetic to
- // fill values, even with batching.
- // 6. Zero-fill features for empty clusters in each layer.
- // 7. Batched inference.
- // 8. Assign the regressed energy and id probabilities to each trackster.
- //
- // Indices used throughout this method:
- // i -> batch element / trackster
- // j -> layer
- // k -> cluster
- // l -> feature
-
- // set default values per trackster, determine if the cluster energy threshold is passed,
- // and store indices of hard tracksters
- std::vector tracksterIndices;
- for (int i = 0; i < static_cast(tracksters.size()); i++) {
- // calculate the cluster energy sum (2)
- // note: after the loop, sumClusterEnergy might be just above the threshold which is enough to
- // decide whether to run inference for the trackster or not
- float sumClusterEnergy = 0.;
- for (const unsigned int &vertex : tracksters[i].vertices()) {
- sumClusterEnergy += static_cast(layerClusters[vertex].energy());
- // there might be many clusters, so try to stop early
- if (sumClusterEnergy >= eidMinClusterEnergy_) {
- // set default values (1)
- tracksters[i].setRegressedEnergy(0.f);
- tracksters[i].zeroProbabilities();
- tracksterIndices.push_back(i);
- break;
- }
- }
- }
-
- // do nothing when no trackster passes the selection (3)
- int batchSize = static_cast(tracksterIndices.size());
- if (batchSize == 0) {
- return;
- }
-
- // create input and output tensors (4)
- tensorflow::TensorShape shape({batchSize, eidNLayers_, eidNClusters_, eidNFeatures_});
- tensorflow::Tensor input(tensorflow::DT_FLOAT, shape);
- tensorflow::NamedTensorList inputList = {{eidInputName_, input}};
-
- std::vector outputs;
- std::vector outputNames;
- if (!eidOutputNameEnergy_.empty()) {
- outputNames.push_back(eidOutputNameEnergy_);
- }
- if (!eidOutputNameId_.empty()) {
- outputNames.push_back(eidOutputNameId_);
- }
-
- // fill input tensor (5)
- for (int i = 0; i < batchSize; i++) {
- const Trackster &trackster = tracksters[tracksterIndices[i]];
-
- // per layer, we only consider the first eidNClusters_ clusters in terms of energy, so in order
- // to avoid creating large / nested structures to do the sorting for an unknown number of total
- // clusters, create a sorted list of layer cluster indices to keep track of the filled clusters
- std::vector clusterIndices(trackster.vertices().size());
- for (int k = 0; k < (int)trackster.vertices().size(); k++) {
- clusterIndices[k] = k;
- }
- sort(clusterIndices.begin(), clusterIndices.end(), [&layerClusters, &trackster](const int &a, const int &b) {
- return layerClusters[trackster.vertices(a)].energy() > layerClusters[trackster.vertices(b)].energy();
- });
-
- // keep track of the number of seen clusters per layer
- std::vector seenClusters(eidNLayers_);
-
- // loop through clusters by descending energy
- for (const int &k : clusterIndices) {
- // get features per layer and cluster and store the values directly in the input tensor
- const reco::CaloCluster &cluster = layerClusters[trackster.vertices(k)];
- int j = rhtools_.getLayerWithOffset(cluster.hitsAndFractions()[0].first) - 1;
- if (j < eidNLayers_ && seenClusters[j] < eidNClusters_) {
- // get the pointer to the first feature value for the current batch, layer and cluster
- float *features = &input.tensor()(i, j, seenClusters[j], 0);
-
- // fill features
- *(features++) = float(cluster.energy() / float(trackster.vertex_multiplicity(k)));
- *(features++) = float(std::abs(cluster.eta()));
- *(features) = float(cluster.phi());
-
- // increment seen clusters
- seenClusters[j]++;
- }
- }
+void PatternRecognitionbyCLUE3D::filter(std::vector &output,
+ const std::vector &inTracksters,
+ const typename PatternRecognitionAlgoBaseT::Inputs &input,
+ std::unordered_map> &seedToTracksterAssociation) {
+ auto isHAD = [this](const Trackster &t) -> bool {
+ auto const hadProb = t.id_probability(ticl::Trackster::ParticleType::charged_hadron) +
+ t.id_probability(ticl::Trackster::ParticleType::neutral_hadron);
+ return hadProb >= cutHadProb_;
+ };
- // zero-fill features of empty clusters in each layer (6)
- for (int j = 0; j < eidNLayers_; j++) {
- for (int k = seenClusters[j]; k < eidNClusters_; k++) {
- float *features = &input.tensor()(i, j, k, 0);
- for (int l = 0; l < eidNFeatures_; l++) {
- *(features++) = 0.f;
- }
+ if (doPidCut_) {
+ for (auto const &t : inTracksters) {
+ if (!isHAD(t)) {
+ output.push_back(t);
}
}
- }
-
- // run the inference (7)
- tensorflow::run(eidSession, inputList, outputNames, &outputs);
-
- // store regressed energy per trackster (8)
- if (!eidOutputNameEnergy_.empty()) {
- // get the pointer to the energy tensor, dimension is batch x 1
- float *energy = outputs[0].flat().data();
-
- for (const int &i : tracksterIndices) {
- tracksters[i].setRegressedEnergy(*(energy++));
- }
- }
-
- // store id probabilities per trackster (8)
- if (!eidOutputNameId_.empty()) {
- // get the pointer to the id probability tensor, dimension is batch x id_probabilities.size()
- int probsIdx = eidOutputNameEnergy_.empty() ? 0 : 1;
- float *probs = outputs[probsIdx].flat().data();
-
- for (const int &i : tracksterIndices) {
- tracksters[i].setProbabilities(probs);
- probs += tracksters[i].id_probabilities().size();
- }
+ } else {
+ output = inTracksters;
}
}
@@ -666,9 +529,9 @@ void PatternRecognitionbyCLUE3D::calculateLocalDensity(
}
}
} // end of loop on possible compatible clusters
- } // end of loop over phi-bin region
- } // end of loop over eta-bin region
- } // end of loop on the sibling layers
+ } // end of loop over phi-bin region
+ } // end of loop over eta-bin region
+ } // end of loop on the sibling layers
if (rescaleDensityByZ_) {
if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Advanced) {
edm::LogVerbatim("PatternRecognitionbyCLUE3D")
@@ -777,9 +640,9 @@ void PatternRecognitionbyCLUE3D::calculateDistanceToHigher(
i_nearestHigher = layerandSoa;
}
} // End of loop on clusters
- } // End of loop on phi bins
- } // End of loop on eta bins
- } // End of loop on layers
+ } // End of loop on phi bins
+ } // End of loop on eta bins
+ } // End of loop on layers
clustersOnLayer.delta[i] = nearest_distances;
clustersOnLayer.nearestHigher[i] = i_nearestHigher;
@@ -898,12 +761,6 @@ void PatternRecognitionbyCLUE3D::fillPSetDescription(edm::ParameterSetDes
iDesc.add>("minNumLayerCluster", {2, 2, 2})->setComment("Not Inclusive");
iDesc.add("doPidCut", false);
iDesc.add("cutHadProb", 0.5);
- iDesc.add("eid_input_name", "input");
- iDesc.add("eid_output_name_energy", "output/regressed_energy");
- iDesc.add("eid_output_name_id", "output/id_probabilities");
- iDesc.add("eid_min_cluster_energy", 1.);
- iDesc.add("eid_n_layers", 50);
- iDesc.add("eid_n_clusters", 10);
iDesc.add("computeLocalTime", false);
iDesc.add("usePCACleaning", false)->setComment("Enable PCA cleaning alorithm");
}
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.h
index b3139e2402501..fa907ad6a6eef 100644
--- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.h
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.h
@@ -18,6 +18,11 @@ namespace ticl {
std::vector& result,
std::unordered_map>& seedToTracksterAssociation) override;
+ void filter(std::vector& output,
+ const std::vector& inTracksters,
+ const typename PatternRecognitionAlgoBaseT::Inputs& input,
+ std::unordered_map>& seedToTracksterAssociation) override;
+
void energyRegressionAndID(const std::vector& layerClusters,
const tensorflow::Session*,
std::vector& result);
@@ -134,19 +139,10 @@ namespace ticl {
const bool doPidCut_;
const float cutHadProb_;
const std::vector filter_on_categories_;
- const std::string eidInputName_;
- const std::string eidOutputNameEnergy_;
- const std::string eidOutputNameId_;
- const float eidMinClusterEnergy_;
- const int eidNLayers_;
- const int eidNClusters_;
const bool computeLocalTime_;
const bool usePCACleaning_;
hgcal::RecHitTools rhtools_;
- tensorflow::Session* eidSession_;
-
- static const int eidNFeatures_ = 3;
};
} // namespace ticl
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc
index b8e8bf99f4a6f..957abb847c0cb 100644
--- a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc
@@ -32,12 +32,6 @@ PatternRecognitionbyFastJet::PatternRecognitionbyFastJet(const edm::Param
caloGeomToken_(iC.esConsumes()),
antikt_radius_(conf.getParameter("antikt_radius")),
minNumLayerCluster_(conf.getParameter("minNumLayerCluster")),
- eidInputName_(conf.getParameter("eid_input_name")),
- eidOutputNameEnergy_(conf.getParameter("eid_output_name_energy")),
- eidOutputNameId_(conf.getParameter("eid_output_name_id")),
- eidMinClusterEnergy_(conf.getParameter("eid_min_cluster_energy")),
- eidNLayers_(conf.getParameter("eid_n_layers")),
- eidNClusters_(conf.getParameter("eid_n_clusters")),
computeLocalTime_(conf.getParameter("computeLocalTime")){};
template
@@ -135,9 +129,9 @@ void PatternRecognitionbyFastJet::makeTracksters(
fpj.set_user_index(clusterIdx);
fjInputs.push_back(fpj);
} // End of loop on the clusters on currentLayer
- } // End of loop over phi-bin region
- } // End of loop over eta-bin region
- } // End of loop over layers
+ } // End of loop over phi-bin region
+ } // End of loop over eta-bin region
+ } // End of loop over layers
// Collect the jet from the other side wrt to the one taken care of inside the main loop above.
buildJetAndTracksters(fjInputs, result);
@@ -150,7 +144,6 @@ void PatternRecognitionbyFastJet::makeTracksters(
computeLocalTime_);
// run energy regression and ID
- energyRegressionAndID(input.layerClusters, input.tfSession, result);
if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Basic) {
for (auto const &t : result) {
edm::LogVerbatim("PatternRecogntionbyFastJet") << "Barycenter: " << t.barycenter();
@@ -162,143 +155,11 @@ void PatternRecognitionbyFastJet::makeTracksters(
}
template
-void PatternRecognitionbyFastJet::energyRegressionAndID(const std::vector &layerClusters,
- const tensorflow::Session *eidSession,
- std::vector &tracksters) {
- // Energy regression and particle identification strategy:
- //
- // 1. Set default values for regressed energy and particle id for each trackster.
- // 2. Store indices of tracksters whose total sum of cluster energies is above the
- // eidMinClusterEnergy_ (GeV) threshold. Inference is not applied for soft tracksters.
- // 3. When no trackster passes the selection, return.
- // 4. Create input and output tensors. The batch dimension is determined by the number of
- // selected tracksters.
- // 5. Fill input tensors with layer cluster features. Per layer, clusters are ordered descending
- // by energy. Given that tensor data is contiguous in memory, we can use pointer arithmetic to
- // fill values, even with batching.
- // 6. Zero-fill features for empty clusters in each layer.
- // 7. Batched inference.
- // 8. Assign the regressed energy and id probabilities to each trackster.
- //
- // Indices used throughout this method:
- // i -> batch element / trackster
- // j -> layer
- // k -> cluster
- // l -> feature
-
- // set default values per trackster, determine if the cluster energy threshold is passed,
- // and store indices of hard tracksters
- std::vector tracksterIndices;
- for (int i = 0; i < static_cast(tracksters.size()); i++) {
- // calculate the cluster energy sum (2)
- // note: after the loop, sumClusterEnergy might be just above the threshold which is enough to
- // decide whether to run inference for the trackster or not
- float sumClusterEnergy = 0.;
- for (const unsigned int &vertex : tracksters[i].vertices()) {
- sumClusterEnergy += static_cast(layerClusters[vertex].energy());
- // there might be many clusters, so try to stop early
- if (sumClusterEnergy >= eidMinClusterEnergy_) {
- // set default values (1)
- tracksters[i].setRegressedEnergy(0.f);
- tracksters[i].zeroProbabilities();
- tracksterIndices.push_back(i);
- break;
- }
- }
- }
-
- // do nothing when no trackster passes the selection (3)
- int batchSize = static_cast(tracksterIndices.size());
- if (batchSize == 0) {
- return;
- }
-
- // create input and output tensors (4)
- tensorflow::TensorShape shape({batchSize, eidNLayers_, eidNClusters_, eidNFeatures_});
- tensorflow::Tensor input(tensorflow::DT_FLOAT, shape);
- tensorflow::NamedTensorList inputList = {{eidInputName_, input}};
-
- std::vector outputs;
- std::vector outputNames;
- if (!eidOutputNameEnergy_.empty()) {
- outputNames.push_back(eidOutputNameEnergy_);
- }
- if (!eidOutputNameId_.empty()) {
- outputNames.push_back(eidOutputNameId_);
- }
-
- // fill input tensor (5)
- for (int i = 0; i < batchSize; i++) {
- const Trackster &trackster = tracksters[tracksterIndices[i]];
-
- // per layer, we only consider the first eidNClusters_ clusters in terms of energy, so in order
- // to avoid creating large / nested structures to do the sorting for an unknown number of total
- // clusters, create a sorted list of layer cluster indices to keep track of the filled clusters
- std::vector clusterIndices(trackster.vertices().size());
- for (int k = 0; k < (int)trackster.vertices().size(); k++) {
- clusterIndices[k] = k;
- }
- sort(clusterIndices.begin(), clusterIndices.end(), [&layerClusters, &trackster](const int &a, const int &b) {
- return layerClusters[trackster.vertices(a)].energy() > layerClusters[trackster.vertices(b)].energy();
- });
-
- // keep track of the number of seen clusters per layer
- std::vector seenClusters(eidNLayers_);
-
- // loop through clusters by descending energy
- for (const int &k : clusterIndices) {
- // get features per layer and cluster and store the values directly in the input tensor
- const reco::CaloCluster &cluster = layerClusters[trackster.vertices(k)];
- int j = rhtools_.getLayerWithOffset(cluster.hitsAndFractions()[0].first) - 1;
- if (j < eidNLayers_ && seenClusters[j] < eidNClusters_) {
- // get the pointer to the first feature value for the current batch, layer and cluster
- float *features = &input.tensor()(i, j, seenClusters[j], 0);
-
- // fill features
- *(features++) = float(cluster.energy() / float(trackster.vertex_multiplicity(k)));
- *(features++) = float(std::abs(cluster.eta()));
- *(features) = float(cluster.phi());
-
- // increment seen clusters
- seenClusters[j]++;
- }
- }
-
- // zero-fill features of empty clusters in each layer (6)
- for (int j = 0; j < eidNLayers_; j++) {
- for (int k = seenClusters[j]; k < eidNClusters_; k++) {
- float *features = &input.tensor()(i, j, k, 0);
- for (int l = 0; l < eidNFeatures_; l++) {
- *(features++) = 0.f;
- }
- }
- }
- }
-
- // run the inference (7)
- tensorflow::run(eidSession, inputList, outputNames, &outputs);
-
- // store regressed energy per trackster (8)
- if (!eidOutputNameEnergy_.empty()) {
- // get the pointer to the energy tensor, dimension is batch x 1
- float *energy = outputs[0].flat().data();
-
- for (const int &i : tracksterIndices) {
- tracksters[i].setRegressedEnergy(*(energy++));
- }
- }
-
- // store id probabilities per trackster (8)
- if (!eidOutputNameId_.empty()) {
- // get the pointer to the id probability tensor, dimension is batch x id_probabilities.size()
- int probsIdx = eidOutputNameEnergy_.empty() ? 0 : 1;
- float *probs = outputs[probsIdx].flat().data();
-
- for (const int &i : tracksterIndices) {
- tracksters[i].setProbabilities(probs);
- probs += tracksters[i].id_probabilities().size();
- }
- }
+void PatternRecognitionbyFastJet::filter(std::vector &output,
+ const std::vector &inTracksters,
+ const typename PatternRecognitionAlgoBaseT::Inputs &input,
+ std::unordered_map> &seedToTracksterAssociation) {
+ output = inTracksters;
}
template
@@ -306,12 +167,6 @@ void PatternRecognitionbyFastJet::fillPSetDescription(edm::ParameterSetDe
iDesc.add("algo_verbosity", 0);
iDesc.add("antikt_radius", 0.09)->setComment("Radius to be used while running the Anti-kt clustering");
iDesc.add("minNumLayerCluster", 5)->setComment("Not Inclusive");
- iDesc.add("eid_input_name", "input");
- iDesc.add("eid_output_name_energy", "output/regressed_energy");
- iDesc.add("eid_output_name_id", "output/id_probabilities");
- iDesc.add("eid_min_cluster_energy", 1.);
- iDesc.add("eid_n_layers", 50);
- iDesc.add("eid_n_clusters", 10);
iDesc.add("computeLocalTime", false);
}
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h
index 2811b54c8e6e4..bfc10ea26e9d3 100644
--- a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h
@@ -24,6 +24,11 @@ namespace ticl {
std::vector& result,
std::unordered_map>& seedToTracksterAssociation) override;
+ void filter(std::vector& output,
+ const std::vector& inTracksters,
+ const typename PatternRecognitionAlgoBaseT::Inputs& input,
+ std::unordered_map>& seedToTracksterAssociation) override;
+
void energyRegressionAndID(const std::vector& layerClusters,
const tensorflow::Session*,
std::vector& result);
@@ -34,18 +39,9 @@ namespace ticl {
edm::ESGetToken caloGeomToken_;
const double antikt_radius_;
const int minNumLayerCluster_;
- const std::string eidInputName_;
- const std::string eidOutputNameEnergy_;
- const std::string eidOutputNameId_;
- const float eidMinClusterEnergy_;
- const int eidNLayers_;
- const int eidNClusters_;
const bool computeLocalTime_;
hgcal::RecHitTools rhtools_;
- tensorflow::Session* eidSession_;
-
- static const int eidNFeatures_ = 3;
void buildJetAndTracksters(std::vector&, std::vector&);
};
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.cc
index ccca28ea82bd5..de40f9fd5d298 100644
--- a/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.cc
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.cc
@@ -62,6 +62,15 @@ void PatternRecognitionbyPassthrough::makeTracksters(
}
}
+template
+void PatternRecognitionbyPassthrough::filter(
+ std::vector &output,
+ const std::vector &inTracksters,
+ const typename PatternRecognitionAlgoBaseT::Inputs &input,
+ std::unordered_map> &seedToTracksterAssociation) {
+ output = inTracksters;
+}
+
template
void PatternRecognitionbyPassthrough::fillPSetDescription(edm::ParameterSetDescription &iDesc) {
iDesc.add("algo_verbosity", 0);
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.h
index 8ef9a76824be0..22f818b8ed958 100644
--- a/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.h
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.h
@@ -18,6 +18,11 @@ namespace ticl {
std::vector& result,
std::unordered_map>& seedToTracksterAssociation) override;
+ void filter(std::vector& output,
+ const std::vector& inTracksters,
+ const typename PatternRecognitionAlgoBaseT::Inputs& input,
+ std::unordered_map>& seedToTracksterAssociation) override;
+
static void fillPSetDescription(edm::ParameterSetDescription& iDesc);
private:
diff --git a/RecoHGCal/TICL/plugins/TracksterInferenceAlgoFactory.cc b/RecoHGCal/TICL/plugins/TracksterInferenceAlgoFactory.cc
new file mode 100644
index 0000000000000..b3580ab956cb4
--- /dev/null
+++ b/RecoHGCal/TICL/plugins/TracksterInferenceAlgoFactory.cc
@@ -0,0 +1,13 @@
+#include "RecoHGCal/TICL/interface/TracksterInferenceAlgoFactory.h"
+#include "RecoHGCal/TICL/interface/TracksterInferenceByDNN.h"
+#include "RecoHGCal/TICL/interface/TracksterInferenceByANN.h"
+#include "RecoHGCal/TICL/interface/TracksterInferenceByCNNv4.h"
+#include "FWCore/ParameterSet/interface/ValidatedPluginFactoryMacros.h"
+#include "FWCore/ParameterSet/interface/ValidatedPluginMacros.h"
+
+EDM_REGISTER_VALIDATED_PLUGINFACTORY(TracksterInferenceAlgoFactory, "TracksterInferenceAlgoFactory");
+DEFINE_EDM_VALIDATED_PLUGIN(TracksterInferenceAlgoFactory, ticl::TracksterInferenceByDNN, "TracksterInferenceByDNN");
+DEFINE_EDM_VALIDATED_PLUGIN(TracksterInferenceAlgoFactory, ticl::TracksterInferenceByANN, "TracksterInferenceByANN");
+DEFINE_EDM_VALIDATED_PLUGIN(TracksterInferenceAlgoFactory,
+ ticl::TracksterInferenceByCNNv4,
+ "TracksterInferenceByCNNv4");
diff --git a/RecoHGCal/TICL/plugins/TracksterInferenceByANN.cc b/RecoHGCal/TICL/plugins/TracksterInferenceByANN.cc
new file mode 100644
index 0000000000000..d57b9ca3bfd0b
--- /dev/null
+++ b/RecoHGCal/TICL/plugins/TracksterInferenceByANN.cc
@@ -0,0 +1,24 @@
+#include "RecoHGCal/TICL/interface/TracksterInferenceAlgoFactory.h"
+#include "RecoHGCal/TICL/interface/TracksterInferenceByANN.h"
+#include "FWCore/ParameterSet/interface/ParameterSet.h"
+#include "FWCore/Framework/interface/ConsumesCollector.h"
+
+namespace ticl {
+
+ TracksterInferenceByANN::TracksterInferenceByANN(const edm::ParameterSet& conf) : TracksterInferenceAlgoBase(conf) {
+ // Load ANN model
+ }
+
+ void TracksterInferenceByANN::inputData(const std::vector& layerClusters,
+ std::vector& tracksters) {
+ // Prepare data for inference
+ }
+
+ void TracksterInferenceByANN::runInference(std::vector