50 #include <unordered_map>
53 #include "CLHEP/Units/SystemOfUnits.h"
84 const std::vector<edm::EDGetTokenT<reco::TrackToTrackingParticleAssociator>>
associators_;
92 uint64_t hashSimInfo(
const T& simTruth,
size_t i = 0) {
94 uint64_t trackid = simTruth.g4Tracks()[
i].trackId();
95 return ((
evtid << 3) + 23401923) ^ trackid;
100 : superClusterThreshold_(conf.getParameter<double>(
"superClusterThreshold")),
101 neutralEMThreshold_(conf.getParameter<double>(
"neutralEMThreshold")),
102 neutralHADThreshold_(conf.getParameter<double>(
"neutralHADThreshold")),
103 useTiming_(conf.existsAs<
edm::
InputTag>(
"trackTimeValueMap")),
104 useTimingQuality_(conf.existsAs<
edm::
InputTag>(
"trackTimeQualityMap")),
105 timingQualityThreshold_(useTimingQuality_ ? conf.getParameter<double>(
"timingQualityThreshold") : -99.),
110 srcTrackTime_(useTiming_ ? consumes<
edm::ValueMap<
float>>(conf.getParameter<
edm::
InputTag>(
"trackTimeValueMap"))
112 srcTrackTimeError_(useTiming_
115 srcTrackTimeQuality_(useTimingQuality_
118 srcGsfTrackTime_(useTiming_
121 srcGsfTrackTimeError_(
122 useTiming_ ? consumes<
edm::ValueMap<
float>>(conf.getParameter<
edm::
InputTag>(
"gsfTrackTimeErrorMap"))
124 srcGsfTrackTimeQuality_(
125 useTimingQuality_ ? consumes<
edm::ValueMap<
float>>(conf.getParameter<
edm::
InputTag>(
"gsfTrackTimeQualityMap"))
130 simClusters_(consumes<
std::vector<
reco::PFCluster>>(conf.getParameter<
edm::
InputTag>(
"simClustersSrc"))),
133 [this](
const edm::
InputTag&
tag) {
return this->consumes<reco::TrackToTrackingParticleAssociator>(
tag); })) {
134 produces<reco::PFBlockCollection>();
135 produces<reco::SuperClusterCollection>(
"perfect");
136 produces<reco::PFCandidateCollection>();
141 std::vector<edm::Handle<reco::TrackToTrackingParticleAssociator>>
associators;
152 std::unordered_set<unsigned> PFTrackToGeneralTrack;
155 PFTrackToGeneralTrack.insert(ptr->trackRef().key());
165 std::unordered_set<unsigned> MuonTrackToGeneralTrack;
166 for (
auto const&
mu : *
muons.product()) {
169 MuonTrackToGeneralTrack.insert(muTrkRef.
key());
203 const std::vector<reco::PFCluster>& SimClusters = *SimClustersH;
205 std::unordered_map<uint64_t, size_t> hashToSimCluster;
207 for (
unsigned i = 0;
i < SimClustersTruth.size(); ++
i) {
208 const auto& simTruth = SimClustersTruth[
i];
209 hashToSimCluster[hashSimInfo(simTruth)] =
i;
213 std::vector<reco::RecoToSimCollection> associatedTracks, associatedTracksGsf;
215 associatedTracks.emplace_back(
associator->associateRecoToSim(TrackCollectionH, TPCollectionH));
221 auto superclusters = std::make_unique<reco::SuperClusterCollection>();
222 auto blocks = std::make_unique<reco::PFBlockCollection>();
223 std::unordered_map<size_t, size_t> simCluster2Block;
224 std::unordered_map<size_t, size_t> simCluster2BlockIndex;
225 std::unordered_multimap<size_t, size_t> caloParticle2SimCluster;
226 std::vector<int> caloParticle2SuperCluster;
227 for (
unsigned icp = 0; icp < CaloParticles.size(); ++icp) {
230 const auto& simclusters = CaloParticles[icp].simClusters();
233 std::vector<size_t> good_simclusters;
234 for (
unsigned isc = 0; isc < simclusters.size(); ++isc) {
235 auto simc = simclusters[isc];
240 good_simclusters.push_back(isc);
241 etot += clusterRef->energy();
242 pttot += clusterRef->pt();
244 block.addElement(bec.get());
245 simCluster2Block[simc.key()] = icp;
246 simCluster2BlockIndex[simc.key()] = bec->index();
247 caloParticle2SimCluster.emplace(CaloParticles[icp].g4Tracks()[0].trackId(), simc.key());
253 caloParticle2SuperCluster.push_back(-1);
255 caloParticle2SuperCluster[icp] = superclusters->size();
260 for (
auto idx : good_simclusters) {
268 superclusters->emplace_back(etot, seedpos,
seed,
clusters);
273 auto superClustersHandle = evt.
put(
std::move(superclusters),
"perfect");
278 usedSimCluster(SimClusters.size(),
false);
280 auto candidates = std::make_unique<reco::PFCandidateCollection>();
285 if (PFTrackToGeneralTrack.count(itk) == 0)
293 if (assoc_tps == associatedTracks.back().end())
296 const auto&
matches = assoc_tps->val;
299 const auto charge = tkRef->charge();
300 const auto three_mom = tkRef->momentum();
301 constexpr
double mpion2 = 0.13957 * 0.13957;
327 candidate.setTime((*trackTimeH)[tkRef], (*trackTimeErrH)[tkRef]);
329 candidate.setTime(0., -1.);
336 if (hashToSimCluster.count(
hash)) {
337 auto simcHash = hashToSimCluster[
hash];
339 if (!usedSimCluster[simcHash]) {
340 if (simCluster2Block.count(simcHash) && simCluster2BlockIndex.count(simcHash)) {
341 size_t block = simCluster2Block.find(simcHash)->second;
342 size_t blockIdx = simCluster2BlockIndex.find(simcHash)->second;
344 candidate.addElementInBlock(blockRef,
blockIdx);
345 usedSimCluster[simcHash] =
true;
348 if (absPdgId == 11) {
349 if (simCluster2Block.count(simcHash)) {
350 auto block_index = simCluster2Block.find(simcHash)->second;
351 auto supercluster_index = caloParticle2SuperCluster[block_index];
352 if (supercluster_index != -1) {
354 for (
const auto& elem : blockRef->elements()) {
355 const auto& ref = elem.clusterRef();
356 if (!usedSimCluster[ref.key()]) {
357 candidate.addElementInBlock(blockRef, elem.
index());
358 usedSimCluster[ref.key()] =
true;
372 if (caloParticle2SimCluster.count(
match.first->g4Tracks()[0].trackId())) {
373 auto range = caloParticle2SimCluster.equal_range(
match.first->g4Tracks()[0].trackId());
374 for (
auto it =
range.first; it !=
range.second; ++it) {
375 if (!usedSimCluster[it->second]) {
376 usedSimCluster[it->second] =
true;
377 if (simCluster2Block.find(it->second) != simCluster2Block.end()) {
378 size_t block = simCluster2Block.find(it->second)->second;
379 size_t blockIdx = simCluster2BlockIndex.find(it->second)->second;
381 candidate.addElementInBlock(blockRef,
blockIdx);
387 usedTrack[tkRef.key()] =
true;
389 if (MuonTrackToGeneralTrack.count(itk) || absPdgId == 13)
395 const auto& theblocks = *blocksHandle;
396 for (
unsigned ibl = 0; ibl < theblocks.size(); ++ibl) {
398 const auto&
elements = theblocks[ibl].elements();
400 const auto& ref = elem.clusterRef();
401 const auto& simtruth = SimClustersTruth[ref.key()];
403 if (!usedSimCluster[ref.key()]) {
404 auto absPdgId =
std::abs(simtruth.pdgId());
413 const auto three_mom = (ref->position() -
math::XYZPoint(0, 0, 0)).
unit() * ref->correctedEnergy();
415 candidates->emplace_back(0, clu_p4, part_type);
417 candidate.addElementInBlock(blref, elem.
index());