diff --git a/Configuration/ProcessModifiers/python/fastJetTICL_cff.py b/Configuration/ProcessModifiers/python/fastJetTICL_cff.py
new file mode 100644
index 0000000000000..977b584061ae1
--- /dev/null
+++ b/Configuration/ProcessModifiers/python/fastJetTICL_cff.py
@@ -0,0 +1,5 @@
+import FWCore.ParameterSet.Config as cms
+
+# This modifier is for injecting CLUE3D-based iterations in TICL.
+
+fastJetTICL = cms.Modifier()
diff --git a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py
index 15a16ec5a3b54..7f19a94d83e75 100644
--- a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py
+++ b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py
@@ -381,6 +381,52 @@ def condition(self, fragment, stepList, key, hasHarvest):
offset = 0.9,
)
+# Special TICL Pattern recognition Workflows
+class UpgradeWorkflow_ticl_clue3D(UpgradeWorkflow):
+ def setup_(self, step, stepName, stepDict, k, properties):
+ if 'RecoGlobal' in step:
+ stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
+ if 'HARVESTGlobal' in step:
+ stepDict[stepName][k] = merge([self.step4, stepDict[step][k]])
+ def condition(self, fragment, stepList, key, hasHarvest):
+ return (fragment=="TTbar_14TeV" or 'CloseByPGun_CE' in fragment) and '2026' in key
+upgradeWFs['ticl_clue3D'] = UpgradeWorkflow_ticl_clue3D(
+ steps = [
+ 'RecoGlobal',
+ 'HARVESTGlobal'
+ ],
+ PU = [
+ 'RecoGlobal',
+ 'HARVESTGlobal'
+ ],
+ suffix = '_ticl_clue3D',
+ offset = 0.201,
+)
+upgradeWFs['ticl_clue3D'].step3 = {'--procModifiers': 'clue3D'}
+upgradeWFs['ticl_clue3D'].step4 = {'--procModifiers': 'clue3D'}
+
+class UpgradeWorkflow_ticl_FastJet(UpgradeWorkflow):
+ def setup_(self, step, stepName, stepDict, k, properties):
+ if 'RecoGlobal' in step:
+ stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
+ if 'HARVESTGlobal' in step:
+ stepDict[stepName][k] = merge([self.step4, stepDict[step][k]])
+ def condition(self, fragment, stepList, key, hasHarvest):
+ return (fragment=="TTbar_14TeV" or 'CloseByPGun_CE' in fragment) and '2026' in key
+upgradeWFs['ticl_FastJet'] = UpgradeWorkflow_ticl_FastJet(
+ steps = [
+ 'RecoGlobal',
+ 'HARVESTGlobal'
+ ],
+ PU = [
+ 'RecoGlobal',
+ 'HARVESTGlobal'
+ ],
+ suffix = '_ticl_FastJet',
+ offset = 0.202,
+)
+upgradeWFs['ticl_FastJet'].step3 = {'--procModifiers': 'fastJetTICL'}
+upgradeWFs['ticl_FastJet'].step4 = {'--procModifiers': 'fastJetTICL'}
# Track DNN workflows
class UpgradeWorkflow_trackdnn(UpgradeWorkflow):
diff --git a/RecoHGCal/TICL/plugins/BuildFile.xml b/RecoHGCal/TICL/plugins/BuildFile.xml
index e23f331607ef8..8c631381e21b4 100644
--- a/RecoHGCal/TICL/plugins/BuildFile.xml
+++ b/RecoHGCal/TICL/plugins/BuildFile.xml
@@ -29,6 +29,7 @@
+
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.cc b/RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.cc
index e35a6d24c91a0..ac6296db5bf3b 100644
--- a/RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.cc
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.cc
@@ -1,6 +1,7 @@
#include "RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.h"
#include "PatternRecognitionbyCA.h"
#include "PatternRecognitionbyCLUE3D.h"
+#include "PatternRecognitionbyFastJet.h"
#include "FWCore/ParameterSet/interface/ValidatedPluginFactoryMacros.h"
#include "FWCore/ParameterSet/interface/ValidatedPluginMacros.h"
@@ -8,4 +9,5 @@ EDM_REGISTER_VALIDATED_PLUGINFACTORY(PatternRecognitionFactory, "PatternRecognit
EDM_REGISTER_VALIDATED_PLUGINFACTORY(PatternRecognitionHFNoseFactory, "PatternRecognitionHFNoseFactory");
DEFINE_EDM_VALIDATED_PLUGIN(PatternRecognitionFactory, ticl::PatternRecognitionbyCA, "CA");
DEFINE_EDM_VALIDATED_PLUGIN(PatternRecognitionFactory, ticl::PatternRecognitionbyCLUE3D, "CLUE3D");
+DEFINE_EDM_VALIDATED_PLUGIN(PatternRecognitionFactory, ticl::PatternRecognitionbyFastJet, "FastJet");
DEFINE_EDM_VALIDATED_PLUGIN(PatternRecognitionHFNoseFactory, ticl::PatternRecognitionbyCA, "CA");
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc
new file mode 100644
index 0000000000000..47e19e499cc92
--- /dev/null
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc
@@ -0,0 +1,319 @@
+// Author: Marco Rovere - marco.rovere@cern.ch
+// Date: 10/2021
+#include
+#include
+#include
+
+#include "tbb/task_arena.h"
+#include "tbb/tbb.h"
+
+#include "DataFormats/Math/interface/deltaR.h"
+#include "DataFormats/Math/interface/LorentzVector.h"
+#include "DataFormats/Candidate/interface/Candidate.h"
+#include "FWCore/Framework/interface/Event.h"
+#include "FWCore/MessageLogger/interface/MessageLogger.h"
+#include "FWCore/Utilities/interface/Exception.h"
+#include "PatternRecognitionbyFastJet.h"
+
+#include "TrackstersPCA.h"
+#include "Geometry/CaloGeometry/interface/CaloGeometry.h"
+#include "Geometry/Records/interface/CaloGeometryRecord.h"
+#include "FWCore/Framework/interface/EventSetup.h"
+
+#include "fastjet/ClusterSequence.hh"
+
+using namespace ticl;
+using namespace fastjet;
+
+template
+PatternRecognitionbyFastJet::PatternRecognitionbyFastJet(const edm::ParameterSet &conf,
+ const CacheBase *cache,
+ edm::ConsumesCollector iC)
+ : PatternRecognitionAlgoBaseT(conf, cache, iC),
+ 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")),
+ eidSession_(nullptr) {
+ // mount the tensorflow graph onto the session when set
+ const TrackstersCache *trackstersCache = dynamic_cast(cache);
+ if (trackstersCache == nullptr || trackstersCache->eidGraphDef == nullptr) {
+ throw cms::Exception("MissingGraphDef")
+ << "PatternRecognitionbyFastJet received an empty graph definition from the global cache";
+ }
+ eidSession_ = tensorflow::createSession(trackstersCache->eidGraphDef);
+}
+
+template
+void PatternRecognitionbyFastJet::buildJetAndTracksters(std::vector &fjInputs,
+ std::vector &result) {
+ if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Basic) {
+ edm::LogVerbatim("PatternRecogntionbyFastJet")
+ << "Creating FastJet with " << fjInputs.size() << " LayerClusters in input";
+ }
+ fastjet::ClusterSequence sequence(fjInputs, JetDefinition(antikt_algorithm, antikt_radius_));
+ auto jets = fastjet::sorted_by_pt(sequence.inclusive_jets(0));
+ if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Basic) {
+ edm::LogVerbatim("PatternRecogntionbyFastJet") << "FastJet produced " << jets.size() << " jets/trackster";
+ }
+
+ auto trackster_idx = result.size();
+ result.resize(trackster_idx + jets.size());
+ for (const auto &pj : jets) {
+ if (pj.constituents().size() > static_cast(minNumLayerCluster_)) {
+ for (const auto &component : pj.constituents()) {
+ result[trackster_idx].vertices().push_back(component.user_index());
+ result[trackster_idx].vertex_multiplicity().push_back(1);
+ if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Basic) {
+ edm::LogVerbatim("PatternRecogntionbyFastJet")
+ << "Jet has " << pj.constituents().size() << " components that are stored in trackster " << trackster_idx;
+ }
+ }
+ trackster_idx++;
+ } else {
+ if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Advanced) {
+ edm::LogVerbatim("PatternRecogntionbyFastJet")
+ << "Jet with " << pj.constituents().size() << " constituents discarded since too small wrt "
+ << minNumLayerCluster_;
+ }
+ }
+ }
+ fjInputs.clear();
+}
+
+template
+void PatternRecognitionbyFastJet::makeTracksters(
+ const typename PatternRecognitionAlgoBaseT::Inputs &input,
+ std::vector &result,
+ std::unordered_map> &seedToTracksterAssociation) {
+ // Protect from events with no seeding regions
+ if (input.regions.empty())
+ return;
+
+ edm::EventSetup const &es = input.es;
+ const CaloGeometry &geom = es.getData(caloGeomToken_);
+ rhtools_.setGeometry(geom);
+
+ constexpr auto isHFnose = std::is_same::value;
+ constexpr int nEtaBin = TILES::constants_type_t::nEtaBins;
+ constexpr int nPhiBin = TILES::constants_type_t::nPhiBins;
+
+ // We need to partition the two sides of the HGCAL detector
+ auto lastLayerPerSide = static_cast(rhtools_.lastLayer(isHFnose)) - 1;
+ unsigned int maxLayer = 2 * lastLayerPerSide - 1;
+ std::vector fjInputs;
+ fjInputs.clear();
+ for (unsigned int currentLayer = 0; currentLayer <= maxLayer; ++currentLayer) {
+ if (currentLayer == lastLayerPerSide) {
+ buildJetAndTracksters(fjInputs, result);
+ }
+ const auto &tileOnLayer = input.tiles[currentLayer];
+ for (int ieta = 0; ieta <= nEtaBin; ++ieta) {
+ auto offset = ieta * nPhiBin;
+ if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Advanced) {
+ edm::LogVerbatim("PatternRecogntionbyFastJet") << "offset: " << offset;
+ }
+ for (int iphi = 0; iphi <= nPhiBin; ++iphi) {
+ if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Advanced) {
+ edm::LogVerbatim("PatternRecogntionbyFastJet") << "iphi: " << iphi;
+ edm::LogVerbatim("PatternRecogntionbyFastJet") << "Entries in tileBin: " << tileOnLayer[offset + iphi].size();
+ }
+ for (auto clusterIdx : tileOnLayer[offset + iphi]) {
+ // Skip masked layer clusters
+ if (input.mask[clusterIdx] == 0.) {
+ if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Advanced) {
+ edm::LogVerbatim("PatternRecogntionbyFastJet") << "Skipping masked layerIdx " << clusterIdx;
+ }
+ continue;
+ }
+ // Should we correct for the position of the PV?
+ auto const &cl = input.layerClusters[clusterIdx];
+ math::XYZVector direction(cl.x(), cl.y(), cl.z());
+ direction = direction.Unit();
+ direction *= cl.energy();
+ auto fpj = fastjet::PseudoJet(direction.X(), direction.Y(), direction.Z(), cl.energy());
+ 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
+
+ // Collect the jet from the other side wrt to the one taken care of inside the main loop above.
+ buildJetAndTracksters(fjInputs, result);
+
+ ticl::assignPCAtoTracksters(result,
+ input.layerClusters,
+ input.layerClustersTime,
+ rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z());
+
+ // run energy regression and ID
+ energyRegressionAndID(input.layerClusters, result);
+ if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Basic) {
+ for (auto const &t : result) {
+ edm::LogVerbatim("PatternRecogntionbyFastJet") << "Barycenter: " << t.barycenter();
+ edm::LogVerbatim("PatternRecogntionbyFastJet") << "LCs: " << t.vertices().size();
+ edm::LogVerbatim("PatternRecogntionbyFastJet") << "Energy: " << t.raw_energy();
+ edm::LogVerbatim("PatternRecogntionbyFastJet") << "Regressed: " << t.regressed_energy();
+ }
+ }
+}
+
+template
+void PatternRecognitionbyFastJet::energyRegressionAndID(const std::vector &layerClusters,
+ 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) treshold. 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();
+ }
+ }
+}
+
+template
+void PatternRecognitionbyFastJet::fillPSetDescription(edm::ParameterSetDescription &iDesc) {
+ 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);
+}
+
+template class ticl::PatternRecognitionbyFastJet;
diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h
new file mode 100644
index 0000000000000..53c9279a31dec
--- /dev/null
+++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h
@@ -0,0 +1,51 @@
+// Author: Marco Rovere - marco.rovere@cern.ch
+// Date: 10/2021
+
+#ifndef __RecoHGCal_TICL_PRbyFASTJET_H__
+#define __RecoHGCal_TICL_PRbyFASTJET_H__
+#include // unique_ptr
+#include "RecoHGCal/TICL/interface/PatternRecognitionAlgoBase.h"
+#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h"
+
+// fwd declaration
+
+namespace fastjet {
+ class PseudoJet;
+};
+
+namespace ticl {
+ template
+ class PatternRecognitionbyFastJet final : public PatternRecognitionAlgoBaseT {
+ public:
+ PatternRecognitionbyFastJet(const edm::ParameterSet& conf, const CacheBase* cache, edm::ConsumesCollector);
+ ~PatternRecognitionbyFastJet() override = default;
+
+ void makeTracksters(const typename PatternRecognitionAlgoBaseT::Inputs& input,
+ std::vector& result,
+ std::unordered_map>& seedToTracksterAssociation) override;
+
+ void energyRegressionAndID(const std::vector& layerClusters, std::vector& result);
+
+ static void fillPSetDescription(edm::ParameterSetDescription& iDesc);
+
+ private:
+ 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_;
+
+ hgcal::RecHitTools rhtools_;
+ tensorflow::Session* eidSession_;
+
+ static const int eidNFeatures_ = 3;
+
+ void buildJetAndTracksters(std::vector&, std::vector&);
+ };
+
+} // namespace ticl
+#endif
diff --git a/RecoHGCal/TICL/plugins/TrackstersProducer.cc b/RecoHGCal/TICL/plugins/TrackstersProducer.cc
index 955af3572dc95..3b126143f91f4 100644
--- a/RecoHGCal/TICL/plugins/TrackstersProducer.cc
+++ b/RecoHGCal/TICL/plugins/TrackstersProducer.cc
@@ -135,13 +135,18 @@ void TrackstersProducer::fillDescriptions(edm::ConfigurationDescriptions& descri
// CA Plugin
edm::ParameterSetDescription pluginDesc;
pluginDesc.addNode(edm::PluginDescription("type", "CA", true));
-
- // CLUE3D Plugin
desc.add("pluginPatternRecognitionByCA", pluginDesc);
+ //
+ // CLUE3D Plugin
edm::ParameterSetDescription pluginDescClue3D;
pluginDescClue3D.addNode(edm::PluginDescription("type", "CLUE3D", true));
desc.add("pluginPatternRecognitionByCLUE3D", pluginDescClue3D);
+ // FastJet Plugin
+ edm::ParameterSetDescription pluginDescFastJet;
+ pluginDescFastJet.addNode(edm::PluginDescription("type", "FastJet", true));
+ desc.add("pluginPatternRecognitionByFastJet", pluginDescFastJet);
+
descriptions.add("trackstersProducer", desc);
}
diff --git a/RecoHGCal/TICL/python/FastJetStep_cff.py b/RecoHGCal/TICL/python/FastJetStep_cff.py
new file mode 100644
index 0000000000000..55a6745ddd1ee
--- /dev/null
+++ b/RecoHGCal/TICL/python/FastJetStep_cff.py
@@ -0,0 +1,32 @@
+import FWCore.ParameterSet.Config as cms
+
+from RecoHGCal.TICL.TICLSeedingRegions_cff import ticlSeedingGlobal, ticlSeedingGlobalHFNose
+from RecoHGCal.TICL.trackstersProducer_cfi import trackstersProducer as _trackstersProducer
+from RecoHGCal.TICL.filteredLayerClustersProducer_cfi import filteredLayerClustersProducer as _filteredLayerClustersProducer
+from RecoHGCal.TICL.multiClustersFromTrackstersProducer_cfi import multiClustersFromTrackstersProducer as _multiClustersFromTrackstersProducer
+
+# CLUSTER FILTERING/MASKING
+
+filteredLayerClustersFastJet = _filteredLayerClustersProducer.clone(
+ clusterFilter = "ClusterFilterByAlgoAndSize",
+ min_cluster_size = 3, # inclusive
+ algo_number = 8,
+ iteration_label = "FastJet"
+)
+
+# PATTERN RECOGNITION
+
+ticlTrackstersFastJet = _trackstersProducer.clone(
+ filtered_mask = "filteredLayerClustersFastJet:FastJet",
+ seeding_regions = "ticlSeedingGlobal",
+ itername = "FastJet",
+ patternRecognitionBy = "FastJet",
+ pluginPatternRecognitionByFastJet = dict (
+ algo_verbosity = 2
+ )
+)
+
+ticlFastJetStepTask = cms.Task(ticlSeedingGlobal
+ ,filteredLayerClustersFastJet
+ ,ticlTrackstersFastJet)
+
diff --git a/RecoHGCal/TICL/python/iterativeTICL_cff.py b/RecoHGCal/TICL/python/iterativeTICL_cff.py
index 1cfe7e953896c..80d660cfdbfb5 100644
--- a/RecoHGCal/TICL/python/iterativeTICL_cff.py
+++ b/RecoHGCal/TICL/python/iterativeTICL_cff.py
@@ -1,5 +1,6 @@
import FWCore.ParameterSet.Config as cms
+from RecoHGCal.TICL.FastJetStep_cff import *
from RecoHGCal.TICL.CLUE3DHighStep_cff import *
from RecoHGCal.TICL.CLUE3DLowStep_cff import *
from RecoHGCal.TICL.MIPStep_cff import *
@@ -31,6 +32,9 @@
from Configuration.ProcessModifiers.clue3D_cff import clue3D
clue3D.toModify(ticlIterationsTask, func=lambda x : x.add(ticlCLUE3DHighStepTask,ticlCLUE3DLowStepTask))
+from Configuration.ProcessModifiers.fastJetTICL_cff import fastJetTICL
+fastJetTICL.toModify(ticlIterationsTask, func=lambda x : x.add(ticlFastJetStepTask))
+
ticlIterLabels = [_step.itername.value() for _iteration in ticlIterationsTask for _step in _iteration if (_step._TypedParameterizable__type == "TrackstersProducer")]
iterTICLTask = cms.Task(ticlLayerTileTask