50 #include <unordered_map> 53 #include "CLHEP/Units/SystemOfUnits.h" 82 const std::vector<edm::EDGetTokenT<reco::TrackToTrackingParticleAssociator> >
associators_;
91 uint64_t hashSimInfo(
const T& simTruth,
size_t i = 0) {
93 uint64_t trackid = simTruth.g4Tracks()[
i].trackId();
94 return ( (evtid << 3) + 23401923 ) ^ trackid ;
102 useTiming_(conf.existsAs<
edm::InputTag>(
"trackTimeValueMap")),
117 produces<reco::PFBlockCollection>();
118 produces<reco::SuperClusterCollection>(
"perfect");
119 produces<reco::PFCandidateCollection>();
124 std::vector<edm::Handle<reco::TrackToTrackingParticleAssociator> >
associators;
126 associators.emplace_back();
127 auto& back = associators.back();
135 std::unordered_set<unsigned> PFTrackToGeneralTrack;
136 for(
unsigned i = 0;
i < PFTrackCollection.
size(); ++
i ) {
137 const auto ptr = PFTrackCollection.
ptrAt(
i);
138 PFTrackToGeneralTrack.insert(ptr->trackRef().key());
148 std::unordered_set<unsigned> MuonTrackToGeneralTrack;
152 MuonTrackToGeneralTrack.insert(muTrkRef.
key());
180 const std::vector<reco::PFCluster>& SimClusters = *SimClustersH;
182 std::unordered_map<uint64_t,size_t> hashToSimCluster;
184 for(
unsigned i = 0;
i < SimClustersTruth.size(); ++
i ) {
185 const auto& simTruth = SimClustersTruth[
i];
186 hashToSimCluster[hashSimInfo(simTruth)] =
i;
190 std::vector<reco::RecoToSimCollection> associatedTracks, associatedTracksGsf;
192 associatedTracks.emplace_back(
associator->associateRecoToSim(TrackCollectionH, TPCollectionH));
198 auto superclusters = std::make_unique<reco::SuperClusterCollection>();
199 auto blocks = std::make_unique<reco::PFBlockCollection>();
200 std::unordered_map<size_t,size_t> simCluster2Block;
201 std::unordered_map<size_t,size_t> simCluster2BlockIndex;
202 std::unordered_multimap<size_t,size_t> caloParticle2SimCluster;
203 std::vector<int> caloParticle2SuperCluster;
204 for(
unsigned icp = 0; icp < CaloParticles.size(); ++icp ) {
205 blocks->emplace_back();
206 auto&
block = blocks->back();
207 const auto& simclusters = CaloParticles[icp].simClusters();
210 std::vector<size_t> good_simclusters;
211 for(
unsigned isc = 0; isc < simclusters.size() ; ++isc ) {
212 auto simc = simclusters[isc];
217 good_simclusters.push_back(isc);
218 etot += clusterRef->energy();
219 pttot += clusterRef->pt();
221 block.addElement(bec.get());
222 simCluster2Block[simc.key()] = icp;
223 simCluster2BlockIndex[simc.key()] = bec->index();
224 caloParticle2SimCluster.emplace(CaloParticles[icp].g4Tracks()[0].trackId(), simc.key());
230 caloParticle2SuperCluster.push_back(-1);
232 caloParticle2SuperCluster[icp] = superclusters->size();
237 for(
auto idx : good_simclusters ) {
245 superclusters->emplace_back(etot,seedpos,seed,clusters);
250 auto superClustersHandle = evt.
put(
std::move(superclusters),
"perfect");
253 std::vector<bool> usedTrack(TrackCollection.
size(),
false),
255 usedSimCluster(SimClusters.size(),
false);
257 auto candidates = std::make_unique<reco::PFCandidateCollection>();
259 for(
unsigned itk = 0; itk < TrackCollection.
size(); ++itk ) {
260 auto tkRef = TrackCollection.
refAt(itk);
262 if( PFTrackToGeneralTrack.count(itk) == 0 )
continue;
264 for(
const auto&
association : associatedTracks ) {
268 if( assoc_tps == associatedTracks.back().end() )
continue;
270 const auto&
matches = assoc_tps->val;
273 const auto charge = tkRef->charge();
274 const auto three_mom = tkRef->momentum();
275 constexpr double mpion2 = 0.13957*0.13957;
276 double energy =
std::sqrt(three_mom.mag2() + mpion2);
292 candidates->emplace_back(charge, trk_p4, part_type);
293 auto& candidate = candidates->back();
297 if (
useTiming_) candidate.setTime( (*trackTimeH)[tkRef], (*trackTimeErrH)[tkRef] );
302 if( hashToSimCluster.count(hash) ) {
303 auto simcHash = hashToSimCluster[
hash];
305 if( !usedSimCluster[simcHash] ) {
306 if( simCluster2Block.count(simcHash) &&
307 simCluster2BlockIndex.count(simcHash) ) {
308 size_t block = simCluster2Block.find(simcHash)->second;
309 size_t blockIdx = simCluster2BlockIndex.find(simcHash)->second;
311 candidate.addElementInBlock(blockRef,blockIdx);
312 usedSimCluster[simcHash] =
true;
315 if( absPdgId == 11 ) {
316 if( simCluster2Block.count(simcHash) ) {
317 auto block_index = simCluster2Block.find(simcHash)->second;
318 auto supercluster_index = caloParticle2SuperCluster[ block_index ];
319 if( supercluster_index != -1 ) {
321 for(
const auto&
elem : blockRef->elements() ) {
322 const auto& ref =
elem.clusterRef();
323 if( !usedSimCluster[ref.key()] ) {
324 candidate.addElementInBlock(blockRef,
elem.index());
325 usedSimCluster[ref.key()] =
true;
340 if (caloParticle2SimCluster.count(
match.first->g4Tracks()[0].trackId()))
342 auto range = caloParticle2SimCluster.equal_range(
match.first->g4Tracks()[0].trackId());
343 for (
auto it = range.first; it != range.second; ++it) {
344 if (!usedSimCluster[it->second]) {
345 usedSimCluster[it->second] =
true;
346 if (simCluster2Block.find(it->second) != simCluster2Block.end()) {
347 size_t block = simCluster2Block.find(it->second)->second;
348 size_t blockIdx = simCluster2BlockIndex.find(it->second)->second;
350 candidate.addElementInBlock(blockRef,blockIdx);
356 usedTrack[tkRef.key()] =
true;
358 if( MuonTrackToGeneralTrack.count(itk) || absPdgId == 13)
359 candidates->pop_back();
364 const auto& theblocks = *blocksHandle;
365 for(
unsigned ibl = 0; ibl < theblocks.size(); ++ibl ) {
367 const auto&
elements = theblocks[ibl].elements();
369 const auto& ref =
elem.clusterRef();
370 const auto& simtruth = SimClustersTruth[ref.key()];
372 if( !usedSimCluster[ref.key()] ) {
373 auto absPdgId =
std::abs(simtruth.pdgId());
382 const auto three_mom = (ref->position() -
math::XYZPoint(0,0,0)).
unit()*ref->correctedEnergy();
384 candidates->emplace_back(0, clu_p4, part_type);
385 auto& candidate = candidates->back();
386 candidate.addElementInBlock(blref,
elem.index());
387 candidate.setTime(ref->time(), ref->timeError());
const math::XYZPoint & position() const
cluster centroid position
const edm::EDGetTokenT< edm::ValueMap< float > > srcTrackTimeError_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
ParticleType
particle types
bool isNonnull() const
Checks for non-null.
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
std::vector< TrackingParticle > TrackingParticleCollection
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
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 >
~SimPFProducer() override
std::vector< Muon > MuonCollection
collection of Muon objects
const double neutralHADThreshold_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
RefToBase< value_type > refAt(size_type i) const
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
const edm::EDGetTokenT< CaloParticleCollection > caloParticles_
const std::vector< edm::EDGetTokenT< reco::TrackToTrackingParticleAssociator > > associators_
bool isNull() const
Checks for null.
Abs< T >::type abs(const T &t)
const edm::EDGetTokenT< edm::View< reco::Track > > tracks_
const edm::EDGetTokenT< edm::ValueMap< float > > srcGsfTrackTime_
const edm::EDGetTokenT< edm::View< reco::PFRecTrack > > pfRecTracks_
double energy() const
cluster energy
const edm::EDGetTokenT< SimClusterCollection > simClustersTruth_
def elem(elemtype, innerHTML='', html_class='', kwargs)
const edm::EDGetTokenT< TrackingParticleCollection > trackingParticles_
T const * product() const
unsigned long long uint64_t
XYZPointD XYZPoint
point in space with cartesian internal representation
SimPFProducer(const edm::ParameterSet &)
const double superClusterThreshold_
const edm::EDGetTokenT< reco::MuonCollection > muons_
const edm::EDGetTokenT< edm::ValueMap< float > > srcTrackTime_
std::vector< CaloParticle > CaloParticleCollection
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< SimCluster > SimClusterCollection
const edm::EDGetTokenT< std::vector< reco::PFCluster > > simClusters_
const edm::EDGetTokenT< edm::View< reco::Track > > gsfTracks_