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(icp,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);
249 auto superClustersHandle = evt.
put(
std::move(superclusters),
"perfect");
252 std::vector<bool> usedTrack(TrackCollection.
size(),
false),
254 usedSimCluster(SimClusters.size(),
false);
256 auto candidates = std::make_unique<reco::PFCandidateCollection>();
258 for(
unsigned itk = 0; itk < TrackCollection.
size(); ++itk ) {
259 auto tkRef = TrackCollection.
refAt(itk);
261 if( PFTrackToGeneralTrack.count(itk) == 0 )
continue;
263 for(
const auto&
association : associatedTracks ) {
267 if( assoc_tps == associatedTracks.back().end() )
continue;
269 const auto&
matches = assoc_tps->val;
272 const auto charge = tkRef->charge();
273 const auto three_mom = tkRef->momentum();
274 constexpr double mpion2 = 0.13957*0.13957;
275 double energy =
std::sqrt(three_mom.mag2() + mpion2);
291 candidates->emplace_back(charge, trk_p4, part_type);
292 auto& candidate = candidates->back();
296 if (
useTiming_) candidate.setTime( (*trackTimeH)[tkRef], (*trackTimeErrH)[tkRef] );
301 if( hashToSimCluster.count(hash) ) {
302 auto simcHash = hashToSimCluster[
hash];
304 if( !usedSimCluster[simcHash] ) {
305 if( simCluster2Block.count(simcHash) &&
306 simCluster2BlockIndex.count(simcHash) ) {
307 size_t block = simCluster2Block.find(simcHash)->second;
308 size_t blockIdx = simCluster2BlockIndex.find(simcHash)->second;
310 candidate.addElementInBlock(blockRef,blockIdx);
311 usedSimCluster[simcHash] =
true;
314 if( absPdgId == 11 ) {
315 if( simCluster2Block.count(simcHash) ) {
316 auto block_index = simCluster2Block.find(simcHash)->second;
317 auto supercluster_index = caloParticle2SuperCluster[ block_index ];
318 if( supercluster_index != -1 ) {
320 for(
const auto&
elem : blockRef->elements() ) {
321 const auto& ref =
elem.clusterRef();
322 if( !usedSimCluster[ref.key()] ) {
323 candidate.addElementInBlock(blockRef,
elem.index());
324 usedSimCluster[ref.key()] =
true;
335 usedTrack[tkRef.key()] =
true;
337 if( MuonTrackToGeneralTrack.count(itk) || absPdgId == 13)
338 candidates->pop_back();
343 const auto& theblocks = *blocksHandle;
344 for(
unsigned ibl = 0; ibl < theblocks.size(); ++ibl ) {
346 const auto&
elements = theblocks[ibl].elements();
348 const auto& ref =
elem.clusterRef();
349 const auto& simtruth = SimClustersTruth[ref.key()];
351 if( !usedSimCluster[ref.key()] ) {
352 auto absPdgId =
std::abs(simtruth.pdgId());
361 const auto three_mom = (ref->position() -
math::XYZPoint(0,0,0)).
unit()*ref->energy();
363 candidates->emplace_back(0, clu_p4, part_type);
364 auto& candidate = candidates->back();
365 candidate.addElementInBlock(blref,
elem.index());
366 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_