File indexing completed on 2024-09-07 04:37:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <memory>
0020
0021 #include "CommonTools/Utils/interface/KinematicTables.h"
0022 #include "CommonTools/Utils/interface/LazyConstructed.h"
0023 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0024 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
0025 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0026 #include "DataFormats/Math/interface/deltaR.h"
0027 #include "DataFormats/ParticleFlowReco/interface/GsfPFRecTrack.h"
0028 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
0029 #include "DataFormats/ParticleFlowReco/interface/PFConversion.h"
0030 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedTrackerVertex.h"
0031 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedVertex.h"
0032 #include "DataFormats/ParticleFlowReco/interface/PFRecTrack.h"
0033 #include "DataFormats/ParticleFlowReco/interface/PFV0.h"
0034 #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
0035 #include "DataFormats/VertexReco/interface/Vertex.h"
0036 #include "FWCore/Framework/interface/ESHandle.h"
0037 #include "FWCore/Framework/interface/Event.h"
0038 #include "FWCore/Framework/interface/stream/EDProducer.h"
0039 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0040 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
0041 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0042 #include "MagneticField/Engine/interface/MagneticField.h"
0043 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0044 #include "RecoParticleFlow/PFClusterTools/interface/ClusterClusterMapping.h"
0045 #include "RecoParticleFlow/PFClusterTools/interface/LinkByRecHit.h"
0046 #include "RecoParticleFlow/PFTracking/interface/ConvBremHeavyObjectCache.h"
0047 #include "RecoParticleFlow/PFTracking/interface/ConvBremPFTrackFinder.h"
0048 #include "RecoParticleFlow/PFTracking/interface/PFTrackAlgoTools.h"
0049 #include "RecoParticleFlow/PFTracking/interface/PFTrackTransformer.h"
0050 #include "TrackingTools/GsfTools/interface/MultiTrajectoryStateMode.h"
0051 #include "TrackingTools/GsfTools/interface/MultiTrajectoryStateTransform.h"
0052 #include "TrackingTools/PatternTools/interface/Trajectory.h"
0053 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0054 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0055
0056 namespace {
0057
0058 constexpr float square(float x) { return x * x; };
0059
0060 }
0061
0062 class PFElecTkProducer final : public edm::stream::EDProducer<edm::GlobalCache<convbremhelpers::HeavyObjectCache> > {
0063 public:
0064
0065 explicit PFElecTkProducer(const edm::ParameterSet&, const convbremhelpers::HeavyObjectCache*);
0066
0067 static std::unique_ptr<convbremhelpers::HeavyObjectCache> initializeGlobalCache(const edm::ParameterSet& conf) {
0068 return std::make_unique<convbremhelpers::HeavyObjectCache>(conf);
0069 }
0070
0071 static void globalEndJob(convbremhelpers::HeavyObjectCache const*) {}
0072 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0073
0074 private:
0075 void beginRun(const edm::Run&, const edm::EventSetup&) override;
0076 void endRun(const edm::Run&, const edm::EventSetup&) override;
0077
0078
0079 void produce(edm::Event&, const edm::EventSetup&) override;
0080
0081 int findPfRef(const reco::PFRecTrackCollection& pfRTkColl,
0082 const reco::GsfTrack&,
0083 edm::soa::EtaPhiTableView trackEtaPhiTable);
0084
0085 bool applySelection(const reco::GsfTrack&);
0086
0087 bool resolveGsfTracks(const std::vector<reco::GsfPFRecTrack>& GsfPFVec,
0088 unsigned int ngsf,
0089 std::vector<unsigned int>& secondaries,
0090 const reco::PFClusterCollection& theEClus);
0091
0092 float minTangDist(const reco::GsfPFRecTrack& primGsf, const reco::GsfPFRecTrack& secGsf);
0093
0094 bool isSameEgSC(const reco::ElectronSeed& nSeed,
0095 const reco::ElectronSeed& iSeed,
0096 bool& bothGsfEcalDriven,
0097 float& SCEnergy);
0098
0099 bool isSharingEcalEnergyWithEgSC(const reco::GsfPFRecTrack& nGsfPFRecTrack,
0100 const reco::GsfPFRecTrack& iGsfPFRecTrack,
0101 const reco::ElectronSeed& nSeed,
0102 const reco::ElectronSeed& iSeed,
0103 const reco::PFClusterCollection& theEClus,
0104 bool& bothGsfTrackerDriven,
0105 bool& nEcalDriven,
0106 bool& iEcalDriven,
0107 float& nEnergy,
0108 float& iEnergy);
0109
0110 bool isInnerMost(const reco::GsfTrackRef& nGsfTrack, const reco::GsfTrackRef& iGsfTrack, bool& sameLayer);
0111
0112 bool isInnerMostWithLostHits(const reco::GsfTrackRef& nGsfTrack, const reco::GsfTrackRef& iGsfTrack, bool& sameLayer);
0113
0114 void createGsfPFRecTrackRef(const edm::OrphanHandle<reco::GsfPFRecTrackCollection>& gsfPfHandle,
0115 std::vector<reco::GsfPFRecTrack>& gsfPFRecTrackPrimary,
0116 const std::map<unsigned int, std::vector<reco::GsfPFRecTrack> >& MapPrimSec);
0117
0118
0119 reco::GsfPFRecTrack pftrack_;
0120 reco::GsfPFRecTrack secpftrack_;
0121 edm::ParameterSet conf_;
0122 edm::EDGetTokenT<reco::GsfTrackCollection> gsfTrackLabel_;
0123 edm::EDGetTokenT<reco::PFRecTrackCollection> pfTrackLabel_;
0124 edm::EDGetTokenT<reco::VertexCollection> primVtxLabel_;
0125 edm::EDGetTokenT<reco::PFClusterCollection> pfEcalClusters_;
0126 edm::EDGetTokenT<reco::PFDisplacedTrackerVertexCollection> pfNuclear_;
0127 edm::EDGetTokenT<reco::PFConversionCollection> pfConv_;
0128 edm::EDGetTokenT<reco::PFV0Collection> pfV0_;
0129 bool useNuclear_;
0130 bool useConversions_;
0131 bool useV0_;
0132 bool applyAngularGsfClean_;
0133 double detaCutGsfClean_;
0134 double dphiCutGsfClean_;
0135
0136 const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> magFieldToken_;
0137 const edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> tkerGeomToken_;
0138 const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> transientTrackToken_;
0139
0140
0141 std::unique_ptr<PFTrackTransformer> pfTransformer_;
0142 MultiTrajectoryStateTransform mtsTransform_;
0143 std::unique_ptr<ConvBremPFTrackFinder> convBremFinder_;
0144
0145
0146 bool trajinev_;
0147 bool modemomentum_;
0148 bool applySel_;
0149 bool applyGsfClean_;
0150 bool useFifthStepForEcalDriven_;
0151 bool useFifthStepForTrackDriven_;
0152
0153 bool debugGsfCleaning_;
0154 double SCEne_;
0155 double detaGsfSC_;
0156 double dphiGsfSC_;
0157 double maxPtConvReco_;
0158
0159
0160 bool useConvBremFinder_;
0161
0162 double mvaConvBremFinderIDBarrelLowPt_;
0163 double mvaConvBremFinderIDBarrelHighPt_;
0164 double mvaConvBremFinderIDEndcapsLowPt_;
0165 double mvaConvBremFinderIDEndcapsHighPt_;
0166 std::string path_mvaWeightFileConvBremBarrelLowPt_;
0167 std::string path_mvaWeightFileConvBremBarrelHighPt_;
0168 std::string path_mvaWeightFileConvBremEndcapsLowPt_;
0169 std::string path_mvaWeightFileConvBremEndcapsHighPt_;
0170
0171
0172 std::vector<double> gsfInnerMomentumCache_;
0173 };
0174
0175 void PFElecTkProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0176 edm::ParameterSetDescription desc;
0177 desc.add<bool>("TrajInEvents", false);
0178 desc.add<std::string>("Fitter", "GsfElectronFittingSmoother");
0179 desc.add<bool>("ModeMomentum", true);
0180 desc.add<bool>("applyEGSelection", false);
0181 desc.add<bool>("applyGsfTrackCleaning", true);
0182 desc.add<bool>("applyAlsoGsfAngularCleaning", true);
0183 desc.add<double>("maxDEtaGsfAngularCleaning", 0.05);
0184 desc.add<double>("maxDPhiBremTangGsfAngularCleaning", 0.05);
0185 desc.add<bool>("useFifthStepForTrackerDrivenGsf", false);
0186 desc.add<bool>("useFifthStepForEcalDrivenGsf", false);
0187 desc.add<double>("MaxConvBremRecoPT", 49.0);
0188 desc.add<double>("MinDEtaGsfSC", 0.06);
0189 desc.add<double>("MinDPhiGsfSC", 0.15);
0190 desc.add<double>("MinSCEnergy", 4.0);
0191 desc.add<std::string>("TTRHBuilder", "WithTrackAngle");
0192 desc.add<edm::InputTag>("GsfTrackModuleLabel", {"electronGsfTracks"});
0193 desc.add<std::string>("Propagator", "fwdElectronPropagator");
0194 desc.add<edm::InputTag>("PFRecTrackLabel", {"pfTrack"});
0195 desc.add<edm::InputTag>("PFEcalClusters", {"particleFlowClusterECAL"});
0196 desc.add<edm::InputTag>("PrimaryVertexLabel", {"offlinePrimaryVertices"});
0197 desc.add<bool>("useConvBremFinder", true);
0198 desc.add<edm::InputTag>("PFNuclear", {"pfDisplacedTrackerVertex"});
0199 desc.add<edm::InputTag>("PFConversions", {"pfConversions"});
0200 desc.add<edm::InputTag>("PFV0", {"pfV0"});
0201 desc.add<bool>("useNuclear", false);
0202 desc.add<bool>("useV0", false);
0203 desc.add<bool>("useConversions", false);
0204 desc.add<bool>("debugGsfCleaning", false);
0205 desc.add<double>("AbsEtaBarrelEndcapsSeparation", 1.479);
0206 desc.add<double>("PtLowHighSeparation", 20);
0207 desc.add<double>("pf_convBremFinderID_mvaCutBarrelLowPt", 0.6);
0208 desc.add<double>("pf_convBremFinderID_mvaCutBarrelHighPt", 0.97);
0209 desc.add<double>("pf_convBremFinderID_mvaCutEndcapsLowPt", 0.9);
0210 desc.add<double>("pf_convBremFinderID_mvaCutEndcapsHighPt", 0.995);
0211 desc.add<edm::FileInPath>(
0212 "pf_convBremFinderID_mvaWeightFileBarrelLowPt",
0213 edm::FileInPath("RecoParticleFlow/PFTracking/data/"
0214 "TMVAClassification_ConvBremFinder_Testetlt20absetalt1_479_BDT.weights.xml"));
0215 desc.add<edm::FileInPath>(
0216 "pf_convBremFinderID_mvaWeightFileBarrelHighPt",
0217 edm::FileInPath("RecoParticleFlow/PFTracking/data/"
0218 "TMVAClassification_ConvBremFinder_Testetgt20absetalt1_479_BDT.weights.xml"));
0219 desc.add<edm::FileInPath>(
0220 "pf_convBremFinderID_mvaWeightFileEndcapsLowPt",
0221 edm::FileInPath("RecoParticleFlow/PFTracking/data/"
0222 "TMVAClassification_ConvBremFinder_Testetlt20absetagt1_479_BDT.weights.xml"));
0223 desc.add<edm::FileInPath>(
0224 "pf_convBremFinderID_mvaWeightFileEndcapsHighPt",
0225 edm::FileInPath("RecoParticleFlow/PFTracking/data/"
0226 "TMVAClassification_ConvBremFinder_Testetgt20absetagt1_479_BDT.weights.xml"));
0227 descriptions.addWithDefaultLabel(desc);
0228 }
0229
0230 using namespace std;
0231 using namespace edm;
0232 using namespace reco;
0233
0234 PFElecTkProducer::PFElecTkProducer(const ParameterSet& iConfig, const convbremhelpers::HeavyObjectCache*)
0235 : conf_(iConfig),
0236 magFieldToken_(esConsumes<edm::Transition::BeginRun>()),
0237 tkerGeomToken_(esConsumes<edm::Transition::BeginRun>()),
0238 transientTrackToken_(esConsumes<edm::Transition::BeginRun>(edm::ESInputTag("", "TransientTrackBuilder"))) {
0239 gsfTrackLabel_ = consumes<reco::GsfTrackCollection>(iConfig.getParameter<InputTag>("GsfTrackModuleLabel"));
0240
0241 pfTrackLabel_ = consumes<reco::PFRecTrackCollection>(iConfig.getParameter<InputTag>("PFRecTrackLabel"));
0242
0243 primVtxLabel_ = consumes<reco::VertexCollection>(iConfig.getParameter<InputTag>("PrimaryVertexLabel"));
0244
0245 pfEcalClusters_ = consumes<reco::PFClusterCollection>(iConfig.getParameter<InputTag>("PFEcalClusters"));
0246
0247 pfNuclear_ = consumes<reco::PFDisplacedTrackerVertexCollection>(iConfig.getParameter<InputTag>("PFNuclear"));
0248
0249 pfConv_ = consumes<reco::PFConversionCollection>(iConfig.getParameter<InputTag>("PFConversions"));
0250
0251 pfV0_ = consumes<reco::PFV0Collection>(iConfig.getParameter<InputTag>("PFV0"));
0252
0253 useNuclear_ = iConfig.getParameter<bool>("useNuclear");
0254 useConversions_ = iConfig.getParameter<bool>("useConversions");
0255 useV0_ = iConfig.getParameter<bool>("useV0");
0256 debugGsfCleaning_ = iConfig.getParameter<bool>("debugGsfCleaning");
0257
0258 produces<GsfPFRecTrackCollection>();
0259 produces<GsfPFRecTrackCollection>("Secondary").setBranchAlias("secondary");
0260
0261 trajinev_ = iConfig.getParameter<bool>("TrajInEvents");
0262 modemomentum_ = iConfig.getParameter<bool>("ModeMomentum");
0263 applySel_ = iConfig.getParameter<bool>("applyEGSelection");
0264 applyGsfClean_ = iConfig.getParameter<bool>("applyGsfTrackCleaning");
0265 applyAngularGsfClean_ = iConfig.getParameter<bool>("applyAlsoGsfAngularCleaning");
0266 detaCutGsfClean_ = iConfig.getParameter<double>("maxDEtaGsfAngularCleaning");
0267 dphiCutGsfClean_ = iConfig.getParameter<double>("maxDPhiBremTangGsfAngularCleaning");
0268 useFifthStepForTrackDriven_ = iConfig.getParameter<bool>("useFifthStepForTrackerDrivenGsf");
0269 useFifthStepForEcalDriven_ = iConfig.getParameter<bool>("useFifthStepForEcalDrivenGsf");
0270 maxPtConvReco_ = iConfig.getParameter<double>("MaxConvBremRecoPT");
0271 detaGsfSC_ = iConfig.getParameter<double>("MinDEtaGsfSC");
0272 dphiGsfSC_ = iConfig.getParameter<double>("MinDPhiGsfSC");
0273 SCEne_ = iConfig.getParameter<double>("MinSCEnergy");
0274
0275
0276 useConvBremFinder_ = iConfig.getParameter<bool>("useConvBremFinder");
0277
0278 mvaConvBremFinderIDBarrelLowPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutBarrelLowPt");
0279 mvaConvBremFinderIDBarrelHighPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutBarrelHighPt");
0280 mvaConvBremFinderIDEndcapsLowPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutEndcapsLowPt");
0281 mvaConvBremFinderIDEndcapsHighPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutEndcapsHighPt");
0282 }
0283
0284
0285
0286
0287
0288
0289 void PFElecTkProducer::produce(Event& iEvent, const EventSetup& iSetup) {
0290
0291 auto gsfPFRecTrackCollection = std::make_unique<GsfPFRecTrackCollection>();
0292
0293 auto gsfPFRecTrackCollectionSecondary = std::make_unique<GsfPFRecTrackCollection>();
0294
0295
0296 Handle<GsfTrackCollection> gsftrackscoll;
0297 iEvent.getByToken(gsfTrackLabel_, gsftrackscoll);
0298
0299
0300 Handle<vector<Trajectory> > TrajectoryCollection;
0301
0302
0303 Handle<PFRecTrackCollection> thePfRecTrackCollection;
0304 iEvent.getByToken(pfTrackLabel_, thePfRecTrackCollection);
0305
0306
0307
0308 auto trackEtaPhiTable = makeLazy<edm::soa::EtaPhiTable>(*thePfRecTrackCollection);
0309
0310
0311 Handle<PFClusterCollection> theECPfClustCollection;
0312 iEvent.getByToken(pfEcalClusters_, theECPfClustCollection);
0313 const PFClusterCollection& theEcalClusters = *(theECPfClustCollection.product());
0314
0315
0316 Handle<reco::VertexCollection> thePrimaryVertexColl;
0317 iEvent.getByToken(primVtxLabel_, thePrimaryVertexColl);
0318
0319
0320 Handle<reco::PFDisplacedTrackerVertexCollection> pfNuclears;
0321 if (useNuclear_)
0322 iEvent.getByToken(pfNuclear_, pfNuclears);
0323
0324
0325 Handle<reco::PFConversionCollection> pfConversions;
0326 if (useConversions_)
0327 iEvent.getByToken(pfConv_, pfConversions);
0328
0329
0330 Handle<reco::PFV0Collection> pfV0;
0331 if (useV0_)
0332 iEvent.getByToken(pfV0_, pfV0);
0333
0334 GsfTrackCollection gsftracks = *(gsftrackscoll.product());
0335 vector<Trajectory> tjvec(0);
0336 if (trajinev_) {
0337 iEvent.getByToken(gsfTrackLabel_, TrajectoryCollection);
0338
0339 tjvec = *(TrajectoryCollection.product());
0340 }
0341
0342 vector<reco::GsfPFRecTrack> selGsfPFRecTracks;
0343 vector<reco::GsfPFRecTrack> primaryGsfPFRecTracks;
0344 std::map<unsigned int, std::vector<reco::GsfPFRecTrack> > GsfPFMap;
0345
0346 for (unsigned igsf = 0; igsf < gsftracks.size(); igsf++) {
0347 GsfTrackRef trackRef(gsftrackscoll, igsf);
0348 gsfInnerMomentumCache_.push_back(trackRef->pMode());
0349 TrajectoryStateOnSurface i_inTSOS = mtsTransform_.innerStateOnSurface((*trackRef));
0350 GlobalVector i_innMom;
0351 if (i_inTSOS.isValid()) {
0352 multiTrajectoryStateMode::momentumFromModeCartesian(i_inTSOS, i_innMom);
0353 gsfInnerMomentumCache_.back() = i_innMom.mag();
0354 }
0355 }
0356
0357 for (unsigned int igsf = 0; igsf < gsftracks.size(); igsf++) {
0358 GsfTrackRef trackRef(gsftrackscoll, igsf);
0359
0360 int kf_ind = findPfRef(*thePfRecTrackCollection, gsftracks[igsf], trackEtaPhiTable.value());
0361
0362 if (kf_ind >= 0) {
0363 PFRecTrackRef kf_ref(thePfRecTrackCollection, kf_ind);
0364
0365
0366 if (useFifthStepForEcalDriven_ == false || useFifthStepForTrackDriven_ == false) {
0367 bool isFifthStepTrack = PFTrackAlgoTools::isFifthStep(kf_ref->trackRef()->algo());
0368 bool isEcalDriven = true;
0369 bool isTrackerDriven = true;
0370
0371 if (trackRef->seedRef().get() == nullptr) {
0372 isEcalDriven = false;
0373 isTrackerDriven = false;
0374 } else {
0375 auto const& SeedFromRef = static_cast<ElectronSeed const&>(*(trackRef->extra()->seedRef()));
0376 if (SeedFromRef.caloCluster().isNull())
0377 isEcalDriven = false;
0378 if (SeedFromRef.ctfTrack().isNull())
0379 isTrackerDriven = false;
0380 }
0381
0382 if (isFifthStepTrack && isEcalDriven && isTrackerDriven == false && useFifthStepForEcalDriven_ == false) {
0383 continue;
0384 }
0385
0386 if (isFifthStepTrack && isTrackerDriven && isEcalDriven == false && useFifthStepForTrackDriven_ == false) {
0387 continue;
0388 }
0389
0390 if (isFifthStepTrack && isTrackerDriven && isEcalDriven && useFifthStepForTrackDriven_ == false &&
0391 useFifthStepForEcalDriven_ == false) {
0392 continue;
0393 }
0394 }
0395
0396 pftrack_ = GsfPFRecTrack(gsftracks[igsf].charge(), reco::PFRecTrack::GSF, igsf, trackRef, kf_ref);
0397 } else {
0398 PFRecTrackRef dummyRef;
0399 pftrack_ = GsfPFRecTrack(gsftracks[igsf].charge(), reco::PFRecTrack::GSF, igsf, trackRef, dummyRef);
0400 }
0401
0402 bool validgsfbrem = false;
0403 if (trajinev_) {
0404 validgsfbrem = pfTransformer_->addPointsAndBrems(pftrack_, gsftracks[igsf], tjvec[igsf], modemomentum_);
0405 } else {
0406 validgsfbrem = pfTransformer_->addPointsAndBrems(pftrack_, gsftracks[igsf], mtsTransform_);
0407 }
0408
0409 bool passSel = true;
0410 if (applySel_)
0411 passSel = applySelection(gsftracks[igsf]);
0412
0413 if (validgsfbrem && passSel)
0414 selGsfPFRecTracks.push_back(pftrack_);
0415 }
0416
0417 unsigned int count_primary = 0;
0418 if (!selGsfPFRecTracks.empty()) {
0419 for (unsigned int ipfgsf = 0; ipfgsf < selGsfPFRecTracks.size(); ipfgsf++) {
0420 vector<unsigned int> secondaries(0);
0421 secondaries.clear();
0422 bool keepGsf = true;
0423
0424 if (applyGsfClean_) {
0425 keepGsf = resolveGsfTracks(selGsfPFRecTracks, ipfgsf, secondaries, theEcalClusters);
0426 }
0427
0428
0429 if (keepGsf == true) {
0430
0431 if (convBremFinder_->foundConvBremPFRecTrack(thePfRecTrackCollection,
0432 thePrimaryVertexColl,
0433 pfNuclears,
0434 pfConversions,
0435 pfV0,
0436 globalCache(),
0437 useNuclear_,
0438 useConversions_,
0439 useV0_,
0440 theEcalClusters,
0441 selGsfPFRecTracks[ipfgsf])) {
0442 const vector<PFRecTrackRef>& convBremPFRecTracks(convBremFinder_->getConvBremPFRecTracks());
0443 for (unsigned int ii = 0; ii < convBremPFRecTracks.size(); ii++) {
0444 selGsfPFRecTracks[ipfgsf].addConvBremPFRecTrackRef(convBremPFRecTracks[ii]);
0445 }
0446 }
0447
0448
0449
0450 primaryGsfPFRecTracks.push_back(selGsfPFRecTracks[ipfgsf]);
0451
0452
0453
0454
0455 unsigned int primGsfIndex = selGsfPFRecTracks[ipfgsf].trackId();
0456 vector<reco::GsfPFRecTrack> trueGsfPFRecTracks;
0457 if (!secondaries.empty()) {
0458
0459 for (unsigned int isecpfgsf = 0; isecpfgsf < secondaries.size(); isecpfgsf++) {
0460 PFRecTrackRef refsecKF = selGsfPFRecTracks[(secondaries[isecpfgsf])].kfPFRecTrackRef();
0461
0462 unsigned int secGsfIndex = selGsfPFRecTracks[(secondaries[isecpfgsf])].trackId();
0463 GsfTrackRef secGsfRef = selGsfPFRecTracks[(secondaries[isecpfgsf])].gsfTrackRef();
0464
0465 if (refsecKF.isNonnull()) {
0466
0467 secpftrack_ = GsfPFRecTrack(
0468 gsftracks[secGsfIndex].charge(), reco::PFRecTrack::GSF, primGsfIndex, secGsfRef, refsecKF);
0469 } else {
0470 PFRecTrackRef dummyRef;
0471
0472 secpftrack_ = GsfPFRecTrack(
0473 gsftracks[secGsfIndex].charge(), reco::PFRecTrack::GSF, primGsfIndex, secGsfRef, dummyRef);
0474 }
0475
0476 bool validgsfbrem = false;
0477 if (trajinev_) {
0478 validgsfbrem = pfTransformer_->addPointsAndBrems(
0479 secpftrack_, gsftracks[secGsfIndex], tjvec[secGsfIndex], modemomentum_);
0480 } else {
0481 validgsfbrem = pfTransformer_->addPointsAndBrems(secpftrack_, gsftracks[secGsfIndex], mtsTransform_);
0482 }
0483
0484 if (validgsfbrem) {
0485 gsfPFRecTrackCollectionSecondary->push_back(secpftrack_);
0486 trueGsfPFRecTracks.push_back(secpftrack_);
0487 }
0488 }
0489 }
0490 GsfPFMap.insert(pair<unsigned int, std::vector<reco::GsfPFRecTrack> >(count_primary, trueGsfPFRecTracks));
0491 trueGsfPFRecTracks.clear();
0492 count_primary++;
0493 }
0494 }
0495 }
0496
0497 const edm::OrphanHandle<GsfPFRecTrackCollection> gsfPfRefProd =
0498 iEvent.put(std::move(gsfPFRecTrackCollectionSecondary), "Secondary");
0499
0500
0501 createGsfPFRecTrackRef(gsfPfRefProd, primaryGsfPFRecTracks, GsfPFMap);
0502
0503 for (unsigned int iGSF = 0; iGSF < primaryGsfPFRecTracks.size(); iGSF++) {
0504 gsfPFRecTrackCollection->push_back(primaryGsfPFRecTracks[iGSF]);
0505 }
0506 iEvent.put(std::move(gsfPFRecTrackCollection));
0507
0508 selGsfPFRecTracks.clear();
0509 GsfPFMap.clear();
0510 primaryGsfPFRecTracks.clear();
0511
0512 std::vector<double>().swap(gsfInnerMomentumCache_);
0513 }
0514
0515
0516 void PFElecTkProducer::createGsfPFRecTrackRef(
0517 const edm::OrphanHandle<reco::GsfPFRecTrackCollection>& gsfPfHandle,
0518 std::vector<reco::GsfPFRecTrack>& gsfPFRecTrackPrimary,
0519 const std::map<unsigned int, std::vector<reco::GsfPFRecTrack> >& MapPrimSec) {
0520 unsigned int cgsf = 0;
0521 unsigned int csecgsf = 0;
0522 for (std::map<unsigned int, std::vector<reco::GsfPFRecTrack> >::const_iterator igsf = MapPrimSec.begin();
0523 igsf != MapPrimSec.end();
0524 igsf++, cgsf++) {
0525 vector<reco::GsfPFRecTrack> SecGsfPF = igsf->second;
0526 for (unsigned int iSecGsf = 0; iSecGsf < SecGsfPF.size(); iSecGsf++) {
0527 edm::Ref<reco::GsfPFRecTrackCollection> refgprt(gsfPfHandle, csecgsf);
0528 gsfPFRecTrackPrimary[cgsf].addConvBremGsfPFRecTrackRef(refgprt);
0529 ++csecgsf;
0530 }
0531 }
0532
0533 return;
0534 }
0535
0536 int PFElecTkProducer::findPfRef(const reco::PFRecTrackCollection& pfRTkColl,
0537 const reco::GsfTrack& gsftk,
0538 edm::soa::EtaPhiTableView trackEtaPhiTable) {
0539 if (gsftk.seedRef().get() == nullptr) {
0540 return -1;
0541 }
0542
0543
0544 constexpr float maxDR2 = square(0.05f);
0545
0546
0547 float gsftkEta = gsftk.eta();
0548 float gsftkPhi = gsftk.phi();
0549 auto const& gsftkHits = gsftk.seedRef()->recHits();
0550
0551 auto const& electronSeedFromRef = static_cast<ElectronSeed const&>(*(gsftk.extra()->seedRef()));
0552
0553 if (electronSeedFromRef.ctfTrack().isNull()) {
0554 unsigned int i_pf = 0;
0555 int ibest = -1;
0556 unsigned int ish_max = 0;
0557 float dr2_min = square(1000.f);
0558
0559
0560
0561 for (auto const& pft : trackEtaPhiTable) {
0562 unsigned int ish = 0;
0563
0564 using namespace edm::soa::col;
0565 const float dr2 = reco::deltaR2(pft.get<Eta>(), pft.get<Phi>(), gsftkEta, gsftkPhi);
0566
0567 if (dr2 <= maxDR2) {
0568 for (auto const& hhit : pfRTkColl[i_pf].trackRef()->recHits()) {
0569 if (!hhit->isValid())
0570 continue;
0571 for (auto const& hit : gsftkHits) {
0572 if (hit.isValid() && hhit->sharesInput(&hit, TrackingRecHit::all))
0573 ish++;
0574 }
0575 }
0576
0577 if ((ish > ish_max) || ((ish == ish_max) && (dr2 < dr2_min))) {
0578 ish_max = ish;
0579 dr2_min = dr2;
0580 ibest = i_pf;
0581 }
0582 }
0583
0584 i_pf++;
0585 }
0586
0587 return ((ish_max == 0) || (dr2_min > maxDR2)) ? -1 : ibest;
0588 } else {
0589
0590
0591 unsigned int i_pf = 0;
0592
0593 for (auto const& pft : pfRTkColl) {
0594
0595 if (pft.trackRef() == electronSeedFromRef.ctfTrack()) {
0596 return i_pf;
0597 }
0598 i_pf++;
0599 }
0600 }
0601 return -1;
0602 }
0603
0604
0605 bool PFElecTkProducer::applySelection(const reco::GsfTrack& gsftk) {
0606 if (gsftk.seedRef().get() == nullptr)
0607 return false;
0608 auto const& ElSeedFromRef = static_cast<ElectronSeed const&>(*(gsftk.extra()->seedRef()));
0609
0610 bool passCut = false;
0611 if (ElSeedFromRef.ctfTrack().isNull()) {
0612 if (ElSeedFromRef.caloCluster().isNull())
0613 return passCut;
0614 auto const* scRef = static_cast<SuperCluster const*>(ElSeedFromRef.caloCluster().get());
0615
0616 if (scRef) {
0617 float caloEne = scRef->energy();
0618 float feta = fabs(scRef->eta() - gsftk.etaMode());
0619 float fphi = fabs(scRef->phi() - gsftk.phiMode());
0620 if (fphi > TMath::Pi())
0621 fphi -= TMath::TwoPi();
0622 if (caloEne > SCEne_ && feta < detaGsfSC_ && fabs(fphi) < dphiGsfSC_)
0623 passCut = true;
0624 }
0625 } else {
0626
0627 passCut = true;
0628 }
0629 return passCut;
0630 }
0631 bool PFElecTkProducer::resolveGsfTracks(const vector<reco::GsfPFRecTrack>& GsfPFVec,
0632 unsigned int ngsf,
0633 vector<unsigned int>& secondaries,
0634 const reco::PFClusterCollection& theEClus) {
0635 bool debugCleaning = debugGsfCleaning_;
0636 bool n_keepGsf = true;
0637
0638 const reco::GsfTrackRef& nGsfTrack = GsfPFVec[ngsf].gsfTrackRef();
0639
0640 if (nGsfTrack->seedRef().get() == nullptr)
0641 return false;
0642 auto const& nElSeedFromRef = static_cast<ElectronSeed const&>(*(nGsfTrack->extra()->seedRef()));
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653 float nPin = gsfInnerMomentumCache_[nGsfTrack.key()];
0654
0655 float neta = nGsfTrack->innerMomentum().eta();
0656 float nphi = nGsfTrack->innerMomentum().phi();
0657
0658 if (debugCleaning)
0659 cout << " PFElecTkProducer:: considering track " << nGsfTrack->pt() << " eta,phi " << nGsfTrack->eta() << ", "
0660 << nGsfTrack->phi() << endl;
0661
0662 for (unsigned int igsf = 0; igsf < GsfPFVec.size(); igsf++) {
0663 if (igsf != ngsf) {
0664 reco::GsfTrackRef iGsfTrack = GsfPFVec[igsf].gsfTrackRef();
0665
0666 if (debugCleaning)
0667 cout << " PFElecTkProducer:: and comparing with track " << iGsfTrack->pt() << " eta,phi " << iGsfTrack->eta()
0668 << ", " << iGsfTrack->phi() << endl;
0669
0670 float ieta = iGsfTrack->innerMomentum().eta();
0671 float iphi = iGsfTrack->innerMomentum().phi();
0672 float feta = fabs(neta - ieta);
0673 float fphi = fabs(nphi - iphi);
0674 if (fphi > TMath::Pi())
0675 fphi -= TMath::TwoPi();
0676
0677
0678 if (feta < 0.5 && fabs(fphi) < 1.0) {
0679 if (debugCleaning)
0680 cout << " Entering angular superloose preselection " << endl;
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691 float iPin = gsfInnerMomentumCache_[iGsfTrack.key()];
0692
0693 if (iGsfTrack->seedRef().get() == nullptr)
0694 continue;
0695 auto const& iElSeedFromRef = static_cast<ElectronSeed const&>(*(iGsfTrack->extra()->seedRef()));
0696
0697 float SCEnergy = -1.;
0698
0699 bool areBothGsfEcalDriven = false;
0700 ;
0701 bool isSameSC = isSameEgSC(nElSeedFromRef, iElSeedFromRef, areBothGsfEcalDriven, SCEnergy);
0702
0703
0704 if (areBothGsfEcalDriven) {
0705 if (isSameSC) {
0706 float nEP = SCEnergy / nPin;
0707 float iEP = SCEnergy / iPin;
0708 if (debugCleaning)
0709 cout << " Entering SAME supercluster case "
0710 << " nEP " << nEP << " iEP " << iEP << endl;
0711
0712
0713
0714
0715
0716 bool isSameLayer = false;
0717 bool iGsfInnermostWithLostHits = isInnerMostWithLostHits(nGsfTrack, iGsfTrack, isSameLayer);
0718
0719 if (debugCleaning)
0720 cout << " iGsf is InnerMostWithLostHits " << iGsfInnermostWithLostHits << " isSameLayer " << isSameLayer
0721 << endl;
0722
0723 if (iGsfInnermostWithLostHits) {
0724 n_keepGsf = false;
0725 return n_keepGsf;
0726 } else if (isSameLayer) {
0727 if (fabs(iEP - 1) < fabs(nEP - 1)) {
0728 n_keepGsf = false;
0729 return n_keepGsf;
0730 } else {
0731 secondaries.push_back(igsf);
0732 }
0733 } else {
0734
0735 secondaries.push_back(igsf);
0736 }
0737 }
0738 } else {
0739
0740 float minBremDphi = minTangDist(GsfPFVec[ngsf], GsfPFVec[igsf]);
0741 float nETot = 0.;
0742 float iETot = 0.;
0743 bool isBothGsfTrackerDriven = false;
0744 bool nEcalDriven = false;
0745 bool iEcalDriven = false;
0746 bool isSameScEgPf = isSharingEcalEnergyWithEgSC(GsfPFVec[ngsf],
0747 GsfPFVec[igsf],
0748 nElSeedFromRef,
0749 iElSeedFromRef,
0750 theEClus,
0751 isBothGsfTrackerDriven,
0752 nEcalDriven,
0753 iEcalDriven,
0754 nETot,
0755 iETot);
0756
0757
0758 bool isSameLayer = false;
0759 bool iGsfInnermostWithLostHits = isInnerMostWithLostHits(nGsfTrack, iGsfTrack, isSameLayer);
0760
0761 if (isSameScEgPf) {
0762
0763
0764 if (debugCleaning) {
0765 cout << " Sharing ECAL energy passed "
0766 << " nEtot " << nETot << " iEtot " << iETot << endl;
0767 if (isBothGsfTrackerDriven)
0768 cout << " Both Track are trackerDriven " << endl;
0769 }
0770
0771
0772 if (iGsfInnermostWithLostHits) {
0773 n_keepGsf = false;
0774 return n_keepGsf;
0775 } else if (isSameLayer) {
0776
0777
0778
0779
0780
0781
0782
0783 if (isBothGsfTrackerDriven == false) {
0784
0785 if (iEcalDriven) {
0786 n_keepGsf = false;
0787 return n_keepGsf;
0788 } else {
0789 secondaries.push_back(igsf);
0790 }
0791 } else {
0792
0793
0794
0795 float ETot = -1;
0796 if (nETot != iETot) {
0797 if (nETot > iETot)
0798 ETot = nETot;
0799 else
0800 ETot = iETot;
0801 } else {
0802 ETot = nETot;
0803 }
0804 float nEP = ETot / nPin;
0805 float iEP = ETot / iPin;
0806
0807 if (debugCleaning)
0808 cout << " nETot " << nETot << " iETot " << iETot << " ETot " << ETot << endl
0809 << " nPin " << nPin << " iPin " << iPin << " nEP " << nEP << " iEP " << iEP << endl;
0810
0811 if (fabs(iEP - 1) < fabs(nEP - 1)) {
0812 n_keepGsf = false;
0813 return n_keepGsf;
0814 } else {
0815 secondaries.push_back(igsf);
0816 }
0817 }
0818 } else {
0819 secondaries.push_back(igsf);
0820 }
0821 } else if (feta < detaCutGsfClean_ && minBremDphi < dphiCutGsfClean_) {
0822
0823 bool secPushedBack = false;
0824 if (nEcalDriven == false && nETot == 0.) {
0825 n_keepGsf = false;
0826 return n_keepGsf;
0827 } else if (iEcalDriven == false && iETot == 0.) {
0828 secondaries.push_back(igsf);
0829 secPushedBack = true;
0830 }
0831 if (debugCleaning)
0832 cout << " Close Tracks "
0833 << " feta " << feta << " fabs(fphi) " << fabs(fphi) << " minBremDphi " << minBremDphi << " nETot "
0834 << nETot << " iETot " << iETot << " nLostHits " << nGsfTrack->missingInnerHits() << " iLostHits "
0835 << iGsfTrack->missingInnerHits() << endl;
0836
0837
0838 if (applyAngularGsfClean_) {
0839 if (iGsfInnermostWithLostHits) {
0840 n_keepGsf = false;
0841 return n_keepGsf;
0842 } else if (isSameLayer == false) {
0843 if (secPushedBack == false)
0844 secondaries.push_back(igsf);
0845 }
0846 }
0847 } else if (feta < 0.1 && minBremDphi < 0.2) {
0848
0849
0850 if (debugCleaning)
0851 cout << " Close Tracks and failed all the conditions "
0852 << " feta " << feta << " fabs(fphi) " << fabs(fphi) << " minBremDphi " << minBremDphi << " nETot "
0853 << nETot << " iETot " << iETot << " nLostHits " << nGsfTrack->missingInnerHits() << " iLostHits "
0854 << iGsfTrack->missingInnerHits() << endl;
0855
0856 if (nEcalDriven == false && nETot == 0.) {
0857 n_keepGsf = false;
0858 return n_keepGsf;
0859 }
0860
0861 }
0862 }
0863 }
0864 }
0865 }
0866
0867 return n_keepGsf;
0868 }
0869 float PFElecTkProducer::minTangDist(const reco::GsfPFRecTrack& primGsf, const reco::GsfPFRecTrack& secGsf) {
0870 float minDphi = 1000.;
0871
0872 std::vector<reco::PFBrem> primPFBrem = primGsf.PFRecBrem();
0873 std::vector<reco::PFBrem> secPFBrem = secGsf.PFRecBrem();
0874
0875 unsigned int cbrem = 0;
0876 for (unsigned isbrem = 0; isbrem < secPFBrem.size(); isbrem++) {
0877 if (secPFBrem[isbrem].indTrajPoint() == 99)
0878 continue;
0879 const reco::PFTrajectoryPoint& atSecECAL =
0880 secPFBrem[isbrem].extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance);
0881 if (!atSecECAL.isValid())
0882 continue;
0883 float secPhi = atSecECAL.positionREP().Phi();
0884
0885 unsigned int sbrem = 0;
0886 for (unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
0887 if (primPFBrem[ipbrem].indTrajPoint() == 99)
0888 continue;
0889 const reco::PFTrajectoryPoint& atPrimECAL =
0890 primPFBrem[ipbrem].extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance);
0891 if (!atPrimECAL.isValid())
0892 continue;
0893 sbrem++;
0894 if (sbrem <= 3) {
0895 float primPhi = atPrimECAL.positionREP().Phi();
0896
0897 float dphi = fabs(primPhi - secPhi);
0898 if (dphi > TMath::Pi())
0899 dphi -= TMath::TwoPi();
0900 if (fabs(dphi) < minDphi) {
0901 minDphi = fabs(dphi);
0902 }
0903 }
0904 }
0905
0906 cbrem++;
0907 if (cbrem == 3)
0908 break;
0909 }
0910 return minDphi;
0911 }
0912 bool PFElecTkProducer::isSameEgSC(const reco::ElectronSeed& nSeed,
0913 const reco::ElectronSeed& iSeed,
0914 bool& bothGsfEcalDriven,
0915 float& SCEnergy) {
0916 bool isSameSC = false;
0917
0918 if (nSeed.caloCluster().isNonnull() && iSeed.caloCluster().isNonnull()) {
0919 auto const* nscRef = static_cast<SuperCluster const*>(nSeed.caloCluster().get());
0920 auto const* iscRef = static_cast<SuperCluster const*>(iSeed.caloCluster().get());
0921
0922 if (nscRef && iscRef) {
0923 bothGsfEcalDriven = true;
0924 if (nscRef == iscRef) {
0925 isSameSC = true;
0926
0927 SCEnergy = nscRef->energy();
0928 }
0929 }
0930 }
0931 return isSameSC;
0932 }
0933 bool PFElecTkProducer::isSharingEcalEnergyWithEgSC(const reco::GsfPFRecTrack& nGsfPFRecTrack,
0934 const reco::GsfPFRecTrack& iGsfPFRecTrack,
0935 const reco::ElectronSeed& nSeed,
0936 const reco::ElectronSeed& iSeed,
0937 const reco::PFClusterCollection& theEClus,
0938 bool& bothGsfTrackerDriven,
0939 bool& nEcalDriven,
0940 bool& iEcalDriven,
0941 float& nEnergy,
0942 float& iEnergy) {
0943 bool isSharingEnergy = false;
0944
0945
0946 bool oneEcalDriven = true;
0947 SuperCluster const* scRef = nullptr;
0948 GsfPFRecTrack gsfPfTrack;
0949
0950 if (nSeed.caloCluster().isNonnull()) {
0951 scRef = static_cast<SuperCluster const*>(nSeed.caloCluster().get());
0952 assert(scRef);
0953 nEnergy = scRef->energy();
0954 nEcalDriven = true;
0955 gsfPfTrack = iGsfPFRecTrack;
0956 } else if (iSeed.caloCluster().isNonnull()) {
0957 scRef = static_cast<SuperCluster const*>(iSeed.caloCluster().get());
0958 assert(scRef);
0959 iEnergy = scRef->energy();
0960 iEcalDriven = true;
0961 gsfPfTrack = nGsfPFRecTrack;
0962 } else {
0963 oneEcalDriven = false;
0964 }
0965
0966 if (oneEcalDriven) {
0967
0968
0969 vector<PFCluster> vecPFClusters;
0970 vecPFClusters.clear();
0971
0972 for (PFClusterCollection::const_iterator clus = theEClus.begin(); clus != theEClus.end(); clus++) {
0973 PFCluster clust = *clus;
0974 clust.calculatePositionREP();
0975
0976 float deta = fabs(scRef->position().eta() - clust.position().eta());
0977 float dphi = fabs(scRef->position().phi() - clust.position().phi());
0978 if (dphi > TMath::Pi())
0979 dphi -= TMath::TwoPi();
0980
0981
0982
0983 if (deta < 0.5 && fabs(dphi) < 1.0) {
0984 double distGsf = gsfPfTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALShowerMax).isValid()
0985 ? LinkByRecHit::testTrackAndClusterByRecHit(gsfPfTrack, clust)
0986 : -1.;
0987
0988 if (distGsf > 0.) {
0989 if (nEcalDriven)
0990 iEnergy += clust.energy();
0991 else
0992 nEnergy += clust.energy();
0993 vecPFClusters.push_back(clust);
0994 }
0995
0996 else {
0997 vector<PFBrem> primPFBrem = gsfPfTrack.PFRecBrem();
0998 for (unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
0999 if (primPFBrem[ipbrem].indTrajPoint() == 99)
1000 continue;
1001 const reco::PFRecTrack& pfBremTrack = primPFBrem[ipbrem];
1002 double dist = pfBremTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALShowerMax).isValid()
1003 ? LinkByRecHit::testTrackAndClusterByRecHit(pfBremTrack, clust, true)
1004 : -1.;
1005 if (dist > 0.) {
1006 if (nEcalDriven)
1007 iEnergy += clust.energy();
1008 else
1009 nEnergy += clust.energy();
1010 vecPFClusters.push_back(clust);
1011 }
1012 }
1013 }
1014 }
1015 }
1016 if (!vecPFClusters.empty()) {
1017 for (unsigned int pf = 0; pf < vecPFClusters.size(); pf++) {
1018 bool isCommon = ClusterClusterMapping::overlap(vecPFClusters[pf], *scRef);
1019 if (isCommon) {
1020 isSharingEnergy = true;
1021 }
1022 break;
1023 }
1024 }
1025 } else {
1026
1027
1028 bothGsfTrackerDriven = true;
1029 vector<PFCluster> nPFCluster;
1030 vector<PFCluster> iPFCluster;
1031
1032 nPFCluster.clear();
1033 iPFCluster.clear();
1034
1035 for (PFClusterCollection::const_iterator clus = theEClus.begin(); clus != theEClus.end(); clus++) {
1036 PFCluster clust = *clus;
1037 clust.calculatePositionREP();
1038
1039 float ndeta = fabs(nGsfPFRecTrack.gsfTrackRef()->eta() - clust.position().eta());
1040 float ndphi = fabs(nGsfPFRecTrack.gsfTrackRef()->phi() - clust.position().phi());
1041 if (ndphi > TMath::Pi())
1042 ndphi -= TMath::TwoPi();
1043
1044
1045 if (ndeta < 0.5 && fabs(ndphi) < 1.0) {
1046 double distGsf = nGsfPFRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALShowerMax).isValid()
1047 ? LinkByRecHit::testTrackAndClusterByRecHit(nGsfPFRecTrack, clust)
1048 : -1.;
1049 if (distGsf > 0.) {
1050 nPFCluster.push_back(clust);
1051 nEnergy += clust.energy();
1052 } else {
1053 const vector<PFBrem>& primPFBrem = nGsfPFRecTrack.PFRecBrem();
1054 for (unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
1055 if (primPFBrem[ipbrem].indTrajPoint() == 99)
1056 continue;
1057 const reco::PFRecTrack& pfBremTrack = primPFBrem[ipbrem];
1058 double dist = pfBremTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALShowerMax).isValid()
1059 ? LinkByRecHit::testTrackAndClusterByRecHit(pfBremTrack, clust, true)
1060 : -1.;
1061 if (dist > 0.) {
1062 nPFCluster.push_back(clust);
1063 nEnergy += clust.energy();
1064 break;
1065 }
1066 }
1067 }
1068 }
1069
1070 float ideta = fabs(iGsfPFRecTrack.gsfTrackRef()->eta() - clust.position().eta());
1071 float idphi = fabs(iGsfPFRecTrack.gsfTrackRef()->phi() - clust.position().phi());
1072 if (idphi > TMath::Pi())
1073 idphi -= TMath::TwoPi();
1074
1075
1076 if (ideta < 0.5 && fabs(idphi) < 1.0) {
1077 double dist = iGsfPFRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALShowerMax).isValid()
1078 ? LinkByRecHit::testTrackAndClusterByRecHit(iGsfPFRecTrack, clust)
1079 : -1.;
1080 if (dist > 0.) {
1081 iPFCluster.push_back(clust);
1082 iEnergy += clust.energy();
1083 } else {
1084 vector<PFBrem> primPFBrem = iGsfPFRecTrack.PFRecBrem();
1085 for (unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
1086 if (primPFBrem[ipbrem].indTrajPoint() == 99)
1087 continue;
1088 const reco::PFRecTrack& pfBremTrack = primPFBrem[ipbrem];
1089 double dist = LinkByRecHit::testTrackAndClusterByRecHit(pfBremTrack, clust, true);
1090 if (dist > 0.) {
1091 iPFCluster.push_back(clust);
1092 iEnergy += clust.energy();
1093 break;
1094 }
1095 }
1096 }
1097 }
1098 }
1099
1100 if (!nPFCluster.empty() && !iPFCluster.empty()) {
1101 for (unsigned int npf = 0; npf < nPFCluster.size(); npf++) {
1102 for (unsigned int ipf = 0; ipf < iPFCluster.size(); ipf++) {
1103 bool isCommon = ClusterClusterMapping::overlap(nPFCluster[npf], iPFCluster[ipf]);
1104 if (isCommon) {
1105 isSharingEnergy = true;
1106 break;
1107 }
1108 }
1109 if (isSharingEnergy)
1110 break;
1111 }
1112 }
1113 }
1114
1115 return isSharingEnergy;
1116 }
1117 bool PFElecTkProducer::isInnerMost(const reco::GsfTrackRef& nGsfTrack,
1118 const reco::GsfTrackRef& iGsfTrack,
1119 bool& sameLayer) {
1120
1121
1122
1123 const reco::HitPattern& gsfHitPattern1 = nGsfTrack->hitPattern();
1124 const reco::HitPattern& gsfHitPattern2 = iGsfTrack->hitPattern();
1125
1126
1127 int gsfHitCounter1 = 0;
1128 for (auto const& hit : nGsfTrack->recHits()) {
1129 if (hit->isValid())
1130 break;
1131 gsfHitCounter1++;
1132 }
1133
1134 int gsfHitCounter2 = 0;
1135 for (auto const& hit : iGsfTrack->recHits()) {
1136 if (hit->isValid())
1137 break;
1138 gsfHitCounter2++;
1139 }
1140
1141 uint32_t gsfHit1 = gsfHitPattern1.getHitPattern(HitPattern::TRACK_HITS, gsfHitCounter1);
1142 uint32_t gsfHit2 = gsfHitPattern2.getHitPattern(HitPattern::TRACK_HITS, gsfHitCounter2);
1143
1144 if (gsfHitPattern1.getSubStructure(gsfHit1) != gsfHitPattern2.getSubStructure(gsfHit2)) {
1145 return (gsfHitPattern2.getSubStructure(gsfHit2) < gsfHitPattern1.getSubStructure(gsfHit1));
1146 } else if (gsfHitPattern1.getLayer(gsfHit1) != gsfHitPattern2.getLayer(gsfHit2)) {
1147 return (gsfHitPattern2.getLayer(gsfHit2) < gsfHitPattern1.getLayer(gsfHit1));
1148 } else {
1149 sameLayer = true;
1150 return false;
1151 }
1152 }
1153 bool PFElecTkProducer::isInnerMostWithLostHits(const reco::GsfTrackRef& nGsfTrack,
1154 const reco::GsfTrackRef& iGsfTrack,
1155 bool& sameLayer) {
1156
1157 unsigned int nLostHits = nGsfTrack->missingInnerHits();
1158 unsigned int iLostHits = iGsfTrack->missingInnerHits();
1159
1160 if (nLostHits != iLostHits) {
1161 return (nLostHits > iLostHits);
1162 } else {
1163 sameLayer = true;
1164 return false;
1165 }
1166 }
1167
1168
1169 void PFElecTkProducer::beginRun(const edm::Run& run, const EventSetup& iSetup) {
1170 auto const& magneticField = &iSetup.getData(magFieldToken_);
1171 auto const& tracker = &iSetup.getData(tkerGeomToken_);
1172
1173 mtsTransform_ = MultiTrajectoryStateTransform(tracker, magneticField);
1174
1175 pfTransformer_ = std::make_unique<PFTrackTransformer>(math::XYZVector(magneticField->inTesla(GlobalPoint(0, 0, 0))));
1176
1177 TransientTrackBuilder thebuilder = iSetup.getData(transientTrackToken_);
1178
1179 convBremFinder_ = std::make_unique<ConvBremPFTrackFinder>(thebuilder,
1180 mvaConvBremFinderIDBarrelLowPt_,
1181 mvaConvBremFinderIDBarrelHighPt_,
1182 mvaConvBremFinderIDEndcapsLowPt_,
1183 mvaConvBremFinderIDEndcapsHighPt_);
1184 }
1185
1186
1187 void PFElecTkProducer::endRun(const edm::Run& run, const EventSetup& iSetup) {
1188 pfTransformer_.reset();
1189 convBremFinder_.reset();
1190 }
1191
1192
1193 #include "FWCore/Framework/interface/MakerMacros.h"
1194 DEFINE_FWK_MODULE(PFElecTkProducer);