File indexing completed on 2024-04-06 12:01:05
0001 #include "CommonTools/Egamma/interface/ConversionTools.h"
0002 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
0003 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0004 #include "DataFormats/TrackReco/interface/Track.h"
0005 #include "DataFormats/Common/interface/RefToPtr.h"
0006 #include "DataFormats/Math/interface/deltaPhi.h"
0007 #include "DataFormats/Math/interface/deltaR.h"
0008
0009 #include <TMath.h>
0010
0011 using namespace edm;
0012 using namespace reco;
0013
0014
0015 bool ConversionTools::isGoodConversion(const Conversion &conv,
0016 const math::XYZPoint &beamspot,
0017 float lxyMin,
0018 float probMin,
0019 unsigned int nHitsBeforeVtxMax) {
0020
0021
0022 const reco::Vertex &vtx = conv.conversionVertex();
0023
0024
0025 if (!vtx.isValid())
0026 return false;
0027
0028
0029 if (TMath::Prob(vtx.chi2(), vtx.ndof()) < probMin)
0030 return false;
0031
0032
0033 math::XYZVector mom(conv.refittedPairMomentum());
0034 double dbsx = vtx.x() - beamspot.x();
0035 double dbsy = vtx.y() - beamspot.y();
0036 double lxy = (mom.x() * dbsx + mom.y() * dbsy) / mom.rho();
0037
0038
0039 if (lxy < lxyMin)
0040 return false;
0041
0042
0043 for (std::vector<uint8_t>::const_iterator it = conv.nHitsBeforeVtx().begin(); it != conv.nHitsBeforeVtx().end();
0044 ++it) {
0045 if ((*it) > nHitsBeforeVtxMax)
0046 return false;
0047 }
0048
0049 return true;
0050 }
0051
0052
0053 bool ConversionTools::matchesConversion(const reco::GsfElectron &ele,
0054 const reco::Conversion &conv,
0055 bool allowCkfMatch,
0056 bool allowAmbiguousGsfMatch) {
0057
0058
0059
0060
0061 const std::vector<edm::RefToBase<reco::Track> > &convTracks = conv.tracks();
0062 for (std::vector<edm::RefToBase<reco::Track> >::const_iterator it = convTracks.begin(); it != convTracks.end();
0063 ++it) {
0064 if (ele.reco::GsfElectron::gsfTrack().isNonnull() && ele.reco::GsfElectron::gsfTrack().id() == it->id() &&
0065 ele.reco::GsfElectron::gsfTrack().key() == it->key())
0066 return true;
0067 else if (allowCkfMatch && ele.reco::GsfElectron::closestCtfTrackRef().isNonnull() &&
0068 ele.reco::GsfElectron::closestCtfTrackRef().id() == it->id() &&
0069 ele.reco::GsfElectron::closestCtfTrackRef().key() == it->key())
0070 return true;
0071 if (allowAmbiguousGsfMatch) {
0072 for (auto const &tk : ele.ambiguousGsfTracks()) {
0073 if (tk.isNonnull() && tk.id() == it->id() && tk.key() == it->key())
0074 return true;
0075 }
0076 }
0077 }
0078
0079 return false;
0080 }
0081
0082
0083 bool ConversionTools::matchesConversion(const reco::GsfElectronCore &eleCore,
0084 const reco::Conversion &conv,
0085 bool allowCkfMatch) {
0086
0087
0088
0089
0090 for (const auto &trkRef : conv.tracks()) {
0091 if (eleCore.gsfTrack().isNonnull() && eleCore.gsfTrack().id() == trkRef.id() &&
0092 eleCore.gsfTrack().key() == trkRef.key())
0093 return true;
0094 else if (allowCkfMatch && eleCore.ctfTrack().isNonnull() && eleCore.ctfTrack().id() == trkRef.id() &&
0095 eleCore.ctfTrack().key() == trkRef.key())
0096 return true;
0097 }
0098
0099 return false;
0100 }
0101
0102
0103 bool ConversionTools::matchesConversion(
0104 const reco::SuperCluster &sc, const reco::Conversion &conv, float dRMax, float dEtaMax, float dPhiMax) {
0105
0106
0107
0108
0109 math::XYZVector mom(conv.refittedPairMomentum());
0110
0111 const math::XYZPoint &scpos(sc.position());
0112 math::XYZPoint cvtx(conv.conversionVertex().position());
0113
0114 math::XYZVector cscvector = scpos - cvtx;
0115 float dR = reco::deltaR(mom, cscvector);
0116 float dEta = mom.eta() - cscvector.eta();
0117 float dPhi = reco::deltaPhi(mom.phi(), cscvector.phi());
0118
0119 if (dR > dRMax)
0120 return false;
0121 if (dEta > dEtaMax)
0122 return false;
0123 if (dPhi > dPhiMax)
0124 return false;
0125
0126 return true;
0127 }
0128
0129
0130 bool ConversionTools::matchesConversion(const edm::RefToBase<reco::Track> &trk, const reco::Conversion &conv) {
0131
0132
0133 if (trk.isNull())
0134 return false;
0135
0136 const std::vector<edm::RefToBase<reco::Track> > &convTracks = conv.tracks();
0137 for (std::vector<edm::RefToBase<reco::Track> >::const_iterator it = convTracks.begin(); it != convTracks.end();
0138 ++it) {
0139 if (trk.id() == it->id() && trk.key() == it->key())
0140 return true;
0141 }
0142
0143 return false;
0144 }
0145
0146
0147 bool ConversionTools::matchesConversion(const reco::TrackRef &trk, const reco::Conversion &conv) {
0148
0149
0150 if (trk.isNull())
0151 return false;
0152
0153 const std::vector<edm::RefToBase<reco::Track> > &convTracks = conv.tracks();
0154 for (std::vector<edm::RefToBase<reco::Track> >::const_iterator it = convTracks.begin(); it != convTracks.end();
0155 ++it) {
0156 if (trk.id() == it->id() && trk.key() == it->key())
0157 return true;
0158 }
0159
0160 return false;
0161 }
0162
0163
0164 bool ConversionTools::matchesConversion(const reco::GsfTrackRef &trk, const reco::Conversion &conv) {
0165
0166
0167 if (trk.isNull())
0168 return false;
0169
0170 const std::vector<edm::RefToBase<reco::Track> > &convTracks = conv.tracks();
0171 for (std::vector<edm::RefToBase<reco::Track> >::const_iterator it = convTracks.begin(); it != convTracks.end();
0172 ++it) {
0173 if (trk.id() == it->id() && trk.key() == it->key())
0174 return true;
0175 }
0176
0177 return false;
0178 }
0179
0180
0181 bool ConversionTools::hasMatchedConversion(const reco::GsfElectron &ele,
0182 const reco::ConversionCollection &convCol,
0183 const math::XYZPoint &beamspot,
0184 bool allowCkfMatch,
0185 float lxyMin,
0186 float probMin,
0187 unsigned int nHitsBeforeVtxMax) {
0188
0189
0190
0191
0192 for (auto const &it : convCol) {
0193 if (!matchesConversion(ele, it, allowCkfMatch))
0194 continue;
0195 if (!isGoodConversion(it, beamspot, lxyMin, probMin, nHitsBeforeVtxMax))
0196 continue;
0197
0198 return true;
0199 }
0200
0201 return false;
0202 }
0203
0204
0205 bool ConversionTools::hasMatchedConversion(const reco::TrackRef &trk,
0206 const reco::ConversionCollection &convCol,
0207 const math::XYZPoint &beamspot,
0208 float lxyMin,
0209 float probMin,
0210 unsigned int nHitsBeforeVtxMax) {
0211
0212
0213
0214 if (trk.isNull())
0215 return false;
0216
0217 for (auto const &it : convCol) {
0218 if (!matchesConversion(trk, it))
0219 continue;
0220 if (!isGoodConversion(it, beamspot, lxyMin, probMin, nHitsBeforeVtxMax))
0221 continue;
0222
0223 return true;
0224 }
0225
0226 return false;
0227 }
0228
0229
0230 bool ConversionTools::hasMatchedConversion(const reco::SuperCluster &sc,
0231 const reco::ConversionCollection &convCol,
0232 const math::XYZPoint &beamspot,
0233 float dRMax,
0234 float dEtaMax,
0235 float dPhiMax,
0236 float lxyMin,
0237 float probMin,
0238 unsigned int nHitsBeforeVtxMax) {
0239
0240
0241
0242 for (auto const &it : convCol) {
0243 if (!matchesConversion(sc, it))
0244 continue;
0245 if (!isGoodConversion(it, beamspot, lxyMin, probMin, nHitsBeforeVtxMax))
0246 continue;
0247
0248 return true;
0249 }
0250
0251 return false;
0252 }
0253
0254
0255 reco::Conversion const *ConversionTools::matchedConversion(const reco::GsfElectron &ele,
0256 const reco::ConversionCollection &convCol,
0257 const math::XYZPoint &beamspot,
0258 bool allowCkfMatch,
0259 float lxyMin,
0260 float probMin,
0261 unsigned int nHitsBeforeVtxMax) {
0262
0263
0264
0265
0266
0267
0268 reco::Conversion const *match = nullptr;
0269
0270 double minRho = 999.;
0271 for (auto const &it : convCol) {
0272 float rho = it.conversionVertex().position().rho();
0273 if (rho > minRho)
0274 continue;
0275 if (!matchesConversion(ele, it, allowCkfMatch))
0276 continue;
0277 if (!isGoodConversion(it, beamspot, lxyMin, probMin, nHitsBeforeVtxMax))
0278 continue;
0279
0280 minRho = rho;
0281 match = ⁢
0282 }
0283
0284 return match;
0285 }
0286
0287
0288 reco::Conversion const *ConversionTools::matchedConversion(const reco::GsfElectronCore &eleCore,
0289 const reco::ConversionCollection &convCol,
0290 const math::XYZPoint &beamspot,
0291 bool allowCkfMatch,
0292 float lxyMin,
0293 float probMin,
0294 unsigned int nHitsBeforeVtxMax) {
0295
0296
0297
0298
0299
0300
0301 reco::Conversion const *match = nullptr;
0302
0303 double minRho = 999.;
0304 for (auto const &it : convCol) {
0305 float rho = it.conversionVertex().position().rho();
0306 if (rho > minRho)
0307 continue;
0308 if (!matchesConversion(eleCore, it, allowCkfMatch))
0309 continue;
0310 if (!isGoodConversion(it, beamspot, lxyMin, probMin, nHitsBeforeVtxMax))
0311 continue;
0312
0313 minRho = rho;
0314 match = ⁢
0315 }
0316
0317 return match;
0318 }
0319
0320
0321 reco::Conversion const *ConversionTools::matchedConversion(const reco::TrackRef &trk,
0322 const reco::ConversionCollection &convCol,
0323 const math::XYZPoint &beamspot,
0324 float lxyMin,
0325 float probMin,
0326 unsigned int nHitsBeforeVtxMax) {
0327
0328
0329
0330
0331
0332 reco::Conversion const *match = nullptr;
0333
0334 if (trk.isNull())
0335 return match;
0336
0337 double minRho = 999.;
0338 for (auto const &it : convCol) {
0339 float rho = it.conversionVertex().position().rho();
0340 if (rho > minRho)
0341 continue;
0342 if (!matchesConversion(trk, it))
0343 continue;
0344 if (!isGoodConversion(it, beamspot, lxyMin, probMin, nHitsBeforeVtxMax))
0345 continue;
0346
0347 minRho = rho;
0348 match = ⁢
0349 }
0350
0351 return match;
0352 }
0353
0354
0355 reco::Conversion const *ConversionTools::matchedConversion(const reco::SuperCluster &sc,
0356 const reco::ConversionCollection &convCol,
0357 const math::XYZPoint &beamspot,
0358 float dRMax,
0359 float dEtaMax,
0360 float dPhiMax,
0361 float lxyMin,
0362 float probMin,
0363 unsigned int nHitsBeforeVtxMax) {
0364
0365
0366
0367
0368
0369 reco::Conversion const *match = nullptr;
0370
0371 double minRho = 999.;
0372 for (auto const &it : convCol) {
0373 float rho = it.conversionVertex().position().rho();
0374 if (rho > minRho)
0375 continue;
0376 if (!matchesConversion(sc, it, dRMax, dEtaMax, dPhiMax))
0377 continue;
0378 if (!isGoodConversion(it, beamspot, lxyMin, probMin, nHitsBeforeVtxMax))
0379 continue;
0380
0381 minRho = rho;
0382 match = ⁢
0383 }
0384
0385 return match;
0386 }
0387
0388
0389 bool ConversionTools::hasMatchedPromptElectron(const reco::SuperClusterRef &sc,
0390 const reco::GsfElectronCollection &eleCol,
0391 const reco::ConversionCollection &convCol,
0392 const math::XYZPoint &beamspot,
0393 bool allowCkfMatch,
0394 float lxyMin,
0395 float probMin,
0396 unsigned int nHitsBeforeVtxMax) {
0397 return !(matchedPromptElectron(sc, eleCol, convCol, beamspot, allowCkfMatch, lxyMin, probMin, nHitsBeforeVtxMax) ==
0398 nullptr);
0399 }
0400
0401
0402 reco::GsfElectron const *ConversionTools::matchedPromptElectron(const reco::SuperClusterRef &sc,
0403 const reco::GsfElectronCollection &eleCol,
0404 const reco::ConversionCollection &convCol,
0405 const math::XYZPoint &beamspot,
0406 bool allowCkfMatch,
0407 float lxyMin,
0408 float probMin,
0409 unsigned int nHitsBeforeVtxMax) {
0410
0411
0412
0413 reco::GsfElectron const *match = nullptr;
0414
0415 if (sc.isNull())
0416 return match;
0417
0418 for (auto const &it : eleCol) {
0419
0420 if (it.superCluster() != sc)
0421 continue;
0422
0423
0424 if (it.gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) > 0)
0425 continue;
0426
0427
0428 if (hasMatchedConversion(it, convCol, beamspot, allowCkfMatch, lxyMin, probMin, nHitsBeforeVtxMax))
0429 continue;
0430
0431 match = ⁢
0432 }
0433
0434 return match;
0435 }
0436
0437
0438 float ConversionTools::getVtxFitProb(const reco::Conversion *conv) {
0439 if (conv != nullptr) {
0440 const reco::Vertex &vtx = conv->conversionVertex();
0441 if (vtx.isValid()) {
0442 return TMath::Prob(vtx.chi2(), vtx.ndof());
0443 }
0444 }
0445 return -1;
0446 }