diff --git a/DataFormats/HGCalReco/interface/Trackster.h b/DataFormats/HGCalReco/interface/Trackster.h index 28e2424a81944..16f9bc1fb8a14 100644 --- a/DataFormats/HGCalReco/interface/Trackster.h +++ b/DataFormats/HGCalReco/interface/Trackster.h @@ -114,7 +114,7 @@ namespace ticl { p = *(probs++); } } - inline void setIdProbability(ParticleType type, float value) { id_probabilities_[int(type)] = 1.f; } + inline void setIdProbability(ParticleType type, float value) { id_probabilities_[int(type)] = value; } inline const Trackster::IterationIndex ticlIteration() const { return (IterationIndex)iterationIndex_; } inline const std::vector &vertices() const { return vertices_; } diff --git a/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py b/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py index 7e0076bb947bb..62ae794e85ecc 100644 --- a/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py +++ b/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py @@ -3,6 +3,7 @@ #AOD content TICL_AOD = cms.PSet( + # 13/04/2021 Felice: MultiClusters will be deprecated soon outputCommands = cms.untracked.vstring( 'keep *_ticlMultiClustersFromTrackstersEM_*_*', 'keep *_ticlMultiClustersFromTrackstersHAD_*_*', @@ -10,6 +11,7 @@ 'keep *_ticlMultiClustersFromTrackstersTrkEM_*_*', 'keep *_ticlMultiClustersFromTrackstersMIP_*_*', 'keep *_ticlMultiClustersFromTrackstersMerge_*_*', + 'keep *_ticlMultiClustersFromSimTracksters_*_*', ) ) @@ -35,6 +37,7 @@ # FEVT Content TICL_FEVT = cms.PSet( outputCommands = cms.untracked.vstring( + 'keep *_ticlSimTracksters_*_*', ) ) TICL_FEVT.outputCommands.extend(TICL_RECO.outputCommands) diff --git a/RecoHGCal/TICL/plugins/BuildFile.xml b/RecoHGCal/TICL/plugins/BuildFile.xml index 00c267848b23e..c3b923786d3f3 100644 --- a/RecoHGCal/TICL/plugins/BuildFile.xml +++ b/RecoHGCal/TICL/plugins/BuildFile.xml @@ -1,18 +1,36 @@ - - - - - - + + + - + + + + + - + + + + + + + + + + + + + + + + + + diff --git a/RecoHGCal/TICL/plugins/TrackstersFromSimClustersProducer.cc b/RecoHGCal/TICL/plugins/TrackstersFromSimClustersProducer.cc new file mode 100644 index 0000000000000..3b0a75ee1a283 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TrackstersFromSimClustersProducer.cc @@ -0,0 +1,151 @@ +// Author: Felice Pantaleo - felice.pantaleo@cern.ch +// Date: 02/2021 + +// user include files + +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include "DataFormats/CaloRecHit/interface/CaloCluster.h" +#include "DataFormats/ParticleFlowReco/interface/PFCluster.h" + +#include "DataFormats/HGCalReco/interface/Trackster.h" + +#include "DataFormats/Common/interface/ValueMap.h" +#include "SimDataFormats/Associations/interface/LayerClusterToSimClusterAssociator.h" +#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" + +#include "TrackstersPCA.h" +#include +#include +#include +using namespace ticl; + +namespace { + Trackster::ParticleType tracksterParticleTypeFromPdgId(int pdgId, int charge) { + if (pdgId == 111) { + return Trackster::ParticleType::neutral_pion; + } else { + pdgId = std::abs(pdgId); + if (pdgId == 22) { + return Trackster::ParticleType::photon; + } else if (pdgId == 11) { + return Trackster::ParticleType::electron; + } else if (pdgId == 13) { + return Trackster::ParticleType::muon; + } else { + bool isHadron = (pdgId > 100 and pdgId < 900) or (pdgId > 1000 and pdgId < 9000); + if (isHadron) { + if (charge != 0) { + return Trackster::ParticleType::charged_hadron; + } else { + return Trackster::ParticleType::neutral_hadron; + } + } else { + return Trackster::ParticleType::unknown; + } + } + } + } +} // namespace + +class TrackstersFromSimClustersProducer : public edm::stream::EDProducer<> { +public: + explicit TrackstersFromSimClustersProducer(const edm::ParameterSet&); + ~TrackstersFromSimClustersProducer() override {} + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + + void produce(edm::Event&, const edm::EventSetup&) override; + +private: + std::string detector_; + const bool doNose_ = false; + const edm::EDGetTokenT> clusters_token_; + const edm::EDGetTokenT>> clustersTime_token_; + const edm::EDGetTokenT> filtered_layerclusters_mask_token_; + + edm::EDGetTokenT> simclusters_token_; + + edm::InputTag associatorLayerClusterSimCluster_; + edm::EDGetTokenT associatorMapSimToReco_token_; + edm::ESGetToken geom_token_; + hgcal::RecHitTools rhtools_; +}; +DEFINE_FWK_MODULE(TrackstersFromSimClustersProducer); + +TrackstersFromSimClustersProducer::TrackstersFromSimClustersProducer(const edm::ParameterSet& ps) + : detector_(ps.getParameter("detector")), + doNose_(detector_ == "HFNose"), + clusters_token_(consumes>(ps.getParameter("layer_clusters"))), + clustersTime_token_( + consumes>>(ps.getParameter("time_layerclusters"))), + filtered_layerclusters_mask_token_(consumes>(ps.getParameter("filtered_mask"))), + simclusters_token_(consumes>(ps.getParameter("simclusters"))), + associatorLayerClusterSimCluster_(ps.getUntrackedParameter("layerClusterSimClusterAssociator")), + associatorMapSimToReco_token_( + consumes(associatorLayerClusterSimCluster_)), + geom_token_(esConsumes()) { + produces>(); + produces>(); +} + +void TrackstersFromSimClustersProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // hgcalMultiClusters + edm::ParameterSetDescription desc; + desc.add("detector", "HGCAL"); + desc.add("layer_clusters", edm::InputTag("hgcalLayerClusters")); + desc.add("time_layerclusters", edm::InputTag("hgcalLayerClusters", "timeLayerCluster")); + desc.add("filtered_mask", edm::InputTag("filteredLayerClustersSimTracksters", "ticlSimTracksters")); + desc.add("simclusters", edm::InputTag("mix", "MergedCaloTruth")); + desc.addUntracked("layerClusterSimClusterAssociator", + edm::InputTag("layerClusterSimClusterAssociationProducer")); + descriptions.add("trackstersFromSimClustersProducer", desc); +} + +void TrackstersFromSimClustersProducer::produce(edm::Event& evt, const edm::EventSetup& es) { + auto result = std::make_unique>(); + auto output_mask = std::make_unique>(); + const auto& layerClusters = evt.get(clusters_token_); + const auto& layerClustersTimes = evt.get(clustersTime_token_); + const auto& inputClusterMask = evt.get(filtered_layerclusters_mask_token_); + output_mask->resize(layerClusters.size(), 1.f); + + const auto& simclusters = evt.get(simclusters_token_); + const auto& simToRecoColl = evt.get(associatorMapSimToReco_token_); + + const auto& geom = es.getData(geom_token_); + rhtools_.setGeometry(geom); + auto num_simclusters = simclusters.size(); + result->reserve(num_simclusters); + for (const auto& [key, values] : simToRecoColl) { + auto const& sc = *(key); + auto simClusterIndex = &sc - &simclusters[0]; + Trackster tmpTrackster; + tmpTrackster.zeroProbabilities(); + tmpTrackster.vertices().reserve(values.size()); + tmpTrackster.vertex_multiplicity().reserve(values.size()); + + for (auto const& [lc, energyScorePair] : values) { + if (inputClusterMask[lc.index()] > 0) { + tmpTrackster.vertices().push_back(lc.index()); + double fraction = energyScorePair.first / lc->energy(); + (*output_mask)[lc.index()] -= fraction; + tmpTrackster.vertex_multiplicity().push_back(static_cast(std::clamp(1. / fraction, 0., 255.))); + } + } + tmpTrackster.setIdProbability(tracksterParticleTypeFromPdgId(sc.pdgId(), sc.charge()), 1.f); + tmpTrackster.setSeed(key.id(), simClusterIndex); + result->emplace_back(tmpTrackster); + } + ticl::assignPCAtoTracksters( + *result, layerClusters, layerClustersTimes, rhtools_.getPositionLayer(rhtools_.lastLayerEE(doNose_)).z()); + evt.put(std::move(result)); + evt.put(std::move(output_mask)); +} diff --git a/RecoHGCal/TICL/python/SimTracksters_cff.py b/RecoHGCal/TICL/python/SimTracksters_cff.py new file mode 100644 index 0000000000000..8aa9d1a9fd8c7 --- /dev/null +++ b/RecoHGCal/TICL/python/SimTracksters_cff.py @@ -0,0 +1,31 @@ +import FWCore.ParameterSet.Config as cms + +from RecoHGCal.TICL.trackstersFromSimClustersProducer_cfi import trackstersFromSimClustersProducer as _trackstersFromSimClustersProducer +from RecoHGCal.TICL.multiClustersFromTrackstersProducer_cfi import multiClustersFromTrackstersProducer as _multiClustersFromTrackstersProducer +from RecoHGCal.TICL.filteredLayerClustersProducer_cfi import filteredLayerClustersProducer as _filteredLayerClustersProducer + + +# CA - PATTERN RECOGNITION + + +filteredLayerClustersSimTracksters = _filteredLayerClustersProducer.clone( + clusterFilter = "ClusterFilterByAlgoAndSize", + algo_number = 8, + min_cluster_size = 0, # inclusive + iteration_label = "ticlSimTracksters" +) + +ticlSimTracksters = _trackstersFromSimClustersProducer.clone( +) + +from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 +premix_stage2.toModify(ticlSimTracksters, + simclusters = "mixData:MergedCaloTruth" +) + +ticlMultiClustersFromSimTracksters = _multiClustersFromTrackstersProducer.clone( + Tracksters = "ticlSimTracksters" +) + +ticlSimTrackstersTask = cms.Task(filteredLayerClustersSimTracksters, ticlSimTracksters, ticlMultiClustersFromSimTracksters) + diff --git a/RecoHGCal/TICL/python/iterativeTICL_cff.py b/RecoHGCal/TICL/python/iterativeTICL_cff.py index 3fdf588e188a5..7ea82224b5611 100644 --- a/RecoHGCal/TICL/python/iterativeTICL_cff.py +++ b/RecoHGCal/TICL/python/iterativeTICL_cff.py @@ -5,6 +5,7 @@ from RecoHGCal.TICL.TrkStep_cff import * from RecoHGCal.TICL.EMStep_cff import * from RecoHGCal.TICL.HADStep_cff import * + from RecoHGCal.TICL.ticlLayerTileProducer_cfi import ticlLayerTileProducer from RecoHGCal.TICL.pfTICLProducer_cfi import pfTICLProducer as _pfTICLProducer from RecoHGCal.TICL.trackstersMergeProducer_cfi import trackstersMergeProducer as _trackstersMergeProducer diff --git a/SimDataFormats/Associations/interface/LayerClusterToSimClusterAssociator.h b/SimDataFormats/Associations/interface/LayerClusterToSimClusterAssociator.h index a5509353f22a8..094db05e3ba5d 100644 --- a/SimDataFormats/Associations/interface/LayerClusterToSimClusterAssociator.h +++ b/SimDataFormats/Associations/interface/LayerClusterToSimClusterAssociator.h @@ -19,8 +19,11 @@ namespace hgcal { LayerClusterToSimClusterAssociator() = default; LayerClusterToSimClusterAssociator(LayerClusterToSimClusterAssociator &&) = default; LayerClusterToSimClusterAssociator &operator=(LayerClusterToSimClusterAssociator &&) = default; - ~LayerClusterToSimClusterAssociator() = default; + LayerClusterToSimClusterAssociator(const LayerClusterToSimClusterAssociator &) = delete; // stop default + ~LayerClusterToSimClusterAssociator() = default; + const LayerClusterToSimClusterAssociator &operator=(const LayerClusterToSimClusterAssociator &) = + delete; // stop default // ---------- const member functions --------------------- /// Associate a LayerCluster to SimClusters hgcal::RecoToSimCollectionWithSimClusters associateRecoToSim(const edm::Handle &cCCH, @@ -35,11 +38,6 @@ namespace hgcal { } private: - LayerClusterToSimClusterAssociator(const LayerClusterToSimClusterAssociator &) = delete; // stop default - - const LayerClusterToSimClusterAssociator &operator=(const LayerClusterToSimClusterAssociator &) = - delete; // stop default - // ---------- member data -------------------------------- std::unique_ptr m_impl; }; diff --git a/Validation/Configuration/python/globalValidation_cff.py b/Validation/Configuration/python/globalValidation_cff.py index 8ea73c681b963..cf25942c176d7 100644 --- a/Validation/Configuration/python/globalValidation_cff.py +++ b/Validation/Configuration/python/globalValidation_cff.py @@ -198,7 +198,7 @@ ) globalValidationHGCal = cms.Sequence(hgcalValidation) -globalPrevalidationHGCal = cms.Sequence(hgcalAssociators) +globalPrevalidationHGCal = cms.Sequence(hgcalAssociators, ticlSimTrackstersTask) globalValidationMTD = cms.Sequence() diff --git a/Validation/Configuration/python/hgcalSimValid_cff.py b/Validation/Configuration/python/hgcalSimValid_cff.py index b0c5a299ccf7c..3ac4142386bb0 100644 --- a/Validation/Configuration/python/hgcalSimValid_cff.py +++ b/Validation/Configuration/python/hgcalSimValid_cff.py @@ -10,6 +10,7 @@ from Validation.HGCalValidation.digiValidation_cff import * from Validation.HGCalValidation.rechitValidation_cff import * from Validation.HGCalValidation.hgcalHitValidation_cfi import * +from RecoHGCal.TICL.SimTracksters_cff import * from Validation.HGCalValidation.HGCalValidator_cfi import hgcalValidator from Validation.RecoParticleFlow.PFJetValidation_cff import pfJetValidation1 as _hgcalPFJetValidation diff --git a/Validation/HGCalValidation/python/HGCalValidator_cfi.py b/Validation/HGCalValidation/python/HGCalValidator_cfi.py index fe55643a325dd..4f415db769eaa 100644 --- a/Validation/HGCalValidation/python/HGCalValidator_cfi.py +++ b/Validation/HGCalValidation/python/HGCalValidator_cfi.py @@ -11,8 +11,9 @@ from RecoHGCal.TICL.iterativeTICL_cff import ticlIterLabels, ticlIterLabelsMerge labelMcl = [cms.InputTag("ticlMultiClustersFromTracksters"+iteration) for iteration in ticlIterLabelsMerge] +labelMcl.extend(["ticlMultiClustersFromSimTracksters"]) lcInputMask = [cms.InputTag("ticlTracksters"+iteration) for iteration in ticlIterLabels] - +lcInputMask.extend(["ticlSimTracksters"]) hgcalValidator = DQMEDAnalyzer( "HGCalValidator", diff --git a/Validation/HGCalValidation/python/PostProcessorHGCAL_cfi.py b/Validation/HGCalValidation/python/PostProcessorHGCAL_cfi.py index ed181b75c5a5a..c138c5f07aa5d 100644 --- a/Validation/HGCalValidation/python/PostProcessorHGCAL_cfi.py +++ b/Validation/HGCalValidation/python/PostProcessorHGCAL_cfi.py @@ -35,6 +35,7 @@ eff_simclusters.extend(["merge_phi_layer{:02d} 'LayerCluster Merge Rate vs #phi Layer{:02d} in z-' NumMerge_LayerCluster_in_SimCluster_Phi_perlayer{:02d} Denom_LayerCluster_in_SimCluster_Phi_perlayer{:02d}".format(i, i%maxlayerzm+1, i, i) if (i