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