File indexing completed on 2024-04-06 12:24:48
0001 #include "RecoEgamma/EgammaElectronAlgos/interface/TrajSeedMatcher.h"
0002
0003 #include "FWCore/Framework/interface/EventSetup.h"
0004 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0006 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0007
0008 #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
0009 #include "DataFormats/GeometryCommonDetAlgo/interface/PerpendicularBoundPlaneBuilder.h"
0010 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
0011
0012 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
0013 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
0014
0015 #include "TrackingTools/TrajectoryState/interface/ftsFromVertexToPoint.h"
0016 #include "RecoEgamma/EgammaElectronAlgos/interface/ElectronUtilities.h"
0017
0018 #include "FWCore/Framework/interface/ConsumesCollector.h"
0019
0020 constexpr float TrajSeedMatcher::kElectronMass_;
0021
0022 namespace {
0023 auto makeMatchingCuts(std::vector<edm::ParameterSet> const& cutsPSets) {
0024 std::vector<std::unique_ptr<TrajSeedMatcher::MatchingCuts> > matchingCuts;
0025
0026 for (const auto& cutPSet : cutsPSets) {
0027 int version = cutPSet.getParameter<int>("version");
0028 switch (version) {
0029 case 1:
0030 matchingCuts.emplace_back(std::make_unique<TrajSeedMatcher::MatchingCutsV1>(cutPSet));
0031 break;
0032 case 2:
0033 matchingCuts.emplace_back(std::make_unique<TrajSeedMatcher::MatchingCutsV2>(cutPSet));
0034 break;
0035 default:
0036 throw cms::Exception("InvalidConfig") << " Error TrajSeedMatcher::TrajSeedMatcher pixel match cuts version "
0037 << version << " not recognised" << std::endl;
0038 }
0039 }
0040
0041 return matchingCuts;
0042 }
0043
0044 TrajSeedMatcher::SCHitMatch makeSCHitMatch(const GlobalPoint& vtxPos,
0045 const TrajectoryStateOnSurface& trajState,
0046 const TrackingRecHit& hit,
0047 float et,
0048 float eta,
0049 float phi,
0050 int charge,
0051 int nrClus) {
0052 EleRelPointPair pointPair(hit.globalPosition(), trajState.globalParameters().position(), vtxPos);
0053 float dRZ = hit.geographicalId().subdetId() == PixelSubdetector::PixelBarrel ? pointPair.dZ() : pointPair.dPerp();
0054 return {hit.geographicalId(), hit.globalPosition(), dRZ, pointPair.dPhi(), hit, et, eta, phi, charge, nrClus};
0055 }
0056
0057 const std::vector<TrajSeedMatcher::MatchInfo> makeMatchInfoVector(
0058 std::vector<TrajSeedMatcher::SCHitMatch> const& posCharge,
0059 std::vector<TrajSeedMatcher::SCHitMatch> const& negCharge) {
0060 std::vector<TrajSeedMatcher::MatchInfo> matchInfos;
0061 size_t nrHitsMax = std::max(posCharge.size(), negCharge.size());
0062 for (size_t hitNr = 0; hitNr < nrHitsMax; hitNr++) {
0063 DetId detIdPos = hitNr < posCharge.size() ? posCharge[hitNr].detId : DetId(0);
0064 float dRZPos = hitNr < posCharge.size() ? posCharge[hitNr].dRZ : std::numeric_limits<float>::max();
0065 float dPhiPos = hitNr < posCharge.size() ? posCharge[hitNr].dPhi : std::numeric_limits<float>::max();
0066
0067 DetId detIdNeg = hitNr < negCharge.size() ? negCharge[hitNr].detId : DetId(0);
0068 float dRZNeg = hitNr < negCharge.size() ? negCharge[hitNr].dRZ : std::numeric_limits<float>::max();
0069 float dPhiNeg = hitNr < negCharge.size() ? negCharge[hitNr].dPhi : std::numeric_limits<float>::max();
0070
0071 if (detIdPos != detIdNeg && (detIdPos.rawId() != 0 && detIdNeg.rawId() != 0)) {
0072 cms::Exception("LogicError") << " error in " << __FILE__ << ", " << __LINE__
0073 << " hits to be combined have different detIDs, this should not be possible and "
0074 "nothing good will come of it";
0075 }
0076 DetId detId = detIdPos.rawId() != 0 ? detIdPos : detIdNeg;
0077 matchInfos.push_back({detId, dRZPos, dRZNeg, dPhiPos, dPhiNeg});
0078 }
0079 return matchInfos;
0080 }
0081 };
0082
0083 TrajSeedMatcher::Configuration::Configuration(const edm::ParameterSet& pset, edm::ConsumesCollector&& cc)
0084 : magFieldToken{cc.esConsumes()},
0085 paramMagFieldToken{cc.esConsumes(pset.getParameter<edm::ESInputTag>("paramMagField"))},
0086 navSchoolToken{cc.esConsumes(pset.getParameter<edm::ESInputTag>("navSchool"))},
0087 detLayerGeomToken{cc.esConsumes(pset.getParameter<edm::ESInputTag>("detLayerGeom"))},
0088 useRecoVertex{pset.getParameter<bool>("useRecoVertex")},
0089 enableHitSkipping{pset.getParameter<bool>("enableHitSkipping")},
0090 requireExactMatchCount{pset.getParameter<bool>("requireExactMatchCount")},
0091 useParamMagFieldIfDefined{pset.getParameter<bool>("useParamMagFieldIfDefined")},
0092 minNrHits{pset.getParameter<std::vector<unsigned int> >("minNrHits")},
0093 minNrHitsValidLayerBins{pset.getParameter<std::vector<int> >("minNrHitsValidLayerBins")},
0094 matchingCuts{makeMatchingCuts(pset.getParameter<std::vector<edm::ParameterSet> >("matchingCuts"))} {
0095 if (minNrHitsValidLayerBins.size() + 1 != minNrHits.size()) {
0096 throw cms::Exception("InvalidConfig")
0097 << " TrajSeedMatcher::TrajSeedMatcher minNrHitsValidLayerBins should be 1 less than minNrHits when its "
0098 << minNrHitsValidLayerBins.size() << " vs " << minNrHits.size();
0099 }
0100 }
0101
0102 TrajSeedMatcher::TrajSeedMatcher(TrajectorySeedCollection const& seeds,
0103 math::XYZPoint const& vprim,
0104 TrajSeedMatcher::Configuration const& cfg,
0105 edm::EventSetup const& iSetup,
0106 MeasurementTrackerEvent const& measTkEvt)
0107 : seeds_{seeds},
0108 vprim_(vprim.x(), vprim.y(), vprim.z()),
0109 cfg_{cfg},
0110 magField_{iSetup.getData(cfg_.magFieldToken)},
0111 magFieldParam_{iSetup.getData(cfg_.paramMagFieldToken)},
0112 measTkEvt_{measTkEvt},
0113 navSchool_{iSetup.getData(cfg_.navSchoolToken)},
0114 detLayerGeom_{iSetup.getData(cfg_.detLayerGeomToken)},
0115 forwardPropagator_(alongMomentum, kElectronMass_, &magField_),
0116 backwardPropagator_(oppositeToMomentum, kElectronMass_, &magField_) {}
0117
0118 edm::ParameterSetDescription TrajSeedMatcher::makePSetDescription() {
0119 edm::ParameterSetDescription desc;
0120 desc.add<bool>("useRecoVertex", false);
0121 desc.add<bool>("enableHitSkipping", false);
0122 desc.add<bool>("requireExactMatchCount", true);
0123 desc.add<bool>("useParamMagFieldIfDefined", true);
0124 desc.add<edm::ESInputTag>("paramMagField", edm::ESInputTag{"", "ParabolicMf"});
0125 desc.add<edm::ESInputTag>("navSchool", edm::ESInputTag{"", "SimpleNavigationSchool"});
0126 desc.add<edm::ESInputTag>("detLayerGeom", edm::ESInputTag{"", "hltESPGlobalDetLayerGeometry"});
0127 desc.add<std::vector<int> >("minNrHitsValidLayerBins", {4});
0128 desc.add<std::vector<unsigned int> >("minNrHits", {2, 3});
0129
0130 edm::ParameterSetDescription cutsDesc;
0131 auto cutDescCases = 1 >> (edm::ParameterDescription<double>("dPhiMax", 0.04, true) and
0132 edm::ParameterDescription<double>("dRZMax", 0.09, true) and
0133 edm::ParameterDescription<double>("dRZMaxLowEtThres", 20., true) and
0134 edm::ParameterDescription<std::vector<double> >("dRZMaxLowEtEtaBins", {1., 1.5}, true) and
0135 edm::ParameterDescription<std::vector<double> >("dRZMaxLowEt", {0.09, 0.15, 0.09}, true)) or
0136 2 >> (edm::ParameterDescription<std::vector<double> >("dPhiMaxHighEt", {0.003}, true) and
0137 edm::ParameterDescription<std::vector<double> >("dPhiMaxHighEtThres", {0.0}, true) and
0138 edm::ParameterDescription<std::vector<double> >("dPhiMaxLowEtGrad", {0.0}, true) and
0139 edm::ParameterDescription<std::vector<double> >("dRZMaxHighEt", {0.005}, true) and
0140 edm::ParameterDescription<std::vector<double> >("dRZMaxHighEtThres", {30}, true) and
0141 edm::ParameterDescription<std::vector<double> >("dRZMaxLowEtGrad", {-0.002}, true) and
0142 edm::ParameterDescription<std::vector<double> >("etaBins", {}, true));
0143 cutsDesc.ifValue(edm::ParameterDescription<int>("version", 1, true), std::move(cutDescCases));
0144
0145 edm::ParameterSet defaults;
0146 defaults.addParameter<double>("dPhiMax", 0.04);
0147 defaults.addParameter<double>("dRZMax", 0.09);
0148 defaults.addParameter<double>("dRZMaxLowEtThres", 0.09);
0149 defaults.addParameter<std::vector<double> >("dRZMaxLowEtEtaBins", std::vector<double>{1., 1.5});
0150 defaults.addParameter<std::vector<double> >("dRZMaxLowEt", std::vector<double>{0.09, 0.09, 0.09});
0151 defaults.addParameter<int>("version", 1);
0152 desc.addVPSet("matchingCuts", cutsDesc, std::vector<edm::ParameterSet>{defaults, defaults, defaults});
0153 return desc;
0154 }
0155
0156 std::vector<TrajSeedMatcher::SeedWithInfo> TrajSeedMatcher::operator()(const GlobalPoint& candPos, const float energy) {
0157 clearCache();
0158
0159 std::vector<SeedWithInfo> matchedSeeds;
0160
0161
0162 TrajectoryStateOnSurface scTrajStateOnSurfNeg = makeTrajStateOnSurface(candPos, energy, -1);
0163 TrajectoryStateOnSurface scTrajStateOnSurfPos = makeTrajStateOnSurface(candPos, energy, 1);
0164
0165 for (const auto& seed : seeds_) {
0166 std::vector<SCHitMatch> matchedHitsNeg = processSeed(seed, candPos, energy, scTrajStateOnSurfNeg);
0167 std::vector<SCHitMatch> matchedHitsPos = processSeed(seed, candPos, energy, scTrajStateOnSurfPos);
0168
0169 int nrValidLayersPos = 0;
0170 int nrValidLayersNeg = 0;
0171 if (matchedHitsNeg.size() >= 2) {
0172 nrValidLayersNeg = getNrValidLayersAlongTraj(matchedHitsNeg[0], matchedHitsNeg[1], candPos, energy, -1);
0173 }
0174 if (matchedHitsPos.size() >= 2) {
0175 nrValidLayersPos = getNrValidLayersAlongTraj(matchedHitsPos[0], matchedHitsPos[1], candPos, energy, +1);
0176 }
0177
0178 int nrValidLayers = std::max(nrValidLayersNeg, nrValidLayersPos);
0179 size_t nrHitsRequired = getNrHitsRequired(nrValidLayers);
0180 bool matchCountPasses;
0181 if (cfg_.requireExactMatchCount) {
0182
0183
0184 matchCountPasses = matchedHitsNeg.size() == nrHitsRequired || matchedHitsPos.size() == nrHitsRequired;
0185 } else {
0186 matchCountPasses = matchedHitsNeg.size() >= nrHitsRequired || matchedHitsPos.size() >= nrHitsRequired;
0187 }
0188 if (matchCountPasses) {
0189 matchedSeeds.push_back({seed, makeMatchInfoVector(matchedHitsPos, matchedHitsNeg), nrValidLayers});
0190 }
0191 }
0192 return matchedSeeds;
0193 }
0194
0195 std::vector<TrajSeedMatcher::SCHitMatch> TrajSeedMatcher::processSeed(const TrajectorySeed& seed,
0196 const GlobalPoint& candPos,
0197 const float energy,
0198 const TrajectoryStateOnSurface& initialTrajState) {
0199
0200 const float candEta = candPos.eta();
0201 const float candEt = energy * std::sin(candPos.theta());
0202 const int charge = initialTrajState.charge();
0203
0204 std::vector<SCHitMatch> matches;
0205 FreeTrajectoryState firstMatchFreeTraj;
0206 GlobalPoint prevHitPos;
0207 GlobalPoint vertex;
0208 const auto nCuts = cfg_.matchingCuts.size();
0209 for (size_t iHit = 0;
0210 matches.size() < nCuts && iHit < seed.nHits() && (cfg_.enableHitSkipping || iHit == matches.size());
0211 iHit++) {
0212 auto const& recHit = *(seed.recHits().begin() + iHit);
0213
0214 if (!recHit.isValid()) {
0215 continue;
0216 }
0217
0218 const bool doFirstMatch = matches.empty();
0219
0220 auto const& trajState = doFirstMatch
0221 ? getTrajStateFromVtx(recHit, initialTrajState, backwardPropagator_)
0222 : getTrajStateFromPoint(recHit, firstMatchFreeTraj, prevHitPos, forwardPropagator_);
0223 if (!trajState.isValid()) {
0224 continue;
0225 }
0226
0227 auto const& vtxForMatchObject = doFirstMatch ? vprim_ : vertex;
0228 auto match = makeSCHitMatch(vtxForMatchObject, trajState, recHit, candEt, candEta, candPos.phi(), charge, 1);
0229
0230 if ((*cfg_.matchingCuts[matches.size()])(match)) {
0231 matches.push_back(match);
0232 if (doFirstMatch) {
0233
0234 double zVertex = cfg_.useRecoVertex ? vprim_.z() : getZVtxFromExtrapolation(vprim_, match.hitPos, candPos);
0235 vertex = GlobalPoint(vprim_.x(), vprim_.y(), zVertex);
0236 firstMatchFreeTraj = ftsFromVertexToPoint(match.hitPos, vertex, energy, charge);
0237 }
0238 prevHitPos = match.hitPos;
0239 }
0240 }
0241 return matches;
0242 }
0243
0244
0245 float TrajSeedMatcher::getZVtxFromExtrapolation(const GlobalPoint& primeVtxPos,
0246 const GlobalPoint& hitPos,
0247 const GlobalPoint& candPos) {
0248 auto sq = [](float x) { return x * x; };
0249 auto calRDiff = [sq](const GlobalPoint& p1, const GlobalPoint& p2) {
0250 return std::sqrt(sq(p2.x() - p1.x()) + sq(p2.y() - p1.y()));
0251 };
0252 const double r1Diff = calRDiff(primeVtxPos, hitPos);
0253 const double r2Diff = calRDiff(hitPos, candPos);
0254 return hitPos.z() - r1Diff * (candPos.z() - hitPos.z()) / r2Diff;
0255 }
0256
0257 const TrajectoryStateOnSurface& TrajSeedMatcher::getTrajStateFromVtx(const TrackingRecHit& hit,
0258 const TrajectoryStateOnSurface& initialState,
0259 const PropagatorWithMaterial& propagator) {
0260 auto& trajStateFromVtxCache =
0261 initialState.charge() == 1 ? trajStateFromVtxPosChargeCache_ : trajStateFromVtxNegChargeCache_;
0262
0263 auto key = hit.det()->gdetIndex();
0264 auto res = trajStateFromVtxCache.find(key);
0265 if (res != trajStateFromVtxCache.end())
0266 return res->second;
0267 else {
0268
0269 auto val = trajStateFromVtxCache.emplace(key, propagator.propagate(initialState, hit.det()->surface()));
0270 return val.first->second;
0271 }
0272 }
0273
0274 const TrajectoryStateOnSurface& TrajSeedMatcher::getTrajStateFromPoint(const TrackingRecHit& hit,
0275 const FreeTrajectoryState& initialState,
0276 const GlobalPoint& point,
0277 const PropagatorWithMaterial& propagator) {
0278 auto& trajStateFromPointCache =
0279 initialState.charge() == 1 ? trajStateFromPointPosChargeCache_ : trajStateFromPointNegChargeCache_;
0280
0281 auto key = std::make_pair(hit.det()->gdetIndex(), point);
0282 auto res = trajStateFromPointCache.find(key);
0283 if (res != trajStateFromPointCache.end())
0284 return res->second;
0285 else {
0286
0287 auto val = trajStateFromPointCache.emplace(key, propagator.propagate(initialState, hit.det()->surface()));
0288 return val.first->second;
0289 }
0290 }
0291
0292 TrajectoryStateOnSurface TrajSeedMatcher::makeTrajStateOnSurface(const GlobalPoint& pos,
0293 const float energy,
0294 const int charge) const {
0295 auto freeTS = ftsFromVertexToPoint(pos, vprim_, energy, charge);
0296 return TrajectoryStateOnSurface(freeTS, *PerpendicularBoundPlaneBuilder{}(freeTS.position(), freeTS.momentum()));
0297 }
0298
0299 void TrajSeedMatcher::clearCache() {
0300 trajStateFromVtxPosChargeCache_.clear();
0301 trajStateFromVtxNegChargeCache_.clear();
0302 trajStateFromPointPosChargeCache_.clear();
0303 trajStateFromPointNegChargeCache_.clear();
0304 }
0305
0306 int TrajSeedMatcher::getNrValidLayersAlongTraj(
0307 const SCHitMatch& hit1, const SCHitMatch& hit2, const GlobalPoint& candPos, const float energy, const int charge) {
0308 double zVertex = cfg_.useRecoVertex ? vprim_.z() : getZVtxFromExtrapolation(vprim_, hit1.hitPos, candPos);
0309 GlobalPoint vertex(vprim_.x(), vprim_.y(), zVertex);
0310
0311 auto firstMatchFreeTraj = ftsFromVertexToPoint(hit1.hitPos, vertex, energy, charge);
0312 auto const& secondHitTraj = getTrajStateFromPoint(hit2.hit, firstMatchFreeTraj, hit1.hitPos, forwardPropagator_);
0313 return getNrValidLayersAlongTraj(hit2.hit.geographicalId(), secondHitTraj);
0314 }
0315
0316 int TrajSeedMatcher::getNrValidLayersAlongTraj(const DetId& hitId, const TrajectoryStateOnSurface& hitTrajState) const {
0317 const DetLayer* detLayer = detLayerGeom_.idToLayer(hitId);
0318 if (detLayer == nullptr)
0319 return 0;
0320
0321 const FreeTrajectoryState& hitFreeState = *hitTrajState.freeState();
0322 auto const inLayers = navSchool_.compatibleLayers(*detLayer, hitFreeState, oppositeToMomentum);
0323 const auto outLayers = navSchool_.compatibleLayers(*detLayer, hitFreeState, alongMomentum);
0324
0325 int nrValidLayers = 1;
0326 for (auto layer : inLayers) {
0327 if (GeomDetEnumerators::isTrackerPixel(layer->subDetector())) {
0328 if (layerHasValidHits(*layer, hitTrajState, backwardPropagator_))
0329 nrValidLayers++;
0330 }
0331 }
0332 for (auto layer : outLayers) {
0333 if (GeomDetEnumerators::isTrackerPixel(layer->subDetector())) {
0334 if (layerHasValidHits(*layer, hitTrajState, forwardPropagator_))
0335 nrValidLayers++;
0336 }
0337 }
0338 return nrValidLayers;
0339 }
0340
0341 bool TrajSeedMatcher::layerHasValidHits(const DetLayer& layer,
0342 const TrajectoryStateOnSurface& hitSurState,
0343 const Propagator& propToLayerFromState) const {
0344
0345
0346
0347 Chi2MeasurementEstimator estimator(30., -3.0, 0.5, 2.0, 0.5, 1.e12);
0348
0349 const std::vector<GeometricSearchDet::DetWithState>& detWithState =
0350 layer.compatibleDets(hitSurState, propToLayerFromState, estimator);
0351 if (detWithState.empty())
0352 return false;
0353 else {
0354 DetId id = detWithState.front().first->geographicalId();
0355 MeasurementDetWithData measDet = measTkEvt_.idToDet(id);
0356
0357 if (measDet.isActive() && !measDet.hasBadComponents(detWithState.front().second))
0358 return true;
0359 else
0360 return false;
0361 }
0362 }
0363
0364 size_t TrajSeedMatcher::getNrHitsRequired(const int nrValidLayers) const {
0365 for (size_t binNr = 0; binNr < cfg_.minNrHitsValidLayerBins.size(); binNr++) {
0366 if (nrValidLayers < cfg_.minNrHitsValidLayerBins[binNr])
0367 return cfg_.minNrHits[binNr];
0368 }
0369 return cfg_.minNrHits.back();
0370 }
0371
0372 TrajSeedMatcher::MatchingCutsV1::MatchingCutsV1(const edm::ParameterSet& pset)
0373 : dPhiMax_(pset.getParameter<double>("dPhiMax")),
0374 dRZMax_(pset.getParameter<double>("dRZMax")),
0375 dRZMaxLowEtThres_(pset.getParameter<double>("dRZMaxLowEtThres")),
0376 dRZMaxLowEtEtaBins_(pset.getParameter<std::vector<double> >("dRZMaxLowEtEtaBins")),
0377 dRZMaxLowEt_(pset.getParameter<std::vector<double> >("dRZMaxLowEt")) {
0378 if (dRZMaxLowEtEtaBins_.size() + 1 != dRZMaxLowEt_.size()) {
0379 throw cms::Exception("InvalidConfig") << " dRZMaxLowEtEtaBins should be 1 less than dRZMaxLowEt when its "
0380 << dRZMaxLowEtEtaBins_.size() << " vs " << dRZMaxLowEt_.size();
0381 }
0382 }
0383
0384 bool TrajSeedMatcher::MatchingCutsV1::operator()(const TrajSeedMatcher::SCHitMatch& scHitMatch) const {
0385 if (dPhiMax_ >= 0 && std::abs(scHitMatch.dPhi) > dPhiMax_)
0386 return false;
0387
0388 const float dRZMax = getDRZCutValue(scHitMatch.et, scHitMatch.eta);
0389 if (dRZMax_ >= 0 && std::abs(scHitMatch.dRZ) > dRZMax)
0390 return false;
0391
0392 return true;
0393 }
0394
0395 float TrajSeedMatcher::MatchingCutsV1::getDRZCutValue(const float scEt, const float scEta) const {
0396 if (scEt >= dRZMaxLowEtThres_)
0397 return dRZMax_;
0398 else {
0399 const float absEta = std::abs(scEta);
0400 for (size_t etaNr = 0; etaNr < dRZMaxLowEtEtaBins_.size(); etaNr++) {
0401 if (absEta < dRZMaxLowEtEtaBins_[etaNr])
0402 return dRZMaxLowEt_[etaNr];
0403 }
0404 return dRZMaxLowEt_.back();
0405 }
0406 }
0407
0408 TrajSeedMatcher::MatchingCutsV2::MatchingCutsV2(const edm::ParameterSet& pset)
0409 : dPhiHighEt_(pset.getParameter<std::vector<double> >("dPhiMaxHighEt")),
0410 dPhiHighEtThres_(pset.getParameter<std::vector<double> >("dPhiMaxHighEtThres")),
0411 dPhiLowEtGrad_(pset.getParameter<std::vector<double> >("dPhiMaxLowEtGrad")),
0412 dRZHighEt_(pset.getParameter<std::vector<double> >("dRZMaxHighEt")),
0413 dRZHighEtThres_(pset.getParameter<std::vector<double> >("dRZMaxHighEtThres")),
0414 dRZLowEtGrad_(pset.getParameter<std::vector<double> >("dRZMaxLowEtGrad")),
0415 etaBins_(pset.getParameter<std::vector<double> >("etaBins")) {
0416 auto binSizeCheck = [](size_t sizeEtaBins, const std::vector<double>& vec, const std::string& name) {
0417 if (vec.size() != sizeEtaBins + 1) {
0418 throw cms::Exception("InvalidConfig")
0419 << " when constructing TrajSeedMatcher::MatchingCutsV2 " << name << " has " << vec.size()
0420 << " bins, it should be equal to #bins of etaBins+1" << sizeEtaBins + 1;
0421 }
0422 };
0423 binSizeCheck(etaBins_.size(), dPhiHighEt_, "dPhiMaxHighEt");
0424 binSizeCheck(etaBins_.size(), dPhiHighEtThres_, "dPhiMaxHighEtThres");
0425 binSizeCheck(etaBins_.size(), dPhiLowEtGrad_, "dPhiMaxLowEtGrad");
0426 binSizeCheck(etaBins_.size(), dRZHighEt_, "dRZMaxHighEt");
0427 binSizeCheck(etaBins_.size(), dRZHighEtThres_, "dRZMaxHighEtThres");
0428 binSizeCheck(etaBins_.size(), dRZLowEtGrad_, "dRZMaxLowEtGrad");
0429 }
0430
0431 bool TrajSeedMatcher::MatchingCutsV2::operator()(const TrajSeedMatcher::SCHitMatch& scHitMatch) const {
0432 size_t binNr = getBinNr(scHitMatch.eta);
0433 float dPhiMax = getCutValue(scHitMatch.et, dPhiHighEt_[binNr], dPhiHighEtThres_[binNr], dPhiLowEtGrad_[binNr]);
0434 if (dPhiMax >= 0 && std::abs(scHitMatch.dPhi) > dPhiMax)
0435 return false;
0436 float dRZMax = getCutValue(scHitMatch.et, dRZHighEt_[binNr], dRZHighEtThres_[binNr], dRZLowEtGrad_[binNr]);
0437 if (dRZMax >= 0 && std::abs(scHitMatch.dRZ) > dRZMax)
0438 return false;
0439
0440 return true;
0441 }
0442
0443
0444 size_t TrajSeedMatcher::MatchingCutsV2::getBinNr(float eta) const {
0445 const float absEta = std::abs(eta);
0446 for (size_t etaNr = 0; etaNr < etaBins_.size(); etaNr++) {
0447 if (absEta < etaBins_[etaNr])
0448 return etaNr;
0449 }
0450 return etaBins_.size();
0451 }