5 #include "CLHEP/Units/SystemOfUnits.h"
42 #include <unordered_map>
72 const std::vector<edm::EDGetTokenT<reco::TrackToTrackingParticleAssociator>>
associators_;
81 desc.
add<
edm::InputTag>(
"simClustersSrc", {
"particleFlowClusterHGCalFromSimCl"});
83 desc.
add<std::vector<edm::InputTag>>(
"associators",
85 {
"quickTrackAssociatorByHits"},
87 desc.
add<
edm::InputTag>(
"pfRecTrackSrc", {
"hgcalTrackCollection",
"TracksInHGCal"});
89 desc.
add<
double>(
"neutralEMThreshold", 0.25);
91 desc.
add<
double>(
"superClusterThreshold", 4.0);
94 desc.
add<
double>(
"neutralHADThreshold", 0.25);
101 desc.
addOptional<
double>(
"timingQualityThreshold");
106 descriptions.
add(
"simPFProducer", desc);
111 template <
typename T>
112 uint64_t hashSimInfo(
const T& simTruth,
size_t i = 0) {
114 uint64_t trackid = simTruth.g4Tracks()[
i].trackId();
115 return ((evtid << 3) + 23401923) ^ trackid;
120 : superClusterThreshold_(conf.getParameter<double>(
"superClusterThreshold")),
121 neutralEMThreshold_(conf.getParameter<double>(
"neutralEMThreshold")),
122 neutralHADThreshold_(conf.getParameter<double>(
"neutralHADThreshold")),
123 useTiming_(conf.existsAs<edm::
InputTag>(
"trackTimeValueMap")),
124 useTimingQuality_(conf.existsAs<edm::
InputTag>(
"trackTimeQualityMap")),
125 timingQualityThreshold_(useTimingQuality_ ? conf.getParameter<double>(
"timingQualityThreshold") : -99.),
126 pfRecTracks_(consumes<edm::
View<
reco::PFRecTrack>>(conf.getParameter<edm::
InputTag>(
"pfRecTrackSrc"))),
127 tracks_(consumes<edm::
View<
reco::Track>>(conf.getParameter<edm::
InputTag>(
"trackSrc"))),
128 gsfTracks_(consumes<edm::
View<
reco::Track>>(conf.getParameter<edm::
InputTag>(
"gsfTrackSrc"))),
130 srcTrackTime_(useTiming_ ? consumes<edm::ValueMap<float>>(conf.getParameter<edm::
InputTag>(
"trackTimeValueMap"))
131 : edm::EDGetTokenT<edm::ValueMap<float>>()),
132 srcTrackTimeError_(useTiming_
133 ? consumes<edm::ValueMap<float>>(conf.getParameter<edm::
InputTag>(
"trackTimeErrorMap"))
134 : edm::EDGetTokenT<edm::ValueMap<float>>()),
135 srcTrackTimeQuality_(useTimingQuality_
136 ? consumes<edm::ValueMap<float>>(conf.getParameter<edm::
InputTag>(
"trackTimeQualityMap"))
137 : edm::EDGetTokenT<edm::ValueMap<float>>()),
138 srcGsfTrackTime_(useTiming_
139 ? consumes<edm::ValueMap<float>>(conf.getParameter<edm::
InputTag>(
"gsfTrackTimeValueMap"))
140 : edm::EDGetTokenT<edm::ValueMap<float>>()),
141 srcGsfTrackTimeError_(
142 useTiming_ ? consumes<edm::ValueMap<float>>(conf.getParameter<edm::
InputTag>(
"gsfTrackTimeErrorMap"))
143 : edm::EDGetTokenT<edm::ValueMap<float>>()),
144 srcGsfTrackTimeQuality_(
145 useTimingQuality_ ? consumes<edm::ValueMap<float>>(conf.getParameter<edm::
InputTag>(
"gsfTrackTimeQualityMap"))
146 : edm::EDGetTokenT<edm::ValueMap<float>>()),
150 simClusters_(consumes<std::
vector<
reco::PFCluster>>(conf.getParameter<edm::
InputTag>(
"simClustersSrc"))),
153 [this](
const edm::
InputTag&
tag) {
return this->consumes<reco::TrackToTrackingParticleAssociator>(
tag); })) {
154 produces<reco::PFBlockCollection>();
155 produces<reco::SuperClusterCollection>(
"perfect");
156 produces<reco::PFCandidateCollection>();
161 std::vector<edm::Handle<reco::TrackToTrackingParticleAssociator>> associators;
163 associators.emplace_back();
164 auto& back = associators.back();
172 std::unordered_set<unsigned> PFTrackToGeneralTrack;
173 for (
unsigned i = 0;
i < PFTrackCollection.
size(); ++
i) {
174 const auto ptr = PFTrackCollection.
ptrAt(
i);
175 PFTrackToGeneralTrack.insert(ptr->trackRef().key());
185 std::unordered_set<unsigned> MuonTrackToGeneralTrack;
186 for (
auto const&
mu : *muons.
product()) {
189 MuonTrackToGeneralTrack.insert(muTrkRef.
key());
223 const std::vector<reco::PFCluster>& SimClusters = *SimClustersH;
225 std::unordered_map<uint64_t, size_t> hashToSimCluster;
227 for (
unsigned i = 0;
i < SimClustersTruth.size(); ++
i) {
228 const auto& simTruth = SimClustersTruth[
i];
229 hashToSimCluster[hashSimInfo(simTruth)] =
i;
233 std::vector<reco::RecoToSimCollection> associatedTracks, associatedTracksGsf;
234 for (
const auto& associator : associators) {
235 associatedTracks.emplace_back(associator->associateRecoToSim(TrackCollectionH, TPCollectionH));
241 auto superclusters = std::make_unique<reco::SuperClusterCollection>();
242 auto blocks = std::make_unique<reco::PFBlockCollection>();
243 std::unordered_map<size_t, size_t> simCluster2Block;
244 std::unordered_map<size_t, size_t> simCluster2BlockIndex;
245 std::unordered_multimap<size_t, size_t> caloParticle2SimCluster;
246 std::vector<int> caloParticle2SuperCluster;
247 for (
unsigned icp = 0; icp < CaloParticles.size(); ++icp) {
248 blocks->emplace_back();
249 auto&
block = blocks->back();
250 const auto&
simclusters = CaloParticles[icp].simClusters();
253 std::vector<size_t> good_simclusters;
254 for (
unsigned isc = 0; isc <
simclusters.size(); ++isc) {
256 auto pdgId =
std::abs(simc->pdgId());
260 good_simclusters.push_back(isc);
261 etot += clusterRef->energy();
262 pttot += clusterRef->pt();
264 block.addElement(bec.get());
265 simCluster2Block[simc.key()] = icp;
266 simCluster2BlockIndex[simc.key()] = bec->index();
267 caloParticle2SimCluster.emplace(CaloParticles[icp].g4Tracks()[0].trackId(), simc.key());
271 auto pdgId =
std::abs(CaloParticles[icp].pdgId());
273 caloParticle2SuperCluster.push_back(-1);
275 caloParticle2SuperCluster[icp] = superclusters->size();
280 for (
auto idx : good_simclusters) {
283 if (seed.
isNull() || seed->energy() < ptr->energy()) {
285 seedpos = ptr->position();
288 superclusters->emplace_back(etot, seedpos, seed, clusters);
293 auto superClustersHandle = evt.
put(
std::move(superclusters),
"perfect");
296 std::vector<bool> usedTrack(TrackCollection.
size(),
false),
298 usedSimCluster(SimClusters.size(),
false);
300 auto candidates = std::make_unique<reco::PFCandidateCollection>();
302 for (
unsigned itk = 0; itk < TrackCollection.
size(); ++itk) {
303 auto tkRef = TrackCollection.
refAt(itk);
305 if (PFTrackToGeneralTrack.count(itk) == 0)
313 if (assoc_tps == associatedTracks.back().end())
316 const auto& matches = assoc_tps->val;
319 const auto charge = tkRef->charge();
320 const auto three_mom = tkRef->momentum();
321 constexpr
double mpion2 = 0.13957 * 0.13957;
338 candidates->emplace_back(charge, trk_p4, part_type);
339 auto& candidate = candidates->back();
347 candidate.setTime((*trackTimeH)[tkRef], (*trackTimeErrH)[tkRef]);
349 candidate.setTime(0., -1.);
354 for (
const auto&
match : matches) {
356 if (hashToSimCluster.count(hash)) {
357 auto simcHash = hashToSimCluster[
hash];
359 if (!usedSimCluster[simcHash]) {
360 if (simCluster2Block.count(simcHash) && simCluster2BlockIndex.count(simcHash)) {
361 size_t block = simCluster2Block.find(simcHash)->second;
362 size_t blockIdx = simCluster2BlockIndex.find(simcHash)->second;
364 candidate.addElementInBlock(blockRef, blockIdx);
365 usedSimCluster[simcHash] =
true;
368 if (absPdgId == 11) {
369 if (simCluster2Block.count(simcHash)) {
370 auto block_index = simCluster2Block.find(simcHash)->second;
371 auto supercluster_index = caloParticle2SuperCluster[block_index];
372 if (supercluster_index != -1) {
374 for (
const auto& elem : blockRef->elements()) {
375 const auto& ref = elem.clusterRef();
376 if (!usedSimCluster[ref.key()]) {
377 candidate.addElementInBlock(blockRef, elem.
index());
378 usedSimCluster[ref.key()] =
true;
392 if (caloParticle2SimCluster.count(
match.first->g4Tracks()[0].trackId())) {
393 auto range = caloParticle2SimCluster.equal_range(
match.first->g4Tracks()[0].trackId());
394 for (
auto it =
range.first; it !=
range.second; ++it) {
395 if (!usedSimCluster[it->second]) {
396 usedSimCluster[it->second] =
true;
397 if (simCluster2Block.find(it->second) != simCluster2Block.end()) {
398 size_t block = simCluster2Block.find(it->second)->second;
399 size_t blockIdx = simCluster2BlockIndex.find(it->second)->second;
401 candidate.addElementInBlock(blockRef, blockIdx);
407 usedTrack[tkRef.key()] =
true;
409 if (MuonTrackToGeneralTrack.count(itk) || absPdgId == 13)
410 candidates->pop_back();
415 const auto& theblocks = *blocksHandle;
416 for (
unsigned ibl = 0; ibl < theblocks.size(); ++ibl) {
418 const auto&
elements = theblocks[ibl].elements();
420 const auto& ref = elem.clusterRef();
421 const auto& simtruth = SimClustersTruth[ref.key()];
423 if (!usedSimCluster[ref.key()]) {
424 auto absPdgId =
std::abs(simtruth.pdgId());
433 const auto three_mom = (ref->position() -
math::XYZPoint(0, 0, 0)).
unit() * ref->correctedEnergy();
435 candidates->emplace_back(0, clu_p4, part_type);
436 auto& candidate = candidates->back();
437 candidate.addElementInBlock(blref, elem.
index());
const edm::EDGetTokenT< edm::ValueMap< float > > srcTrackTimeError_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
ParticleType
particle types
bool isNonnull() const
Checks for non-null.
friend struct const_iterator
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Ptr< value_type > ptrAt(size_type i) const
#define DEFINE_FWK_MODULE(type)
void push_back(Ptr< T > const &iPtr)
std::vector< Track > TrackCollection
collection of Tracks
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
key_type key() const
Accessor for product key.
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
std::vector< Muon > MuonCollection
collection of Muon objects
const double neutralHADThreshold_
const uint16_t range(const Frame &aFrame)
RefToBase< value_type > refAt(size_type i) const
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
const edm::EDGetTokenT< edm::ValueMap< float > > srcTrackTimeQuality_
const double timingQualityThreshold_
const edm::EDGetTokenT< CaloParticleCollection > caloParticles_
std::tuple< layerClusterToCaloParticle, caloParticleToLayerCluster > association
const std::vector< edm::EDGetTokenT< reco::TrackToTrackingParticleAssociator > > associators_
bool isNull() const
Checks for null.
tuple key
prepare the HTCondor submission files and eventually submit them
Abs< T >::type abs(const T &t)
const edm::EDGetTokenT< edm::View< reco::Track > > tracks_
const edm::EDGetTokenT< edm::ValueMap< float > > srcGsfTrackTime_
ParameterDescriptionBase * add(U const &iLabel, T const &value)
const edm::EDGetTokenT< edm::View< reco::PFRecTrack > > pfRecTracks_
const edm::EDGetTokenT< SimClusterCollection > simClustersTruth_
const edm::EDGetTokenT< TrackingParticleCollection > trackingParticles_
T const * product() const
unsigned long long uint64_t
const bool useTimingQuality_
XYZPointD XYZPoint
point in space with cartesian internal representation
SimPFProducer(const edm::ParameterSet &)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const double superClusterThreshold_
const edm::EDGetTokenT< reco::MuonCollection > muons_
const edm::EDGetTokenT< edm::ValueMap< float > > srcGsfTrackTimeQuality_
std::vector< l1t::PFTrack > PFTrackCollection
const edm::EDGetTokenT< edm::ValueMap< float > > srcTrackTime_
std::vector< CaloParticle > CaloParticleCollection
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const edm::EDGetTokenT< edm::ValueMap< float > > srcGsfTrackTimeError_
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
const double neutralEMThreshold_
std::vector< TrackingParticle > TrackingParticleCollection
std::vector< SimCluster > SimClusterCollection
const edm::EDGetTokenT< std::vector< reco::PFCluster > > simClusters_
const edm::EDGetTokenT< edm::View< reco::Track > > gsfTracks_
Basic3DVector unit() const