00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <memory>
00013
00014
00015 #include "RecoParticleFlow/PFTracking/interface/PFElecTkProducer.h"
00016 #include "RecoParticleFlow/PFTracking/interface/PFTrackTransformer.h"
00017 #include "RecoParticleFlow/PFTracking/interface/ConvBremPFTrackFinder.h"
00018 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
00019 #include "MagneticField/Engine/interface/MagneticField.h"
00020 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00021 #include "FWCore/Framework/interface/ESHandle.h"
00022 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00023 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00024 #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
00025 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h"
00026 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
00027 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00028 #include "DataFormats/EgammaReco/interface/ElectronSeedFwd.h"
00029 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00030 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00031 #include "MagneticField/Engine/interface/MagneticField.h"
00032 #include "DataFormats/ParticleFlowReco/interface/PFClusterFwd.h"
00033 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00034 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00035 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00036 #include "DataFormats/VertexReco/interface/Vertex.h"
00037 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00038 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedTrackerVertex.h"
00039 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedVertexFwd.h"
00040 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedVertex.h"
00041 #include "DataFormats/ParticleFlowReco/interface/PFConversionFwd.h"
00042 #include "DataFormats/ParticleFlowReco/interface/PFConversion.h"
00043 #include "DataFormats/ParticleFlowReco/interface/PFV0Fwd.h"
00044 #include "DataFormats/ParticleFlowReco/interface/PFV0.h"
00045
00046 #include "TMath.h"
00047 using namespace std;
00048 using namespace edm;
00049 using namespace reco;
00050 PFElecTkProducer::PFElecTkProducer(const ParameterSet& iConfig):
00051 conf_(iConfig),
00052 pfTransformer_(0),
00053 convBremFinder_(0)
00054 {
00055 LogInfo("PFElecTkProducer")<<"PFElecTkProducer started";
00056
00057 gsfTrackLabel_ = iConfig.getParameter<InputTag>
00058 ("GsfTrackModuleLabel");
00059
00060 pfTrackLabel_ = iConfig.getParameter<InputTag>
00061 ("PFRecTrackLabel");
00062
00063 primVtxLabel_ = iConfig.getParameter<InputTag>
00064 ("PrimaryVertexLabel");
00065
00066 pfEcalClusters_ = iConfig.getParameter<InputTag>
00067 ("PFEcalClusters");
00068
00069 pfNuclear_ = iConfig.getParameter<InputTag>
00070 ("PFNuclear");
00071
00072 pfConv_ = iConfig.getParameter<InputTag>
00073 ("PFConversions");
00074
00075 pfV0_ = iConfig.getParameter<InputTag>
00076 ("PFV0");
00077
00078 useNuclear_ = iConfig.getParameter<bool>("useNuclear");
00079 useConversions_ = iConfig.getParameter<bool>("useConversions");
00080 useV0_ = iConfig.getParameter<bool>("useV0");
00081
00082
00083 produces<GsfPFRecTrackCollection>();
00084 produces<GsfPFRecTrackCollection>( "Secondary" ).setBranchAlias( "secondary" );
00085
00086
00087 trajinev_ = iConfig.getParameter<bool>("TrajInEvents");
00088 modemomentum_ = iConfig.getParameter<bool>("ModeMomentum");
00089 applySel_ = iConfig.getParameter<bool>("applyEGSelection");
00090 applyGsfClean_ = iConfig.getParameter<bool>("applyGsfTrackCleaning");
00091 useFifthStep_ = iConfig.getParameter<bool>("useFifthTrackingStep");
00092 useFifthStepSec_ = iConfig.getParameter<bool>("useFifthTrackingStepForSecondaries");
00093 maxPtConvReco_ = iConfig.getParameter<double>("MaxConvBremRecoPT");
00094 detaGsfSC_ = iConfig.getParameter<double>("MinDEtaGsfSC");
00095 dphiGsfSC_ = iConfig.getParameter<double>("MinDPhiGsfSC");
00096 SCEne_ = iConfig.getParameter<double>("MinSCEnergy");
00097
00098
00099 useConvBremFinder_ = iConfig.getParameter<bool>("useConvBremFinder");
00100 mvaConvBremFinderID_
00101 = iConfig.getParameter<double>("pf_convBremFinderID_mvaCut");
00102
00103 string mvaWeightFileConvBrem
00104 = iConfig.getParameter<string>("pf_convBremFinderID_mvaWeightFile");
00105
00106
00107 if(useConvBremFinder_)
00108 path_mvaWeightFileConvBrem_ = edm::FileInPath ( mvaWeightFileConvBrem.c_str() ).fullPath();
00109
00110 }
00111
00112
00113 PFElecTkProducer::~PFElecTkProducer()
00114 {
00115
00116 delete pfTransformer_;
00117 delete convBremFinder_;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 void
00127 PFElecTkProducer::produce(Event& iEvent, const EventSetup& iSetup)
00128 {
00129 LogDebug("PFElecTkProducer")<<"START event: "<<iEvent.id().event()
00130 <<" in run "<<iEvent.id().run();
00131
00132
00133 auto_ptr< GsfPFRecTrackCollection >
00134 gsfPFRecTrackCollection(new GsfPFRecTrackCollection);
00135
00136
00137 auto_ptr< GsfPFRecTrackCollection >
00138 gsfPFRecTrackCollectionSecondary(new GsfPFRecTrackCollection);
00139
00140
00141 Handle<GsfTrackCollection> gsftrackscoll;
00142 iEvent.getByLabel(gsfTrackLabel_,gsftrackscoll);
00143
00144
00145 Handle<vector<Trajectory> > TrajectoryCollection;
00146
00147
00148 Handle<PFRecTrackCollection> thePfRecTrackCollection;
00149 iEvent.getByLabel(pfTrackLabel_,thePfRecTrackCollection);
00150 const PFRecTrackCollection& PfRTkColl = *(thePfRecTrackCollection.product());
00151
00152
00153 Handle<PFClusterCollection> theECPfClustCollection;
00154 iEvent.getByLabel(pfEcalClusters_,theECPfClustCollection);
00155 const PFClusterCollection& theEcalClusters = *(theECPfClustCollection.product());
00156
00157
00158 Handle<reco::VertexCollection> thePrimaryVertexColl;
00159 iEvent.getByLabel(primVtxLabel_,thePrimaryVertexColl);
00160
00161
00162
00163
00164 Handle< reco::PFDisplacedTrackerVertexCollection > pfNuclears;
00165 if( useNuclear_ ) {
00166 bool found = iEvent.getByLabel(pfNuclear_, pfNuclears);
00167
00168
00169 if(!found )
00170 LogError("PFElecTkProducer")<<" cannot get PFNuclear : "
00171 << pfNuclear_
00172 << " please set useNuclear=False in RecoParticleFlow/PFTracking/python/pfTrackElec_cfi.py" << endl;
00173 }
00174
00175
00176 Handle< reco::PFConversionCollection > pfConversions;
00177 if( useConversions_ ) {
00178 bool found = iEvent.getByLabel(pfConv_,pfConversions);
00179 if(!found )
00180 LogError("PFElecTkProducer")<<" cannot get PFConversions : "
00181 << pfConv_
00182 << " please set useConversions=False in RecoParticleFlow/PFTracking/python/pfTrackElec_cfi.py" << endl;
00183 }
00184
00185
00186 Handle< reco::PFV0Collection > pfV0;
00187 if( useV0_ ) {
00188 bool found = iEvent.getByLabel(pfV0_, pfV0);
00189
00190 if(!found )
00191 LogError("PFElecTkProducer")<<" cannot get PFV0 : "
00192 << pfV0_
00193 << " please set useV0=False RecoParticleFlow/PFTracking/python/pfTrackElec_cfi.py" << endl;
00194 }
00195
00196
00197
00198 GsfTrackCollection gsftracks = *(gsftrackscoll.product());
00199 vector<Trajectory> tjvec(0);
00200 if (trajinev_){
00201 bool foundTraj = iEvent.getByLabel(gsfTrackLabel_,TrajectoryCollection);
00202 if(!foundTraj)
00203 LogError("PFElecTkProducer")
00204 <<" cannot get Trajectories of : "
00205 << gsfTrackLabel_
00206 << " please set TrajInEvents = False in RecoParticleFlow/PFTracking/python/pfTrackElec_cfi.py" << endl;
00207
00208 tjvec= *(TrajectoryCollection.product());
00209 }
00210
00211
00212 vector<reco::GsfPFRecTrack> selGsfPFRecTracks(0);
00213 selGsfPFRecTracks.clear();
00214
00215
00216 for (unsigned int igsf=0; igsf<gsftracks.size();igsf++) {
00217
00218 GsfTrackRef trackRef(gsftrackscoll, igsf);
00219
00220 int kf_ind=FindPfRef(PfRTkColl,gsftracks[igsf],false);
00221
00222 if (kf_ind>=0) {
00223
00224 PFRecTrackRef kf_ref(thePfRecTrackCollection,
00225 kf_ind);
00226 pftrack_=GsfPFRecTrack( gsftracks[igsf].charge(),
00227 reco::PFRecTrack::GSF,
00228 igsf, trackRef,
00229 kf_ref);
00230 } else {
00231 PFRecTrackRef dummyRef;
00232 pftrack_=GsfPFRecTrack( gsftracks[igsf].charge(),
00233 reco::PFRecTrack::GSF,
00234 igsf, trackRef,
00235 dummyRef);
00236 }
00237
00238
00239 bool validgsfbrem = false;
00240 if(trajinev_) {
00241 validgsfbrem = pfTransformer_->addPointsAndBrems(pftrack_,
00242 gsftracks[igsf],
00243 tjvec[igsf],
00244 modemomentum_);
00245 } else {
00246 validgsfbrem = pfTransformer_->addPointsAndBrems(pftrack_,
00247 gsftracks[igsf],
00248 mtsTransform_);
00249 }
00250
00251 bool passSel = true;
00252 if(applySel_)
00253 passSel = applySelection(gsftracks[igsf]);
00254
00255
00256 if(validgsfbrem && passSel)
00257 selGsfPFRecTracks.push_back(pftrack_);
00258 }
00259 if(selGsfPFRecTracks.size() > 0) {
00260 for(unsigned int ipfgsf=0; ipfgsf<selGsfPFRecTracks.size();ipfgsf++) {
00261
00262 vector<unsigned int> secondaries(0);
00263 secondaries.clear();
00264 bool keepGsf = true;
00265
00266 if(applyGsfClean_) {
00267 keepGsf = resolveGsfTracks(selGsfPFRecTracks,ipfgsf,secondaries);
00268 }
00269
00270
00271 if(keepGsf == true) {
00272 PFRecTrackRef refprimKF = selGsfPFRecTracks[ipfgsf].kfPFRecTrackRef();
00273
00274
00275 if(refprimKF.isNonnull()) {
00276 if(useFifthStep_ == false) {
00277 bool isFifthStepTrack = isFifthStep(refprimKF);
00278 if(isFifthStepTrack)
00279 continue;
00280 }
00281 }
00282
00283
00284
00285 if(convBremFinder_->foundConvBremPFRecTrack(thePfRecTrackCollection,thePrimaryVertexColl,
00286 pfNuclears,pfConversions,pfV0,
00287 useNuclear_,useConversions_,useV0_,
00288 theEcalClusters,selGsfPFRecTracks[ipfgsf])) {
00289 const vector<PFRecTrackRef>& convBremPFRecTracks (convBremFinder_->getConvBremPFRecTracks());
00290 for(unsigned int ii = 0; ii<convBremPFRecTracks.size(); ii++) {
00291 selGsfPFRecTracks[ipfgsf].addConvBremPFRecTrackRef(convBremPFRecTracks[ii]);
00292 }
00293 }
00294
00295
00296 gsfPFRecTrackCollection->push_back(selGsfPFRecTracks[ipfgsf]);
00297
00298
00299
00300
00301
00302
00303 unsigned int primGsfIndex = selGsfPFRecTracks[ipfgsf].trackId();
00304 if(secondaries.size() > 0) {
00305
00306 for(unsigned int isecpfgsf=0; isecpfgsf<secondaries.size();isecpfgsf++) {
00307
00308 PFRecTrackRef refsecKF = selGsfPFRecTracks[(secondaries[isecpfgsf])].kfPFRecTrackRef();
00309
00310
00311 if(refsecKF.isNonnull()) {
00312 if(useFifthStepSec_ == false) {
00313 bool isFifthStepTrack = isFifthStep(refsecKF);
00314 if(isFifthStepTrack)
00315 continue;
00316 }
00317 }
00318
00319 unsigned int secGsfIndex = selGsfPFRecTracks[(secondaries[isecpfgsf])].trackId();
00320 GsfTrackRef secGsfRef = selGsfPFRecTracks[(secondaries[isecpfgsf])].gsfTrackRef();
00321
00322 if(refsecKF.isNonnull()) {
00323
00324 secpftrack_= GsfPFRecTrack( gsftracks[secGsfIndex].charge(),
00325 reco::PFRecTrack::GSF,
00326 primGsfIndex, secGsfRef,
00327 refsecKF);
00328 }
00329 else{
00330 PFRecTrackRef dummyRef;
00331
00332 secpftrack_= GsfPFRecTrack( gsftracks[secGsfIndex].charge(),
00333 reco::PFRecTrack::GSF,
00334 primGsfIndex, secGsfRef,
00335 dummyRef);
00336 }
00337
00338 bool validgsfbrem = false;
00339 if(trajinev_) {
00340 validgsfbrem = pfTransformer_->addPointsAndBrems(secpftrack_,
00341 gsftracks[secGsfIndex],
00342 tjvec[secGsfIndex],
00343 modemomentum_);
00344 } else {
00345 validgsfbrem = pfTransformer_->addPointsAndBrems(secpftrack_,
00346 gsftracks[secGsfIndex],
00347 mtsTransform_);
00348 }
00349
00350 if(validgsfbrem)
00351 gsfPFRecTrackCollectionSecondary->push_back(secpftrack_);
00352 }
00353 }
00354 }
00355 }
00356 }
00357
00358 iEvent.put(gsfPFRecTrackCollection);
00359 iEvent.put(gsfPFRecTrackCollectionSecondary,"Secondary");
00360
00361
00362 }
00363
00364 int
00365 PFElecTkProducer::FindPfRef(const reco::PFRecTrackCollection & PfRTkColl,
00366 reco::GsfTrack gsftk,
00367 bool otherColl){
00368
00369
00370 if (&(*gsftk.seedRef())==0) return -1;
00371 ElectronSeedRef ElSeedRef=gsftk.extra()->seedRef().castTo<ElectronSeedRef>();
00372
00373 if (ElSeedRef->ctfTrack().isNull()){
00374 reco::PFRecTrackCollection::const_iterator pft=PfRTkColl.begin();
00375 reco::PFRecTrackCollection::const_iterator pftend=PfRTkColl.end();
00376 unsigned int i_pf=0;
00377 int ibest=-1;
00378 unsigned int ish_max=0;
00379 float dr_min=1000;
00380
00381 for(;pft!=pftend;++pft){
00382 unsigned int ish=0;
00383
00384 float dph= fabs(pft->trackRef()->phi()-gsftk.phi());
00385 if (dph>TMath::Pi()) dph-= TMath::TwoPi();
00386 float det=fabs(pft->trackRef()->eta()-gsftk.eta());
00387 float dr =sqrt(dph*dph+det*det);
00388
00389 trackingRecHit_iterator hhit=
00390 pft->trackRef()->recHitsBegin();
00391 trackingRecHit_iterator hhit_end=
00392 pft->trackRef()->recHitsEnd();
00393
00394
00395
00396 for(;hhit!=hhit_end;++hhit){
00397 if (!(*hhit)->isValid()) continue;
00398 TrajectorySeed::const_iterator hit=
00399 gsftk.seedRef()->recHits().first;
00400 TrajectorySeed::const_iterator hit_end=
00401 gsftk.seedRef()->recHits().second;
00402 for(;hit!=hit_end;++hit){
00403 if (!(hit->isValid())) continue;
00404 if((*hhit)->sharesInput(&*(hit),TrackingRecHit::all)) ish++;
00405
00406
00407 }
00408
00409 }
00410
00411
00412 if ((ish>ish_max)||
00413 ((ish==ish_max)&&(dr<dr_min))){
00414 ish_max=ish;
00415 dr_min=dr;
00416 ibest=i_pf;
00417 }
00418
00419
00420
00421 i_pf++;
00422 }
00423 if (ibest<0) return -1;
00424
00425 if((ish_max==0) || (dr_min>0.05))return -1;
00426 if(otherColl && (ish_max==0)) return -1;
00427 return ibest;
00428 }
00429 else{
00430
00431
00432 reco::PFRecTrackCollection::const_iterator pft=PfRTkColl.begin();
00433 reco::PFRecTrackCollection::const_iterator pftend=PfRTkColl.end();
00434 unsigned int i_pf=0;
00435
00436 for(;pft!=pftend;++pft){
00437
00438 if (pft->trackRef()==ElSeedRef->ctfTrack()){
00439 return i_pf;
00440 }
00441 i_pf++;
00442 }
00443 }
00444 return -1;
00445 }
00446 bool PFElecTkProducer::isFifthStep(reco::PFRecTrackRef pfKfTrack) {
00447
00448 bool isFithStep = false;
00449
00450
00451 TrackRef kfref = pfKfTrack->trackRef();
00452 unsigned int Algo = 0;
00453 switch (kfref->algo()) {
00454 case TrackBase::ctf:
00455 case TrackBase::iter0:
00456 case TrackBase::iter1:
00457 Algo = 0;
00458 break;
00459 case TrackBase::iter2:
00460 Algo = 1;
00461 break;
00462 case TrackBase::iter3:
00463 Algo = 2;
00464 break;
00465 case TrackBase::iter4:
00466 Algo = 3;
00467 break;
00468 case TrackBase::iter5:
00469 Algo = 4;
00470 break;
00471 default:
00472 Algo = 5;
00473 break;
00474 }
00475 if ( Algo >= 4 ) {
00476 isFithStep = true;
00477 }
00478
00479 return isFithStep;
00480 }
00481
00482 bool
00483 PFElecTkProducer::applySelection(reco::GsfTrack gsftk) {
00484 if (&(*gsftk.seedRef())==0) return false;
00485 ElectronSeedRef ElSeedRef=gsftk.extra()->seedRef().castTo<ElectronSeedRef>();
00486
00487 bool passCut = false;
00488 if (ElSeedRef->ctfTrack().isNull()){
00489 if(ElSeedRef->caloCluster().isNull()) return passCut;
00490 SuperClusterRef scRef = ElSeedRef->caloCluster().castTo<SuperClusterRef>();
00491
00492 if(scRef.isNonnull()) {
00493 float caloEne = scRef->energy();
00494 float feta = fabs(scRef->eta()-gsftk.etaMode());
00495 float fphi = fabs(scRef->phi()-gsftk.phiMode());
00496 if (fphi>TMath::Pi()) fphi-= TMath::TwoPi();
00497 if(caloEne > SCEne_ && feta < detaGsfSC_ && fabs(fphi) < dphiGsfSC_)
00498 passCut = true;
00499 }
00500 }
00501 else {
00502
00503 passCut = true;
00504 }
00505 return passCut;
00506 }
00507 bool
00508 PFElecTkProducer::resolveGsfTracks(const vector<reco::GsfPFRecTrack> & GsfPFVec,
00509 unsigned int ngsf,
00510 vector<unsigned int> &secondaries) {
00511
00512
00513 reco::GsfTrackRef nGsfTrack = GsfPFVec[ngsf].gsfTrackRef();
00514
00515 if (&(*nGsfTrack->seedRef())==0) return false;
00516 ElectronSeedRef nElSeedRef=nGsfTrack->extra()->seedRef().castTo<ElectronSeedRef>();
00517
00518
00519 bool n_keepGsf = true;
00520 const math::XYZPoint nxyz = nGsfTrack->innerPosition();
00521 int nhits=nGsfTrack->numberOfValidHits();
00522 int ncharge = nGsfTrack->chargeMode();
00523 TrajectoryStateOnSurface outTSOS = mtsTransform_.outerStateOnSurface((*nGsfTrack));
00524 TrajectoryStateOnSurface inTSOS = mtsTransform_.innerStateOnSurface((*nGsfTrack));
00525 GlobalVector ninnMom;
00526
00527 int outCharge = -2;
00528 int inCharge = -2;
00529 float nPin = nGsfTrack->pMode();
00530 if(outTSOS.isValid())
00531 outCharge = mtsMode_->chargeFromMode(outTSOS);
00532 if(inTSOS.isValid()){
00533 inCharge = mtsMode_->chargeFromMode(inTSOS);
00534 mtsMode_->momentumFromModeCartesian(inTSOS,ninnMom);
00535 nPin = ninnMom.mag();
00536 }
00537
00538 float nchi2 = nGsfTrack->chi2();
00539 float neta = nGsfTrack->innerMomentum().eta();
00540 float nphi = nGsfTrack->innerMomentum().phi();
00541 float ndist = sqrt(nxyz.x()*nxyz.x()+
00542 nxyz.y()*nxyz.y()+
00543 nxyz.z()*nxyz.z());
00544
00545
00546
00547 for (unsigned int igsf=0; igsf< GsfPFVec.size();igsf++) {
00548 if(igsf != ngsf ) {
00549
00550 reco::GsfTrackRef iGsfTrack = GsfPFVec[igsf].gsfTrackRef();
00551
00552 float ieta = iGsfTrack->innerMomentum().eta();
00553 float iphi = iGsfTrack->innerMomentum().phi();
00554 float feta = fabs(neta - ieta);
00555 float fphi = fabs(nphi - iphi);
00556 if (fphi>TMath::Pi()) fphi-= TMath::TwoPi();
00557 const math::XYZPoint ixyz = iGsfTrack->innerPosition();
00558 float idist = sqrt(ixyz.x()*ixyz.x()+
00559 ixyz.y()*ixyz.y()+
00560 ixyz.z()*ixyz.z());
00561
00562 float minBremDphi = selectSecondaries(GsfPFVec[ngsf],GsfPFVec[igsf]);
00563
00564 if(feta < 0.05 && (fabs(fphi) < 0.3 || minBremDphi < 0.05)) {
00565
00566 TrajectoryStateOnSurface i_outTSOS = mtsTransform_.outerStateOnSurface((*iGsfTrack));
00567 TrajectoryStateOnSurface i_inTSOS = mtsTransform_.innerStateOnSurface((*iGsfTrack));
00568 GlobalVector i_innMom;
00569 int i_outCharge = -2;
00570 int i_inCharge = -2;
00571 float iPin = iGsfTrack->pMode();
00572 if(i_outTSOS.isValid())
00573 i_outCharge = mtsMode_->chargeFromMode(i_outTSOS);
00574 if(i_inTSOS.isValid()){
00575 i_inCharge = mtsMode_->chargeFromMode(i_inTSOS);
00576 mtsMode_->momentumFromModeCartesian(i_inTSOS,i_innMom);
00577 iPin = i_innMom.mag();
00578 }
00579
00580 if (&(*iGsfTrack->seedRef())==0) continue;
00581 ElectronSeedRef iElSeedRef=iGsfTrack->extra()->seedRef().castTo<ElectronSeedRef>();
00582
00583
00584 if(nElSeedRef->caloCluster().isNonnull() && iElSeedRef->caloCluster().isNonnull()) {
00585
00586 SuperClusterRef nscRef = nElSeedRef->caloCluster().castTo<SuperClusterRef>();
00587 if(nscRef.isNull()) {
00588 n_keepGsf = false;
00589 return n_keepGsf;
00590 }
00591 float nEP = nscRef->energy()/nPin;
00592 SuperClusterRef iscRef = iElSeedRef->caloCluster().castTo<SuperClusterRef>();
00593 if(iscRef.isNonnull()) {
00594 if(nscRef == iscRef) {
00595 float iEP = iscRef->energy()/iPin;
00596
00597
00598 trackingRecHit_iterator nhit=nGsfTrack->recHitsBegin();
00599 trackingRecHit_iterator nhit_end=nGsfTrack->recHitsEnd();
00600 unsigned int tmp_sh = 0;
00601 for (;nhit!=nhit_end;++nhit){
00602 if ((*nhit)->isValid()){
00603 trackingRecHit_iterator ihit=iGsfTrack->recHitsBegin();
00604 trackingRecHit_iterator ihit_end=iGsfTrack->recHitsEnd();
00605 for (;ihit!=ihit_end;++ihit){
00606 if ((*ihit)->isValid()) {
00607 if((*nhit)->sharesInput(&*(*ihit),TrackingRecHit::all)) tmp_sh++;
00608 }
00609 }
00610 }
00611 }
00612 if (tmp_sh>0) {
00613
00614
00615 if (idist < (ndist-5)) {
00616 n_keepGsf = false;
00617 return n_keepGsf;
00618 }
00619 else if(ndist > (idist-5)){
00620 if(fabs(iEP-1) < fabs(nEP-1)) {
00621 n_keepGsf = false;
00622 return n_keepGsf;
00623 }
00624 else{
00625 if(minBremDphi < 0.05)
00626 secondaries.push_back(igsf);
00627 }
00628 }
00629 else {
00630
00631 if(minBremDphi < 0.05)
00632 secondaries.push_back(igsf);
00633 }
00634 }
00635 }
00636 }
00637 }
00638 else {
00639
00640
00641
00642 int ihits=iGsfTrack->numberOfValidHits();
00643 float ichi2 = iGsfTrack->chi2();
00644 int icharge = iGsfTrack->chargeMode();
00645
00646 if (idist < (ndist-5)) {
00647 n_keepGsf = false;
00648 return n_keepGsf;
00649 }
00650 else if(ndist > (idist-5)){
00651
00652
00653
00654
00655
00656
00657 unsigned int sharedMod = 0;
00658 unsigned int sharedHits = 0;
00659
00660 trackingRecHit_iterator nhit=nGsfTrack->recHitsBegin();
00661 trackingRecHit_iterator nhit_end=nGsfTrack->recHitsEnd();
00662 for (;nhit!=nhit_end;++nhit){
00663 if ((*nhit)->isValid()){
00664 trackingRecHit_iterator ihit=iGsfTrack->recHitsBegin();
00665 trackingRecHit_iterator ihit_end=iGsfTrack->recHitsEnd();
00666 for (;ihit!=ihit_end;++ihit){
00667 if ((*ihit)->isValid()) {
00668 if((*ihit)->geographicalId()==(*nhit)->geographicalId()) sharedMod++;
00669 if((*nhit)->sharesInput(&*(*ihit),TrackingRecHit::all)) sharedHits++;
00670 }
00671 }
00672 }
00673 }
00674 unsigned int den = ihits;
00675 if(nhits < ihits)
00676 den = nhits;
00677 if (den == 0) den = 1;
00678 float fracMod = sharedMod*1./den*1.;
00679
00680 TrajectoryStateOnSurface i_outTSOS = mtsTransform_.outerStateOnSurface((*iGsfTrack));
00681 TrajectoryStateOnSurface i_inTSOS = mtsTransform_.innerStateOnSurface((*iGsfTrack));
00682 int i_outCharge = -2;
00683 int i_inCharge = -2;
00684 if(i_outTSOS.isValid())
00685 i_outCharge = mtsMode_->chargeFromMode(i_outTSOS);
00686 if(i_inTSOS.isValid())
00687 i_inCharge = mtsMode_->chargeFromMode(i_inTSOS);
00688
00689
00690 if(fracMod > 0.5 && sharedHits > 1 && icharge == ncharge && i_outCharge == i_inCharge) {
00691 if(ihits > nhits) {
00692 n_keepGsf = false;
00693 return n_keepGsf;
00694 }
00695 else if(ihits == nhits && ichi2 < nchi2) {
00696 n_keepGsf = false;
00697 return n_keepGsf;
00698 }
00699 else {
00700 if(minBremDphi < 0.05)
00701 secondaries.push_back(igsf);
00702 }
00703 }
00704 if(fracMod > 0.3 && sharedHits > 1 && outCharge != -2 && inCharge != outCharge) {
00705 n_keepGsf = false;
00706 return n_keepGsf;
00707 }
00708 else {
00709 if(minBremDphi < 0.05)
00710 secondaries.push_back(igsf);
00711 }
00712 }
00713 else {
00714 if(minBremDphi < 0.05)
00715 secondaries.push_back(igsf);
00716 }
00717 }
00718 }
00719 }
00720 }
00721
00722 return n_keepGsf;
00723 }
00724 float
00725 PFElecTkProducer::selectSecondaries(const reco::GsfPFRecTrack primGsf,
00726 const reco::GsfPFRecTrack secGsf) {
00727
00728
00729
00730 float minDeta = 1000.;
00731 float minDphi = 1000.;
00732
00733
00734
00735
00736
00737
00738
00739 PFRecTrackRef refsecKF = secGsf.kfPFRecTrackRef();
00740 if(refsecKF.isNonnull()) {
00741 TrackRef kfref = refsecKF->trackRef();
00742 if(kfref->pt() > maxPtConvReco_)
00743 return minDphi;
00744 }
00745
00746 reco::GsfTrackRef secGsfTrack = secGsf.gsfTrackRef();
00747 if(secGsfTrack->ptMode() > maxPtConvReco_)
00748 return minDphi;
00749
00750
00751
00752 std::vector<reco::PFBrem> primPFBrem = primGsf.PFRecBrem();
00753 std::vector<reco::PFBrem> secPFBrem = secGsf.PFRecBrem();
00754
00755
00756 unsigned int cbrem = 0;
00757
00758 for (unsigned isbrem = 0; isbrem < secPFBrem.size(); isbrem++) {
00759 if(secPFBrem[isbrem].indTrajPoint() == 99) continue;
00760 const reco::PFTrajectoryPoint& atSecECAL
00761 = secPFBrem[isbrem].extrapolatedPoint( reco::PFTrajectoryPoint::ECALEntrance );
00762 if( ! atSecECAL.isValid() ) continue;
00763 float secEta = atSecECAL.positionREP().Eta();
00764 float secPhi = atSecECAL.positionREP().Phi();
00765
00766
00767 for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
00768 if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
00769 const reco::PFTrajectoryPoint& atPrimECAL
00770 = primPFBrem[ipbrem].extrapolatedPoint( reco::PFTrajectoryPoint::ECALEntrance );
00771 if( ! atPrimECAL.isValid() ) continue;
00772 float primEta = atPrimECAL.positionREP().Eta();
00773 float primPhi = atPrimECAL.positionREP().Phi();
00774
00775 float deta = fabs(primEta - secEta);
00776 float dphi = fabs(primPhi - secPhi);
00777 if (dphi>TMath::Pi()) dphi-= TMath::TwoPi();
00778 if(fabs(dphi) < minDphi) {
00779 minDeta = deta;
00780 minDphi = fabs(dphi);
00781 }
00782 }
00783
00784
00785 cbrem++;
00786 if(cbrem == 2)
00787 break;
00788 }
00789 return minDphi;
00790 }
00791
00792 void
00793 PFElecTkProducer::beginRun(edm::Run& run,
00794 const EventSetup& iSetup)
00795 {
00796 ESHandle<MagneticField> magneticField;
00797 iSetup.get<IdealMagneticFieldRecord>().get(magneticField);
00798
00799 ESHandle<TrackerGeometry> tracker;
00800 iSetup.get<TrackerDigiGeometryRecord>().get(tracker);
00801
00802
00803 mtsTransform_ = MultiTrajectoryStateTransform(tracker.product(),magneticField.product());
00804
00805
00806 pfTransformer_= new PFTrackTransformer(math::XYZVector(magneticField->inTesla(GlobalPoint(0,0,0))));
00807
00808
00809 edm::ESHandle<TransientTrackBuilder> builder;
00810 iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", builder);
00811 TransientTrackBuilder thebuilder = *(builder.product());
00812
00813
00814 if(useConvBremFinder_) {
00815 FILE * fileConvBremID = fopen(path_mvaWeightFileConvBrem_.c_str(), "r");
00816 if (fileConvBremID) {
00817 fclose(fileConvBremID);
00818 }
00819 else {
00820 string err = "PFElecTkProducer: cannot open weight file '";
00821 err += path_mvaWeightFileConvBrem_;
00822 err += "'";
00823 throw invalid_argument( err );
00824 }
00825 }
00826 convBremFinder_ = new ConvBremPFTrackFinder(thebuilder,mvaConvBremFinderID_,path_mvaWeightFileConvBrem_);
00827
00828 }
00829
00830
00831 void
00832 PFElecTkProducer::endRun() {
00833 delete pfTransformer_;
00834 }
00835
00836