diff --git a/CommonTools/RecoAlgos/interface/MultiVectorManager.h b/CommonTools/RecoAlgos/interface/MultiVectorManager.h new file mode 100644 index 0000000000000..97e8a7285039c --- /dev/null +++ b/CommonTools/RecoAlgos/interface/MultiVectorManager.h @@ -0,0 +1,79 @@ +// Author: Felice Pantaleo (CERN), 2023, felice.pantaleo@cern.ch +#ifndef MultiVectorManager_h +#define MultiVectorManager_h + +#include +#include +#include +#include + +template +class MultiVectorManager { +public: + void addVector(const std::vector& vec) { + vectors.emplace_back(vec.begin(), vec.end()); + offsets.push_back(totalSize); + totalSize += vec.size(); + } + + T& operator[](size_t globalIndex) { + return const_cast(static_cast(this)->operator[](globalIndex)); + } + + const T& operator[](size_t globalIndex) const { + assert(globalIndex < totalSize && "Global index out of range"); + + auto it = std::upper_bound(offsets.begin(), offsets.end(), globalIndex); + size_t vectorIndex = std::distance(offsets.begin(), it) - 1; + size_t localIndex = globalIndex - offsets[vectorIndex]; + + return vectors[vectorIndex][localIndex]; + } + + size_t getGlobalIndex(size_t vectorIndex, size_t localIndex) const { + assert(vectorIndex < vectors.size() && "Vector index out of range"); + + const auto& vec = vectors[vectorIndex]; + assert(localIndex < vec.size() && "Local index out of range"); + + return offsets[vectorIndex] + localIndex; + } + + size_t size() const { return totalSize; } + + std::pair getVectorAndLocalIndex(size_t globalIndex) const { + assert(globalIndex < totalSize && "Global index out of range"); + + auto it = std::upper_bound(offsets.begin(), offsets.end(), globalIndex); + size_t vectorIndex = std::distance(offsets.begin(), it) - 1; + size_t localIndex = globalIndex - offsets[vectorIndex]; + + return {vectorIndex, localIndex}; + } + + class Iterator { + public: + Iterator(const MultiVectorManager& manager, size_t index) : manager(manager), currentIndex(index) {} + + bool operator!=(const Iterator& other) const { return currentIndex != other.currentIndex; } + + T& operator*() const { return const_cast(manager[currentIndex]); } + + void operator++() { ++currentIndex; } + + private: + const MultiVectorManager& manager; + size_t currentIndex; + }; + + Iterator begin() const { return Iterator(*this, 0); } + + Iterator end() const { return Iterator(*this, totalSize); } + +private: + std::vector> vectors; + std::vector offsets; + size_t totalSize = 0; +}; + +#endif diff --git a/Configuration/EventContent/python/EventContent_cff.py b/Configuration/EventContent/python/EventContent_cff.py index 65abe1059971f..54cca52eaebc8 100644 --- a/Configuration/EventContent/python/EventContent_cff.py +++ b/Configuration/EventContent/python/EventContent_cff.py @@ -568,6 +568,8 @@ def SwapKeepAndDrop(l): outputCommands = FEVTEventContent.outputCommands + RecoLocalFastTimeFEVT.outputCommands) phase2_timing_layer.toModify(FEVTEventContent, outputCommands = FEVTEventContent.outputCommands + RecoMTDFEVT.outputCommands) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(FEVTEventContent, outputCommands=FEVTEventContent.outputCommands+TICLv5_FEVT.outputCommands) FEVTHLTALLEventContent = cms.PSet( outputCommands = cms.untracked.vstring('drop *'), @@ -651,6 +653,8 @@ def SwapKeepAndDrop(l): 'keep *_hltSiStripClusters2ApproxClusters_*_*', 'keep DetIds_hltSiStripRawToDigi_*_*' ]) + +ticl_v5.toModify(FEVTDEBUGEventContent, outputCommands=FEVTDEBUGEventContent.outputCommands+TICLv5_FEVT.outputCommands) # # # FEVTDEBUGHLT Data Tier definition diff --git a/Configuration/ProcessModifiers/python/ticl_v3_cff.py b/Configuration/ProcessModifiers/python/ticl_v3_cff.py deleted file mode 100644 index 77f0f70c70404..0000000000000 --- a/Configuration/ProcessModifiers/python/ticl_v3_cff.py +++ /dev/null @@ -1,5 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -# This modifier is for running TICL v3. - -ticl_v3 = cms.Modifier() diff --git a/Configuration/ProcessModifiers/python/ticl_v5_cff.py b/Configuration/ProcessModifiers/python/ticl_v5_cff.py new file mode 100644 index 0000000000000..1bb678b4451ac --- /dev/null +++ b/Configuration/ProcessModifiers/python/ticl_v5_cff.py @@ -0,0 +1,5 @@ +import FWCore.ParameterSet.Config as cms + +# This modifier is for running TICL v5. + +ticl_v5 = cms.Modifier() diff --git a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py index a5b2fa489346a..d29bbb0485238 100644 --- a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py +++ b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py @@ -689,7 +689,7 @@ def condition(self, fragment, stepList, key, hasHarvest): upgradeWFs['ticl_FastJet'].step3 = {'--procModifiers': 'fastJetTICL'} upgradeWFs['ticl_FastJet'].step4 = {'--procModifiers': 'fastJetTICL'} -class UpgradeWorkflow_ticl_v3(UpgradeWorkflow): +class UpgradeWorkflow_ticl_v5(UpgradeWorkflow): def setup_(self, step, stepName, stepDict, k, properties): if 'RecoGlobal' in step: stepDict[stepName][k] = merge([self.step3, stepDict[step][k]]) @@ -697,7 +697,7 @@ def setup_(self, step, stepName, stepDict, k, properties): stepDict[stepName][k] = merge([self.step4, stepDict[step][k]]) def condition(self, fragment, stepList, key, hasHarvest): return (fragment=="TTbar_14TeV" or 'CloseByP' in fragment or 'Eta1p7_2p7' in fragment) and '2026' in key -upgradeWFs['ticl_v3'] = UpgradeWorkflow_ticl_v3( +upgradeWFs['ticl_v5'] = UpgradeWorkflow_ticl_v5( steps = [ 'RecoGlobal', 'HARVESTGlobal' @@ -706,12 +706,11 @@ def condition(self, fragment, stepList, key, hasHarvest): 'RecoGlobal', 'HARVESTGlobal' ], - suffix = '_ticl_v3', + suffix = '_ticl_v5', offset = 0.203, ) -upgradeWFs['ticl_v3'].step3 = {'--procModifiers': 'ticl_v3'} -upgradeWFs['ticl_v3'].step4 = {'--procModifiers': 'ticl_v3'} - +upgradeWFs['ticl_v5'].step3 = {'--procModifiers': 'ticl_v5'} +upgradeWFs['ticl_v5'].step4 = {'--procModifiers': 'ticl_v5'} # Track DNN workflows class UpgradeWorkflow_trackdnn(UpgradeWorkflow): diff --git a/DataFormats/CaloRecHit/interface/CaloCluster.h b/DataFormats/CaloRecHit/interface/CaloCluster.h index 9606805e4fb2a..c2c4dc095fc19 100644 --- a/DataFormats/CaloRecHit/interface/CaloCluster.h +++ b/DataFormats/CaloRecHit/interface/CaloCluster.h @@ -39,6 +39,7 @@ namespace reco { particleFlow = 5, hgcal_em = 6, hgcal_had = 7, + hgcal_scintillator = 8, hfnose = 9, undefined = 1000 }; diff --git a/DataFormats/GeometryVector/src/classes.h b/DataFormats/GeometryVector/src/classes.h index e02c13019c150..87a4718785891 100644 --- a/DataFormats/GeometryVector/src/classes.h +++ b/DataFormats/GeometryVector/src/classes.h @@ -1,3 +1,5 @@ +#include "DataFormats/Common/interface/ValueMap.h" +#include "DataFormats/Common/interface/Wrapper.h" #include "DataFormats/GeometryVector/interface/Phi.h" namespace { Geom::Phi dummy; diff --git a/DataFormats/GeometryVector/src/classes_def.xml b/DataFormats/GeometryVector/src/classes_def.xml index 3fc5d0737608e..454e562fa177b 100644 --- a/DataFormats/GeometryVector/src/classes_def.xml +++ b/DataFormats/GeometryVector/src/classes_def.xml @@ -88,6 +88,8 @@ + + diff --git a/DataFormats/HGCalReco/BuildFile.xml b/DataFormats/HGCalReco/BuildFile.xml index ea59e3506573a..c1cfec3d136b7 100644 --- a/DataFormats/HGCalReco/BuildFile.xml +++ b/DataFormats/HGCalReco/BuildFile.xml @@ -1,5 +1,7 @@ + + diff --git a/DataFormats/HGCalReco/interface/MtdHostCollection.h b/DataFormats/HGCalReco/interface/MtdHostCollection.h new file mode 100644 index 0000000000000..49c137c53f498 --- /dev/null +++ b/DataFormats/HGCalReco/interface/MtdHostCollection.h @@ -0,0 +1,12 @@ +#ifndef DataFormats_HGCalReco_MtdHostCollection_h +#define DataFormats_HGCalReco_MtdHostCollection_h + +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/HGCalReco/interface/MtdSoA.h" + +// MtdSoA in host memory +using MtdHostCollection = PortableHostCollection; +using MtdHostCollectionView = PortableHostCollection::View; +using MtdHostCollectionConstView = PortableHostCollection::ConstView; + +#endif diff --git a/DataFormats/HGCalReco/interface/MtdSoA.h b/DataFormats/HGCalReco/interface/MtdSoA.h new file mode 100644 index 0000000000000..9776224a11f8a --- /dev/null +++ b/DataFormats/HGCalReco/interface/MtdSoA.h @@ -0,0 +1,27 @@ +#ifndef DataFormats_HGCalReco_MtdSoA_h +#define DataFormats_HGCalReco_MtdSoA_h + +#include "DataFormats/SoATemplate/interface/SoALayout.h" + +GENERATE_SOA_LAYOUT(MtdSoALayout, + SOA_COLUMN(int32_t, trackAsocMTD), + SOA_COLUMN(float, time0), + SOA_COLUMN(float, time0Err), + SOA_COLUMN(float, time), + SOA_COLUMN(float, timeErr), + SOA_COLUMN(float, MVAquality), + SOA_COLUMN(float, pathLength), + SOA_COLUMN(float, beta), + SOA_COLUMN(float, posInMTD_x), + SOA_COLUMN(float, posInMTD_y), + SOA_COLUMN(float, posInMTD_z), + SOA_COLUMN(float, momentumWithMTD), + SOA_COLUMN(float, probPi), + SOA_COLUMN(float, probK), + SOA_COLUMN(float, probP)) + +using MtdSoA = MtdSoALayout<>; +using MtdSoAView = MtdSoA::View; +using MtdSoAConstView = MtdSoA::ConstView; + +#endif diff --git a/DataFormats/HGCalReco/interface/TICLCandidate.h b/DataFormats/HGCalReco/interface/TICLCandidate.h index 25cedc49df025..8752c9bf27a15 100644 --- a/DataFormats/HGCalReco/interface/TICLCandidate.h +++ b/DataFormats/HGCalReco/interface/TICLCandidate.h @@ -7,6 +7,9 @@ #include "DataFormats/Math/interface/Point3D.h" #include "DataFormats/TrackReco/interface/Track.h" #include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "RecoHGCal/TICL/interface/commons.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" // A TICLCandidate is a lightweight physics object made from one or multiple Tracksters. @@ -15,23 +18,82 @@ class TICLCandidate : public reco::LeafCandidate { typedef ticl::Trackster::ParticleType ParticleType; TICLCandidate(Charge q, const LorentzVector& p4) - : LeafCandidate(q, p4), time_(0.f), timeError_(-1.f), rawEnergy_(0.f), idProbabilities_{} {} + : LeafCandidate(q, p4), idProbabilities_{}, time_(0.f), timeError_(-1.f), rawEnergy_(0.f) {} - TICLCandidate() : LeafCandidate(), time_(0.f), timeError_(-1.f), rawEnergy_(0.f), idProbabilities_{} {} + TICLCandidate() : LeafCandidate(), idProbabilities_{}, time_(0.f), timeError_(-1.f), rawEnergy_(0.f) {} TICLCandidate(const edm::Ptr& trackster) : LeafCandidate(), + tracksters_({trackster}), + idProbabilities_{}, time_(trackster->time()), timeError_(trackster->timeError()), - rawEnergy_(0.f), - tracksters_({trackster}), - idProbabilities_{} {} + MTDtime_{0.f}, + MTDtimeError_{-1.f}, + rawEnergy_(0.f) {} + + TICLCandidate(const edm::Ptr trackPtr, const edm::Ptr& tracksterPtr) + : LeafCandidate(), tracksters_{}, trackPtr_(trackPtr), time_(0.f), timeError_(-1.f) { + if (trackPtr_.isNull() and tracksterPtr.isNull()) + throw cms::Exception("NullPointerError") + << "TICLCandidate constructor: at least one between track and trackster must be valid"; + + if (tracksterPtr.isNonnull()) { + tracksters_.push_back(tracksterPtr); + auto const& trackster = tracksters_[0].get(); + idProbabilities_ = trackster->id_probabilities(); + if (trackPtr_.isNonnull()) { + auto pdgId = trackster->isHadronic() ? 211 : 11; + auto const& tk = trackPtr_.get(); + setPdgId(pdgId * tk->charge()); + setCharge(tk->charge()); + rawEnergy_ = trackster->raw_energy(); + auto const& regrE = trackster->regressed_energy(); + math::XYZTLorentzVector p4(regrE * tk->momentum().unit().x(), + regrE * tk->momentum().unit().y(), + regrE * tk->momentum().unit().z(), + regrE); + setP4(p4); + + } else { + auto pdgId = trackster->isHadronic() ? 130 : 22; + setPdgId(pdgId); + setCharge(0); + rawEnergy_ = trackster->raw_energy(); + const float& regrE = trackster->regressed_energy(); + math::XYZTLorentzVector p4(regrE * trackster->barycenter().unit().x(), + regrE * trackster->barycenter().unit().y(), + regrE * trackster->barycenter().unit().z(), + regrE); + setP4(p4); + } + } else { + //candidate from track only + auto const& tk = trackPtr_.get(); + setPdgId(211 * tk->charge()); + setCharge(tk->charge()); + const float energy = std::sqrt(tk->p() * tk->p() + ticl::mpion2); + setRawEnergy(energy); + math::PtEtaPhiMLorentzVector p4Polar(tk->pt(), tk->eta(), tk->phi(), ticl::mpion); + setP4(p4Polar); + } + } inline float time() const { return time_; } inline float timeError() const { return timeError_; } - void setTime(float time) { time_ = time; }; - void setTimeError(float timeError) { timeError_ = timeError; } + void setTime(float time, float timeError) { + time_ = time; + timeError_ = timeError; + }; + + inline float MTDtime() const { return MTDtime_; } + inline float MTDtimeError() const { return MTDtimeError_; } + + void setMTDTime(float time, float timeError) { + MTDtime_ = time; + MTDtimeError_ = timeError; + }; inline const edm::Ptr trackPtr() const { return trackPtr_; } void setTrackPtr(const edm::Ptr& trackPtr) { trackPtr_ = trackPtr; } @@ -65,17 +127,17 @@ class TICLCandidate : public reco::LeafCandidate { inline void setIdProbability(ParticleType type, float value) { idProbabilities_[int(type)] = value; } private: - float time_; - float timeError_; - edm::Ptr trackPtr_; - - float rawEnergy_; - // vector of Ptr so Tracksters can come from different collections // and there can be derived classes std::vector > tracksters_; - + edm::Ptr trackPtr_; // Since it contains multiple tracksters, duplicate the probability interface std::array idProbabilities_; + + float time_; + float timeError_; + float MTDtime_; + float MTDtimeError_; + float rawEnergy_; }; #endif diff --git a/DataFormats/HGCalReco/interface/TICLLayerTile.h b/DataFormats/HGCalReco/interface/TICLLayerTile.h index 6b56aa70fe607..b114b6268a751 100644 --- a/DataFormats/HGCalReco/interface/TICLLayerTile.h +++ b/DataFormats/HGCalReco/interface/TICLLayerTile.h @@ -12,9 +12,7 @@ class TICLLayerTileT { public: typedef T type; - void fill(double eta, double phi, unsigned int layerClusterId) { - tile_[globalBin(eta, phi)].push_back(layerClusterId); - } + void fill(float eta, float phi, unsigned int layerClusterId) { tile_[globalBin(eta, phi)].push_back(layerClusterId); } int etaBin(float eta) const { constexpr float etaRange = T::maxEta - T::minEta; @@ -62,7 +60,7 @@ class TICLLayerTileT { int globalBin(int etaBin, int phiBin) const { return phiBin + etaBin * T::nPhiBins; } - int globalBin(double eta, double phi) const { return phiBin(phi) + etaBin(eta) * T::nPhiBins; } + int globalBin(float eta, float phi) const { return phiBin(phi) + etaBin(eta) * T::nPhiBins; } void clear() { auto nBins = T::nEtaBins * T::nPhiBins; @@ -96,7 +94,7 @@ class TICLGenericTile { // numbering is not handled internally. It is the user's responsibility to // properly use and consistently access it here. const auto& operator[](int index) const { return tiles_[index]; } - void fill(int index, double eta, double phi, unsigned int objectId) { tiles_[index].fill(eta, phi, objectId); } + void fill(int index, float eta, float phi, unsigned int objectId) { tiles_[index].fill(eta, phi, objectId); } private: T tiles_; diff --git a/DataFormats/HGCalReco/interface/Trackster.h b/DataFormats/HGCalReco/interface/Trackster.h index 648442584f516..3bbdef6dcc595 100644 --- a/DataFormats/HGCalReco/interface/Trackster.h +++ b/DataFormats/HGCalReco/interface/Trackster.h @@ -40,12 +40,13 @@ namespace ticl { : barycenter_({0.f, 0.f, 0.f}), regressed_energy_(0.f), raw_energy_(0.f), + boundTime_(0.f), time_(0.f), timeError_(-1.f), - raw_em_energy_(0.f), id_probabilities_{}, raw_pt_(0.f), raw_em_pt_(0.f), + raw_em_energy_(0.f), seedIndex_(-1), eigenvalues_{}, sigmas_{}, @@ -74,7 +75,26 @@ namespace ticl { inline void setBarycenter(Vector value) { barycenter_ = value; } inline void setTrackIdx(int index) { track_idx_ = index; } int trackIdx() const { return track_idx_; } + inline bool isHadronic(float th = 0.5f) const { + return id_probability(Trackster::ParticleType::photon) + id_probability(Trackster::ParticleType::electron) < th; + } + inline void mergeTracksters(const Trackster &other) { + *this += other; + + //remove duplicates + removeDuplicates(); + zeroProbabilities(); + } + + inline void mergeTracksters(const std::vector &others) { + for (auto &other : others) { + *this += other; + } + //remove duplicates + removeDuplicates(); + zeroProbabilities(); + } inline void fillPCAVariables(Eigen::Vector3d &eigenvalues, Eigen::Matrix3d &eigenvectors, Eigen::Vector3d &sigmas, @@ -118,6 +138,8 @@ namespace ticl { } inline void setIdProbability(ParticleType type, float value) { id_probabilities_[int(type)] = value; } + inline void setBoundaryTime(float t) { boundTime_ = t; }; + inline const Trackster::IterationIndex ticlIteration() const { return (IterationIndex)iterationIndex_; } inline const std::vector &vertices() const { return vertices_; } inline const unsigned int vertices(int index) const { return vertices_[index]; } @@ -133,6 +155,7 @@ namespace ticl { inline const float raw_em_energy() const { return raw_em_energy_; } inline const float raw_pt() const { return raw_pt_; } inline const float raw_em_pt() const { return raw_em_pt_; } + inline const float boundaryTime() const { return boundTime_; }; inline const Vector &barycenter() const { return barycenter_; } inline const std::array &eigenvalues() const { return eigenvalues_; } inline const std::array &eigenvectors() const { return eigenvectors_; } @@ -153,9 +176,9 @@ namespace ticl { float regressed_energy_; float raw_energy_; // -99, -1 if not available. ns units otherwise + float boundTime_; float time_; float timeError_; - float raw_em_energy_; // trackster ID probabilities std::array id_probabilities_; @@ -166,6 +189,7 @@ namespace ticl { std::vector vertex_multiplicity_; float raw_pt_; float raw_em_pt_; + float raw_em_energy_; // Product ID of the seeding collection used to create the Trackster. // For GlobalSeeding the ProductID is set to 0. For track-based seeding @@ -194,6 +218,37 @@ namespace ticl { // TICL iteration producing the trackster uint8_t iterationIndex_; + inline void removeDuplicates() { + auto vtx_sorted{vertices_}; + std::sort(std::begin(vtx_sorted), std::end(vtx_sorted)); + for (unsigned int iLC = 1; iLC < vtx_sorted.size(); ++iLC) { + if (vtx_sorted[iLC] == vtx_sorted[iLC - 1]) { + // Clean up duplicate LCs + const auto lcIdx = vtx_sorted[iLC]; + const auto firstEl = std::find(vertices_.begin(), vertices_.end(), lcIdx); + const auto firstPos = std::distance(std::begin(vertices_), firstEl); + auto iDup = std::find(std::next(firstEl), vertices_.end(), lcIdx); + while (iDup != vertices_.end()) { + vertex_multiplicity_.erase(vertex_multiplicity_.begin() + std::distance(std::begin(vertices_), iDup)); + vertices_.erase(iDup); + vertex_multiplicity_[firstPos] -= 1; + iDup = std::find(std::next(firstEl), vertices_.end(), lcIdx); + }; + } + } + } + inline void operator+=(const Trackster &other) { + // use getters on other + raw_energy_ += other.raw_energy(); + raw_em_energy_ += other.raw_em_energy(); + raw_pt_ += other.raw_pt(); + raw_em_pt_ += other.raw_em_pt(); + // add vertices and multiplicities + std::copy(std::begin(other.vertices()), std::end(other.vertices()), std::back_inserter(vertices_)); + std::copy(std::begin(other.vertex_multiplicity()), + std::end(other.vertex_multiplicity()), + std::back_inserter(vertex_multiplicity_)); + } }; typedef std::vector TracksterCollection; diff --git a/DataFormats/HGCalReco/src/classes.cc b/DataFormats/HGCalReco/src/classes.cc new file mode 100644 index 0000000000000..8274f7ff0ca66 --- /dev/null +++ b/DataFormats/HGCalReco/src/classes.cc @@ -0,0 +1,4 @@ +#include "DataFormats/Portable/interface/PortableHostCollectionReadRules.h" +#include "DataFormats/Portable/interface/PortableHostObjectReadRules.h" +#include "DataFormats/HGCalReco/interface/MtdHostCollection.h" +SET_PORTABLEHOSTCOLLECTION_READ_RULES(MtdHostCollection); diff --git a/DataFormats/HGCalReco/src/classes.h b/DataFormats/HGCalReco/src/classes.h index d871bfb485a71..51d53d433e05a 100644 --- a/DataFormats/HGCalReco/src/classes.h +++ b/DataFormats/HGCalReco/src/classes.h @@ -1,5 +1,7 @@ #include #include +#include "DataFormats/HGCalReco/interface/MtdSoA.h" +#include "DataFormats/HGCalReco/interface/MtdHostCollection.h" #include "DataFormats/HGCalReco/interface/Trackster.h" #include "DataFormats/HGCalReco/interface/TICLLayerTile.h" #include "DataFormats/HGCalReco/interface/TICLSeedingRegion.h" diff --git a/DataFormats/HGCalReco/src/classes_def.xml b/DataFormats/HGCalReco/src/classes_def.xml index 18c2cf05b934d..672af0b71bbe1 100644 --- a/DataFormats/HGCalReco/src/classes_def.xml +++ b/DataFormats/HGCalReco/src/classes_def.xml @@ -1,6 +1,7 @@ - + + @@ -49,10 +50,18 @@ - + + + + + + + + + diff --git a/DataFormats/WrappedStdDictionaries/src/classes_def.xml b/DataFormats/WrappedStdDictionaries/src/classes_def.xml index 3def4d8b7a5f5..b179ffd11dd41 100644 --- a/DataFormats/WrappedStdDictionaries/src/classes_def.xml +++ b/DataFormats/WrappedStdDictionaries/src/classes_def.xml @@ -41,6 +41,7 @@ + diff --git a/Fireworks/Calo/plugins/FWCaloClusterProxyBuilder.cc b/Fireworks/Calo/plugins/FWCaloClusterProxyBuilder.cc index 741521d1c75df..b0bca171d9658 100644 --- a/Fireworks/Calo/plugins/FWCaloClusterProxyBuilder.cc +++ b/Fireworks/Calo/plugins/FWCaloClusterProxyBuilder.cc @@ -115,13 +115,13 @@ void FWCaloClusterProxyBuilder::build(const reco::CaloCluster &iData, // HGCal if (iData.algo() == reco::CaloCluster::hgcal_em || iData.algo() == reco::CaloCluster::hgcal_had || - (type >= 8 && type <= 10)) { + iData.algo() == reco::CaloCluster::hgcal_scintillator || (type >= 8 && type <= 10)) { if (heatmap && hitmap->find(it->first) == hitmap->end()) continue; const bool z = (it->first >> 25) & 0x1; - // discard everything thats not at the side that we are intersted in + // discard everything thats not at the side that we are interested in if (((z_plus & z_minus) != 1) && (((z_plus | z_minus) == 0) || !(z == z_minus || z == !z_plus))) continue; diff --git a/HLTrigger/Configuration/python/HLT_75e33/modules/HGCalUncalibRecHitL1Seeded_cfi.py b/HLTrigger/Configuration/python/HLT_75e33/modules/HGCalUncalibRecHitL1Seeded_cfi.py index dedeaab780ffc..2d3970191a213 100644 --- a/HLTrigger/Configuration/python/HLT_75e33/modules/HGCalUncalibRecHitL1Seeded_cfi.py +++ b/HLTrigger/Configuration/python/HLT_75e33/modules/HGCalUncalibRecHitL1Seeded_cfi.py @@ -54,5 +54,6 @@ ), HGCHFNosedigiCollection = cms.InputTag("hfnoseDigis","HFNose"), HGCHFNosehitCollection = cms.string('HGCHFNoseUncalibRecHits'), + computeLocalTime = cms.bool(False), algo = cms.string('HGCalUncalibRecHitWorkerWeights') ) diff --git a/HLTrigger/Configuration/python/HLT_75e33/modules/HGCalUncalibRecHit_cfi.py b/HLTrigger/Configuration/python/HLT_75e33/modules/HGCalUncalibRecHit_cfi.py index 7038deed503ea..49e42633a9d32 100644 --- a/HLTrigger/Configuration/python/HLT_75e33/modules/HGCalUncalibRecHit_cfi.py +++ b/HLTrigger/Configuration/python/HLT_75e33/modules/HGCalUncalibRecHit_cfi.py @@ -55,5 +55,7 @@ ), HGCHFNosedigiCollection = cms.InputTag("hfnoseDigis","HFNose"), HGCHFNosehitCollection = cms.string('HGCHFNoseUncalibRecHits'), + computeLocalTime = cms.bool(False), algo = cms.string('HGCalUncalibRecHitWorkerWeights') ) + diff --git a/HLTrigger/Configuration/python/HLT_75e33/modules/ticlTrackstersCLUE3DHighL1Seeded_cfi.py b/HLTrigger/Configuration/python/HLT_75e33/modules/ticlTrackstersCLUE3DHighL1Seeded_cfi.py index a02d4675e0bd1..2d5e06aef40de 100644 --- a/HLTrigger/Configuration/python/HLT_75e33/modules/ticlTrackstersCLUE3DHighL1Seeded_cfi.py +++ b/HLTrigger/Configuration/python/HLT_75e33/modules/ticlTrackstersCLUE3DHighL1Seeded_cfi.py @@ -39,30 +39,77 @@ type = cms.string('CA') ), pluginPatternRecognitionByCLUE3D = cms.PSet( - algo_verbosity = cms.int32(0), - criticalDensity = cms.double(0.6), - criticalEtaPhiDistance = cms.double(0.025), - criticalSelfDensity = cms.double(0.15), - criticalXYDistance = cms.double(1.8), - criticalZDistanceLyr = cms.int32(5), - densityEtaPhiDistanceSqr = cms.double(0.0008), - densityOnSameLayer = cms.bool(False), - densitySiblingLayers = cms.int32(3), - densityXYDistanceSqr = cms.double(3.24), - 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.double(0.2), - minNumLayerCluster = cms.int32(2), - nearestHigherOnSameLayer = cms.bool(False), - outlierMultiplier = cms.double(2), - rescaleDensityByZ = cms.bool(False), - type = cms.string('CLUE3D'), - useAbsoluteProjectiveScale = cms.bool(True), - useClusterDimensionXY = cms.bool(False) + algo_verbosity = cms.int32(0), + criticalDensity = cms.vdouble( + 0.6, + 0.6, + 0.6 + ), + criticalSelfDensity = cms.vdouble( + 0.15, + 0.15, + 0.15 + ), + densitySiblingLayers = cms.vint32( + 3, + 3, + 3 + ), + densityEtaPhiDistanceSqr = cms.vdouble( + 0.0008, + 0.0008, + 0.0008 + ), + densityXYDistanceSqr = cms.vdouble( + 3.24, + 3.24, + 3.24 + ), + kernelDensityFactor = cms.vdouble( + 0.2, + 0.2, + 0.2 + ), + densityOnSameLayer = cms.bool(False), + nearestHigherOnSameLayer = cms.bool(False), + useAbsoluteProjectiveScale = cms.bool(True), + useClusterDimensionXY = cms.bool(False), + rescaleDensityByZ = cms.bool(False), + criticalEtaPhiDistance = cms.vdouble( + 0.025, + 0.025, + 0.025 + ), + criticalXYDistance = cms.vdouble( + 1.8, + 1.8, + 1.8 + ), + criticalZDistanceLyr = cms.vint32( + 5, + 5, + 5 + ), + outlierMultiplier = cms.vdouble( + 2, + 2, + 2 + ), + minNumLayerCluster = cms.vint32( + 2, + 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), + doPidCut = cms.bool(True), + cutHadProb = cms.double(999.), + type = cms.string('CLUE3D') + ), pluginPatternRecognitionByFastJet = cms.PSet( algo_verbosity = cms.int32(0), diff --git a/HLTrigger/Configuration/python/HLT_75e33/modules/ticlTrackstersCLUE3DHigh_cfi.py b/HLTrigger/Configuration/python/HLT_75e33/modules/ticlTrackstersCLUE3DHigh_cfi.py index 54e5a6766d084..3bbe16747ec47 100644 --- a/HLTrigger/Configuration/python/HLT_75e33/modules/ticlTrackstersCLUE3DHigh_cfi.py +++ b/HLTrigger/Configuration/python/HLT_75e33/modules/ticlTrackstersCLUE3DHigh_cfi.py @@ -39,30 +39,77 @@ type = cms.string('CA') ), pluginPatternRecognitionByCLUE3D = cms.PSet( - algo_verbosity = cms.int32(0), - criticalDensity = cms.double(0.6), - criticalEtaPhiDistance = cms.double(0.025), - criticalSelfDensity = cms.double(0.15), - criticalXYDistance = cms.double(1.8), - criticalZDistanceLyr = cms.int32(5), - densityEtaPhiDistanceSqr = cms.double(0.0008), - densityOnSameLayer = cms.bool(False), - densitySiblingLayers = cms.int32(3), - densityXYDistanceSqr = cms.double(3.24), - 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.double(0.2), - minNumLayerCluster = cms.int32(2), - nearestHigherOnSameLayer = cms.bool(False), - outlierMultiplier = cms.double(2), - rescaleDensityByZ = cms.bool(False), - type = cms.string('CLUE3D'), - useAbsoluteProjectiveScale = cms.bool(True), - useClusterDimensionXY = cms.bool(False) + algo_verbosity = cms.int32(0), + criticalDensity = cms.vdouble( + 0.6, + 0.6, + 0.6 + ), + criticalSelfDensity = cms.vdouble( + 0.15, + 0.15, + 0.15 + ), + densitySiblingLayers = cms.vint32( + 3, + 3, + 3 + ), + densityEtaPhiDistanceSqr = cms.vdouble( + 0.0008, + 0.0008, + 0.0008 + ), + densityXYDistanceSqr = cms.vdouble( + 3.24, + 3.24, + 3.24 + ), + kernelDensityFactor = cms.vdouble( + 0.2, + 0.2, + 0.2 + ), + densityOnSameLayer = cms.bool(False), + nearestHigherOnSameLayer = cms.bool(False), + useAbsoluteProjectiveScale = cms.bool(True), + useClusterDimensionXY = cms.bool(False), + rescaleDensityByZ = cms.bool(False), + criticalEtaPhiDistance = cms.vdouble( + 0.025, + 0.025, + 0.025 + ), + criticalXYDistance = cms.vdouble( + 1.8, + 1.8, + 1.8 + ), + criticalZDistanceLyr = cms.vint32( + 5, + 5, + 5 + ), + outlierMultiplier = cms.vdouble( + 2, + 2, + 2 + ), + minNumLayerCluster = cms.vint32( + 2, + 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), + doPidCut = cms.bool(True), + cutHadProb = cms.double(999.), + type = cms.string('CLUE3D') + ), pluginPatternRecognitionByFastJet = cms.PSet( algo_verbosity = cms.int32(0), diff --git a/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py b/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py index cd378f8f543b4..4952089002906 100644 --- a/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py +++ b/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py @@ -13,7 +13,8 @@ TICL_RECO = cms.PSet( outputCommands = cms.untracked.vstring( trackstersIters + - ['keep *_ticlTrackstersHFNoseTrkEM_*_*', + [ + 'keep *_ticlTrackstersHFNoseTrkEM_*_*', 'keep *_ticlTrackstersHFNoseEM_*_*', 'keep *_ticlTrackstersHFNoseTrk_*_*', 'keep *_ticlTrackstersHFNoseMIP_*_*', @@ -21,14 +22,29 @@ 'keep *_ticlTrackstersHFNoseMerge_*_*',] + ['keep *_pfTICL_*_*'] + ['keep CaloParticles_mix_*_*', 'keep SimClusters_mix_*_*'] + - ['keep *_layerClusterSimClusterAssociationProducer_*_*','keep *_layerClusterCaloParticleAssociationProducer_*_*', 'keep *_layerClusterSimTracksterAssociationProducer_*_*'] + + ['keep *_layerClusterSimClusterAssociationProducer_*_*','keep *_layerClusterCaloParticleAssociationProducer_*_*', 'keep *_layerClusterSimTracksterAssociationProducer_*_*'] + ['keep *_tracksterSimTracksterAssociationLinking_*_*' ,'keep *_tracksterSimTracksterAssociationPR_*_*'] + ['keep *_tracksterSimTracksterAssociationLinkingPU_*_*' ,'keep *_tracksterSimTracksterAssociationPRPU_*_*'] + - ['keep *_tracksterSimTracksterAssociationLinkingbyCLUE3D_*_*', 'keep *_tracksterSimTracksterAssociationPRbyCLUE3D_*_*'] + ['keep *_tracksterSimTracksterAssociationLinkingbyCLUE3D_*_*', 'keep *_tracksterSimTracksterAssociationPRbyCLUE3D_*_*'] ) ) + +TICLv5_RECO = cms.PSet( + outputCommands = cms.untracked.vstring( + [ + 'drop *_ticlTracksters*_*_*', + 'keep *_ticlTrackstersCLUE3DEM_*_*', + 'keep *_ticlTrackstersCLUE3DHAD_*_*', + 'keep *_ticlTracksterLinks_*_*', + 'keep *_ticlCandidate_*_*', + ] + ) +) + + TICL_RECO.outputCommands.extend(TICL_AOD.outputCommands) + # FEVT Content TICL_FEVT = cms.PSet( outputCommands = cms.untracked.vstring( @@ -39,6 +55,19 @@ ) ) TICL_FEVT.outputCommands.extend(TICL_RECO.outputCommands) +TICLv5_FEVT = cms.PSet( + outputCommands = cms.untracked.vstring( + 'keep *_ticlSimTracksters_*_*', + 'keep *_ticlSimTICLCandidates_*_*', + 'keep *_ticlSimTrackstersFromCP_*_*', + ) + ) + +TICLv5_FEVT.outputCommands.extend(TICLv5_RECO.outputCommands) + + + + def customiseHGCalOnlyEventContent(process): def cleanOutputAndSet(outputModule, ticl_outputCommads): @@ -57,11 +86,11 @@ def cleanOutputAndSet(outputModule, ticl_outputCommads): 'keep *_randomEngineStateProducer_*_*', 'keep *_layerClusterSimTracksterAssociationProducer_*_*', 'keep *_tracksterSimTracksterAssociationLinking_*_*', - 'keep *_tracksterSimTracksterAssociationPR_*_*', + 'keep *_tracksterSimTracksterAssociationPR_*_*', 'keep *_tracksterSimTracksterAssociationLinkingPU_*_*', - 'keep *_tracksterSimTracksterAssociationPRPU_*_*', + 'keep *_tracksterSimTracksterAssociationPRPU_*_*', 'keep *_tracksterSimTracksterAssociationLinkingbyCLUE3D_*_*', - 'keep *_tracksterSimTracksterAssociationPRbyCLUE3D_*_*', + 'keep *_tracksterSimTracksterAssociationPRbyCLUE3D_*_*', ]) if hasattr(process, 'FEVTDEBUGEventContent'): @@ -70,3 +99,19 @@ def cleanOutputAndSet(outputModule, ticl_outputCommads): cleanOutputAndSet(process.FEVTDEBUGHLToutput, TICL_FEVT.outputCommands) return process + + + +def customiseForTICLv5EventContent(process): + def cleanOutputAndSet(outputModule, ticl_outputCommands): + outputModule.outputCommands.extend(ticl_outputCommands) + + if hasattr(process, 'FEVTDEBUGEventContent'): + cleanOutputAndSet(process.FEVTDEBUGEventContent, TICLv5_FEVT.outputCommands) + if hasattr(process, 'FEVTDEBUGHLToutput'): + cleanOutputAndSet(process.FEVTDEBUGHLToutput, TICLv5_FEVT.outputCommands) + if hasattr(process, 'FEVTEventContent'): + cleanOutputAndSet(process.FEVTEventContent, TICLv5_FEVT.outputCommands) + + return process + diff --git a/RecoHGCal/TICL/BuildFile.xml b/RecoHGCal/TICL/BuildFile.xml index 29a694d95b8eb..fc31796e1bd74 100644 --- a/RecoHGCal/TICL/BuildFile.xml +++ b/RecoHGCal/TICL/BuildFile.xml @@ -2,6 +2,7 @@ + diff --git a/RecoHGCal/TICL/interface/TICLInterpretationAlgoBase.h b/RecoHGCal/TICL/interface/TICLInterpretationAlgoBase.h new file mode 100644 index 0000000000000..8f016ef31ec8a --- /dev/null +++ b/RecoHGCal/TICL/interface/TICLInterpretationAlgoBase.h @@ -0,0 +1,100 @@ +#ifndef RecoHGCal_TICL_PatternRecognitionAlgoBase_H__ +#define RecoHGCal_TICL_PatternRecognitionAlgoBase_H__ + +#include +#include +#include "DataFormats/CaloRecHit/interface/CaloCluster.h" +#include "DataFormats/HGCalReco/interface/MtdHostCollection.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "DataFormats/HGCalReco/interface/TICLCandidate.h" +#include "DataFormats/HGCalReco/interface/TICLLayerTile.h" +#include "DataFormats/HGCalReco/interface/TICLSeedingRegion.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/Common/interface/ValueMap.h" +#include "MagneticField/Engine/interface/MagneticField.h" +#include "TrackingTools/GeomPropagators/interface/Propagator.h" +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" +#include "Geometry/HGCalCommonData/interface/HGCalDDDConstants.h" +#include "RecoHGCal/TICL/interface/GlobalCache.h" +#include "RecoHGCal/TICL/interface/commons.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" +#include "CommonTools/RecoAlgos/interface/MultiVectorManager.h" + +namespace edm { + class Event; + class EventSetup; +} // namespace edm +namespace ticl { + template + class TICLInterpretationAlgoBase { + public: + TICLInterpretationAlgoBase(const edm::ParameterSet& conf, edm::ConsumesCollector) + : algo_verbosity_(conf.getParameter("algo_verbosity")) {} + virtual ~TICLInterpretationAlgoBase(){}; + struct Inputs { + const edm::Event& ev; + const edm::EventSetup& es; + const std::vector& layerClusters; + const edm::ValueMap>& layerClustersTime; + const MultiVectorManager& tracksters; + const std::vector>& linkedResultTracksters; + const edm::Handle> tracksHandle; + const std::vector& maskedTracks; + + Inputs(const edm::Event& eV, + const edm::EventSetup& eS, + const std::vector& lC, + const edm::ValueMap>& lcT, + const MultiVectorManager& tS, + const std::vector>& links, + const edm::Handle> trks, + const std::vector& mT) + : ev(eV), + es(eS), + layerClusters(lC), + layerClustersTime(lcT), + tracksters(tS), + linkedResultTracksters(links), + tracksHandle(trks), + maskedTracks(mT) {} + }; + + struct TrackTimingInformation { + const edm::Handle> tkTime_h; + const edm::Handle> tkTimeErr_h; + const edm::Handle> tkQuality_h; + const edm::Handle> tkBeta_h; + const edm::Handle> tkPath_h; + const edm::Handle> tkMtdPos_h; + + TrackTimingInformation(const edm::Handle> tkT, + const edm::Handle> tkTE, + const edm::Handle> tkQ, + const edm::Handle> tkB, + const edm::Handle> tkP, + const edm::Handle> mtdPos) + : tkTime_h(tkT), tkTimeErr_h(tkTE), tkQuality_h(tkQ), tkBeta_h(tkB), tkPath_h(tkP), tkMtdPos_h(mtdPos) {} + }; + + virtual void makeCandidates(const Inputs& input, + edm::Handle inputTiming_h, + std::vector& resultTracksters, + std::vector& resultCandidate) = 0; + + virtual void initialize(const HGCalDDDConstants* hgcons, + const hgcal::RecHitTools rhtools, + const edm::ESHandle bfieldH, + const edm::ESHandle propH) = 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/TracksterLinkingAlgoBase.h b/RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h new file mode 100644 index 0000000000000..3b8b5db320b08 --- /dev/null +++ b/RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h @@ -0,0 +1,72 @@ +// Author: Felice Pantaleo - felice.pantaleo@cern.ch +// Date: 09/2018 + +#ifndef RecoHGCal_TICL_PatternRecognitionAlgoBase_H__ +#define RecoHGCal_TICL_PatternRecognitionAlgoBase_H__ + +#include +#include +#include "DataFormats/CaloRecHit/interface/CaloCluster.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "DataFormats/HGCalReco/interface/TICLLayerTile.h" +#include "DataFormats/HGCalReco/interface/TICLSeedingRegion.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/Common/interface/ValueMap.h" +#include "RecoHGCal/TICL/interface/GlobalCache.h" +#include "RecoHGCal/TICL/interface/commons.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" +#include "CommonTools/RecoAlgos/interface/MultiVectorManager.h" +#include "MagneticField/Engine/interface/MagneticField.h" +#include "TrackingTools/GeomPropagators/interface/Propagator.h" +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" +#include "Geometry/HGCalCommonData/interface/HGCalDDDConstants.h" + +namespace edm { + class Event; + class EventSetup; +} // namespace edm + +namespace ticl { + class TracksterLinkingAlgoBase { + public: + TracksterLinkingAlgoBase(const edm::ParameterSet& conf, edm::ConsumesCollector) + : algo_verbosity_(conf.getParameter("algo_verbosity")) {} + virtual ~TracksterLinkingAlgoBase(){}; + + struct Inputs { + const edm::Event& ev; + const edm::EventSetup& es; + const std::vector& layerClusters; + const edm::ValueMap>& layerClustersTime; + const MultiVectorManager& tracksters; + + Inputs(const edm::Event& eV, + const edm::EventSetup& eS, + const std::vector& lC, + const edm::ValueMap>& lT, + const MultiVectorManager& tS) + : ev(eV), es(eS), layerClusters(lC), layerClustersTime(lT), tracksters(tS) {} + }; + + virtual void linkTracksters(const Inputs& input, + std::vector& resultTracksters, + std::vector>& linkedResultTracksters, + std::vector>& linkedTracksterIdToInputTracksterId) = 0; + + virtual void initialize(const HGCalDDDConstants* hgcons, + const hgcal::RecHitTools rhtools, + const edm::ESHandle bfieldH, + const edm::ESHandle propH) = 0; + + static void fillPSetDescription(edm::ParameterSetDescription& desc) { desc.add("algo_verbosity", 0); }; + + protected: + int algo_verbosity_; + }; +} // namespace ticl + +#endif diff --git a/RecoHGCal/TICL/plugins/BuildFile.xml b/RecoHGCal/TICL/plugins/BuildFile.xml index b15bebb41e80b..d48af46aa1572 100644 --- a/RecoHGCal/TICL/plugins/BuildFile.xml +++ b/RecoHGCal/TICL/plugins/BuildFile.xml @@ -2,6 +2,7 @@ + @@ -12,6 +13,7 @@ + @@ -20,6 +22,7 @@ + @@ -29,8 +32,6 @@ - - diff --git a/RecoHGCal/TICL/plugins/ClusterFilterBase.h b/RecoHGCal/TICL/plugins/ClusterFilterBase.h index a686da6813614..54cf99e78f43d 100644 --- a/RecoHGCal/TICL/plugins/ClusterFilterBase.h +++ b/RecoHGCal/TICL/plugins/ClusterFilterBase.h @@ -24,7 +24,6 @@ namespace ticl { virtual ~ClusterFilterBase(){}; virtual void filter(const std::vector& layerClusters, - const TICLClusterFilterMask& mask, std::vector& layerClustersMask, hgcal::RecHitTools& rhtools) const = 0; }; diff --git a/RecoHGCal/TICL/plugins/ClusterFilterByAlgo.h b/RecoHGCal/TICL/plugins/ClusterFilterByAlgo.h index 18b80728cf782..445cdebec740b 100644 --- a/RecoHGCal/TICL/plugins/ClusterFilterByAlgo.h +++ b/RecoHGCal/TICL/plugins/ClusterFilterByAlgo.h @@ -19,15 +19,11 @@ namespace ticl { ~ClusterFilterByAlgo() override{}; void filter(const std::vector& layerClusters, - const TICLClusterFilterMask& availableLayerClusters, std::vector& layerClustersMask, hgcal::RecHitTools& rhtools) const override { - auto filteredLayerClusters = std::make_unique(); - for (auto const& cl : availableLayerClusters) { - if (find(algo_number_.begin(), algo_number_.end(), layerClusters[cl.first].algo()) != algo_number_.end()) { - filteredLayerClusters->emplace_back(cl); - } else { - layerClustersMask[cl.first] = 0.; + for (size_t i = 0; i < layerClusters.size(); i++) { + if (find(algo_number_.begin(), algo_number_.end(), layerClusters[i].algo()) == algo_number_.end()) { + layerClustersMask[i] = 0.; } } } diff --git a/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSize.h b/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSize.h index c136f54f89205..431feb4a04384 100644 --- a/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSize.h +++ b/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSize.h @@ -16,25 +16,21 @@ namespace ticl { public: ClusterFilterByAlgoAndSize(const edm::ParameterSet& ps) : ClusterFilterBase(ps), - algo_number_(ps.getParameter>("algo_number")), + algo_number_(ps.getParameter>( + "algo_number")), // hgcal_em = 6, hgcal_had = 7, hgcal_scintillator = 8, hfnose = 9 min_cluster_size_(ps.getParameter("min_cluster_size")), max_cluster_size_(ps.getParameter("max_cluster_size")) {} ~ClusterFilterByAlgoAndSize() override{}; void filter(const std::vector& layerClusters, - const TICLClusterFilterMask& availableLayerClusters, std::vector& layerClustersMask, hgcal::RecHitTools& rhtools) const override { - auto filteredLayerClusters = std::make_unique(); - for (auto const& cl : availableLayerClusters) { - auto const& layerCluster = layerClusters[cl.first]; - if (find(algo_number_.begin(), algo_number_.end(), layerCluster.algo()) != algo_number_.end() and - layerCluster.hitsAndFractions().size() <= max_cluster_size_ and - (layerCluster.hitsAndFractions().size() >= min_cluster_size_ or - (!(rhtools.isSilicon(layerCluster.hitsAndFractions()[0].first))))) { - filteredLayerClusters->emplace_back(cl); - } else { - layerClustersMask[cl.first] = 0.; + for (size_t i = 0; i < layerClusters.size(); i++) { + if ((find(algo_number_.begin(), algo_number_.end(), layerClusters[i].algo()) == algo_number_.end()) or + (layerClusters[i].hitsAndFractions().size() > max_cluster_size_) or + ((layerClusters[i].hitsAndFractions().size() < min_cluster_size_) and + (rhtools.isSilicon(layerClusters[i].hitsAndFractions()[0].first)))) { + layerClustersMask[i] = 0.; } } } diff --git a/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSizeAndLayerRange.h b/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSizeAndLayerRange.h index 5ef553b4b6af4..fb68067039628 100644 --- a/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSizeAndLayerRange.h +++ b/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSizeAndLayerRange.h @@ -24,20 +24,16 @@ namespace ticl { ~ClusterFilterByAlgoAndSizeAndLayerRange() override{}; void filter(const std::vector& layerClusters, - const TICLClusterFilterMask& availableLayerClusters, std::vector& layerClustersMask, hgcal::RecHitTools& rhtools) const override { - auto filteredLayerClusters = std::make_unique(); - for (auto const& cl : availableLayerClusters) { - auto const& layerCluster = layerClusters[cl.first]; + for (size_t i = 0; i < layerClusters.size(); i++) { + auto const& layerCluster = layerClusters[i]; auto const& haf = layerCluster.hitsAndFractions(); auto layerId = rhtools.getLayerWithOffset(haf[0].first); - if (find(algo_number_.begin(), algo_number_.end(), layerCluster.algo()) != algo_number_.end() and - layerId <= max_layerId_ and layerId >= min_layerId_ and haf.size() <= max_cluster_size_ and - (haf.size() >= min_cluster_size_ or !(rhtools.isSilicon(haf[0].first)))) { - filteredLayerClusters->emplace_back(cl); - } else { - layerClustersMask[cl.first] = 0.; + if (find(algo_number_.begin(), algo_number_.end(), layerCluster.algo()) == algo_number_.end() or + layerId > max_layerId_ or layerId < min_layerId_ or haf.size() > max_cluster_size_ or + (haf.size() < min_cluster_size_ and rhtools.isSilicon(haf[0].first))) { + layerClustersMask[i] = 0.; } } } diff --git a/RecoHGCal/TICL/plugins/ClusterFilterBySize.h b/RecoHGCal/TICL/plugins/ClusterFilterBySize.h index 9e2f9bf139a6a..bb87234159cdf 100644 --- a/RecoHGCal/TICL/plugins/ClusterFilterBySize.h +++ b/RecoHGCal/TICL/plugins/ClusterFilterBySize.h @@ -19,15 +19,11 @@ namespace ticl { ~ClusterFilterBySize() override{}; void filter(const std::vector& layerClusters, - const TICLClusterFilterMask& availableLayerClusters, std::vector& layerClustersMask, hgcal::RecHitTools& rhtools) const override { - auto filteredLayerClusters = std::make_unique(); - for (auto const& cl : availableLayerClusters) { - if (layerClusters[cl.first].hitsAndFractions().size() <= max_cluster_size_) { - filteredLayerClusters->emplace_back(cl); - } else { - layerClustersMask[cl.first] = 0.; + for (size_t i = 0; i < layerClusters.size(); i++) { + if (layerClusters[i].hitsAndFractions().size() > max_cluster_size_) { + layerClustersMask[i] = 0.; } } } diff --git a/RecoHGCal/TICL/plugins/FilteredLayerClustersProducer.cc b/RecoHGCal/TICL/plugins/FilteredLayerClustersProducer.cc index 2ee6f89fcc519..b11e436ea53f0 100644 --- a/RecoHGCal/TICL/plugins/FilteredLayerClustersProducer.cc +++ b/RecoHGCal/TICL/plugins/FilteredLayerClustersProducer.cc @@ -56,14 +56,15 @@ void FilteredLayerClustersProducer::beginRun(edm::Run const&, edm::EventSetup co } void FilteredLayerClustersProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - // hgcalMultiClusters edm::ParameterSetDescription desc; desc.add("LayerClusters", edm::InputTag("hgcalMergeLayerClusters")); desc.add("LayerClustersInputMask", edm::InputTag("hgcalMergeLayerClusters", "InitialLayerClustersMask")); desc.add("iteration_label", "iterationLabelGoesHere"); desc.add("clusterFilter", "ClusterFilterByAlgoAndSize"); - desc.add>("algo_number", {reco::CaloCluster::hgcal_em, reco::CaloCluster::hgcal_had}); // 6,7 + desc.add>( + "algo_number", + {reco::CaloCluster::hgcal_em, reco::CaloCluster::hgcal_had, reco::CaloCluster::hgcal_scintillator}); // 6,7,8 desc.add("min_cluster_size", 0); desc.add("max_cluster_size", 9999); desc.add("min_layerId", 0); @@ -74,7 +75,6 @@ void FilteredLayerClustersProducer::fillDescriptions(edm::ConfigurationDescripti void FilteredLayerClustersProducer::produce(edm::Event& evt, const edm::EventSetup& es) { edm::Handle> clusterHandle; edm::Handle> inputClustersMaskHandle; - auto availableLayerClusters = std::make_unique(); evt.getByToken(clusters_token_, clusterHandle); evt.getByToken(clustersMask_token_, inputClustersMaskHandle); const auto& inputClusterMask = *inputClustersMaskHandle; @@ -83,16 +83,8 @@ void FilteredLayerClustersProducer::produce(edm::Event& evt, const edm::EventSet auto layerClustersMask = std::make_unique>(inputClusterMask); const auto& layerClusters = *clusterHandle; - auto numLayerClusters = layerClusters.size(); - availableLayerClusters->reserve(numLayerClusters); - for (unsigned int i = 0; i < numLayerClusters; ++i) { - if (inputClusterMask[i] > 0.f) { - availableLayerClusters->emplace_back(std::make_pair(i, inputClusterMask[i])); - } - } - if (theFilter_) { - theFilter_->filter(layerClusters, *availableLayerClusters, *layerClustersMask, rhtools_); + theFilter_->filter(layerClusters, *layerClustersMask, rhtools_); } evt.put(std::move(layerClustersMask), iteration_label_); diff --git a/RecoHGCal/TICL/plugins/GeneralInterpretationAlgo.cc b/RecoHGCal/TICL/plugins/GeneralInterpretationAlgo.cc new file mode 100644 index 0000000000000..efab1b702f824 --- /dev/null +++ b/RecoHGCal/TICL/plugins/GeneralInterpretationAlgo.cc @@ -0,0 +1,414 @@ +#include "RecoHGCal/TICL/interface/TICLInterpretationAlgoBase.h" +#include "RecoHGCal/TICL/plugins/GeneralInterpretationAlgo.h" +#include "RecoParticleFlow/PFProducer/interface/PFMuonAlgo.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" + +using namespace ticl; + +using Vector = ticl::Trackster::Vector; + +GeneralInterpretationAlgo::~GeneralInterpretationAlgo(){}; + +GeneralInterpretationAlgo::GeneralInterpretationAlgo(const edm::ParameterSet &conf, edm::ConsumesCollector cc) + : TICLInterpretationAlgoBase(conf, cc), + del_tk_ts_layer1_(conf.getParameter("delta_tk_ts_layer1")), + del_tk_ts_int_(conf.getParameter("delta_tk_ts_interface")), + timing_quality_threshold_(conf.getParameter("timing_quality_threshold")) {} + +void GeneralInterpretationAlgo::initialize(const HGCalDDDConstants *hgcons, + const hgcal::RecHitTools rhtools, + const edm::ESHandle bfieldH, + const edm::ESHandle propH) { + hgcons_ = hgcons; + rhtools_ = rhtools; + buildLayers(); + + bfield_ = bfieldH; + propagator_ = propH; +} + +void GeneralInterpretationAlgo::buildLayers() { + // build disks at HGCal front & EM-Had interface for track propagation + + float zVal = hgcons_->waferZ(1, true); + std::pair rMinMax = hgcons_->rangeR(zVal, true); + + float zVal_interface = rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z(); + std::pair rMinMax_interface = hgcons_->rangeR(zVal_interface, true); + + for (int iSide = 0; iSide < 2; ++iSide) { + float zSide = (iSide == 0) ? (-1. * zVal) : zVal; + firstDisk_[iSide] = + std::make_unique(Disk::build(Disk::PositionType(0, 0, zSide), + Disk::RotationType(), + SimpleDiskBounds(rMinMax.first, rMinMax.second, zSide - 0.5, zSide + 0.5)) + .get()); + + zSide = (iSide == 0) ? (-1. * zVal_interface) : zVal_interface; + interfaceDisk_[iSide] = std::make_unique( + Disk::build(Disk::PositionType(0, 0, zSide), + Disk::RotationType(), + SimpleDiskBounds(rMinMax_interface.first, rMinMax_interface.second, zSide - 0.5, zSide + 0.5)) + .get()); + } +} +Vector GeneralInterpretationAlgo::propagateTrackster(const Trackster &t, + const unsigned idx, + float zVal, + std::array &tracksterTiles) { + // needs only the positive Z co-ordinate of the surface to propagate to + // the correct sign is calculated inside according to the barycenter of trackster + Vector const &baryc = t.barycenter(); + Vector directnv = t.eigenvectors(0); + + // barycenter as direction for tracksters w/ poor PCA + // propagation still done to get the cartesian coords + // which are anyway converted to eta, phi in linking + // -> can be simplified later + + //FP: disable PCA propagation for the moment and fallback to barycenter position + // if (t.eigenvalues()[0] / t.eigenvalues()[1] < 20) + directnv = baryc.unit(); + zVal *= (baryc.Z() > 0) ? 1 : -1; + float par = (zVal - baryc.Z()) / directnv.Z(); + float xOnSurface = par * directnv.X() + baryc.X(); + float yOnSurface = par * directnv.Y() + baryc.Y(); + Vector tPoint(xOnSurface, yOnSurface, zVal); + if (tPoint.Eta() > 0) { + tracksterTiles[1].fill(tPoint.Eta(), tPoint.Phi(), idx); + } else if (tPoint.Eta() < 0) { + tracksterTiles[0].fill(tPoint.Eta(), tPoint.Phi(), idx); + } + + return tPoint; +} + +void GeneralInterpretationAlgo::findTrackstersInWindow(const MultiVectorManager &tracksters, + const std::vector> &seedingCollection, + const std::array &tracksterTiles, + const std::vector &tracksterPropPoints, + const float delta, + unsigned trackstersSize, + std::vector> &resultCollection, + bool useMask = false) { + // Finds tracksters in tracksterTiles within an eta-phi window + // (given by delta) of the objects (track/trackster) in the seedingCollection. + // Element i in resultCollection is the vector of trackster + // indices found close to the i-th object in the seedingCollection. + // If specified, Tracksters are masked once found as close to an object. + std::vector mask(trackstersSize, 0); + const float delta2 = delta * delta; + + for (auto &i : seedingCollection) { + float seed_eta = i.first.Eta(); + float seed_phi = i.first.Phi(); + unsigned seedId = i.second; + auto sideZ = seed_eta > 0; //forward or backward region + const TICLLayerTile &tile = tracksterTiles[sideZ]; + float eta_min = std::max(std::fabs(seed_eta) - delta, (float)TileConstants::minEta); + float eta_max = std::min(std::fabs(seed_eta) + delta, (float)TileConstants::maxEta); + + // get range of bins touched by delta + std::array search_box = tile.searchBoxEtaPhi(eta_min, eta_max, seed_phi - delta, seed_phi + delta); + + std::vector in_delta; + // std::vector distances2; + std::vector energies; + for (int eta_i = search_box[0]; eta_i <= search_box[1]; ++eta_i) { + for (int phi_i = search_box[2]; phi_i <= search_box[3]; ++phi_i) { + const auto &in_tile = tile[tile.globalBin(eta_i, (phi_i % TileConstants::nPhiBins))]; + for (const unsigned &t_i : in_tile) { + // calculate actual distances of tracksters to the seed for a more accurate cut + auto sep2 = (tracksterPropPoints[t_i].Eta() - seed_eta) * (tracksterPropPoints[t_i].Eta() - seed_eta) + + (tracksterPropPoints[t_i].Phi() - seed_phi) * (tracksterPropPoints[t_i].Phi() - seed_phi); + if (sep2 < delta2) { + in_delta.push_back(t_i); + // distances2.push_back(sep2); + energies.push_back(tracksters[t_i].raw_energy()); + } + } + } + } + + // sort tracksters found in ascending order of their distances from the seed + std::vector indices(in_delta.size()); + std::iota(indices.begin(), indices.end(), 0); + std::sort(indices.begin(), indices.end(), [&](unsigned i, unsigned j) { return energies[i] > energies[j]; }); + + // push back sorted tracksters in the result collection + for (const unsigned &index : indices) { + const auto &t_i = in_delta[index]; + if (!mask[t_i]) { + resultCollection[seedId].push_back(t_i); + if (useMask) + mask[t_i] = 1; + } + } + + } // seeding collection loop +} + +bool GeneralInterpretationAlgo::timeAndEnergyCompatible(float &total_raw_energy, + const reco::Track &track, + const Trackster &trackster, + const float &tkT, + const float &tkTErr, + const float &tkQual, + const float &tkBeta, + const GlobalPoint &tkMtdPos, + bool useMTDTiming) { + float threshold = std::min(0.2 * trackster.raw_energy(), 10.0); + bool energyCompatible = (total_raw_energy + trackster.raw_energy() < track.p() + threshold); + + if (!useMTDTiming) + return energyCompatible; + + // compatible if trackster time is within 3sigma of + // track time; compatible if either: no time assigned + // to trackster or track + + float tsT = trackster.time(); + float tsTErr = trackster.timeError(); + + bool timeCompatible = false; + if (tsT == -99. or tkTErr == -1 or tkQual < timing_quality_threshold_) + timeCompatible = true; + else { + const auto &barycenter = trackster.barycenter(); + + const auto deltaSoverV = std::sqrt((barycenter.x() - tkMtdPos.x()) * (barycenter.x() - tkMtdPos.x()) + + (barycenter.y() - tkMtdPos.y()) * (barycenter.y() - tkMtdPos.y()) + + (barycenter.z() - tkMtdPos.z()) * (barycenter.z() - tkMtdPos.z())) / + (tkBeta * 29.9792458); + + const auto deltaT = tsT - tkT; + + // timeCompatible = (std::abs(deltaSoverV - deltaT) < maxDeltaT_ * sqrt(tsTErr * tsTErr + tkTErr * tkTErr)); + // use sqrt(2) * error on the track for the total error, because the time of the trackster is too small + timeCompatible = std::abs(deltaSoverV - deltaT) < maxDeltaT_ * std::sqrt(tsTErr * tsTErr + tkTErr * tkTErr); + } + + if (TICLInterpretationAlgoBase::algo_verbosity_ > VerbosityLevel::Advanced) { + if (!(energyCompatible)) + LogDebug("GeneralInterpretationAlgo") + << "energy incompatible : track p " << track.p() << " trackster energy " << trackster.raw_energy() << "\n" + << " total_raw_energy " << total_raw_energy << " greater than track p + threshold " + << track.p() + threshold << "\n"; + if (!(timeCompatible)) + LogDebug("GeneralInterpretationAlgo") << "time incompatible : track time " << tkT << " +/- " << tkTErr + << " trackster time " << tsT << " +/- " << tsTErr << "\n"; + } + + return energyCompatible && timeCompatible; +} + +void GeneralInterpretationAlgo::makeCandidates(const Inputs &input, + edm::Handle inputTiming_h, + std::vector &resultTracksters, + std::vector &resultCandidate) { + bool useMTDTiming = inputTiming_h.isValid(); + const auto tkH = input.tracksHandle; + const auto maskTracks = input.maskedTracks; + const auto &tracks = *tkH; + const auto &tracksters = input.tracksters; + + auto bFieldProd = bfield_.product(); + const Propagator &prop = (*propagator_); + + // propagated point collections + // elements in the propagated points collecions are used + // to look for potential linkages in the appropriate tiles + std::vector> trackPColl; // propagated track points and index of track in collection + std::vector> tkPropIntColl; // tracks propagated to lastLayerEE + + trackPColl.reserve(tracks.size()); + tkPropIntColl.reserve(tracks.size()); + + std::array tracksterPropTiles = {}; // all Tracksters, propagated to layer 1 + std::array tsPropIntTiles = {}; // all Tracksters, propagated to lastLayerEE + + if (TICLInterpretationAlgoBase::algo_verbosity_ > VerbosityLevel::Advanced) + LogDebug("GeneralInterpretationAlgo") << "------- Geometric Linking ------- \n"; + + // Propagate tracks + std::vector candidateTrackIds; + candidateTrackIds.reserve(tracks.size()); + for (unsigned i = 0; i < tracks.size(); ++i) { + if (!maskTracks[i]) + continue; + candidateTrackIds.push_back(i); + } + + std::sort(candidateTrackIds.begin(), candidateTrackIds.end(), [&](unsigned i, unsigned j) { + return tracks[i].p() > tracks[j].p(); + }); + + for (auto const i : candidateTrackIds) { + const auto &tk = tracks[i]; + int iSide = int(tk.eta() > 0); + const auto &fts = trajectoryStateTransform::outerFreeState((tk), bFieldProd); + // to the HGCal front + const auto &tsos = prop.propagate(fts, firstDisk_[iSide]->surface()); + if (tsos.isValid()) { + Vector trackP(tsos.globalPosition().x(), tsos.globalPosition().y(), tsos.globalPosition().z()); + trackPColl.emplace_back(trackP, i); + } + // to lastLayerEE + const auto &tsos_int = prop.propagate(fts, interfaceDisk_[iSide]->surface()); + if (tsos_int.isValid()) { + Vector trackP(tsos_int.globalPosition().x(), tsos_int.globalPosition().y(), tsos_int.globalPosition().z()); + tkPropIntColl.emplace_back(trackP, i); + } + } // Tracks + tkPropIntColl.shrink_to_fit(); + trackPColl.shrink_to_fit(); + candidateTrackIds.shrink_to_fit(); + + // Propagate tracksters + + // Record postions of all tracksters propagated to layer 1 and lastLayerEE, + // to be used later for distance calculation in the link finding stage + // indexed by trackster index in event collection + std::vector tsAllProp; + std::vector tsAllPropInt; + tsAllProp.reserve(tracksters.size()); + tsAllPropInt.reserve(tracksters.size()); + // Propagate tracksters + + for (unsigned i = 0; i < tracksters.size(); ++i) { + const auto &t = tracksters[i]; + if (TICLInterpretationAlgoBase::algo_verbosity_ > VerbosityLevel::Advanced) + LogDebug("GeneralInterpretationAlgo") + << "trackster " << i << " - eta " << t.barycenter().eta() << " phi " << t.barycenter().phi() << " time " + << t.time() << " energy " << t.raw_energy() << "\n"; + + // to HGCal front + float zVal = hgcons_->waferZ(1, true); + auto tsP = propagateTrackster(t, i, zVal, tracksterPropTiles); + tsAllProp.emplace_back(tsP); + + // to lastLayerEE + zVal = rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z(); + tsP = propagateTrackster(t, i, zVal, tsPropIntTiles); + tsAllPropInt.emplace_back(tsP); + + } // TS + + // step 1: tracks -> all tracksters, at firstLayerEE + std::vector> tsNearTk(tracks.size()); + findTrackstersInWindow( + tracksters, trackPColl, tracksterPropTiles, tsAllProp, del_tk_ts_layer1_, tracksters.size(), tsNearTk); + + // step 2: tracks -> all tracksters, at lastLayerEE + std::vector> tsNearTkAtInt(tracks.size()); + findTrackstersInWindow( + tracksters, tkPropIntColl, tsPropIntTiles, tsAllPropInt, del_tk_ts_int_, tracksters.size(), tsNearTkAtInt); + + std::vector chargedHadronsFromTk; + std::vector> trackstersInTrackIndices; + trackstersInTrackIndices.resize(tracks.size()); + + std::vector chargedMask(tracksters.size(), true); + for (unsigned &i : candidateTrackIds) { + if (tsNearTk[i].empty() && tsNearTkAtInt[i].empty()) { // nothing linked to track, make charged hadrons + continue; + } + + std::vector chargedCandidate; + float total_raw_energy = 0.f; + + float track_time = 0.f; + float track_timeErr = 0.f; + float track_quality = 0.f; + float track_beta = 0.f; + GlobalPoint track_MtdPos{0.f, 0.f, 0.f}; + if (useMTDTiming) { + auto const &inputTimingView = (*inputTiming_h).const_view(); + track_time = inputTimingView.time()[i]; + track_timeErr = inputTimingView.timeErr()[i]; + track_quality = inputTimingView.MVAquality()[i]; + track_beta = inputTimingView.beta()[i]; + track_MtdPos = { + inputTimingView.posInMTD_x()[i], inputTimingView.posInMTD_y()[i], inputTimingView.posInMTD_z()[i]}; + } + + for (auto const tsIdx : tsNearTk[i]) { + if (chargedMask[tsIdx] && timeAndEnergyCompatible(total_raw_energy, + tracks[i], + tracksters[tsIdx], + track_time, + track_timeErr, + track_quality, + track_beta, + track_MtdPos, + useMTDTiming)) { + chargedCandidate.push_back(tsIdx); + chargedMask[tsIdx] = false; + total_raw_energy += tracksters[tsIdx].raw_energy(); + } + } + for (const unsigned tsIdx : tsNearTkAtInt[i]) { // do the same for tk -> ts links at the interface + if (chargedMask[tsIdx] && timeAndEnergyCompatible(total_raw_energy, + tracks[i], + tracksters[tsIdx], + track_time, + track_timeErr, + track_quality, + track_beta, + track_MtdPos, + useMTDTiming)) { + chargedCandidate.push_back(tsIdx); + chargedMask[tsIdx] = false; + total_raw_energy += tracksters[tsIdx].raw_energy(); + } + } + trackstersInTrackIndices[i] = chargedCandidate; + } + + for (size_t iTrack = 0; iTrack < trackstersInTrackIndices.size(); iTrack++) { + if (!trackstersInTrackIndices[iTrack].empty()) { + if (trackstersInTrackIndices[iTrack].size() == 1) { + auto tracksterId = trackstersInTrackIndices[iTrack][0]; + resultCandidate[iTrack] = resultTracksters.size(); + resultTracksters.push_back(input.tracksters[tracksterId]); + } else { + // in this case mergeTracksters() clears the pid probabilities and the regressed energy is not set + // TODO: fix probabilities when CNN will be splitted + Trackster outTrackster; + float regr_en = 0.f; + bool isHadron = false; + for (auto const tracksterId : trackstersInTrackIndices[iTrack]) { + //maskTracksters[tracksterId] = 0; + outTrackster.mergeTracksters(input.tracksters[tracksterId]); + regr_en += input.tracksters[tracksterId].regressed_energy(); + if (input.tracksters[tracksterId].isHadronic()) + isHadron = true; + } + resultCandidate[iTrack] = resultTracksters.size(); + resultTracksters.push_back(outTrackster); + resultTracksters.back().setRegressedEnergy(regr_en); + // since a track has been linked it can only be electron or charged hadron + if (isHadron) + resultTracksters.back().setIdProbability(ticl::Trackster::ParticleType::charged_hadron, 1.f); + else + resultTracksters.back().setIdProbability(ticl::Trackster::ParticleType::electron, 1.f); + } + } + } + + for (size_t iTrackster = 0; iTrackster < input.tracksters.size(); iTrackster++) { + if (chargedMask[iTrackster]) { + resultTracksters.push_back(input.tracksters[iTrackster]); + } + } +}; + +void GeneralInterpretationAlgo::fillPSetDescription(edm::ParameterSetDescription &desc) { + desc.add("cutTk", + "1.48 < abs(eta) < 3.0 && pt > 1. && quality(\"highPurity\") && " + "hitPattern().numberOfLostHits(\"MISSING_OUTER_HITS\") < 5"); + desc.add("delta_tk_ts_layer1", 0.02); + desc.add("delta_tk_ts_interface", 0.03); + desc.add("timing_quality_threshold", 0.5); + TICLInterpretationAlgoBase::fillPSetDescription(desc); +} diff --git a/RecoHGCal/TICL/plugins/GeneralInterpretationAlgo.h b/RecoHGCal/TICL/plugins/GeneralInterpretationAlgo.h new file mode 100644 index 0000000000000..f5346d4a35e79 --- /dev/null +++ b/RecoHGCal/TICL/plugins/GeneralInterpretationAlgo.h @@ -0,0 +1,78 @@ +#ifndef RecoHGCal_TICL_GeneralInterpretationAlgo_H_ +#define RecoHGCal_TICL_GeneralInterpretationAlgo_H_ + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "RecoHGCal/TICL/interface/TICLInterpretationAlgoBase.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/GeometrySurface/interface/BoundDisk.h" + +namespace ticl { + + class GeneralInterpretationAlgo : public TICLInterpretationAlgoBase { + public: + GeneralInterpretationAlgo(const edm::ParameterSet &conf, edm::ConsumesCollector iC); + + ~GeneralInterpretationAlgo() override; + + void makeCandidates(const Inputs &input, + edm::Handle inputTiming_h, + std::vector &resultTracksters, + std::vector &resultCandidate) override; + + void initialize(const HGCalDDDConstants *hgcons, + const hgcal::RecHitTools rhtools, + const edm::ESHandle bfieldH, + const edm::ESHandle propH) override; + + static void fillPSetDescription(edm::ParameterSetDescription &iDesc); + + private: + void buildLayers(); + + Vector propagateTrackster(const Trackster &t, + const unsigned idx, + float zVal, + std::array &tracksterTiles); + + void findTrackstersInWindow(const MultiVectorManager &tracksters, + const std::vector> &seedingCollection, + const std::array &tracksterTiles, + const std::vector &tracksterPropPoints, + float delta, + unsigned trackstersSize, + std::vector> &resultCollection, + bool useMask); + + bool timeAndEnergyCompatible(float &total_raw_energy, + const reco::Track &track, + const Trackster &trackster, + const float &tkTime, + const float &tkTimeErr, + const float &tkQual, + const float &tkBeta, + const GlobalPoint &tkMtdPos, + bool useMTDTiming); + + const float tkEnergyCut_ = 2.0f; + const float maxDeltaT_ = 3.0f; + const float del_tk_ts_layer1_; + const float del_tk_ts_int_; + const float timing_quality_threshold_; + + const HGCalDDDConstants *hgcons_; + + std::unique_ptr firstDisk_[2]; + std::unique_ptr interfaceDisk_[2]; + + hgcal::RecHitTools rhtools_; + + edm::ESHandle bfield_; + edm::ESHandle propagator_; + }; + +} // namespace ticl + +#endif diff --git a/RecoHGCal/TICL/plugins/MTDSoAProducer.cc b/RecoHGCal/TICL/plugins/MTDSoAProducer.cc new file mode 100644 index 0000000000000..f5367265ff01c --- /dev/null +++ b/RecoHGCal/TICL/plugins/MTDSoAProducer.cc @@ -0,0 +1,150 @@ +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "HeterogeneousCore/AlpakaInterface/interface/host.h" + +#include "DataFormats/Common/interface/ValueMap.h" +#include "DataFormats/HGCalReco/interface/MtdHostCollection.h" +#include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "DataFormats/TrackReco/interface/Track.h" + +using namespace edm; + +class MTDSoAProducer : public edm::stream::EDProducer<> { +public: + MTDSoAProducer(const ParameterSet& pset); + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + + void produce(edm::Event& ev, const edm::EventSetup& es) final; + +private: + edm::EDGetTokenT tracksToken_; + edm::EDGetTokenT> trackAssocToken_; + edm::EDGetTokenT> t0Token_; + edm::EDGetTokenT> sigmat0Token_; + edm::EDGetTokenT> tmtdToken_; + edm::EDGetTokenT> sigmatmtdToken_; + edm::EDGetTokenT> betaToken_; + edm::EDGetTokenT> pathToken_; + edm::EDGetTokenT> MVAQualityToken_; + edm::EDGetTokenT> posInMtdToken_; + edm::EDGetTokenT> momentumWithMTDToken_; + edm::EDGetTokenT> probPiToken_; + edm::EDGetTokenT> probKToken_; + edm::EDGetTokenT> probPToken_; +}; + +MTDSoAProducer::MTDSoAProducer(const ParameterSet& iConfig) + : tracksToken_(consumes(iConfig.getParameter("tracksSrc"))), + trackAssocToken_(consumes>(iConfig.getParameter("trackAssocSrc"))), + t0Token_(consumes>(iConfig.getParameter("t0Src"))), + sigmat0Token_(consumes>(iConfig.getParameter("sigmat0Src"))), + tmtdToken_(consumes>(iConfig.getParameter("tmtdSrc"))), + sigmatmtdToken_(consumes>(iConfig.getParameter("sigmatmtdSrc"))), + betaToken_(consumes>(iConfig.getParameter("betamtd"))), + pathToken_(consumes>(iConfig.getParameter("pathmtd"))), + MVAQualityToken_(consumes>(iConfig.getParameter("mvaquality"))), + posInMtdToken_(consumes>(iConfig.getParameter("posmtd"))), + momentumWithMTDToken_(consumes>(iConfig.getParameter("momentum"))), + probPiToken_(consumes>(iConfig.getParameter("probPi"))), + probKToken_(consumes>(iConfig.getParameter("probK"))), + probPToken_(consumes>(iConfig.getParameter("probP"))) { + produces(); +} + +// Configuration descriptions +void MTDSoAProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("tracksSrc", edm::InputTag("generalTracks")); + desc.add("trackAssocSrc", edm::InputTag("trackExtenderWithMTD:generalTrackassoc")); + desc.add("t0Src", edm::InputTag("tofPID:t0")); + desc.add("sigmat0Src", edm::InputTag("tofPID:sigmat0")); + desc.add("tmtdSrc", edm::InputTag("trackExtenderWithMTD:generalTracktmtd")); + desc.add("sigmatmtdSrc", edm::InputTag("trackExtenderWithMTD:generalTracksigmatmtd")); + desc.add("betamtd", edm::InputTag("trackExtenderWithMTD:generalTrackBeta")); + desc.add("pathmtd", edm::InputTag("trackExtenderWithMTD:generalTrackPathLength")); + desc.add("mvaquality", edm::InputTag("mtdTrackQualityMVA:mtdQualMVA")); + desc.add("posmtd", edm::InputTag("trackExtenderWithMTD:generalTrackmtdpos")); + desc.add("momentum", edm::InputTag("trackExtenderWithMTD:generalTrackp")); + desc.add("probPi", edm::InputTag("tofPID:probPi")); + desc.add("probK", edm::InputTag("tofPID:probK")); + desc.add("probP", edm::InputTag("tofPID:probP")); + + descriptions.add("mtdSoAProducer", desc); +} + +void MTDSoAProducer::produce(edm::Event& ev, const edm::EventSetup& es) { + edm::Handle tracksH; + ev.getByToken(tracksToken_, tracksH); + const auto& tracks = *tracksH; + + const auto& trackAssoc = ev.get(trackAssocToken_); + + const auto& t0 = ev.get(t0Token_); + const auto& sigmat0 = ev.get(sigmat0Token_); + + const auto& tmtd = ev.get(tmtdToken_); + const auto& sigmatmtd = ev.get(sigmatmtdToken_); + + const auto& beta = ev.get(betaToken_); + const auto& path = ev.get(pathToken_); + const auto& MVAquality = ev.get(MVAQualityToken_); + const auto& posInMTD = ev.get(posInMtdToken_); + const auto& momentum = ev.get(momentumWithMTDToken_); + const auto& probPi = ev.get(probPiToken_); + const auto& probK = ev.get(probKToken_); + const auto& probP = ev.get(probPToken_); + + auto MtdInfo = std::make_unique(tracks.size(), cms::alpakatools::host()); + + auto& MtdInfoView = MtdInfo->view(); + for (unsigned int iTrack = 0; iTrack < tracks.size(); ++iTrack) { + const reco::TrackRef trackref(tracksH, iTrack); + + if (trackAssoc[trackref] == -1) { + MtdInfoView.trackAsocMTD()[iTrack] = -1; + MtdInfoView.time0()[iTrack] = 0.f; + MtdInfoView.time0Err()[iTrack] = -1.f; + MtdInfoView.time()[iTrack] = 0.f; + MtdInfoView.timeErr()[iTrack] = -1.f; + MtdInfoView.MVAquality()[iTrack] = 0.f; + MtdInfoView.pathLength()[iTrack] = 0.f; + MtdInfoView.beta()[iTrack] = 0.f; + MtdInfoView.posInMTD_x()[iTrack] = 0.f; + MtdInfoView.posInMTD_y()[iTrack] = 0.f; + MtdInfoView.posInMTD_z()[iTrack] = 0.f; + MtdInfoView.momentumWithMTD()[iTrack] = 0.f; + MtdInfoView.probPi()[iTrack] = 0.f; + MtdInfoView.probK()[iTrack] = 0.f; + MtdInfoView.probP()[iTrack] = 0.f; + continue; + } + + MtdInfoView.trackAsocMTD()[iTrack] = trackAssoc[trackref]; + MtdInfoView.time0()[iTrack] = t0[trackref]; + MtdInfoView.time0Err()[iTrack] = sigmat0[trackref]; + MtdInfoView.time()[iTrack] = tmtd[trackref]; + MtdInfoView.timeErr()[iTrack] = sigmatmtd[trackref]; + MtdInfoView.MVAquality()[iTrack] = MVAquality[trackref]; + MtdInfoView.pathLength()[iTrack] = path[trackref]; + MtdInfoView.beta()[iTrack] = beta[trackref]; + MtdInfoView.posInMTD_x()[iTrack] = posInMTD[trackref].x(); + MtdInfoView.posInMTD_y()[iTrack] = posInMTD[trackref].y(); + MtdInfoView.posInMTD_z()[iTrack] = posInMTD[trackref].z(); + MtdInfoView.momentumWithMTD()[iTrack] = momentum[trackref]; + MtdInfoView.probPi()[iTrack] = probPi[trackref]; + MtdInfoView.probK()[iTrack] = probK[trackref]; + MtdInfoView.probP()[iTrack] = probP[trackref]; + } + + ev.put(std::move(MtdInfo)); +} + +//define this as a plug-in +#include +DEFINE_FWK_MODULE(MTDSoAProducer); diff --git a/RecoHGCal/TICL/plugins/MergedTrackstersProducer.cc b/RecoHGCal/TICL/plugins/MergedTrackstersProducer.cc new file mode 100644 index 0000000000000..dba31c3b6653d --- /dev/null +++ b/RecoHGCal/TICL/plugins/MergedTrackstersProducer.cc @@ -0,0 +1,58 @@ +// Author: Felice Pantaleo, Wahid Redjeb, Aurora Perego (CERN) - felice.pantaleo@cern.ch, wahid.redjeb@cern.ch, aurora.perego@cern.ch +// Date: 12/2023 +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/PluginDescription.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" + +using namespace ticl; + +class MergedTrackstersProducer : public edm::stream::EDProducer<> { +public: + explicit MergedTrackstersProducer(const edm::ParameterSet &ps); + ~MergedTrackstersProducer() override{}; + void produce(edm::Event &, const edm::EventSetup &) override; + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); + +private: + edm::EDGetTokenT> egamma_tracksters_token_; + + edm::EDGetTokenT> general_tracksters_token_; +}; + +MergedTrackstersProducer::MergedTrackstersProducer(const edm::ParameterSet &ps) + : egamma_tracksters_token_( + consumes>(ps.getParameter("egamma_tracksters"))), + general_tracksters_token_( + consumes>(ps.getParameter("had_tracksters"))) { + produces>(); +} + +void MergedTrackstersProducer::produce(edm::Event &evt, const edm::EventSetup &es) { + auto resultTracksters = std::make_unique>(); + auto const &egamma_tracksters = evt.get(egamma_tracksters_token_); + auto const &had_tracksters = evt.get(general_tracksters_token_); + for (auto const &eg_trackster : egamma_tracksters) { + resultTracksters->push_back(eg_trackster); + } + for (auto const &had_trackster : had_tracksters) { + resultTracksters->push_back(had_trackster); + } + + evt.put(std::move(resultTracksters)); +} + +void MergedTrackstersProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { + edm::ParameterSetDescription desc; + desc.add("egamma_tracksters", edm::InputTag("ticlTrackstersCLUE3DEM")); + desc.add("had_tracksters", edm::InputTag("ticlTrackstersCLUE3DHAD")); + descriptions.add("mergedTrackstersProducer", desc); +} + +DEFINE_FWK_MODULE(MergedTrackstersProducer); diff --git a/RecoHGCal/TICL/plugins/MultiClustersFromTrackstersProducer.cc b/RecoHGCal/TICL/plugins/MultiClustersFromTrackstersProducer.cc deleted file mode 100644 index 468bc512c19da..0000000000000 --- a/RecoHGCal/TICL/plugins/MultiClustersFromTrackstersProducer.cc +++ /dev/null @@ -1,100 +0,0 @@ -// user include files -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" -#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" - -#include "DataFormats/ParticleFlowReco/interface/HGCalMultiCluster.h" -#include "DataFormats/HGCalReco/interface/Trackster.h" - -#include -#include -#include -#include - -class MultiClustersFromTrackstersProducer : public edm::stream::EDProducer<> { -public: - MultiClustersFromTrackstersProducer(const edm::ParameterSet&); - ~MultiClustersFromTrackstersProducer() override {} - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - - void produce(edm::Event&, const edm::EventSetup&) override; - -private: - edm::EDGetTokenT> layer_clusters_token_; - edm::EDGetTokenT> tracksters_token_; -}; - -DEFINE_FWK_MODULE(MultiClustersFromTrackstersProducer); - -MultiClustersFromTrackstersProducer::MultiClustersFromTrackstersProducer(const edm::ParameterSet& ps) - : layer_clusters_token_(consumes>(ps.getParameter("LayerClusters"))), - tracksters_token_(consumes>(ps.getParameter("Tracksters"))) { - produces>(); -} - -void MultiClustersFromTrackstersProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - // hgcalMultiClusters - edm::ParameterSetDescription desc; - desc.add("Tracksters", edm::InputTag("Tracksters", "TrackstersByCA")); - desc.add("LayerClusters", edm::InputTag("hgcalMergeLayerClusters")); - desc.addUntracked("verbosity", 3); - descriptions.add("multiClustersFromTrackstersProducer", desc); -} - -void MultiClustersFromTrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) { - auto multiclusters = std::make_unique>(); - edm::Handle> tracksterHandle; - evt.getByToken(tracksters_token_, tracksterHandle); - - edm::Handle> layer_clustersHandle; - evt.getByToken(layer_clusters_token_, layer_clustersHandle); - - auto const& tracksters = *tracksterHandle; - auto const& layerClusters = *layer_clustersHandle; - - edm::PtrVector clusterPtrs; - for (unsigned i = 0; i < layerClusters.size(); ++i) { - edm::Ptr ptr(layer_clustersHandle, i); - clusterPtrs.push_back(ptr); - } - - std::for_each(std::begin(tracksters), std::end(tracksters), [&](auto const& trackster) { - // Create an empty multicluster if the trackster has no layer clusters. - // This could happen when a seed leads to no trackster and a dummy one is produced. - - std::array baricenter{{0., 0., 0.}}; - double total_weight = 0.; - reco::HGCalMultiCluster temp; - int counter = 0; - if (!trackster.vertices().empty()) { - std::for_each(std::begin(trackster.vertices()), std::end(trackster.vertices()), [&](unsigned int idx) { - temp.push_back(clusterPtrs[idx]); - auto fraction = 1.f / trackster.vertex_multiplicity(counter++); - for (auto const& cell : clusterPtrs[idx]->hitsAndFractions()) { - temp.addHitAndFraction(cell.first, cell.second * fraction); - } - auto weight = clusterPtrs[idx]->energy() * fraction; - total_weight += weight; - baricenter[0] += clusterPtrs[idx]->x() * weight; - baricenter[1] += clusterPtrs[idx]->y() * weight; - baricenter[2] += clusterPtrs[idx]->z() * weight; - }); - std::transform( - std::begin(baricenter), std::end(baricenter), std::begin(baricenter), [&total_weight](double val) -> double { - return val / total_weight; - }); - } - temp.setEnergy(total_weight); - temp.setCorrectedEnergy(total_weight); - temp.setPosition(math::XYZPoint(baricenter[0], baricenter[1], baricenter[2])); - temp.setAlgoId(reco::CaloCluster::hgcal_em); - temp.setTime(trackster.time(), trackster.timeError()); - multiclusters->push_back(temp); - }); - - evt.put(std::move(multiclusters)); -} diff --git a/RecoHGCal/TICL/plugins/PFTICLProducer.cc b/RecoHGCal/TICL/plugins/PFTICLProducer.cc index a111ac95e2dd0..1fb3ae06c9ad9 100644 --- a/RecoHGCal/TICL/plugins/PFTICLProducer.cc +++ b/RecoHGCal/TICL/plugins/PFTICLProducer.cc @@ -30,9 +30,10 @@ class PFTICLProducer : public edm::stream::EDProducer<> { const bool useTimingAverage_; const float timingQualityThreshold_; const bool energy_from_regression_; + const bool isTICLv5_; // inputs const edm::EDGetTokenT> ticl_candidates_; - const edm::EDGetTokenT> srcTrackTime_, srcTrackTimeError_, srcTrackTimeQuality_; + edm::EDGetTokenT> srcTrackTime_, srcTrackTimeError_, srcTrackTimeQuality_; const edm::EDGetTokenT muons_; // For PFMuonAlgo std::unique_ptr pfmu_; @@ -45,13 +46,16 @@ PFTICLProducer::PFTICLProducer(const edm::ParameterSet& conf) useTimingAverage_(conf.getParameter("useTimingAverage")), timingQualityThreshold_(conf.getParameter("timingQualityThreshold")), energy_from_regression_(conf.getParameter("energyFromRegression")), + isTICLv5_(conf.getParameter("isTICLv5")), ticl_candidates_(consumes>(conf.getParameter("ticlCandidateSrc"))), - srcTrackTime_(consumes>(conf.getParameter("trackTimeValueMap"))), - srcTrackTimeError_(consumes>(conf.getParameter("trackTimeErrorMap"))), - srcTrackTimeQuality_(consumes>(conf.getParameter("trackTimeQualityMap"))), muons_(consumes(conf.getParameter("muonSrc"))), pfmu_(std::make_unique(conf.getParameterSet("pfMuonAlgoParameters"), false)) { // postMuonCleaning = false + if (not isTICLv5_) { + srcTrackTime_ = consumes>(conf.getParameter("trackTimeValueMap")); + srcTrackTimeError_ = consumes>(conf.getParameter("trackTimeErrorMap")); + srcTrackTimeQuality_ = consumes>(conf.getParameter("trackTimeQualityMap")); + } produces(); } @@ -64,6 +68,7 @@ void PFTICLProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptio desc.add("energyFromRegression", true); desc.add("timingQualityThreshold", 0.5); desc.add("useMTDTiming", true); + desc.add("isTICLv5", false); desc.add("useTimingAverage", false); // For PFMuonAlgo desc.add("muonSrc", edm::InputTag("muons1stStep")); @@ -80,9 +85,11 @@ void PFTICLProducer::produce(edm::Event& evt, const edm::EventSetup& es) { evt.getByToken(ticl_candidates_, ticl_cand_h); const auto ticl_candidates = *ticl_cand_h; edm::Handle> trackTimeH, trackTimeErrH, trackTimeQualH; - evt.getByToken(srcTrackTime_, trackTimeH); - evt.getByToken(srcTrackTimeError_, trackTimeErrH); - evt.getByToken(srcTrackTimeQuality_, trackTimeQualH); + if (not isTICLv5_) { + evt.getByToken(srcTrackTime_, trackTimeH); + evt.getByToken(srcTrackTimeError_, trackTimeErrH); + evt.getByToken(srcTrackTimeQuality_, trackTimeQualH); + } const auto muonH = evt.getHandle(muons_); const auto& muons = *muonH; @@ -139,44 +146,60 @@ void PFTICLProducer::produce(edm::Event& evt, const edm::EventSetup& es) { candidate.setTrackRef(trackref); // Utilize PFMuonAlgo const int muId = PFMuonAlgo::muAssocToTrack(trackref, muons); - if (muId != -1) { - const reco::MuonRef muonref = reco::MuonRef(muonH, muId); - const bool allowLoose = (part_type == reco::PFCandidate::mu); - // Redefine pfmuon candidate kinematics and add muonref - pfmu_->reconstructMuon(candidate, muonref, allowLoose); + if (isTICLv5_) { + if (muId != -1) { + const reco::MuonRef muonref = reco::MuonRef(muonH, muId); + if ((PFMuonAlgo::isMuon(muonref) and not(*muonH)[muId].isTrackerMuon()) or + (ticl_cand.tracksters().empty() and muonref.isNonnull() and muonref->isGlobalMuon())) { + const bool allowLoose = (part_type == reco::PFCandidate::mu); + // Redefine pfmuon candidate kinematics and add muonref + pfmu_->reconstructMuon(candidate, muonref, allowLoose); + } + } + } else { + if (muId != -1) { + const reco::MuonRef muonref = reco::MuonRef(muonH, muId); + const bool allowLoose = (part_type == reco::PFCandidate::mu); + // Redefine pfmuon candidate kinematics and add muonref + pfmu_->reconstructMuon(candidate, muonref, allowLoose); + } } } - // HGCAL timing as default values - auto time = ticl_cand.time(); - auto timeE = ticl_cand.timeError(); - - if (useMTDTiming_ and candidate.charge()) { - // Ignore HGCAL timing until it will be TOF corrected - time = -99.; - timeE = -1.; - // Check MTD timing availability - const bool assocQuality = (*trackTimeQualH)[candidate.trackRef()] > timingQualityThreshold_; - if (assocQuality) { - const auto timeHGC = time; - const auto timeEHGC = timeE; - const auto timeMTD = (*trackTimeH)[candidate.trackRef()]; - const auto timeEMTD = (*trackTimeErrH)[candidate.trackRef()]; - - if (useTimingAverage_ && (timeEMTD > 0 && timeEHGC > 0)) { - // Compute weighted average between HGCAL and MTD timing - const auto invTimeESqHGC = pow(timeEHGC, -2); - const auto invTimeESqMTD = pow(timeEMTD, -2); - timeE = (invTimeESqHGC * invTimeESqMTD) / (invTimeESqHGC + invTimeESqMTD); - time = (timeHGC * invTimeESqHGC + timeMTD * invTimeESqMTD) * timeE; - timeE = sqrt(timeE); - } else if (timeEMTD > 0) { // Ignore HGCal timing until it will be TOF corrected - time = timeMTD; - timeE = timeEMTD; + if (isTICLv5_) { + candidate.setTime(ticl_cand.time(), ticl_cand.timeError()); + } else { + // HGCAL timing as default values + auto time = ticl_cand.time(); + auto timeE = ticl_cand.timeError(); + + if (useMTDTiming_ and candidate.charge()) { + // Ignore HGCAL timing until it will be TOF corrected + time = -99.; + timeE = -1.; + // Check MTD timing availability + const bool assocQuality = (*trackTimeQualH)[candidate.trackRef()] > timingQualityThreshold_; + if (assocQuality) { + const auto timeHGC = time; + const auto timeEHGC = timeE; + const auto timeMTD = (*trackTimeH)[candidate.trackRef()]; + const auto timeEMTD = (*trackTimeErrH)[candidate.trackRef()]; + + if (useTimingAverage_ && (timeEMTD > 0 && timeEHGC > 0)) { + // Compute weighted average between HGCAL and MTD timing + const auto invTimeESqHGC = pow(timeEHGC, -2); + const auto invTimeESqMTD = pow(timeEMTD, -2); + timeE = 1.f / (invTimeESqHGC + invTimeESqMTD); + time = (timeHGC * invTimeESqHGC + timeMTD * invTimeESqMTD) * timeE; + timeE = sqrt(timeE); + } else if (timeEMTD > 0) { // Ignore HGCal timing until it will be TOF corrected + time = timeMTD; + timeE = timeEMTD; + } } } + candidate.setTime(time, timeE); } - candidate.setTime(time, timeE); } evt.put(std::move(candidates)); diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.cc b/RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.cc index ac6296db5bf3b..3ca289ff9e77d 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.cc +++ b/RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.cc @@ -2,6 +2,7 @@ #include "PatternRecognitionbyCA.h" #include "PatternRecognitionbyCLUE3D.h" #include "PatternRecognitionbyFastJet.h" +#include "PatternRecognitionbyPassthrough.h" #include "FWCore/ParameterSet/interface/ValidatedPluginFactoryMacros.h" #include "FWCore/ParameterSet/interface/ValidatedPluginMacros.h" @@ -10,4 +11,7 @@ EDM_REGISTER_VALIDATED_PLUGINFACTORY(PatternRecognitionHFNoseFactory, "PatternRe 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(PatternRecognitionFactory, + ticl::PatternRecognitionbyPassthrough, + "Passthrough"); DEFINE_EDM_VALIDATED_PLUGIN(PatternRecognitionHFNoseFactory, ticl::PatternRecognitionbyCA, "CA"); diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc index d4cb8d1f3a514..582cf9fe324a5 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc @@ -46,6 +46,7 @@ PatternRecognitionbyCA::PatternRecognitionbyCA(const edm::ParameterSet &c 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")){}; template @@ -182,7 +183,8 @@ void PatternRecognitionbyCA::makeTracksters( ticl::assignPCAtoTracksters(tmpTracksters, input.layerClusters, input.layerClustersTime, - rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z()); + rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z(), + computeLocalTime_); // run energy regression and ID energyRegressionAndID(input.layerClusters, input.tfSession, tmpTracksters); @@ -243,7 +245,8 @@ void PatternRecognitionbyCA::makeTracksters( ticl::assignPCAtoTracksters(result, input.layerClusters, input.layerClustersTime, - rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z()); + rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z(), + computeLocalTime_); // run energy regression and ID energyRegressionAndID(input.layerClusters, input.tfSession, result); @@ -509,6 +512,7 @@ void PatternRecognitionbyCA::fillPSetDescription(edm::ParameterSetDescrip 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 1912520d89138..90bcddf06eabf 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h @@ -61,6 +61,7 @@ namespace ticl { const float eidMinClusterEnergy_; const int eidNLayers_; const int eidNClusters_; + const bool computeLocalTime_; hgcal::RecHitTools rhtools_; tensorflow::Session* eidSession_; diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.cc index 1c804857d6bc9..0fcf37ebc2e43 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.cc +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.cc @@ -21,28 +21,31 @@ template PatternRecognitionbyCLUE3D::PatternRecognitionbyCLUE3D(const edm::ParameterSet &conf, edm::ConsumesCollector iC) : PatternRecognitionAlgoBaseT(conf, iC), caloGeomToken_(iC.esConsumes()), - criticalDensity_(conf.getParameter("criticalDensity")), - criticalSelfDensity_(conf.getParameter("criticalSelfDensity")), - densitySiblingLayers_(conf.getParameter("densitySiblingLayers")), - densityEtaPhiDistanceSqr_(conf.getParameter("densityEtaPhiDistanceSqr")), - densityXYDistanceSqr_(conf.getParameter("densityXYDistanceSqr")), - kernelDensityFactor_(conf.getParameter("kernelDensityFactor")), + criticalDensity_(conf.getParameter>("criticalDensity")), + criticalSelfDensity_(conf.getParameter>("criticalSelfDensity")), + densitySiblingLayers_(conf.getParameter>("densitySiblingLayers")), + densityEtaPhiDistanceSqr_(conf.getParameter>("densityEtaPhiDistanceSqr")), + densityXYDistanceSqr_(conf.getParameter>("densityXYDistanceSqr")), + kernelDensityFactor_(conf.getParameter>("kernelDensityFactor")), densityOnSameLayer_(conf.getParameter("densityOnSameLayer")), nearestHigherOnSameLayer_(conf.getParameter("nearestHigherOnSameLayer")), useAbsoluteProjectiveScale_(conf.getParameter("useAbsoluteProjectiveScale")), useClusterDimensionXY_(conf.getParameter("useClusterDimensionXY")), rescaleDensityByZ_(conf.getParameter("rescaleDensityByZ")), - criticalEtaPhiDistance_(conf.getParameter("criticalEtaPhiDistance")), - criticalXYDistance_(conf.getParameter("criticalXYDistance")), - criticalZDistanceLyr_(conf.getParameter("criticalZDistanceLyr")), - outlierMultiplier_(conf.getParameter("outlierMultiplier")), - minNumLayerCluster_(conf.getParameter("minNumLayerCluster")), + criticalEtaPhiDistance_(conf.getParameter>("criticalEtaPhiDistance")), + criticalXYDistance_(conf.getParameter>("criticalXYDistance")), + criticalZDistanceLyr_(conf.getParameter>("criticalZDistanceLyr")), + outlierMultiplier_(conf.getParameter>("outlierMultiplier")), + 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")){}; + eidNClusters_(conf.getParameter("eid_n_clusters")), + computeLocalTime_(conf.getParameter("computeLocalTime")){}; template void PatternRecognitionbyCLUE3D::dumpTiles(const TILES &tiles) const { @@ -175,6 +178,8 @@ void PatternRecognitionbyCLUE3D::makeTracksters( } clusters_.clear(); + tracksterSeedAlgoId_.clear(); + clusters_.resize(2 * rhtools_.lastLayer(false)); std::vector> layerIdx2layerandSoa; //used everywhere also to propagate cluster masking @@ -194,8 +199,8 @@ void PatternRecognitionbyCLUE3D::makeTracksters( rhtools_.lastLayer(false) * ((rhtools_.zside(firstHitDetId) + 1) >> 1); assert(layer >= 0); auto detId = lc.hitsAndFractions()[0].first; - - layerIdx2layerandSoa.emplace_back(layer, clusters_[layer].x.size()); + int layerClusterIndexInLayer = clusters_[layer].x.size(); + layerIdx2layerandSoa.emplace_back(layer, layerClusterIndexInLayer); float sum_x = 0.; float sum_y = 0.; float sum_sqr_x = 0.; @@ -246,6 +251,8 @@ void PatternRecognitionbyCLUE3D::makeTracksters( } } } + + // Maybe check if these vectors can be reserved beforehands clusters_[layer].x.emplace_back(lc.x()); clusters_[layer].y.emplace_back(lc.y()); clusters_[layer].z.emplace_back(lc.z()); @@ -254,6 +261,7 @@ void PatternRecognitionbyCLUE3D::makeTracksters( clusters_[layer].eta.emplace_back(lc.eta()); clusters_[layer].phi.emplace_back(lc.phi()); clusters_[layer].cells.push_back(lc.hitsAndFractions().size()); + clusters_[layer].algoId.push_back(lc.algo() - reco::CaloCluster::hgcal_em); clusters_[layer].isSilicon.push_back(rhtools_.isSilicon(detId)); clusters_[layer].energy.emplace_back(lc.energy()); clusters_[layer].isSeed.push_back(false); @@ -313,21 +321,34 @@ void PatternRecognitionbyCLUE3D::makeTracksters( } } } - - result.erase( - std::remove_if(std::begin(result), - std::end(result), - [&](auto const &v) { return static_cast(v.vertices().size()) < minNumLayerCluster_; }), - result.end()); + size_t tracksterIndex = 0; + result.erase(std::remove_if(std::begin(result), + std::end(result), + [&](auto const &v) { + return static_cast(v.vertices().size()) < + 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, input.layerClusters, input.layerClustersTime, - rhtools_.getPositionLayer(rhtools_.lastLayerEE(false), false).z()); + rhtools_.getPositionLayer(rhtools_.lastLayerEE(false), false).z(), + computeLocalTime_); - // run energy regression and ID - energyRegressionAndID(input.layerClusters, input.tfSession, result); if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Advanced) { for (auto const &t : result) { edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Barycenter: " << t.barycenter(); @@ -506,16 +527,17 @@ void PatternRecognitionbyCLUE3D::calculateLocalDensity( }; for (unsigned int i = 0; i < numberOfClusters; i++) { + auto algoId = clustersOnLayer.algoId[i]; // We need to partition the two sides of the HGCAL detector auto lastLayerPerSide = static_cast(rhtools_.lastLayer(false)); int minLayer = 0; int maxLayer = 2 * lastLayerPerSide - 1; if (layerId < lastLayerPerSide) { - minLayer = std::max(layerId - densitySiblingLayers_, minLayer); - maxLayer = std::min(layerId + densitySiblingLayers_, lastLayerPerSide - 1); + minLayer = std::max(layerId - densitySiblingLayers_[algoId], minLayer); + maxLayer = std::min(layerId + densitySiblingLayers_[algoId], lastLayerPerSide - 1); } else { - minLayer = std::max(layerId - densitySiblingLayers_, lastLayerPerSide); - maxLayer = std::min(layerId + densitySiblingLayers_, maxLayer); + minLayer = std::max(layerId - densitySiblingLayers_[algoId], lastLayerPerSide); + maxLayer = std::min(layerId + densitySiblingLayers_[algoId], maxLayer); } float deltaLayersZ = std::abs(layersPosZ_[maxLayer % lastLayerPerSide] - layersPosZ_[minLayer % lastLayerPerSide]); @@ -589,13 +611,13 @@ void PatternRecognitionbyCLUE3D::calculateLocalDensity( clustersOnLayer.radius[i] * clustersOnLayer.radius[i]); } else { // Still differentiate between silicon and Scintillator. - // Silicon has yet to be studied further. + // Scintillator has yet to be studied further. if (clustersOnLayer.isSilicon[i]) { reachable = isReachable(clustersOnLayer.r_over_absz[i] * clustersOnLayer.z[i], clustersLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[i], clustersOnLayer.phi[i], clustersLayer.phi[layerandSoa.second], - densityXYDistanceSqr_); + densityXYDistanceSqr_[algoId]); } else { reachable = isReachable(clustersOnLayer.r_over_absz[i] * clustersOnLayer.z[i], clustersLayer.r_over_absz[layerandSoa.second] * clustersOnLayer.z[i], @@ -608,7 +630,7 @@ void PatternRecognitionbyCLUE3D::calculateLocalDensity( reachable = (reco::deltaR2(clustersOnLayer.eta[i], clustersOnLayer.phi[i], clustersLayer.eta[layerandSoa.second], - clustersLayer.phi[layerandSoa.second]) < densityEtaPhiDistanceSqr_); + clustersLayer.phi[layerandSoa.second]) < densityEtaPhiDistanceSqr_[algoId]); } if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Advanced) { edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Distance[eta,phi]: " @@ -627,8 +649,11 @@ void PatternRecognitionbyCLUE3D::calculateLocalDensity( edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Cluster radius: " << clustersOnLayer.radius[i]; } if (reachable) { - auto energyToAdd = - (onSameCluster ? 1.f : kernelDensityFactor_) * clustersLayer.energy[layerandSoa.second]; + float factor_same_layer_different_cluster = (onSameLayer && !densityOnSameLayer_) ? 0.f : 1.f; + auto energyToAdd = (clustersOnLayer.layerClusterOriginalIdx[i] == otherClusterIdx + ? 1.f + : kernelDensityFactor_[algoId] * factor_same_layer_different_cluster) * + clustersLayer.energy[layerandSoa.second]; clustersOnLayer.rho[i] += energyToAdd; clustersOnLayer.z_extension[i] = deltaLayersZ; if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Advanced) { @@ -675,12 +700,13 @@ void PatternRecognitionbyCLUE3D::calculateDistanceToHigher( auto lastLayerPerSide = static_cast(rhtools_.lastLayer(false)); int minLayer = 0; int maxLayer = 2 * lastLayerPerSide - 1; + auto algoId = clustersOnLayer.algoId[i]; if (layerId < lastLayerPerSide) { - minLayer = std::max(layerId - densitySiblingLayers_, minLayer); - maxLayer = std::min(layerId + densitySiblingLayers_, lastLayerPerSide - 1); + minLayer = std::max(layerId - densitySiblingLayers_[algoId], minLayer); + maxLayer = std::min(layerId + densitySiblingLayers_[algoId], lastLayerPerSide - 1); } else { - minLayer = std::max(layerId - densitySiblingLayers_, lastLayerPerSide + 1); - maxLayer = std::min(layerId + densitySiblingLayers_, maxLayer); + minLayer = std::max(layerId - densitySiblingLayers_[algoId], lastLayerPerSide + 1); + maxLayer = std::min(layerId + densitySiblingLayers_[algoId], maxLayer); } constexpr float maxDelta = std::numeric_limits::max(); float i_delta = maxDelta; @@ -760,9 +786,9 @@ template int PatternRecognitionbyCLUE3D::findAndAssignTracksters( const TILES &tiles, const std::vector> &layerIdx2layerandSoa) { unsigned int nTracksters = 0; - std::vector> localStack; - auto critical_transverse_distance = useAbsoluteProjectiveScale_ ? criticalXYDistance_ : criticalEtaPhiDistance_; + const auto &critical_transverse_distance = + useAbsoluteProjectiveScale_ ? criticalXYDistance_ : criticalEtaPhiDistance_; // find cluster seeds and outlier for (unsigned int layer = 0; layer < 2 * rhtools_.lastLayer(); layer++) { auto &clustersOnLayer = clusters_[layer]; @@ -770,24 +796,27 @@ int PatternRecognitionbyCLUE3D::findAndAssignTracksters( for (unsigned int i = 0; i < numberOfClusters; i++) { // initialize clusterIndex clustersOnLayer.clusterIndex[i] = -1; - bool isSeed = (clustersOnLayer.delta[i].first > critical_transverse_distance || - clustersOnLayer.delta[i].second > criticalZDistanceLyr_) && - (clustersOnLayer.rho[i] >= criticalDensity_) && - (clustersOnLayer.energy[i] / clustersOnLayer.rho[i] > criticalSelfDensity_); + auto algoId = clustersOnLayer.algoId[i]; + bool isSeed = (clustersOnLayer.delta[i].first > critical_transverse_distance[algoId] || + clustersOnLayer.delta[i].second > criticalZDistanceLyr_[algoId]) && + (clustersOnLayer.rho[i] >= criticalDensity_[algoId]) && + (clustersOnLayer.energy[i] / clustersOnLayer.rho[i] > criticalSelfDensity_[algoId]); if (!clustersOnLayer.isSilicon[i]) { isSeed = (clustersOnLayer.delta[i].first > clustersOnLayer.radius[i] || - clustersOnLayer.delta[i].second > criticalZDistanceLyr_) && - (clustersOnLayer.rho[i] >= criticalDensity_) && - (clustersOnLayer.energy[i] / clustersOnLayer.rho[i] > criticalSelfDensity_); + clustersOnLayer.delta[i].second > criticalZDistanceLyr_[algoId]) && + (clustersOnLayer.rho[i] >= criticalDensity_[algoId]) && + (clustersOnLayer.energy[i] / clustersOnLayer.rho[i] > criticalSelfDensity_[algoId]); } - bool isOutlier = (clustersOnLayer.delta[i].first > outlierMultiplier_ * critical_transverse_distance) && - (clustersOnLayer.rho[i] < criticalDensity_); + bool isOutlier = + (clustersOnLayer.delta[i].first > outlierMultiplier_[algoId] * critical_transverse_distance[algoId]) && + (clustersOnLayer.rho[i] < criticalDensity_[algoId]); if (isSeed) { if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Advanced) { edm::LogVerbatim("PatternRecognitionbyCLUE3D") << "Found seed on Layer " << layer << " SOAidx: " << i << " assigned ClusterIdx: " << nTracksters; } clustersOnLayer.clusterIndex[i] = nTracksters++; + tracksterSeedAlgoId_.push_back(algoId); clustersOnLayer.isSeed[i] = true; localStack.emplace_back(layer, i); } else if (!isOutlier) { @@ -829,16 +858,17 @@ int PatternRecognitionbyCLUE3D::findAndAssignTracksters( template void PatternRecognitionbyCLUE3D::fillPSetDescription(edm::ParameterSetDescription &iDesc) { iDesc.add("algo_verbosity", 0); - iDesc.add("criticalDensity", 4)->setComment("in GeV"); - iDesc.add("criticalSelfDensity", 0.15 /* roughly 1/(densitySiblingLayers+1) */) + iDesc.add>("criticalDensity", {4, 4, 4})->setComment("in GeV"); + iDesc.add>("criticalSelfDensity", {0.15, 0.15, 0.15} /* roughly 1/(densitySiblingLayers+1) */) ->setComment("Minimum ratio of self_energy/local_density to become a seed."); - iDesc.add("densitySiblingLayers", 3) + iDesc.add>("densitySiblingLayers", {3, 3, 3}) ->setComment( "inclusive, layers to consider while computing local density and searching for nearestHigher higher"); - iDesc.add("densityEtaPhiDistanceSqr", 0.0008); - iDesc.add("densityXYDistanceSqr", 3.24 /*6.76*/) - ->setComment("in cm, 2.6*2.6, distance on the transverse plane to consider for local density"); - iDesc.add("kernelDensityFactor", 0.2) + iDesc.add>("densityEtaPhiDistanceSqr", {0.0008, 0.0008, 0.0008}) + ->setComment("in eta,phi space, distance to consider for local density"); + iDesc.add>("densityXYDistanceSqr", {3.24, 3.24, 3.24}) + ->setComment("in cm, distance on the transverse plane to consider for local density"); + iDesc.add>("kernelDensityFactor", {0.2, 0.2, 0.2}) ->setComment("Kernel factor to be applied to other LC while computing the local density"); iDesc.add("densityOnSameLayer", false); iDesc.add("nearestHigherOnSameLayer", false) @@ -853,20 +883,24 @@ void PatternRecognitionbyCLUE3D::fillPSetDescription(edm::ParameterSetDes ->setComment( "Rescale local density by the extension of the Z 'volume' explored. The transvere dimension is, at present, " "fixed and factored out."); - iDesc.add("criticalEtaPhiDistance", 0.025) + iDesc.add>("criticalEtaPhiDistance", {0.025, 0.025, 0.025}) ->setComment("Minimal distance in eta,phi space from nearestHigher to become a seed"); - iDesc.add("criticalXYDistance", 1.8) + iDesc.add>("criticalXYDistance", {1.8, 1.8, 1.8}) ->setComment("Minimal distance in cm on the XY plane from nearestHigher to become a seed"); - iDesc.add("criticalZDistanceLyr", 5) + iDesc.add>("criticalZDistanceLyr", {5, 5, 5}) ->setComment("Minimal distance in layers along the Z axis from nearestHigher to become a seed"); - iDesc.add("outlierMultiplier", 2); - iDesc.add("minNumLayerCluster", 2)->setComment("Not Inclusive"); + iDesc.add>("outlierMultiplier", {2, 2, 2}) + ->setComment("Minimal distance in transverse space from nearestHigher to become an outlier"); + 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); } template class ticl::PatternRecognitionbyCLUE3D; diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.h index 8e77ff55e605e..243cd441732d3 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.h +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCLUE3D.h @@ -34,6 +34,7 @@ namespace ticl { std::vector eta; std::vector phi; std::vector cells; + std::vector algoId; // hgcal_em = 6, hgcal_had = 7, hgcal_scintillator = 8, hfnose = 9 std::vector isSilicon; std::vector energy; @@ -56,6 +57,7 @@ namespace ticl { eta.clear(); phi.clear(); cells.clear(); + algoId.clear(); isSilicon.clear(); energy.clear(); rho.clear(); @@ -77,6 +79,7 @@ namespace ticl { eta.shrink_to_fit(); phi.shrink_to_fit(); cells.shrink_to_fit(); + algoId.shrink_to_fit(); isSilicon.shrink_to_fit(); energy.shrink_to_fit(); rho.shrink_to_fit(); @@ -109,24 +112,27 @@ namespace ticl { std::vector clusters_; std::vector layersPosZ_; + std::vector tracksterSeedAlgoId_; edm::ESGetToken caloGeomToken_; - const double criticalDensity_; - const double criticalSelfDensity_; - const int densitySiblingLayers_; - const double densityEtaPhiDistanceSqr_; - const double densityXYDistanceSqr_; - const double kernelDensityFactor_; + const std::vector criticalDensity_; + const std::vector criticalSelfDensity_; + const std::vector densitySiblingLayers_; + const std::vector densityEtaPhiDistanceSqr_; + const std::vector densityXYDistanceSqr_; + const std::vector kernelDensityFactor_; const bool densityOnSameLayer_; const bool nearestHigherOnSameLayer_; const bool useAbsoluteProjectiveScale_; const bool useClusterDimensionXY_; const bool rescaleDensityByZ_; - const double criticalEtaPhiDistance_; - const double criticalXYDistance_; - const int criticalZDistanceLyr_; - const double outlierMultiplier_; - const int minNumLayerCluster_; + const std::vector criticalEtaPhiDistance_; + const std::vector criticalXYDistance_; + const std::vector criticalZDistanceLyr_; + const std::vector outlierMultiplier_; + const std::vector minNumLayerCluster_; + const bool doPidCut_; + const float cutHadProb_; const std::vector filter_on_categories_; const std::string eidInputName_; const std::string eidOutputNameEnergy_; @@ -134,6 +140,7 @@ namespace ticl { const float eidMinClusterEnergy_; const int eidNLayers_; const int eidNClusters_; + const bool computeLocalTime_; hgcal::RecHitTools rhtools_; tensorflow::Session* eidSession_; diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc index 09814ac13556c..5615ca3751d9d 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.cc @@ -37,7 +37,8 @@ PatternRecognitionbyFastJet::PatternRecognitionbyFastJet(const edm::Param 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")){}; + eidNClusters_(conf.getParameter("eid_n_clusters")), + computeLocalTime_(conf.getParameter("computeLocalTime")){}; template void PatternRecognitionbyFastJet::buildJetAndTracksters(std::vector &fjInputs, @@ -144,7 +145,8 @@ void PatternRecognitionbyFastJet::makeTracksters( ticl::assignPCAtoTracksters(result, input.layerClusters, input.layerClustersTime, - rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z()); + rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z(), + computeLocalTime_); // run energy regression and ID energyRegressionAndID(input.layerClusters, input.tfSession, result); @@ -309,6 +311,7 @@ void PatternRecognitionbyFastJet::fillPSetDescription(edm::ParameterSetDe iDesc.add("eid_min_cluster_energy", 1.); iDesc.add("eid_n_layers", 50); iDesc.add("eid_n_clusters", 10); + iDesc.add("computeLocalTime", false); } template class ticl::PatternRecognitionbyFastJet; diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h index 2524a29921019..2811b54c8e6e4 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyFastJet.h @@ -40,6 +40,7 @@ namespace ticl { const float eidMinClusterEnergy_; const int eidNLayers_; const int eidNClusters_; + const bool computeLocalTime_; hgcal::RecHitTools rhtools_; tensorflow::Session* eidSession_; diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.cc deleted file mode 100644 index 68f303b5a0bc3..0000000000000 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include "PatternRecognitionbyMultiClusters.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" - -template -void ticl::PatternRecognitionbyMultiClusters::makeTracksters( - const typename PatternRecognitionAlgoBaseT::Inputs& input, - std::vector& result, - std::unordered_map>& seedToTracksterAssociation) { - LogDebug("HGCPatterRecoTrackster") << "making Tracksters" << std::endl; -} diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.h deleted file mode 100644 index c4702c36b6267..0000000000000 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.h +++ /dev/null @@ -1,29 +0,0 @@ -// Author: Felice Pantaleo - felice.pantaleo@cern.ch -// Date: 09/2018 - -#ifndef __RecoHGCal_TICL_PRbyMultiClusters_H__ -#define __RecoHGCal_TICL_PRbyMultiClusters_H__ -#include "RecoHGCal/TICL/interface/PatternRecognitionAlgoBase.h" - -#include - -namespace edm { - class ParameterSet; - class Event; - class EventSetup; -} // namespace edm - -namespace ticl { - template - class PatternRecognitionbyMultiClusters final : public PatternRecognitionAlgoBaseT { - public: - PatternRecognitionbyMultiClusters(const edm::ParameterSet& conf, const CacheBase* cache) - : PatternRecognitionAlgoBaseT(conf, cache) {} - ~PatternRecognitionbyMultiClusters() override{}; - - void makeTracksters(const typename PatternRecognitionAlgoBaseT::Inputs& input, - std::vector& result, - std::unordered_map>& seedToTracksterAssociation) override; - }; -} // namespace ticl -#endif diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.cc new file mode 100644 index 0000000000000..8f587ccb88ef3 --- /dev/null +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.cc @@ -0,0 +1,71 @@ +// Author: Felice Pantaleo - felice.pantaleo@cern.ch +// Date: 05/2024 + +#include +#include "DataFormats/Math/interface/deltaR.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "PatternRecognitionbyPassthrough.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "TrackstersPCA.h" + +using namespace ticl; + +template +PatternRecognitionbyPassthrough::PatternRecognitionbyPassthrough(const edm::ParameterSet &conf, + edm::ConsumesCollector iC) + : PatternRecognitionAlgoBaseT(conf, iC), caloGeomToken_(iC.esConsumes()) {} + +template +void PatternRecognitionbyPassthrough::makeTracksters( + const typename PatternRecognitionAlgoBaseT::Inputs &input, + std::vector &result, + std::unordered_map> &seedToTracksterAssociation) { + // Get the geometry setup + edm::EventSetup const &es = input.es; + const CaloGeometry &geom = es.getData(caloGeomToken_); + rhtools_.setGeometry(geom); + + // Clear the result vector + result.clear(); + + // Iterate over all layer clusters + for (size_t i = 0; i < input.layerClusters.size(); ++i) { + if (input.mask[i] == 0.) { + continue; // Skip masked clusters + } + + // Create a new trackster for each layer cluster + Trackster trackster; + trackster.vertices().push_back(i); + trackster.vertex_multiplicity().push_back(1); + + // Add the trackster to the result vector + result.push_back(trackster); + } + + // Assign PCA to tracksters + ticl::assignPCAtoTracksters(result, + input.layerClusters, + input.layerClustersTime, + rhtools_.getPositionLayer(rhtools_.lastLayerEE(false), false).z(), + false); + + // Log the number of tracksters created + if (PatternRecognitionAlgoBaseT::algo_verbosity_ > VerbosityLevel::Advanced) { + edm::LogVerbatim("PatternRecognitionbyPassthrough") << "Created " << result.size() << " tracksters"; + } +} + +template +void PatternRecognitionbyPassthrough::fillPSetDescription(edm::ParameterSetDescription &iDesc) { + iDesc.add("algo_verbosity", 0); +} + +// Explicitly instantiate the templates +template class ticl::PatternRecognitionbyPassthrough; +template class ticl::PatternRecognitionbyPassthrough; diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.h new file mode 100644 index 0000000000000..8ef9a76824be0 --- /dev/null +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyPassthrough.h @@ -0,0 +1,30 @@ +// Author: Felice Pantaleo - felice.pantaleo@cern.ch +// Date: 05/2024 + +#ifndef __RecoHGCal_TICL_PatternRecognitionbyPassthrough_H__ +#define __RecoHGCal_TICL_PatternRecognitionbyPassthrough_H__ +#include // unique_ptr +#include "RecoHGCal/TICL/interface/PatternRecognitionAlgoBase.h" +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" + +namespace ticl { + template + class PatternRecognitionbyPassthrough final : public PatternRecognitionAlgoBaseT { + public: + PatternRecognitionbyPassthrough(const edm::ParameterSet& conf, edm::ConsumesCollector); + ~PatternRecognitionbyPassthrough() override = default; + + void makeTracksters(const typename PatternRecognitionAlgoBaseT::Inputs& input, + std::vector& result, + std::unordered_map>& seedToTracksterAssociation) override; + + static void fillPSetDescription(edm::ParameterSetDescription& iDesc); + + private: + edm::ESGetToken caloGeomToken_; + hgcal::RecHitTools rhtools_; + }; + +} // namespace ticl + +#endif // __RecoHGCal_TICL_PatternRecognitionbyPassthrough_H__ diff --git a/RecoHGCal/TICL/plugins/SimTrackstersProducer.cc b/RecoHGCal/TICL/plugins/SimTrackstersProducer.cc index 4304bf8300152..0b86d999ac80c 100644 --- a/RecoHGCal/TICL/plugins/SimTrackstersProducer.cc +++ b/RecoHGCal/TICL/plugins/SimTrackstersProducer.cc @@ -28,6 +28,8 @@ #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h" #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" +#include "SimDataFormats/CaloAnalysis/interface/MtdSimTrackster.h" +#include "SimDataFormats/CaloAnalysis/interface/MtdSimTracksterFwd.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" #include "SimDataFormats/Vertex/interface/SimVertex.h" @@ -67,7 +69,7 @@ class SimTrackstersProducer : public edm::stream::EDProducer<> { const float energy, const int pdgId, const int charge, - float time, + const float time, const edm::ProductID seed, const Trackster::IterationIndex iter, std::vector& output_mask, @@ -78,12 +80,14 @@ class SimTrackstersProducer : public edm::stream::EDProducer<> { private: std::string detector_; const bool doNose_ = false; + const bool computeLocalTime_; const edm::EDGetTokenT> clusters_token_; const edm::EDGetTokenT>> clustersTime_token_; const edm::EDGetTokenT> filtered_layerclusters_mask_token_; const edm::EDGetTokenT> simclusters_token_; const edm::EDGetTokenT> caloparticles_token_; + const edm::EDGetTokenT MTDSimTrackstersToken_; const edm::EDGetTokenT associatorMapSimClusterToReco_token_; const edm::EDGetTokenT associatorMapCaloParticleToReco_token_; @@ -107,11 +111,13 @@ DEFINE_FWK_MODULE(SimTrackstersProducer); SimTrackstersProducer::SimTrackstersProducer(const edm::ParameterSet& ps) : detector_(ps.getParameter("detector")), doNose_(detector_ == "HFNose"), + computeLocalTime_(ps.getParameter("computeLocalTime")), 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"))), caloparticles_token_(consumes(ps.getParameter("caloparticles"))), + MTDSimTrackstersToken_(consumes(ps.getParameter("MtdSimTracksters"))), associatorMapSimClusterToReco_token_( consumes(ps.getParameter("layerClusterSimClusterAssociator"))), associatorMapCaloParticleToReco_token_( @@ -138,11 +144,13 @@ SimTrackstersProducer::SimTrackstersProducer(const edm::ParameterSet& ps) void SimTrackstersProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add("detector", "HGCAL"); + desc.add("computeLocalTime", "false"); desc.add("layer_clusters", edm::InputTag("hgcalMergeLayerClusters")); desc.add("time_layerclusters", edm::InputTag("hgcalMergeLayerClusters", "timeLayerCluster")); desc.add("filtered_mask", edm::InputTag("filteredLayerClustersSimTracksters", "ticlSimTracksters")); desc.add("simclusters", edm::InputTag("mix", "MergedCaloTruth")); desc.add("caloparticles", edm::InputTag("mix", "MergedCaloTruth")); + desc.add("MtdSimTracksters", edm::InputTag("mix", "MergedMtdTruthST")); desc.add("layerClusterSimClusterAssociator", edm::InputTag("layerClusterSimClusterAssociationProducer")); desc.add("layerClusterCaloParticleAssociator", @@ -217,6 +225,7 @@ void SimTrackstersProducer::addTrackster( tmpTrackster.setRegressedEnergy(energy); tmpTrackster.setIteration(iter); tmpTrackster.setSeed(seed, index); + tmpTrackster.setBoundaryTime(time * 1e9); if (add) { result[index] = tmpTrackster; loop_index += 1; @@ -245,6 +254,9 @@ void SimTrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) evt.getByToken(caloparticles_token_, caloParticles_h); const auto& caloparticles = *caloParticles_h; + edm::Handle MTDSimTracksters_h; + evt.getByToken(MTDSimTrackstersToken_, MTDSimTracksters_h); + const auto& simClustersToRecoColl = evt.get(associatorMapSimClusterToReco_token_); const auto& caloParticlesToRecoColl = evt.get(associatorMapCaloParticleToReco_token_); const auto& simVertices = evt.get(simVerticesToken_); @@ -353,11 +365,17 @@ void SimTrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) } // TODO: remove time computation from PCA calculation and // store time from boundary position in simTracksters - ticl::assignPCAtoTracksters( - *result, layerClusters, layerClustersTimes, rhtools_.getPositionLayer(rhtools_.lastLayerEE(doNose_)).z()); + ticl::assignPCAtoTracksters(*result, + layerClusters, + layerClustersTimes, + rhtools_.getPositionLayer(rhtools_.lastLayerEE(doNose_)).z(), + computeLocalTime_); result->shrink_to_fit(); - ticl::assignPCAtoTracksters( - *result_fromCP, layerClusters, layerClustersTimes, rhtools_.getPositionLayer(rhtools_.lastLayerEE(doNose_)).z()); + ticl::assignPCAtoTracksters(*result_fromCP, + layerClusters, + layerClustersTimes, + rhtools_.getPositionLayer(rhtools_.lastLayerEE(doNose_)).z(), + computeLocalTime_); makePUTrackster(inputClusterMask, *output_mask, *resultPU, caloParticles_h.id(), 0); @@ -412,6 +430,13 @@ void SimTrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) edm::OrphanHandle> simTracksters_h = evt.put(std::move(result)); + // map between simTrack and Mtd SimTracksters to loop on them only one + std::unordered_map SimTrackToMtdST; + for (unsigned int i = 0; i < MTDSimTracksters_h->size(); ++i) { + const auto& simTrack = (*MTDSimTracksters_h)[i].g4Tracks()[0]; + SimTrackToMtdST[simTrack.trackId()] = &((*MTDSimTracksters_h)[i]); + } + result_ticlCandidates->resize(result_fromCP->size()); std::vector toKeep; for (size_t i = 0; i < simTracksters_h->size(); ++i) { @@ -425,10 +450,6 @@ void SimTrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) auto& cand = (*result_ticlCandidates)[cp_index]; cand.addTrackster(edm::Ptr(simTracksters_h, i)); - if (trackIndex != -1 and (trackIndex < 0 or trackIndex >= (long int)recoTracks.size())) { - } - cand.setTime((*result_fromCP)[cp_index].time()); - cand.setTimeError(0); if (trackIndex != -1 && caloparticles[cp_index].charge() != 0) cand.setTrackPtr(edm::Ptr(recoTracks_h, trackIndex)); toKeep.push_back(cp_index); @@ -451,6 +472,16 @@ void SimTrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) float rawEnergy = 0.f; float regressedEnergy = 0.f; + const auto& simTrack = cp.g4Tracks()[0]; + auto pos = SimTrackToMtdST.find(simTrack.trackId()); + if (pos != SimTrackToMtdST.end()) { + auto MTDst = pos->second; + // TODO: once the associators have been implemented check if the MTDst is associated with a reco before adding the MTD time + cand.setMTDTime(MTDst->time(), 0); + } + + cand.setTime(simVertices[cp.g4Tracks()[0].vertIndex()].position().t() * pow(10, 9), 0); + for (const auto& trackster : cand.tracksters()) { rawEnergy += trackster->raw_energy(); regressedEnergy += trackster->regressed_energy(); @@ -459,9 +490,7 @@ void SimTrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) auto pdgId = cp.pdgId(); auto charge = cp.charge(); - if (cand.trackPtr().isNonnull() and charge == 0) { - } - if (cand.trackPtr().isNonnull() and charge != 0) { + if (cand.trackPtr().isNonnull()) { auto const& track = cand.trackPtr().get(); if (std::abs(pdgId) == 13) { cand.setPdgId(pdgId); @@ -475,7 +504,14 @@ void SimTrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) regressedEnergy); cand.setP4(p4); } else { // neutral candidates - cand.setPdgId(isHad(pdgId) ? 130 : 22); + // a neutral candidate with a charged CaloParticle is charged without a reco track associated with it + // set the charge = 0, but keep the real pdgId to keep track of that + if (charge != 0) + cand.setPdgId(isHad(pdgId) ? 211 : 11); + else if (pdgId == 111) + cand.setPdgId(pdgId); + else + cand.setPdgId(isHad(pdgId) ? 130 : 22); cand.setCharge(0); auto particleType = tracksterParticleTypeFromPdgId(cand.pdgId(), 1); diff --git a/RecoHGCal/TICL/plugins/TICLCandidateProducer.cc b/RecoHGCal/TICL/plugins/TICLCandidateProducer.cc new file mode 100644 index 0000000000000..53c9bdcaa7282 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TICLCandidateProducer.cc @@ -0,0 +1,525 @@ +// Author: Felice Pantaleo, Wahid Redjeb, Aurora Perego (CERN) - felice.pantaleo@cern.ch, wahid.redjeb@cern.ch, aurora.perego@cern.ch +// Date: 12/2023 +#include // unique_ptr +#include "CommonTools/RecoAlgos/interface/MultiVectorManager.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/PluginDescription.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "DataFormats/Common/interface/OrphanHandle.h" + +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/CaloRecHit/interface/CaloCluster.h" +#include "DataFormats/HGCalReco/interface/Common.h" +#include "DataFormats/HGCalReco/interface/MtdHostCollection.h" +#include "DataFormats/HGCalReco/interface/TICLLayerTile.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/MuonReco/interface/Muon.h" +#include "DataFormats/GeometrySurface/interface/BoundDisk.h" +#include "DataFormats/HGCalReco/interface/TICLCandidate.h" +#include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" + +#include "RecoHGCal/TICL/interface/TICLInterpretationAlgoBase.h" +#include "RecoHGCal/TICL/plugins/TICLInterpretationPluginFactory.h" +#include "RecoHGCal/TICL/plugins/GeneralInterpretationAlgo.h" + +#include "RecoParticleFlow/PFProducer/interface/PFMuonAlgo.h" + +#include "RecoHGCal/TICL/interface/GlobalCache.h" +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" + +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" +#include "TrackingTools/GeomPropagators/interface/Propagator.h" +#include "TrackingTools/Records/interface/TrackingComponentsRecord.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateClosestToBeamLine.h" +#include "TrackingTools/PatternTools/interface/Trajectory.h" +#include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h" +#include "TrackingTools/PatternTools/interface/TSCBLBuilderWithPropagator.h" + +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" + +#include "Geometry/HGCalCommonData/interface/HGCalDDDConstants.h" +#include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "Geometry/CommonDetUnit/interface/GeomDet.h" + +#include "TrackstersPCA.h" + +using namespace ticl; + +class TICLCandidateProducer : public edm::stream::EDProducer<> { +public: + explicit TICLCandidateProducer(const edm::ParameterSet &ps); + ~TICLCandidateProducer() override{}; + void produce(edm::Event &, const edm::EventSetup &) override; + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); + + void beginRun(edm::Run const &iEvent, edm::EventSetup const &es) override; + +private: + void dumpCandidate(const TICLCandidate &) const; + + template + void assignTimeToCandidates(std::vector &resultCandidates, + edm::Handle> track_h, + edm::Handle inputTiming_h, + TrajTrackAssociationCollection trjtrks, + F func) const; + + std::unique_ptr> generalInterpretationAlgo_; + std::vector>> egamma_tracksters_tokens_; + std::vector>>> egamma_tracksterlinks_tokens_; + + std::vector>> general_tracksters_tokens_; + std::vector>>> general_tracksterlinks_tokens_; + + const edm::EDGetTokenT> clusters_token_; + const edm::EDGetTokenT>> clustersTime_token_; + + std::vector>> original_masks_tokens_; + + const edm::EDGetTokenT> tracks_token_; + const edm::EDGetTokenT trajTrackAssToken_; + edm::EDGetTokenT inputTimingToken_; + + const edm::EDGetTokenT> muons_token_; + const bool useMTDTiming_; + const bool useTimingAverage_; + const float timingQualityThreshold_; + const edm::ESGetToken geometry_token_; + + const edm::ESGetToken bfield_token_; + const std::string detector_; + const std::string propName_; + const edm::ESGetToken propagator_token_; + const edm::EDGetTokenT bsToken_; + + std::once_flag initializeGeometry_; + const HGCalDDDConstants *hgcons_; + hgcal::RecHitTools rhtools_; + const float tkEnergyCut_ = 2.0f; + const StringCutObjectSelector cutTk_; + edm::ESGetToken hdc_token_; + edm::ESHandle bfield_; + edm::ESHandle propagator_; + static constexpr float c_light_ = CLHEP::c_light * CLHEP::ns / CLHEP::cm; +}; + +TICLCandidateProducer::TICLCandidateProducer(const edm::ParameterSet &ps) + : clusters_token_(consumes>(ps.getParameter("layer_clusters"))), + clustersTime_token_( + consumes>>(ps.getParameter("layer_clustersTime"))), + tracks_token_(consumes>(ps.getParameter("tracks"))), + trajTrackAssToken_(consumes(ps.getParameter("trjtrkAss"))), + inputTimingToken_(consumes(ps.getParameter("timingSoA"))), + muons_token_(consumes>(ps.getParameter("muons"))), + useMTDTiming_(ps.getParameter("useMTDTiming")), + useTimingAverage_(ps.getParameter("useTimingAverage")), + timingQualityThreshold_(ps.getParameter("timingQualityThreshold")), + geometry_token_(esConsumes()), + bfield_token_(esConsumes()), + detector_(ps.getParameter("detector")), + propName_(ps.getParameter("propagator")), + propagator_token_( + esConsumes(edm::ESInputTag("", propName_))), + bsToken_(consumes(ps.getParameter("beamspot"))), + cutTk_(ps.getParameter("cutTk")) { + // These are the CLUE3DEM Tracksters put in the event by the TracksterLinksProducer with the superclustering algorithm + for (auto const &tag : ps.getParameter>("egamma_tracksters_collections")) { + egamma_tracksters_tokens_.emplace_back(consumes>(tag)); + } + + // These are the links put in the event by the TracksterLinksProducer with the superclustering algorithm + for (auto const &tag : ps.getParameter>("egamma_tracksterlinks_collections")) { + egamma_tracksterlinks_tokens_.emplace_back(consumes>>(tag)); + } + + //make sure that the number of tracksters collections and tracksterlinks collections is the same + assert(egamma_tracksters_tokens_.size() == egamma_tracksterlinks_tokens_.size()); + + // Loop over the edm::VInputTag and append the token to general_tracksters_tokens_ + // These, instead, are the tracksters already merged by the TrackstersLinksProducer + for (auto const &tag : ps.getParameter>("general_tracksters_collections")) { + general_tracksters_tokens_.emplace_back(consumes>(tag)); + } + + for (auto const &tag : ps.getParameter>("general_tracksterlinks_collections")) { + general_tracksterlinks_tokens_.emplace_back(consumes>>(tag)); + } + + //make sure that the number of tracksters collections and tracksterlinks collections is the same + assert(general_tracksters_tokens_.size() == general_tracksterlinks_tokens_.size()); + + //Loop over the edm::VInputTag of masks and append the token to original_masks_tokens_ + for (auto const &tag : ps.getParameter>("original_masks")) { + original_masks_tokens_.emplace_back(consumes>(tag)); + } + + std::string detectorName_ = (detector_ == "HFNose") ? "HGCalHFNoseSensitive" : "HGCalEESensitive"; + hdc_token_ = + esConsumes(edm::ESInputTag("", detectorName_)); + if (useMTDTiming_) { + inputTimingToken_ = consumes(ps.getParameter("timingSoA")); + } + + produces>(); + + // New trackster collection after linking + produces>(); + + auto interpretationPSet = ps.getParameter("interpretationDescPSet"); + auto algoType = interpretationPSet.getParameter("type"); + generalInterpretationAlgo_ = + TICLGeneralInterpretationPluginFactory::get()->create(algoType, interpretationPSet, consumesCollector()); +} + +void TICLCandidateProducer::beginRun(edm::Run const &iEvent, edm::EventSetup const &es) { + edm::ESHandle hdc = es.getHandle(hdc_token_); + hgcons_ = hdc.product(); + + edm::ESHandle geom = es.getHandle(geometry_token_); + rhtools_.setGeometry(*geom); + + bfield_ = es.getHandle(bfield_token_); + propagator_ = es.getHandle(propagator_token_); + generalInterpretationAlgo_->initialize(hgcons_, rhtools_, bfield_, propagator_); +}; + +void filterTracks(edm::Handle> tkH, + const edm::Handle> &muons_h, + const StringCutObjectSelector cutTk_, + const float tkEnergyCut_, + std::vector &maskTracks) { + auto const &tracks = *tkH; + for (unsigned i = 0; i < tracks.size(); ++i) { + const auto &tk = tracks[i]; + reco::TrackRef trackref = reco::TrackRef(tkH, i); + + // veto tracks associated to muons + int muId = PFMuonAlgo::muAssocToTrack(trackref, *muons_h); + const reco::MuonRef muonref = reco::MuonRef(muons_h, muId); + + if (!cutTk_((tk)) or (muId != -1 and PFMuonAlgo::isMuon(muonref) and not(*muons_h)[muId].isTrackerMuon())) { + maskTracks[i] = false; + continue; + } + + // don't consider tracks below 2 GeV for linking + if (std::sqrt(tk.p() * tk.p() + ticl::mpion2) < tkEnergyCut_) { + maskTracks[i] = false; + continue; + } + + // record tracks that can be used to make a ticlcandidate + maskTracks[i] = true; + } +} + +void TICLCandidateProducer::produce(edm::Event &evt, const edm::EventSetup &es) { + auto resultTracksters = std::make_unique>(); + auto resultTrackstersMerged = std::make_unique>(); + auto linkedResultTracksters = std::make_unique>>(); + + const auto &layerClusters = evt.get(clusters_token_); + const auto &layerClustersTimes = evt.get(clustersTime_token_); + edm::Handle muons_h; + evt.getByToken(muons_token_, muons_h); + + edm::Handle> tracks_h; + evt.getByToken(tracks_token_, tracks_h); + const auto &tracks = *tracks_h; + + const auto &trjtrks = evt.get(trajTrackAssToken_); + + edm::Handle inputTiming_h; + if (useMTDTiming_) { + evt.getByToken(inputTimingToken_, inputTiming_h); + } + + const auto &bs = evt.get(bsToken_); + + auto const bFieldProd = bfield_.product(); + const Propagator *propagator = propagator_.product(); + + // loop over the original_masks_tokens_ and get the original masks collections and multiply them + // to get the global mask + std::vector original_global_mask(layerClusters.size(), 1.f); + for (unsigned int i = 0; i < original_masks_tokens_.size(); ++i) { + const auto &tmp_mask = evt.get(original_masks_tokens_[i]); + for (unsigned int j = 0; j < tmp_mask.size(); ++j) { + original_global_mask[j] *= tmp_mask[j]; + } + } + + auto resultMask = std::make_unique>(original_global_mask); + + std::vector>> general_tracksters_h(general_tracksters_tokens_.size()); + MultiVectorManager generalTrackstersManager; + for (unsigned int i = 0; i < general_tracksters_tokens_.size(); ++i) { + evt.getByToken(general_tracksters_tokens_[i], general_tracksters_h[i]); + //Fill MultiVectorManager + generalTrackstersManager.addVector(*general_tracksters_h[i]); + } + //now get the general_tracksterlinks_tokens_ + std::vector>>> general_tracksterlinks_h( + general_tracksterlinks_tokens_.size()); + std::vector> generalTracksterLinksGlobalId; + for (unsigned int i = 0; i < general_tracksterlinks_tokens_.size(); ++i) { + evt.getByToken(general_tracksterlinks_tokens_[i], general_tracksterlinks_h[i]); + for (unsigned int j = 0; j < general_tracksterlinks_h[i]->size(); ++j) { + generalTracksterLinksGlobalId.emplace_back(); + auto &links_vector = generalTracksterLinksGlobalId.back(); + links_vector.resize((*general_tracksterlinks_h[i])[j].size()); + for (unsigned int k = 0; k < links_vector.size(); ++k) { + links_vector[k] = generalTrackstersManager.getGlobalIndex(i, (*general_tracksterlinks_h[i])[j][k]); + } + } + } + + std::vector maskTracks; + maskTracks.resize(tracks.size()); + filterTracks(tracks_h, muons_h, cutTk_, tkEnergyCut_, maskTracks); + + const typename TICLInterpretationAlgoBase::Inputs input(evt, + es, + layerClusters, + layerClustersTimes, + generalTrackstersManager, + generalTracksterLinksGlobalId, + tracks_h, + maskTracks); + + auto resultCandidates = std::make_unique>(); + std::vector trackstersInTrackIndices(tracks.size(), -1); + + //TODO + //egammaInterpretationAlg_->makecandidates(inputGSF, inputTiming, *resultTrackstersMerged, trackstersInGSFTrackIndices) + // mask generalTracks associated to GSFTrack linked in egammaInterpretationAlgo_ + + generalInterpretationAlgo_->makeCandidates(input, inputTiming_h, *resultTracksters, trackstersInTrackIndices); + + assignPCAtoTracksters( + *resultTracksters, layerClusters, layerClustersTimes, rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z(), true); + + std::vector maskTracksters(resultTracksters->size(), true); + edm::OrphanHandle> resultTracksters_h = evt.put(std::move(resultTracksters)); + //create ChargedCandidates + for (size_t iTrack = 0; iTrack < tracks.size(); iTrack++) { + if (maskTracks[iTrack]) { + auto const tracksterId = trackstersInTrackIndices[iTrack]; + auto trackPtr = edm::Ptr(tracks_h, iTrack); + if (tracksterId != -1 and !maskTracksters.empty()) { + auto tracksterPtr = edm::Ptr(resultTracksters_h, tracksterId); + TICLCandidate chargedCandidate(trackPtr, tracksterPtr); + resultCandidates->push_back(chargedCandidate); + maskTracksters[tracksterId] = false; + } else { + //charged candidates track only + edm::Ptr tracksterPtr; + TICLCandidate chargedCandidate(trackPtr, tracksterPtr); + auto trackRef = edm::Ref(tracks_h, iTrack); + const int muId = PFMuonAlgo::muAssocToTrack(trackRef, *muons_h); + const reco::MuonRef muonRef = reco::MuonRef(muons_h, muId); + if (muonRef.isNonnull() and muonRef->isGlobalMuon()) { + // create muon candidate + chargedCandidate.setPdgId(13 * trackPtr.get()->charge()); + } + resultCandidates->push_back(chargedCandidate); + } + } + } + + //Neutral Candidate + for (size_t iTrackster = 0; iTrackster < maskTracksters.size(); iTrackster++) { + if (maskTracksters[iTrackster]) { + edm::Ptr tracksterPtr(resultTracksters_h, iTrackster); + edm::Ptr trackPtr; + TICLCandidate neutralCandidate(trackPtr, tracksterPtr); + resultCandidates->push_back(neutralCandidate); + } + } + + auto getPathLength = + [&](const reco::Track track, float zVal, const Trajectory &traj, TrajectoryStateClosestToBeamLine &tscbl) { + TrajectoryStateOnSurface stateForProjectionToBeamLineOnSurface = + traj.closestMeasurement(GlobalPoint(bs.x0(), bs.y0(), bs.z0())).updatedState(); + + if (!stateForProjectionToBeamLineOnSurface.isValid()) { + edm::LogError("CannotPropagateToBeamLine") + << "the state on the closest measurement is not valid. skipping track."; + return 0.f; + } + const FreeTrajectoryState &stateForProjectionToBeamLine = *stateForProjectionToBeamLineOnSurface.freeState(); + + TSCBLBuilderWithPropagator tscblBuilder(*propagator); + tscbl = tscblBuilder(stateForProjectionToBeamLine, bs); + + if (tscbl.isValid()) { + auto const &tscblPCA = tscbl.trackStateAtPCA(); + auto const &innSurface = traj.direction() == alongMomentum ? traj.firstMeasurement().updatedState().surface() + : traj.lastMeasurement().updatedState().surface(); + auto const &extSurface = traj.direction() == alongMomentum ? traj.lastMeasurement().updatedState().surface() + : traj.firstMeasurement().updatedState().surface(); + float pathlength = propagator->propagateWithPath(tscblPCA, innSurface).second; + + if (pathlength) { + const auto &fts_inn = trajectoryStateTransform::innerFreeState((track), bFieldProd); + const auto &t_inn_out = propagator->propagateWithPath(fts_inn, extSurface); + + if (t_inn_out.first.isValid()) { + pathlength += t_inn_out.second; + + std::pair rMinMax = hgcons_->rangeR(zVal, true); + + int iSide = int(track.eta() > 0); + float zSide = (iSide == 0) ? (-1. * zVal) : zVal; + const auto &disk = std::make_unique( + Disk::build(Disk::PositionType(0, 0, zSide), + Disk::RotationType(), + SimpleDiskBounds(rMinMax.first, rMinMax.second, zSide - 0.5, zSide + 0.5)) + .get()); + const auto &fts_out = trajectoryStateTransform::outerFreeState((track), bFieldProd); + const auto &tsos = propagator->propagateWithPath(fts_out, disk->surface()); + + if (tsos.first.isValid()) { + pathlength += tsos.second; + return pathlength; + } + } + } + } + return 0.f; + }; + + assignTimeToCandidates(*resultCandidates, tracks_h, inputTiming_h, trjtrks, getPathLength); + + evt.put(std::move(resultCandidates)); +} + +template +void TICLCandidateProducer::assignTimeToCandidates(std::vector &resultCandidates, + edm::Handle> track_h, + edm::Handle inputTiming_h, + TrajTrackAssociationCollection trjtrks, + F func) const { + for (auto &cand : resultCandidates) { + float beta = 1; + float time = 0.f; + float invTimeErr = 0.f; + float timeErr = -1.f; + + for (const auto &tr : cand.tracksters()) { + if (tr->timeError() > 0) { + const auto invTimeESq = pow(tr->timeError(), -2); + const auto x = tr->barycenter().X(); + const auto y = tr->barycenter().Y(); + const auto z = tr->barycenter().Z(); + auto path = std::sqrt(x * x + y * y + z * z); + if (cand.trackPtr().get() != nullptr) { + const auto &trackIndex = cand.trackPtr().get() - (edm::Ptr(track_h, 0)).get(); + if (useMTDTiming_) { + auto const &inputTimingView = (*inputTiming_h).const_view(); + if (inputTimingView.timeErr()[trackIndex] > 0) { + const auto xMtd = inputTimingView.posInMTD_x()[trackIndex]; + const auto yMtd = inputTimingView.posInMTD_y()[trackIndex]; + const auto zMtd = inputTimingView.posInMTD_z()[trackIndex]; + + beta = inputTimingView.beta()[trackIndex]; + path = std::sqrt((x - xMtd) * (x - xMtd) + (y - yMtd) * (y - yMtd) + (z - zMtd) * (z - zMtd)) + + inputTimingView.pathLength()[trackIndex]; + } + } else { + const auto &trackIndex = cand.trackPtr().get() - (edm::Ptr(track_h, 0)).get(); + for (const auto &trj : trjtrks) { + if (trj.val != edm::Ref>(track_h, trackIndex)) + continue; + const Trajectory &traj = *trj.key; + TrajectoryStateClosestToBeamLine tscbl; + + float pathLength = func(*(cand.trackPtr().get()), z, traj, tscbl); + if (pathLength) { + path = pathLength; + break; + } + } + } + } + time += (tr->time() - path / (beta * c_light_)) * invTimeESq; + invTimeErr += invTimeESq; + } + } + if (invTimeErr > 0) { + time = time / invTimeErr; + // FIXME_ set a liminf of 0.02 ns on the ts error (based on residuals) + timeErr = sqrt(1.f / invTimeErr) > 0.02 ? sqrt(1.f / invTimeErr) : 0.02; + cand.setTime(time, timeErr); + } + + if (useMTDTiming_ and cand.charge()) { + // Check MTD timing availability + auto const &inputTimingView = (*inputTiming_h).const_view(); + const auto &trackIndex = cand.trackPtr().get() - (edm::Ptr(track_h, 0)).get(); + const bool assocQuality = inputTimingView.MVAquality()[trackIndex] > timingQualityThreshold_; + if (assocQuality) { + const auto timeHGC = cand.time(); + const auto timeEHGC = cand.timeError(); + const auto timeMTD = inputTimingView.time0()[trackIndex]; + const auto timeEMTD = inputTimingView.time0Err()[trackIndex]; + + if (useTimingAverage_ && (timeEMTD > 0 && timeEHGC > 0)) { + // Compute weighted average between HGCAL and MTD timing + const auto invTimeESqHGC = pow(timeEHGC, -2); + const auto invTimeESqMTD = pow(timeEMTD, -2); + timeErr = 1.f / (invTimeESqHGC + invTimeESqMTD); + time = (timeHGC * invTimeESqHGC + timeMTD * invTimeESqMTD) * timeErr; + timeErr = sqrt(timeErr); + } else if (timeEMTD > 0) { + time = timeMTD; + timeErr = timeEMTD; + } + } + cand.setTime(time, timeErr); + cand.setMTDTime(inputTimingView.time()[trackIndex], inputTimingView.timeErr()[trackIndex]); + } + } +} + +void TICLCandidateProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { + edm::ParameterSetDescription desc; + edm::ParameterSetDescription interpretationDesc; + interpretationDesc.addNode(edm::PluginDescription("type", "General", true)); + desc.add("interpretationDescPSet", interpretationDesc); + desc.add>("egamma_tracksters_collections", {edm::InputTag("ticlTracksterLinks")}); + desc.add>("egamma_tracksterlinks_collections", {edm::InputTag("ticlTracksterLinks")}); + desc.add>("general_tracksters_collections", {edm::InputTag("ticlTracksterLinks")}); + desc.add>("general_tracksterlinks_collections", {edm::InputTag("ticlTracksterLinks")}); + desc.add>("original_masks", + {edm::InputTag("hgcalMergeLayerClusters", "InitialLayerClustersMask")}); + desc.add("layer_clusters", edm::InputTag("hgcalMergeLayerClusters")); + desc.add("layer_clustersTime", edm::InputTag("hgcalMergeLayerClusters", "timeLayerCluster")); + desc.add("tracks", edm::InputTag("generalTracks")); + desc.add("trjtrkAss", edm::InputTag("generalTracks")); + desc.add("timingSoA", edm::InputTag("mtdSoA")); + desc.add("muons", edm::InputTag("muons1stStep")); + desc.add("detector", "HGCAL"); + desc.add("propagator", "PropagatorWithMaterial"); + desc.add("beamspot", edm::InputTag("offlineBeamSpot")); + desc.add("useMTDTiming", true); + desc.add("useTimingAverage", true); + desc.add("timingQualityThreshold", 0.5); + desc.add("cutTk", + "1.48 < abs(eta) < 3.0 && pt > 1. && quality(\"highPurity\") && " + "hitPattern().numberOfLostHits(\"MISSING_OUTER_HITS\") < 5"); + descriptions.add("ticlCandidateProducer", desc); +} + +DEFINE_FWK_MODULE(TICLCandidateProducer); diff --git a/RecoHGCal/TICL/plugins/TICLDumper.cc b/RecoHGCal/TICL/plugins/TICLDumper.cc index 2159bd2fc09db..1a02ffbd2e015 100644 --- a/RecoHGCal/TICL/plugins/TICLDumper.cc +++ b/RecoHGCal/TICL/plugins/TICLDumper.cc @@ -24,6 +24,7 @@ #include "DataFormats/CaloRecHit/interface/CaloCluster.h" #include "DataFormats/HGCalReco/interface/Trackster.h" #include "DataFormats/HGCalReco/interface/TICLCandidate.h" +#include "DataFormats/MuonReco/interface/Muon.h" #include "DataFormats/TrackReco/interface/Track.h" #include "DataFormats/TrackReco/interface/TrackFwd.h" #include "DataFormats/DetId/interface/DetId.h" @@ -34,6 +35,7 @@ #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" +#include "RecoParticleFlow/PFProducer/interface/PFMuonAlgo.h" #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" #include "TrackingTools/GeomPropagators/interface/Propagator.h" #include "TrackingTools/Records/interface/TrackingComponentsRecord.h" @@ -61,7 +63,7 @@ class TICLDumper : public edm::one::EDAnalyzer Vec; private: @@ -80,6 +82,7 @@ class TICLDumper : public edm::one::EDAnalyzer> tracksters_token_; + const edm::EDGetTokenT> tracksters_in_candidate_token_; const edm::EDGetTokenT> layer_clusters_token_; const edm::EDGetTokenT> ticl_candidates_token_; const edm::EDGetTokenT> tracks_token_; @@ -87,6 +90,10 @@ class TICLDumper : public edm::one::EDAnalyzer> tracks_time_token_; const edm::EDGetTokenT> tracks_time_quality_token_; const edm::EDGetTokenT> tracks_time_err_token_; + const edm::EDGetTokenT> tracks_beta_token_; + const edm::EDGetTokenT> tracks_time_mtd_token_; + const edm::EDGetTokenT> tracks_time_mtd_err_token_; + const edm::EDGetTokenT> tracks_pos_mtd_token_; const edm::EDGetTokenT> hgcaltracks_x_token_; const edm::EDGetTokenT> hgcaltracks_y_token_; const edm::EDGetTokenT> hgcaltracks_z_token_; @@ -96,6 +103,7 @@ class TICLDumper : public edm::one::EDAnalyzer> hgcaltracks_py_token_; const edm::EDGetTokenT> hgcaltracks_pz_token_; const edm::EDGetTokenT> tracksters_merged_token_; + const edm::EDGetTokenT> muons_token_; const edm::EDGetTokenT>> clustersTime_token_; const edm::EDGetTokenT> tracksterSeeds_token_; edm::ESGetToken caloGeometry_token_; @@ -186,6 +194,7 @@ class TICLDumper : public edm::one::EDAnalyzer> trackster_vertices_multiplicity; std::vector stsSC_trackster_time; + std::vector stsSC_trackster_timeBoundary; std::vector stsSC_trackster_timeError; std::vector stsSC_trackster_regressed_energy; std::vector stsSC_trackster_regressed_pt; @@ -238,6 +247,7 @@ class TICLDumper : public edm::one::EDAnalyzer> stsSC_trackster_vertices_correctedEnergyUncertainty; std::vector> stsSC_trackster_vertices_multiplicity; std::vector stsCP_trackster_time; + std::vector stsCP_trackster_timeBoundary; std::vector stsCP_trackster_timeError; std::vector stsCP_trackster_regressed_energy; std::vector stsCP_trackster_regressed_pt; @@ -299,9 +309,8 @@ class TICLDumper : public edm::one::EDAnalyzer simTICLCandidate_boundaryPx; std::vector simTICLCandidate_boundaryPy; std::vector simTICLCandidate_boundaryPz; - std::vector simTICLCandidate_trackTime; - std::vector simTICLCandidate_trackBeta; std::vector simTICLCandidate_caloParticleMass; + std::vector simTICLCandidate_time; std::vector simTICLCandidate_pdgId; std::vector simTICLCandidate_charge; std::vector simTICLCandidate_track_in_candidate; @@ -311,6 +320,7 @@ class TICLDumper : public edm::one::EDAnalyzer candidate_charge; std::vector candidate_pdgId; std::vector candidate_energy; + std::vector candidate_raw_energy; std::vector candidate_px; std::vector candidate_py; std::vector candidate_pz; @@ -419,11 +429,18 @@ class TICLDumper : public edm::one::EDAnalyzer track_pt; std::vector track_quality; std::vector track_missing_outer_hits; + std::vector track_missing_inner_hits; std::vector track_charge; std::vector track_time; std::vector track_time_quality; std::vector track_time_err; + std::vector track_beta; + std::vector track_time_mtd; + std::vector track_time_mtd_err; + std::vector track_pos_mtd; std::vector track_nhits; + std::vector track_isMuon; + std::vector track_isTrackerMuon; TTree* trackster_tree_; TTree* cluster_tree_; @@ -475,6 +492,7 @@ void TICLDumper::clearVariables() { trackster_vertices_multiplicity.clear(); stsSC_trackster_time.clear(); + stsSC_trackster_timeBoundary.clear(); stsSC_trackster_timeError.clear(); stsSC_trackster_regressed_energy.clear(); stsSC_trackster_regressed_pt.clear(); @@ -528,6 +546,7 @@ void TICLDumper::clearVariables() { stsSC_trackster_vertices_multiplicity.clear(); stsCP_trackster_time.clear(); + stsCP_trackster_timeBoundary.clear(); stsCP_trackster_timeError.clear(); stsCP_trackster_regressed_energy.clear(); stsCP_trackster_regressed_pt.clear(); @@ -583,8 +602,7 @@ void TICLDumper::clearVariables() { simTICLCandidate_boundaryPx.clear(); simTICLCandidate_boundaryPy.clear(); simTICLCandidate_boundaryPz.clear(); - simTICLCandidate_trackTime.clear(); - simTICLCandidate_trackBeta.clear(); + simTICLCandidate_time.clear(); simTICLCandidate_caloParticleMass.clear(); simTICLCandidate_pdgId.clear(); simTICLCandidate_charge.clear(); @@ -594,6 +612,7 @@ void TICLDumper::clearVariables() { candidate_charge.clear(); candidate_pdgId.clear(); candidate_energy.clear(); + candidate_raw_energy.clear(); candidate_px.clear(); candidate_py.clear(); candidate_pz.clear(); @@ -710,23 +729,37 @@ void TICLDumper::clearVariables() { track_quality.clear(); track_pt.clear(); track_missing_outer_hits.clear(); + track_missing_inner_hits.clear(); track_charge.clear(); track_time.clear(); track_time_quality.clear(); track_time_err.clear(); + track_beta.clear(); + track_time_mtd.clear(); + track_time_mtd_err.clear(); + track_pos_mtd.clear(); track_nhits.clear(); + track_isMuon.clear(); + track_isTrackerMuon.clear(); }; TICLDumper::TICLDumper(const edm::ParameterSet& ps) : tracksters_token_(consumes>(ps.getParameter("trackstersclue3d"))), + tracksters_in_candidate_token_( + consumes>(ps.getParameter("trackstersInCand"))), layer_clusters_token_(consumes>(ps.getParameter("layerClusters"))), ticl_candidates_token_(consumes>(ps.getParameter("ticlcandidates"))), tracks_token_(consumes>(ps.getParameter("tracks"))), tracks_time_token_(consumes>(ps.getParameter("tracksTime"))), tracks_time_quality_token_(consumes>(ps.getParameter("tracksTimeQual"))), tracks_time_err_token_(consumes>(ps.getParameter("tracksTimeErr"))), + tracks_beta_token_(consumes>(ps.getParameter("tracksBeta"))), + tracks_time_mtd_token_(consumes>(ps.getParameter("tracksTimeMtd"))), + tracks_time_mtd_err_token_(consumes>(ps.getParameter("tracksTimeMtdErr"))), + tracks_pos_mtd_token_(consumes>(ps.getParameter("tracksPosMtd"))), tracksters_merged_token_( consumes>(ps.getParameter("trackstersmerged"))), + muons_token_(consumes>(ps.getParameter("muons"))), clustersTime_token_( consumes>>(ps.getParameter("layer_clustersTime"))), caloGeometry_token_(esConsumes()), @@ -860,6 +893,7 @@ void TICLDumper::beginJob() { candidate_tree_->Branch("candidate_time", &candidate_time); candidate_tree_->Branch("candidate_timeErr", &candidate_time_err); candidate_tree_->Branch("candidate_energy", &candidate_energy); + candidate_tree_->Branch("candidate_raw_energy", &candidate_raw_energy); candidate_tree_->Branch("candidate_px", &candidate_px); candidate_tree_->Branch("candidate_py", &candidate_py); candidate_tree_->Branch("candidate_pz", &candidate_pz); @@ -947,6 +981,7 @@ void TICLDumper::beginJob() { simtrackstersSC_tree_->Branch("event", &ev_event_); simtrackstersSC_tree_->Branch("NTracksters", &stsSC_ntracksters_); simtrackstersSC_tree_->Branch("time", &stsSC_trackster_time); + simtrackstersSC_tree_->Branch("timeBoundary", &stsSC_trackster_timeBoundary); simtrackstersSC_tree_->Branch("timeError", &stsSC_trackster_timeError); simtrackstersSC_tree_->Branch("regressed_energy", &stsSC_trackster_regressed_energy); simtrackstersSC_tree_->Branch("regressed_pt", &stsSC_trackster_regressed_pt); @@ -1006,6 +1041,7 @@ void TICLDumper::beginJob() { simtrackstersCP_tree_->Branch("event", &ev_event_); simtrackstersCP_tree_->Branch("NTracksters", &stsCP_ntracksters_); simtrackstersCP_tree_->Branch("time", &stsCP_trackster_time); + simtrackstersCP_tree_->Branch("timeBoundary", &stsCP_trackster_timeBoundary); simtrackstersCP_tree_->Branch("timeError", &stsCP_trackster_timeError); simtrackstersCP_tree_->Branch("regressed_energy", &stsCP_trackster_regressed_energy); simtrackstersCP_tree_->Branch("regressed_pt", &stsCP_trackster_regressed_pt); @@ -1064,15 +1100,27 @@ void TICLDumper::beginJob() { tracks_tree_ = fs->make("tracks", "Tracks"); tracks_tree_->Branch("event", &ev_event_); tracks_tree_->Branch("track_id", &track_id); + tracks_tree_->Branch("track_hgcal_x", &track_hgcal_x); + tracks_tree_->Branch("track_hgcal_y", &track_hgcal_y); + tracks_tree_->Branch("track_hgcal_z", &track_hgcal_z); + tracks_tree_->Branch("track_hgcal_eta", &track_hgcal_eta); + tracks_tree_->Branch("track_hgcal_phi", &track_hgcal_phi); tracks_tree_->Branch("track_hgcal_pt", &track_hgcal_pt); tracks_tree_->Branch("track_pt", &track_pt); tracks_tree_->Branch("track_missing_outer_hits", &track_missing_outer_hits); + tracks_tree_->Branch("track_missing_inner_hits", &track_missing_inner_hits); tracks_tree_->Branch("track_quality", &track_quality); tracks_tree_->Branch("track_charge", &track_charge); tracks_tree_->Branch("track_time", &track_time); tracks_tree_->Branch("track_time_quality", &track_time_quality); tracks_tree_->Branch("track_time_err", &track_time_err); + tracks_tree_->Branch("track_beta", &track_beta); + tracks_tree_->Branch("track_time_mtd", &track_time_mtd); + tracks_tree_->Branch("track_time_mtd_err", &track_time_mtd_err); + tracks_tree_->Branch("track_pos_mtd", &track_pos_mtd); tracks_tree_->Branch("track_nhits", &track_nhits); + tracks_tree_->Branch("track_isMuon", &track_isMuon); + tracks_tree_->Branch("track_isTrackerMuon", &track_isTrackerMuon); } if (saveSimTICLCandidate_) { @@ -1086,8 +1134,7 @@ void TICLDumper::beginJob() { simTICLCandidate_tree->Branch("simTICLCandidate_boundaryPx", &simTICLCandidate_boundaryPx); simTICLCandidate_tree->Branch("simTICLCandidate_boundaryPy", &simTICLCandidate_boundaryPy); simTICLCandidate_tree->Branch("simTICLCandidate_boundaryPz", &simTICLCandidate_boundaryPz); - simTICLCandidate_tree->Branch("simTICLCandidate_trackTime", &simTICLCandidate_trackTime); - simTICLCandidate_tree->Branch("simTICLCandidate_trackBeta", &simTICLCandidate_trackBeta); + simTICLCandidate_tree->Branch("simTICLCandidate_time", &simTICLCandidate_time); simTICLCandidate_tree->Branch("simTICLCandidate_caloParticleMass", &simTICLCandidate_caloParticleMass); simTICLCandidate_tree->Branch("simTICLCandidate_pdgId", &simTICLCandidate_pdgId); simTICLCandidate_tree->Branch("simTICLCandidate_charge", &simTICLCandidate_charge); @@ -1142,6 +1189,9 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) event.getByToken(tracksters_token_, tracksters_handle); const auto& tracksters = *tracksters_handle; + edm::Handle> tracksters_in_candidate_handle; + event.getByToken(tracksters_in_candidate_token_, tracksters_in_candidate_handle); + //get all the layer clusters edm::Handle> layer_clusters_h; event.getByToken(layer_clusters_token_, layer_clusters_h); @@ -1169,15 +1219,36 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) event.getByToken(tracks_time_err_token_, trackTimeErr_h); const auto& trackTimeErr = *trackTimeErr_h; + edm::Handle> trackBeta_h; + event.getByToken(tracks_beta_token_, trackBeta_h); + const auto& trackBeta = *trackBeta_h; + edm::Handle> trackTimeQual_h; event.getByToken(tracks_time_quality_token_, trackTimeQual_h); const auto& trackTimeQual = *trackTimeQual_h; + edm::Handle> trackTimeMtd_h; + event.getByToken(tracks_time_mtd_token_, trackTimeMtd_h); + const auto& trackTimeMtd = *trackTimeMtd_h; + + edm::Handle> trackTimeMtdErr_h; + event.getByToken(tracks_time_mtd_err_token_, trackTimeMtdErr_h); + const auto& trackTimeMtdErr = *trackTimeMtdErr_h; + + edm::Handle> trackPosMtd_h; + event.getByToken(tracks_pos_mtd_token_, trackPosMtd_h); + const auto& trackPosMtd = *trackPosMtd_h; + //Tracksters merged edm::Handle> tracksters_merged_h; event.getByToken(tracksters_merged_token_, tracksters_merged_h); const auto& trackstersmerged = *tracksters_merged_h; + // muons + edm::Handle> muons_h; + event.getByToken(muons_token_, muons_h); + auto& muons = *muons_h; + // simTracksters from SC edm::Handle> simTrackstersSC_h; event.getByToken(simTracksters_SC_token_, simTrackstersSC_h); @@ -1329,6 +1400,7 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) ++trackster_iterator) { //per-trackster analysis stsSC_trackster_time.push_back(trackster_iterator->time()); + stsSC_trackster_timeBoundary.push_back(trackster_iterator->boundaryTime()); stsSC_trackster_timeError.push_back(trackster_iterator->timeError()); stsSC_trackster_regressed_energy.push_back(trackster_iterator->regressed_energy()); stsSC_trackster_raw_energy.push_back(trackster_iterator->raw_energy()); @@ -1474,6 +1546,7 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) ++trackster_iterator) { //per-trackster analysis stsCP_trackster_time.push_back(trackster_iterator->time()); + stsCP_trackster_timeBoundary.push_back(trackster_iterator->boundaryTime()); stsCP_trackster_timeError.push_back(trackster_iterator->timeError()); stsCP_trackster_regressed_energy.push_back(trackster_iterator->regressed_energy()); stsCP_trackster_raw_energy.push_back(trackster_iterator->raw_energy()); @@ -1620,6 +1693,7 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) simTICLCandidate_regressed_energy.push_back(cand.p4().energy()); simTICLCandidate_pdgId.push_back(cand.pdgId()); simTICLCandidate_charge.push_back(cand.charge()); + simTICLCandidate_time.push_back(cand.time()); std::vector tmpIdxVec; for (auto const& simTS : cand.tracksters()) { auto trackster_idx = simTS.get() - (edm::Ptr(simTrackstersSC_h, 0)).get(); @@ -1646,8 +1720,6 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) simTICLCandidate_boundaryPx.push_back(globalMom.x()); simTICLCandidate_boundaryPy.push_back(globalMom.y()); simTICLCandidate_boundaryPz.push_back(globalMom.z()); - simTICLCandidate_trackTime.push_back(track.t0()); - simTICLCandidate_trackBeta.push_back(track.beta()); } else { simTICLCandidate_boundaryX.push_back(-999); simTICLCandidate_boundaryY.push_back(-999); @@ -1655,8 +1727,6 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) simTICLCandidate_boundaryPx.push_back(-999); simTICLCandidate_boundaryPy.push_back(-999); simTICLCandidate_boundaryPz.push_back(-999); - simTICLCandidate_trackTime.push_back(-999); - simTICLCandidate_trackBeta.push_back(-999); } } else { simTICLCandidate_boundaryX.push_back(-999); @@ -1665,8 +1735,6 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) simTICLCandidate_boundaryPx.push_back(-999); simTICLCandidate_boundaryPy.push_back(-999); simTICLCandidate_boundaryPz.push_back(-999); - simTICLCandidate_trackTime.push_back(-999); - simTICLCandidate_trackBeta.push_back(-999); } } @@ -1702,6 +1770,7 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) candidate_charge.push_back(candidate.charge()); candidate_pdgId.push_back(candidate.pdgId()); candidate_energy.push_back(candidate.energy()); + candidate_raw_energy.push_back(candidate.rawEnergy()); candidate_px.push_back(candidate.px()); candidate_py.push_back(candidate.py()); candidate_pz.push_back(candidate.pz()); @@ -1717,7 +1786,7 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) auto trackster_ptrs = candidate.tracksters(); auto track_ptr = candidate.trackPtr(); for (const auto& ts_ptr : trackster_ptrs) { - auto ts_idx = ts_ptr.get() - (edm::Ptr(tracksters_handle, 0)).get(); + auto ts_idx = ts_ptr.get() - (edm::Ptr(tracksters_in_candidate_handle, 0)).get(); tracksters_in_candidate[i].push_back(ts_idx); } if (track_ptr.isNull()) @@ -2017,11 +2086,25 @@ void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) track_pt.push_back(track.pt()); track_quality.push_back(track.quality(reco::TrackBase::highPurity)); track_missing_outer_hits.push_back(track.missingOuterHits()); + track_missing_inner_hits.push_back(track.missingInnerHits()); track_charge.push_back(track.charge()); track_time.push_back(trackTime[trackref]); track_time_quality.push_back(trackTimeQual[trackref]); track_time_err.push_back(trackTimeErr[trackref]); + track_beta.push_back(trackBeta[trackref]); + track_time_mtd.push_back(trackTimeMtd[trackref]); + track_time_mtd_err.push_back(trackTimeMtdErr[trackref]); + track_pos_mtd.push_back(trackPosMtd[trackref]); track_nhits.push_back(tracks[i].recHitsSize()); + int muId = PFMuonAlgo::muAssocToTrack(trackref, *muons_h); + if (muId != -1) { + const reco::MuonRef muonref = reco::MuonRef(muons_h, muId); + track_isMuon.push_back(PFMuonAlgo::isMuon(muonref)); + track_isTrackerMuon.push_back(muons[muId].isTrackerMuon()); + } else { + track_isMuon.push_back(-1); + track_isTrackerMuon.push_back(-1); + } } } @@ -2050,6 +2133,7 @@ void TICLDumper::endJob() {} void TICLDumper::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add("trackstersclue3d", edm::InputTag("ticlTrackstersCLUE3DHigh")); + desc.add("trackstersInCand", edm::InputTag("ticlTrackstersCLUE3DHigh")); desc.add("layerClusters", edm::InputTag("hgcalMergeLayerClusters")); desc.add("layer_clustersTime", edm::InputTag("hgcalMergeLayerClusters", "timeLayerCluster")); desc.add("ticlcandidates", edm::InputTag("ticlTrackstersMerge")); @@ -2057,7 +2141,12 @@ void TICLDumper::fillDescriptions(edm::ConfigurationDescriptions& descriptions) desc.add("tracksTime", edm::InputTag("tofPID:t0")); desc.add("tracksTimeQual", edm::InputTag("mtdTrackQualityMVA:mtdQualMVA")); desc.add("tracksTimeErr", edm::InputTag("tofPID:sigmat0")); + desc.add("tracksBeta", edm::InputTag("trackExtenderWithMTD:generalTrackBeta")); + desc.add("tracksTimeMtd", edm::InputTag("trackExtenderWithMTD:generalTracktmtd")); + desc.add("tracksTimeMtdErr", edm::InputTag("trackExtenderWithMTD:generalTracksigmatmtd")); + desc.add("tracksPosMtd", edm::InputTag("trackExtenderWithMTD:generalTrackmtdpos")); desc.add("trackstersmerged", edm::InputTag("ticlTrackstersMerge")); + desc.add("muons", edm::InputTag("muons1stStep")); desc.add("simtrackstersSC", edm::InputTag("ticlSimTracksters")); desc.add("simtrackstersCP", edm::InputTag("ticlSimTracksters", "fromCPs")); desc.add("simtrackstersPU", edm::InputTag("ticlSimTracksters", "PU")); diff --git a/RecoHGCal/TICL/plugins/TICLGraph.cc b/RecoHGCal/TICL/plugins/TICLGraph.cc new file mode 100644 index 0000000000000..f51e7ab086d05 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TICLGraph.cc @@ -0,0 +1,60 @@ +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "TICLGraph.h" + +namespace ticl { + + void Node::findSubComponents(std::vector& graph, std::vector& subComponent, std::string tabs) { + tabs += "\t"; + if (!alreadyVisited_) { + LogDebug("TICLGraph") << tabs << " Visiting node " << index_ << std::endl; + alreadyVisited_ = true; + subComponent.push_back(index_); + for (auto const& neighbour : outerNeighboursId_) { + LogDebug("TICLGraph") << tabs << " Trying to visit " << neighbour << std::endl; + graph[neighbour].findSubComponents(graph, subComponent, tabs); + } + } + } +} // namespace ticl + +std::vector> TICLGraph::findSubComponents() { + std::vector> components; + for (auto const& node : nodes_) { + auto const id = node.getId(); + if (isRootNode_[id]) { + //LogDebug("TICLGraph") << "DFS Starting From " << id << std::endl; + std::string tabs = "\t"; + std::vector tmpSubComponents; + nodes_[id].findSubComponents(nodes_, tmpSubComponents, tabs); + components.push_back(tmpSubComponents); + } + } + return components; +} + +void TICLGraph::dfsForCC(unsigned int nodeIndex, + std::unordered_set& visited, + std::vector& component) const { + visited.insert(nodeIndex); + component.push_back(nodeIndex); + + for (auto const& neighbourIndex : nodes_[nodeIndex].getOuterNeighbours()) { + if (visited.find(neighbourIndex) == visited.end()) { + dfsForCC(neighbourIndex, visited, component); + } + } +} + +std::vector> TICLGraph::getConnectedComponents() const { + std::unordered_set visited; + std::vector> components; + + for (unsigned int i = 0; i < nodes_.size(); ++i) { + if (visited.find(i) == visited.end()) { + std::vector component; + dfsForCC(i, visited, component); + components.push_back(component); + } + } + return components; +} diff --git a/RecoHGCal/TICL/plugins/TICLGraph.h b/RecoHGCal/TICL/plugins/TICLGraph.h new file mode 100644 index 0000000000000..36e09bb87a384 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TICLGraph.h @@ -0,0 +1,69 @@ +#ifndef DataFormats_HGCalReco_TICLGraph_h +#define DataFormats_HGCalReco_TICLGraph_h + +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include + +namespace ticl { + + class Node { + public: + Node() = default; + Node(unsigned index, bool isTrackster = true) : index_(index), isTrackster_(isTrackster), alreadyVisited_{false} {}; + + inline void addOuterNeighbour(unsigned int trackster_id) { outerNeighboursId_.push_back(trackster_id); } + inline void addInnerNeighbour(unsigned int trackster_id) { innerNeighboursId_.push_back(trackster_id); } + + inline const unsigned int getId() const { return index_; } + const std::vector& getOuterNeighbours() const { return outerNeighboursId_; } + const std::vector& getInnerNeighbours() const { return innerNeighboursId_; } + void findSubComponents(std::vector& graph, std::vector& subComponent, std::string tabs); + + inline bool isInnerNeighbour(const unsigned int tid) { + auto findInner = std::find(innerNeighboursId_.begin(), innerNeighboursId_.end(), tid); + return findInner != innerNeighboursId_.end(); + } + + ~Node() = default; + + private: + unsigned index_; + bool isTrackster_; + + std::vector outerNeighboursId_; + std::vector innerNeighboursId_; + bool alreadyVisited_; + + //bool areCompatible(const std::vector& graph, const unsigned int& outerNode) { return true; }; + }; +} // namespace ticl + +class TICLGraph { +public: + // can i remove default constructor ?? edm::Wrapper problem + // without default constructor i could initialize connectedComponents when building the Graph + TICLGraph() = default; + TICLGraph(std::vector& n, std::vector isRootNode) { + nodes_ = n; + isRootNode_ = isRootNode; + }; + inline const std::vector& getNodes() const { return nodes_; } + inline const ticl::Node& getNode(int i) const { return nodes_[i]; } + + std::vector> findSubComponents(); + + ~TICLGraph() = default; + + void dfsForCC(unsigned int nodeIndex, + std::unordered_set& visited, + std::vector& component) const; + + std::vector> getConnectedComponents() const; + +private: + std::vector nodes_; + std::vector isRootNode_; +}; + +#endif diff --git a/RecoHGCal/TICL/plugins/TICLInterpretationPluginFactory.cc b/RecoHGCal/TICL/plugins/TICLInterpretationPluginFactory.cc new file mode 100644 index 0000000000000..00681086d3a58 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TICLInterpretationPluginFactory.cc @@ -0,0 +1,11 @@ +// #include "TracksterLinkingbySkeletons.h" +// #include "TracksterLinkingbySuperClustering.h" +#include "FWCore/ParameterSet/interface/ValidatedPluginFactoryMacros.h" +#include "FWCore/ParameterSet/interface/ValidatedPluginMacros.h" +#include "RecoHGCal/TICL/plugins/TICLInterpretationPluginFactory.h" +#include "GeneralInterpretationAlgo.h" + +EDM_REGISTER_VALIDATED_PLUGINFACTORY(TICLGeneralInterpretationPluginFactory, "TICLGeneralInterpretationPluginFactory"); +EDM_REGISTER_VALIDATED_PLUGINFACTORY(TICLEGammaInterpretationPluginFactory, "TICLEGammaInterpretationPluginFactory"); +DEFINE_EDM_VALIDATED_PLUGIN(TICLGeneralInterpretationPluginFactory, ticl::GeneralInterpretationAlgo, "General"); +// DEFINE_EDM_VALIDATED_PLUGIN(TICLEGammaInterpretationPluginFactory, ticl::EGammaInterpretation, "EGamma"); diff --git a/RecoHGCal/TICL/plugins/TICLInterpretationPluginFactory.h b/RecoHGCal/TICL/plugins/TICLInterpretationPluginFactory.h new file mode 100644 index 0000000000000..6fb9f7c787b1a --- /dev/null +++ b/RecoHGCal/TICL/plugins/TICLInterpretationPluginFactory.h @@ -0,0 +1,17 @@ +#ifndef RecoHGCal_TICL_TICLInterpretationPluginFactory_H +#define RecoHGCal_TICL_TICLInterpretationPluginFactory_H + +#include "FWCore/PluginManager/interface/PluginFactory.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "RecoHGCal/TICL/interface/TICLInterpretationAlgoBase.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/GsfTrackReco/interface/GsfTrack.h" + +using TICLGeneralInterpretationPluginFactory = edmplugin::PluginFactory*( + const edm::ParameterSet&, edm::ConsumesCollector)>; +using TICLEGammaInterpretationPluginFactory = + edmplugin::PluginFactory*(const edm::ParameterSet&, + edm::ConsumesCollector)>; + +#endif diff --git a/RecoHGCal/TICL/plugins/TracksterLinkingPassthrough.cc b/RecoHGCal/TICL/plugins/TracksterLinkingPassthrough.cc new file mode 100644 index 0000000000000..9749d30163859 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TracksterLinkingPassthrough.cc @@ -0,0 +1,20 @@ +#include "RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h" +#include "RecoHGCal/TICL/plugins/TracksterLinkingPassthrough.h" + +using namespace ticl; + +void TracksterLinkingPassthrough::linkTracksters( + const Inputs& input, + std::vector& resultTracksters, + std::vector>& linkedResultTracksters, + std::vector>& linkedTracksterIdToInputTracksterId) { + resultTracksters.reserve(input.tracksters.size()); + linkedResultTracksters.resize(input.tracksters.size()); + linkedTracksterIdToInputTracksterId.resize(input.tracksters.size()); + // Merge all trackster collections into a single collection + for (size_t i = 0; i < input.tracksters.size(); ++i) { + resultTracksters.push_back(input.tracksters[i]); + linkedResultTracksters[i].push_back(resultTracksters.size() - 1); + linkedTracksterIdToInputTracksterId[i].push_back(resultTracksters.size() - 1); + } +} diff --git a/RecoHGCal/TICL/plugins/TracksterLinkingPassthrough.h b/RecoHGCal/TICL/plugins/TracksterLinkingPassthrough.h new file mode 100644 index 0000000000000..d66f6015caa44 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TracksterLinkingPassthrough.h @@ -0,0 +1,34 @@ +#ifndef RecoHGCal_TICL_TracksterLinkingPassthrough_H +#define RecoHGCal_TICL_TracksterLinkingPassthrough_H + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h" + +namespace ticl { + + class TracksterLinkingPassthrough : public TracksterLinkingAlgoBase { + public: + TracksterLinkingPassthrough(const edm::ParameterSet& conf, edm::ConsumesCollector iC) + : TracksterLinkingAlgoBase(conf, iC) {} + + ~TracksterLinkingPassthrough() override {} + + void linkTracksters(const Inputs& input, + std::vector& resultTracksters, + std::vector>& linkedResultTracksters, + std::vector>& linkedTracksterIdToInputTracksterId) override; + + void initialize(const HGCalDDDConstants* hgcons, + const hgcal::RecHitTools rhtools, + const edm::ESHandle bfieldH, + const edm::ESHandle propH) override{}; + + static void fillPSetDescription(edm::ParameterSetDescription& iDesc) { iDesc.add("algo_verbosity", 0); } + }; + +} // namespace ticl + +#endif diff --git a/RecoHGCal/TICL/plugins/TracksterLinkingPluginFactory.cc b/RecoHGCal/TICL/plugins/TracksterLinkingPluginFactory.cc new file mode 100644 index 0000000000000..b6027ef4ebe6c --- /dev/null +++ b/RecoHGCal/TICL/plugins/TracksterLinkingPluginFactory.cc @@ -0,0 +1,13 @@ +// #include "TracksterLinkingbySuperClustering.h" +#include "FWCore/ParameterSet/interface/ValidatedPluginFactoryMacros.h" +#include "FWCore/ParameterSet/interface/ValidatedPluginMacros.h" +#include "TracksterLinkingbyFastJet.h" +#include "TracksterLinkingbySkeletons.h" +#include "TracksterLinkingPassthrough.h" +#include "RecoHGCal/TICL/plugins/TracksterLinkingPluginFactory.h" + +EDM_REGISTER_VALIDATED_PLUGINFACTORY(TracksterLinkingPluginFactory, "TracksterLinkingPluginFactory"); +DEFINE_EDM_VALIDATED_PLUGIN(TracksterLinkingPluginFactory, ticl::TracksterLinkingbySkeletons, "Skeletons"); +// DEFINE_EDM_VALIDATED_PLUGIN(TracksterLinkingPluginFactory, ticl::TracksterLinkingbySuperClustering, "SuperClustering"); +DEFINE_EDM_VALIDATED_PLUGIN(TracksterLinkingPluginFactory, ticl::TracksterLinkingbyFastJet, "FastJet"); +DEFINE_EDM_VALIDATED_PLUGIN(TracksterLinkingPluginFactory, ticl::TracksterLinkingPassthrough, "Passthrough"); diff --git a/RecoHGCal/TICL/plugins/TracksterLinkingPluginFactory.h b/RecoHGCal/TICL/plugins/TracksterLinkingPluginFactory.h new file mode 100644 index 0000000000000..1b9cc19ff0122 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TracksterLinkingPluginFactory.h @@ -0,0 +1,12 @@ +#ifndef RecoHGCal_TICL_TracksterLinkingPluginFactory_H +#define RecoHGCal_TICL_TracksterLinkingPluginFactory_H + +#include "FWCore/PluginManager/interface/PluginFactory.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h" + +using TracksterLinkingPluginFactory = + edmplugin::PluginFactory; + +#endif diff --git a/RecoHGCal/TICL/plugins/TracksterLinkingbyFastJet.cc b/RecoHGCal/TICL/plugins/TracksterLinkingbyFastJet.cc new file mode 100644 index 0000000000000..0c7bf5bc0e869 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TracksterLinkingbyFastJet.cc @@ -0,0 +1,48 @@ +#include "RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h" +#include "fastjet/ClusterSequence.hh" +#include "DataFormats/Math/interface/deltaR.h" +#include "RecoHGCal/TICL/plugins/TracksterLinkingbyFastJet.h" + +using namespace ticl; + +void TracksterLinkingbyFastJet::linkTracksters( + const Inputs& input, + std::vector& resultTracksters, + std::vector>& linkedResultTracksters, + std::vector>& linkedTracksterIdToInputTracksterId) { + // Create jets of tracksters using FastJet + std::vector fjInputs; + for (size_t i = 0; i < input.tracksters.size(); ++i) { + // Convert Trackster information to PseudoJet + fastjet::PseudoJet pj(input.tracksters[i].barycenter().x(), + input.tracksters[i].barycenter().y(), + input.tracksters[i].barycenter().z(), + input.tracksters[i].raw_energy()); + pj.set_user_index(i); + fjInputs.push_back(pj); + } + + // Cluster tracksters into jets using FastJet + fastjet::ClusterSequence sequence(fjInputs, fastjet::JetDefinition(algorithm_, radius_)); + auto jets = fastjet::sorted_by_pt(sequence.inclusive_jets(0)); + linkedTracksterIdToInputTracksterId.resize(jets.size()); + // Link tracksters based on which ones are components of the same jet + for (unsigned int i = 0; i < jets.size(); ++i) { + const auto& jet = jets[i]; + + std::vector linkedTracksters; + Trackster outTrackster; + if (!jet.constituents().empty()) { + // Check if a trackster is a component of the current jet + for (const auto& constituent : jet.constituents()) { + auto tracksterIndex = constituent.user_index(); + linkedTracksterIdToInputTracksterId[i].push_back(tracksterIndex); + outTrackster.mergeTracksters(input.tracksters[tracksterIndex]); + } + linkedTracksters.push_back(resultTracksters.size()); + resultTracksters.push_back(outTrackster); + // Store the linked tracksters + linkedResultTracksters.push_back(linkedTracksters); + } + } +} diff --git a/RecoHGCal/TICL/plugins/TracksterLinkingbyFastJet.h b/RecoHGCal/TICL/plugins/TracksterLinkingbyFastJet.h new file mode 100644 index 0000000000000..d2389bf15b6d9 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TracksterLinkingbyFastJet.h @@ -0,0 +1,62 @@ +#ifndef RecoHGCal_TICL_TracksterLinkingAlgoByFastJet_H +#define RecoHGCal_TICL_TracksterLinkingAlgoByFastJet_H + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h" +#include "fastjet/ClusterSequence.hh" +#include "DataFormats/Math/interface/deltaR.h" + +namespace ticl { + + class TracksterLinkingbyFastJet : public TracksterLinkingAlgoBase { + public: + TracksterLinkingbyFastJet(const edm::ParameterSet& conf, edm::ConsumesCollector iC) + : TracksterLinkingAlgoBase(conf, iC), radius_(conf.getParameter("radius")) { + // Cluster tracksters into jets using FastJet with configurable algorithm + auto algo = conf.getParameter("jet_algorithm"); + + switch (algo) { + case 0: + algorithm_ = fastjet::kt_algorithm; + break; + case 1: + algorithm_ = fastjet::cambridge_algorithm; + break; + case 2: + algorithm_ = fastjet::antikt_algorithm; + break; + default: + throw cms::Exception("BadConfig") << "FastJet jet clustering algorithm not set correctly."; + } + } + + ~TracksterLinkingbyFastJet() override {} + + void linkTracksters(const Inputs& input, + std::vector& resultTracksters, + std::vector>& linkedResultTracksters, + std::vector>& linkedTracksterIdToInputTracksterId) override; + + void initialize(const HGCalDDDConstants* hgcons, + const hgcal::RecHitTools rhtools, + const edm::ESHandle bfieldH, + const edm::ESHandle propH) override{}; + + static void fillPSetDescription(edm::ParameterSetDescription& iDesc) { + iDesc.add("algo_verbosity", 0); + iDesc.add("jet_algorithm", 2) + ->setComment("FastJet jet clustering algorithm: 0 = kt, 1 = Cambridge/Aachen, 2 = anti-kt"); + iDesc.add("radius", 0.1); + } + + private: + fastjet::JetAlgorithm algorithm_; // FastJet jet clustering algorithm + const float radius_; + }; + +} // namespace ticl + +#endif diff --git a/RecoHGCal/TICL/plugins/TracksterLinkingbySkeletons.cc b/RecoHGCal/TICL/plugins/TracksterLinkingbySkeletons.cc new file mode 100644 index 0000000000000..1621521992779 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TracksterLinkingbySkeletons.cc @@ -0,0 +1,415 @@ +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include +#include "DataFormats/Math/interface/deltaR.h" +#include "DataFormats/HGCalReco/interface/Common.h" +#include "DataFormats/GeometrySurface/interface/BoundDisk.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" +#include "RecoParticleFlow/PFProducer/interface/PFMuonAlgo.h" +#include "RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h" +#include "RecoHGCal/TICL/plugins/TracksterLinkingbySkeletons.h" +#include "TICLGraph.h" + +namespace { + bool isRoundTrackster(std::array skeleton) { return (skeleton[0].Z() == skeleton[2].Z()); } + + bool isGoodTrackster(const ticl::Trackster &trackster, + const std::array &skeleton, + const unsigned int min_num_lcs, + const float min_trackster_energy, + const float pca_quality_th) { + bool isGood = false; + + if (isRoundTrackster(skeleton) or trackster.vertices().size() < min_num_lcs or + trackster.raw_energy() < min_trackster_energy) { + isGood = false; + } else { + auto const &eigenvalues = trackster.eigenvalues(); + auto const sum = std::accumulate(std::begin(eigenvalues), std::end(eigenvalues), 0.f); + float pcaQuality = eigenvalues[0] / sum; + if (pcaQuality > pca_quality_th) { + isGood = true; + } + } + return isGood; + } + + //distance between skeletons + float projective_distance(const ticl::Vector &point1, const ticl::Vector &point2) { + // squared projective distance + float r1 = std::sqrt(point1.x() * point1.x() + point1.y() * point1.y()); + float r2_at_z1 = + std::sqrt(point2.x() * point2.x() + point2.y() * point2.y()) * std::abs(point1.z()) / std::abs(point2.z()); + float delta_phi = reco::deltaPhi(point1.Phi(), point2.Phi()); + float projective_distance = (r1 - r2_at_z1) * (r1 - r2_at_z1) + r2_at_z1 * r2_at_z1 * delta_phi * delta_phi; + LogDebug("TracksterLinkingbySkeletons") << "Computing distance between point : " << point1 << " And point " + << point2 << " Distance " << projective_distance << std::endl; + return projective_distance; + } +} // namespace + +using namespace ticl; + +TracksterLinkingbySkeletons::TracksterLinkingbySkeletons(const edm::ParameterSet &conf, edm::ConsumesCollector iC) + : TracksterLinkingAlgoBase(conf, iC), + timing_quality_threshold_(conf.getParameter("track_time_quality_threshold")), + del_(conf.getParameter("wind")), + min_num_lcs_(conf.getParameter("min_num_lcs")), + min_trackster_energy_(conf.getParameter("min_trackster_energy")), + pca_quality_th_(conf.getParameter("pca_quality_th")), + dot_prod_th_(conf.getParameter("dot_prod_th")), + max_distance_projective_sqr_(conf.getParameter>("max_distance_projective_sqr")), + min_distance_z_(conf.getParameter>("min_distance_z")), + max_distance_projective_sqr_closest_points_( + conf.getParameter>("max_distance_projective_sqr_closest_points")), + max_z_distance_closest_points_(conf.getParameter>("max_z_distance_closest_points")), + cylinder_radius_sqr_(conf.getParameter>("cylinder_radius_sqr")) + +{} + +void TracksterLinkingbySkeletons::buildLayers() { + // build disks at HGCal front & EM-Had interface for track propagation + + float zVal = hgcons_->waferZ(1, true); + std::pair rMinMax = hgcons_->rangeR(zVal, true); + + float zVal_interface = rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z(); + std::pair rMinMax_interface = hgcons_->rangeR(zVal_interface, true); + + for (int iSide = 0; iSide < 2; ++iSide) { + float zSide = (iSide == 0) ? (-1. * zVal) : zVal; + firstDisk_[iSide] = + std::make_unique(Disk::build(Disk::PositionType(0, 0, zSide), + Disk::RotationType(), + SimpleDiskBounds(rMinMax.first, rMinMax.second, zSide - 0.5, zSide + 0.5)) + .get()); + + zSide = (iSide == 0) ? (-1. * zVal_interface) : zVal_interface; + interfaceDisk_[iSide] = std::make_unique( + Disk::build(Disk::PositionType(0, 0, zSide), + Disk::RotationType(), + SimpleDiskBounds(rMinMax_interface.first, rMinMax_interface.second, zSide - 0.5, zSide + 0.5)) + .get()); + } +} + +void TracksterLinkingbySkeletons::initialize(const HGCalDDDConstants *hgcons, + const hgcal::RecHitTools rhtools, + const edm::ESHandle bfieldH, + const edm::ESHandle propH) { + hgcons_ = hgcons; + rhtools_ = rhtools; + buildLayers(); + + bfield_ = bfieldH; + propagator_ = propH; +} + +std::array TracksterLinkingbySkeletons::findSkeletonNodes( + const ticl::Trackster &trackster, + float lower_percentage, + float upper_percentage, + const std::vector &layerClusters, + const hgcal::RecHitTools &rhtools) { + auto const &vertices = trackster.vertices(); + auto const trackster_raw_energy = trackster.raw_energy(); + // sort vertices by layerId + std::vector sortedVertices(vertices); + std::sort(sortedVertices.begin(), sortedVertices.end(), [&layerClusters](unsigned int i, unsigned int j) { + return std::abs(layerClusters[i].z()) < std::abs(layerClusters[j].z()); + }); + + // now loop over sortedVertices and find the layerId that contains the lower_percentage of the energy + // and the layerId that contains the upper_percentage of the energy + float cumulativeEnergyFraction = 0.f; + int innerLayerId = rhtools.getLayerWithOffset(layerClusters[sortedVertices[0]].hitsAndFractions()[0].first); + float innerLayerZ = layerClusters[sortedVertices[0]].z(); + int outerLayerId = rhtools.getLayerWithOffset(layerClusters[sortedVertices.back()].hitsAndFractions()[0].first); + float outerLayerZ = layerClusters[sortedVertices.back()].z(); + bool foundInnerLayer = false; + bool foundOuterLayer = false; + for (auto const &v : sortedVertices) { + auto const &lc = layerClusters[v]; + auto const &n_lay = rhtools.getLayerWithOffset(lc.hitsAndFractions()[0].first); + cumulativeEnergyFraction += lc.energy() / trackster_raw_energy; + if (cumulativeEnergyFraction >= lower_percentage and not foundInnerLayer) { + innerLayerId = n_lay; + innerLayerZ = lc.z(); + foundInnerLayer = true; + } + if (cumulativeEnergyFraction >= upper_percentage and not foundOuterLayer) { + outerLayerId = n_lay; + outerLayerZ = lc.z(); + foundOuterLayer = true; + } + } + std::array skeleton; + int minimumDistanceInLayers = 4; + if (outerLayerId - innerLayerId < minimumDistanceInLayers) { + skeleton = {{trackster.barycenter(), trackster.barycenter(), trackster.barycenter()}}; + } else { + auto intersectLineWithSurface = [](float surfaceZ, const Vector &origin, const Vector &direction) -> Vector { + auto const t = (surfaceZ - origin.Z()) / direction.Z(); + auto const iX = t * direction.X() + origin.X(); + auto const iY = t * direction.Y() + origin.Y(); + auto const iZ = surfaceZ; + const Vector intersection(iX, iY, iZ); + return intersection; + }; + + auto const &t0_p1 = trackster.barycenter(); + auto const t0_p0 = intersectLineWithSurface(innerLayerZ, t0_p1, trackster.eigenvectors(0)); + auto const t0_p2 = intersectLineWithSurface(outerLayerZ, t0_p1, trackster.eigenvectors(0)); + skeleton = {{t0_p0, t0_p1, t0_p2}}; + std::sort(skeleton.begin(), skeleton.end(), [](Vector &v1, Vector &v2) { return v1.Z() < v2.Z(); }); + } + + return skeleton; +} + +bool isInCylinder(const std::array &mySkeleton, + const std::array &otherSkeleton, + const float radius_sqr) { + const auto ¢er = mySkeleton[1]; + const auto &pointToCheck = otherSkeleton[0]; + const auto distance2_xy = (pointToCheck.x() - center.x()) * (pointToCheck.x() - center.x()) + + (pointToCheck.y() - center.y()) * (pointToCheck.y() - center.y()); + LogDebug("TracksterLinkingbySkeletons") << " Distance XY " << distance2_xy << std::endl; + bool isWithinZ = std::abs(pointToCheck.z()) >= std::abs(mySkeleton[0].z()) and + std::abs(pointToCheck.z()) <= std::abs(mySkeleton[2].z()); + return (distance2_xy <= radius_sqr) && isWithinZ; +} + +bool TracksterLinkingbySkeletons::areCompatible(const ticl::Trackster &myTrackster, + const ticl::Trackster &otherTrackster, + const std::array &mySkeleton, + const std::array &otherSkeleton) { + //do not start links from small/bad tracksters + float zVal_interface = rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z(); + if (!isGoodTrackster(myTrackster, mySkeleton, min_num_lcs_, min_trackster_energy_, pca_quality_th_)) { + LogDebug("TracksterLinkingbySkeletons") << "Inner Trackster with energy " << myTrackster.raw_energy() << " Num LCs " + << myTrackster.vertices().size() << " NOT GOOD " << std::endl; + return false; + } else { + LogDebug("TracksterLinkingbySkeletons") << "Inner Trackster wi energy " << myTrackster.raw_energy() << " Num LCs " + << myTrackster.vertices().size() << " IS GOOD " << std::endl; + float proj_distance = projective_distance(mySkeleton[1], otherSkeleton[1]); + auto isEE = mySkeleton[1].z() <= zVal_interface ? 0 : 1; + bool areAlignedInProjectiveSpace = proj_distance < max_distance_projective_sqr_[isEE]; + LogDebug("TracksterLinkingbySkeletons") + << "\t Trying to compare with outer Trackster with energy " << otherTrackster.raw_energy() << " Num LCS " + << otherTrackster.vertices().size() << " Projective distance " << proj_distance << " areAlignedProjective " + << areAlignedInProjectiveSpace << " TH " << max_distance_projective_sqr_[isEE] << std::endl; + //check if otherTrackster is good + if (isGoodTrackster(otherTrackster, otherSkeleton, min_num_lcs_, min_trackster_energy_, pca_quality_th_)) { + // if both tracksters are good, then we can check the projective distance between the barycenters. + // if the barycenters are aligned, then we check that the two skeletons are aligned + if (areAlignedInProjectiveSpace) { + auto dotProdSkeletons = + ((mySkeleton[2] - mySkeleton[0]).Unit()).Dot((otherSkeleton[2] - otherSkeleton[0]).Unit()); + bool alignedSkeletons = dotProdSkeletons > dot_prod_th_; + LogDebug("TracksterLinkingbySkeletons") + << "\t Outer Trackster is Good, checking for skeleton alignment " << alignedSkeletons << " dotProd " + << dotProdSkeletons << " Threshold " << dot_prod_th_ << std::endl; + if (alignedSkeletons) + LogDebug("TracksterLinkingbySkeletons") << "\t\t Linked! " << std::endl; + return alignedSkeletons; + } else { + // we measure the distance between the two closest nodes in the two skeletons + LogDebug("TracksterLinkingbySkeletons") + << "\t Outer Trackster is not aligned, check skeletons distances " << std::endl; + int myClosestPoint = -1; + int otherClosestPoint = -1; + float minDistance_z = std::numeric_limits::max(); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + float dist_z = std::abs(mySkeleton[i].Z() - otherSkeleton[j].Z()); + if (dist_z < minDistance_z) { + myClosestPoint = i; + otherClosestPoint = j; + minDistance_z = dist_z; + } + } + } + if (minDistance_z < min_distance_z_[isEE]) { + LogDebug("TracksterLinkingbySkeletons") + << "\t Trackster have distance in Z " << minDistance_z + << "Checking if they are aligned in projective space " + << projective_distance(mySkeleton[myClosestPoint], otherSkeleton[otherClosestPoint]) << " TH " + << max_distance_projective_sqr_[isEE] << std::endl; + if (projective_distance(mySkeleton[myClosestPoint], otherSkeleton[otherClosestPoint]) < + max_distance_projective_sqr_[isEE]) { + LogDebug("TracksterLinkingbySkeletons") << "\t\t Linked! " << std::endl; + } + return projective_distance(mySkeleton[myClosestPoint], otherSkeleton[otherClosestPoint]) < + max_distance_projective_sqr_[isEE]; + } else { + LogDebug("TracksterLinkingbySkeletons") << "\t\t Not Linked Distance Z " << minDistance_z << std::endl; + return false; + } + } + } else { + LogDebug("TracksterLinkingbySkeletons") + << "\t Outer Trackster is NOT GOOD, check projective space alignment " << areAlignedInProjectiveSpace + << " proj_distance " << max_distance_projective_sqr_[isEE] << std::endl; + if (areAlignedInProjectiveSpace) { + LogDebug("TracksterLinkingbySkeletons") << "\t\t Linked! " << std::endl; + return true; + } else { + LogDebug("TracksterLinkingbySkeletons") + << "\t Not aligned in projective space, check distance between closest points in the two skeletons " + << std::endl; + // we measure the distance between the two closest nodes in the two skeletons + int myClosestPoint = -1; + int otherClosestPoint = -1; + float minDistance_z = std::numeric_limits::max(); + // we skip the innermost node of mySkeleton + for (int i = 1; i < 3; i++) { + for (int j = 0; j < 3; j++) { + float dist_z = std::abs(mySkeleton[i].Z() - otherSkeleton[j].Z()); + if (dist_z < minDistance_z) { + myClosestPoint = i; + otherClosestPoint = j; + minDistance_z = dist_z; + } + } + } + float d = projective_distance(mySkeleton[myClosestPoint], otherSkeleton[otherClosestPoint]); + LogDebug("TracksterLinkingbySkeletons") + << "\t\t Distance between closest points " << d << " TH " << 10.f << " Z Distance " << minDistance_z + << " TH " << max_distance_projective_sqr_closest_points_[isEE] << std::endl; + if (d < max_distance_projective_sqr_closest_points_[isEE] and + minDistance_z < max_z_distance_closest_points_[isEE]) { + LogDebug("TracksterLinkingbySkeletons") << "\t\t\t Linked! " << d << std::endl; + return true; + } else { + LogDebug("TracksterLinkingbySkeletons") << "Distance between closest point " << d << " Distance in z " + << max_z_distance_closest_points_[isEE] << std::endl; + bool isInCyl = isInCylinder(mySkeleton, otherSkeleton, cylinder_radius_sqr_[isEE]); + LogDebug("TracksterLinkingbySkeletons") << "Two Points are in Cylinder " << isInCylinder << std::endl; + if (isInCyl) { + LogDebug("TracksterLinkingbySkeletons") << "\t\t\t Linked! " << d << std::endl; + } + return isInCyl; + } + } + } + } +} + +void TracksterLinkingbySkeletons::linkTracksters( + const Inputs &input, + std::vector &resultTracksters, + std::vector> &linkedResultTracksters, + std::vector> &linkedTracksterIdToInputTracksterId) { + const auto &tracksters = input.tracksters; + const auto &layerClusters = input.layerClusters; + + // sort tracksters by energy + std::vector sortedTracksters(tracksters.size()); + std::iota(sortedTracksters.begin(), sortedTracksters.end(), 0); + std::sort(sortedTracksters.begin(), sortedTracksters.end(), [&tracksters](unsigned int i, unsigned int j) { + return tracksters[i].raw_energy() > tracksters[j].raw_energy(); + }); + // fill tiles for trackster linking + // tile 0 for negative eta + // tile 1 for positive eta + std::array tracksterTile; + // loop over tracksters sorted by energy and calculate skeletons + // fill tiles for trackster linking + std::vector> skeletons(tracksters.size()); + for (auto const t_idx : sortedTracksters) { + const auto &trackster = tracksters[t_idx]; + skeletons[t_idx] = findSkeletonNodes(tracksters[t_idx], 0.1, 0.9, layerClusters, rhtools_); + tracksterTile[trackster.barycenter().eta() > 0.f].fill( + trackster.barycenter().eta(), trackster.barycenter().phi(), t_idx); + } + std::vector maskReceivedLink(tracksters.size(), 1); + std::vector isRootTracksters(tracksters.size(), 1); + + std::vector allNodes; + for (size_t it = 0; it < tracksters.size(); ++it) { + allNodes.emplace_back(it); + } + + // loop over tracksters sorted by energy and link them + for (auto const &t_idx : sortedTracksters) { + auto const &trackster = tracksters[t_idx]; + auto const &skeleton = skeletons[t_idx]; + + auto const bary = trackster.barycenter(); + float eta_min = std::max(abs(bary.eta()) - del_, TileConstants::minEta); + float eta_max = std::min(abs(bary.eta()) + del_, TileConstants::maxEta); + int tileIndex = bary.eta() > 0.f; + const auto &tiles = tracksterTile[tileIndex]; + std::array search_box = tiles.searchBoxEtaPhi(eta_min, eta_max, bary.phi() - del_, bary.phi() + del_); + if (search_box[2] > search_box[3]) { + search_box[3] += TileConstants::nPhiBins; + } + + for (int eta_i = search_box[0]; eta_i <= search_box[1]; ++eta_i) { + for (int phi_i = search_box[2]; phi_i <= search_box[3]; ++phi_i) { + auto &neighbours = tiles[tiles.globalBin(eta_i, (phi_i % TileConstants::nPhiBins))]; + for (auto n : neighbours) { + if (t_idx == n) + continue; + if (maskReceivedLink[n] == 0 or allNodes[t_idx].isInnerNeighbour(n)) + continue; + if (isGoodTrackster(trackster, skeleton, min_num_lcs_, min_trackster_energy_, pca_quality_th_)) { + LogDebug("TracksterLinkingbySkeletons") + << "Trying to Link Trackster " << t_idx << " With Trackster " << n << std::endl; + if (areCompatible(trackster, tracksters[n], skeleton, skeletons[n])) { + LogDebug("TracksterLinkingbySkeletons") + << "\t==== LINK: Trackster " << t_idx << " Linked with Trackster " << n << std::endl; + maskReceivedLink[n] = 0; + allNodes[t_idx].addOuterNeighbour(n); + allNodes[n].addInnerNeighbour(t_idx); + isRootTracksters[n] = 0; + } + } + } + } + } + } + + LogDebug("TracksterLinkingbySkeletons") << "**************** FINAL GRAPH **********************" << std::endl; + for (auto const &node : allNodes) { + if (isRootTracksters[node.getId()]) { + LogDebug("TracksterLinkingbySkeletons") + << "ISROOT " + << " Node " << node.getId() << " position " << tracksters[node.getId()].barycenter() << " energy " + << tracksters[node.getId()].raw_energy() << std::endl; + } else { + LogDebug("TracksterLinkingbySkeletons") + << "Node " << node.getId() << " position " << tracksters[node.getId()].barycenter() << " energy " + << tracksters[node.getId()].raw_energy() << std::endl; + } + } + LogDebug("TracksterLinkingbySkeletons") << "********************************************************" << std::endl; + + TICLGraph graph(allNodes, isRootTracksters); + + int ic = 0; + auto const &components = graph.findSubComponents(); + linkedTracksterIdToInputTracksterId.resize(components.size()); + for (auto const &comp : components) { + LogDebug("TracksterLinkingbySkeletons") << "Component " << ic << " Node: "; + std::vector linkedTracksters; + Trackster outTrackster; + if (comp.size() == 1) { + if (input.tracksters[comp[0]].vertices().size() <= 3) { + continue; + } + } + for (auto const &node : comp) { + LogDebug("TracksterLinkingbySkeletons") << node << " "; + linkedTracksterIdToInputTracksterId[ic].push_back(node); + outTrackster.mergeTracksters(input.tracksters[node]); + } + linkedTracksters.push_back(resultTracksters.size()); + resultTracksters.push_back(outTrackster); + linkedResultTracksters.push_back(linkedTracksters); + LogDebug("TracksterLinkingbySkeletons") << "\n"; + ++ic; + } +} // linkTracksters diff --git a/RecoHGCal/TICL/plugins/TracksterLinkingbySkeletons.h b/RecoHGCal/TICL/plugins/TracksterLinkingbySkeletons.h new file mode 100644 index 0000000000000..d357889305bca --- /dev/null +++ b/RecoHGCal/TICL/plugins/TracksterLinkingbySkeletons.h @@ -0,0 +1,98 @@ +#ifndef RecoHGCal_TICL_TracksterLinkingAlgoBySkeletons_H +#define RecoHGCal_TICL_TracksterLinkingAlgoBySkeletons_H + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" +#include "RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h" +#include "Geometry/HGCalCommonData/interface/HGCalDDDConstants.h" +#include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "Geometry/CommonDetUnit/interface/GeomDet.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "DataFormats/GeometrySurface/interface/BoundDisk.h" +#include "MagneticField/Engine/interface/MagneticField.h" +#include "TrackingTools/GeomPropagators/interface/Propagator.h" +#include + +namespace ticl { + + class TracksterLinkingbySkeletons : public TracksterLinkingAlgoBase { + public: + TracksterLinkingbySkeletons(const edm::ParameterSet& conf, edm::ConsumesCollector iC); + + ~TracksterLinkingbySkeletons() override {} + + void linkTracksters(const Inputs& input, + std::vector& resultTracksters, + std::vector>& linkedResultTracksters, + std::vector>& linkedTracksterIdToInputTracksterId) override; + + std::array findSkeletonNodes(const ticl::Trackster& trackster, + float lower_percentage, + float upper_percentage, + const std::vector& layerClusters, + const hgcal::RecHitTools& rhtools); + + bool areCompatible(const ticl::Trackster& myTrackster, + const ticl::Trackster& otherTrackster, + const std::array& mySkeleton, + const std::array& otherSkeleton); + + void initialize(const HGCalDDDConstants* hgcons, + const hgcal::RecHitTools rhtools, + const edm::ESHandle bfieldH, + const edm::ESHandle propH) override; + + static void fillPSetDescription(edm::ParameterSetDescription& iDesc) { + iDesc.add("track_time_quality_threshold", 0.5); + iDesc.add("wind", 0.036); + iDesc.add("min_num_lcs", 7); + iDesc.add("min_trackster_energy", 10.); + iDesc.add("pca_quality_th", 0.85); + iDesc.add("dot_prod_th", 0.97); + iDesc.add>("max_distance_projective_sqr", {60., 60.}); + iDesc.add>("min_distance_z", {30., 30.}); + iDesc.add>("max_distance_projective_sqr_closest_points", {60., 60.}); + iDesc.add>("max_z_distance_closest_points", {35., 35.}); + iDesc.add>("cylinder_radius_sqr", {9., 9.}); + TracksterLinkingAlgoBase::fillPSetDescription(iDesc); + } + + private: + using Vector = ticl::Trackster::Vector; + + void buildLayers(); + + void dumpLinksFound(std::vector>& resultCollection, const char* label) const; + + float timing_quality_threshold_; + float del_; + unsigned int min_num_lcs_; + float min_trackster_energy_; + float pca_quality_th_; + float dot_prod_th_; + std::vector max_distance_projective_sqr_; + std::vector min_distance_z_; + std::vector max_distance_projective_sqr_closest_points_; + std::vector max_z_distance_closest_points_; + std::vector cylinder_radius_sqr_; + + const HGCalDDDConstants* hgcons_; + + std::unique_ptr firstDisk_[2]; + std::unique_ptr interfaceDisk_[2]; + + hgcal::RecHitTools rhtools_; + + edm::ESHandle bfield_; + edm::ESHandle propagator_; + }; + +} // namespace ticl + +#endif diff --git a/RecoHGCal/TICL/plugins/TracksterLinksProducer.cc b/RecoHGCal/TICL/plugins/TracksterLinksProducer.cc new file mode 100644 index 0000000000000..85573fdca6014 --- /dev/null +++ b/RecoHGCal/TICL/plugins/TracksterLinksProducer.cc @@ -0,0 +1,417 @@ +// Author: Felice Pantaleo, Wahid Redjeb (CERN) - felice.pantaleo@cern.ch, wahid.redjeb@cern.ch +// Date: 12/2023 +#include // unique_ptr +#include "CommonTools/RecoAlgos/interface/MultiVectorManager.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/PluginDescription.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" + +#include "DataFormats/Common/interface/OrphanHandle.h" + +#include "DataFormats/CaloRecHit/interface/CaloCluster.h" +#include "DataFormats/HGCalReco/interface/Common.h" +#include "DataFormats/HGCalReco/interface/TICLLayerTile.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" + +#include "PhysicsTools/TensorFlow/interface/TfGraphRecord.h" +#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" +#include "PhysicsTools/TensorFlow/interface/TfGraphDefWrapper.h" +#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" + +#include "RecoHGCal/TICL/interface/TracksterLinkingAlgoBase.h" +#include "RecoHGCal/TICL/plugins/TracksterLinkingPluginFactory.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" + +#include "TrackingTools/GeomPropagators/interface/Propagator.h" +#include "TrackingTools/Records/interface/TrackingComponentsRecord.h" + +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" + +#include "Geometry/HGCalCommonData/interface/HGCalDDDConstants.h" +#include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "Geometry/CommonDetUnit/interface/GeomDet.h" + +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" + +#include "TrackstersPCA.h" + +using namespace ticl; + +class TracksterLinksProducer : public edm::stream::EDProducer<> { +public: + explicit TracksterLinksProducer(const edm::ParameterSet &ps); + ~TracksterLinksProducer() override{}; + void produce(edm::Event &, const edm::EventSetup &) override; + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); + + void beginRun(edm::Run const &iEvent, edm::EventSetup const &es) override; + +private: + void printTrackstersDebug(const std::vector &, const char *label) const; + void dumpTrackster(const Trackster &) const; + void energyRegressionAndID(const std::vector &layerClusters, + const tensorflow::Session *, + std::vector &result) const; + + std::unique_ptr linkingAlgo_; + + std::vector>> tracksters_tokens_; + const edm::EDGetTokenT> clusters_token_; + const edm::EDGetTokenT>> clustersTime_token_; + + const bool regressionAndPid_; + const std::string tfDnnLabel_; + const edm::ESGetToken tfDnnToken_; + const tensorflow::Session *tfSession_; + const std::string eidInputName_; + const std::string eidOutputNameEnergy_; + const std::string eidOutputNameId_; + const float eidMinClusterEnergy_; + const int eidNLayers_; + const int eidNClusters_; + static constexpr int eidNFeatures_ = 3; + tensorflow::Session *eidSession_; + + std::vector>> original_masks_tokens_; + + const edm::ESGetToken geometry_token_; + const std::string detector_; + const std::string propName_; + + const edm::ESGetToken bfield_token_; + const edm::ESGetToken propagator_token_; + const HGCalDDDConstants *hgcons_; + hgcal::RecHitTools rhtools_; + edm::ESGetToken hdc_token_; +}; + +TracksterLinksProducer::TracksterLinksProducer(const edm::ParameterSet &ps) + : clusters_token_(consumes>(ps.getParameter("layer_clusters"))), + clustersTime_token_( + consumes>>(ps.getParameter("layer_clustersTime"))), + regressionAndPid_(ps.getParameter("regressionAndPid")), + tfDnnLabel_(ps.getParameter("tfDnnLabel")), + tfDnnToken_(esConsumes(edm::ESInputTag("", tfDnnLabel_))), + tfSession_(nullptr), + eidInputName_(ps.getParameter("eid_input_name")), + eidOutputNameEnergy_(ps.getParameter("eid_output_name_energy")), + eidOutputNameId_(ps.getParameter("eid_output_name_id")), + eidMinClusterEnergy_(ps.getParameter("eid_min_cluster_energy")), + eidNLayers_(ps.getParameter("eid_n_layers")), + eidNClusters_(ps.getParameter("eid_n_clusters")), + eidSession_(nullptr), + geometry_token_(esConsumes()), + detector_(ps.getParameter("detector")), + propName_(ps.getParameter("propagator")), + bfield_token_(esConsumes()), + propagator_token_( + esConsumes(edm::ESInputTag("", propName_))) { + // Loop over the edm::VInputTag and append the token to tracksters_tokens_ + for (auto const &tag : ps.getParameter>("tracksters_collections")) { + tracksters_tokens_.emplace_back(consumes>(tag)); + } + //Loop over the edm::VInputTag of masks and append the token to original_masks_tokens_ + for (auto const &tag : ps.getParameter>("original_masks")) { + original_masks_tokens_.emplace_back(consumes>(tag)); + } + + // New trackster collection after linking + produces>(); + + // Links + produces>>(); + // LayerClusters Mask + produces>(); + + auto linkingPSet = ps.getParameter("linkingPSet"); + auto algoType = linkingPSet.getParameter("type"); + + if (algoType == "Skeletons") { + std::string detectorName_ = (detector_ == "HFNose") ? "HGCalHFNoseSensitive" : "HGCalEESensitive"; + hdc_token_ = esConsumes( + edm::ESInputTag("", detectorName_)); + } + + linkingAlgo_ = TracksterLinkingPluginFactory::get()->create(algoType, linkingPSet, consumesCollector()); +} + +void TracksterLinksProducer::beginRun(edm::Run const &iEvent, edm::EventSetup const &es) { + edm::ESHandle hdc = es.getHandle(hdc_token_); + hgcons_ = hdc.product(); + + edm::ESHandle geom = es.getHandle(geometry_token_); + rhtools_.setGeometry(*geom); + + edm::ESHandle bfield = es.getHandle(bfield_token_); + edm::ESHandle propagator = es.getHandle(propagator_token_); + + linkingAlgo_->initialize(hgcons_, rhtools_, bfield, propagator); +}; + +void TracksterLinksProducer::dumpTrackster(const Trackster &t) const { + auto e_over_h = (t.raw_em_pt() / ((t.raw_pt() - t.raw_em_pt()) != 0. ? (t.raw_pt() - t.raw_em_pt()) : 1.)); + LogDebug("TracksterLinksProducer") + << "\nTrackster raw_pt: " << t.raw_pt() << " raw_em_pt: " << t.raw_em_pt() << " eoh: " << e_over_h + << " barycenter: " << t.barycenter() << " eta,phi (baricenter): " << t.barycenter().eta() << ", " + << t.barycenter().phi() << " eta,phi (eigen): " << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() + << " pt(eigen): " << std::sqrt(t.eigenvectors(0).Unit().perp2()) * t.raw_energy() << " seedID: " << t.seedID() + << " seedIndex: " << t.seedIndex() << " size: " << t.vertices().size() << " average usage: " + << (std::accumulate(std::begin(t.vertex_multiplicity()), std::end(t.vertex_multiplicity()), 0.) / + (float)t.vertex_multiplicity().size()) + << " raw_energy: " << t.raw_energy() << " regressed energy: " << t.regressed_energy() + << " probs(ga/e/mu/np/cp/nh/am/unk): "; + for (auto const &p : t.id_probabilities()) { + LogDebug("TracksterLinksProducer") << std::fixed << p << " "; + } + LogDebug("TracksterLinksProducer") << " sigmas: "; + for (auto const &s : t.sigmas()) { + LogDebug("TracksterLinksProducer") << s << " "; + } + LogDebug("TracksterLinksProducer") << std::endl; +} + +void TracksterLinksProducer::energyRegressionAndID(const std::vector &layerClusters, + const tensorflow::Session *eidSession, + std::vector &tracksters) const { + // 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 + + // do nothing when no trackster passes the selection (3) + int batchSize = (int)tracksters.size(); + if (batchSize == 0) { + return; + } + + for (auto &t : tracksters) { + t.setRegressedEnergy(0.f); + t.zeroProbabilities(); + } + + // 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}}; + static constexpr int inputDimension = 4; + + 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[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 (int i = 0; i < batchSize; ++i) { + float regressedEnergy = + tracksters[i].raw_energy() > eidMinClusterEnergy_ ? energy[i] : tracksters[i].raw_energy(); + tracksters[i].setRegressedEnergy(regressedEnergy); + } + } + + // 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(); + float *probs = outputs[probsIdx].flat().data(); + int probsNumber = tracksters[0].id_probabilities().size(); + for (int i = 0; i < batchSize; ++i) { + tracksters[i].setProbabilities(&probs[i * probsNumber]); + } + } +} + +void TracksterLinksProducer::produce(edm::Event &evt, const edm::EventSetup &es) { + auto resultTracksters = std::make_unique>(); + + auto linkedResultTracksters = std::make_unique>>(); + + const auto &layerClusters = evt.get(clusters_token_); + const auto &layerClustersTimes = evt.get(clustersTime_token_); + + tfSession_ = es.getData(tfDnnToken_).getSession(); + // loop over the original_masks_tokens_ and get the original masks collections and multiply them + // to get the global mask + std::vector original_global_mask(layerClusters.size(), 1.f); + for (unsigned int i = 0; i < original_masks_tokens_.size(); ++i) { + const auto &tmp_mask = evt.get(original_masks_tokens_[i]); + for (unsigned int j = 0; j < tmp_mask.size(); ++j) { + original_global_mask[j] *= tmp_mask[j]; + } + } + + auto resultMask = std::make_unique>(original_global_mask); + + std::vector>> tracksters_h(tracksters_tokens_.size()); + MultiVectorManager trackstersManager; + for (unsigned int i = 0; i < tracksters_tokens_.size(); ++i) { + evt.getByToken(tracksters_tokens_[i], tracksters_h[i]); + //Fill MultiVectorManager + trackstersManager.addVector(*tracksters_h[i]); + } + + // Linking + const typename TracksterLinkingAlgoBase::Inputs input(evt, es, layerClusters, layerClustersTimes, trackstersManager); + std::vector> linkedTracksterIdToInputTracksterId; + + // LinkTracksters will produce a vector of vector of indices of tracksters that: + // 1) are linked together if more than one + // 2) are isolated if only one + // Result tracksters contains the final version of the trackster collection + // linkedTrackstersToInputTrackstersMap contains the mapping between the linked tracksters and the input tracksters + linkingAlgo_->linkTracksters(input, *resultTracksters, *linkedResultTracksters, linkedTracksterIdToInputTracksterId); + + // Now we need to remove the tracksters that are not linked + // We need to emplace_back in the resultTracksters only the tracksters that are linked + + for (auto const &resultTrackster : *resultTracksters) { + for (auto const &clusterIndex : resultTrackster.vertices()) { + (*resultMask)[clusterIndex] = 0.f; + } + } + + if (regressionAndPid_) + energyRegressionAndID(layerClusters, tfSession_, *resultTracksters); + + assignPCAtoTracksters( + *resultTracksters, layerClusters, layerClustersTimes, rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z(), true); + + evt.put(std::move(linkedResultTracksters)); + evt.put(std::move(resultMask)); + evt.put(std::move(resultTracksters)); +} + +void TracksterLinksProducer::printTrackstersDebug(const std::vector &tracksters, const char *label) const { + int counter = 0; + LogDebug("TracksterLinksProducer").log([&](auto &log) { + for (auto const &t : tracksters) { + log << counter++ << " TracksterLinksProducer (" << label << ") obj barycenter: " << t.barycenter() + << " eta,phi (baricenter): " << t.barycenter().eta() << ", " << t.barycenter().phi() + << " eta,phi (eigen): " << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() + << " pt(eigen): " << std::sqrt(t.eigenvectors(0).Unit().perp2()) * t.raw_energy() << " seedID: " << t.seedID() + << " seedIndex: " << t.seedIndex() << " size: " << t.vertices().size() << " average usage: " + << (std::accumulate(std::begin(t.vertex_multiplicity()), std::end(t.vertex_multiplicity()), 0.) / + (float)t.vertex_multiplicity().size()) + << " raw_energy: " << t.raw_energy() << " regressed energy: " << t.regressed_energy() + << " probs(ga/e/mu/np/cp/nh/am/unk): "; + for (auto const &p : t.id_probabilities()) { + log << std::fixed << p << " "; + } + log << " sigmas: "; + for (auto const &s : t.sigmas()) { + log << s << " "; + } + log << "\n"; + } + }); +} + +void TracksterLinksProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { + edm::ParameterSetDescription desc; + edm::ParameterSetDescription linkingDesc; + linkingDesc.addNode(edm::PluginDescription("type", "Skeletons", true)); + + desc.add("linkingPSet", linkingDesc); + desc.add>("tracksters_collections", {edm::InputTag("ticlTrackstersCLUE3DHigh")}); + desc.add>("original_masks", + {edm::InputTag("hgcalMergeLayerClusters", "InitialLayerClustersMask")}); + desc.add("layer_clusters", edm::InputTag("hgcalMergeLayerClusters")); + desc.add("layer_clustersTime", edm::InputTag("hgcalMergeLayerClusters", "timeLayerCluster")); + desc.add("regressionAndPid", false); + desc.add("tfDnnLabel", "tracksterSelectionTf"); + desc.add("eid_input_name", "input"); + desc.add("eid_output_name_energy", "output/regressed_energy"); + desc.add("eid_output_name_id", "output/id_probabilities"); + desc.add("eid_min_cluster_energy", 2.5); + desc.add("eid_n_layers", 50); + desc.add("eid_n_clusters", 10); + desc.add("detector", "HGCAL"); + desc.add("propagator", "PropagatorWithMaterial"); + descriptions.add("tracksterLinksProducer", desc); +} + +DEFINE_FWK_MODULE(TracksterLinksProducer); diff --git a/RecoHGCal/TICL/plugins/TrackstersMergeProducer.cc b/RecoHGCal/TICL/plugins/TrackstersMergeProducer.cc index c44ec8f5a5811..dda200de1f456 100644 --- a/RecoHGCal/TICL/plugins/TrackstersMergeProducer.cc +++ b/RecoHGCal/TICL/plugins/TrackstersMergeProducer.cc @@ -68,7 +68,7 @@ class TrackstersMergeProducer : public edm::stream::EDProducer<> { private: typedef ticl::Trackster::IterationIndex TracksterIterIndex; - typedef math::XYZVector Vector; + typedef ticl::Vector Vector; void fillTile(TICLTracksterTiles &, const std::vector &, TracksterIterIndex); @@ -85,9 +85,9 @@ class TrackstersMergeProducer : public edm::stream::EDProducer<> { const edm::EDGetTokenT> clusters_token_; const edm::EDGetTokenT>> clustersTime_token_; const edm::EDGetTokenT> tracks_token_; - const edm::EDGetTokenT> tracks_time_token_; - const edm::EDGetTokenT> tracks_time_quality_token_; - const edm::EDGetTokenT> tracks_time_err_token_; + edm::EDGetTokenT> tracks_time_token_; + edm::EDGetTokenT> tracks_time_quality_token_; + edm::EDGetTokenT> tracks_time_err_token_; const edm::EDGetTokenT> muons_token_; const std::string tfDnnLabel_; const edm::ESGetToken tfDnnToken_; @@ -143,9 +143,6 @@ TrackstersMergeProducer::TrackstersMergeProducer(const edm::ParameterSet &ps) clustersTime_token_( consumes>>(ps.getParameter("layer_clustersTime"))), tracks_token_(consumes>(ps.getParameter("tracks"))), - tracks_time_token_(consumes>(ps.getParameter("tracksTime"))), - tracks_time_quality_token_(consumes>(ps.getParameter("tracksTimeQual"))), - tracks_time_err_token_(consumes>(ps.getParameter("tracksTimeErr"))), muons_token_(consumes>(ps.getParameter("muons"))), tfDnnLabel_(ps.getParameter("tfDnnLabel")), tfDnnToken_(esConsumes(edm::ESInputTag("", tfDnnLabel_))), @@ -184,6 +181,12 @@ TrackstersMergeProducer::TrackstersMergeProducer(const edm::ParameterSet &ps) produces>(); produces>(); + if (useMTDTiming_) { + tracks_time_token_ = consumes>(ps.getParameter("tracksTime")); + tracks_time_quality_token_ = consumes>(ps.getParameter("tracksTimeQual")); + tracks_time_err_token_ = consumes>(ps.getParameter("tracksTimeErr")); + } + std::string detectorName_ = (detector_ == "HFNose") ? "HGCalHFNoseSensitive" : "HGCalEESensitive"; hdc_token_ = esConsumes(edm::ESInputTag("", detectorName_)); @@ -556,8 +559,7 @@ void TrackstersMergeProducer::assignTimeToCandidates(std::vector } } if (invTimeErr > 0) { - cand.setTime(time / invTimeErr); - cand.setTimeError(sqrt(1.f / invTimeErr)); + cand.setTime(time / invTimeErr, sqrt(1.f / invTimeErr)); } } } diff --git a/RecoHGCal/TICL/plugins/TrackstersMergeProducerV3.cc b/RecoHGCal/TICL/plugins/TrackstersMergeProducerV3.cc deleted file mode 100644 index 2237ecf8ae19a..0000000000000 --- a/RecoHGCal/TICL/plugins/TrackstersMergeProducerV3.cc +++ /dev/null @@ -1,752 +0,0 @@ -#include // unique_ptr -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/ESGetToken.h" - -#include "DataFormats/CaloRecHit/interface/CaloCluster.h" -#include "DataFormats/HGCalReco/interface/Common.h" -#include "DataFormats/HGCalReco/interface/TICLLayerTile.h" -#include "DataFormats/HGCalReco/interface/Trackster.h" -#include "DataFormats/HGCalReco/interface/TICLSeedingRegion.h" -#include "DataFormats/TrackReco/interface/Track.h" -#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" -#include "RecoHGCal/TICL/interface/GlobalCache.h" - -#include "PhysicsTools/TensorFlow/interface/TfGraphRecord.h" -#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" -#include "PhysicsTools/TensorFlow/interface/TfGraphDefWrapper.h" - -#include "DataFormats/HGCalReco/interface/TICLCandidate.h" - -#include "TrackstersPCA.h" - -using namespace ticl; - -class TrackstersMergeProducerV3 : public edm::stream::EDProducer<> { -public: - explicit TrackstersMergeProducerV3(const edm::ParameterSet &ps); - ~TrackstersMergeProducerV3() override{}; - void produce(edm::Event &, const edm::EventSetup &) override; - static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); - -private: - typedef ticl::Trackster::IterationIndex TracksterIterIndex; - - void fillTile(TICLTracksterTiles &, const std::vector &, TracksterIterIndex); - - void energyRegressionAndID(const std::vector &layerClusters, - const tensorflow::Session *, - std::vector &result) const; - void printTrackstersDebug(const std::vector &, const char *label) const; - void assignTimeToCandidates(std::vector &resultCandidates) const; - void dumpTrackster(const Trackster &) const; - - const edm::EDGetTokenT> tracksterstrkem_token_; - const edm::EDGetTokenT> trackstersem_token_; - const edm::EDGetTokenT> tracksterstrk_token_; - const edm::EDGetTokenT> trackstershad_token_; - const edm::EDGetTokenT> seedingTrk_token_; - const edm::EDGetTokenT> clusters_token_; - const edm::EDGetTokenT>> clustersTime_token_; - const edm::EDGetTokenT> tracks_token_; - const edm::ESGetToken geometry_token_; - const std::string tfDnnLabel_; - const edm::ESGetToken tfDnnToken_; - const tensorflow::Session *tfSession_; - - const bool optimiseAcrossTracksters_; - const int eta_bin_window_; - const int phi_bin_window_; - const double pt_sigma_high_; - const double pt_sigma_low_; - const double halo_max_distance2_; - const double track_min_pt_; - const double track_min_eta_; - const double track_max_eta_; - const int track_max_missing_outerhits_; - const double cosangle_align_; - const double e_over_h_threshold_; - const double pt_neutral_threshold_; - const double resol_calo_offset_had_; - const double resol_calo_scale_had_; - const double resol_calo_offset_em_; - const double resol_calo_scale_em_; - const std::string eidInputName_; - const std::string eidOutputNameEnergy_; - const std::string eidOutputNameId_; - const float eidMinClusterEnergy_; - const int eidNLayers_; - const int eidNClusters_; - - tensorflow::Session *eidSession_; - hgcal::RecHitTools rhtools_; - - static constexpr int eidNFeatures_ = 3; -}; - -TrackstersMergeProducerV3::TrackstersMergeProducerV3(const edm::ParameterSet &ps) - : tracksterstrkem_token_(consumes>(ps.getParameter("tracksterstrkem"))), - trackstersem_token_(consumes>(ps.getParameter("trackstersem"))), - tracksterstrk_token_(consumes>(ps.getParameter("tracksterstrk"))), - trackstershad_token_(consumes>(ps.getParameter("trackstershad"))), - seedingTrk_token_(consumes>(ps.getParameter("seedingTrk"))), - clusters_token_(consumes>(ps.getParameter("layer_clusters"))), - clustersTime_token_( - consumes>>(ps.getParameter("layer_clustersTime"))), - tracks_token_(consumes>(ps.getParameter("tracks"))), - geometry_token_(esConsumes()), - tfDnnLabel_(ps.getParameter("tfDnnLabel")), - tfDnnToken_(esConsumes(edm::ESInputTag("", tfDnnLabel_))), - tfSession_(nullptr), - optimiseAcrossTracksters_(ps.getParameter("optimiseAcrossTracksters")), - eta_bin_window_(ps.getParameter("eta_bin_window")), - phi_bin_window_(ps.getParameter("phi_bin_window")), - pt_sigma_high_(ps.getParameter("pt_sigma_high")), - pt_sigma_low_(ps.getParameter("pt_sigma_low")), - halo_max_distance2_(ps.getParameter("halo_max_distance2")), - track_min_pt_(ps.getParameter("track_min_pt")), - track_min_eta_(ps.getParameter("track_min_eta")), - track_max_eta_(ps.getParameter("track_max_eta")), - track_max_missing_outerhits_(ps.getParameter("track_max_missing_outerhits")), - cosangle_align_(ps.getParameter("cosangle_align")), - e_over_h_threshold_(ps.getParameter("e_over_h_threshold")), - pt_neutral_threshold_(ps.getParameter("pt_neutral_threshold")), - resol_calo_offset_had_(ps.getParameter("resol_calo_offset_had")), - resol_calo_scale_had_(ps.getParameter("resol_calo_scale_had")), - resol_calo_offset_em_(ps.getParameter("resol_calo_offset_em")), - resol_calo_scale_em_(ps.getParameter("resol_calo_scale_em")), - eidInputName_(ps.getParameter("eid_input_name")), - eidOutputNameEnergy_(ps.getParameter("eid_output_name_energy")), - eidOutputNameId_(ps.getParameter("eid_output_name_id")), - eidMinClusterEnergy_(ps.getParameter("eid_min_cluster_energy")), - eidNLayers_(ps.getParameter("eid_n_layers")), - eidNClusters_(ps.getParameter("eid_n_clusters")), - eidSession_(nullptr) { - produces>(); - produces>(); -} - -void TrackstersMergeProducerV3::fillTile(TICLTracksterTiles &tracksterTile, - const std::vector &tracksters, - TracksterIterIndex tracksterIteration) { - int tracksterId = 0; - for (auto const &t : tracksters) { - tracksterTile.fill(tracksterIteration, t.barycenter().eta(), t.barycenter().phi(), tracksterId); - LogDebug("TrackstersMergeProducerV3") << "Adding tracksterId: " << tracksterId << " into bin [eta,phi]: [ " - << tracksterTile[tracksterIteration].etaBin(t.barycenter().eta()) << ", " - << tracksterTile[tracksterIteration].phiBin(t.barycenter().phi()) - << "] for iteration: " << tracksterIteration << std::endl; - - tracksterId++; - } -} - -void TrackstersMergeProducerV3::dumpTrackster(const Trackster &t) const { - auto e_over_h = (t.raw_em_pt() / ((t.raw_pt() - t.raw_em_pt()) != 0. ? (t.raw_pt() - t.raw_em_pt()) : 1.)); - LogDebug("TrackstersMergeProducerV3") - << "\nTrackster raw_pt: " << t.raw_pt() << " raw_em_pt: " << t.raw_em_pt() << " eoh: " << e_over_h - << " barycenter: " << t.barycenter() << " eta,phi (baricenter): " << t.barycenter().eta() << ", " - << t.barycenter().phi() << " eta,phi (eigen): " << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() - << " pt(eigen): " << std::sqrt(t.eigenvectors(0).Unit().perp2()) * t.raw_energy() << " seedID: " << t.seedID() - << " seedIndex: " << t.seedIndex() << " size: " << t.vertices().size() << " average usage: " - << (std::accumulate(std::begin(t.vertex_multiplicity()), std::end(t.vertex_multiplicity()), 0.) / - (float)t.vertex_multiplicity().size()) - << " raw_energy: " << t.raw_energy() << " regressed energy: " << t.regressed_energy() - << " probs(ga/e/mu/np/cp/nh/am/unk): "; - for (auto const &p : t.id_probabilities()) { - LogDebug("TrackstersMergeProducerV3") << std::fixed << p << " "; - } - LogDebug("TrackstersMergeProducerV3") << " sigmas: "; - for (auto const &s : t.sigmas()) { - LogDebug("TrackstersMergeProducerV3") << s << " "; - } - LogDebug("TrackstersMergeProducerV3") << std::endl; -} - -void TrackstersMergeProducerV3::produce(edm::Event &evt, const edm::EventSetup &es) { - edm::ESHandle geom = es.getHandle(geometry_token_); - rhtools_.setGeometry(*geom); - auto resultTrackstersMerged = std::make_unique>(); - auto resultCandidates = std::make_unique>(); - - tfSession_ = es.getData(tfDnnToken_).getSession(); - - TICLTracksterTiles tracksterTile; - std::vector usedTrackstersMerged; - std::vector indexInMergedCollTRKEM; - std::vector indexInMergedCollEM; - std::vector indexInMergedCollTRK; - std::vector indexInMergedCollHAD; - std::vector usedSeeds; - - // associating seed to the index of the trackster in the merged collection and the iteration that found it - std::map>> seedToTracksterAssociator; - - edm::Handle> track_h; - evt.getByToken(tracks_token_, track_h); - const auto &tracks = *track_h; - - const auto &layerClusters = evt.get(clusters_token_); - const auto &layerClustersTimes = evt.get(clustersTime_token_); - const auto &trackstersEM = evt.get(trackstersem_token_); - const auto &trackstersTRKEM = evt.get(tracksterstrkem_token_); - const auto &trackstersTRK = evt.get(tracksterstrk_token_); - const auto &trackstersHAD = evt.get(trackstershad_token_); - const auto &seedingTrk = evt.get(seedingTrk_token_); - - usedSeeds.resize(tracks.size(), false); - - fillTile(tracksterTile, trackstersTRKEM, TracksterIterIndex::TRKEM); - fillTile(tracksterTile, trackstersEM, TracksterIterIndex::EM); - fillTile(tracksterTile, trackstersTRK, TracksterIterIndex::TRKHAD); - fillTile(tracksterTile, trackstersHAD, TracksterIterIndex::HAD); - - auto totalNumberOfTracksters = - trackstersTRKEM.size() + trackstersTRK.size() + trackstersEM.size() + trackstersHAD.size(); - resultTrackstersMerged->reserve(totalNumberOfTracksters); - usedTrackstersMerged.resize(totalNumberOfTracksters, false); - indexInMergedCollTRKEM.reserve(trackstersTRKEM.size()); - indexInMergedCollEM.reserve(trackstersEM.size()); - indexInMergedCollTRK.reserve(trackstersTRK.size()); - indexInMergedCollHAD.reserve(trackstersHAD.size()); - - printTrackstersDebug(trackstersTRKEM, "tracksterTRKEM"); - printTrackstersDebug(trackstersEM, "tracksterEM"); - printTrackstersDebug(trackstersTRK, "tracksterTRK"); - printTrackstersDebug(trackstersHAD, "tracksterHAD"); - - for (auto const &t : trackstersTRKEM) { - indexInMergedCollTRKEM.push_back(resultTrackstersMerged->size()); - seedToTracksterAssociator[t.seedIndex()].emplace_back(resultTrackstersMerged->size(), TracksterIterIndex::TRKEM); - resultTrackstersMerged->push_back(t); - } - - for (auto const &t : trackstersEM) { - indexInMergedCollEM.push_back(resultTrackstersMerged->size()); - resultTrackstersMerged->push_back(t); - } - - for (auto const &t : trackstersTRK) { - indexInMergedCollTRK.push_back(resultTrackstersMerged->size()); - seedToTracksterAssociator[t.seedIndex()].emplace_back(resultTrackstersMerged->size(), TracksterIterIndex::TRKHAD); - resultTrackstersMerged->push_back(t); - } - - for (auto const &t : trackstersHAD) { - indexInMergedCollHAD.push_back(resultTrackstersMerged->size()); - resultTrackstersMerged->push_back(t); - } - - assignPCAtoTracksters(*resultTrackstersMerged, - layerClusters, - layerClustersTimes, - rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z()); - energyRegressionAndID(layerClusters, tfSession_, *resultTrackstersMerged); - - printTrackstersDebug(*resultTrackstersMerged, "TrackstersMergeProducerV3"); - - auto trackstersMergedHandle = evt.put(std::move(resultTrackstersMerged)); - - // TICL Candidate creation - // We start from neutrals first - - // Photons - for (unsigned i = 0; i < trackstersEM.size(); ++i) { - auto mergedIdx = indexInMergedCollEM[i]; - usedTrackstersMerged[mergedIdx] = true; - const auto &t = trackstersEM[i]; //trackster - TICLCandidate tmpCandidate; - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); - tmpCandidate.setCharge(0); - tmpCandidate.setPdgId(22); - tmpCandidate.setRawEnergy(t.raw_energy()); - math::XYZTLorentzVector p4(t.raw_energy() * t.barycenter().unit().x(), - t.raw_energy() * t.barycenter().unit().y(), - t.raw_energy() * t.barycenter().unit().z(), - t.raw_energy()); - tmpCandidate.setP4(p4); - resultCandidates->push_back(tmpCandidate); - } - - // Neutral Hadrons - constexpr double mpion = 0.13957; - constexpr float mpion2 = mpion * mpion; - for (unsigned i = 0; i < trackstersHAD.size(); ++i) { - auto mergedIdx = indexInMergedCollHAD[i]; - usedTrackstersMerged[mergedIdx] = true; - const auto &t = trackstersHAD[i]; //trackster - TICLCandidate tmpCandidate; - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); - tmpCandidate.setCharge(0); - tmpCandidate.setPdgId(130); - tmpCandidate.setRawEnergy(t.raw_energy()); - float momentum = std::sqrt(t.raw_energy() * t.raw_energy() - mpion2); - math::XYZTLorentzVector p4(momentum * t.barycenter().unit().x(), - momentum * t.barycenter().unit().y(), - momentum * t.barycenter().unit().z(), - t.raw_energy()); - tmpCandidate.setP4(p4); - resultCandidates->push_back(tmpCandidate); - } - - // Charged Particles - for (unsigned i = 0; i < trackstersTRKEM.size(); ++i) { - auto mergedIdx = indexInMergedCollTRKEM[i]; - if (!usedTrackstersMerged[mergedIdx]) { - const auto &t = trackstersTRKEM[i]; //trackster - auto trackIdx = t.seedIndex(); - auto const &track = tracks[trackIdx]; - if (!usedSeeds[trackIdx] and t.raw_energy() > 0) { - usedSeeds[trackIdx] = true; - usedTrackstersMerged[mergedIdx] = true; - - std::vector trackstersTRKwithSameSeed; - std::vector trackstersTRKEMwithSameSeed; - - for (const auto &tracksterIterationPair : seedToTracksterAssociator[trackIdx]) { - if (tracksterIterationPair.first != mergedIdx and !usedTrackstersMerged[tracksterIterationPair.first] and - trackstersMergedHandle->at(tracksterIterationPair.first).raw_energy() > 0.) { - if (tracksterIterationPair.second == TracksterIterIndex::TRKEM) { - trackstersTRKEMwithSameSeed.push_back(tracksterIterationPair.first); - } else if (tracksterIterationPair.second == TracksterIterIndex::TRKHAD) { - trackstersTRKwithSameSeed.push_back(tracksterIterationPair.first); - } - } - } - - float tracksterTotalRawPt = t.raw_pt(); - std::vector haloTrackstersTRKIdx; - bool foundCompatibleTRK = false; - - for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { - usedTrackstersMerged[otherTracksterIdx] = true; - tracksterTotalRawPt += trackstersMergedHandle->at(otherTracksterIdx).raw_pt(); - - // Check the X,Y,Z barycenter and merge if they are very close (halo) - if ((t.barycenter() - trackstersMergedHandle->at(otherTracksterIdx).barycenter()).mag2() < - halo_max_distance2_) { - haloTrackstersTRKIdx.push_back(otherTracksterIdx); - - } else { - foundCompatibleTRK = true; - } - } - - //check if there is 1-to-1 relationship - if (trackstersTRKEMwithSameSeed.empty()) { - if (foundCompatibleTRK) { - TICLCandidate tmpCandidate; - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); - double raw_energy = t.raw_energy(); - - tmpCandidate.setCharge(track.charge()); - tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); - tmpCandidate.setPdgId(211 * track.charge()); - for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, otherTracksterIdx)); - raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy(); - } - tmpCandidate.setRawEnergy(raw_energy); - math::XYZTLorentzVector p4(raw_energy * track.momentum().unit().x(), - raw_energy * track.momentum().unit().y(), - raw_energy * track.momentum().unit().z(), - raw_energy); - tmpCandidate.setP4(p4); - resultCandidates->push_back(tmpCandidate); - - } else { - TICLCandidate tmpCandidate; - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); - double raw_energy = t.raw_energy(); - tmpCandidate.setCharge(track.charge()); - tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); - for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, otherTracksterIdx)); - raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy(); - } - tmpCandidate.setPdgId(11 * track.charge()); - - tmpCandidate.setRawEnergy(raw_energy); - math::XYZTLorentzVector p4(raw_energy * track.momentum().unit().x(), - raw_energy * track.momentum().unit().y(), - raw_energy * track.momentum().unit().z(), - raw_energy); - tmpCandidate.setP4(p4); - resultCandidates->push_back(tmpCandidate); - } - - } else { - // if 1-to-many find closest trackster in momentum - int closestTrackster = mergedIdx; - float minPtDiff = std::abs(t.raw_pt() - track.pt()); - for (auto otherTracksterIdx : trackstersTRKEMwithSameSeed) { - auto thisPt = tracksterTotalRawPt + trackstersMergedHandle->at(otherTracksterIdx).raw_pt() - t.raw_pt(); - closestTrackster = std::abs(thisPt - track.pt()) < minPtDiff ? otherTracksterIdx : closestTrackster; - } - usedTrackstersMerged[closestTrackster] = true; - - if (foundCompatibleTRK) { - TICLCandidate tmpCandidate; - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, closestTrackster)); - double raw_energy = trackstersMergedHandle->at(closestTrackster).raw_energy(); - - tmpCandidate.setCharge(track.charge()); - tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); - tmpCandidate.setPdgId(211 * track.charge()); - for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, otherTracksterIdx)); - raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy(); - } - tmpCandidate.setRawEnergy(raw_energy); - float momentum = std::sqrt(raw_energy * raw_energy - mpion2); - math::XYZTLorentzVector p4(momentum * track.momentum().unit().x(), - momentum * track.momentum().unit().y(), - momentum * track.momentum().unit().z(), - raw_energy); - tmpCandidate.setP4(p4); - resultCandidates->push_back(tmpCandidate); - - } else { - TICLCandidate tmpCandidate; - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, closestTrackster)); - double raw_energy = trackstersMergedHandle->at(closestTrackster).raw_energy(); - - tmpCandidate.setCharge(track.charge()); - tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); - for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, otherTracksterIdx)); - raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy(); - } - tmpCandidate.setPdgId(11 * track.charge()); - tmpCandidate.setRawEnergy(raw_energy); - math::XYZTLorentzVector p4(raw_energy * track.momentum().unit().x(), - raw_energy * track.momentum().unit().y(), - raw_energy * track.momentum().unit().z(), - raw_energy); - tmpCandidate.setP4(p4); - resultCandidates->push_back(tmpCandidate); - } - // Promote all other TRKEM tracksters as photons with their energy. - for (auto otherTracksterIdx : trackstersTRKEMwithSameSeed) { - auto tmpIndex = (otherTracksterIdx != closestTrackster) ? otherTracksterIdx : mergedIdx; - TICLCandidate photonCandidate; - const auto &otherTrackster = trackstersMergedHandle->at(tmpIndex); - auto gammaEnergy = otherTrackster.raw_energy(); - photonCandidate.setCharge(0); - photonCandidate.setPdgId(22); - photonCandidate.setRawEnergy(gammaEnergy); - math::XYZTLorentzVector gammaP4(gammaEnergy * otherTrackster.barycenter().unit().x(), - gammaEnergy * otherTrackster.barycenter().unit().y(), - gammaEnergy * otherTrackster.barycenter().unit().z(), - gammaEnergy); - photonCandidate.setP4(gammaP4); - photonCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, tmpIndex)); - resultCandidates->push_back(photonCandidate); - } - } - } - } - } //end of loop over trackstersTRKEM - - for (unsigned i = 0; i < trackstersTRK.size(); ++i) { - auto mergedIdx = indexInMergedCollTRK[i]; - const auto &t = trackstersTRK[i]; //trackster - - if (!usedTrackstersMerged[mergedIdx] and t.raw_energy() > 0) { - auto trackIdx = t.seedIndex(); - auto const &track = tracks[trackIdx]; - if (!usedSeeds[trackIdx]) { - usedSeeds[trackIdx] = true; - usedTrackstersMerged[mergedIdx] = true; - TICLCandidate tmpCandidate; - tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); - tmpCandidate.setCharge(track.charge()); - tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); - tmpCandidate.setPdgId(211 * track.charge()); - tmpCandidate.setRawEnergy(t.raw_energy()); - float momentum = std::sqrt(t.raw_energy() * t.raw_energy() - mpion2); - math::XYZTLorentzVector p4(momentum * track.momentum().unit().x(), - momentum * track.momentum().unit().y(), - momentum * track.momentum().unit().z(), - t.raw_energy()); - tmpCandidate.setP4(p4); - resultCandidates->push_back(tmpCandidate); - } - } - } - // For all seeds that have 0-energy tracksters whose track is not marked as used, create a charged hadron with the track information. - for (auto const &s : seedingTrk) { - if (usedSeeds[s.index] == false) { - auto const &track = tracks[s.index]; - // emit a charged hadron - TICLCandidate tmpCandidate; - tmpCandidate.setCharge(track.charge()); - tmpCandidate.setTrackPtr(edm::Ptr(track_h, s.index)); - tmpCandidate.setPdgId(211 * track.charge()); - float energy = std::sqrt(track.p() * track.p() + mpion2); - tmpCandidate.setRawEnergy(energy); - math::PtEtaPhiMLorentzVector p4Polar(track.pt(), track.eta(), track.phi(), mpion); - tmpCandidate.setP4(p4Polar); - resultCandidates->push_back(tmpCandidate); - usedSeeds[s.index] = true; - } - } - - // for all general tracks (high purity, pt > 1), check if they have been used: if not, promote them as charged hadrons - for (unsigned i = 0; i < tracks.size(); ++i) { - auto const &track = tracks[i]; - if (track.pt() > track_min_pt_ and track.quality(reco::TrackBase::highPurity) and - track.missingOuterHits() < track_max_missing_outerhits_ and std::abs(track.outerEta()) > track_min_eta_ and - std::abs(track.outerEta()) < track_max_eta_ and usedSeeds[i] == false) { - // emit a charged hadron - TICLCandidate tmpCandidate; - tmpCandidate.setCharge(track.charge()); - tmpCandidate.setTrackPtr(edm::Ptr(track_h, i)); - tmpCandidate.setPdgId(211 * track.charge()); - float energy = std::sqrt(track.p() * track.p() + mpion2); - tmpCandidate.setRawEnergy(energy); - math::PtEtaPhiMLorentzVector p4Polar(track.pt(), track.eta(), track.phi(), mpion); - tmpCandidate.setP4(p4Polar); - resultCandidates->push_back(tmpCandidate); - usedSeeds[i] = true; - } - } - - // Compute timing - assignTimeToCandidates(*resultCandidates); - - evt.put(std::move(resultCandidates)); -} - -void TrackstersMergeProducerV3::energyRegressionAndID(const std::vector &layerClusters, - const tensorflow::Session *eidSession, - std::vector &tracksters) const { - // 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}}; - static constexpr int inputDimension = 4; - - 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(); - float *probs = outputs[probsIdx].flat().data(); - - for (const int &i : tracksterIndices) { - tracksters[i].setProbabilities(probs); - probs += tracksters[i].id_probabilities().size(); - } - } -} - -void TrackstersMergeProducerV3::assignTimeToCandidates(std::vector &resultCandidates) const { - for (auto &cand : resultCandidates) { - if (cand.tracksters().size() > 1) { // For single-trackster candidates the timing is already set - float time = 0.f; - float timeErr = 0.f; - for (const auto &tr : cand.tracksters()) { - if (tr->timeError() > 0) { - auto invTimeESq = pow(tr->timeError(), -2); - time += tr->time() * invTimeESq; - timeErr += invTimeESq; - } - } - if (timeErr > 0) { - timeErr = 1. / timeErr; - - cand.setTime(time * timeErr); - cand.setTimeError(sqrt(timeErr)); - } - } - } -} - -void TrackstersMergeProducerV3::printTrackstersDebug(const std::vector &tracksters, - const char *label) const { -#ifdef EDM_ML_DEBUG - int counter = 0; - for (auto const &t : tracksters) { - LogDebug("TrackstersMergeProducerV3") - << counter++ << " TrackstersMergeProducerV3 (" << label << ") obj barycenter: " << t.barycenter() - << " eta,phi (baricenter): " << t.barycenter().eta() << ", " << t.barycenter().phi() - << " eta,phi (eigen): " << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() - << " pt(eigen): " << std::sqrt(t.eigenvectors(0).Unit().perp2()) * t.raw_energy() << " seedID: " << t.seedID() - << " seedIndex: " << t.seedIndex() << " size: " << t.vertices().size() << " average usage: " - << (std::accumulate(std::begin(t.vertex_multiplicity()), std::end(t.vertex_multiplicity()), 0.) / - (float)t.vertex_multiplicity().size()) - << " raw_energy: " << t.raw_energy() << " regressed energy: " << t.regressed_energy() - << " probs(ga/e/mu/np/cp/nh/am/unk): "; - for (auto const &p : t.id_probabilities()) { - LogDebug("TrackstersMergeProducerV3") << std::fixed << p << " "; - } - LogDebug("TrackstersMergeProducerV3") << " sigmas: "; - for (auto const &s : t.sigmas()) { - LogDebug("TrackstersMergeProducerV3") << s << " "; - } - LogDebug("TrackstersMergeProducerV3") << std::endl; - } -#endif -} - -void TrackstersMergeProducerV3::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { - edm::ParameterSetDescription desc; - desc.add("tracksterstrkem", edm::InputTag("ticlTrackstersTrkEM")); - desc.add("trackstersem", edm::InputTag("ticlTrackstersEM")); - desc.add("tracksterstrk", edm::InputTag("ticlTrackstersTrk")); - desc.add("trackstershad", edm::InputTag("ticlTrackstersHAD")); - desc.add("seedingTrk", edm::InputTag("ticlSeedingTrk")); - desc.add("layer_clusters", edm::InputTag("hgcalMergeLayerClusters")); - desc.add("layer_clustersTime", edm::InputTag("hgcalMergeLayerClusters", "timeLayerCluster")); - desc.add("tracks", edm::InputTag("generalTracks")); - desc.add("optimiseAcrossTracksters", true); - desc.add("eta_bin_window", 1); - desc.add("phi_bin_window", 1); - desc.add("pt_sigma_high", 2.); - desc.add("pt_sigma_low", 2.); - desc.add("halo_max_distance2", 4.); - desc.add("track_min_pt", 1.); - desc.add("track_min_eta", 1.48); - desc.add("track_max_eta", 3.); - desc.add("track_max_missing_outerhits", 5); - desc.add("cosangle_align", 0.9945); - desc.add("e_over_h_threshold", 1.); - desc.add("pt_neutral_threshold", 2.); - desc.add("resol_calo_offset_had", 1.5); - desc.add("resol_calo_scale_had", 0.15); - desc.add("resol_calo_offset_em", 1.5); - desc.add("resol_calo_scale_em", 0.15); - desc.add("tfDnnLabel", "tracksterSelectionTf"); - desc.add("eid_input_name", "input"); - desc.add("eid_output_name_energy", "output/regressed_energy"); - desc.add("eid_output_name_id", "output/id_probabilities"); - desc.add("eid_min_cluster_energy", 1.); - desc.add("eid_n_layers", 50); - desc.add("eid_n_clusters", 10); - descriptions.add("trackstersMergeProducerV3", desc); -} - -#include "FWCore/Framework/interface/MakerMacros.h" -DEFINE_FWK_MODULE(TrackstersMergeProducerV3); diff --git a/RecoHGCal/TICL/plugins/TrackstersPCA.cc b/RecoHGCal/TICL/plugins/TrackstersPCA.cc index 65d9ed0a92254..5aa224b1f98bf 100644 --- a/RecoHGCal/TICL/plugins/TrackstersPCA.cc +++ b/RecoHGCal/TICL/plugins/TrackstersPCA.cc @@ -13,6 +13,7 @@ void ticl::assignPCAtoTracksters(std::vector &tracksters, const std::vector &layerClusters, const edm::ValueMap> &layerClustersTime, double z_limit_em, + bool computeLocalTime, bool energyWeight) { LogDebug("TrackstersPCA_Eigen") << "------- Eigen -------" << std::endl; @@ -35,17 +36,10 @@ void ticl::assignPCAtoTracksters(std::vector &tracksters, trackster.setRawEmPt(0.f); size_t N = trackster.vertices().size(); + if (N == 0) + continue; float weight = 1.f / N; float weights2_sum = 0.f; - Eigen::Vector3d sigmas; - sigmas << 0., 0., 0.; - Eigen::Vector3d sigmasEigen; - sigmasEigen << 0., 0., 0.; - Eigen::Matrix3d covM = Eigen::Matrix3d::Zero(); - - std::vector times; - std::vector timeErrors; - std::set usedLC; for (size_t i = 0; i < N; ++i) { auto fraction = 1.f / trackster.vertex_multiplicity(i); @@ -59,70 +53,19 @@ void ticl::assignPCAtoTracksters(std::vector &tracksters, fillPoint(layerClusters[trackster.vertices(i)], weight); for (size_t j = 0; j < 3; ++j) barycenter[j] += point[j]; - - // Add timing from layerClusters not already used - if ((usedLC.insert(trackster.vertices(i))).second) { - float timeE = layerClustersTime.get(trackster.vertices(i)).second; - if (timeE > 0.f) { - times.push_back(layerClustersTime.get(trackster.vertices(i)).first); - timeErrors.push_back(1. / pow(timeE, 2)); - } - } - } - if (energyWeight && trackster.raw_energy()) - barycenter /= trackster.raw_energy(); - - hgcalsimclustertime::ComputeClusterTime timeEstimator; - std::pair timeTrackster = timeEstimator.fixSizeHighestDensity(times, timeErrors); - - // Compute the Covariance Matrix and the sum of the squared weights, used - // to compute the correct normalization. - // The barycenter has to be known. - for (size_t i = 0; i < N; ++i) { - fillPoint(layerClusters[trackster.vertices(i)]); - if (energyWeight && trackster.raw_energy()) - weight = - (layerClusters[trackster.vertices(i)].energy() / trackster.vertex_multiplicity(i)) / trackster.raw_energy(); - weights2_sum += weight * weight; - for (size_t x = 0; x < 3; ++x) - for (size_t y = 0; y <= x; ++y) { - covM(x, y) += weight * (point[x] - barycenter[x]) * (point[y] - barycenter[y]); - covM(y, x) = covM(x, y); - } - } - covM *= 1. / (1. - weights2_sum); - - // Perform the actual decomposition - Eigen::SelfAdjointEigenSolver::RealVectorType eigenvalues_fromEigen; - Eigen::SelfAdjointEigenSolver::EigenvectorsType eigenvectors_fromEigen; - Eigen::SelfAdjointEigenSolver eigensolver(covM); - if (eigensolver.info() != Eigen::Success) { - eigenvalues_fromEigen = eigenvalues_fromEigen.Zero(); - eigenvectors_fromEigen = eigenvectors_fromEigen.Zero(); - } else { - eigenvalues_fromEigen = eigensolver.eigenvalues(); - eigenvectors_fromEigen = eigensolver.eigenvectors(); - } - - // Compute the spread in the both spaces. - for (size_t i = 0; i < N; ++i) { - fillPoint(layerClusters[trackster.vertices(i)]); - sigmas += weight * (point - barycenter).cwiseAbs2(); - Eigen::Vector3d point_transformed = eigenvectors_fromEigen * (point - barycenter); - if (energyWeight && trackster.raw_energy()) - weight = - (layerClusters[trackster.vertices(i)].energy() / trackster.vertex_multiplicity(i)) / trackster.raw_energy(); - sigmasEigen += weight * (point_transformed.cwiseAbs2()); } - sigmas /= (1. - weights2_sum); - sigmasEigen /= (1. - weights2_sum); - - // Add trackster attributes + float raw_energy = trackster.raw_energy(); + float inv_raw_energy = 1.f / raw_energy; + if (energyWeight) + barycenter *= inv_raw_energy; trackster.setBarycenter(ticl::Trackster::Vector(barycenter)); - trackster.setTimeAndError(timeTrackster.first, timeTrackster.second); - trackster.fillPCAVariables( - eigenvalues_fromEigen, eigenvectors_fromEigen, sigmas, sigmasEigen, 3, ticl::Trackster::PCAOrdering::ascending); + std::pair timeTrackster; + if (computeLocalTime) + timeTrackster = ticl::computeLocalTracksterTime(trackster, layerClusters, layerClustersTime, barycenter, N); + else + timeTrackster = ticl::computeTracksterTime(trackster, layerClustersTime, N); + trackster.setTimeAndError(timeTrackster.first, timeTrackster.second); LogDebug("TrackstersPCA") << "Use energy weighting: " << energyWeight << std::endl; LogDebug("TrackstersPCA") << "\nTrackster characteristics: " << std::endl; LogDebug("TrackstersPCA") << "Size: " << N << std::endl; @@ -131,21 +74,165 @@ void ticl::assignPCAtoTracksters(std::vector &tracksters, LogDebug("TrackstersPCA") << "Means: " << barycenter[0] << ", " << barycenter[1] << ", " << barycenter[2] << std::endl; LogDebug("TrackstersPCA") << "Time: " << trackster.time() << " +/- " << trackster.timeError() << std::endl; - LogDebug("TrackstersPCA") << "EigenValues from Eigen/Tr(cov): " << eigenvalues_fromEigen[2] / covM.trace() << ", " - << eigenvalues_fromEigen[1] / covM.trace() << ", " - << eigenvalues_fromEigen[0] / covM.trace() << std::endl; - LogDebug("TrackstersPCA") << "EigenValues from Eigen: " << eigenvalues_fromEigen[2] << ", " - << eigenvalues_fromEigen[1] << ", " << eigenvalues_fromEigen[0] << std::endl; - LogDebug("TrackstersPCA") << "EigenVector 3 from Eigen: " << eigenvectors_fromEigen(0, 2) << ", " - << eigenvectors_fromEigen(1, 2) << ", " << eigenvectors_fromEigen(2, 2) << std::endl; - LogDebug("TrackstersPCA") << "EigenVector 2 from Eigen: " << eigenvectors_fromEigen(0, 1) << ", " - << eigenvectors_fromEigen(1, 1) << ", " << eigenvectors_fromEigen(2, 1) << std::endl; - LogDebug("TrackstersPCA") << "EigenVector 1 from Eigen: " << eigenvectors_fromEigen(0, 0) << ", " - << eigenvectors_fromEigen(1, 0) << ", " << eigenvectors_fromEigen(2, 0) << std::endl; - LogDebug("TrackstersPCA") << "Original sigmas: " << sigmas[0] << ", " << sigmas[1] << ", " << sigmas[2] - << std::endl; - LogDebug("TrackstersPCA") << "SigmasEigen in PCA space: " << sigmasEigen[2] << ", " << sigmasEigen[1] << ", " - << sigmasEigen[0] << std::endl; - LogDebug("TrackstersPCA") << "covM: \n" << covM << std::endl; + + if (N > 2) { + Eigen::Vector3d sigmas; + sigmas << 0., 0., 0.; + Eigen::Vector3d sigmasEigen; + sigmasEigen << 0., 0., 0.; + Eigen::Matrix3d covM = Eigen::Matrix3d::Zero(); + // Compute the Covariance Matrix and the sum of the squared weights, used + // to compute the correct normalization. + // The barycenter has to be known. + for (size_t i = 0; i < N; ++i) { + fillPoint(layerClusters[trackster.vertices(i)]); + if (energyWeight && trackster.raw_energy()) + weight = (layerClusters[trackster.vertices(i)].energy() / trackster.vertex_multiplicity(i)) * inv_raw_energy; + weights2_sum += weight * weight; + for (size_t x = 0; x < 3; ++x) + for (size_t y = 0; y <= x; ++y) { + covM(x, y) += weight * (point[x] - barycenter[x]) * (point[y] - barycenter[y]); + covM(y, x) = covM(x, y); + } + } + covM *= 1.f / (1.f - weights2_sum); + + // Perform the actual decomposition + Eigen::SelfAdjointEigenSolver::RealVectorType eigenvalues_fromEigen; + Eigen::SelfAdjointEigenSolver::EigenvectorsType eigenvectors_fromEigen; + Eigen::SelfAdjointEigenSolver eigensolver(covM); + if (eigensolver.info() != Eigen::Success) { + eigenvalues_fromEigen = eigenvalues_fromEigen.Zero(); + eigenvectors_fromEigen = eigenvectors_fromEigen.Zero(); + } else { + eigenvalues_fromEigen = eigensolver.eigenvalues(); + eigenvectors_fromEigen = eigensolver.eigenvectors(); + } + + // Compute the spread in the both spaces. + for (size_t i = 0; i < N; ++i) { + fillPoint(layerClusters[trackster.vertices(i)]); + sigmas += weight * (point - barycenter).cwiseAbs2(); + Eigen::Vector3d point_transformed = eigenvectors_fromEigen * (point - barycenter); + if (energyWeight && raw_energy) + weight = (layerClusters[trackster.vertices(i)].energy() / trackster.vertex_multiplicity(i)) * inv_raw_energy; + sigmasEigen += weight * (point_transformed.cwiseAbs2()); + } + sigmas /= (1.f - weights2_sum); + sigmasEigen /= (1.f - weights2_sum); + + trackster.fillPCAVariables(eigenvalues_fromEigen, + eigenvectors_fromEigen, + sigmas, + sigmasEigen, + 3, + ticl::Trackster::PCAOrdering::ascending); + + LogDebug("TrackstersPCA") << "EigenValues from Eigen/Tr(cov): " << eigenvalues_fromEigen[2] / covM.trace() << ", " + << eigenvalues_fromEigen[1] / covM.trace() << ", " + << eigenvalues_fromEigen[0] / covM.trace() << std::endl; + LogDebug("TrackstersPCA") << "EigenValues from Eigen: " << eigenvalues_fromEigen[2] << ", " + << eigenvalues_fromEigen[1] << ", " << eigenvalues_fromEigen[0] << std::endl; + LogDebug("TrackstersPCA") << "EigenVector 3 from Eigen: " << eigenvectors_fromEigen(0, 2) << ", " + << eigenvectors_fromEigen(1, 2) << ", " << eigenvectors_fromEigen(2, 2) << std::endl; + LogDebug("TrackstersPCA") << "EigenVector 2 from Eigen: " << eigenvectors_fromEigen(0, 1) << ", " + << eigenvectors_fromEigen(1, 1) << ", " << eigenvectors_fromEigen(2, 1) << std::endl; + LogDebug("TrackstersPCA") << "EigenVector 1 from Eigen: " << eigenvectors_fromEigen(0, 0) << ", " + << eigenvectors_fromEigen(1, 0) << ", " << eigenvectors_fromEigen(2, 0) << std::endl; + LogDebug("TrackstersPCA") << "Original sigmas: " << sigmas[0] << ", " << sigmas[1] << ", " << sigmas[2] + << std::endl; + LogDebug("TrackstersPCA") << "SigmasEigen in PCA space: " << sigmasEigen[2] << ", " << sigmasEigen[1] << ", " + << sigmasEigen[0] << std::endl; + LogDebug("TrackstersPCA") << "covM: \n" << covM << std::endl; + } } } + +std::pair ticl::computeLocalTracksterTime(const Trackster &trackster, + const std::vector &layerClusters, + const edm::ValueMap> &layerClustersTime, + const Eigen::Vector3d &barycenter, + size_t N) { + float tracksterTime = 0.; + float tracksterTimeErr = 0.; + std::set usedLC; + + auto project_lc_to_pca = [](const std::vector &point, const std::vector &segment_end) { + double dot_product = 0.0; + double segment_dot = 0.0; + + for (int i = 0; i < 3; ++i) { + dot_product += point[i] * segment_end[i]; + segment_dot += segment_end[i] * segment_end[i]; + } + + double projection = 0.0; + if (segment_dot != 0.0) { + projection = dot_product / segment_dot; + } + + std::vector closest_point(3); + for (int i = 0; i < 3; ++i) { + closest_point[i] = projection * segment_end[i]; + } + + double distance = 0.0; + for (int i = 0; i < 3; ++i) { + distance += std::pow(point[i] - closest_point[i], 2); + } + + return std::sqrt(distance); + }; + + constexpr double c = 29.9792458; // cm/ns + for (size_t i = 0; i < N; ++i) { + // Add timing from layerClusters not already used + if ((usedLC.insert(trackster.vertices(i))).second) { + float timeE = layerClustersTime.get(trackster.vertices(i)).second; + if (timeE > 0.f) { + float time = layerClustersTime.get(trackster.vertices(i)).first; + timeE = 1.f / pow(timeE, 2); + float x = layerClusters[trackster.vertices(i)].x(); + float y = layerClusters[trackster.vertices(i)].y(); + float z = layerClusters[trackster.vertices(i)].z(); + + if (project_lc_to_pca({x, y, z}, {barycenter[0], barycenter[1], barycenter[2]}) < 3) { // set MR to 3 + float deltaT = 1.f / c * + std::sqrt(((barycenter[2] / z - 1.f) * x) * ((barycenter[2] / z - 1.f) * x) + + ((barycenter[2] / z - 1.f) * y) * ((barycenter[2] / z - 1.f) * y) + + (barycenter[2] - z) * (barycenter[2] - z)); + time = std::abs(barycenter[2]) < std::abs(z) ? time - deltaT : time + deltaT; + + tracksterTime += time * timeE; + tracksterTimeErr += timeE; + } + } + } + } + if (tracksterTimeErr > 0.f) + return {tracksterTime / tracksterTimeErr, 1.f / std::sqrt(tracksterTimeErr)}; + else + return {-99.f, -1.f}; +} + +std::pair ticl::computeTracksterTime(const Trackster &trackster, + const edm::ValueMap> &layerClustersTime, + size_t N) { + std::vector times; + std::vector timeErrors; + std::set usedLC; + + for (size_t i = 0; i < N; ++i) { + // Add timing from layerClusters not already used + if ((usedLC.insert(trackster.vertices(i))).second) { + float timeE = layerClustersTime.get(trackster.vertices(i)).second; + if (timeE > 0.f) { + times.push_back(layerClustersTime.get(trackster.vertices(i)).first); + timeErrors.push_back(1.f / pow(timeE, 2)); + } + } + } + + hgcalsimclustertime::ComputeClusterTime timeEstimator; + return timeEstimator.fixSizeHighestDensity(times, timeErrors); +} diff --git a/RecoHGCal/TICL/plugins/TrackstersPCA.h b/RecoHGCal/TICL/plugins/TrackstersPCA.h index ed172f8a27931..2b6de0bb409e9 100644 --- a/RecoHGCal/TICL/plugins/TrackstersPCA.h +++ b/RecoHGCal/TICL/plugins/TrackstersPCA.h @@ -10,6 +10,15 @@ namespace ticl { const std::vector &, const edm::ValueMap> &, double, + bool computeLocalTime = false, bool energyWeight = true); -} + std::pair computeLocalTracksterTime(const Trackster &trackster, + const std::vector &layerClusters, + const edm::ValueMap> &layerClustersTime, + const Eigen::Vector3d &barycenter, + size_t N); + std::pair computeTracksterTime(const Trackster &trackster, + const edm::ValueMap> &layerClustersTime, + size_t N); +} // namespace ticl #endif diff --git a/RecoHGCal/TICL/plugins/TrackstersProducer.cc b/RecoHGCal/TICL/plugins/TrackstersProducer.cc index 54a66c0d4ceff..d3fbb3a91e67e 100644 --- a/RecoHGCal/TICL/plugins/TrackstersProducer.cc +++ b/RecoHGCal/TICL/plugins/TrackstersProducer.cc @@ -22,8 +22,6 @@ #include "DataFormats/HGCalReco/interface/TICLSeedingRegion.h" #include "RecoHGCal/TICL/plugins/PatternRecognitionPluginFactory.h" -#include "PatternRecognitionbyCA.h" -#include "PatternRecognitionbyMultiClusters.h" #include "PhysicsTools/TensorFlow/interface/TfGraphRecord.h" #include "PhysicsTools/TensorFlow/interface/TensorFlow.h" @@ -136,6 +134,11 @@ void TrackstersProducer::fillDescriptions(edm::ConfigurationDescriptions& descri pluginDescFastJet.addNode(edm::PluginDescription("type", "FastJet", true)); desc.add("pluginPatternRecognitionByFastJet", pluginDescFastJet); + // PassThrough Plugin + edm::ParameterSetDescription pluginDescPassThrough; + pluginDescPassThrough.addNode(edm::PluginDescription("type", "Passthrough", true)); + desc.add("pluginPatternRecognitionByPassthrough", pluginDescPassThrough); + descriptions.add("trackstersProducer", desc); } diff --git a/RecoHGCal/TICL/python/CLUE3DEM_cff.py b/RecoHGCal/TICL/python/CLUE3DEM_cff.py new file mode 100644 index 0000000000000..eca99580f8290 --- /dev/null +++ b/RecoHGCal/TICL/python/CLUE3DEM_cff.py @@ -0,0 +1,39 @@ +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 + +# CLUSTER FILTERING/MASKING + +filteredLayerClustersCLUE3DEM = _filteredLayerClustersProducer.clone( + clusterFilter = "ClusterFilterByAlgoAndSizeAndLayerRange", + min_cluster_size = 2, # inclusive + iteration_label = "CLUE3DEM", + algo_number = [6,7], + max_layerId = 28, # inclusive +) + +# PATTERN RECOGNITION + +ticlTrackstersCLUE3DEM = _trackstersProducer.clone( + filtered_mask = "filteredLayerClustersCLUE3DEM:CLUE3DEM", + seeding_regions = "ticlSeedingGlobal", + itername = "EM", + patternRecognitionBy = "CLUE3D", + pluginPatternRecognitionByCLUE3D = dict ( + criticalDensity = [0.6, 0.6, 0.6], + criticalEtaPhiDistance = [0.025, 0.025, 0.025], + kernelDensityFactor = [0.2, 0.2, 0.2], + algo_verbosity = 0 + ) + +) + +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlTrackstersCLUE3DEM.pluginPatternRecognitionByCLUE3D, computeLocalTime = cms.bool(True)) + +ticlCLUE3DEMStepTask = cms.Task(ticlSeedingGlobal + ,filteredLayerClustersCLUE3DEM + ,ticlTrackstersCLUE3DEM) + diff --git a/RecoHGCal/TICL/python/CLUE3DHAD_cff.py b/RecoHGCal/TICL/python/CLUE3DHAD_cff.py new file mode 100644 index 0000000000000..d510887a1533e --- /dev/null +++ b/RecoHGCal/TICL/python/CLUE3DHAD_cff.py @@ -0,0 +1,39 @@ +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 + +# CLUSTER FILTERING/MASKING + +filteredLayerClustersCLUE3DHAD = _filteredLayerClustersProducer.clone( + clusterFilter = "ClusterFilterBySize", + min_cluster_size = 2, # inclusive + iteration_label = "CLUE3DHAD", + LayerClustersInputMask = 'ticlTrackstersCLUE3DEM', +) + +# PATTERN RECOGNITION + +ticlTrackstersCLUE3DHAD = _trackstersProducer.clone( + filtered_mask = "filteredLayerClustersCLUE3DHAD:CLUE3DHAD", + original_mask = 'ticlTrackstersCLUE3DEM', + seeding_regions = "ticlSeedingGlobal", + itername = "HAD", + patternRecognitionBy = "CLUE3D", + pluginPatternRecognitionByCLUE3D = dict ( + criticalDensity = [0.6, 0.6, 0.6], + criticalEtaPhiDistance = [0.025, 0.025, 0.025], + kernelDensityFactor = [0.2, 0.2, 0.2], + algo_verbosity = 0 + ) + +) + +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlTrackstersCLUE3DHAD.pluginPatternRecognitionByCLUE3D, computeLocalTime = cms.bool(True)) + +ticlCLUE3DHADStepTask = cms.Task(ticlSeedingGlobal + ,filteredLayerClustersCLUE3DHAD + ,ticlTrackstersCLUE3DHAD) + diff --git a/RecoHGCal/TICL/python/CLUE3DHighStep_cff.py b/RecoHGCal/TICL/python/CLUE3DHighStep_cff.py index 34fcd2e654f3a..10ecfa20458bb 100644 --- a/RecoHGCal/TICL/python/CLUE3DHighStep_cff.py +++ b/RecoHGCal/TICL/python/CLUE3DHighStep_cff.py @@ -3,7 +3,6 @@ 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 @@ -21,14 +20,20 @@ itername = "CLUE3DHigh", patternRecognitionBy = "CLUE3D", pluginPatternRecognitionByCLUE3D = dict ( - criticalDensity = 0.6, - criticalEtaPhiDistance = 0.025, - kernelDensityFactor = 0.2, - algo_verbosity = 0 + criticalDensity = [0.6, 0.6, 0.6], + criticalEtaPhiDistance = [0.025, 0.025, 0.025], + kernelDensityFactor = [0.2, 0.2, 0.2], + algo_verbosity = 0, + doPidCut = True, + cutHadProb = 999 ) ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlTrackstersCLUE3DHigh.pluginPatternRecognitionByCLUE3D, computeLocalTime = cms.bool(True)) +ticl_v5.toModify(ticlTrackstersCLUE3DHigh.pluginPatternRecognitionByCLUE3D, doPidCut = cms.bool(False)) + ticlCLUE3DHighStepTask = cms.Task(ticlSeedingGlobal ,filteredLayerClustersCLUE3DHigh ,ticlTrackstersCLUE3DHigh) diff --git a/RecoHGCal/TICL/python/CLUE3DLowStep_cff.py b/RecoHGCal/TICL/python/CLUE3DLowStep_cff.py deleted file mode 100644 index fba3b76a06c23..0000000000000 --- a/RecoHGCal/TICL/python/CLUE3DLowStep_cff.py +++ /dev/null @@ -1,33 +0,0 @@ -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 - -filteredLayerClustersCLUE3DLow = _filteredLayerClustersProducer.clone( - clusterFilter = "ClusterFilterByAlgoAndSize", - min_cluster_size = 2, # inclusive - LayerClustersInputMask = 'ticlTrackstersCLUE3DHigh', - iteration_label = "CLUE3DLow" -) - -# PATTERN RECOGNITION - -ticlTrackstersCLUE3DLow = _trackstersProducer.clone( - filtered_mask = "filteredLayerClustersCLUE3DLow:CLUE3DLow", - seeding_regions = "ticlSeedingGlobal", - itername = "CLUE3DLow", - patternRecognitionBy = "CLUE3D", - pluginPatternRecognitionByCLUE3D = dict ( - criticalDensity = 2., - criticalEtaPhiDistance = 0.025 - ) -) - -ticlCLUE3DLowStepTask = cms.Task(ticlSeedingGlobal - ,filteredLayerClustersCLUE3DLow - ,ticlTrackstersCLUE3DLow) - diff --git a/RecoHGCal/TICL/python/EMStep_cff.py b/RecoHGCal/TICL/python/EMStep_cff.py index c5653e96fb73f..c8cf97fcab3c9 100644 --- a/RecoHGCal/TICL/python/EMStep_cff.py +++ b/RecoHGCal/TICL/python/EMStep_cff.py @@ -37,6 +37,8 @@ ), itername = "EM" ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlTrackstersEM.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) ticlEMStepTask = cms.Task(ticlSeedingGlobal ,filteredLayerClustersEM @@ -71,6 +73,7 @@ shower_start_max_layer = 4 ### inclusive ) ) +ticl_v5.toModify(ticlTrackstersHFNoseEM.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) ticlHFNoseEMStepTask = cms.Task(ticlSeedingGlobalHFNose ,filteredLayerClustersHFNoseEM diff --git a/RecoHGCal/TICL/python/FastJetStep_cff.py b/RecoHGCal/TICL/python/FastJetStep_cff.py index a8bf71ff10cb5..c13488b9e66d4 100644 --- a/RecoHGCal/TICL/python/FastJetStep_cff.py +++ b/RecoHGCal/TICL/python/FastJetStep_cff.py @@ -3,7 +3,6 @@ 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 @@ -25,6 +24,10 @@ ) ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlTrackstersFastJet.pluginPatternRecognitionByFastJet, computeLocalTime = cms.bool(True)) + + ticlFastJetStepTask = cms.Task(ticlSeedingGlobal ,filteredLayerClustersFastJet ,ticlTrackstersFastJet) diff --git a/RecoHGCal/TICL/python/HADStep_cff.py b/RecoHGCal/TICL/python/HADStep_cff.py index d7c3b7334135a..8c4012e7127cd 100644 --- a/RecoHGCal/TICL/python/HADStep_cff.py +++ b/RecoHGCal/TICL/python/HADStep_cff.py @@ -33,6 +33,9 @@ itername = "HAD" ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlTrackstersHAD.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) + ticlHADStepTask = cms.Task(ticlSeedingGlobal ,filteredLayerClustersHAD ,ticlTrackstersHAD) @@ -68,6 +71,8 @@ itername = "HADn" ) +ticl_v5.toModify(ticlTrackstersHFNoseHAD.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) + ticlHFNoseHADStepTask = cms.Task(ticlSeedingGlobalHFNose ,filteredLayerClustersHFNoseHAD ,ticlTrackstersHFNoseHAD) diff --git a/RecoHGCal/TICL/python/MIPStep_cff.py b/RecoHGCal/TICL/python/MIPStep_cff.py index 1b5a295b2b4a9..b6057ed7bfbf4 100644 --- a/RecoHGCal/TICL/python/MIPStep_cff.py +++ b/RecoHGCal/TICL/python/MIPStep_cff.py @@ -29,6 +29,9 @@ itername = "MIP" ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlTrackstersMIP.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) + ticlMIPStepTask = cms.Task(ticlSeedingGlobal ,filteredLayerClustersMIP ,ticlTrackstersMIP) @@ -51,6 +54,8 @@ pluginPatternRecognitionByCA = dict(min_layers_per_trackster = 6) ) +ticl_v5.toModify(ticlTrackstersHFNoseMIP.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) + ticlHFNoseMIPStepTask = cms.Task(ticlSeedingGlobalHFNose ,filteredLayerClustersHFNoseMIP ,ticlTrackstersHFNoseMIP diff --git a/RecoHGCal/TICL/python/PRbyPassthrough_cff.py b/RecoHGCal/TICL/python/PRbyPassthrough_cff.py new file mode 100644 index 0000000000000..b42533ee7ed1e --- /dev/null +++ b/RecoHGCal/TICL/python/PRbyPassthrough_cff.py @@ -0,0 +1,33 @@ +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 + +# CLUSTER FILTERING/MASKING + +filteredLayerClustersPassthrough = _filteredLayerClustersProducer.clone( + clusterFilter = "ClusterFilterBySize", + min_cluster_size = 2, # inclusive + iteration_label = "Passthrough", + LayerClustersInputMask = 'ticlTrackstersCLUE3DHigh', +) + +# PATTERN RECOGNITION + +ticlTrackstersPassthrough = _trackstersProducer.clone( + filtered_mask = "filteredLayerClustersPassthrough:Passthrough", + original_mask = 'ticlTrackstersCLUE3DHigh', + seeding_regions = "ticlSeedingGlobal", + itername = "PassThrough", + patternRecognitionBy = "Passthrough", + pluginPatternRecognitionByPassthrough = dict ( + algo_verbosity = 0 + ) +) + +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 + +ticlPassthroughStepTask = cms.Task(ticlSeedingGlobal + ,filteredLayerClustersPassthrough + ,ticlTrackstersPassthrough) diff --git a/RecoHGCal/TICL/python/SimTracksters_cff.py b/RecoHGCal/TICL/python/SimTracksters_cff.py index 4fbe78ca74e0a..1a545bd243874 100644 --- a/RecoHGCal/TICL/python/SimTracksters_cff.py +++ b/RecoHGCal/TICL/python/SimTracksters_cff.py @@ -14,7 +14,10 @@ ) ticlSimTracksters = _simTrackstersProducer.clone( + computeLocalTime = cms.bool(False) ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlSimTracksters, computeLocalTime = cms.bool(True)) from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 premix_stage2.toModify(ticlSimTracksters, diff --git a/RecoHGCal/TICL/python/TrkEMStep_cff.py b/RecoHGCal/TICL/python/TrkEMStep_cff.py index f28364ebf44cb..e642fcc143c26 100644 --- a/RecoHGCal/TICL/python/TrkEMStep_cff.py +++ b/RecoHGCal/TICL/python/TrkEMStep_cff.py @@ -37,6 +37,9 @@ itername = "TrkEM", ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlTrackstersTrkEM.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) + ticlTrkEMStepTask = cms.Task(ticlSeedingTrk ,filteredLayerClustersTrkEM ,ticlTrackstersTrkEM) @@ -70,6 +73,8 @@ ) ) +ticl_v5.toModify(ticlTrackstersHFNoseTrkEM.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) + ticlHFNoseTrkEMStepTask = cms.Task(ticlSeedingTrkHFNose ,filteredLayerClustersHFNoseTrkEM ,ticlTrackstersHFNoseTrkEM) diff --git a/RecoHGCal/TICL/python/TrkStep_cff.py b/RecoHGCal/TICL/python/TrkStep_cff.py index 40e5513904889..82a26349ff835 100644 --- a/RecoHGCal/TICL/python/TrkStep_cff.py +++ b/RecoHGCal/TICL/python/TrkStep_cff.py @@ -35,10 +35,13 @@ itername = "Trk" ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(ticlTrackstersTrk.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) + ticlTrkStepTask = cms.Task(ticlSeedingTrk ,filteredLayerClustersTrk ,ticlTrackstersTrk) - + # HFNOSE CLUSTER FILTERING/MASKING filteredLayerClustersHFNoseTrk = filteredLayerClustersTrk.clone( @@ -70,6 +73,8 @@ itername = "Trkn" ) +ticl_v5.toModify(ticlTrackstersHFNoseTrk.pluginPatternRecognitionByCA, computeLocalTime = cms.bool(True)) + ticlHFNoseTrkStepTask = cms.Task(ticlSeedingTrkHFNose ,filteredLayerClustersHFNoseTrk ,ticlTrackstersHFNoseTrk) diff --git a/RecoHGCal/TICL/python/customiseForTICLv5_cff.py b/RecoHGCal/TICL/python/customiseForTICLv5_cff.py new file mode 100644 index 0000000000000..d548d5d434b5b --- /dev/null +++ b/RecoHGCal/TICL/python/customiseForTICLv5_cff.py @@ -0,0 +1,178 @@ +import FWCore.ParameterSet.Config as cms + +from RecoLocalCalo.HGCalRecProducers.hgcalLayerClusters_cff import hgcalLayerClustersEE, hgcalLayerClustersHSi, hgcalLayerClustersHSci +from RecoLocalCalo.HGCalRecProducers.hgcalMergeLayerClusters_cfi import hgcalMergeLayerClusters +from RecoTracker.IterativeTracking.iterativeTk_cff import trackdnn_source +from RecoLocalCalo.HGCalRecProducers.hgcalRecHitMapProducer_cfi import hgcalRecHitMapProducer + +from RecoHGCal.TICL.ticlLayerTileProducer_cfi import ticlLayerTileProducer + +from RecoHGCal.TICL.CLUE3DEM_cff import * +from RecoHGCal.TICL.CLUE3DHAD_cff import * +from RecoHGCal.TICL.pfTICLProducer_cfi import pfTICLProducer as _pfTICLProducer + +from RecoHGCal.TICL.ticlLayerTileProducer_cfi import ticlLayerTileProducer +from RecoHGCal.TICL.tracksterSelectionTf_cfi import * + +from RecoHGCal.TICL.tracksterLinksProducer_cfi import tracksterLinksProducer as _tracksterLinksProducer +from RecoHGCal.TICL.ticlCandidateProducer_cfi import ticlCandidateProducer as _ticlCandidateProducer +from RecoHGCal.Configuration.RecoHGCal_EventContent_cff import customiseForTICLv5EventContent +from RecoHGCal.TICL.iterativeTICL_cff import ticlIterLabels, ticlIterLabelsMerge +from RecoHGCal.TICL.ticlDumper_cfi import ticlDumper +from RecoHGCal.TICL.mergedTrackstersProducer_cfi import mergedTrackstersProducer as _mergedTrackstersProducer +from SimCalorimetry.HGCalAssociatorProducers.TSToSimTSAssociation_cfi import tracksterSimTracksterAssociationLinkingbyCLUE3D as _tracksterSimTracksterAssociationLinkingbyCLUE3D +from SimCalorimetry.HGCalAssociatorProducers.TSToSimTSAssociation_cfi import tracksterSimTracksterAssociationPRbyCLUE3D as _tracksterSimTracksterAssociationPRbyCLUE3D +from Validation.HGCalValidation.HGCalValidator_cff import hgcalValidator +from RecoLocalCalo.HGCalRecProducers.HGCalUncalibRecHit_cfi import HGCalUncalibRecHit +from RecoHGCal.TICL.SimTracksters_cff import ticlSimTracksters, ticlSimTrackstersTask + +from RecoHGCal.TICL.FastJetStep_cff import ticlTrackstersFastJet +from RecoHGCal.TICL.EMStep_cff import ticlTrackstersEM, ticlTrackstersHFNoseEM +from RecoHGCal.TICL.TrkStep_cff import ticlTrackstersTrk, ticlTrackstersHFNoseTrk +from RecoHGCal.TICL.MIPStep_cff import ticlTrackstersMIP, ticlTrackstersHFNoseMIP +from RecoHGCal.TICL.HADStep_cff import ticlTrackstersHAD, ticlTrackstersHFNoseHAD +from RecoHGCal.TICL.CLUE3DEM_cff import ticlTrackstersCLUE3DEM +from RecoHGCal.TICL.CLUE3DHAD_cff import ticlTrackstersCLUE3DHAD +from RecoHGCal.TICL.CLUE3DHighStep_cff import ticlTrackstersCLUE3DHigh +from RecoHGCal.TICL.TrkEMStep_cff import ticlTrackstersTrkEM, filteredLayerClustersHFNoseTrkEM + +from RecoHGCal.TICL.mtdSoAProducer_cfi import mtdSoAProducer as _mtdSoAProducer + +def customiseTICLv5FromReco(process, enableDumper = False): + # TensorFlow ESSource + + process.TFESSource = cms.Task(process.trackdnn_source) + + process.hgcalLayerClustersTask = cms.Task(process.hgcalLayerClustersEE, + process.hgcalLayerClustersHSi, + process.hgcalLayerClustersHSci, + process.hgcalMergeLayerClusters) + + # Reconstruction + + process.ticlSimTracksters.computeLocalTime = cms.bool(True) + + process.ticlTrackstersCLUE3DHigh.pluginPatternRecognitionByCLUE3D.computeLocalTime = cms.bool(True) + + '''for future CLUE3D separate iterations + process.ticlTrackstersCLUE3DHAD.pluginPatternRecognitionByCLUE3D.computeLocalTime = cms.bool(True) + process.ticlTrackstersCLUE3DEM.pluginPatternRecognitionByCLUE3D.computeLocalTime = cms.bool(True) + ''' + + process.ticlLayerTileTask = cms.Task(ticlLayerTileProducer) + + process.ticlIterationsTask = cms.Task( + process.ticlTrackstersCLUE3DHigh, + ) + + process.mtdSoA = _mtdSoAProducer.clone() + process.mtdSoATask = cms.Task(process.mtdSoA) + + process.ticlTracksterLinks = _tracksterLinksProducer.clone() + process.ticlTracksterLinks = _tracksterLinksProducer.clone( + tracksters_collections = cms.VInputTag( + 'ticlTrackstersCLUE3DHigh' + ), + ) + + process.ticlCandidate = _ticlCandidateProducer.clone() + process.ticlCandidateTask = cms.Task(process.ticlCandidate) + + process.tracksterSimTracksterAssociationLinkingbyCLUE3DHigh = _tracksterSimTracksterAssociationLinkingbyCLUE3D.clone( + label_tst = cms.InputTag("ticlTrackstersCLUE3DHigh") + ) + process.tracksterSimTracksterAssociationPRbyCLUE3DHigh = _tracksterSimTracksterAssociationPRbyCLUE3D.clone( + label_tst = cms.InputTag("ticlTrackstersCLUE3DHigh") + ) + + '''for future CLUE3D separate iterations, merge collections and compute scores + process.tracksterSimTracksterAssociationLinkingbyCLUE3DEM = _tracksterSimTracksterAssociationLinkingbyCLUE3D.clone( + label_tst = cms.InputTag("ticlTrackstersCLUE3DEM") + ) + process.tracksterSimTracksterAssociationPRbyCLUE3DEM = _tracksterSimTracksterAssociationPRbyCLUE3D.clone( + label_tst = cms.InputTag("ticlTrackstersCLUE3DEM") + ) + process.tracksterSimTracksterAssociationLinkingbyCLUE3DHAD = _tracksterSimTracksterAssociationLinkingbyCLUE3D.clone( + label_tst = cms.InputTag("ticlTrackstersCLUE3DHAD") + ) + process.tracksterSimTracksterAssociationPRbyCLUE3DHAD = _tracksterSimTracksterAssociationPRbyCLUE3D.clone( + label_tst = cms.InputTag("ticlTrackstersCLUE3DHAD") + ) + + process.mergedTrackstersProducer = _mergedTrackstersProducer.clone() + process.tracksterSimTracksterAssociationLinkingbyCLUE3D = _tracksterSimTracksterAssociationLinkingbyCLUE3D.clone( + label_tst = cms.InputTag("mergedTrackstersProducer") + ) + process.tracksterSimTracksterAssociationPRbyCLUE3D = _tracksterSimTracksterAssociationPRbyCLUE3D.clone( + label_tst = cms.InputTag("mergedTrackstersProducer") + ) + ''' + + + process.iterTICLTask = cms.Path(process.hgcalLayerClustersTask, + process.TFESSource, + process.ticlLayerTileTask, + process.mtdSoATask, + process.ticlIterationsTask, + process.ticlTracksterLinksTask, + process.ticlCandidateTask) + + process.particleFlowClusterHGCal.initialClusteringStep.tracksterSrc = "ticlCandidate" + process.globalrecoTask.remove(process.ticlTrackstersMerge) + + process.tracksterSimTracksterAssociationLinking.label_tst = cms.InputTag("ticlCandidate") + process.tracksterSimTracksterAssociationPR.label_tst = cms.InputTag("ticlCandidate") + + process.tracksterSimTracksterAssociationLinkingPU.label_tst = cms.InputTag("ticlCandidate") + process.tracksterSimTracksterAssociationPRPU.label_tst = cms.InputTag("ticlCandidate") + process.mergeTICLTask = cms.Task() + process.pfTICL = _pfTICLProducer.clone( + ticlCandidateSrc = cms.InputTag('ticlCandidate'), + isTICLv5 = cms.bool(True) + ) + process.hgcalAssociators = cms.Task(process.hgcalRecHitMapProducer, process.lcAssocByEnergyScoreProducer, process.layerClusterCaloParticleAssociationProducer, + process.scAssocByEnergyScoreProducer, process.layerClusterSimClusterAssociationProducer, + process.lcSimTSAssocByEnergyScoreProducer, process.layerClusterSimTracksterAssociationProducer, + process.simTsAssocByEnergyScoreProducer, process.simTracksterHitLCAssociatorByEnergyScoreProducer, + process.tracksterSimTracksterAssociationLinking, process.tracksterSimTracksterAssociationPR, + process.tracksterSimTracksterAssociationLinkingbyCLUE3DHigh, process.tracksterSimTracksterAssociationPRbyCLUE3DHigh, + process.tracksterSimTracksterAssociationLinkingPU, process.tracksterSimTracksterAssociationPRPU + ) + + '''for future CLUE3D separate iterations, merge collections and compute scores + process.tracksterSimTracksterAssociationLinkingbyCLUE3D, process.tracksterSimTracksterAssociationPRbyCLUE3D, + process.tracksterSimTracksterAssociationLinkingbyCLUE3DEM, process.tracksterSimTracksterAssociationPRbyCLUE3DEM, + process.tracksterSimTracksterAssociationLinkingbyCLUE3DHAD, process.tracksterSimTracksterAssociationPRbyCLUE3DHAD, + ''' + + if(enableDumper): + process.ticlDumper = ticlDumper.clone( + saveLCs=True, + saveCLUE3DTracksters=True, + saveTrackstersMerged=True, + saveSimTrackstersSC=True, + saveSimTrackstersCP=True, + saveTICLCandidate=True, + saveSimTICLCandidate=True, + saveTracks=True, + saveAssociations=True, + trackstersclue3d = cms.InputTag('ticlTrackstersCLUE3DHigh'), + ticlcandidates = cms.InputTag("ticlCandidate"), + trackstersmerged = cms.InputTag("ticlCandidate"), + trackstersInCand = cms.InputTag("ticlCandidate") + ) + process.TFileService = cms.Service("TFileService", + fileName=cms.string("histo.root") + ) + + process.FEVTDEBUGHLToutput_step = cms.EndPath(process.ticlDumper) + + process.TICL_Validation = cms.Path(process.ticlSimTrackstersTask, process.hgcalAssociators) + +# Schedule definition + process.schedule = cms.Schedule(process.iterTICLTask, + process.TICL_Validation, + process.FEVTDEBUGHLToutput_step) + process = customiseForTICLv5EventContent(process) + + return process diff --git a/RecoHGCal/TICL/python/customiseTICLFromReco.py b/RecoHGCal/TICL/python/customiseTICLFromReco.py index 0b447844c09ec..91d932d2914cf 100644 --- a/RecoHGCal/TICL/python/customiseTICLFromReco.py +++ b/RecoHGCal/TICL/python/customiseTICLFromReco.py @@ -79,6 +79,15 @@ def customiseTICLForDumper(process): saveTracks=True, saveAssociations=True, ) + + from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 + ticl_v5.toModify(process.ticlDumper, + # trackstersclue3d = cms.InputTag('mergedTrackstersProducer'), # For future separate iterations + trackstersclue3d = cms.InputTag('ticlTrackstersCLUE3DHigh'), + ticlcandidates = cms.InputTag("ticlCandidate"), + trackstersmerged = cms.InputTag("ticlCandidate"), + trackstersInCand = cms.InputTag("ticlCandidate")) + process.TFileService = cms.Service("TFileService", fileName=cms.string("histo.root") ) diff --git a/RecoHGCal/TICL/python/iterativeTICL_cff.py b/RecoHGCal/TICL/python/iterativeTICL_cff.py index 69c9989ca8955..ae13a46fc961f 100644 --- a/RecoHGCal/TICL/python/iterativeTICL_cff.py +++ b/RecoHGCal/TICL/python/iterativeTICL_cff.py @@ -2,62 +2,85 @@ from RecoHGCal.TICL.FastJetStep_cff import * from RecoHGCal.TICL.CLUE3DHighStep_cff import * -from RecoHGCal.TICL.CLUE3DLowStep_cff import * from RecoHGCal.TICL.MIPStep_cff import * from RecoHGCal.TICL.TrkEMStep_cff import * from RecoHGCal.TICL.TrkStep_cff import * from RecoHGCal.TICL.EMStep_cff import * from RecoHGCal.TICL.HADStep_cff import * +from RecoHGCal.TICL.CLUE3DEM_cff import * +from RecoHGCal.TICL.CLUE3DHAD_cff import * +from RecoHGCal.TICL.PRbyPassthrough_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 -from RecoHGCal.TICL.trackstersMergeProducerV3_cfi import trackstersMergeProducerV3 as _trackstersMergeProducerV3 from RecoHGCal.TICL.tracksterSelectionTf_cfi import * +from RecoHGCal.TICL.tracksterLinksProducer_cfi import tracksterLinksProducer as _tracksterLinksProducer +from RecoHGCal.TICL.ticlCandidateProducer_cfi import ticlCandidateProducer as _ticlCandidateProducer + +from RecoHGCal.TICL.mtdSoAProducer_cfi import mtdSoAProducer as _mtdSoAProducer + +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 + ticlLayerTileTask = cms.Task(ticlLayerTileProducer) ticlTrackstersMerge = _trackstersMergeProducer.clone() -ticlTrackstersMergeV3 = _trackstersMergeProducerV3.clone() +ticlTracksterLinks = _tracksterLinksProducer.clone( + tracksters_collections = cms.VInputTag( + 'ticlTrackstersCLUE3DHigh', + 'ticlTrackstersPassthrough' + ), + regressionAndPid = cms.bool(True) +) +ticlCandidate = _ticlCandidateProducer.clone() +mtdSoA = _mtdSoAProducer.clone() pfTICL = _pfTICLProducer.clone() +ticl_v5.toModify(pfTICL, ticlCandidateSrc = cms.InputTag('ticlCandidate'), isTICLv5 = cms.bool(True)) + ticlPFTask = cms.Task(pfTICL) ticlIterationsTask = cms.Task( - ticlCLUE3DHighStepTask + ticlCLUE3DHighStepTask, + ticlPassthroughStepTask + ) +''' For future separate iterations +,ticlCLUE3DEMStepTask, +,ticlCLUE3DHADStepTask + ''' -from Configuration.ProcessModifiers.clue3D_cff import clue3D -clue3D.toModify(ticlIterationsTask, func=lambda x : x.add(ticlCLUE3DHighStepTask,ticlCLUE3DLowStepTask)) +''' For future separate iterations +ticl_v5.toReplaceWith(ticlIterationsTask, ticlIterationsTask.copyAndExclude([ticlCLUE3DHighStepTask])) +''' from Configuration.ProcessModifiers.fastJetTICL_cff import fastJetTICL fastJetTICL.toModify(ticlIterationsTask, func=lambda x : x.add(ticlFastJetStepTask)) -from Configuration.ProcessModifiers.ticl_v3_cff import ticl_v3 -ticl_v3.toModify(ticlIterationsTask, func=lambda x : x.add( ticlTrkEMStepTask - ,ticlEMStepTask - ,ticlTrkStepTask - ,ticlHADStepTask) ) -ticlIterLabels = [_step.itername.value() for _iteration in ticlIterationsTask for _step in _iteration if (_step._TypedParameterizable__type == "TrackstersProducer")] +ticlIterLabels = ["CLUE3DHigh"] +''' For future separate iterations +"CLUE3DEM", "CLUE3DHAD", +''' ticlTracksterMergeTask = cms.Task(ticlTrackstersMerge) -ticlTracksterMergeTaskV3 = cms.Task(ticlTrackstersMergeV3) - -ticl_v3.toModify(pfTICL, ticlCandidateSrc = "ticlTrackstersMergeV3") +ticlTracksterLinksTask = cms.Task(ticlTracksterLinks) mergeTICLTask = cms.Task(ticlLayerTileTask ,ticlIterationsTask ,ticlTracksterMergeTask ) +ticl_v5.toReplaceWith(mergeTICLTask, mergeTICLTask.copyAndExclude([ticlTracksterMergeTask])) +ticl_v5.toModify(mergeTICLTask, func=lambda x : x.add(ticlTracksterLinksTask)) -ticl_v3.toModify(mergeTICLTask, func=lambda x : x.add(ticlTracksterMergeTaskV3)) ticlIterLabelsMerge = ticlIterLabels + ["Merge"] -ticlIterLabelsMergeV3 = ticlIterLabels + ["MergeV3"] -ticl_v3.toModify(ticlIterLabelsMerge, func=lambda x : x.extend(ticlIterLabelsMergeV3)) +mtdSoATask = cms.Task(mtdSoA) +ticlCandidateTask = cms.Task(ticlCandidate) -iterTICLTask = cms.Task(mergeTICLTask - ,ticlPFTask) +iterTICLTask = cms.Task(mergeTICLTask, + ticlPFTask) +ticl_v5.toModify(iterTICLTask, func=lambda x : x.add(mtdSoATask, ticlCandidateTask)) ticlLayerTileHFNose = ticlLayerTileProducer.clone( detector = 'HFNose' diff --git a/RecoLocalCalo/HGCalRecAlgos/interface/HGCalUncalibRecHitRecWeightsAlgo.h b/RecoLocalCalo/HGCalRecAlgos/interface/HGCalUncalibRecHitRecWeightsAlgo.h index ef9460644eb0d..6bff0e40d6a70 100644 --- a/RecoLocalCalo/HGCalRecAlgos/interface/HGCalUncalibRecHitRecWeightsAlgo.h +++ b/RecoLocalCalo/HGCalRecAlgos/interface/HGCalUncalibRecHitRecWeightsAlgo.h @@ -52,7 +52,7 @@ class HGCalUncalibRecHitRecWeightsAlgo { } /// Compute HGCUncalibratedRecHit from DataFrame - virtual HGCUncalibratedRecHit makeRecHit(const C& dataFrame) { + virtual HGCUncalibratedRecHit makeRecHit(const C& dataFrame, const bool computeLocalTime) { double amplitude_(-1.), pedestal_(-1.), jitter_(-99.), chi2_(-1.); uint32_t flag = 0; @@ -84,7 +84,8 @@ class HGCalUncalibRecHitRecWeightsAlgo { if (sample.getToAValid()) { const auto& dist2center = geom_ ? geom_->getPosition(dataFrame.id()).mag() : 0; - jitter_ = double(sample.toa()) * toaLSBToNS_ - dist2center / c_cm_ns - tofDelay_; + jitter_ = computeLocalTime ? double(sample.toa()) * toaLSBToNS_ - tofDelay_ + : double(sample.toa()) * toaLSBToNS_ - dist2center / c_cm_ns - tofDelay_; } int thickness = (ddd_ != nullptr) ? ddd_->waferType(dataFrame.id(), false) : 0; diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalUncalibRecHitWorkerBaseClass.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalUncalibRecHitWorkerBaseClass.h index ba695de9e76a9..a1d19a74f6151 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalUncalibRecHitWorkerBaseClass.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/HGCalUncalibRecHitWorkerBaseClass.h @@ -16,7 +16,7 @@ namespace edm { // change in the future. class HGCalUncalibRecHitWorkerBaseClass { public: - HGCalUncalibRecHitWorkerBaseClass(const edm::ParameterSet& ps, edm::ConsumesCollector iC) {} + HGCalUncalibRecHitWorkerBaseClass(const edm::ParameterSet& ps, edm::ConsumesCollector iC, bool localTime) {} virtual ~HGCalUncalibRecHitWorkerBaseClass() {} // run HGC-EE things @@ -38,6 +38,8 @@ class HGCalUncalibRecHitWorkerBaseClass { virtual bool runHGCHFNose(const edm::ESHandle& geom, const HGCalDigiCollection& digis, HGChfnoseUncalibratedRecHitCollection& result) = 0; + + bool computeLocalTime_ = false; }; #endif diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalUncalibRecHitWorkerFactory.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalUncalibRecHitWorkerFactory.h index da212b45757c5..5f3ed6f781e3b 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalUncalibRecHitWorkerFactory.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/HGCalUncalibRecHitWorkerFactory.h @@ -3,7 +3,8 @@ #include "FWCore/PluginManager/interface/PluginFactory.h" #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalUncalibRecHitWorkerBaseClass.h" -typedef edmplugin::PluginFactory +typedef edmplugin::PluginFactory HGCalUncalibRecHitWorkerFactory; #endif diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc index 742e388ac1589..50b88336718df 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc @@ -281,12 +281,14 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& } void HGCalLayerClusterProducer::setAlgoId() { - if (detector_ == "HFNose") { - algoId_ = reco::CaloCluster::hfnose; - } else if (detector_ == "EE") { + if (detector_ == "EE") { algoId_ = reco::CaloCluster::hgcal_em; - } else { //for FH or BH + } else if (detector_ == "FH") { algoId_ = reco::CaloCluster::hgcal_had; + } else if (detector_ == "BH") { + algoId_ = reco::CaloCluster::hgcal_scintillator; + } else if (detector_ == "HFNose") { + algoId_ = reco::CaloCluster::hfnose; } } diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitProducer.cc index 4de1603e8eca4..304634cb3d2c3 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitProducer.cc @@ -23,7 +23,7 @@ HGCalUncalibRecHitProducer::HGCalUncalibRecHitProducer(const edm::ParameterSet& hebHitCollection_(ps.getParameter("HGCHEBhitCollection")), hfnoseHitCollection_(ps.getParameter("HGCHFNosehitCollection")), worker_{HGCalUncalibRecHitWorkerFactory::get()->create( - ps.getParameter("algo"), ps, consumesCollector())} { + ps.getParameter("algo"), ps, consumesCollector(), ps.getParameter("computeLocalTime"))} { produces(eeHitCollection_); produces(hefHitCollection_); produces(hebHitCollection_); @@ -69,6 +69,86 @@ void HGCalUncalibRecHitProducer::produce(edm::Event& evt, const edm::EventSetup& evt.put(std::move(hfnoseUncalibRechits), hfnoseHitCollection_); } +void HGCalUncalibRecHitProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // HGCalUncalibRecHit + edm::ParameterSetDescription desc; + desc.add("HGCEEdigiCollection", edm::InputTag("hgcalDigis", "EE")); + desc.add("HGCEEhitCollection", "HGCEEUncalibRecHits"); + desc.add("HGCHEFdigiCollection", edm::InputTag("hgcalDigis", "HEfront")); + desc.add("HGCHEFhitCollection", "HGCHEFUncalibRecHits"); + desc.add("HGCHEBdigiCollection", edm::InputTag("hgcalDigis", "HEback")); + desc.add("HGCHEBhitCollection", "HGCHEBUncalibRecHits"); + desc.add("HGCHFNosedigiCollection", edm::InputTag("hfnoseDigis", "HFNose")); + desc.add("HGCHFNosehitCollection", "HGCHFNoseUncalibRecHits"); + edm::ParameterSetDescription HGCEEConfigPSet; + HGCEEConfigPSet.add("isSiFE", true); + HGCEEConfigPSet.add("adcNbits", 10); + HGCEEConfigPSet.add("adcSaturation", 100); + HGCEEConfigPSet.add("tdcNbits", 12); + HGCEEConfigPSet.add("tdcSaturation", 10000); + HGCEEConfigPSet.add("tdcOnset", 60); + HGCEEConfigPSet.add("toaLSB_ns", 0.0244); + HGCEEConfigPSet.add("tofDelay", -9); + HGCEEConfigPSet.add>("fCPerMIP", + { + 1.25, + 2.57, + 3.88, + }); + desc.add("HGCEEConfig", HGCEEConfigPSet); + edm::ParameterSetDescription HGCHEFConfigPSet; + HGCHEFConfigPSet.add("isSiFE", true); + HGCHEFConfigPSet.add("adcNbits", 10); + HGCHEFConfigPSet.add("adcSaturation", 100); + HGCHEFConfigPSet.add("tdcNbits", 12); + HGCHEFConfigPSet.add("tdcSaturation", 10000); + HGCHEFConfigPSet.add("tdcOnset", 60); + HGCHEFConfigPSet.add("toaLSB_ns", 0.0244); + HGCHEFConfigPSet.add("tofDelay", -11); + HGCHEFConfigPSet.add>("fCPerMIP", + { + 1.25, + 2.57, + 3.88, + }); + desc.add("HGCHEFConfig", HGCHEFConfigPSet); + edm::ParameterSetDescription HGCHEBConfigPSet; + HGCHEBConfigPSet.add("isSiFE", true); + HGCHEBConfigPSet.add("adcNbits", 10); + HGCHEBConfigPSet.add("adcSaturation", 68.75); + HGCHEBConfigPSet.add("tdcNbits", 12); + HGCHEBConfigPSet.add("tdcSaturation", 1000); + HGCHEBConfigPSet.add("tdcOnset", 55); + HGCHEBConfigPSet.add("toaLSB_ns", 0.0244); + HGCHEBConfigPSet.add("tofDelay", -14); + HGCHEBConfigPSet.add>("fCPerMIP", + { + 1.0, + 1.0, + 1.0, + }); + desc.add("HGCHEBConfig", HGCHEBConfigPSet); + edm::ParameterSetDescription HGCHFNoseConfigPSet; + HGCHFNoseConfigPSet.add("isSiFE", false); + HGCHFNoseConfigPSet.add("adcNbits", 10); + HGCHFNoseConfigPSet.add("adcSaturation", 100); + HGCHFNoseConfigPSet.add("tdcNbits", 12); + HGCHFNoseConfigPSet.add("tdcSaturation", 10000); + HGCHFNoseConfigPSet.add("tdcOnset", 60); + HGCHFNoseConfigPSet.add("toaLSB_ns", 0.0244); + HGCHFNoseConfigPSet.add("tofDelay", -33); + HGCHFNoseConfigPSet.add>("fCPerMIP", + { + 1.25, + 2.57, + 3.88, + }); + desc.add("HGCHFNoseConfig", HGCHFNoseConfigPSet); + desc.add("algo", "HGCalUncalibRecHitWorkerWeights"); + desc.add("computeLocalTime", false); + descriptions.add("HGCalUncalibRecHitProducer", desc); +} + #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(HGCalUncalibRecHitProducer); diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitProducer.h b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitProducer.h index 132a7dac48e0d..39991d1af95bc 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitProducer.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitProducer.h @@ -5,6 +5,8 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "DataFormats/HGCDigi/interface/HGCDataFrame.h" @@ -15,6 +17,7 @@ class HGCalUncalibRecHitProducer : public edm::stream::EDProducer<> { explicit HGCalUncalibRecHitProducer(const edm::ParameterSet& ps); ~HGCalUncalibRecHitProducer() override; void produce(edm::Event& evt, const edm::EventSetup& es) override; + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); private: const edm::EDGetTokenT eeDigiCollection_; // collection of HGCEE digis diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitWorkerWeights.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitWorkerWeights.cc index ea635c3b738c0..954d48ffdfa20 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitWorkerWeights.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitWorkerWeights.cc @@ -59,8 +59,10 @@ void configureIt(const edm::ParameterSet& conf, HGCalUncalibRecHitRecWeightsAlgo maker.set_tofDelay(conf.getParameter("tofDelay")); } -HGCalUncalibRecHitWorkerWeights::HGCalUncalibRecHitWorkerWeights(const edm::ParameterSet& ps, edm::ConsumesCollector iC) - : HGCalUncalibRecHitWorkerBaseClass(ps, iC) { +HGCalUncalibRecHitWorkerWeights::HGCalUncalibRecHitWorkerWeights(const edm::ParameterSet& ps, + edm::ConsumesCollector iC, + bool useTime) + : HGCalUncalibRecHitWorkerBaseClass(ps, iC, useTime) { const edm::ParameterSet& ee_cfg = ps.getParameterSet("HGCEEConfig"); const edm::ParameterSet& hef_cfg = ps.getParameterSet("HGCHEFConfig"); const edm::ParameterSet& heb_cfg = ps.getParameterSet("HGCHEBConfig"); @@ -69,6 +71,7 @@ HGCalUncalibRecHitWorkerWeights::HGCalUncalibRecHitWorkerWeights(const edm::Para configureIt(hef_cfg, uncalibMaker_hef_); configureIt(heb_cfg, uncalibMaker_heb_); configureIt(hfnose_cfg, uncalibMaker_hfnose_); + computeLocalTime_ = useTime; } bool HGCalUncalibRecHitWorkerWeights::run(const edm::ESHandle& geom, @@ -78,7 +81,7 @@ bool HGCalUncalibRecHitWorkerWeights::run(const edm::ESHandle& ge uncalibMaker.setGeometry(geom); result.reserve(result.size() + digis.size()); for (const auto& digi : digis) - result.push_back(uncalibMaker.makeRecHit(digi)); + result.push_back(uncalibMaker.makeRecHit(digi, computeLocalTime_)); return true; } diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitWorkerWeights.h b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitWorkerWeights.h index 9375dba97f09f..4473c4e49f0a3 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitWorkerWeights.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalUncalibRecHitWorkerWeights.h @@ -24,7 +24,7 @@ namespace edm { class HGCalUncalibRecHitWorkerWeights : public HGCalUncalibRecHitWorkerBaseClass { public: - HGCalUncalibRecHitWorkerWeights(const edm::ParameterSet&, edm::ConsumesCollector iC); + HGCalUncalibRecHitWorkerWeights(const edm::ParameterSet&, edm::ConsumesCollector iC, bool useTime); ~HGCalUncalibRecHitWorkerWeights() override{}; bool runHGCEE(const edm::ESHandle& geom, diff --git a/RecoLocalCalo/HGCalRecProducers/python/HGCalUncalibRecHit_cfi.py b/RecoLocalCalo/HGCalRecProducers/python/HGCalUncalibRecHit_cfi.py index c5546d21b420a..91ead51c5c2e1 100644 --- a/RecoLocalCalo/HGCalRecProducers/python/HGCalUncalibRecHit_cfi.py +++ b/RecoLocalCalo/HGCalRecProducers/python/HGCalUncalibRecHit_cfi.py @@ -1,22 +1,14 @@ import FWCore.ParameterSet.Config as cms +from RecoLocalCalo.HGCalRecProducers.HGCalUncalibRecHitProducer_cfi import HGCalUncalibRecHitProducer from SimCalorimetry.HGCalSimProducers.hgcalDigitizer_cfi import hgceeDigitizer, hgchefrontDigitizer, hgchebackDigitizer, hfnoseDigitizer fCPerMIP_mpv = cms.vdouble(1.25,2.57,3.88) #120um, 200um, 300um fCPerMIP_mean = cms.vdouble(2.06,3.43,5.15) #120um, 200um, 300um # HGCAL producer of rechits starting from digis -HGCalUncalibRecHit = cms.EDProducer( - "HGCalUncalibRecHitProducer", - HGCEEdigiCollection = cms.InputTag('hgcalDigis:EE'), - HGCEEhitCollection = cms.string('HGCEEUncalibRecHits'), - HGCHEFdigiCollection = cms.InputTag('hgcalDigis:HEfront'), - HGCHEFhitCollection = cms.string('HGCHEFUncalibRecHits'), - HGCHEBdigiCollection = cms.InputTag('hgcalDigis:HEback'), - HGCHEBhitCollection = cms.string('HGCHEBUncalibRecHits'), - HGCHFNosedigiCollection = cms.InputTag('hfnoseDigis:HFNose'), - HGCHFNosehitCollection = cms.string('HGCHFNoseUncalibRecHits'), - +HGCalUncalibRecHit = HGCalUncalibRecHitProducer.clone( + HGCEEConfig = cms.PSet( isSiFE = cms.bool(True), # adc information @@ -30,7 +22,7 @@ tofDelay = hgceeDigitizer.tofDelay, fCPerMIP = fCPerMIP_mpv ), - + HGCHEFConfig = cms.PSet( isSiFE = cms.bool(True), # adc information @@ -71,17 +63,15 @@ toaLSB_ns = hfnoseDigitizer.digiCfg.feCfg.toaLSB_ns, tofDelay = hfnoseDigitizer.tofDelay, fCPerMIP = fCPerMIP_mpv - ), - - algo = cms.string("HGCalUncalibRecHitWorkerWeights") + ) ) from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 -phase2_hgcalV10.toModify( HGCalUncalibRecHit.HGCEEConfig , fCPerMIP = fCPerMIP_mean ) +phase2_hgcalV10.toModify( HGCalUncalibRecHit.HGCEEConfig , fCPerMIP = fCPerMIP_mean ) phase2_hgcalV10.toModify( HGCalUncalibRecHit.HGCHEFConfig , fCPerMIP = fCPerMIP_mean ) from Configuration.Eras.Modifier_phase2_hgcalV16_cff import phase2_hgcalV16 -phase2_hgcalV16.toModify( HGCalUncalibRecHit.HGCEEConfig , fCPerMIP = fCPerMIP_mean ) +phase2_hgcalV16.toModify( HGCalUncalibRecHit.HGCEEConfig , fCPerMIP = fCPerMIP_mean ) phase2_hgcalV16.toModify( HGCalUncalibRecHit.HGCHEFConfig , fCPerMIP = fCPerMIP_mean ) from Configuration.Eras.Modifier_phase2_hfnose_cff import phase2_hfnose @@ -89,3 +79,6 @@ isSiFE = True , fCPerMIP = fCPerMIP_mean ) + +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(HGCalUncalibRecHit, computeLocalTime = cms.bool(True)) diff --git a/RecoMTD/Configuration/python/RecoMTD_EventContent_cff.py b/RecoMTD/Configuration/python/RecoMTD_EventContent_cff.py index 8f1e2dc5cbdb3..67c5bd241e35c 100644 --- a/RecoMTD/Configuration/python/RecoMTD_EventContent_cff.py +++ b/RecoMTD/Configuration/python/RecoMTD_EventContent_cff.py @@ -3,8 +3,7 @@ #AOD RecoMTDAOD = cms.PSet( outputCommands = cms.untracked.vstring( - 'keep intedmValueMap_trackExtenderWithMTD_*_*', - 'keep floatedmValueMap_trackExtenderWithMTD_*_*', + 'keep *edmValueMap_trackExtenderWithMTD_*_*', 'keep *_mtdTrackQualityMVA_*_*') ) diff --git a/RecoMTD/TrackExtender/plugins/TrackExtenderWithMTD.cc b/RecoMTD/TrackExtender/plugins/TrackExtenderWithMTD.cc index 1123d54c1ed97..697b7efe6dd5e 100644 --- a/RecoMTD/TrackExtender/plugins/TrackExtenderWithMTD.cc +++ b/RecoMTD/TrackExtender/plugins/TrackExtenderWithMTD.cc @@ -23,6 +23,7 @@ #include "DataFormats/ForwardDetId/interface/ETLDetId.h" #include "DataFormats/ForwardDetId/interface/MTDChannelIdentifier.h" #include "Geometry/CommonTopologies/interface/PixelTopology.h" +#include "DataFormats/GeometryVector/interface/GlobalPoint.h" #include "TrackingTools/PatternTools/interface/Trajectory.h" #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h" @@ -549,6 +550,7 @@ class TrackExtenderWithMTDT : public edm::stream::EDProducer<> { float& pathLength, float& tmtdOut, float& sigmatmtdOut, + GlobalPoint& tmtdPosOut, float& tofpi, float& tofk, float& tofp, @@ -573,6 +575,7 @@ class TrackExtenderWithMTDT : public edm::stream::EDProducer<> { edm::EDPutToken pathLengthOrigTrkToken_; edm::EDPutToken tmtdOrigTrkToken_; edm::EDPutToken sigmatmtdOrigTrkToken_; + edm::EDPutToken tmtdPosOrigTrkToken_; edm::EDPutToken tofpiOrigTrkToken_; edm::EDPutToken tofkOrigTrkToken_; edm::EDPutToken tofpOrigTrkToken_; @@ -664,6 +667,7 @@ TrackExtenderWithMTDT::TrackExtenderWithMTDT(const ParameterSet pathLengthOrigTrkToken_ = produces>("generalTrackPathLength"); tmtdOrigTrkToken_ = produces>("generalTracktmtd"); sigmatmtdOrigTrkToken_ = produces>("generalTracksigmatmtd"); + tmtdPosOrigTrkToken_ = produces>("generalTrackmtdpos"); tofpiOrigTrkToken_ = produces>("generalTrackTofPi"); tofkOrigTrkToken_ = produces>("generalTrackTofK"); tofpOrigTrkToken_ = produces>("generalTrackTofP"); @@ -745,7 +749,6 @@ void TrackExtenderWithMTDT::produce(edm::Event& ev, const edm:: Traj2TrackHits t2t; theTransformer->setServices(es); - TrackingRecHitRefProd hitsRefProd = ev.getRefBeforePut(); reco::TrackExtraRefProd extrasRefProd = ev.getRefBeforePut(); @@ -781,6 +784,7 @@ void TrackExtenderWithMTDT::produce(edm::Event& ev, const edm:: std::vector pathLengthsOrigTrkRaw; std::vector tmtdOrigTrkRaw; std::vector sigmatmtdOrigTrkRaw; + std::vector tmtdPosOrigTrkRaw; std::vector tofpiOrigTrkRaw; std::vector tofkOrigTrkRaw; std::vector tofpOrigTrkRaw; @@ -912,12 +916,14 @@ void TrackExtenderWithMTDT::produce(edm::Event& ev, const edm:: float pMap = 0.f, betaMap = 0.f, t0Map = 0.f, sigmat0Map = -1.f, pathLengthMap = -1.f, tmtdMap = 0.f, sigmatmtdMap = -1.f, tofpiMap = 0.f, tofkMap = 0.f, tofpMap = 0.f, sigmatofpiMap = -1.f, sigmatofkMap = -1.f, sigmatofpMap = -1.f; + GlobalPoint tmtdPosMap{0., 0., 0.}; int iMap = -1; for (const auto& trj : trajwithmtd) { const auto& thetrj = (updateTraj_ ? trj : trajs); float pathLength = 0.f, tmtd = 0.f, sigmatmtd = -1.f, tofpi = 0.f, tofk = 0.f, tofp = 0.f, sigmatofpi = -1.f, sigmatofk = -1.f, sigmatofp = -1.f; + GlobalPoint tmtdPos{0., 0., 0.}; LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: refit track " << itrack << " p/pT = " << track->p() << " " << track->pt() << " eta = " << track->eta(); reco::Track result = buildTrack(track, @@ -930,6 +936,7 @@ void TrackExtenderWithMTDT::produce(edm::Event& ev, const edm:: pathLength, tmtd, sigmatmtd, + tmtdPos, tofpi, tofk, tofp, @@ -959,6 +966,7 @@ void TrackExtenderWithMTDT::produce(edm::Event& ev, const edm:: pathLengthMap = pathLength; tmtdMap = tmtd; sigmatmtdMap = sigmatmtd; + tmtdPosMap = tmtdPos; auto& backtrack = output->back(); iMap = output->size() - 1; pMap = backtrack.p(); @@ -998,6 +1006,7 @@ void TrackExtenderWithMTDT::produce(edm::Event& ev, const edm:: pathLengthsOrigTrkRaw.push_back(pathLengthMap); tmtdOrigTrkRaw.push_back(tmtdMap); sigmatmtdOrigTrkRaw.push_back(sigmatmtdMap); + tmtdPosOrigTrkRaw.push_back(tmtdPosMap); tofpiOrigTrkRaw.push_back(tofpiMap); tofkOrigTrkRaw.push_back(tofkMap); tofpOrigTrkRaw.push_back(tofpMap); @@ -1035,6 +1044,7 @@ void TrackExtenderWithMTDT::produce(edm::Event& ev, const edm:: fillValueMap(ev, tracksH, pathLengthsOrigTrkRaw, pathLengthOrigTrkToken_); fillValueMap(ev, tracksH, tmtdOrigTrkRaw, tmtdOrigTrkToken_); fillValueMap(ev, tracksH, sigmatmtdOrigTrkRaw, sigmatmtdOrigTrkToken_); + fillValueMap(ev, tracksH, tmtdPosOrigTrkRaw, tmtdPosOrigTrkToken_); fillValueMap(ev, tracksH, tofpiOrigTrkRaw, tofpiOrigTrkToken_); fillValueMap(ev, tracksH, tofkOrigTrkRaw, tofkOrigTrkToken_); fillValueMap(ev, tracksH, tofpOrigTrkRaw, tofpOrigTrkToken_); @@ -1301,6 +1311,7 @@ reco::Track TrackExtenderWithMTDT::buildTrack(const reco::Track float& pathLengthOut, float& tmtdOut, float& sigmatmtdOut, + GlobalPoint& tmtdPosOut, float& tofpi, float& tofk, float& tofp, @@ -1350,6 +1361,7 @@ reco::Track TrackExtenderWithMTDT::buildTrack(const reco::Track bool validpropagation = trackPathLength(trajWithMtd, bs, thePropagator, pathlength, trs); float thit = 0.f; float thiterror = -1.f; + GlobalPoint thitpos{0., 0., 0.}; bool validmtd = false; if (!validpropagation) { @@ -1375,6 +1387,7 @@ reco::Track TrackExtenderWithMTDT::buildTrack(const reco::Track const MTDTrackingRecHit* mtdhit = static_cast((*ihit1).recHit()->hit()); thit = mtdhit->time(); thiterror = mtdhit->timeError(); + thitpos = mtdhit->globalPosition(); validmtd = true; } else if (ihitcount == 2 && ietlcount == 2) { std::pair lastStep = trs.getSegmentPathAndMom2(0); @@ -1410,11 +1423,13 @@ reco::Track TrackExtenderWithMTDT::buildTrack(const reco::Track thiterror = 1.f / (err1 + err2); thit = (tofInfo.dt * err1 + mtdhit2->time() * err2) * thiterror; thiterror = std::sqrt(thiterror); + thitpos = mtdhit2->globalPosition(); LogTrace("TrackExtenderWithMTD") - << "TrackExtenderWithMTD: p trk = " << p.mag() << " ETL hits times/errors: " << mtdhit1->time() - << " +/- " << mtdhit1->timeError() << " , " << mtdhit2->time() << " +/- " << mtdhit2->timeError() + << "TrackExtenderWithMTD: p trk = " << p.mag() << " ETL hits times/errors: 1) " << mtdhit1->time() + << " +/- " << mtdhit1->timeError() << " , 2) " << mtdhit2->time() << " +/- " << mtdhit2->timeError() << " extrapolated time1: " << tofInfo.dt << " +/- " << tofInfo.dterror << " average = " << thit - << " +/- " << thiterror; + << " +/- " << thiterror << "\n hit1 pos: " << mtdhit1->globalPosition() + << " hit2 pos: " << mtdhit2->globalPosition() << " etl path length " << etlpathlength << std::endl; validmtd = true; } else { // if back extrapolated time of the outermost measurement not compatible with the innermost, keep the one with smallest error @@ -1443,6 +1458,7 @@ reco::Track TrackExtenderWithMTDT::buildTrack(const reco::Track pathLengthOut = pathlength; // set path length if we've got a timing hit tmtdOut = thit; sigmatmtdOut = thiterror; + tmtdPosOut = thitpos; t0 = tofInfo.dt; covt0t0 = tofInfo.dterror2; betaOut = tofInfo.beta_pi; diff --git a/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHGC_cfi.py b/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHGC_cfi.py index bd32a4e366a55..4073547214f6f 100644 --- a/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHGC_cfi.py +++ b/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHGC_cfi.py @@ -73,3 +73,6 @@ particleFlowClusterHGCalFromSimCl = particleFlowClusterHGCal.clone( initialClusteringStep = _simClusterMapper_HGCal ) + +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +ticl_v5.toModify(particleFlowClusterHGCal.initialClusteringStep, tracksterSrc = "ticlCandidate") diff --git a/SimCalorimetry/HGCalAssociatorProducers/python/TSToSimTSAssociation_cfi.py b/SimCalorimetry/HGCalAssociatorProducers/python/TSToSimTSAssociation_cfi.py index 1d012306ab86d..a1c684519a968 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/python/TSToSimTSAssociation_cfi.py +++ b/SimCalorimetry/HGCalAssociatorProducers/python/TSToSimTSAssociation_cfi.py @@ -55,4 +55,18 @@ label_cp = cms.InputTag("mix","MergedCaloTruth"), ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +''' For future separate iterations +ticl_v5.toModify(tracksterSimTracksterAssociationLinkingbyCLUE3D, label_tst = cms.InputTag("mergedTrackstersProducer")) +tracksterSimTracksterAssociationLinkingbyCLUE3DEM = tracksterSimTracksterAssociationLinkingbyCLUE3D.clone(label_tst = cms.InputTag("ticlTrackstersCLUE3DEM")) +tracksterSimTracksterAssociationLinkingbyCLUE3DHAD = tracksterSimTracksterAssociationLinkingbyCLUE3D.clone(label_tst = cms.InputTag("ticlTrackstersCLUE3DHAD")) +ticl_v5.toModify(tracksterSimTracksterAssociationPRbyCLUE3D, label_tst = cms.InputTag("mergedTrackstersProducer")) +tracksterSimTracksterAssociationPRbyCLUE3DEM = tracksterSimTracksterAssociationPRbyCLUE3D.clone(label_tst = cms.InputTag("ticlTrackstersCLUE3DEM")) +tracksterSimTracksterAssociationPRbyCLUE3DHAD = tracksterSimTracksterAssociationPRbyCLUE3D.clone(label_tst = cms.InputTag("ticlTrackstersCLUE3DHAD")) +''' + +ticl_v5.toModify(tracksterSimTracksterAssociationLinking, label_tst = cms.InputTag("ticlCandidate")) +ticl_v5.toModify(tracksterSimTracksterAssociationPR, label_tst = cms.InputTag("ticlCandidate")) +ticl_v5.toModify(tracksterSimTracksterAssociationLinkingPU, label_tst = cms.InputTag("ticlCandidate")) +ticl_v5.toModify(tracksterSimTracksterAssociationPRPU, label_tst = cms.InputTag("ticlCandidate")) diff --git a/Validation/Configuration/python/hgcalSimValid_cff.py b/Validation/Configuration/python/hgcalSimValid_cff.py index 89ff13ad37371..9a3ba580ad81b 100644 --- a/Validation/Configuration/python/hgcalSimValid_cff.py +++ b/Validation/Configuration/python/hgcalSimValid_cff.py @@ -9,7 +9,8 @@ from SimCalorimetry.HGCalAssociatorProducers.LCToSimTSAssociation_cfi import layerClusterSimTracksterAssociation as layerClusterSimTracksterAssociationProducer from SimCalorimetry.HGCalAssociatorProducers.LCToCPAssociation_cfi import layerClusterCaloParticleAssociationHFNose as layerClusterCaloParticleAssociationProducerHFNose from SimCalorimetry.HGCalAssociatorProducers.LCToSCAssociation_cfi import layerClusterSimClusterAssociationHFNose as layerClusterSimClusterAssociationProducerHFNose -from SimCalorimetry.HGCalAssociatorProducers.TSToSimTSAssociation_cfi import tracksterSimTracksterAssociationLinking, tracksterSimTracksterAssociationPR,tracksterSimTracksterAssociationLinkingbyCLUE3D, tracksterSimTracksterAssociationPRbyCLUE3D, tracksterSimTracksterAssociationLinkingPU, tracksterSimTracksterAssociationPRPU +from SimCalorimetry.HGCalAssociatorProducers.TSToSimTSAssociation_cfi import tracksterSimTracksterAssociationLinking, tracksterSimTracksterAssociationPR,tracksterSimTracksterAssociationLinkingbyCLUE3D, tracksterSimTracksterAssociationPRbyCLUE3D, tracksterSimTracksterAssociationLinkingPU, tracksterSimTracksterAssociationPRPU #, tracksterSimTracksterAssociationLinkingbyCLUE3DEM, tracksterSimTracksterAssociationLinkingbyCLUE3DHAD, tracksterSimTracksterAssociationPRbyCLUE3DEM, tracksterSimTracksterAssociationPRbyCLUE3DHAD +from RecoHGCal.TICL.mergedTrackstersProducer_cfi import mergedTrackstersProducer as _mergedTrackstersProducer from SimCalorimetry.HGCalAssociatorProducers.SimTauProducer_cfi import * from Validation.HGCalValidation.simhitValidation_cff import * @@ -43,6 +44,12 @@ SimTauProducer ) +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +''' For future separate iterations +mergedTrackstersProducer = _mergedTrackstersProducer.clone() +ticl_v5.toModify(hgcalAssociators, lambda x: x.add(mergedTrackstersProducer, tracksterSimTracksterAssociationLinkingbyCLUE3DEM, tracksterSimTracksterAssociationLinkingbyCLUE3DHAD, tracksterSimTracksterAssociationPRbyCLUE3DEM, tracksterSimTracksterAssociationPRbyCLUE3DHAD)) +''' + hgcalValidation = cms.Sequence(hgcalSimHitValidationEE + hgcalSimHitValidationHEF + hgcalSimHitValidationHEB diff --git a/Validation/HGCalValidation/interface/HGCalValidator.h b/Validation/HGCalValidation/interface/HGCalValidator.h index b00e5100d56df..08f96327d6ed9 100644 --- a/Validation/HGCalValidation/interface/HGCalValidator.h +++ b/Validation/HGCalValidation/interface/HGCalValidator.h @@ -22,6 +22,7 @@ #include "DQMServices/Core/interface/DQMGlobalEDAnalyzer.h" +#include "Validation/HGCalValidation/interface/TICLCandidateValidator.h" #include "Validation/HGCalValidation/interface/HGVHistoProducerAlgo.h" #include "Validation/HGCalValidation/interface/CaloParticleSelector.h" #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h" @@ -33,6 +34,7 @@ class PileupSummaryInfo; struct HGCalValidatorHistograms { HGVHistoProducerAlgoHistograms histoProducerAlgo; + TICLCandidateValidatorHistograms histoTICLCandidates; std::vector h_layerclusters_coll; }; @@ -76,7 +78,10 @@ class HGCalValidator : public DQMGlobalEDAnalyzer { const bool doTrackstersPlots_; std::string label_TS_, label_TSToCPLinking_, label_TSToSTSPR_; std::vector label_clustersmask; + const bool doCandidatesPlots_; + std::string label_candidates_; const edm::FileInPath cummatbudinxo_; + const bool isTICLv5_; std::vector> labelToken; edm::EDGetTokenT> simClusters_; @@ -97,11 +102,12 @@ class HGCalValidator : public DQMGlobalEDAnalyzer { std::unique_ptr histoProducerAlgo_; std::vector hits_label_; std::vector> hits_token_; + std::unique_ptr candidateVal_; private: CaloParticleSelector cpSelector; std::shared_ptr tools_; - std::map cummatbudg; + std::map cumulative_material_budget; std::vector particles_to_monitor_; unsigned totallayers_to_monitor_; std::vector thicknesses_to_monitor_; diff --git a/Validation/HGCalValidation/interface/TICLCandidateValidator.h b/Validation/HGCalValidation/interface/TICLCandidateValidator.h new file mode 100644 index 0000000000000..46dfcb5b89b64 --- /dev/null +++ b/Validation/HGCalValidation/interface/TICLCandidateValidator.h @@ -0,0 +1,140 @@ +#ifndef Validation_HGCalValidation_TICLCandidateValidator_h +#define Validation_HGCalValidation_TICLCandidateValidator_h + +#include +#include +#include + +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" + +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "DataFormats/HGCalReco/interface/TICLCandidate.h" + +#include "SimDataFormats/Associations/interface/TracksterToSimTracksterHitLCAssociator.h" + +#include "DQMServices/Core/interface/DQMStore.h" + +struct TICLCandidateValidatorHistograms { + dqm::reco::MonitorElement* h_tracksters_in_candidate; + dqm::reco::MonitorElement* h_candidate_raw_energy; + dqm::reco::MonitorElement* h_candidate_regressed_energy; + dqm::reco::MonitorElement* h_candidate_pT; + dqm::reco::MonitorElement* h_candidate_charge; + dqm::reco::MonitorElement* h_candidate_pdgId; + dqm::reco::MonitorElement* h_candidate_partType; + + std::vector h_den_chg_energy_candidate; + std::vector h_num_chg_energy_candidate_track; + std::vector h_num_chg_energy_candidate_pdgId; + std::vector h_num_chg_energy_candidate_energy; + std::vector h_den_chg_pt_candidate; + std::vector h_num_chg_pt_candidate_track; + std::vector h_num_chg_pt_candidate_pdgId; + std::vector h_num_chg_pt_candidate_energy; + std::vector h_den_chg_eta_candidate; + std::vector h_num_chg_eta_candidate_track; + std::vector h_num_chg_eta_candidate_pdgId; + std::vector h_num_chg_eta_candidate_energy; + std::vector h_den_chg_phi_candidate; + std::vector h_num_chg_phi_candidate_track; + std::vector h_num_chg_phi_candidate_pdgId; + std::vector h_num_chg_phi_candidate_energy; + + std::vector h_den_neut_energy_candidate; + std::vector h_num_neut_energy_candidate_pdgId; + std::vector h_num_neut_energy_candidate_energy; + std::vector h_den_neut_pt_candidate; + std::vector h_num_neut_pt_candidate_pdgId; + std::vector h_num_neut_pt_candidate_energy; + std::vector h_den_neut_eta_candidate; + std::vector h_num_neut_eta_candidate_pdgId; + std::vector h_num_neut_eta_candidate_energy; + std::vector h_den_neut_phi_candidate; + std::vector h_num_neut_phi_candidate_pdgId; + std::vector h_num_neut_phi_candidate_energy; + + std::vector h_den_fake_chg_energy_candidate; + std::vector h_num_fake_chg_energy_candidate_track; + std::vector h_num_fake_chg_energy_candidate_pdgId; + std::vector h_num_fake_chg_energy_candidate_energy; + std::vector h_den_fake_chg_pt_candidate; + std::vector h_num_fake_chg_pt_candidate_track; + std::vector h_num_fake_chg_pt_candidate_pdgId; + std::vector h_num_fake_chg_pt_candidate_energy; + std::vector h_den_fake_chg_eta_candidate; + std::vector h_num_fake_chg_eta_candidate_track; + std::vector h_num_fake_chg_eta_candidate_pdgId; + std::vector h_num_fake_chg_eta_candidate_energy; + std::vector h_den_fake_chg_phi_candidate; + std::vector h_num_fake_chg_phi_candidate_track; + std::vector h_num_fake_chg_phi_candidate_pdgId; + std::vector h_num_fake_chg_phi_candidate_energy; + + std::vector h_den_fake_neut_energy_candidate; + std::vector h_num_fake_neut_energy_candidate_pdgId; + std::vector h_num_fake_neut_energy_candidate_energy; + std::vector h_den_fake_neut_pt_candidate; + std::vector h_num_fake_neut_pt_candidate_pdgId; + std::vector h_num_fake_neut_pt_candidate_energy; + std::vector h_den_fake_neut_eta_candidate; + std::vector h_num_fake_neut_eta_candidate_pdgId; + std::vector h_num_fake_neut_eta_candidate_energy; + std::vector h_den_fake_neut_phi_candidate; + std::vector h_num_fake_neut_phi_candidate_pdgId; + std::vector h_num_fake_neut_phi_candidate_energy; + + std::vector h_chg_tracksters_in_candidate; + std::vector h_chg_candidate_regressed_energy; + std::vector h_chg_candidate_charge; + std::vector h_chg_candidate_pdgId; + std::vector h_chg_candidate_partType; + + std::vector h_neut_tracksters_in_candidate; + std::vector h_neut_candidate_regressed_energy; + std::vector h_neut_candidate_charge; + std::vector h_neut_candidate_pdgId; + std::vector h_neut_candidate_partType; +}; + +class TICLCandidateValidator { +public: + typedef dqm::legacy::DQMStore DQMStore; + typedef dqm::legacy::MonitorElement MonitorElement; + + TICLCandidateValidator(){}; + TICLCandidateValidator(edm::EDGetTokenT> TICLCandidates, + edm::EDGetTokenT> simTICLCandidatesToken, + edm::EDGetTokenT> recoTracksToken, + edm::EDGetTokenT> trackstersToken, + edm::EDGetTokenT associatorMapRtSToken, + edm::EDGetTokenT associatorMapStRToken, + edm::EDGetTokenT associatorMapRtSPUToken, + bool isTICLv5); + ~TICLCandidateValidator(); + + using Histograms = TICLCandidateValidatorHistograms; + + void bookCandidatesHistos(DQMStore::IBooker& ibook, Histograms& histograms, std::string baseDir) const; + + void fillCandidateHistos(const edm::Event& event, + const Histograms& histograms, + edm::Handle simTrackstersCP_h) const; + +private: + edm::EDGetTokenT> TICLCandidatesToken_; + edm::EDGetTokenT> simTICLCandidatesToken_; + edm::EDGetTokenT> recoTracksToken_; + edm::EDGetTokenT> trackstersToken_; + edm::EDGetTokenT associatorMapRtSToken_; + edm::EDGetTokenT associatorMapStRToken_; + edm::EDGetTokenT associatorMapRtSPUToken_; + bool isTICLv5_ = false; +}; + +#endif diff --git a/Validation/HGCalValidation/plugins/HGCalValidator.cc b/Validation/HGCalValidation/plugins/HGCalValidator.cc index 5dc82508ee8cb..acd7500379322 100644 --- a/Validation/HGCalValidation/plugins/HGCalValidator.cc +++ b/Validation/HGCalValidation/plugins/HGCalValidator.cc @@ -30,7 +30,10 @@ HGCalValidator::HGCalValidator(const edm::ParameterSet& pset) label_TSToCPLinking_(pset.getParameter("label_TSToCPLinking")), label_TSToSTSPR_(pset.getParameter("label_TSToSTSPR")), label_clustersmask(pset.getParameter>("LayerClustersInputMask")), + doCandidatesPlots_(pset.getUntrackedParameter("doCandidatesPlots")), + label_candidates_(pset.getParameter("ticlCandidates")), cummatbudinxo_(pset.getParameter("cummatbudinxo")), + isTICLv5_(pset.getUntrackedParameter("isticlv5")), hits_label_(pset.getParameter>("hits")) { //In this way we can easily generalize to associations between other objects also. const edm::InputTag& label_cp_effic_tag = pset.getParameter("label_cp_effic"); @@ -60,6 +63,33 @@ HGCalValidator::HGCalValidator(const edm::ParameterSet& pset) layerclusters_ = consumes(label_lcl); + if (doCandidatesPlots_) { + edm::EDGetTokenT> TICLCandidatesToken = + consumes>(pset.getParameter("ticlTrackstersMerge")); + edm::EDGetTokenT> simTICLCandidatesToken = + consumes>(pset.getParameter("simTiclCandidates")); + edm::EDGetTokenT> recoTracksToken = + consumes>(pset.getParameter("recoTracks")); + edm::EDGetTokenT> trackstersToken = + consumes>(pset.getParameter("ticlTrackstersMerge")); + edm::EDGetTokenT associatorMapRtSToken = + consumes(pset.getParameter("mergeRecoToSimAssociator")); + edm::EDGetTokenT associatorMapStRToken = + consumes(pset.getParameter("mergeSimToRecoAssociator")); + edm::EDGetTokenT associatorMapRtSPUToken = + consumes( + pset.getParameter("mergeRecoToSimAssociatorPU")); + + candidateVal_ = std::make_unique(TICLCandidatesToken, + simTICLCandidatesToken, + recoTracksToken, + trackstersToken, + associatorMapRtSToken, + associatorMapStRToken, + associatorMapRtSPUToken, + isTICLv5_); + } + for (auto& itag : label_tst) { label_tstTokens.push_back(consumes(itag)); } @@ -97,7 +127,7 @@ HGCalValidator::HGCalValidator(const edm::ParameterSet& pset) double mbg = 0.; for (unsigned ilayer = 1; ilayer <= totallayers_to_monitor_; ++ilayer) { fmb >> thelay >> mbg; - cummatbudg.insert(std::pair(thelay, mbg)); + cumulative_material_budget.insert(std::pair(thelay, mbg)); } fmb.close(); @@ -224,6 +254,13 @@ void HGCalValidator::bookHistograms(DQMStore::IBooker& ibook, ibook, histograms.histoProducerAlgo, HGVHistoProducerAlgo::validationType::PatternRecognition); } } //end of booking Tracksters loop + + // Booking histograms concerning TICL candidates + if (doCandidatesPlots_) { + ibook.cd(); + ibook.setCurrentFolder(dirName_ + label_candidates_); + candidateVal_->bookCandidatesHistos(ibook, histograms.histoTICLCandidates, dirName_ + label_candidates_); + } } void HGCalValidator::cpParametersAndSelection(const Histograms& histograms, @@ -401,7 +438,7 @@ void HGCalValidator::dqmAnalyze(const edm::Event& event, cPIndices, selected_cPeff, *hitMap, - cummatbudg, + cumulative_material_budget, totallayers_to_monitor_, thicknesses_to_monitor_, recSimColl, @@ -449,4 +486,9 @@ void HGCalValidator::dqmAnalyze(const edm::Event& event, hits); } } //end of loop over Trackster input labels + + // tracksters histograms + if (doCandidatesPlots_) { + candidateVal_->fillCandidateHistos(event, histograms.histoTICLCandidates, simTracksterFromCPHandle); + } } diff --git a/Validation/HGCalValidation/python/HGCalPostProcessor_cff.py b/Validation/HGCalValidation/python/HGCalPostProcessor_cff.py index d87f588a30a75..219f9ce6fefde 100644 --- a/Validation/HGCalValidation/python/HGCalPostProcessor_cff.py +++ b/Validation/HGCalValidation/python/HGCalPostProcessor_cff.py @@ -3,7 +3,7 @@ from Validation.HGCalValidation.HGCalSimHitsClient_cff import * from Validation.HGCalValidation.HGCalDigiClient_cff import * from Validation.HGCalValidation.HGCalRecHitsClient_cff import * -from Validation.HGCalValidation.PostProcessorHGCAL_cfi import postProcessorHGCALlayerclusters,postProcessorHGCALsimclusters,postProcessorHGCALTracksters +from Validation.HGCalValidation.PostProcessorHGCAL_cfi import postProcessorHGCALlayerclusters,postProcessorHGCALsimclusters,postProcessorHGCALTracksters,postProcessorHGCALCandidates hgcalPostProcessor = cms.Sequence(hgcalSimHitClientEE + hgcalSimHitClientHEF @@ -18,4 +18,5 @@ hgcalValidatorPostProcessor = cms.Sequence( postProcessorHGCALlayerclusters+ postProcessorHGCALsimclusters+ - postProcessorHGCALTracksters) + postProcessorHGCALTracksters+ + postProcessorHGCALCandidates) diff --git a/Validation/HGCalValidation/python/HGCalValidator_cfi.py b/Validation/HGCalValidation/python/HGCalValidator_cfi.py index fbff6504ea56c..0c72904adbb52 100644 --- a/Validation/HGCalValidation/python/HGCalValidator_cfi.py +++ b/Validation/HGCalValidation/python/HGCalValidator_cfi.py @@ -14,6 +14,7 @@ labelTst.extend([cms.InputTag("ticlSimTracksters", "fromCPs"), cms.InputTag("ticlSimTracksters")]) lcInputMask = [cms.InputTag("ticlTracksters"+iteration) for iteration in ticlIterLabels] lcInputMask.extend([cms.InputTag("ticlSimTracksters", "fromCPs"), cms.InputTag("ticlSimTracksters")]) + hgcalValidator = DQMEDAnalyzer( "HGCalValidator", @@ -52,6 +53,16 @@ label_TS = cms.string("Morphology"), label_TSToCPLinking = cms.string("TSToCP_linking"), label_TSToSTSPR = cms.string("TSToSTS_patternRecognition"), + #candidates plots + doCandidatesPlots = cms.untracked.bool(True), + ticlCandidates = cms.string("ticlCandidates"), + + ticlTrackstersMerge = cms.InputTag("ticlTrackstersMerge"), + simTiclCandidates = cms.InputTag("ticlSimTracksters"), + recoTracks = cms.InputTag("generalTracks"), + mergeRecoToSimAssociator = cms.InputTag("tracksterSimTracksterAssociationLinking", "recoToSim"), + mergeSimToRecoAssociator = cms.InputTag("tracksterSimTracksterAssociationLinking", "simToReco"), + mergeRecoToSimAssociatorPU = cms.InputTag("tracksterSimTracksterAssociationLinkingPU", "recoToSim"), #The cumulative material budget in front of each layer. To be more specific, it #is the material budget just in front of the active material (not including it). @@ -78,8 +89,9 @@ histoProducerAlgoBlock = HGVHistoProducerAlgoBlock, ### output configuration - dirName = cms.string('HGCAL/HGCalValidator/') + dirName = cms.string('HGCAL/HGCalValidator/'), + isticlv5 = cms.untracked.bool(False) ) from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 @@ -92,3 +104,18 @@ from Configuration.Eras.Modifier_phase2_hgcalV16_cff import phase2_hgcalV16 phase2_hgcalV16.toModify(hgcalValidator, totallayers_to_monitor = cms.int32(47)) + +from Configuration.ProcessModifiers.ticl_v5_cff import ticl_v5 +# labelTst_v5 = ["ticlTrackstersCLUE3DEM", "ticlTrackstersCLUE3DHAD", "ticlTracksterLinks"] # for separate CLUE3D iterations +labelTst_v5 = ["ticlTrackstersCLUE3DHigh", "ticlTracksterLinks"] +labelTst_v5.extend([cms.InputTag("ticlSimTracksters", "fromCPs"), cms.InputTag("ticlSimTracksters")]) +# lcInputMask_v5 = ["ticlTrackstersCLUE3DEM", "ticlTrackstersCLUE3DHAD", "ticlTracksterLinks"] # for separate CLUE3D iterations +lcInputMask_v5 = ["ticlTrackstersCLUE3DHigh", "ticlTracksterLinks"] +lcInputMask_v5.extend([cms.InputTag("ticlSimTracksters", "fromCPs"), cms.InputTag("ticlSimTracksters")]) + +ticl_v5.toModify(hgcalValidator, + label_tst = cms.VInputTag(labelTst_v5), + LayerClustersInputMask = cms.VInputTag(lcInputMask_v5), + ticlTrackstersMerge = cms.InputTag("ticlCandidate"), + isticlv5 = cms.untracked.bool(True) +) diff --git a/Validation/HGCalValidation/python/PostProcessorHGCAL_cfi.py b/Validation/HGCalValidation/python/PostProcessorHGCAL_cfi.py index 89b639d95739c..db3a8546775a6 100644 --- a/Validation/HGCalValidation/python/PostProcessorHGCAL_cfi.py +++ b/Validation/HGCalValidation/python/PostProcessorHGCAL_cfi.py @@ -82,3 +82,38 @@ outputFileName = cms.untracked.string(""), verbose = cms.untracked.uint32(4) ) + +neutrals = ["photons", "neutral_pions", "neutral_hadrons"] +charged = ["electrons", "muons", "charged_hadrons"] +subDirsCandidates = [prefix + hgcalValidator.ticlCandidates.value() + "/" + c for cands in (neutrals, charged) for c in cands] +eff_candidates = [] + +for c in charged: + for var in variables.keys(): + eff_candidates.append("eff_"+c+"_track_"+var+" '"+c.replace("_", " ")+" candidates track efficiency vs "+var+"' num_track_cand_vs_"+var+"_"+c+" den_cand_vs_"+var+"_"+c) + eff_candidates.append("eff_"+c+"_pid_"+var+" '"+c.replace("_", " ")+" candidates track + pid efficiency vs "+var+"' num_pid_cand_vs_"+var+"_"+c+" den_cand_vs_"+var+"_"+c) + eff_candidates.append("eff_"+c+"_energy_"+var+" '"+c.replace("_", " ")+" candidates track + pid + energy efficiency vs "+var+"' num_energy_cand_vs_"+var+"_"+c+" den_cand_vs_"+var+"_"+c) +for n in neutrals: + for var in variables.keys(): + eff_candidates.append("eff_"+n+"_pid_"+var+" '"+n.replace("_", " ")+" candidates pid efficiency vs "+var+"' num_pid_cand_vs_"+var+"_"+n+" den_cand_vs_"+var+"_"+n) + eff_candidates.append("eff_"+n+"_energy_"+var+" '"+n.replace("_", " ")+" candidates pid + energy efficiency vs "+var+"' num_energy_cand_vs_"+var+"_"+n+" den_cand_vs_"+var+"_"+n) + +for c in charged: + for var in variables.keys(): + eff_candidates.append("fake_"+c+"_track_"+var+" '"+c.replace("_", " ")+" candidates track fake vs "+var+"' num_fake_track_cand_vs_"+var+"_"+c+" den_fake_cand_vs_"+var+"_"+c) + eff_candidates.append("fake_"+c+"_pid_"+var+" '"+c.replace("_", " ")+" candidates track + pid fake vs "+var+"' num_fake_pid_cand_vs_"+var+"_"+c+" den_fake_cand_vs_"+var+"_"+c) + eff_candidates.append("fake_"+c+"_energy_"+var+" '"+c.replace("_", " ")+" candidates track + pid + energy fake vs "+var+"' num_fake_energy_cand_vs_"+var+"_"+c+" den_fake_cand_vs_"+var+"_"+c) +for n in neutrals: + for var in variables.keys(): + eff_candidates.append("fake_"+n+"_pid_"+var+" '"+n.replace("_", " ")+" candidates pid fake vs "+var+"' num_fake_pid_cand_vs_"+var+"_"+n+" den_fake_cand_vs_"+var+"_"+n) + eff_candidates.append("fake_"+n+"_energy_"+var+" '"+n.replace("_", " ")+" candidates pid + energy fake vs "+var+"' num_fake_energy_cand_vs_"+var+"_"+n+" den_fake_cand_vs_"+var+"_"+n) + +postProcessorHGCALCandidates = DQMEDHarvester('DQMGenericClient', + subDirs = cms.untracked.vstring(subDirsCandidates), + efficiency = cms.vstring(eff_candidates), + resolution = cms.vstring(), + cumulativeDists = cms.untracked.vstring(), + noFlowDists = cms.untracked.vstring(), + outputFileName = cms.untracked.string(""), + verbose = cms.untracked.uint32(4) +) diff --git a/Validation/HGCalValidation/python/hgcalPlots.py b/Validation/HGCalValidation/python/hgcalPlots.py index 50dc4bc37cb0e..732aa9e032268 100644 --- a/Validation/HGCalValidation/python/hgcalPlots.py +++ b/Validation/HGCalValidation/python/hgcalPlots.py @@ -20,7 +20,7 @@ from Validation.HGCalValidation.PostProcessorHGCAL_cfi import lcToCP_linking, simDict, tsToCP_linking, tsToSTS_patternRec, variables hgcVal_dqm = "DQMData/Run 1/HGCAL/Run summary/HGCalValidator/" -#The number of layers per endcap in the current default geometry scenario. +#The number of layers per endcap in the current default geometry scenario. geometryscenario = 47 #To be able to spot any issues both in -z and +z a layer id was introduced @@ -1177,18 +1177,18 @@ xmax=1., ymin=0.01, ymax=1.) -_energyscore_cp2lc_zminus = PlotGroup("Energy_vs_Score_CP2LC", [Plot("Energy_vs_Score_caloparticle2layer_perlayer{:02d}".format(i), title="Energy_vs_Score_CP2LC", +_energyscore_cp2lc_zminus = PlotGroup("Energy_vs_Score_CP2LC", [Plot("Energy_vs_Score_caloparticle2layer_perlayer{:02d}".format(i), title="Energy_vs_Score_CP2LC", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_energy_score) for i in range(0, maxlayerzm) ], ncols=10) -_energyscore_cp2lc_zplus = PlotGroup("Energy_vs_Score_CP2LC", [Plot("Energy_vs_Score_caloparticle2layer_perlayer{:02d}".format(i), title="Energy_vs_Score_CP2LC", +_energyscore_cp2lc_zplus = PlotGroup("Energy_vs_Score_CP2LC", [Plot("Energy_vs_Score_caloparticle2layer_perlayer{:02d}".format(i), title="Energy_vs_Score_CP2LC", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_energy_score) for i in range(maxlayerzm,maxlayerzp) ], ncols=10) _common_energy_score["xmin"]=-0.1 -_energyscore_lc2cp_zminus = PlotGroup("Energy_vs_Score_LC2CP", [Plot("Energy_vs_Score_layer2caloparticle_perlayer{:02d}".format(i), title="Energy_vs_Score_LC2CP", +_energyscore_lc2cp_zminus = PlotGroup("Energy_vs_Score_LC2CP", [Plot("Energy_vs_Score_layer2caloparticle_perlayer{:02d}".format(i), title="Energy_vs_Score_LC2CP", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_energy_score) for i in range(0, maxlayerzm) ], ncols=10) -_energyscore_lc2cp_zplus = PlotGroup("Energy_vs_Score_LC2CP", [Plot("Energy_vs_Score_layer2caloparticle_perlayer{:02d}".format(i), title="Energy_vs_Score_LC2CP", +_energyscore_lc2cp_zplus = PlotGroup("Energy_vs_Score_LC2CP", [Plot("Energy_vs_Score_layer2caloparticle_perlayer{:02d}".format(i), title="Energy_vs_Score_LC2CP", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_energy_score) for i in range(maxlayerzm,maxlayerzp) ], ncols=10) @@ -1709,7 +1709,7 @@ _multiplicityOfLCinTST_plots = [Plot("multiplicityOfLCinTST", drawCommand = "colz text45", normalizeToNumberOfEvents = True, **_common)] _multiplicityOfLCinTST_plots.extend([Plot("multiplicityOfLCinTST_vs_layerclusterenergy", - drawCommand = "colz text45", normalizeToNumberOfEvents = True, **_common)]) + drawCommand = "colz text45", normalizeToNumberOfEvents = True, **_common)]) _multiplicityOfLCinTST_plots.extend([Plot("multiplicityOfLCinTST_vs_layercluster_zplus", drawCommand = "colz text45", normalizeToNumberOfEvents = True, **_common)]) _multiplicityOfLCinTST_plots.extend([Plot("multiplicityOfLCinTST_vs_layercluster_zminus", @@ -1762,6 +1762,67 @@ _trackster_xyz_plots.extend([Plot("trackster_z", **_common)]) _trackster_xyz = PlotGroup("XYZ", _trackster_xyz_plots, ncols=3) +#-------------------------------------------------------------------------------------------- +# CANDIDATES +#-------------------------------------------------------------------------------------------- + +# all candidates +cand_plots_names = ["N of tracksters in candidate", "Candidates PDG Id", "Candidates charge", "Candidates type"] +_candidate_nts_plots = [] +for name in cand_plots_names: + _candidate_nts_plots.extend([Plot(name, **_common)]) +_candidatesPlots1 = PlotGroup("General_plots_pid_type", _candidate_nts_plots, ncols=2) + +cand_plots_names = ["Candidates pT", "Candidates raw energy", "Candidates regressed energy"] +_candidate_nts_plots = [] +for name in cand_plots_names: + _candidate_nts_plots.extend([Plot(name, **_common)]) +_candidatesPlots2 = PlotGroup("General_plots_pt_energy", _candidate_nts_plots, ncols=3) + +_candidatesPlots = [_candidatesPlots1, _candidatesPlots2] + +# divided by candidate's type +cand_type = ["charged_hadrons", "electrons", "muons", "neutral_hadrons", "neutral_pions", "photons"] +cand_plots_names = [" candidates PDG Id", " candidates charge", " candidates type"] +cand_plots_names_den = ["den_fake_cand_vs_energy_", "den_fake_cand_vs_eta_", "den_fake_cand_vs_phi_", "den_fake_cand_vs_pt_"] + +_all_cand_type_plots = [] +for ct in cand_type: + cand_type_plots = [Plot("N of tracksters in candidate for "+ct, title="N of tracksters in candidate for "+ct.replace("_", " "), **_common)] + for name in cand_plots_names: + cand_type_plots.extend([Plot(ct+name, title=ct.replace("_", " ")+name, **_common)]) + _all_cand_type_plots.append(cand_type_plots) + +_all_cand_ene_plots = [] +for ct in cand_type: + name = "candidates regressed energy" + cand_type_plots = [Plot(ct+name, title=ct.replace("_", " ")+" "+name, **_common)] + for name in cand_plots_names_den: + cand_type_plots.extend([Plot(name+ct, title=ct.replace("_", " ")+" candidates "+name.replace("den_fake_cand_vs_", "").replace("_", ""), **_common)]) + _all_cand_ene_plots.append(cand_type_plots) + +#efficiency and fake +_common_eff_fake = {"stat": False, "legend": False, "xbinlabelsize": 14, "xtitle": "Default", "xbinlabeloption": "d", "ymin": 0.0, "ymax": 1.1} +_all_cand_eff_plots = [] +for ct in cand_type: + cand_eff_plots = [] + for var in ["pt", "energy", "eta", "phi"]: + for cut in ["track", "pid", "energy"]: + cand_eff_plots.extend([Plot("eff_"+ct+"_"+cut+"_"+var, title=cut + " efficiency for "+ct.replace("_", " ")+" vs "+var, ytitle="Efficiency", **_common_eff_fake)]) + _all_cand_eff_plots.append(cand_eff_plots) + +_all_cand_fake_plots = [] +for ct in cand_type: + cand_fake_plots = [] + for var in ["pt", "energy", "eta", "phi"]: + for cut in ["track", "pid", "energy"]: + cand_fake_plots.extend([Plot("fake_"+ct+"_"+cut+"_"+var, title=cut + " fake rate for "+ct.replace("_", " ")+" vs "+var, ytitle="Fake rate", **_common_eff_fake)]) + _all_cand_fake_plots.append(cand_fake_plots) + +_allCandidatesPlots = [[],[],[],[],[],[]] +for i in range(6): + _allCandidatesPlots[i].extend([PlotGroup(cand_type[i]+"_type", _all_cand_type_plots[i], ncols=2), PlotGroup(cand_type[i]+"_kin", _all_cand_ene_plots[i], ncols=3), PlotGroup(cand_type[i]+"_eff", _all_cand_eff_plots[i], ncols=3), PlotGroup(cand_type[i]+"_fake", _all_cand_fake_plots[i], ncols=3)]) + #-------------------------------------------------------------------------------------------- # SIMHITS, DIGIS, RECHITS #-------------------------------------------------------------------------------------------- @@ -1776,143 +1837,143 @@ _common = {"stat": True, "drawStyle": "hist", "staty": 0.65} -_Occupancy_EE_zplus = PlotGroup("Occupancy_EE_zplus", [Plot("HitOccupancy_Plus_layer_{:02d}".format(i), title="Occupancy_EE_zplus", +_Occupancy_EE_zplus = PlotGroup("Occupancy_EE_zplus", [Plot("HitOccupancy_Plus_layer_{:02d}".format(i), title="Occupancy_EE_zplus", xtitle="Layer {}".format(i), **_common) for i in range(EE_min,EE_max+1) ], ncols=7) -_Occupancy_HE_Silicon_zplus = PlotGroup("Occupancy_HE_Silicon_zplus", [Plot("HitOccupancy_Plus_layer_{:02d}".format(i), title="Occupancy_HE_zplus", +_Occupancy_HE_Silicon_zplus = PlotGroup("Occupancy_HE_Silicon_zplus", [Plot("HitOccupancy_Plus_layer_{:02d}".format(i), title="Occupancy_HE_zplus", xtitle="Layer {}".format(i), **_common) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_Occupancy_HE_Scintillator_zplus = PlotGroup("Occupancy_HE_Scintillator_zplus", [Plot("HitOccupancy_Plus_layer_{:02d}".format(i), title="Occupancy_HE_Scintillator_zplus", +_Occupancy_HE_Scintillator_zplus = PlotGroup("Occupancy_HE_Scintillator_zplus", [Plot("HitOccupancy_Plus_layer_{:02d}".format(i), title="Occupancy_HE_Scintillator_zplus", xtitle="Layer {}".format(i), **_common) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) -_Occupancy_EE_zminus = PlotGroup("Occupancy_EE_zminus", [Plot("HitOccupancy_Minus_layer_{:02d}".format(i), title="Occupancy_EE_zminus", +_Occupancy_EE_zminus = PlotGroup("Occupancy_EE_zminus", [Plot("HitOccupancy_Minus_layer_{:02d}".format(i), title="Occupancy_EE_zminus", xtitle="Layer {}".format(i), **_common) for i in range(EE_min,EE_max+1) ], ncols=7) -_Occupancy_HE_Silicon_zminus = PlotGroup("Occupancy_HE_Silicon_zminus", [Plot("HitOccupancy_Minus_layer_{:02d}".format(i), title="Occupancy_HE_Silicon_zminus", +_Occupancy_HE_Silicon_zminus = PlotGroup("Occupancy_HE_Silicon_zminus", [Plot("HitOccupancy_Minus_layer_{:02d}".format(i), title="Occupancy_HE_Silicon_zminus", xtitle="Layer {}".format(i), **_common) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_Occupancy_HE_Scintillator_zminus = PlotGroup("Occupancy_HE_Scintillator_zminus", [Plot("HitOccupancy_Minus_layer_{:02d}".format(i), title="Occupancy_HE_Scintillator_zminus", +_Occupancy_HE_Scintillator_zminus = PlotGroup("Occupancy_HE_Scintillator_zminus", [Plot("HitOccupancy_Minus_layer_{:02d}".format(i), title="Occupancy_HE_Scintillator_zminus", xtitle="Layer {}".format(i), **_common) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) _common_etaphi = dict(removeEmptyBins=False, xbinlabelsize=10, xbinlabeloption="d", ymin=None) -_EtaPhi_EE_zplus = PlotGroup("EtaPhi_EE_zplus", [Plot("EtaPhi_Plus_layer_{:02d}".format(i), title="EtaPhi_EE_zplus", +_EtaPhi_EE_zplus = PlotGroup("EtaPhi_EE_zplus", [Plot("EtaPhi_Plus_layer_{:02d}".format(i), title="EtaPhi_EE_zplus", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_etaphi) for i in range(EE_min,EE_max+1) ], ncols=7) -_EtaPhi_HE_Silicon_zplus = PlotGroup("EtaPhi_HE_Silicon_zplus", [Plot("EtaPhi_Plus_layer_{:02d}".format(i), title="EtaPhi_HE_Silicon_zplus", +_EtaPhi_HE_Silicon_zplus = PlotGroup("EtaPhi_HE_Silicon_zplus", [Plot("EtaPhi_Plus_layer_{:02d}".format(i), title="EtaPhi_HE_Silicon_zplus", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_etaphi) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_EtaPhi_HE_Scintillator_zplus = PlotGroup("EtaPhi_HE_Scintillator_zplus", [Plot("EtaPhi_Plus_layer_{:02d}".format(i), title="EtaPhi_HE_Scintillator_zplus", +_EtaPhi_HE_Scintillator_zplus = PlotGroup("EtaPhi_HE_Scintillator_zplus", [Plot("EtaPhi_Plus_layer_{:02d}".format(i), title="EtaPhi_HE_Scintillator_zplus", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_etaphi) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) -_EtaPhi_EE_zminus = PlotGroup("EtaPhi_EE_zminus", [Plot("EtaPhi_Minus_layer_{:02d}".format(i), title="EtaPhi_EE_zminus", +_EtaPhi_EE_zminus = PlotGroup("EtaPhi_EE_zminus", [Plot("EtaPhi_Minus_layer_{:02d}".format(i), title="EtaPhi_EE_zminus", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_etaphi) for i in range(EE_min,EE_max+1) ], ncols=7) -_EtaPhi_HE_Silicon_zminus = PlotGroup("EtaPhi_HE_Silicon_zminus", [Plot("EtaPhi_Minus_layer_{:02d}".format(i), title="EtaPhi_HE_Silicon_zminus", +_EtaPhi_HE_Silicon_zminus = PlotGroup("EtaPhi_HE_Silicon_zminus", [Plot("EtaPhi_Minus_layer_{:02d}".format(i), title="EtaPhi_HE_Silicon_zminus", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_etaphi) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_EtaPhi_HE_Scintillator_zminus = PlotGroup("EtaPhi_HE_Scintillator_zminus", [Plot("EtaPhi_Minus_layer_{:02d}".format(i), title="EtaPhi_HE_Scintillator_zminus", +_EtaPhi_HE_Scintillator_zminus = PlotGroup("EtaPhi_HE_Scintillator_zminus", [Plot("EtaPhi_Minus_layer_{:02d}".format(i), title="EtaPhi_HE_Scintillator_zminus", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_etaphi) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) _common = {"stat": True, "drawStyle": "hist", "staty": 0.65, "ymin": 0.1, "ylog": True} -_Energy_EE_0 = PlotGroup("Energy_Time_0_EE", [Plot("energy_time_0_layer_{:02d}".format(i), title="Energy_Time_0_EE", +_Energy_EE_0 = PlotGroup("Energy_Time_0_EE", [Plot("energy_time_0_layer_{:02d}".format(i), title="Energy_Time_0_EE", xtitle="Layer {}".format(i), **_common) for i in range(EE_min,EE_max+1) ], ncols=7) -_Energy_HE_Silicon_0 = PlotGroup("Energy_Time_0_HE_Silicon", [Plot("energy_time_0_layer_{:02d}".format(i), title="Energy_Time_0_HE_Silicon", +_Energy_HE_Silicon_0 = PlotGroup("Energy_Time_0_HE_Silicon", [Plot("energy_time_0_layer_{:02d}".format(i), title="Energy_Time_0_HE_Silicon", xtitle="Layer {}".format(i), **_common) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_Energy_HE_Scintillator_0 = PlotGroup("Energy_Time_0_HE_Scintillator", [Plot("energy_time_0_layer_{:02d}".format(i), title="Energy_Time_0_HE_Scintillator", +_Energy_HE_Scintillator_0 = PlotGroup("Energy_Time_0_HE_Scintillator", [Plot("energy_time_0_layer_{:02d}".format(i), title="Energy_Time_0_HE_Scintillator", xtitle="Layer {}".format(i), **_common) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) -_Energy_EE_1 = PlotGroup("Energy_Time_1_EE", [Plot("energy_time_1_layer_{:02d}".format(i), title="Energy_Time_1_EE", +_Energy_EE_1 = PlotGroup("Energy_Time_1_EE", [Plot("energy_time_1_layer_{:02d}".format(i), title="Energy_Time_1_EE", xtitle="Layer {}".format(i), **_common) for i in range(EE_min,EE_max+1) ], ncols=7) -_Energy_HE_Silicon_1 = PlotGroup("Energy_Time_1_HE_Silicon", [Plot("energy_time_1_layer_{:02d}".format(i), title="Energy_Time_1_HE_Silicon", +_Energy_HE_Silicon_1 = PlotGroup("Energy_Time_1_HE_Silicon", [Plot("energy_time_1_layer_{:02d}".format(i), title="Energy_Time_1_HE_Silicon", xtitle="Layer {}".format(i), **_common) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_Energy_HE_Scintillator_1 = PlotGroup("Energy_Time_1_HE_Scintillator", [Plot("energy_time_1_layer_{:02d}".format(i), title="Energy_Time_1_HE_Scintillator", +_Energy_HE_Scintillator_1 = PlotGroup("Energy_Time_1_HE_Scintillator", [Plot("energy_time_1_layer_{:02d}".format(i), title="Energy_Time_1_HE_Scintillator", xtitle="Layer {}".format(i), **_common) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) -_Energy_EE = PlotGroup("Energy_EE", [Plot("energy_layer_{:02d}".format(i), title="Energy_EE", +_Energy_EE = PlotGroup("Energy_EE", [Plot("energy_layer_{:02d}".format(i), title="Energy_EE", xtitle="Layer {}".format(i), **_common) for i in range(EE_min,EE_max+1) ], ncols=7) -_Energy_HE_Silicon = PlotGroup("Energy_HE_Silicon", [Plot("energy_layer_{:02d}".format(i), title="Energy_HE_Silicon", +_Energy_HE_Silicon = PlotGroup("Energy_HE_Silicon", [Plot("energy_layer_{:02d}".format(i), title="Energy_HE_Silicon", xtitle="Layer {}".format(i), **_common) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_Energy_HE_Scintillator = PlotGroup("Energy_HE_Scintillator", [Plot("energy_layer_{:02d}".format(i), title="Energy_HE_Scintillator", +_Energy_HE_Scintillator = PlotGroup("Energy_HE_Scintillator", [Plot("energy_layer_{:02d}".format(i), title="Energy_HE_Scintillator", xtitle="Layer {}".format(i), **_common) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) -_DigiHits_ADC_EE = PlotGroup("ADC_EE", [Plot("ADC_layer_{:02d}".format(i), title="DigiHits_ADC_EE", +_DigiHits_ADC_EE = PlotGroup("ADC_EE", [Plot("ADC_layer_{:02d}".format(i), title="DigiHits_ADC_EE", xtitle="Layer {}".format(i), **_common) for i in range(EE_min,EE_max+1) ], ncols=7) -_DigiHits_ADC_HE_Silicon = PlotGroup("ADC_HE_Silicon", [Plot("ADC_layer_{:02d}".format(i), title="DigiHits_ADC_HE_Silicon", +_DigiHits_ADC_HE_Silicon = PlotGroup("ADC_HE_Silicon", [Plot("ADC_layer_{:02d}".format(i), title="DigiHits_ADC_HE_Silicon", xtitle="Layer {}".format(i), **_common) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_DigiHits_ADC_HE_Scintillator = PlotGroup("ADC_HE_Scintillator", [Plot("ADC_layer_{:02d}".format(i), title="DigiHits_ADC_HE_Scintillator", +_DigiHits_ADC_HE_Scintillator = PlotGroup("ADC_HE_Scintillator", [Plot("ADC_layer_{:02d}".format(i), title="DigiHits_ADC_HE_Scintillator", xtitle="Layer {}".format(i), **_common) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) _common = {"stat": True, "drawStyle": "hist", "staty": 0.65} -_DigiHits_Occupancy_EE_zplus = PlotGroup("Occupancy_EE_zplus", [Plot("DigiOccupancy_Plus_layer_{:02d}".format(i), title="DigiHits_Occupancy_EE_zplus", +_DigiHits_Occupancy_EE_zplus = PlotGroup("Occupancy_EE_zplus", [Plot("DigiOccupancy_Plus_layer_{:02d}".format(i), title="DigiHits_Occupancy_EE_zplus", xtitle="Layer {}".format(i), **_common) for i in range(EE_min,EE_max+1) ], ncols=7) -_DigiHits_Occupancy_HE_Silicon_zplus = PlotGroup("Occupancy_HE_Silicon_zplus", [Plot("DigiOccupancy_Plus_layer_{:02d}".format(i), title="DigiHits_Occupancy_HE_Silicon_zplus", +_DigiHits_Occupancy_HE_Silicon_zplus = PlotGroup("Occupancy_HE_Silicon_zplus", [Plot("DigiOccupancy_Plus_layer_{:02d}".format(i), title="DigiHits_Occupancy_HE_Silicon_zplus", xtitle="Layer {}".format(i), **_common) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_DigiHits_Occupancy_HE_Scintillator_zplus = PlotGroup("Occupancy_HE_Scintillator_zplus", [Plot("DigiOccupancy_Plus_layer_{:02d}".format(i), title="DigiHits_Occupancy_HE_Scintillator_zplus", +_DigiHits_Occupancy_HE_Scintillator_zplus = PlotGroup("Occupancy_HE_Scintillator_zplus", [Plot("DigiOccupancy_Plus_layer_{:02d}".format(i), title="DigiHits_Occupancy_HE_Scintillator_zplus", xtitle="Layer {}".format(i), **_common) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) -_DigiHits_Occupancy_EE_zminus = PlotGroup("Occupancy_EE_zminus", [Plot("DigiOccupancy_Minus_layer_{:02d}".format(i), title="DigiHits_Occupancy_EE_zminus", +_DigiHits_Occupancy_EE_zminus = PlotGroup("Occupancy_EE_zminus", [Plot("DigiOccupancy_Minus_layer_{:02d}".format(i), title="DigiHits_Occupancy_EE_zminus", xtitle="Layer {}".format(i), **_common) for i in range(EE_min,EE_max+1) ], ncols=7) -_DigiHits_Occupancy_HE_Silicon_zminus = PlotGroup("Occupancy_HE_Silicon_zminus", [Plot("DigiOccupancy_Minus_layer_{:02d}".format(i), title="DigiHits_Occupancy_HE_Silicon_zminus", +_DigiHits_Occupancy_HE_Silicon_zminus = PlotGroup("Occupancy_HE_Silicon_zminus", [Plot("DigiOccupancy_Minus_layer_{:02d}".format(i), title="DigiHits_Occupancy_HE_Silicon_zminus", xtitle="Layer {}".format(i), **_common) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_DigiHits_Occupancy_HE_Scintillator_zminus = PlotGroup("Occupancy_HE_Scintillator_zminus", [Plot("DigiOccupancy_Minus_layer_{:02d}".format(i), title="DigiHits_Occupancy_HE_Scintillator_zminus", +_DigiHits_Occupancy_HE_Scintillator_zminus = PlotGroup("Occupancy_HE_Scintillator_zminus", [Plot("DigiOccupancy_Minus_layer_{:02d}".format(i), title="DigiHits_Occupancy_HE_Scintillator_zminus", xtitle="Layer {}".format(i), **_common) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) _common_XY = dict(removeEmptyBins=True, xbinlabelsize=10, xbinlabeloption="d", ymin=None) -_DigiHits_Occupancy_XY_EE = PlotGroup("Occupancy_XY_EE", [Plot("DigiOccupancy_XY_layer_{:02d}".format(i), title="DigiHits_Occupancy_XY_EE", +_DigiHits_Occupancy_XY_EE = PlotGroup("Occupancy_XY_EE", [Plot("DigiOccupancy_XY_layer_{:02d}".format(i), title="DigiHits_Occupancy_XY_EE", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_XY) for i in range(EE_min,EE_max+1) ], ncols=7) -_DigiHits_Occupancy_XY_HE_Silicon = PlotGroup("Occupancy_XY_HE_Silicon", [Plot("DigiOccupancy_XY_layer_{:02d}".format(i), title="DigiHits_Occupancy_XY_HE_Silicon", +_DigiHits_Occupancy_XY_HE_Silicon = PlotGroup("Occupancy_XY_HE_Silicon", [Plot("DigiOccupancy_XY_layer_{:02d}".format(i), title="DigiHits_Occupancy_XY_HE_Silicon", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_XY) for i in range(HESilicon_min,HESilicon_max+1) ], ncols=7) -_DigiHits_Occupancy_XY_HE_Scintillator = PlotGroup("Occupancy_XY_HE_Scintillator", [Plot("DigiOccupancy_XY_layer_{:02d}".format(i), title="DigiHits_Occupancy_XY_HE_Scintillator", +_DigiHits_Occupancy_XY_HE_Scintillator = PlotGroup("Occupancy_XY_HE_Scintillator", [Plot("DigiOccupancy_XY_layer_{:02d}".format(i), title="DigiHits_Occupancy_XY_HE_Scintillator", xtitle="Layer {}".format(i), drawStyle="COLZ", adjustMarginRight=0.1, **_common_XY) for i in range(HEScintillator_min,HEScintillator_max+1) ], ncols=7) @@ -2186,7 +2247,7 @@ # Merge Rate Plots _merges_zplus, _merges_zplus_eta, - _merges_zplus_phi, + _merges_zplus_phi, # Score of CaloParticles wrt Layer Clusters _score_caloparticle_to_layerclusters_zplus, # Score of LayerClusters wrt CaloParticles @@ -2280,22 +2341,22 @@ def append_hgcalLayerClustersPlots(collection = hgcalValidator.label_layerCluste regions_ClusterLevel = ["General: Cluster Level", "Z-minus: Cluster Level", "Z-plus: Cluster Level"] regions_CellLevel = ["Z-minus: Cell Level", "Z-plus: Cell Level"] regions_LCtoCP_association = ["Z-minus: LC_CP association", "Z-plus: LC_CP association"] - + plots_lc_general_clusterlevel = lc_general_clusterlevel - plots_lc_clusterlevel_zminus = lc_clusterlevel_zminus - plots_lc_cellevel_zminus = lc_cellevel_zminus + plots_lc_clusterlevel_zminus = lc_clusterlevel_zminus + plots_lc_cellevel_zminus = lc_cellevel_zminus plots_lc_clusterlevel_zplus = lc_clusterlevel_zplus plots_lc_cellevel_zplus = lc_cellevel_zplus plots_lc_cp_association_zminus = lc_cp_association_zminus plots_lc_cp_association_zplus = lc_cp_association_zplus if extended : - #plots_lc_clusterlevel_zminus = lc_clusterlevel_zminus - #plots_lc_clusterlevel_zplus = lc_clusterlevel_zplus + #plots_lc_clusterlevel_zminus = lc_clusterlevel_zminus + #plots_lc_clusterlevel_zplus = lc_clusterlevel_zplus plots_lc_cellevel_zminus = lc_cellevel_zminus + lc_zminus_extended plots_lc_cellevel_zplus = lc_cellevel_zplus + lc_zplus_extended - #plots_lc_cp_association_zminus = lc_cp_association_zminus - #plots_lc_cp_association_zplus = lc_cp_association_zplus + #plots_lc_cp_association_zminus = lc_cp_association_zminus + #plots_lc_cp_association_zplus = lc_cp_association_zplus setPlots_ClusterLevel = [plots_lc_general_clusterlevel, plots_lc_clusterlevel_zminus, plots_lc_clusterlevel_zplus] setPlots_CellLevel = [plots_lc_cellevel_zminus, plots_lc_cellevel_zplus] @@ -2718,7 +2779,7 @@ def _hgcalHitFolders(dirName="HGCalSimHitsV/HGCalEESensitive"): def append_hgcalHitsPlots(collection = "HGCalSimHitsV", name_collection = "Simulated Hits"): _hitsCommonPlots_EE = [ _Occupancy_EE_zplus, - _Occupancy_EE_zminus, + _Occupancy_EE_zminus, _EtaPhi_EE_zminus, _EtaPhi_EE_zplus ] @@ -2840,3 +2901,20 @@ def append_hgcalDigisPlots(collection = "HGCalDigisV", name_collection = "Digis" loopSubFolders=False, purpose=PlotPurpose.Timing, page=hitCalibrationLabel, section=hitCalibrationLabel )) + +hgcalTICLCandPlotter = Plotter() + +hgcalTICLCandPlotter.append('ticlCandidates', [ + "DQMData/Run 1/HGCAL/Run summary/HGCalValidator/"+hgcalValidator.ticlCandidates.value(), + ], PlotFolder( + *_candidatesPlots, + loopSubFolders=False, + purpose=PlotPurpose.Timing, page="General", section="Candidates")) + +for i in range(6): + hgcalTICLCandPlotter.append('ticlCandidates', [ + "DQMData/Run 1/HGCAL/Run summary/HGCalValidator/"+hgcalValidator.ticlCandidates.value()+"/"+cand_type[i], + ], PlotFolder( + *_allCandidatesPlots[i], + loopSubFolders=False, + purpose=PlotPurpose.Timing, page=cand_type[i], section="Candidates")) diff --git a/Validation/HGCalValidation/scripts/makeHGCalValidationPlots.py b/Validation/HGCalValidation/scripts/makeHGCalValidationPlots.py index 64ff38ca7cdc2..795366a7d8c50 100755 --- a/Validation/HGCalValidation/scripts/makeHGCalValidationPlots.py +++ b/Validation/HGCalValidation/scripts/makeHGCalValidationPlots.py @@ -19,11 +19,12 @@ layerClustersLabel = 'layerClusters' trackstersLabel = 'tracksters' trackstersWithEdgesLabel = 'trackstersWithEdges' +candidatesLabel = 'candidates' simLabel = 'simulation' allLabel = 'all' collection_choices = [allLabel] -collection_choices.extend([hitCalLabel]+[hitValLabel]+[layerClustersLabel]+[trackstersLabel]+[trackstersWithEdgesLabel]+[simLabel]) +collection_choices.extend([hitCalLabel]+[hitValLabel]+[layerClustersLabel]+[trackstersLabel]+[trackstersWithEdgesLabel]+[candidatesLabel]+[simLabel]) def main(opts): @@ -42,11 +43,11 @@ def main(opts): filenames = [(f, f.replace(".root", "")) for f in opts.files] sample = SimpleSample(opts.subdirprefix[0], opts.html_sample, filenames) - + val = SimpleValidation([sample], opts.outputDir[0], nProc=opts.jobs) if opts.separate: val = SeparateValidation([sample], opts.outputDir[0]) - htmlReport = val.createHtmlReport(validationName=opts.html_validation_name[0]) + htmlReport = val.createHtmlReport(validationName=opts.html_validation_name[0]) #layerClusters def plot_LC(): @@ -78,8 +79,8 @@ def plot_TstEdges(): #caloParticles def plot_CP(): particletypes = {"pion-":"-211", "pion+":"211", "pion0": "111", - "muon-": "-13", "muon+":"13", - "electron-": "-11", "electron+": "11", "photon": "22", + "muon-": "-13", "muon+":"13", + "electron-": "-11", "electron+": "11", "photon": "22", "kaon0L": "310", "kaon0S": "130", "kaon-": "-321", "kaon+": "321"} hgcaloPart = [hgcalPlots.hgcalCaloParticlesPlotter] @@ -100,8 +101,11 @@ def plot_hitCal(): hgchitcalib = [hgcalPlots.hgcalHitCalibPlotter] val.doPlots(hgchitcalib, plotterDrawArgs=drawArgs) + def plotCand(): + ticlcand = [hgcalPlots.hgcalTICLCandPlotter] + val.doPlots(ticlcand, plotterDrawArgs=drawArgs) - plotDict = {hitCalLabel:[plot_hitCal], hitValLabel:[plot_hitVal], layerClustersLabel:[plot_LC], trackstersLabel:[plot_Tst], trackstersWithEdgesLabel:[plot_TstEdges], simLabel:[plot_SC, plot_CP]} + plotDict = {hitCalLabel:[plot_hitCal], hitValLabel:[plot_hitVal], layerClustersLabel:[plot_LC], trackstersLabel:[plot_Tst], trackstersWithEdgesLabel:[plot_TstEdges], simLabel:[plot_SC, plot_CP], candidatesLabel:[plotCand]} if (opts.collection != allLabel): for task in plotDict[opts.collection]: @@ -121,7 +125,7 @@ def plot_hitCal(): if __name__ == "__main__": parser = argparse.ArgumentParser(description="Create set of HGCal validation plots from one or more DQM files.") - parser.add_argument("files", metavar="file", type=str, nargs="+", + parser.add_argument("files", metavar="file", type=str, nargs="+", default = "DQM_V0001_R000000001__Global__CMSSW_X_Y_Z__RECO.root", help="DQM file to plot the validation plots from") parser.add_argument("-o", "--outputDir", type=str, default=["plots1","plots2"], nargs="+", @@ -132,7 +136,7 @@ def plot_hitCal(): help="Disable ratio pads") parser.add_argument("--separate", action="store_true", default = False, help="Save all plots separately instead of grouping them") - parser.add_argument("--png", action="store_true", + parser.add_argument("--png", action="store_true", default = True, help="Save plots in PNG instead of PDF") parser.add_argument("--no-html", action="store_true", default = False, help="Disable HTML page generation") @@ -141,7 +145,7 @@ def plot_hitCal(): parser.add_argument("--html-validation-name", type=str, default=["",""], nargs="+", help="Validation name for HTML page generation (enters to element) (default '')") parser.add_argument("--collection", choices=collection_choices, default=layerClustersLabel, - help="Choose output plots collections among possible choices") + help="Choose output plots collections among possible choices") parser.add_argument("--extended", action="store_true", default = False, help="Include extended set of plots (e.g. bunch of distributions; default off)") parser.add_argument("--jobs", default=0, type=int, diff --git a/Validation/HGCalValidation/src/TICLCandidateValidator.cc b/Validation/HGCalValidation/src/TICLCandidateValidator.cc new file mode 100644 index 0000000000000..a892227d370d2 --- /dev/null +++ b/Validation/HGCalValidation/src/TICLCandidateValidator.cc @@ -0,0 +1,750 @@ +#include +#include +#include + +#include "Validation/HGCalValidation/interface/TICLCandidateValidator.h" +#include "RecoHGCal/TICL/interface/commons.h" + +TICLCandidateValidator::TICLCandidateValidator( + edm::EDGetTokenT> ticlCandidates, + edm::EDGetTokenT> simTICLCandidatesToken, + edm::EDGetTokenT> recoTracksToken, + edm::EDGetTokenT> trackstersToken, + edm::EDGetTokenT associatorMapRtSToken, + edm::EDGetTokenT associatorMapStRToken, + edm::EDGetTokenT associatorMapRtSPUToken, + bool isTICLv5) + : TICLCandidatesToken_(ticlCandidates), + simTICLCandidatesToken_(simTICLCandidatesToken), + recoTracksToken_(recoTracksToken), + trackstersToken_(trackstersToken), + associatorMapRtSToken_(associatorMapRtSToken), + associatorMapStRToken_(associatorMapStRToken), + associatorMapRtSPUToken_(associatorMapRtSPUToken), + isTICLv5_(isTICLv5) {} + +TICLCandidateValidator::~TICLCandidateValidator() {} + +void TICLCandidateValidator::bookCandidatesHistos(DQMStore::IBooker& ibook, + Histograms& histograms, + std::string baseDir) const { + // book CAND histos + histograms.h_tracksters_in_candidate = + ibook.book1D("N of tracksters in candidate", "N of tracksters in candidate", 100, 0, 99); + histograms.h_candidate_raw_energy = + ibook.book1D("Candidates raw energy", "Candidates raw energy;E (GeV)", 250, 0, 250); + histograms.h_candidate_regressed_energy = + ibook.book1D("Candidates regressed energy", "Candidates regressed energy;E (GeV)", 250, 0, 250); + histograms.h_candidate_pT = ibook.book1D("Candidates pT", "Candidates pT;p_{T}", 250, 0, 250); + histograms.h_candidate_charge = ibook.book1D("Candidates charge", "Candidates charge;Charge", 3, -1.5, 1.5); + histograms.h_candidate_pdgId = ibook.book1D("Candidates PDG Id", "Candidates PDG ID", 100, -220, 220); + histograms.h_candidate_partType = ibook.book1D("Candidates type", "Candidates type", 9, -0.5, 8.5); + + // neutral: photon, pion, hadron + const std::vector neutrals{"photons", "neutral_pions", "neutral_hadrons"}; + for (long unsigned int i = 0; i < neutrals.size(); i++) { + ibook.setCurrentFolder(baseDir + "/" + neutrals[i]); + + histograms.h_neut_tracksters_in_candidate.push_back(ibook.book1D("N of tracksters in candidate for " + neutrals[i], + "N of tracksters in candidate for " + neutrals[i], + 100, + 0, + 99)); + histograms.h_neut_candidate_regressed_energy.push_back(ibook.book1D( + neutrals[i] + "candidates regressed energy", neutrals[i] + " candidates regressed energy;E (GeV)", 250, 0, 250)); + histograms.h_neut_candidate_charge.push_back( + ibook.book1D(neutrals[i] + " candidates charge", neutrals[i] + " candidates charge;Charge", 3, -1.5, 1.5)); + histograms.h_neut_candidate_pdgId.push_back( + ibook.book1D(neutrals[i] + " candidates PDG Id", neutrals[i] + " candidates PDG ID", 100, -220, 220)); + histograms.h_neut_candidate_partType.push_back( + ibook.book1D(neutrals[i] + " candidates type", neutrals[i] + " candidates type", 9, -0.5, 8.5)); + + histograms.h_den_fake_neut_energy_candidate.push_back( + ibook.book1D("den_fake_cand_vs_energy_" + neutrals[i], neutrals[i] + " candidates energy;E (GeV)", 50, 0, 250)); + histograms.h_num_fake_neut_energy_candidate_pdgId.push_back(ibook.book1D( + "num_fake_pid_cand_vs_energy_" + neutrals[i], neutrals[i] + " PID fake vs energy;E (GeV)", 50, 0, 250)); + histograms.h_num_fake_neut_energy_candidate_energy.push_back( + ibook.book1D("num_fake_energy_cand_vs_energy_" + neutrals[i], + neutrals[i] + " PID and energy fake vs energy;E (GeV)", + 50, + 0, + 250)); + histograms.h_den_fake_neut_pt_candidate.push_back( + ibook.book1D("den_fake_cand_vs_pt_" + neutrals[i], neutrals[i] + " candidates pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_fake_neut_pt_candidate_pdgId.push_back(ibook.book1D( + "num_fake_pid_cand_vs_pt_" + neutrals[i], neutrals[i] + " PID fake vs pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_fake_neut_pt_candidate_energy.push_back( + ibook.book1D("num_fake_energy_cand_vs_pt_" + neutrals[i], + neutrals[i] + " PID and energy fake vs pT;p_{T} (GeV)", + 50, + 0, + 250)); + histograms.h_den_fake_neut_eta_candidate.push_back( + ibook.book1D("den_fake_cand_vs_eta_" + neutrals[i], neutrals[i] + " candidates eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_fake_neut_eta_candidate_pdgId.push_back(ibook.book1D( + "num_fake_pid_cand_vs_eta_" + neutrals[i], neutrals[i] + " PID fake vs eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_fake_neut_eta_candidate_energy.push_back( + ibook.book1D("num_fake_energy_cand_vs_eta_" + neutrals[i], + neutrals[i] + " PID and energy fake vs eta;#eta (GeV)", + 50, + -3, + 3)); + histograms.h_den_fake_neut_phi_candidate.push_back(ibook.book1D( + "den_fake_cand_vs_phi_" + neutrals[i], neutrals[i] + " candidates phi;#phi (GeV)", 50, -3.14159, 3.14159)); + histograms.h_num_fake_neut_phi_candidate_pdgId.push_back(ibook.book1D( + "num_fake_pid_cand_vs_phi_" + neutrals[i], neutrals[i] + " PID fake vs phi;#phi (GeV)", 50, -3.14159, 3.14159)); + histograms.h_num_fake_neut_phi_candidate_energy.push_back( + ibook.book1D("num_fake_energy_cand_vs_phi_" + neutrals[i], + neutrals[i] + " PID and energy fake vs phi;#phi (GeV)", + 50, + -3.14159, + 3.14159)); + + histograms.h_den_neut_energy_candidate.push_back( + ibook.book1D("den_cand_vs_energy_" + neutrals[i], neutrals[i] + " simCandidates energy;E (GeV)", 50, 0, 250)); + histograms.h_num_neut_energy_candidate_pdgId.push_back( + ibook.book1D("num_pid_cand_vs_energy_" + neutrals[i], + neutrals[i] + " track and PID efficiency vs energy;E (GeV)", + 50, + 0, + 250)); + histograms.h_num_neut_energy_candidate_energy.push_back( + ibook.book1D("num_energy_cand_vs_energy_" + neutrals[i], + neutrals[i] + " track, PID and energy efficiency vs energy;E (GeV)", + 50, + 0, + 250)); + histograms.h_den_neut_pt_candidate.push_back( + ibook.book1D("den_cand_vs_pt_" + neutrals[i], neutrals[i] + " simCandidates pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_neut_pt_candidate_pdgId.push_back(ibook.book1D( + "num_pid_cand_vs_pt_" + neutrals[i], neutrals[i] + " track and PID efficiency vs pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_neut_pt_candidate_energy.push_back( + ibook.book1D("num_energy_cand_vs_pt_" + neutrals[i], + neutrals[i] + " track, PID and energy efficiency vs pT;p_{T} (GeV)", + 50, + 0, + 250)); + histograms.h_den_neut_eta_candidate.push_back( + ibook.book1D("den_cand_vs_eta_" + neutrals[i], neutrals[i] + " simCandidates eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_neut_eta_candidate_pdgId.push_back(ibook.book1D( + "num_pid_cand_vs_eta_" + neutrals[i], neutrals[i] + " track and PID efficiency vs eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_neut_eta_candidate_energy.push_back( + ibook.book1D("num_energy_cand_vs_eta_" + neutrals[i], + neutrals[i] + " track, PID and energy efficiency vs eta;#eta (GeV)", + 50, + -3, + 3)); + histograms.h_den_neut_phi_candidate.push_back(ibook.book1D( + "den_cand_vs_phi_" + neutrals[i], neutrals[i] + " simCandidates phi;#phi (GeV)", 50, -3.14159, 3.14159)); + histograms.h_num_neut_phi_candidate_pdgId.push_back( + ibook.book1D("num_pid_cand_vs_phi_" + neutrals[i], + neutrals[i] + " track and PID efficiency vs phi;#phi (GeV)", + 50, + -3.14159, + 3.14159)); + histograms.h_num_neut_phi_candidate_energy.push_back( + ibook.book1D("num_energy_cand_vs_phi_" + neutrals[i], + neutrals[i] + " track, PID and energy efficiency vs phi;#phi (GeV)", + 50, + -3.14159, + 3.14159)); + } + // charged: electron, muon, hadron + const std::vector charged{"electrons", "muons", "charged_hadrons"}; + for (long unsigned int i = 0; i < charged.size(); i++) { + ibook.setCurrentFolder(baseDir + "/" + charged[i]); + + histograms.h_chg_tracksters_in_candidate.push_back(ibook.book1D( + "N of tracksters in candidate for " + charged[i], "N of tracksters in candidate for " + charged[i], 100, 0, 99)); + histograms.h_chg_candidate_regressed_energy.push_back(ibook.book1D( + charged[i] + "candidates regressed energy", charged[i] + " candidates regressed energy;E (GeV)", 250, 0, 250)); + histograms.h_chg_candidate_charge.push_back( + ibook.book1D(charged[i] + " candidates charge", charged[i] + " candidates charge;Charge", 3, -1.5, 1.5)); + histograms.h_chg_candidate_pdgId.push_back( + ibook.book1D(charged[i] + " candidates PDG Id", charged[i] + " candidates PDG ID", 100, -220, 220)); + histograms.h_chg_candidate_partType.push_back( + ibook.book1D(charged[i] + " candidates type", charged[i] + " candidates type", 9, -0.5, 8.5)); + + histograms.h_den_fake_chg_energy_candidate.push_back( + ibook.book1D("den_fake_cand_vs_energy_" + charged[i], charged[i] + " candidates energy;E (GeV)", 50, 0, 250)); + histograms.h_num_fake_chg_energy_candidate_track.push_back(ibook.book1D( + "num_fake_track_cand_vs_energy_" + charged[i], charged[i] + " track fake vs energy;E (GeV)", 50, 0, 250)); + histograms.h_num_fake_chg_energy_candidate_pdgId.push_back(ibook.book1D( + "num_fake_pid_cand_vs_energy_" + charged[i], charged[i] + " track and PID fake vs energy;E (GeV)", 50, 0, 250)); + histograms.h_num_fake_chg_energy_candidate_energy.push_back( + ibook.book1D("num_fake_energy_cand_vs_energy_" + charged[i], + charged[i] + " track, PID and energy fake vs energy;E (GeV)", + 50, + 0, + 250)); + histograms.h_den_fake_chg_pt_candidate.push_back( + ibook.book1D("den_fake_cand_vs_pt_" + charged[i], charged[i] + " candidates pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_fake_chg_pt_candidate_track.push_back(ibook.book1D( + "num_fake_track_cand_vs_pt_" + charged[i], charged[i] + " track fake vs pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_fake_chg_pt_candidate_pdgId.push_back(ibook.book1D( + "num_fake_pid_cand_vs_pt_" + charged[i], charged[i] + " track and PID fake vs pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_fake_chg_pt_candidate_energy.push_back( + ibook.book1D("num_fake_energy_cand_vs_pt_" + charged[i], + charged[i] + " track, PID and energy fake vs pT;p_{T} (GeV)", + 50, + 0, + 250)); + histograms.h_den_fake_chg_eta_candidate.push_back( + ibook.book1D("den_fake_cand_vs_eta_" + charged[i], charged[i] + " candidates eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_fake_chg_eta_candidate_track.push_back(ibook.book1D( + "num_fake_track_cand_vs_eta_" + charged[i], charged[i] + " track fake vs eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_fake_chg_eta_candidate_pdgId.push_back(ibook.book1D( + "num_fake_pid_cand_vs_eta_" + charged[i], charged[i] + " track and PID fake vs eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_fake_chg_eta_candidate_energy.push_back( + ibook.book1D("num_fake_energy_cand_vs_eta_" + charged[i], + charged[i] + " track, PID and energy fake vs eta;#eta (GeV)", + 50, + -3, + 3)); + histograms.h_den_fake_chg_phi_candidate.push_back(ibook.book1D( + "den_fake_cand_vs_phi_" + charged[i], charged[i] + " candidates phi;#phi (GeV)", 50, -3.14159, 3.14159)); + histograms.h_num_fake_chg_phi_candidate_track.push_back(ibook.book1D("num_fake_track_cand_vs_phi_" + charged[i], + charged[i] + " track fake vs phi;#phi (GeV)", + 50, + -3.14159, + 3.14159)); + histograms.h_num_fake_chg_phi_candidate_pdgId.push_back( + ibook.book1D("num_fake_pid_cand_vs_phi_" + charged[i], + charged[i] + " track and PID fake vs phi;#phi (GeV)", + 50, + -3.14159, + 3.14159)); + histograms.h_num_fake_chg_phi_candidate_energy.push_back( + ibook.book1D("num_fake_energy_cand_vs_phi_" + charged[i], + charged[i] + " track, PID and energy fake vs phi;#phi (GeV)", + 50, + -3.14159, + 3.14159)); + + histograms.h_den_chg_energy_candidate.push_back( + ibook.book1D("den_cand_vs_energy_" + charged[i], charged[i] + " simCandidates energy;E (GeV)", 50, 0, 250)); + histograms.h_num_chg_energy_candidate_track.push_back(ibook.book1D( + "num_track_cand_vs_energy_" + charged[i], charged[i] + " track efficiency vs energy;E (GeV)", 50, 0, 250)); + histograms.h_num_chg_energy_candidate_pdgId.push_back(ibook.book1D( + "num_pid_cand_vs_energy_" + charged[i], charged[i] + " track and PID efficiency vs energy;E (GeV)", 50, 0, 250)); + histograms.h_num_chg_energy_candidate_energy.push_back( + ibook.book1D("num_energy_cand_vs_energy_" + charged[i], + charged[i] + " track, PID and energy efficiency vs energy;E (GeV)", + 50, + 0, + 250)); + histograms.h_den_chg_pt_candidate.push_back( + ibook.book1D("den_cand_vs_pt_" + charged[i], charged[i] + " simCandidates pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_chg_pt_candidate_track.push_back(ibook.book1D( + "num_track_cand_vs_pt_" + charged[i], charged[i] + " track efficiency vs pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_chg_pt_candidate_pdgId.push_back(ibook.book1D( + "num_pid_cand_vs_pt_" + charged[i], charged[i] + " track and PID efficiency vs pT;p_{T} (GeV)", 50, 0, 250)); + histograms.h_num_chg_pt_candidate_energy.push_back( + ibook.book1D("num_energy_cand_vs_pt_" + charged[i], + charged[i] + " track, PID and energy efficiency vs pT;p_{T} (GeV)", + 50, + 0, + 250)); + histograms.h_den_chg_eta_candidate.push_back( + ibook.book1D("den_cand_vs_eta_" + charged[i], charged[i] + " simCandidates eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_chg_eta_candidate_track.push_back(ibook.book1D( + "num_track_cand_vs_eta_" + charged[i], charged[i] + " track efficiency vs eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_chg_eta_candidate_pdgId.push_back(ibook.book1D( + "num_pid_cand_vs_eta_" + charged[i], charged[i] + " track and PID efficiency vs eta;#eta (GeV)", 50, -3, 3)); + histograms.h_num_chg_eta_candidate_energy.push_back( + ibook.book1D("num_energy_cand_vs_eta_" + charged[i], + charged[i] + " track, PID and energy efficiency vs eta;#eta (GeV)", + 50, + -3, + 3)); + histograms.h_den_chg_phi_candidate.push_back(ibook.book1D( + "den_cand_vs_phi_" + charged[i], charged[i] + " simCandidates phi;#phi (GeV)", 50, -3.14159, 3.14159)); + histograms.h_num_chg_phi_candidate_track.push_back(ibook.book1D("num_track_cand_vs_phi_" + charged[i], + charged[i] + " track efficiency vs phi;#phi (GeV)", + 50, + -3.14159, + 3.14159)); + histograms.h_num_chg_phi_candidate_pdgId.push_back( + ibook.book1D("num_pid_cand_vs_phi_" + charged[i], + charged[i] + " track and PID efficiency vs phi;#phi (GeV)", + 50, + -3.14159, + 3.14159)); + histograms.h_num_chg_phi_candidate_energy.push_back( + ibook.book1D("num_energy_cand_vs_phi_" + charged[i], + charged[i] + " track, PID and energy efficiency vs phi;#phi (GeV)", + 50, + -3.14159, + 3.14159)); + } +} + +void TICLCandidateValidator::fillCandidateHistos(const edm::Event& event, + const Histograms& histograms, + edm::Handle simTrackstersCP_h) const { + auto TICLCandidates = event.get(TICLCandidatesToken_); + + edm::Handle> simTICLCandidates_h; + event.getByToken(simTICLCandidatesToken_, simTICLCandidates_h); + auto simTICLCandidates = *simTICLCandidates_h; + + edm::Handle> recoTracks_h; + event.getByToken(recoTracksToken_, recoTracks_h); + auto recoTracks = *recoTracks_h; + + edm::Handle> Tracksters_h; + event.getByToken(trackstersToken_, Tracksters_h); + auto trackstersMerged = *Tracksters_h; + + edm::Handle mergeTsRecoToSim_h; + event.getByToken(associatorMapRtSToken_, mergeTsRecoToSim_h); + auto const& mergeTsRecoToSimMap = *mergeTsRecoToSim_h; + + edm::Handle mergeTsSimToReco_h; + event.getByToken(associatorMapStRToken_, mergeTsSimToReco_h); + auto const& mergeTsSimToRecoMap = *mergeTsSimToReco_h; + + edm::Handle mergeTsRecoToSimPU_h; + event.getByToken(associatorMapRtSPUToken_, mergeTsRecoToSimPU_h); + auto const& mergeTsRecoToSimPUMap = *mergeTsRecoToSimPU_h; + + // candidates plots + for (const auto& cand : TICLCandidates) { + histograms.h_tracksters_in_candidate->Fill(cand.tracksters().size()); + histograms.h_candidate_raw_energy->Fill(cand.rawEnergy()); + histograms.h_candidate_regressed_energy->Fill(cand.energy()); + histograms.h_candidate_pT->Fill(cand.pt()); + histograms.h_candidate_charge->Fill(cand.charge()); + histograms.h_candidate_pdgId->Fill(cand.pdgId()); + const auto& arr = cand.idProbabilities(); + histograms.h_candidate_partType->Fill(std::max_element(arr.begin(), arr.end()) - arr.begin()); + } + + std::vector chargedCandidates; + std::vector neutralCandidates; + chargedCandidates.reserve(simTICLCandidates.size()); + neutralCandidates.reserve(simTICLCandidates.size()); + + for (size_t i = 0; i < simTICLCandidates.size(); ++i) { + const auto& simCand = simTICLCandidates[i]; + const auto particleType = ticl::tracksterParticleTypeFromPdgId(simCand.pdgId(), simCand.charge()); + if (particleType == ticl::Trackster::ParticleType::electron or + particleType == ticl::Trackster::ParticleType::muon or + particleType == ticl::Trackster::ParticleType::charged_hadron) + chargedCandidates.emplace_back(i); + else if (particleType == ticl::Trackster::ParticleType::photon or + particleType == ticl::Trackster::ParticleType::neutral_pion or + particleType == ticl::Trackster::ParticleType::neutral_hadron) + neutralCandidates.emplace_back(i); + // should consider also unknown ? + } + + chargedCandidates.shrink_to_fit(); + neutralCandidates.shrink_to_fit(); + + for (const auto i : chargedCandidates) { + const auto& simCand = simTICLCandidates[i]; + auto index = std::log2(int(ticl::tracksterParticleTypeFromPdgId(simCand.pdgId(), 1))); + /* 11 (type 1) becomes 0 + * 13 (type 2) becomes 1 + * 211 (type 4) becomes 2 + */ + int32_t simCandTrackIdx = -1; + if (simCand.trackPtr().get() != nullptr) + simCandTrackIdx = simCand.trackPtr().get() - edm::Ptr(recoTracks_h, 0).get(); + else { + // no reco track, but simCand is charged + continue; + } + if (simCand.trackPtr().get()->pt() < 1 or simCand.trackPtr().get()->missingOuterHits() > 5 or + not simCand.trackPtr().get()->quality(reco::TrackBase::highPurity)) + continue; + + // +1 to all denominators + histograms.h_den_chg_energy_candidate[index]->Fill(simCand.rawEnergy()); + histograms.h_den_chg_pt_candidate[index]->Fill(simCand.pt()); + histograms.h_den_chg_eta_candidate[index]->Fill(simCand.eta()); + histograms.h_den_chg_phi_candidate[index]->Fill(simCand.phi()); + + int32_t cand_idx = -1; + const edm::Ref stsRef(simTrackstersCP_h, i); + const auto ts_iter = mergeTsSimToRecoMap.find(stsRef); + float shared_energy = 0.; + // search for reco cand associated + if (ts_iter != mergeTsSimToRecoMap.end()) { + const auto& tsAssoc = (ts_iter->val); + std::vector MergeTracksters_simToReco; + std::vector MergeTracksters_simToReco_score; + std::vector MergeTracksters_simToReco_sharedE; + MergeTracksters_simToReco.reserve(tsAssoc.size()); + MergeTracksters_simToReco_score.reserve(tsAssoc.size()); + MergeTracksters_simToReco_sharedE.reserve(tsAssoc.size()); + for (auto& ts : tsAssoc) { + auto ts_id = (ts.first).get() - (edm::Ref(Tracksters_h, 0)).get(); + MergeTracksters_simToReco.push_back(ts_id); + MergeTracksters_simToReco_score.push_back(ts.second.second); + MergeTracksters_simToReco_sharedE.push_back(ts.second.first); + } + auto min_idx = std::min_element(MergeTracksters_simToReco_score.begin(), MergeTracksters_simToReco_score.end()); + if (*min_idx != 1) { + cand_idx = MergeTracksters_simToReco[min_idx - MergeTracksters_simToReco_score.begin()]; + shared_energy = MergeTracksters_simToReco_sharedE[min_idx - MergeTracksters_simToReco_score.begin()]; + } + } + + // no reco associated to sim + if (cand_idx == -1) + continue; + + auto& recoCand = TICLCandidates[cand_idx]; + if (isTICLv5_) { + // cand_idx is the tsMerge index, find the ts in the candidates collection + auto const tsPtr = edm::Ptr(Tracksters_h, cand_idx); + auto cand_it = std::find_if(TICLCandidates.begin(), TICLCandidates.end(), [tsPtr](TICLCandidate const& cand) { + if (!cand.tracksters().empty()) + return cand.tracksters()[0] == tsPtr; + else + return false; + }); + if (cand_it != TICLCandidates.end()) + recoCand = *cand_it; + else + continue; + } + + if (recoCand.trackPtr().get() != nullptr) { + const auto candTrackIdx = recoCand.trackPtr().get() - edm::Ptr(recoTracks_h, 0).get(); + if (simCandTrackIdx == candTrackIdx) { + // +1 to track num + histograms.h_num_chg_energy_candidate_track[index]->Fill(simCand.rawEnergy()); + histograms.h_num_chg_pt_candidate_track[index]->Fill(simCand.pt()); + histograms.h_num_chg_eta_candidate_track[index]->Fill(simCand.eta()); + histograms.h_num_chg_phi_candidate_track[index]->Fill(simCand.phi()); + } else { + continue; + } + } else { + continue; + } + + //step 2: PID + if (simCand.pdgId() == recoCand.pdgId()) { + // +1 to num pdg id + histograms.h_num_chg_energy_candidate_pdgId[index]->Fill(simCand.rawEnergy()); + histograms.h_num_chg_pt_candidate_pdgId[index]->Fill(simCand.pt()); + histograms.h_num_chg_eta_candidate_pdgId[index]->Fill(simCand.eta()); + histograms.h_num_chg_phi_candidate_pdgId[index]->Fill(simCand.phi()); + + //step 3: energy + if (shared_energy / simCand.rawEnergy() > 0.5) { + // +1 to ene num + histograms.h_num_chg_energy_candidate_energy[index]->Fill(simCand.rawEnergy()); + histograms.h_num_chg_pt_candidate_energy[index]->Fill(simCand.pt()); + histograms.h_num_chg_eta_candidate_energy[index]->Fill(simCand.eta()); + histograms.h_num_chg_phi_candidate_energy[index]->Fill(simCand.phi()); + } + } + } + + for (const auto i : neutralCandidates) { + const auto& simCand = simTICLCandidates[i]; + auto index = int(ticl::tracksterParticleTypeFromPdgId(simCand.pdgId(), 0)) / 2; + /* 22 (type 0) becomes 0 + * 111 (type 3) becomes 1 + * 130 (type 5) becomes 2 + */ + histograms.h_den_neut_energy_candidate[index]->Fill(simCand.rawEnergy()); + histograms.h_den_neut_pt_candidate[index]->Fill(simCand.pt()); + histograms.h_den_neut_eta_candidate[index]->Fill(simCand.eta()); + histograms.h_den_neut_phi_candidate[index]->Fill(simCand.phi()); + + int32_t cand_idx = -1; + const edm::Ref stsRef(simTrackstersCP_h, i); + const auto ts_iter = mergeTsSimToRecoMap.find(stsRef); + float shared_energy = 0.; + // search for reco cand associated + if (ts_iter != mergeTsSimToRecoMap.end()) { + const auto& tsAssoc = (ts_iter->val); + std::vector MergeTracksters_simToReco; + std::vector MergeTracksters_simToReco_score; + std::vector MergeTracksters_simToReco_sharedE; + MergeTracksters_simToReco.reserve(tsAssoc.size()); + MergeTracksters_simToReco_score.reserve(tsAssoc.size()); + MergeTracksters_simToReco_sharedE.reserve(tsAssoc.size()); + for (auto& ts : tsAssoc) { + auto ts_id = (ts.first).get() - (edm::Ref(Tracksters_h, 0)).get(); + MergeTracksters_simToReco.push_back(ts_id); + MergeTracksters_simToReco_score.push_back(ts.second.second); + MergeTracksters_simToReco_sharedE.push_back(ts.second.first); + } + auto min_idx = std::min_element(MergeTracksters_simToReco_score.begin(), MergeTracksters_simToReco_score.end()); + if (*min_idx != 1) { + cand_idx = MergeTracksters_simToReco[min_idx - MergeTracksters_simToReco_score.begin()]; + shared_energy = MergeTracksters_simToReco_sharedE[min_idx - MergeTracksters_simToReco_score.begin()]; + } + } + + // no reco associated to sim + if (cand_idx == -1) + continue; + + auto& recoCand = TICLCandidates[cand_idx]; + if (isTICLv5_) { + // cand_idx is the tsMerge index, find the ts in the candidates collection + auto const tsPtr = edm::Ptr(Tracksters_h, cand_idx); + auto cand_it = std::find_if(TICLCandidates.begin(), TICLCandidates.end(), [tsPtr](TICLCandidate const& cand) { + if (!cand.tracksters().empty()) + return cand.tracksters()[0] == tsPtr; + else + return false; + }); + if (cand_it != TICLCandidates.end()) + recoCand = *cand_it; + else + continue; + } + + if (recoCand.trackPtr().get() != nullptr) + continue; + + //step 2: PID + if (simCand.pdgId() == recoCand.pdgId()) { + // +1 to num pdg id + histograms.h_num_neut_energy_candidate_pdgId[index]->Fill(simCand.rawEnergy()); + histograms.h_num_neut_pt_candidate_pdgId[index]->Fill(simCand.pt()); + histograms.h_num_neut_eta_candidate_pdgId[index]->Fill(simCand.eta()); + histograms.h_num_neut_phi_candidate_pdgId[index]->Fill(simCand.phi()); + + //step 3: energy + if (shared_energy / simCand.rawEnergy() > 0.5) { + // +1 to ene num + histograms.h_num_neut_energy_candidate_energy[index]->Fill(simCand.rawEnergy()); + histograms.h_num_neut_pt_candidate_energy[index]->Fill(simCand.pt()); + histograms.h_num_neut_eta_candidate_energy[index]->Fill(simCand.eta()); + histograms.h_num_neut_phi_candidate_energy[index]->Fill(simCand.phi()); + } + } + } + + // FAKE rate + chargedCandidates.clear(); + neutralCandidates.clear(); + chargedCandidates.reserve(TICLCandidates.size()); + neutralCandidates.reserve(TICLCandidates.size()); + + auto isCharged = [](int pdgId) { + pdgId = std::abs(pdgId); + return (pdgId == 11 or pdgId == 211 or pdgId == 13); + }; + + for (size_t i = 0; i < TICLCandidates.size(); ++i) { + const auto& cand = TICLCandidates[i]; + const auto& charged = isCharged(cand.pdgId()); + if (charged) + chargedCandidates.emplace_back(i); + else + neutralCandidates.emplace_back(i); + + // should consider also unknown ? + } + + chargedCandidates.shrink_to_fit(); + neutralCandidates.shrink_to_fit(); + + // loop on charged + for (const auto i : chargedCandidates) { + const auto& cand = TICLCandidates[i]; + auto index = std::log2(int(ticl::tracksterParticleTypeFromPdgId(cand.pdgId(), 1))); + /* 11 (type 1) becomes 0 + * 13 (type 2) becomes 1 + * 211 (type 4) becomes 2 + */ + int32_t candTrackIdx = -1; + candTrackIdx = cand.trackPtr().get() - edm::Ptr(recoTracks_h, 0).get(); + + if (cand.tracksters().empty()) + continue; + + // i is the candidate idx == ts idx only in v4, find ts_idx in v5 + auto mergeTs_id = i; + if (isTICLv5_) { + mergeTs_id = cand.tracksters()[0].get() - edm::Ptr(Tracksters_h, 0).get(); + } + // remove PU tracksters + const edm::Ref tsRef(Tracksters_h, mergeTs_id); + auto const sts_iterPU = mergeTsRecoToSimPUMap.find(tsRef); + if (sts_iterPU != mergeTsRecoToSimPUMap.end()) { + const auto& stsPUAssociated = sts_iterPU->val; + if (stsPUAssociated[0].second.first / (*Tracksters_h)[mergeTs_id].raw_energy() > 0.95) + continue; + } + + // +1 to all denominators + histograms.h_den_fake_chg_energy_candidate[index]->Fill(cand.rawEnergy()); + histograms.h_den_fake_chg_pt_candidate[index]->Fill(cand.pt()); + histograms.h_den_fake_chg_eta_candidate[index]->Fill(cand.eta()); + histograms.h_den_fake_chg_phi_candidate[index]->Fill(cand.phi()); + + histograms.h_chg_tracksters_in_candidate[index]->Fill(cand.tracksters().size()); + histograms.h_chg_candidate_regressed_energy[index]->Fill(cand.energy()); + histograms.h_chg_candidate_charge[index]->Fill(cand.charge()); + histograms.h_chg_candidate_pdgId[index]->Fill(cand.pdgId()); + const auto& arr = cand.idProbabilities(); + histograms.h_chg_candidate_partType[index]->Fill(std::max_element(arr.begin(), arr.end()) - arr.begin()); + + int32_t simCand_idx = -1; + const auto sts_iter = mergeTsRecoToSimMap.find(tsRef); + float shared_energy = 0.; + // search for reco cand associated + if (sts_iter != mergeTsRecoToSimMap.end()) { + const auto& stsAssoc = (sts_iter->val); + std::vector MergeTracksters_recoToSim; + std::vector MergeTracksters_recoToSim_score; + std::vector MergeTracksters_recoToSim_sharedE; + MergeTracksters_recoToSim.reserve(stsAssoc.size()); + MergeTracksters_recoToSim_score.reserve(stsAssoc.size()); + MergeTracksters_recoToSim_sharedE.reserve(stsAssoc.size()); + for (auto& sts : stsAssoc) { + auto sts_id = (sts.first).get() - (edm::Ref(simTrackstersCP_h, 0)).get(); + MergeTracksters_recoToSim.push_back(sts_id); + MergeTracksters_recoToSim_score.push_back(sts.second.second); + MergeTracksters_recoToSim_sharedE.push_back(sts.second.first); + } + auto min_idx = std::min_element(MergeTracksters_recoToSim_score.begin(), MergeTracksters_recoToSim_score.end()); + if (*min_idx != 1) { + simCand_idx = MergeTracksters_recoToSim[min_idx - MergeTracksters_recoToSim_score.begin()]; + shared_energy = MergeTracksters_recoToSim_sharedE[min_idx - MergeTracksters_recoToSim_score.begin()]; + } + } + + if (simCand_idx == -1) + continue; + + const auto& simCand = simTICLCandidates[simCand_idx]; + if (simCand.trackPtr().get() != nullptr) { + const auto simCandTrackIdx = simCand.trackPtr().get() - edm::Ptr(recoTracks_h, 0).get(); + if (simCandTrackIdx != candTrackIdx) { + // fake += 1 + histograms.h_num_fake_chg_energy_candidate_track[index]->Fill(cand.rawEnergy()); + histograms.h_num_fake_chg_pt_candidate_track[index]->Fill(cand.pt()); + histograms.h_num_fake_chg_eta_candidate_track[index]->Fill(cand.eta()); + histograms.h_num_fake_chg_phi_candidate_track[index]->Fill(cand.phi()); + continue; + } + } else { + // fake += 1 + histograms.h_num_fake_chg_energy_candidate_track[index]->Fill(cand.rawEnergy()); + histograms.h_num_fake_chg_pt_candidate_track[index]->Fill(cand.pt()); + histograms.h_num_fake_chg_eta_candidate_track[index]->Fill(cand.eta()); + histograms.h_num_fake_chg_phi_candidate_track[index]->Fill(cand.phi()); + continue; + } + + //step 2: PID + if (simCand.pdgId() != cand.pdgId()) { + // +1 to num fake pdg id + histograms.h_num_fake_chg_energy_candidate_pdgId[index]->Fill(cand.rawEnergy()); + histograms.h_num_fake_chg_pt_candidate_pdgId[index]->Fill(cand.pt()); + histograms.h_num_fake_chg_eta_candidate_pdgId[index]->Fill(cand.eta()); + histograms.h_num_fake_chg_phi_candidate_pdgId[index]->Fill(cand.phi()); + continue; + } + + //step 3: energy + if (shared_energy / simCand.rawEnergy() < 0.5) { + // +1 to ene num + histograms.h_num_fake_chg_energy_candidate_energy[index]->Fill(cand.rawEnergy()); + histograms.h_num_fake_chg_pt_candidate_energy[index]->Fill(cand.pt()); + histograms.h_num_fake_chg_eta_candidate_energy[index]->Fill(cand.eta()); + histograms.h_num_fake_chg_phi_candidate_energy[index]->Fill(cand.phi()); + } + } + // loop on neutrals + for (const auto i : neutralCandidates) { + const auto& cand = TICLCandidates[i]; + auto index = int(ticl::tracksterParticleTypeFromPdgId(cand.pdgId(), 0)) / 2; + /* 22 (type 0) becomes 0 + * 111 (type 3) becomes 1 + * 130 (type 5) becomes 2 + */ + + if (cand.tracksters().empty()) + continue; + + // i is the candidate idx == ts idx only in v4, find ts_idx in v5 + auto mergeTs_id = i; + if (isTICLv5_) { + mergeTs_id = cand.tracksters()[0].get() - edm::Ptr(Tracksters_h, 0).get(); + } + // remove PU tracksters + const edm::Ref tsRef(Tracksters_h, mergeTs_id); + auto const sts_iterPU = mergeTsRecoToSimPUMap.find(tsRef); + if (sts_iterPU != mergeTsRecoToSimPUMap.end()) { + const auto& stsPUAssociated = sts_iterPU->val; + if (stsPUAssociated[0].second.first / (*Tracksters_h)[mergeTs_id].raw_energy() > 0.95) + continue; + } + + // +1 to all denominators + histograms.h_den_fake_neut_energy_candidate[index]->Fill(cand.rawEnergy()); + histograms.h_den_fake_neut_pt_candidate[index]->Fill(cand.pt()); + histograms.h_den_fake_neut_eta_candidate[index]->Fill(cand.eta()); + histograms.h_den_fake_neut_phi_candidate[index]->Fill(cand.phi()); + + histograms.h_neut_tracksters_in_candidate[index]->Fill(cand.tracksters().size()); + histograms.h_neut_candidate_regressed_energy[index]->Fill(cand.energy()); + histograms.h_neut_candidate_charge[index]->Fill(cand.charge()); + histograms.h_neut_candidate_pdgId[index]->Fill(cand.pdgId()); + const auto& arr = cand.idProbabilities(); + histograms.h_neut_candidate_partType[index]->Fill(std::max_element(arr.begin(), arr.end()) - arr.begin()); + + int32_t simCand_idx = -1; + const auto sts_iter = mergeTsRecoToSimMap.find(tsRef); + float shared_energy = 0.; + // search for reco cand associated + if (sts_iter != mergeTsRecoToSimMap.end()) { + const auto& stsAssoc = (sts_iter->val); + std::vector MergeTracksters_recoToSim; + std::vector MergeTracksters_recoToSim_score; + std::vector MergeTracksters_recoToSim_sharedE; + MergeTracksters_recoToSim.reserve(stsAssoc.size()); + MergeTracksters_recoToSim_score.reserve(stsAssoc.size()); + MergeTracksters_recoToSim_sharedE.reserve(stsAssoc.size()); + for (auto& sts : stsAssoc) { + auto sts_id = (sts.first).get() - (edm::Ref(simTrackstersCP_h, 0)).get(); + MergeTracksters_recoToSim.push_back(sts_id); + MergeTracksters_recoToSim_score.push_back(sts.second.second); + MergeTracksters_recoToSim_sharedE.push_back(sts.second.first); + } + auto min_idx = std::min_element(MergeTracksters_recoToSim_score.begin(), MergeTracksters_recoToSim_score.end()); + if (*min_idx != 1) { + simCand_idx = MergeTracksters_recoToSim[min_idx - MergeTracksters_recoToSim_score.begin()]; + shared_energy = MergeTracksters_recoToSim_sharedE[min_idx - MergeTracksters_recoToSim_score.begin()]; + } + } + + if (simCand_idx == -1) + continue; + + const auto& simCand = simTICLCandidates[simCand_idx]; + + //step 2: PID + if (simCand.pdgId() != cand.pdgId()) { + // +1 to num fake pdg id + histograms.h_num_fake_neut_energy_candidate_pdgId[index]->Fill(cand.rawEnergy()); + histograms.h_num_fake_neut_pt_candidate_pdgId[index]->Fill(cand.pt()); + histograms.h_num_fake_neut_eta_candidate_pdgId[index]->Fill(cand.eta()); + histograms.h_num_fake_neut_phi_candidate_pdgId[index]->Fill(cand.phi()); + continue; + } + + //step 3: energy + if (shared_energy / simCand.rawEnergy() < 0.5) { + // +1 to ene num + histograms.h_num_fake_neut_energy_candidate_energy[index]->Fill(cand.rawEnergy()); + histograms.h_num_fake_neut_pt_candidate_energy[index]->Fill(cand.pt()); + histograms.h_num_fake_neut_eta_candidate_energy[index]->Fill(cand.eta()); + histograms.h_num_fake_neut_phi_candidate_energy[index]->Fill(cand.phi()); + } + } +}