Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-02 05:10:05

0001 #include "TauAnalysis/MCEmbeddingTools/plugins/TrackMergeremb.h"
0002 
0003 #include <memory>
0004 
0005 #include "DataFormats/TrackReco/interface/TrackExtra.h"
0006 
0007 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0008 #include "DataFormats/GsfTrackReco/interface/GsfTrackExtra.h"
0009 #include "DataFormats/GsfTrackReco/interface/GsfTrackExtraFwd.h"
0010 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
0011 
0012 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0013 #include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
0014 
0015 #include "DataFormats/EgammaTrackReco/interface/ConversionTrack.h"
0016 #include "DataFormats/EgammaTrackReco/interface/ConversionTrackFwd.h"
0017 
0018 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0019 #include "DataFormats/MuonReco/interface/MuonTrackLinks.h"
0020 
0021 #include "DataFormats/Common/interface/ValueMap.h"
0022 #include "DataFormats/MuonReco/interface/MuonQuality.h"
0023 
0024 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0025 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0026 
0027 #include "DataFormats/MuonReco/interface/CaloMuon.h"
0028 #include "DataFormats/MuonReco/interface/Muon.h"
0029 #include "DataFormats/MuonReco/interface/MuonCocktails.h"
0030 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0031 #include "DataFormats/MuonReco/interface/MuonTime.h"
0032 #include "DataFormats/MuonReco/interface/MuonTimeExtra.h"
0033 #include "DataFormats/MuonReco/interface/MuonTimeExtraMap.h"
0034 #include "DataFormats/MuonReco/interface/MuonTrackLinks.h"
0035 #include "DataFormats/RecoCandidate/interface/IsoDeposit.h"
0036 #include "DataFormats/RecoCandidate/interface/IsoDepositFwd.h"
0037 #include "RecoMuon/MuonIdentification/interface/MuonTimingFiller.h"
0038 
0039 #include "DataFormats/EgammaCandidates/interface/Photon.h"
0040 #include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
0041 
0042 #include "DataFormats/ParticleFlowReco/interface/PFRecTrack.h"
0043 #include "DataFormats/ParticleFlowReco/interface/PFRecTrackFwd.h"
0044 
0045 typedef TrackMergeremb<reco::TrackCollection> TrackColMerger;
0046 typedef TrackMergeremb<reco::GsfTrackCollection> GsfTrackColMerger;
0047 typedef TrackMergeremb<reco::MuonCollection> MuonColMerger;
0048 typedef TrackMergeremb<reco::GsfElectronCollection> GsfElectronColMerger;
0049 typedef TrackMergeremb<reco::PhotonCollection> PhotonColMerger;
0050 typedef TrackMergeremb<reco::ConversionCollection> ConversionColMerger;
0051 typedef TrackMergeremb<reco::PFCandidateCollection> PFColMerger;
0052 
0053 template <typename T1>
0054 TrackMergeremb<T1>::TrackMergeremb(const edm::ParameterSet &iConfig) {
0055   alias = iConfig.getParameter<std::string>("@module_label");
0056   std::vector<edm::InputTag> inCollections = iConfig.getParameter<std::vector<edm::InputTag>>("mergCollections");
0057   globalGeomToken_ = esConsumes();
0058   for (const auto &inCollection : inCollections) {
0059     inputs_[inCollection.instance()].push_back(consumes<TrackCollectionemb>(inCollection));
0060   }
0061   willconsume(iConfig);
0062   for (const auto &toproduce : inputs_) {
0063     willproduce(toproduce.first, alias);
0064   }
0065 }
0066 
0067 template <typename T1>
0068 TrackMergeremb<T1>::~TrackMergeremb() {
0069   // nothing to be done yet...
0070 }
0071 
0072 template <typename T1>
0073 void TrackMergeremb<T1>::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0074   geometry_ = &iSetup.getData(globalGeomToken_);
0075   for (auto input_ : inputs_) {
0076     merg_and_put(iEvent, input_.first, input_.second);
0077 
0078   }  // end instance
0079 }
0080 
0081 template <typename T1>
0082 void TrackMergeremb<T1>::willproduce(std::string instance, std::string alias) {
0083   produces<TrackCollectionemb>(instance);
0084 }
0085 
0086 template <typename T1>
0087 void TrackMergeremb<T1>::willconsume(const edm::ParameterSet &iConfig) {}
0088 
0089 template <typename T1>
0090 void TrackMergeremb<T1>::merg_and_put(edm::Event &iEvent,
0091                                       std::string instance,
0092                                       std::vector<edm::EDGetTokenT<TrackCollectionemb>> &to_merge) {
0093   std::unique_ptr<TrackCollectionemb> outTracks = std::unique_ptr<TrackCollectionemb>(new TrackCollectionemb);
0094 
0095   for (auto akt_collection : to_merge) {
0096     edm::Handle<TrackCollectionemb> track_col_in;
0097     iEvent.getByToken(akt_collection, track_col_in);
0098 
0099     size_t sedref_it = 0;
0100     for (typename TrackCollectionemb::const_iterator it = track_col_in->begin(); it != track_col_in->end();
0101          ++it, ++sedref_it) {
0102       outTracks->push_back(typename T1::value_type(*it));
0103     }
0104 
0105   }  // end merge
0106 
0107   iEvent.put(std::move(outTracks), instance);
0108 }
0109 
0110 template <>
0111 void TrackMergeremb<reco::TrackCollection>::willproduce(std::string instance, std::string alias) {
0112   produces<reco::TrackCollection>(instance).setBranchAlias(alias + "Tracks");
0113   produces<reco::TrackExtraCollection>(instance).setBranchAlias(alias + "TrackExtras");
0114   produces<TrackingRecHitCollection>(instance).setBranchAlias(alias + "RecHits");
0115   produces<TrackToTrackMapnew>();
0116 }
0117 
0118 template <>
0119 void TrackMergeremb<reco::TrackCollection>::merg_and_put(
0120     edm::Event &iEvent, std::string instance, std::vector<edm::EDGetTokenT<reco::TrackCollection>> &to_merge) {
0121   std::unique_ptr<reco::TrackCollection> outTracks = std::make_unique<reco::TrackCollection>();
0122   std::unique_ptr<reco::TrackExtraCollection> outTracks_ex = std::make_unique<reco::TrackExtraCollection>();
0123   std::unique_ptr<TrackingRecHitCollection> outTracks_rh = std::make_unique<TrackingRecHitCollection>();
0124   std::unique_ptr<TrackToTrackMapnew> outTracks_refs = std::make_unique<TrackToTrackMapnew>();
0125 
0126   auto rTrackExtras = iEvent.getRefBeforePut<reco::TrackExtraCollection>();
0127 
0128   std::vector<reco::TrackRefVector> trackRefColl;
0129 
0130   for (auto akt_collection : to_merge) {
0131     edm::Handle<reco::TrackCollection> track_col_in;
0132     iEvent.getByToken(akt_collection, track_col_in);
0133 
0134     unsigned sedref_it = 0;
0135     for (reco::TrackCollection::const_iterator it = track_col_in->begin(); it != track_col_in->end();
0136          ++it, ++sedref_it) {
0137       outTracks->push_back(reco::Track(*it));
0138       auto rechits = it->recHits();
0139       // Fixing geometry records of detector components for tracking rec. hits
0140       for (auto ith = rechits.begin(); ith != rechits.end(); ith++) {
0141         auto hit = *(&(*ith));
0142         hit->setDet(*geometry_->idToDet(hit->rawId()));
0143       }
0144       outTracks_ex->push_back(reco::TrackExtra(*it->extra()));
0145       outTracks->back().setExtra(reco::TrackExtraRef(rTrackExtras, outTracks_ex->size() - 1));
0146       reco::TrackRef trackRefold(track_col_in, sedref_it);
0147 
0148       reco::TrackRefVector trackRefColl_helpvec;
0149       trackRefColl_helpvec.push_back(trackRefold);
0150       trackRefColl.push_back(trackRefColl_helpvec);
0151     }
0152 
0153   }  // end merge
0154 
0155   edm::OrphanHandle<reco::TrackCollection> trackHandle = iEvent.put(std::move(outTracks), instance);
0156   iEvent.put(std::move(outTracks_ex), instance);
0157 
0158   TrackToTrackMapnew::Filler filler(*outTracks_refs);
0159   filler.insert(trackHandle, trackRefColl.begin(), trackRefColl.end());
0160   filler.fill();
0161 
0162   iEvent.put(std::move(outTracks_refs));
0163   iEvent.put(std::move(outTracks_rh), instance);  // not implemented so far
0164 }
0165 
0166 template <>
0167 void TrackMergeremb<reco::GsfTrackCollection>::willconsume(const edm::ParameterSet &iConfig) {
0168   // track refs for trackerdriven seeds
0169   inputs_fixtrackrefs_ = consumes<TrackToTrackMapnew>(edm::InputTag("generalTracks"));
0170   inputs_fixtrackcol_ = consumes<reco::TrackCollection>(edm::InputTag("generalTracks"));
0171   inputs_rElectronMergedSeeds_ = consumes<reco::ElectronSeedCollection>(edm::InputTag("electronMergedSeeds"));
0172   inputs_rElectronMergedSeedViews_ = consumes<edm::View<TrajectorySeed>>(edm::InputTag("electronMergedSeeds"));
0173 }
0174 
0175 template <>
0176 void TrackMergeremb<reco::GsfTrackCollection>::willproduce(std::string instance, std::string alias) {
0177   produces<reco::GsfTrackCollection>(instance).setBranchAlias(alias + "GsfTracks");
0178   produces<reco::TrackExtraCollection>(instance).setBranchAlias(alias + "TrackExtras");
0179   produces<reco::GsfTrackExtraCollection>(instance).setBranchAlias(alias + "GsfTrackExtras");
0180   produces<TrackingRecHitCollection>(instance).setBranchAlias(alias + "RecHits");
0181   produces<GsfTrackToTrackMapnew>();
0182 }
0183 
0184 template <>
0185 void TrackMergeremb<reco::GsfTrackCollection>::merg_and_put(
0186     edm::Event &iEvent, std::string instance, std::vector<edm::EDGetTokenT<reco::GsfTrackCollection>> &to_merge) {
0187   std::unique_ptr<reco::GsfTrackCollection> outTracks = std::make_unique<reco::GsfTrackCollection>();
0188   std::unique_ptr<reco::TrackExtraCollection> outTracks_ex = std::make_unique<reco::TrackExtraCollection>();
0189   std::unique_ptr<reco::GsfTrackExtraCollection> outTracks_exgsf = std::make_unique<reco::GsfTrackExtraCollection>();
0190   std::unique_ptr<TrackingRecHitCollection> outTracks_rh = std::make_unique<TrackingRecHitCollection>();
0191   std::unique_ptr<GsfTrackToTrackMapnew> outTracks_refs = std::make_unique<GsfTrackToTrackMapnew>();
0192 
0193   auto rTrackExtras = iEvent.getRefBeforePut<reco::TrackExtraCollection>();
0194   auto rTrackExtras_gsf = iEvent.getRefBeforePut<reco::GsfTrackExtraCollection>();
0195 
0196   auto rHits = iEvent.getRefBeforePut<TrackingRecHitCollection>();
0197   std::vector<reco::GsfTrackRefVector> trackRefColl;
0198 
0199   // track to track map for trackerdriven seed fix
0200   edm::Handle<TrackToTrackMapnew> track_ref_map;
0201   iEvent.getByToken(inputs_fixtrackrefs_, track_ref_map);
0202 
0203   edm::Handle<reco::TrackCollection> track_new_col;
0204   iEvent.getByToken(inputs_fixtrackcol_, track_new_col);
0205 
0206   std::map<reco::TrackRef, reco::TrackRef> simple_track_to_track_map;
0207   for (unsigned abc = 0; abc < track_new_col->size(); ++abc) {
0208     reco::TrackRef trackRef(track_new_col, abc);
0209     simple_track_to_track_map[trackRef] = trackRef;
0210     simple_track_to_track_map[((*track_ref_map)[trackRef])[0]] = trackRef;
0211   }
0212 
0213   // merge begin
0214   for (auto akt_collection : to_merge) {
0215     edm::Handle<reco::GsfTrackCollection> track_col_in;
0216     iEvent.getByToken(akt_collection, track_col_in);
0217 
0218     size_t sedref_it = 0;
0219     for (reco::GsfTrackCollection::const_iterator it = track_col_in->begin(); it != track_col_in->end();
0220          ++it, ++sedref_it) {
0221       reco::ElectronSeedRef seed = it->seedRef().castTo<reco::ElectronSeedRef>();
0222       (const_cast<reco::ElectronSeed *>(seed.get()))->setCtfTrack(simple_track_to_track_map[seed->ctfTrack()]);
0223       outTracks->push_back(reco::GsfTrack(*it));
0224       auto rechits = it->recHits();
0225       // Fixing geometry records of detector components for tracking rec. hits
0226       for (auto ith = rechits.begin(); ith != rechits.end(); ith++) {
0227         auto hit = *(&(*ith));
0228         hit->setDet(*geometry_->idToDet(hit->rawId()));
0229       }
0230       outTracks_ex->push_back(reco::TrackExtra(*it->extra()));
0231       outTracks_exgsf->push_back(reco::GsfTrackExtra(*it->gsfExtra()));
0232 
0233       outTracks->back().setExtra(reco::TrackExtraRef(rTrackExtras, outTracks_ex->size() - 1));
0234       outTracks->back().setGsfExtra(reco::GsfTrackExtraRef(rTrackExtras_gsf, outTracks_exgsf->size() - 1));
0235 
0236       reco::GsfTrackRef trackRefold(track_col_in, sedref_it);
0237       reco::GsfTrackRefVector trackRefColl_helpvec;
0238       trackRefColl_helpvec.push_back(trackRefold);
0239       trackRefColl.push_back(trackRefColl_helpvec);
0240     }
0241 
0242   }  // end merge
0243 
0244   edm::OrphanHandle<reco::GsfTrackCollection> trackHandle = iEvent.put(std::move(outTracks), instance);
0245   GsfTrackToTrackMapnew::Filler filler(*outTracks_refs);
0246   filler.insert(trackHandle, trackRefColl.begin(), trackRefColl.end());
0247   filler.fill();
0248 
0249   edm::Handle<reco::ElectronSeedCollection> elSeeds;
0250   iEvent.getByToken(inputs_rElectronMergedSeeds_, elSeeds);
0251   auto bElSeeds = elSeeds->cbegin();
0252   auto eElSeeds = elSeeds->cend();
0253 
0254   edm::Handle<edm::View<TrajectorySeed>> seedViewsHandle;
0255   iEvent.getByToken(inputs_rElectronMergedSeedViews_, seedViewsHandle);
0256 
0257   std::unique_ptr<reco::TrackExtraCollection> outTracks_ex_new = std::make_unique<reco::TrackExtraCollection>();
0258 
0259   // fix track extras to new merged seeds
0260   for (typename reco::TrackExtraCollection::const_iterator tex = outTracks_ex->begin(); tex != outTracks_ex->end();
0261        ++tex) {
0262     reco::TrackExtra newTrackExtra(*tex);
0263 
0264     if (tex->seedRef().isAvailable()) {
0265       const reco::ElectronSeedRef &trSeedRef(tex->seedRef().castTo<reco::ElectronSeedRef>());
0266       if (trSeedRef.isAvailable()) {
0267         // find new seed with corresponding supercluster or ctfTrack
0268         // note that seed can be both Ecal- and Tracker-driven
0269         size_t sedref_it = 0;
0270         for (auto tseed = bElSeeds; tseed != eElSeeds; ++tseed, ++sedref_it) {
0271           const reco::ElectronSeedRef elSeedRef(elSeeds, sedref_it);
0272 
0273           if (trSeedRef->isEcalDriven() && elSeedRef->isEcalDriven()) {
0274             // match seeds by pair of detIds
0275             if (trSeedRef->detId(0) == elSeedRef->detId(0) && trSeedRef->detId(1) == elSeedRef->detId(1)) {
0276               edm::RefToBase<TrajectorySeed> traSeedRef(seedViewsHandle, sedref_it);
0277               newTrackExtra.setSeedRef(traSeedRef);
0278             }
0279           }
0280           if (trSeedRef->isTrackerDriven() && elSeedRef->isTrackerDriven()) {
0281             // if tracker driven, check for same ctf track
0282             if (simple_track_to_track_map[trSeedRef->ctfTrack()] == elSeedRef->ctfTrack()) {
0283               edm::RefToBase<TrajectorySeed> traSeedRef(seedViewsHandle, sedref_it);
0284               newTrackExtra.setSeedRef(traSeedRef);
0285             }
0286           }
0287         }
0288       }
0289     }
0290 
0291     outTracks_ex_new->push_back(newTrackExtra);
0292   }
0293 
0294   iEvent.put(std::move(outTracks_refs));
0295   iEvent.put(std::move(outTracks_ex_new), instance);
0296   iEvent.put(std::move(outTracks_exgsf), instance);
0297   iEvent.put(std::move(outTracks_rh), instance);
0298 }
0299 
0300 template <>
0301 void TrackMergeremb<reco::MuonCollection>::willproduce(std::string instance, std::string alias) {
0302   produces<reco::MuonCollection>();
0303   produces<reco::CaloMuonCollection>();
0304   produces<reco::MuonTimeExtraMap>("combined");
0305   produces<reco::MuonTimeExtraMap>("dt");
0306   produces<reco::MuonTimeExtraMap>("csc");
0307 
0308   // todo make this configurable (or not )
0309   produces<reco::IsoDepositMap>("tracker");
0310   produces<reco::IsoDepositMap>("ecal");
0311   produces<reco::IsoDepositMap>("hcal");
0312   produces<reco::IsoDepositMap>("ho");
0313   produces<reco::IsoDepositMap>("jets");
0314 
0315   produces<reco::MuonToMuonMap>();
0316 }
0317 
0318 template <>
0319 void TrackMergeremb<reco::MuonCollection>::willconsume(const edm::ParameterSet &iConfig) {
0320   if (alias == "displacedMuons1stStep") {
0321     inputs_fixtrackrefs_ = consumes<TrackToTrackMapnew>(edm::InputTag("displacedTracks"));
0322     inputs_fixtrackcol_ = consumes<reco::TrackCollection>(edm::InputTag("displacedTracks"));
0323   } else {
0324     inputs_fixtrackrefs_ = consumes<TrackToTrackMapnew>(edm::InputTag("generalTracks"));
0325     inputs_fixtrackcol_ = consumes<reco::TrackCollection>(edm::InputTag("generalTracks"));
0326   }
0327 }
0328 
0329 template <>
0330 void TrackMergeremb<reco::MuonCollection>::merg_and_put(edm::Event &iEvent,
0331                                                         std::string instance,
0332                                                         std::vector<edm::EDGetTokenT<reco::MuonCollection>> &to_merge) {
0333   std::unique_ptr<reco::MuonCollection> outTracks = std::make_unique<reco::MuonCollection>();
0334   std::unique_ptr<reco::CaloMuonCollection> calomu =
0335       std::make_unique<reco::CaloMuonCollection>();  // not implemented so far
0336 
0337   edm::Handle<TrackToTrackMapnew> track_ref_map;
0338   iEvent.getByToken(inputs_fixtrackrefs_, track_ref_map);
0339 
0340   edm::Handle<reco::TrackCollection> track_new_col;
0341   iEvent.getByToken(inputs_fixtrackcol_, track_new_col);
0342   std::map<reco::TrackRef, reco::TrackRef> simple_track_to_track_map;
0343   for (unsigned abc = 0; abc < track_new_col->size(); ++abc) {
0344     reco::TrackRef trackRef(track_new_col, abc);
0345     simple_track_to_track_map[trackRef] =
0346         trackRef;  // catch the case, where a seed ctf track could already be updated, such that the update doesn't happen again
0347     simple_track_to_track_map[((*track_ref_map)[trackRef])[0]] = trackRef;
0348   }
0349 
0350   std::vector<reco::MuonRef> muonRefColl;
0351   reco::MuonRefProd outputMuonsRefProd = iEvent.getRefBeforePut<reco::MuonCollection>();
0352   unsigned new_idx = 0;
0353   for (auto akt_collection : to_merge) {
0354     edm::Handle<reco::MuonCollection> track_col_in;
0355     iEvent.getByToken(akt_collection, track_col_in);
0356     unsigned old_idx = 0;
0357     for (reco::MuonCollection::const_iterator it = track_col_in->begin(); it != track_col_in->end();
0358          ++it, ++old_idx, ++new_idx) {
0359       outTracks->push_back(reco::Muon(*it));
0360       reco::MuonRef muRefold(track_col_in, old_idx);
0361       muonRefColl.push_back(muRefold);
0362       reco::MuonRef muRefnew(outputMuonsRefProd, new_idx);
0363 
0364       if (it->track().isNonnull()) {
0365         outTracks->back().setTrack(simple_track_to_track_map[it->track()]);
0366       }
0367     }
0368 
0369   }  // end merge
0370 
0371   const int nMuons = outTracks->size();
0372 
0373   std::vector<reco::MuonTimeExtra> dtTimeColl(nMuons);
0374   std::vector<reco::MuonTimeExtra> cscTimeColl(nMuons);
0375   std::vector<reco::MuonTimeExtra> combinedTimeColl(nMuons);
0376   std::vector<reco::IsoDeposit> trackDepColl(nMuons);
0377   std::vector<reco::IsoDeposit> ecalDepColl(nMuons);
0378   std::vector<reco::IsoDeposit> hcalDepColl(nMuons);
0379   std::vector<reco::IsoDeposit> hoDepColl(nMuons);
0380   std::vector<reco::IsoDeposit> jetDepColl(nMuons);
0381 
0382   edm::OrphanHandle<reco::MuonCollection> muonHandle = iEvent.put(std::move(outTracks));
0383 
0384   auto fillMap = [](auto refH, auto &vec, edm::Event &ev, const std::string &cAl = "") {
0385     typedef edm::ValueMap<typename std::decay<decltype(vec)>::type::value_type> MapType;
0386     std::unique_ptr<MapType> oMap(new MapType());
0387     {
0388       typename MapType::Filler filler(*oMap);
0389       filler.insert(refH, vec.begin(), vec.end());
0390       vec.clear();
0391       filler.fill();
0392     }
0393     ev.put(std::move(oMap), cAl);
0394   };
0395 
0396   fillMap(muonHandle, combinedTimeColl, iEvent, "combined");
0397   fillMap(muonHandle, dtTimeColl, iEvent, "dt");
0398   fillMap(muonHandle, cscTimeColl, iEvent, "csc");
0399   fillMap(muonHandle, trackDepColl, iEvent, "tracker");
0400   fillMap(muonHandle, ecalDepColl, iEvent, "ecal");
0401   fillMap(muonHandle, hcalDepColl, iEvent, "hcal");
0402   fillMap(muonHandle, hoDepColl, iEvent, "ho");
0403   fillMap(muonHandle, jetDepColl, iEvent, "jets");
0404   fillMap(muonHandle, muonRefColl, iEvent);
0405   iEvent.put(std::move(calomu));
0406 }
0407 
0408 template <>
0409 void TrackMergeremb<reco::PFCandidateCollection>::willproduce(std::string instance, std::string alias) {
0410   produces<reco::PFCandidateCollection>(instance);
0411 }
0412 
0413 template <>
0414 void TrackMergeremb<reco::PFCandidateCollection>::willconsume(const edm::ParameterSet &iConfig) {
0415   inputs_fixtrackrefs_ = consumes<TrackToTrackMapnew>(edm::InputTag("generalTracks"));
0416   inputs_fixtrackcol_ = consumes<reco::TrackCollection>(edm::InputTag("generalTracks"));
0417   inputs_fixgsftrackrefs_ = consumes<GsfTrackToTrackMapnew>(edm::InputTag("electronGsfTracks"));
0418   inputs_fixgsftrackcol_ = consumes<reco::GsfTrackCollection>(edm::InputTag("electronGsfTracks"));
0419   inputs_fixmurefs_ = consumes<reco::MuonToMuonMap>(edm::InputTag("muons1stStep"));
0420   inputs_fixmucol_ = consumes<reco::MuonCollection>(edm::InputTag("muons1stStep"));
0421   inputs_SC_ = consumes<reco::SuperClusterCollection>(edm::InputTag("particleFlowEGamma"));
0422 }
0423 
0424 template <>
0425 void TrackMergeremb<reco::PFCandidateCollection>::merg_and_put(
0426     edm::Event &iEvent, std::string instance, std::vector<edm::EDGetTokenT<reco::PFCandidateCollection>> &to_merge) {
0427   std::unique_ptr<reco::PFCandidateCollection> outTracks = std::make_unique<reco::PFCandidateCollection>();
0428 
0429   edm::Handle<TrackToTrackMapnew> track_ref_map;
0430   iEvent.getByToken(inputs_fixtrackrefs_, track_ref_map);
0431 
0432   edm::Handle<reco::TrackCollection> track_new_col;
0433   iEvent.getByToken(inputs_fixtrackcol_, track_new_col);
0434   std::map<reco::TrackRef, reco::TrackRef> simple_track_to_track_map;
0435   for (unsigned abc = 0; abc < track_new_col->size(); ++abc) {
0436     reco::TrackRef trackRef(track_new_col, abc);
0437     simple_track_to_track_map[trackRef] =
0438         trackRef;  // catch the case, where a seed ctf track could already be updated, such that the update doesn't happen again
0439     simple_track_to_track_map[((*track_ref_map)[trackRef])[0]] = trackRef;
0440   }
0441 
0442   edm::Handle<GsfTrackToTrackMapnew> gsftrack_ref_map;
0443   iEvent.getByToken(inputs_fixgsftrackrefs_, gsftrack_ref_map);
0444 
0445   edm::Handle<reco::GsfTrackCollection> gsftrack_new_col;
0446   iEvent.getByToken(inputs_fixgsftrackcol_, gsftrack_new_col);
0447   std::map<reco::GsfTrackRef, reco::GsfTrackRef> simple_gsftrack_to_gsftrack_map;
0448   for (unsigned abc = 0; abc < gsftrack_new_col->size(); ++abc) {
0449     reco::GsfTrackRef gsfTrackRef(gsftrack_new_col, abc);
0450     simple_gsftrack_to_gsftrack_map[((*gsftrack_ref_map)[gsfTrackRef])[0]] = gsfTrackRef;
0451   }
0452 
0453   edm::Handle<reco::MuonToMuonMap> muon_ref_map;
0454   iEvent.getByToken(inputs_fixmurefs_, muon_ref_map);
0455 
0456   edm::Handle<reco::MuonCollection> muon_new_col;
0457   iEvent.getByToken(inputs_fixmucol_, muon_new_col);
0458   std::map<reco::MuonRef, reco::MuonRef> simple_mu_to_mu_map;
0459   for (unsigned abc = 0; abc < muon_new_col->size(); ++abc) {
0460     reco::MuonRef muRef(muon_new_col, abc);
0461     simple_mu_to_mu_map[(*muon_ref_map)[muRef]] = muRef;
0462   }
0463 
0464   // used for photon matching
0465   edm::Handle<reco::SuperClusterCollection> sCs;
0466   iEvent.getByToken(inputs_SC_, sCs);
0467   auto bSc = sCs->cbegin();
0468   auto eSc = sCs->cend();
0469 
0470   for (auto akt_collection : to_merge) {
0471     edm::Handle<reco::PFCandidateCollection> track_col_in;
0472     iEvent.getByToken(akt_collection, track_col_in);
0473     for (reco::PFCandidateCollection::const_iterator it = track_col_in->begin(); it != track_col_in->end(); ++it) {
0474       outTracks->push_back(reco::PFCandidate(*it));
0475       if (it->trackRef().isNonnull() && outTracks->back().charge()) {
0476         outTracks->back().setTrackRef(simple_track_to_track_map[it->trackRef()]);
0477       }
0478       if (it->gsfTrackRef().isNonnull()) {
0479         outTracks->back().setGsfTrackRef(simple_gsftrack_to_gsftrack_map[it->gsfTrackRef()]);
0480       }
0481       if (it->superClusterRef().isNonnull()) {
0482         const reco::SuperClusterRef &pfScRef(it->superClusterRef());
0483 
0484         float dx, dy, dz, dr;
0485         float drMin = 10.0;  // also used as treshold for matching
0486         reco::SuperClusterRef ccrefMin;
0487         for (auto sc = bSc; sc != eSc; ++sc) {
0488           const reco::SuperClusterRef &scRef(reco::SuperClusterRef(sCs, std::distance(bSc, sc)));
0489           dx = fabs(scRef->x() - pfScRef->x());
0490           dy = fabs(scRef->y() - pfScRef->y());
0491           dz = fabs(scRef->z() - pfScRef->z());
0492           dr = sqrt(dx * dx + dy * dy + dz * dz);
0493           if (dr < drMin) {
0494             drMin = dr;
0495             outTracks->back().setSuperClusterRef(scRef);
0496           }
0497         }
0498       }
0499       if (it->muonRef().isNonnull()) {
0500         outTracks->back().setMuonRef(simple_mu_to_mu_map[it->muonRef()]);
0501       }
0502     }
0503   }  // end merge
0504 
0505   iEvent.put(std::move(outTracks), instance);
0506 }
0507 
0508 #include "FWCore/Framework/interface/MakerMacros.h"
0509 
0510 DEFINE_FWK_MODULE(TrackColMerger);
0511 DEFINE_FWK_MODULE(GsfTrackColMerger);
0512 DEFINE_FWK_MODULE(MuonColMerger);
0513 DEFINE_FWK_MODULE(GsfElectronColMerger);
0514 DEFINE_FWK_MODULE(PhotonColMerger);
0515 DEFINE_FWK_MODULE(ConversionColMerger);
0516 DEFINE_FWK_MODULE(PFColMerger);