00001 #include "RecoParticleFlow/PFTracking/interface/ConvBremPFTrackFinder.h"
00002 #include "FWCore/Framework/interface/ESHandle.h"
00003
00004
00005 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00006 #include "RecoParticleFlow/PFProducer/interface/Utils.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00009 #include "DataFormats/EgammaReco/interface/ElectronSeedFwd.h"
00010 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00011 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
00012 #include "TrackingTools/IPTools/interface/IPTools.h"
00013 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00014 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00015 #include "TMath.h"
00016 #include "RecoParticleFlow/PFClusterTools/interface/LinkByRecHit.h"
00017
00018 using namespace edm;
00019 using namespace std;
00020 using namespace reco;
00021
00022 ConvBremPFTrackFinder::ConvBremPFTrackFinder(const TransientTrackBuilder& builder,
00023 double mvaBremConvCut,
00024 string mvaWeightFileConvBrem):
00025 builder_(builder),
00026 mvaBremConvCut_(mvaBremConvCut),
00027 mvaWeightFileConvBrem_(mvaWeightFileConvBrem)
00028 {
00029 tmvaReader_ = new TMVA::Reader("!Color:Silent");
00030 tmvaReader_->AddVariable("secR",&secR);
00031 tmvaReader_->AddVariable("sTIP",&sTIP);
00032 tmvaReader_->AddVariable("nHITS1",&nHITS1);
00033 tmvaReader_->AddVariable("secPin",&secPin);
00034 tmvaReader_->AddVariable("Epout",&Epout);
00035 tmvaReader_->AddVariable("detaBremKF",&detaBremKF);
00036 tmvaReader_->AddVariable("ptRatioGsfKF",&ptRatioGsfKF);
00037 tmvaReader_->BookMVA("BDT",mvaWeightFileConvBrem.c_str());
00038
00039 pfcalib_ = new PFEnergyCalibration();
00040
00041 }
00042 ConvBremPFTrackFinder::~ConvBremPFTrackFinder(){delete tmvaReader_; delete pfcalib_; }
00043
00044 void
00045 ConvBremPFTrackFinder::runConvBremFinder(const Handle<PFRecTrackCollection>& thePfRecTrackCol,
00046 const Handle<VertexCollection>& primaryVertex,
00047 const edm::Handle<reco::PFDisplacedTrackerVertexCollection>& pfNuclears,
00048 const edm::Handle<reco::PFConversionCollection >& pfConversions,
00049 const edm::Handle<reco::PFV0Collection >& pfV0,
00050 bool useNuclear,
00051 bool useConversions,
00052 bool useV0,
00053 const reco::PFClusterCollection & theEClus,
00054 reco::GsfPFRecTrack gsfpfrectk)
00055 {
00056
00057
00058 found_ = false;
00059 bool debug = false;
00060 bool debugRef = false;
00061
00062 if(debug)
00063 cout << "runConvBremFinder:: Entering " << endl;
00064
00065
00066
00067 reco::GsfTrackRef refGsf = gsfpfrectk.gsfTrackRef();
00068 reco::PFRecTrackRef pfTrackRef = gsfpfrectk.kfPFRecTrackRef();
00069 vector<PFBrem> primPFBrem = gsfpfrectk.PFRecBrem();
00070
00071
00072 const PFRecTrackCollection& PfRTkColl = *(thePfRecTrackCol.product());
00073 reco::PFRecTrackCollection::const_iterator pft=PfRTkColl.begin();
00074 reco::PFRecTrackCollection::const_iterator pftend=PfRTkColl.end();
00075
00076
00077
00078
00079
00080 vector<PFRecTrackRef> AllPFRecTracks;
00081 AllPFRecTracks.clear();
00082 unsigned int ipft = 0;
00083
00084
00085 for(;pft!=pftend;++pft,ipft++){
00086
00087 if(pfTrackRef.isNonnull())
00088 if(pfTrackRef->trackRef() == pft->trackRef()) continue;
00089
00090 PFRecTrackRef pfRecTrRef(thePfRecTrackCol,ipft);
00091 TrackRef trackRef = pfRecTrRef->trackRef();
00092 reco::TrackBaseRef selTrackBaseRef(trackRef);
00093
00094 if(debug)
00095 cout << "runConvBremFinder:: pushing_back High Purity " << pft->trackRef()->pt()
00096 << " eta,phi " << pft->trackRef()->eta() << ", " << pft->trackRef()->phi()
00097 << " Memory Address Ref " << &*trackRef << " Memory Address BaseRef " << &*selTrackBaseRef << endl;
00098 AllPFRecTracks.push_back(pfRecTrRef);
00099 }
00100
00101
00102 if(useConversions) {
00103 const PFConversionCollection& PfConvColl = *(pfConversions.product());
00104 for(unsigned i=0;i<PfConvColl.size(); i++) {
00105 reco::PFConversionRef convRef(pfConversions,i);
00106
00107 unsigned int trackSize=(convRef->pfTracks()).size();
00108 if ( convRef->pfTracks().size() < 2) continue;
00109 for(unsigned iTk=0;iTk<trackSize; iTk++) {
00110 PFRecTrackRef compPFTkRef = convRef->pfTracks()[iTk];
00111 reco::TrackBaseRef newTrackBaseRef(compPFTkRef->trackRef());
00112
00113 if(pfTrackRef.isNonnull()) {
00114 reco::TrackBaseRef primaryTrackBaseRef(pfTrackRef->trackRef());
00115 if(primaryTrackBaseRef == newTrackBaseRef) continue;
00116 }
00117 bool notFound = true;
00118 for(unsigned iPF = 0; iPF < AllPFRecTracks.size(); iPF++) {
00119 reco::TrackBaseRef selTrackBaseRef(AllPFRecTracks[iPF]->trackRef());
00120
00121 if(debugRef)
00122 cout << "## Track 1 HP pt " << AllPFRecTracks[iPF]->trackRef()->pt() << " eta, phi " << AllPFRecTracks[iPF]->trackRef()->eta() << ", " << AllPFRecTracks[iPF]->trackRef()->phi()
00123 << " Memory Address Ref " << &(*AllPFRecTracks[iPF]->trackRef()) << " Memory Address BaseRef " << &*selTrackBaseRef << endl;
00124 if(debugRef)
00125 cout << "** Track 2 CONV pt " << compPFTkRef->trackRef()->pt() << " eta, phi " << compPFTkRef->trackRef()->eta() << ", " << compPFTkRef->trackRef()->phi()
00126 << " Memory Address Ref " << &*compPFTkRef->trackRef() << " Memory Address BaseRef " << &*newTrackBaseRef << endl;
00127
00128 if(AllPFRecTracks[iPF]->trackRef()== compPFTkRef->trackRef()) {
00129 if(debugRef)
00130 cout << " SAME BREM REF " << endl;
00131 notFound = false;
00132 }
00133 }
00134 if(notFound) {
00135 if(debug)
00136 cout << "runConvBremFinder:: pushing_back Conversions " << compPFTkRef->trackRef()->pt()
00137 << " eta,phi " << compPFTkRef->trackRef()->eta() << " phi " << compPFTkRef->trackRef()->phi() <<endl;
00138 AllPFRecTracks.push_back(compPFTkRef);
00139 }
00140 }
00141 }
00142 }
00143
00144 if(useNuclear) {
00145 const PFDisplacedTrackerVertexCollection& PfNuclColl = *(pfNuclears.product());
00146 for(unsigned i=0;i<PfNuclColl.size(); i++) {
00147 const reco::PFDisplacedTrackerVertexRef dispacedVertexRef(pfNuclears, i );
00148 unsigned int trackSize= dispacedVertexRef->pfRecTracks().size();
00149 for(unsigned iTk=0;iTk < trackSize; iTk++) {
00150 reco::PFRecTrackRef newPFRecTrackRef = dispacedVertexRef->pfRecTracks()[iTk];
00151 reco::TrackBaseRef newTrackBaseRef(newPFRecTrackRef->trackRef());
00152
00153 if(pfTrackRef.isNonnull()) {
00154 reco::TrackBaseRef primaryTrackBaseRef(pfTrackRef->trackRef());
00155 if(primaryTrackBaseRef == newTrackBaseRef) continue;
00156 }
00157 bool notFound = true;
00158 for(unsigned iPF = 0; iPF < AllPFRecTracks.size(); iPF++) {
00159 reco::TrackBaseRef selTrackBaseRef(AllPFRecTracks[iPF]->trackRef());
00160 if(selTrackBaseRef == newTrackBaseRef) notFound = false;
00161 }
00162 if(notFound) {
00163 if(debug)
00164 cout << "runConvBremFinder:: pushing_back displaced Vertex pt " << newPFRecTrackRef->trackRef()->pt()
00165 << " eta,phi " << newPFRecTrackRef->trackRef()->eta() << ", " << newPFRecTrackRef->trackRef()->phi() << endl;
00166 AllPFRecTracks.push_back(newPFRecTrackRef);
00167 }
00168 }
00169 }
00170 }
00171
00172 if(useV0) {
00173 const PFV0Collection& PfV0Coll = *(pfV0.product());
00174 for(unsigned i=0;i<PfV0Coll.size(); i++) {
00175 reco::PFV0Ref v0Ref( pfV0, i );
00176 unsigned int trackSize=(v0Ref->pfTracks()).size();
00177 for(unsigned iTk=0;iTk<trackSize; iTk++) {
00178 reco::PFRecTrackRef newPFRecTrackRef = (v0Ref->pfTracks())[iTk];
00179 reco::TrackBaseRef newTrackBaseRef(newPFRecTrackRef->trackRef());
00180
00181 if(pfTrackRef.isNonnull()) {
00182 reco::TrackBaseRef primaryTrackBaseRef(pfTrackRef->trackRef());
00183 if(primaryTrackBaseRef == newTrackBaseRef) continue;
00184 }
00185 bool notFound = true;
00186 for(unsigned iPF = 0; iPF < AllPFRecTracks.size(); iPF++) {
00187 reco::TrackBaseRef selTrackBaseRef(AllPFRecTracks[iPF]->trackRef());
00188 if(selTrackBaseRef == newTrackBaseRef) notFound = false;
00189 }
00190 if(notFound) {
00191 if(debug)
00192 cout << "runConvBremFinder:: pushing_back V0 " << newPFRecTrackRef->trackRef()->pt()
00193 << " eta,phi " << newPFRecTrackRef->trackRef()->eta() << ", " << newPFRecTrackRef->trackRef()->phi() << endl;
00194 AllPFRecTracks.push_back(newPFRecTrackRef);
00195 }
00196 }
00197 }
00198 }
00199
00200
00201
00202 pfRecTrRef_vec_.clear();
00203
00204
00205 for(unsigned iPF = 0; iPF < AllPFRecTracks.size(); iPF++) {
00206
00207
00208 double dphi= fabs(AllPFRecTracks[iPF]->trackRef()->phi()-refGsf->phi());
00209 if (dphi>TMath::Pi()) dphi-= TMath::TwoPi();
00210 double deta=fabs(AllPFRecTracks[iPF]->trackRef()->eta()-refGsf->eta());
00211
00212
00213 if( fabs(dphi)> 1.0 || fabs(deta) > 0.4) continue;
00214
00215
00216 double minDEtaBremKF = 1000.;
00217 double minDPhiBremKF = 1000.;
00218 double minDRBremKF = 1000.;
00219 double minDEtaBremKFPos = 1000.;
00220 double minDPhiBremKFPos = 1000.;
00221 double minDRBremKFPos = 1000.;
00222 reco:: TrackRef trkRef = AllPFRecTracks[iPF]->trackRef();
00223
00224 double secEta = trkRef->innerMomentum().eta();
00225 double secPhi = trkRef->innerMomentum().phi();
00226
00227 for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
00228 if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
00229 const reco::PFTrajectoryPoint& atPrimECAL
00230 = primPFBrem[ipbrem].extrapolatedPoint( reco::PFTrajectoryPoint::ECALEntrance );
00231 if( ! atPrimECAL.isValid() ) continue;
00232 double bremEta = atPrimECAL.momentum().Eta();
00233 double bremPhi = atPrimECAL.momentum().Phi();
00234
00235
00236 double deta = fabs(bremEta - secEta);
00237 double dphi = fabs(bremPhi - secPhi);
00238 if (dphi>TMath::Pi()) dphi-= TMath::TwoPi();
00239 double DR = sqrt(deta*deta + dphi*dphi);
00240
00241
00242 double detaPos = fabs(bremEta - trkRef->innerPosition().eta());
00243 double dphiPos = fabs(bremPhi - trkRef->innerPosition().phi());
00244 if (dphiPos>TMath::Pi()) dphiPos-= TMath::TwoPi();
00245 double DRPos = sqrt(detaPos*detaPos + dphiPos*dphiPos);
00246
00247
00248
00249
00250 if(DR < minDRBremKF) {
00251
00252 minDRBremKF = DR;
00253 minDEtaBremKF = deta;
00254 minDPhiBremKF = fabs(dphi);
00255 }
00256
00257 if(DRPos < minDRBremKFPos) {
00258 minDRBremKFPos = DR;
00259 minDEtaBremKFPos = detaPos;
00260 minDPhiBremKFPos = fabs(dphiPos);
00261 }
00262
00263 }
00264
00265
00266 float gsfR = sqrt(refGsf->innerPosition().x()*refGsf->innerPosition().x() +
00267 refGsf->innerPosition().y()*refGsf->innerPosition().y() );
00268
00269
00270
00271 secR = sqrt(trkRef->innerPosition().x()*trkRef->innerPosition().x() +
00272 trkRef->innerPosition().y()*trkRef->innerPosition().y() );
00273
00274
00275
00276
00277 if( (minDPhiBremKF < 0.1 || minDPhiBremKFPos < 0.1) &&
00278 (minDEtaBremKF < 0.02 || minDEtaBremKFPos < 0.02)&&
00279 secR > (gsfR-8)) {
00280
00281
00282 if(debug)
00283 cout << "runConvBremFinder:: OK Find track and BREM close "
00284 << " MinDphi " << minDPhiBremKF << " MinDeta " << minDEtaBremKF << endl;
00285
00286
00287 float MinDist = 100000.;
00288 float EE_calib = 0.;
00289 PFRecTrack pfrectrack = *AllPFRecTracks[iPF];
00290 pfrectrack.calculatePositionREP();
00291
00292 for (PFClusterCollection::const_iterator clus = theEClus.begin();
00293 clus != theEClus.end();
00294 clus++ ) {
00295
00296 clus->position();
00297 double dist = -1.;
00298 PFCluster clust = *clus;
00299 clust.calculatePositionREP();
00300 dist = pfrectrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
00301 LinkByRecHit::testTrackAndClusterByRecHit(pfrectrack , clust ) : -1.;
00302
00303 if(dist > 0.) {
00304 bool applyCrackCorrections = false;
00305 vector<double> ps1Ene(0);
00306 vector<double> ps2Ene(0);
00307 double ps1,ps2;
00308 ps1=ps2=0.;
00309 if(dist < MinDist) {
00310 MinDist = dist;
00311 EE_calib = pfcalib_->energyEm(*clus,ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections);
00312 }
00313 }
00314 }
00315 if(MinDist > 0. && MinDist < 100000.) {
00316
00317
00318
00319 secPout = sqrt(trkRef->outerMomentum().x()*trkRef->outerMomentum().x() +
00320 trkRef->outerMomentum().y()*trkRef->outerMomentum().y() +
00321 trkRef->outerMomentum().z()*trkRef->outerMomentum().z());
00322
00323 secPin = sqrt(trkRef->innerMomentum().x()*trkRef->innerMomentum().x() +
00324 trkRef->innerMomentum().y()*trkRef->innerMomentum().y() +
00325 trkRef->innerMomentum().z()*trkRef->innerMomentum().z());
00326
00327
00328
00329 ptRatioGsfKF = trkRef->pt()/(refGsf->ptMode());
00330
00331 Vertex dummy;
00332 const Vertex *pv = &dummy;
00333 edm::Ref<VertexCollection> pvRef;
00334 if (primaryVertex->size() != 0) {
00335 pv = &*primaryVertex->begin();
00336
00337 pvRef = edm::Ref<VertexCollection>(primaryVertex, 0);
00338 } else {
00339 Vertex::Error e;
00340 e(0, 0) = 0.0015 * 0.0015;
00341 e(1, 1) = 0.0015 * 0.0015;
00342 e(2, 2) = 15. * 15.;
00343 Vertex::Point p(0, 0, 0);
00344 dummy = Vertex(p, e, 0, 0, 0);
00345 }
00346
00347
00348
00349 GlobalVector direction(refGsf->innerMomentum().x(),
00350 refGsf->innerMomentum().y(),
00351 refGsf->innerMomentum().z());
00352
00353 TransientTrack transientTrack = builder_.build(*trkRef);
00354 sTIP = IPTools::signedTransverseImpactParameter(transientTrack, direction, *pv).second.significance();
00355
00356
00357 Epout = EE_calib/secPout;
00358
00359
00360 detaBremKF = minDEtaBremKF;
00361
00362
00363 trackingRecHit_iterator nhit=refGsf->recHitsBegin();
00364 trackingRecHit_iterator nhit_end=refGsf->recHitsEnd();
00365 unsigned int tmp_sh = 0;
00366
00367
00368 for (;nhit!=nhit_end;++nhit){
00369 if ((*nhit)->isValid()){
00370 trackingRecHit_iterator ihit=trkRef->recHitsBegin();
00371 trackingRecHit_iterator ihit_end=trkRef->recHitsEnd();
00372 for (;ihit!=ihit_end;++ihit){
00373 if ((*ihit)->isValid()) {
00374
00375 if((*nhit)->sharesInput(&*(*ihit),TrackingRecHit::all)) tmp_sh++;
00376
00377
00378
00379
00380
00381
00382 }
00383 }
00384 }
00385 }
00386
00387 nHITS1 = tmp_sh;
00388
00389 double mvaValue = tmvaReader_->EvaluateMVA("BDT");
00390
00391 if(debug)
00392 cout << " The imput variables for conv brem tracks identification " << endl
00393 << " secR " << secR << " gsfR " << gsfR << endl
00394 << " N shared hits " << nHITS1 << endl
00395 << " sTIP " << sTIP << endl
00396 << " detaBremKF " << detaBremKF << endl
00397 << " E/pout " << Epout << endl
00398 << " pin " << secPin << endl
00399 << " ptRatioKFGsf " << ptRatioGsfKF << endl
00400 << " ***** MVA ***** " << mvaValue << endl;
00401
00402 if(mvaValue > mvaBremConvCut_) {
00403 found_ = true;
00404 pfRecTrRef_vec_.push_back(AllPFRecTracks[iPF]);
00405
00406 }
00407 }
00408 }
00409 }
00410
00411
00412
00413
00414
00415
00416 }
00417
00418