File indexing completed on 2024-04-06 12:28:08
0001 #include "RecoTracker/FinalTrackSelectors/interface/TrackMVAClassifier.h"
0002
0003 #include "DataFormats/TrackReco/interface/Track.h"
0004
0005 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
0006
0007 #include "RecoTracker/FinalTrackSelectors/interface/getBestVertex.h"
0008
0009 #include <cassert>
0010
0011 #include "powN.h"
0012
0013 namespace {
0014
0015 void fillArrayF(float* x, const edm::ParameterSet& cfg, const char* name) {
0016 auto v = cfg.getParameter<std::vector<double>>(name);
0017 assert(v.size() == 3);
0018 std::copy(std::begin(v), std::end(v), x);
0019 }
0020
0021 void fillArrayI(int* x, const edm::ParameterSet& cfg, const char* name) {
0022 auto v = cfg.getParameter<std::vector<int>>(name);
0023 assert(v.size() == 3);
0024 std::copy(std::begin(v), std::end(v), x);
0025 }
0026
0027
0028 constexpr float mvaVal[3] = {-.5, .5, 1.};
0029
0030 template <typename T, typename Comp>
0031 inline float cut(T val, const T* cuts, Comp comp) {
0032 for (int i = 2; i >= 0; --i) {
0033 if (comp(val, cuts[i]))
0034 return mvaVal[i];
0035 }
0036 return -1.f;
0037 }
0038
0039 inline float chi2n(reco::Track const& tk) { return tk.normalizedChi2(); }
0040
0041 inline float relPtErr(reco::Track const& tk) {
0042 return (tk.pt() != 0. ? float(tk.ptError()) / float(tk.pt()) : 9999999.);
0043 }
0044
0045 inline int lostLayers(reco::Track const& tk) {
0046 return tk.hitPattern().trackerLayersWithoutMeasurement(reco::HitPattern::TRACK_HITS);
0047 }
0048
0049 inline int n3DLayers(reco::Track const& tk, bool isHLT) {
0050 uint32_t nlayers3D = tk.hitPattern().pixelLayersWithMeasurement();
0051 if (!isHLT)
0052 nlayers3D += tk.hitPattern().numberOfValidStripLayersWithMonoAndStereo();
0053 else {
0054 size_t count3D = 0;
0055 for (auto it = tk.recHitsBegin(), et = tk.recHitsEnd(); it != et; ++it) {
0056 const TrackingRecHit* hit = (*it);
0057 if (!trackerHitRTTI::isFromDetOrFast(*hit))
0058 continue;
0059
0060 if (hit->dimension() == 2) {
0061 auto const& thit = static_cast<BaseTrackerRecHit const&>(*hit);
0062 if (thit.isMatched())
0063 count3D++;
0064 }
0065 }
0066 nlayers3D += count3D;
0067 }
0068 return nlayers3D;
0069 }
0070
0071 inline int nHits(reco::Track const& tk) { return tk.numberOfValidHits(); }
0072
0073 inline int nPixelHits(reco::Track const& tk) { return tk.hitPattern().numberOfValidPixelHits(); }
0074
0075 inline float dz(reco::Track const& trk, Point const& bestVertex) { return std::abs(trk.dz(bestVertex)); }
0076 inline float dr(reco::Track const& trk, Point const& bestVertex) { return std::abs(trk.dxy(bestVertex)); }
0077
0078 inline void dzCut_par1(reco::Track const& trk, int& nLayers, const float* par, const int* exp, float dzCut[]) {
0079 float dzE = trk.dzError();
0080 for (int i = 2; i >= 0; --i) {
0081 dzCut[i] = powN(par[i] * nLayers, exp[i]) * dzE;
0082 }
0083 }
0084 inline void drCut_par1(reco::Track const& trk, int& nLayers, const float* par, const int* exp, float drCut[]) {
0085 float drE = trk.d0Error();
0086 for (int i = 2; i >= 0; --i) {
0087 drCut[i] = powN(par[i] * nLayers, exp[i]) * drE;
0088 }
0089 }
0090
0091 inline void dzCut_par2(reco::Track const& trk,
0092 int& nLayers,
0093 const float* par,
0094 const int* exp,
0095 const float* d0err,
0096 const float* d0err_par,
0097 float dzCut[]) {
0098 float pt = float(trk.pt());
0099 float p = float(trk.p());
0100
0101 for (int i = 2; i >= 0; --i) {
0102
0103 float nomd0E = sqrt(d0err[i] * d0err[i] + (d0err_par[i] / pt) * (d0err_par[i] / pt));
0104
0105 float nomdzE = nomd0E * (p / pt);
0106
0107 dzCut[i] = powN(par[i] * nLayers, exp[i]) * nomdzE;
0108 }
0109 }
0110 inline void drCut_par2(reco::Track const& trk,
0111 int& nLayers,
0112 const float* par,
0113 const int* exp,
0114 const float* d0err,
0115 const float* d0err_par,
0116 float drCut[]) {
0117 float pt = trk.pt();
0118
0119 for (int i = 2; i >= 0; --i) {
0120
0121 float nomd0E = sqrt(d0err[i] * d0err[i] + (d0err_par[i] / pt) * (d0err_par[i] / pt));
0122
0123 drCut[i] = powN(par[i] * nLayers, exp[i]) * nomd0E;
0124 }
0125 }
0126
0127 inline void dzCut_wPVerror_par(reco::Track const& trk,
0128 int& nLayers,
0129 const float* par,
0130 const int* exp,
0131 Point const& bestVertexError,
0132 float dzCut[]) {
0133 float dzE = trk.dzError();
0134 float zPVerr = bestVertexError.z();
0135
0136 float dzErrPV = std::sqrt(dzE * dzE + zPVerr * zPVerr);
0137 for (int i = 2; i >= 0; --i) {
0138 dzCut[i] = par[i] * dzErrPV;
0139 if (exp[i] != 0)
0140 dzCut[i] *= pow(nLayers, exp[i]);
0141 }
0142 }
0143
0144 inline void drCut_wPVerror_par(reco::Track const& trk,
0145 int& nLayers,
0146 const float* par,
0147 const int* exp,
0148 Point const& bestVertexError,
0149 float drCut[]) {
0150 float drE = trk.d0Error();
0151
0152 float rPVerr = sqrt(bestVertexError.x() * bestVertexError.y());
0153
0154 float drErrPV = std::sqrt(drE * drE + rPVerr * rPVerr);
0155 for (int i = 2; i >= 0; --i) {
0156 drCut[i] = par[i] * drErrPV;
0157 if (exp[i] != 0)
0158 drCut[i] *= pow(nLayers, exp[i]);
0159 }
0160 }
0161
0162 struct Cuts {
0163 Cuts(const edm::ParameterSet& cfg, edm::ConsumesCollector) {
0164 isHLT = cfg.getParameter<bool>("isHLT");
0165 fillArrayF(minNdof, cfg, "minNdof");
0166 fillArrayF(maxChi2, cfg, "maxChi2");
0167 fillArrayF(maxChi2n, cfg, "maxChi2n");
0168 fillArrayI(minHits4pass, cfg, "minHits4pass");
0169 fillArrayI(minHits, cfg, "minHits");
0170 fillArrayI(minPixelHits, cfg, "minPixelHits");
0171 fillArrayI(min3DLayers, cfg, "min3DLayers");
0172 fillArrayI(minLayers, cfg, "minLayers");
0173 fillArrayI(maxLostLayers, cfg, "maxLostLayers");
0174 fillArrayF(maxRelPtErr, cfg, "maxRelPtErr");
0175 minNVtxTrk = cfg.getParameter<int>("minNVtxTrk");
0176 fillArrayF(maxDz, cfg, "maxDz");
0177 fillArrayF(maxDzWrtBS, cfg, "maxDzWrtBS");
0178 fillArrayF(maxDr, cfg, "maxDr");
0179 edm::ParameterSet dz_par = cfg.getParameter<edm::ParameterSet>("dz_par");
0180 fillArrayI(dz_exp, dz_par, "dz_exp");
0181 fillArrayF(dz_par1, dz_par, "dz_par1");
0182 fillArrayF(dz_par2, dz_par, "dz_par2");
0183 fillArrayF(dzWPVerr_par, dz_par, "dzWPVerr_par");
0184 edm::ParameterSet dr_par = cfg.getParameter<edm::ParameterSet>("dr_par");
0185 fillArrayI(dr_exp, dr_par, "dr_exp");
0186 fillArrayF(dr_par1, dr_par, "dr_par1");
0187 fillArrayF(dr_par2, dr_par, "dr_par2");
0188 fillArrayF(d0err, dr_par, "d0err");
0189 fillArrayF(d0err_par, dr_par, "d0err_par");
0190 fillArrayF(drWPVerr_par, dr_par, "drWPVerr_par");
0191 }
0192
0193 void beginStream() {}
0194 void initEvent(const edm::EventSetup&) {}
0195
0196 float operator()(reco::Track const& trk,
0197 reco::BeamSpot const& beamSpot,
0198 reco::VertexCollection const& vertices) const {
0199 float ret = 1.f;
0200
0201 if (minHits4pass[0] < std::numeric_limits<int>::max()) {
0202 ret = std::min(ret, cut(nHits(trk), minHits4pass, std::greater_equal<int>()));
0203 if (ret == 1.f)
0204 return ret;
0205 }
0206
0207 if (maxRelPtErr[2] < std::numeric_limits<float>::max()) {
0208 ret = std::min(ret, cut(relPtErr(trk), maxRelPtErr, std::less_equal<float>()));
0209 if (ret == -1.f)
0210 return ret;
0211 }
0212
0213 ret = std::min(ret, cut(float(trk.ndof()), minNdof, std::greater_equal<float>()));
0214 if (ret == -1.f)
0215 return ret;
0216
0217 auto nLayers = trk.hitPattern().trackerLayersWithMeasurement();
0218 ret = std::min(ret, cut(nLayers, minLayers, std::greater_equal<int>()));
0219 if (ret == -1.f)
0220 return ret;
0221
0222 ret = std::min(ret, cut(chi2n(trk) / float(nLayers), maxChi2n, std::less_equal<float>()));
0223 if (ret == -1.f)
0224 return ret;
0225
0226 ret = std::min(ret, cut(chi2n(trk), maxChi2, std::less_equal<float>()));
0227 if (ret == -1.f)
0228 return ret;
0229
0230 ret = std::min(ret, cut(n3DLayers(trk, isHLT), min3DLayers, std::greater_equal<int>()));
0231 if (ret == -1.f)
0232 return ret;
0233
0234 ret = std::min(ret, cut(nHits(trk), minHits, std::greater_equal<int>()));
0235 if (ret == -1.f)
0236 return ret;
0237
0238 ret = std::min(ret, cut(nPixelHits(trk), minPixelHits, std::greater_equal<int>()));
0239 if (ret == -1.f)
0240 return ret;
0241
0242 ret = std::min(ret, cut(lostLayers(trk), maxLostLayers, std::less_equal<int>()));
0243 if (ret == -1.f)
0244 return ret;
0245
0246
0247 if (maxDz[2] < std::numeric_limits<float>::max() || maxDr[2] < std::numeric_limits<float>::max()) {
0248
0249
0250 Point bestVertex = getBestVertex(trk, vertices, minNVtxTrk);
0251 float maxDzcut[3];
0252 std::copy(std::begin(maxDz), std::end(maxDz), std::begin(maxDzcut));
0253 if (bestVertex.z() < -99998.) {
0254 bestVertex = beamSpot.position();
0255 std::copy(std::begin(maxDzWrtBS), std::end(maxDzWrtBS), std::begin(maxDzcut));
0256 }
0257 ret = std::min(ret, cut(dr(trk, bestVertex), maxDr, std::less<float>()));
0258 if (ret == -1.f)
0259 return ret;
0260
0261 ret = std::min(ret, cut(dz(trk, bestVertex), maxDzcut, std::less<float>()));
0262 if (ret == -1.f)
0263 return ret;
0264 }
0265
0266
0267 if (dzWPVerr_par[2] < std::numeric_limits<float>::max() || drWPVerr_par[2] < std::numeric_limits<float>::max()) {
0268 Point bestVertexError(-1., -1., -1.);
0269
0270 Point bestVertex = getBestVertex_withError(trk, vertices, bestVertexError, minNVtxTrk);
0271
0272 float maxDz_par[3];
0273 float maxDr_par[3];
0274 dzCut_wPVerror_par(trk, nLayers, dzWPVerr_par, dz_exp, bestVertexError, maxDz_par);
0275 drCut_wPVerror_par(trk, nLayers, drWPVerr_par, dr_exp, bestVertexError, maxDr_par);
0276
0277 ret = std::min(ret, cut(dr(trk, bestVertex), maxDr_par, std::less<float>()));
0278 if (ret == -1.f)
0279 return ret;
0280
0281 ret = std::min(ret, cut(dz(trk, bestVertex), maxDr_par, std::less<float>()));
0282 if (ret == -1.f)
0283 return ret;
0284 }
0285
0286
0287 if (dz_par1[2] < std::numeric_limits<float>::max() || dr_par1[2] < std::numeric_limits<float>::max()) {
0288 float maxDz_par1[3];
0289 float maxDr_par1[3];
0290 dzCut_par1(trk, nLayers, dz_par1, dz_exp, maxDz_par1);
0291 drCut_par1(trk, nLayers, dr_par1, dr_exp, maxDr_par1);
0292
0293 float maxDz_par[3];
0294 float maxDr_par[3];
0295 std::copy(std::begin(maxDz_par1), std::end(maxDz_par1), std::begin(maxDz_par));
0296 std::copy(std::begin(maxDr_par1), std::end(maxDr_par1), std::begin(maxDr_par));
0297
0298
0299 if (dz_par2[2] < std::numeric_limits<float>::max() || dr_par2[2] < std::numeric_limits<float>::max()) {
0300 float maxDz_par2[3];
0301 float maxDr_par2[3];
0302 dzCut_par2(trk, nLayers, dz_par2, dz_exp, d0err, d0err_par, maxDz_par2);
0303 drCut_par2(trk, nLayers, dr_par2, dr_exp, d0err, d0err_par, maxDr_par2);
0304
0305 for (int i = 2; i >= 0; --i) {
0306 if (maxDr_par2[i] < maxDr_par[i])
0307 maxDr_par[i] = maxDr_par2[i];
0308 if (maxDz_par2[i] < maxDz_par[i])
0309 maxDz_par[i] = maxDz_par2[i];
0310 }
0311 }
0312
0313 Point bestVertex = getBestVertex(trk, vertices, minNVtxTrk);
0314 if (bestVertex.z() < -99998.) {
0315 bestVertex = beamSpot.position();
0316 }
0317
0318 ret = std::min(ret, cut(dz(trk, bestVertex), maxDz_par, std::less<float>()));
0319 if (ret == -1.f)
0320 return ret;
0321 ret = std::min(ret, cut(dr(trk, bestVertex), maxDr_par, std::less<float>()));
0322 if (ret == -1.f)
0323 return ret;
0324 }
0325 if (ret == -1.f)
0326 return ret;
0327
0328 return ret;
0329 }
0330
0331 static const char* name() { return "TrackCutClassifier"; }
0332
0333 static void fillDescriptions(edm::ParameterSetDescription& desc) {
0334 desc.add<bool>("isHLT", false);
0335 desc.add<std::vector<int>>(
0336 "minHits4pass",
0337 {std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), std::numeric_limits<int>::max()});
0338 desc.add<std::vector<int>>("minHits", {0, 0, 1});
0339 desc.add<std::vector<int>>("minPixelHits", {0, 0, 1});
0340 desc.add<std::vector<int>>("minLayers", {3, 4, 5});
0341 desc.add<std::vector<int>>("min3DLayers", {1, 2, 3});
0342 desc.add<std::vector<int>>("maxLostLayers", {99, 3, 3});
0343 desc.add<std::vector<double>>(
0344 "maxRelPtErr",
0345 {std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max()});
0346 desc.add<std::vector<double>>("minNdof", {-1., -1., -1.});
0347 desc.add<std::vector<double>>("maxChi2", {9999., 25., 16.});
0348 desc.add<std::vector<double>>("maxChi2n", {9999., 1.0, 0.4});
0349
0350 desc.add<int>("minNVtxTrk", 2);
0351
0352 desc.add<std::vector<double>>(
0353 "maxDz",
0354 {std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max()});
0355 desc.add<std::vector<double>>("maxDzWrtBS", {std::numeric_limits<float>::max(), 24., 15.});
0356 desc.add<std::vector<double>>(
0357 "maxDr",
0358 {std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max()});
0359
0360 edm::ParameterSetDescription dz_par;
0361 dz_par.add<std::vector<int>>("dz_exp",
0362 {std::numeric_limits<int>::max(),
0363 std::numeric_limits<int>::max(),
0364 std::numeric_limits<int>::max()});
0365 dz_par.add<std::vector<double>>("dz_par1",
0366 {std::numeric_limits<float>::max(),
0367 std::numeric_limits<float>::max(),
0368 std::numeric_limits<float>::max()});
0369 dz_par.add<std::vector<double>>("dz_par2",
0370 {std::numeric_limits<float>::max(),
0371 std::numeric_limits<float>::max(),
0372 std::numeric_limits<float>::max()});
0373 dz_par.add<std::vector<double>>("dzWPVerr_par",
0374 {std::numeric_limits<float>::max(),
0375 std::numeric_limits<float>::max(),
0376 std::numeric_limits<float>::max()});
0377 desc.add<edm::ParameterSetDescription>("dz_par", dz_par);
0378
0379 edm::ParameterSetDescription dr_par;
0380 dr_par.add<std::vector<int>>("dr_exp",
0381 {std::numeric_limits<int>::max(),
0382 std::numeric_limits<int>::max(),
0383 std::numeric_limits<int>::max()});
0384 dr_par.add<std::vector<double>>("dr_par1",
0385 {std::numeric_limits<float>::max(),
0386 std::numeric_limits<float>::max(),
0387 std::numeric_limits<float>::max()});
0388 dr_par.add<std::vector<double>>("dr_par2",
0389 {std::numeric_limits<float>::max(),
0390 std::numeric_limits<float>::max(),
0391 std::numeric_limits<float>::max()});
0392 dr_par.add<std::vector<double>>("d0err", {0.003, 0.003, 0.003});
0393 dr_par.add<std::vector<double>>("d0err_par", {0.001, 0.001, 0.001});
0394 dr_par.add<std::vector<double>>("drWPVerr_par",
0395 {std::numeric_limits<float>::max(),
0396 std::numeric_limits<float>::max(),
0397 std::numeric_limits<float>::max()});
0398 desc.add<edm::ParameterSetDescription>("dr_par", dr_par);
0399 }
0400
0401 bool isHLT;
0402 float maxRelPtErr[3];
0403 float minNdof[3];
0404 float maxChi2[3];
0405 float maxChi2n[3];
0406 int minLayers[3];
0407 int min3DLayers[3];
0408 int minHits4pass[3];
0409 int minHits[3];
0410 int minPixelHits[3];
0411 int maxLostLayers[3];
0412 int minNVtxTrk;
0413 float maxDz[3];
0414 float maxDzWrtBS[3];
0415 float maxDr[3];
0416 int dz_exp[3];
0417 float dz_par1[3];
0418 float dz_par2[3];
0419 float dzWPVerr_par[3];
0420 int dr_exp[3];
0421 float dr_par1[3];
0422 float dr_par2[3];
0423 float d0err[3];
0424 float d0err_par[3];
0425 float drWPVerr_par[3];
0426 };
0427
0428 using TrackCutClassifier = TrackMVAClassifier<Cuts>;
0429
0430 }
0431
0432 #include "FWCore/PluginManager/interface/ModuleDef.h"
0433 #include "FWCore/Framework/interface/MakerMacros.h"
0434
0435 DEFINE_FWK_MODULE(TrackCutClassifier);