File indexing completed on 2024-04-06 12:09:06
0001 #include "FWCore/Framework/interface/Event.h"
0002 #include "FWCore/Framework/interface/ESHandle.h"
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 #include "FWCore/Utilities/interface/VecArray.h"
0008 #include "FWCore/Utilities/interface/isFinite.h"
0009
0010 #include "DQMServices/Core/interface/DQMEDAnalyzer.h"
0011 #include "DQMServices/Core/interface/DQMStore.h"
0012
0013 #include "DataFormats/Common/interface/Association.h"
0014 #include "DataFormats/TrackReco/interface/Track.h"
0015 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0016 #include "DataFormats/Math/interface/libminifloat.h"
0017 #include "DataFormats/Math/interface/liblogintpack.h"
0018 #include "DataFormats/VertexReco/interface/Vertex.h"
0019 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0020 #include "DataFormats/Math/interface/deltaPhi.h"
0021
0022 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0023 #include "Geometry/Records/interface/TrackerTopologyRcd.h"
0024
0025 #include <iomanip>
0026
0027 namespace {
0028 using dqm::reco::DQMStore;
0029 using dqm::reco::MonitorElement;
0030
0031 template <typename T>
0032 void fillNoFlow(MonitorElement* me, T val) {
0033 auto h = me->getTH1();
0034 const auto xaxis = h->GetXaxis();
0035 if (val <= xaxis->GetXmin())
0036 h->AddBinContent(xaxis->GetFirst());
0037 else if (val >= xaxis->GetXmax())
0038 h->AddBinContent(xaxis->GetLast());
0039 else
0040 h->Fill(val);
0041 }
0042
0043 class HitPatternPrinter {
0044 public:
0045 explicit HitPatternPrinter(const reco::Track& trk) : track(trk) {}
0046
0047 void print(std::ostream& os) const {
0048 const reco::HitPattern& p = track.hitPattern();
0049
0050 for (int i = 0; i < p.numberOfAllHits(reco::HitPattern::TRACK_HITS); ++i) {
0051 uint32_t hit = p.getHitPattern(reco::HitPattern::TRACK_HITS, i);
0052
0053 detLayer(os, p, hit);
0054 if (p.missingHitFilter(hit)) {
0055 os << "(miss)";
0056 } else if (p.inactiveHitFilter(hit)) {
0057 os << "(inact)";
0058 } else if (p.badHitFilter(hit)) {
0059 os << "(bad)";
0060 }
0061 os << " ";
0062 }
0063
0064 if (p.numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) > 0) {
0065 os << "lost inner ";
0066
0067 for (int i = 0; i < p.numberOfAllHits(reco::HitPattern::MISSING_INNER_HITS); ++i) {
0068 uint32_t hit = p.getHitPattern(reco::HitPattern::MISSING_INNER_HITS, i);
0069 detLayer(os, p, hit);
0070 if (p.missingHitFilter(hit)) {
0071 os << "(miss)";
0072 } else if (p.inactiveHitFilter(hit)) {
0073 os << "(inact)";
0074 }
0075 }
0076 }
0077 if (p.numberOfLostHits(reco::HitPattern::MISSING_OUTER_HITS) > 0) {
0078 os << "lost outer ";
0079
0080 for (int i = 0; i < p.numberOfAllHits(reco::HitPattern::MISSING_OUTER_HITS); ++i) {
0081 uint32_t hit = p.getHitPattern(reco::HitPattern::MISSING_OUTER_HITS, i);
0082 detLayer(os, p, hit);
0083 if (p.missingHitFilter(hit)) {
0084 os << "(miss)";
0085 } else if (p.inactiveHitFilter(hit)) {
0086 os << "(inact)";
0087 }
0088 }
0089 }
0090 }
0091
0092 private:
0093 static void detLayer(std::ostream& os, const reco::HitPattern& p, uint32_t hit) {
0094 if (p.pixelBarrelHitFilter(hit)) {
0095 os << "BPIX";
0096 } else if (p.pixelEndcapHitFilter(hit)) {
0097 os << "FPIX";
0098 } else if (p.stripTIBHitFilter(hit)) {
0099 os << "TIB";
0100 } else if (p.stripTIDHitFilter(hit)) {
0101 os << "TID";
0102 } else if (p.stripTOBHitFilter(hit)) {
0103 os << "TOB";
0104 } else if (p.stripTECHitFilter(hit)) {
0105 os << "TEC";
0106 }
0107 os << p.getLayer(hit);
0108 }
0109
0110 const reco::Track& track;
0111 };
0112
0113 std::ostream& operator<<(std::ostream& os, const HitPatternPrinter& hpp) {
0114 hpp.print(os);
0115 return os;
0116 }
0117
0118 class TrackAlgoPrinter {
0119 public:
0120 explicit TrackAlgoPrinter(const reco::Track& trk) : track(trk) {}
0121
0122 void print(std::ostream& os) const {
0123 edm::VecArray<reco::TrackBase::TrackAlgorithm, reco::TrackBase::algoSize> algos;
0124 for (int ialgo = 0; ialgo < reco::TrackBase::algoSize; ++ialgo) {
0125 auto algo = static_cast<reco::TrackBase::TrackAlgorithm>(ialgo);
0126 if (track.isAlgoInMask(algo)) {
0127 algos.push_back(algo);
0128 }
0129 }
0130
0131 os << "algo " << reco::TrackBase::algoName(track.algo());
0132 if (track.originalAlgo() != track.algo())
0133 os << " originalAlgo " << reco::TrackBase::algoName(track.originalAlgo());
0134 if (algos.size() > 1) {
0135 os << " algoMask";
0136 for (auto algo : algos) {
0137 os << " " << reco::TrackBase::algoName(algo);
0138 }
0139 }
0140 }
0141
0142 private:
0143 const reco::Track& track;
0144 };
0145 std::ostream& operator<<(std::ostream& os, const TrackAlgoPrinter& tap) {
0146 tap.print(os);
0147 return os;
0148 }
0149
0150 double diffRelative(double a, double b) { return (a - b) / b; }
0151
0152 class LogIntHelper {
0153 public:
0154 LogIntHelper(double lmin, double lmax) : lmin_(lmin), lmax_(lmax) {}
0155
0156 class UnderOverflow {
0157 public:
0158 UnderOverflow(double largestValue, double smallestValue, std::function<double(double)> modifyUnpack)
0159 : unpackedLargestValue_(modifyUnpack ? modifyUnpack(largestValue) : largestValue),
0160 unpackedSmallestValue_(modifyUnpack ? modifyUnpack(smallestValue) : smallestValue) {}
0161
0162 bool compatibleWithUnderflow(double value) const { return value == unpackedSmallestValue_; }
0163 void printNonOkUnderflow(std::ostream& os) const { os << " (not min " << unpackedSmallestValue_ << ")"; }
0164
0165 bool compatibleWithOverflow(double value) const { return value == unpackedLargestValue_; }
0166 void printNonOkOverflow(std::ostream& os) const { os << " (not max " << unpackedLargestValue_ << ")"; }
0167
0168 private:
0169
0170
0171
0172 const float unpackedLargestValue_;
0173 const float unpackedSmallestValue_;
0174 };
0175
0176 static std::string maxName() { return "max"; }
0177 static std::string minName() { return "min"; }
0178
0179 UnderOverflow underOverflowHelper(double value, std::function<double(double)> modifyUnpack) const {
0180 return UnderOverflow(
0181 largestValue(), value >= 0 ? smallestPositiveValue() : std::abs(smallestNegativeValue()), modifyUnpack);
0182 }
0183
0184 double largestValue() const { return logintpack::unpack8log(127, lmin_, lmax_); }
0185
0186 static bool wouldBeDenorm(double value) { return false; }
0187
0188
0189 bool lessThanSmallestValue(double value) const {
0190 if (value >= 0)
0191 return value < smallestPositiveValue();
0192 else
0193 return value > smallestNegativeValue();
0194 }
0195
0196 double smallestPositiveValue() const { return logintpack::unpack8log(logintpack::smallestPositive, lmin_, lmax_); }
0197
0198 double smallestNegativeValue() const { return logintpack::unpack8log(logintpack::smallestNegative, lmin_, lmax_); }
0199
0200 private:
0201 const double lmin_;
0202 const double lmax_;
0203 };
0204 class Float16Helper {
0205 public:
0206 class UnderOverflow {
0207 public:
0208 static void printNonOkUnderflow(std::ostream& os) { os << " (not 0)"; }
0209 static bool compatibleWithUnderflow(double value) { return value == 0.0; }
0210 static void printNonOkOverflow(std::ostream& os) { os << " (not inf)"; }
0211 static bool compatibleWithOverflow(double value) { return edm::isNotFinite(value); }
0212 };
0213
0214 static std::string maxName() { return "inf"; }
0215 static std::string minName() { return "0"; }
0216
0217 static UnderOverflow underOverflowHelper(double value, std::function<double(double)>) { return UnderOverflow(); }
0218
0219 static double largestValue() { return MiniFloatConverter::max32RoundedToMax16(); }
0220
0221 static bool wouldBeDenorm(double value) {
0222 const float valuef = static_cast<float>(value);
0223 return valuef >= MiniFloatConverter::denorm_min() && valuef < MiniFloatConverter::min();
0224 }
0225
0226 static bool lessThanSmallestValue(double value) { return std::abs(value) < smallestValue(); }
0227
0228 static double smallestValue() { return MiniFloatConverter::denorm_min(); }
0229 };
0230
0231 enum class RangeStatus {
0232 inrange = 0,
0233 inrange_signflip = 1,
0234 denormal = 2,
0235 underflow_OK = 3,
0236 underflow_notOK = 4,
0237 overflow_OK = 5,
0238 overflow_notOK = 6
0239 };
0240 bool isInRange(RangeStatus status) { return status == RangeStatus::inrange || status == RangeStatus::denormal; }
0241
0242 template <typename T>
0243 class PackedValueCheckResult {
0244 public:
0245 PackedValueCheckResult(RangeStatus status,
0246 double diff,
0247 double pcvalue,
0248 double trackvalue,
0249 double rangeMin,
0250 double rangeMax,
0251 const typename T::UnderOverflow& underOverflow)
0252 : diff_(diff),
0253 pcvalue_(pcvalue),
0254 trackvalue_(trackvalue),
0255 rangeMin_(rangeMin),
0256 rangeMax_(rangeMax),
0257 status_(status),
0258 underOverflow_(underOverflow) {}
0259
0260 RangeStatus status() const { return status_; }
0261 double diff() const { return diff_; }
0262
0263 bool outsideExpectedRange() const {
0264 if (status_ == RangeStatus::inrange)
0265 return diff_ < rangeMin_ || diff_ > rangeMax_;
0266
0267 return status_ == RangeStatus::underflow_notOK || status_ == RangeStatus::overflow_notOK ||
0268 status_ == RangeStatus::inrange_signflip;
0269 }
0270
0271 void print(std::ostream& os) const {
0272 if (outsideExpectedRange())
0273 os << "!! ";
0274 os << "(" << rangeMin_ << "," << rangeMax_ << ") ";
0275
0276 os << diff_ << " " << pcvalue_;
0277 if (status_ == RangeStatus::underflow_OK || status_ == RangeStatus::underflow_notOK) {
0278 os << " (underflow) ";
0279 if (status_ == RangeStatus::underflow_notOK)
0280 underOverflow_.printNonOkUnderflow(os);
0281 } else if (status_ == RangeStatus::overflow_OK || status_ == RangeStatus::overflow_notOK) {
0282 os << " (overflow) ";
0283 if (status_ == RangeStatus::overflow_notOK)
0284 underOverflow_.printNonOkOverflow(os);
0285 } else if (status_ == RangeStatus::denormal)
0286 os << " (denormal)";
0287 os << " " << trackvalue_;
0288 }
0289
0290 private:
0291 const double diff_;
0292 const double pcvalue_;
0293 const double trackvalue_;
0294 const double rangeMin_;
0295 const double rangeMax_;
0296 const RangeStatus status_;
0297 const typename T::UnderOverflow underOverflow_;
0298 };
0299
0300 struct Range {
0301 Range(double mi, double ma) : min(mi), max(ma) {}
0302 const double min, max;
0303 };
0304 struct RangeAbs {
0305 RangeAbs(double val) : min(-val), max(val) {}
0306 const double min, max;
0307 };
0308
0309 template <typename T>
0310 class PackedValueCheck {
0311 public:
0312 template <typename R, typename... Args>
0313 PackedValueCheck(const R& range, Args&&... args)
0314 : helper_(std::forward<Args>(args)...), rangeMin_(range.min), rangeMax_(range.max) {}
0315
0316 void book(DQMStore::IBooker& iBooker,
0317 const std::string& name,
0318 const std::string& title,
0319 int nbins,
0320 double min,
0321 double max,
0322 int flow_nbins,
0323 double flow_min,
0324 double flow_max) {
0325 hInrange = iBooker.book1D(name, title, nbins, min, max);
0326 hUnderOverflowSign = iBooker.book1D(name + "UnderOverFlowSign",
0327 title + " with over- and underflow, and sign flip",
0328 flow_nbins,
0329 flow_min,
0330 flow_max);
0331 hStatus = iBooker.book1D(name + "Status", title + " status", 7, -0.5, 6.5);
0332 hStatus->setBinLabel(1, "In range");
0333 hStatus->setBinLabel(2, "In range, sign flip");
0334 hStatus->setBinLabel(3, "Denormal");
0335 hStatus->setBinLabel(4, "Underflow, PC is " + T::minName());
0336 hStatus->setBinLabel(5, "Underflow, PC is not " + T::minName());
0337 hStatus->setBinLabel(6, "Overflow, PC is " + T::maxName());
0338 hStatus->setBinLabel(7, "Overflow, PC is not " + T::maxName());
0339 }
0340
0341 PackedValueCheckResult<T> fill(double pcvalue,
0342 double trackvalue,
0343 std::function<double(double)> modifyPack = std::function<double(double)>(),
0344 std::function<double(double)> modifyUnpack = std::function<double(double)>()) {
0345 const auto diff = diffRelative(pcvalue, trackvalue);
0346
0347 const auto tmpSigned = modifyPack ? modifyPack(trackvalue) : trackvalue;
0348 const auto tmp = std::abs(tmpSigned);
0349 const auto underOverflow = helper_.underOverflowHelper(tmpSigned, modifyUnpack);
0350 RangeStatus status;
0351 if (tmp > helper_.largestValue()) {
0352 fillNoFlow(hUnderOverflowSign, diff);
0353 if (underOverflow.compatibleWithOverflow(std::abs(pcvalue))) {
0354 status = RangeStatus::overflow_OK;
0355 } else {
0356 status = RangeStatus::overflow_notOK;
0357 }
0358 } else if (helper_.lessThanSmallestValue(tmpSigned)) {
0359 fillNoFlow(hUnderOverflowSign, diff);
0360 if (underOverflow.compatibleWithUnderflow(std::abs(pcvalue))) {
0361 status = RangeStatus::underflow_OK;
0362 } else {
0363 status = RangeStatus::underflow_notOK;
0364 }
0365 } else {
0366
0367 if (pcvalue * trackvalue > 0 || pcvalue == trackvalue) {
0368 if (T::wouldBeDenorm(tmp)) {
0369 status = RangeStatus::denormal;
0370 } else {
0371 status = RangeStatus::inrange;
0372 }
0373 fillNoFlow(hInrange, diff);
0374 } else {
0375 fillNoFlow(hUnderOverflowSign, diff);
0376 status = RangeStatus::inrange_signflip;
0377 }
0378 }
0379 hStatus->Fill(static_cast<int>(status));
0380
0381 return PackedValueCheckResult<T>(status, diff, pcvalue, trackvalue, rangeMin_, rangeMax_, underOverflow);
0382 }
0383
0384 private:
0385 const T helper_;
0386 const double rangeMin_;
0387 const double rangeMax_;
0388
0389 MonitorElement* hInrange;
0390 MonitorElement* hUnderOverflowSign;
0391 MonitorElement* hStatus;
0392 };
0393 template <typename T>
0394 std::ostream& operator<<(std::ostream& os, const PackedValueCheckResult<T>& res) {
0395 res.print(os);
0396 return os;
0397 }
0398 }
0399
0400 class PackedCandidateTrackValidator : public DQMEDAnalyzer {
0401 public:
0402 PackedCandidateTrackValidator(const edm::ParameterSet& pset);
0403 ~PackedCandidateTrackValidator() override;
0404
0405 void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
0406 void analyze(const edm::Event&, const edm::EventSetup&) override;
0407
0408 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0409
0410 private:
0411 edm::EDGetTokenT<edm::View<reco::Track>> tracksToken_;
0412 edm::EDGetTokenT<reco::VertexCollection> verticesToken_;
0413 edm::EDGetTokenT<edm::Association<pat::PackedCandidateCollection>> trackToPackedCandidateToken_;
0414
0415 std::string rootFolder_;
0416 bool debug_;
0417
0418 enum {
0419 sf_AllTracks = 0,
0420 sf_AssociatedToPC = 1,
0421 sf_PCIsCharged = 2,
0422 sf_PCHasTrack = 3,
0423 sf_PCIsNotElectron = 4,
0424 sf_PCHasHits = 5,
0425 sf_PCNdofNot0 = 6,
0426 sf_NoMissingInnerHits = 7
0427 };
0428 MonitorElement* h_selectionFlow;
0429
0430 MonitorElement* h_diffVx;
0431 MonitorElement* h_diffVy;
0432 MonitorElement* h_diffVz;
0433
0434 MonitorElement* h_diffNormalizedChi2;
0435 MonitorElement* h_diffNdof;
0436
0437 MonitorElement* h_diffCharge;
0438 MonitorElement* h_diffIsHighPurity;
0439
0440 MonitorElement* h_diffPt;
0441 MonitorElement* h_diffEta;
0442 MonitorElement* h_diffPhi;
0443 PackedValueCheck<Float16Helper> h_diffDxyAssocPV;
0444 PackedValueCheck<Float16Helper> h_diffDzAssocPV;
0445 MonitorElement* h_diffDxyPV;
0446 MonitorElement* h_diffDzPV;
0447
0448 MonitorElement* h_diffTrackDxyAssocPV;
0449 MonitorElement* h_diffTrackDzAssocPV;
0450
0451 PackedValueCheck<LogIntHelper> h_diffCovQoverpQoverp;
0452 PackedValueCheck<LogIntHelper> h_diffCovLambdaLambda;
0453 PackedValueCheck<LogIntHelper> h_diffCovLambdaDsz;
0454 PackedValueCheck<LogIntHelper> h_diffCovPhiPhi;
0455 PackedValueCheck<LogIntHelper> h_diffCovPhiDxy;
0456 PackedValueCheck<Float16Helper> h_diffCovDxyDxy;
0457 PackedValueCheck<Float16Helper> h_diffCovDxyDsz;
0458 PackedValueCheck<Float16Helper> h_diffCovDszDsz;
0459
0460 MonitorElement* h_diffDxyError;
0461 MonitorElement* h_diffDszError;
0462 MonitorElement* h_diffDzError;
0463
0464 MonitorElement* h_diffTrackDxyError;
0465 MonitorElement* h_diffTrackDzError;
0466
0467 MonitorElement* h_diffPtError;
0468 MonitorElement* h_diffEtaError;
0469
0470 MonitorElement* h_diffNumberOfPixelLayers;
0471 MonitorElement* h_diffNumberOfStripLayers;
0472 MonitorElement* h_diffNumberOfPixelHits;
0473 MonitorElement* h_diffNumberOfHits;
0474 MonitorElement* h_diffLostInnerHits;
0475
0476 MonitorElement* h_diffHitPatternPixelLayersWithMeasurement;
0477 MonitorElement* h_diffHitPatternTrackerLayersWithMeasurement;
0478 MonitorElement* h_diffHitPatternStripLayersWithMeasurement;
0479 MonitorElement* h_diffHitPatternNumberOfValidPixelHits;
0480 MonitorElement* h_diffHitPatternNumberOfValidHits;
0481 MonitorElement* h_diffHitPatternNumberOfLostInnerHits;
0482 MonitorElement* h_diffHitPatternHasValidHitInFirstPixelBarrel;
0483
0484 MonitorElement* h_numberPixelLayersOverMax;
0485 MonitorElement* h_numberStripLayersOverMax;
0486 MonitorElement* h_numberLayersOverMax;
0487 MonitorElement* h_numberPixelHitsOverMax;
0488 MonitorElement* h_numberStripHitsOverMax;
0489 MonitorElement* h_numberHitsOverMax;
0490 };
0491
0492 PackedCandidateTrackValidator::PackedCandidateTrackValidator(const edm::ParameterSet& iConfig)
0493 : tracksToken_(consumes<edm::View<reco::Track>>(iConfig.getUntrackedParameter<edm::InputTag>("tracks"))),
0494 verticesToken_(consumes<reco::VertexCollection>(iConfig.getUntrackedParameter<edm::InputTag>("vertices"))),
0495 trackToPackedCandidateToken_(consumes<edm::Association<pat::PackedCandidateCollection>>(
0496 iConfig.getUntrackedParameter<edm::InputTag>("trackToPackedCandidateAssociation"))),
0497 rootFolder_(iConfig.getUntrackedParameter<std::string>("rootFolder")),
0498 debug_(iConfig.getUntrackedParameter<bool>("debug")),
0499 h_diffDxyAssocPV(RangeAbs(0.001)),
0500 h_diffDzAssocPV(RangeAbs(0.001)),
0501 h_diffCovQoverpQoverp(Range(-1e-6, 0.13), -15, 0),
0502 h_diffCovLambdaLambda(
0503 Range(-1e-6, 0.13), -20, -5),
0504 h_diffCovLambdaDsz(RangeAbs(0.13), -17, -4),
0505 h_diffCovPhiPhi(RangeAbs(0.13), -15, 0),
0506 h_diffCovPhiDxy(RangeAbs(0.13), -17, -4),
0507 h_diffCovDxyDxy(RangeAbs(0.001)),
0508 h_diffCovDxyDsz(RangeAbs(0.001)),
0509 h_diffCovDszDsz(RangeAbs(0.001)) {}
0510
0511 PackedCandidateTrackValidator::~PackedCandidateTrackValidator() {}
0512
0513 void PackedCandidateTrackValidator::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0514 edm::ParameterSetDescription desc;
0515
0516 desc.addUntracked<edm::InputTag>("tracks", edm::InputTag("generalTracks"));
0517 desc.addUntracked<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
0518 desc.addUntracked<edm::InputTag>("trackToPackedCandidateAssociation", edm::InputTag("packedPFCandidates"));
0519 desc.addUntracked<std::string>("rootFolder", "Tracking/PackedCandidate");
0520 desc.addUntracked<bool>("debug", false);
0521
0522 descriptions.add("packedCandidateTrackValidator", desc);
0523 }
0524
0525 void PackedCandidateTrackValidator::bookHistograms(DQMStore::IBooker& iBooker,
0526 edm::Run const&,
0527 edm::EventSetup const&) {
0528 iBooker.setCurrentFolder(rootFolder_);
0529
0530 h_selectionFlow = iBooker.book1D("selectionFlow", "Track selection flow", 8, -0.5, 7.5);
0531 h_selectionFlow->setBinLabel(1, "All tracks");
0532 h_selectionFlow->setBinLabel(2, "Associated to PackedCandidate");
0533 h_selectionFlow->setBinLabel(3, "PC is charged"), h_selectionFlow->setBinLabel(4, "PC has track");
0534 h_selectionFlow->setBinLabel(5, "PC is not electron");
0535 h_selectionFlow->setBinLabel(6, "PC has hits");
0536 h_selectionFlow->setBinLabel(7, "PC ndof != 0");
0537 h_selectionFlow->setBinLabel(8, "Track: no missing inner hits");
0538
0539 constexpr int diffBins = 50;
0540
0541 h_diffVx =
0542 iBooker.book1D("diffVx", "PackedCandidate::bestTrack() - reco::Track in vx()", diffBins, -0.2, 0.2);
0543 h_diffVy =
0544 iBooker.book1D("diffVy", "PackedCandidate::bestTrack() - reco::Track in vy()", diffBins, -0.2, 0.2);
0545 h_diffVz =
0546 iBooker.book1D("diffVz", "PackedCandidate::bestTrack() - reco::Track in vz()", diffBins, -0.4, 0.4);
0547
0548 h_diffNormalizedChi2 = iBooker.book1D("diffNormalizedChi2",
0549 "PackedCandidate::bestTrack() - reco::Track in normalizedChi2()",
0550 30,
0551 -1.5,
0552 1.5);
0553 h_diffNdof = iBooker.book1D(
0554 "diffNdof", "PackedCandidate::bestTrack() - reco::Track in ndof()", 33, -30.5, 2.5);
0555
0556 h_diffCharge = iBooker.book1D(
0557 "diffCharge", "PackedCandidate::bestTrack() - reco::Track in charge()", 5, -2.5, 2.5);
0558 h_diffIsHighPurity = iBooker.book1D("diffIsHighPurity",
0559 "PackedCandidate::bestTrack() - reco::Track in quality(highPurity)",
0560 3,
0561 -1.5,
0562 1.5);
0563
0564 h_diffPt = iBooker.book1D("diffPt",
0565 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in pt()",
0566 diffBins,
0567 -1.1,
0568 1.1);
0569 h_diffEta = iBooker.book1D(
0570 "diffEta", "PackedCandidate::bestTrack() - reco::Track in eta()", diffBins, -0.001, 0.001);
0571 h_diffPhi = iBooker.book1D("diffPhi",
0572 "PackedCandidate::bestTrack() - reco::Track in phi()",
0573 diffBins,
0574 -0.0005,
0575 0.0005);
0576
0577 h_diffDxyAssocPV.book(iBooker,
0578 "diffDxyAssocPV",
0579 "(PackedCandidate::dxy() - reco::Track::dxy(assocPV))/reco::Track",
0580 40,
0581 -0.001,
0582 0.001,
0583 50,
0584 -0.5,
0585 0.5);
0586 h_diffDzAssocPV.book(iBooker,
0587 "diffDzAssocPV",
0588 "(PackedCandidate::dzAssociatedPV() - reco::Track::dz(assocPV))/reco::Track",
0589 40,
0590 -0.001,
0591 0.001,
0592 50,
0593 -0.5,
0594 0.5);
0595 h_diffDxyPV = iBooker.book1D("diffDxyPV",
0596 "(PackedCandidate::dxy(PV) - reco::Track::dxy(PV))/reco::Track",
0597 diffBins,
0598 -0.01,
0599 0.01);
0600 h_diffDzPV = iBooker.book1D("diffDzPV",
0601 "(PackedCandidate::dz(PV) - reco::Track::dz(PV))/reco::Track",
0602 diffBins,
0603 -0.01,
0604 0.01);
0605 h_diffTrackDxyAssocPV =
0606 iBooker.book1D("diffTrackDxyAssocPV",
0607 "(PackedCandidate::bestTrack()::dxy(assocPV)) - reco::Track::dxy(assocPV))/reco::Track",
0608 diffBins,
0609 -0.01,
0610 0.01);
0611 h_diffTrackDzAssocPV =
0612 iBooker.book1D("diffTrackDzAssocPV",
0613 "(PackedCandidate::bestTrack()::dz(assocPV)) - reco::Track::dz(assocPV))/reco::Track",
0614 diffBins,
0615 -0.01,
0616 0.01);
0617
0618 h_diffCovQoverpQoverp.book(iBooker,
0619 "diffCovQoverpQoverp",
0620 "(PackedCandidate::bestTrack() - reco::Track)/reco::track in cov(qoverp, qoverp)",
0621 40,
0622 -0.05,
0623 0.15,
0624 50,
0625 -0.5,
0626 0.5);
0627 h_diffCovLambdaLambda.book(
0628 iBooker,
0629 "diffCovLambdaLambda",
0630 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in cov(lambda, lambda)",
0631 40,
0632 -0.05,
0633 0.15,
0634 50,
0635 -0.5,
0636 0.5);
0637 h_diffCovLambdaDsz.book(iBooker,
0638 "diffCovLambdaDsz",
0639 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in cov(lambda, dsz)",
0640 60,
0641 -0.15,
0642 0.15,
0643 50,
0644 -1,
0645 1);
0646 h_diffCovPhiPhi.book(
0647 iBooker,
0648 "diffCovPhiPhi",
0649 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in cov(phi, phi)",
0650 40,
0651 -0.05,
0652 0.15,
0653 50,
0654 -0.5,
0655 0.5);
0656 h_diffCovPhiDxy.book(iBooker,
0657 "diffCovPhiDxy",
0658 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in cov(phi, dxy)",
0659 60,
0660 -0.15,
0661 0.15,
0662 50,
0663 -1,
0664 1);
0665 h_diffCovDxyDxy.book(iBooker,
0666 "diffCovDxyDxy",
0667 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in cov(dxy, dxy)",
0668 40,
0669 -0.001,
0670 0.001,
0671 50,
0672 -0.1,
0673 0.1);
0674 h_diffCovDxyDsz.book(iBooker,
0675 "diffCovDxyDsz",
0676 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in cov(dxy, dsz)",
0677 40,
0678 -0.001,
0679 0.001,
0680 50,
0681 -0.5,
0682 0.5);
0683 h_diffCovDszDsz.book(iBooker,
0684 "diffCovDszDsz",
0685 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in cov(dsz, dsz)",
0686 40,
0687 -0.001,
0688 0.001,
0689 50,
0690 -0.1,
0691 0.1);
0692
0693 h_diffDxyError = iBooker.book1D("diffDxyError",
0694 "(PackedCandidate::dxyError() - reco::Track::dxyError())/reco::Track",
0695 40,
0696 -0.001,
0697 0.001);
0698 h_diffDszError = iBooker.book1D("diffDszError",
0699 "(PackedCandidate::dzError() - reco::Track::dszError())/reco::Track",
0700 40,
0701 -0.001,
0702 0.001);
0703 h_diffDzError = iBooker.book1D("diffDzError",
0704 "(PackedCandidate::dzError() - reco::Track::dzError())/reco::Track",
0705 40,
0706 -0.001,
0707 0.001);
0708
0709 h_diffTrackDxyError = iBooker.book1D("diffTrackDxyError",
0710 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in dxyError()",
0711 40,
0712 -0.001,
0713 0.001);
0714 h_diffTrackDzError = iBooker.book1D("diffTrackDzError",
0715 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in dzError()",
0716 40,
0717 -0.05,
0718 0.05);
0719
0720 h_diffPtError = iBooker.book1D("diffPtError",
0721 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in ptError()",
0722 diffBins,
0723 -1.1,
0724 1.1);
0725 h_diffEtaError = iBooker.book1D("diffEtaError",
0726 "(PackedCandidate::bestTrack() - reco::Track)/reco::Track in etaError()",
0727 60,
0728 -0.15,
0729 0.15);
0730
0731 h_diffNumberOfPixelLayers = iBooker.book1D(
0732 "diffNumberOfPixelLayers",
0733 "PackedCandidate::pixelLayersWithMeasurement() - reco::Track::hitPattern::pixelLayersWithMeasurement()",
0734 5,
0735 -2.5,
0736 2.5);
0737 h_diffNumberOfStripLayers = iBooker.book1D(
0738 "diffNumberOfStripLayers",
0739 "PackedCandidate::stripLayersWithMeasurement() - reco::Track::hitPattern::stripLayersWithMeasurement()",
0740 5,
0741 -2.5,
0742 2.5);
0743 h_diffNumberOfPixelHits =
0744 iBooker.book1D("diffNumberOfPixelHits",
0745 "PackedCandidate::numberOfPixelHits() - reco::Track::hitPattern::numberOfValidPixelHits()",
0746 5,
0747 -2.5,
0748 2.5);
0749 h_diffNumberOfHits = iBooker.book1D("diffNumberOfHits",
0750 "PackedCandidate::numberHits() - reco::Track::hitPattern::numberOfValidHits()",
0751 5,
0752 -2.5,
0753 2.5);
0754 h_diffLostInnerHits =
0755 iBooker.book1D("diffLostInnerHits",
0756 "PackedCandidate::lostInnerHits() - reco::Track::hitPattern::numberOfLostHits(MISSING_INNER_HITS)",
0757 5,
0758 -2.5,
0759 2.5);
0760
0761 h_diffHitPatternPixelLayersWithMeasurement =
0762 iBooker.book1D("diffHitPatternPixelLayersWithMeasurement",
0763 "PackedCandidate::bestTrack() - reco::Track in hitPattern::pixelLayersWithMeasurement()",
0764 13,
0765 -10.5,
0766 2.5);
0767 h_diffHitPatternStripLayersWithMeasurement =
0768 iBooker.book1D("diffHitPatternStripLayersWithMeasurement",
0769 "PackedCandidate::bestTrack() - reco::Track in hitPattern::stripLayersWithMeasurement()",
0770 13,
0771 -10.5,
0772 2.5);
0773 h_diffHitPatternTrackerLayersWithMeasurement =
0774 iBooker.book1D("diffHitPatternTrackerLayersWithMeasurement",
0775 "PackedCandidate::bestTrack() - reco::Track in hitPattern::trackerLayersWithMeasurement()",
0776 13,
0777 -10.5,
0778 2.5);
0779 h_diffHitPatternNumberOfValidPixelHits =
0780 iBooker.book1D("diffHitPatternNumberOfValidPixelHits",
0781 "PackedCandidate::bestTrack() - reco::Track in hitPattern::numberOfValidPixelHits()",
0782 13,
0783 -10.5,
0784 2.5);
0785 h_diffHitPatternNumberOfValidHits =
0786 iBooker.book1D("diffHitPatternNumberOfValidHits",
0787 "PackedCandidate::bestTrack() - reco::Track in hitPattern::numberOfValidHits()",
0788 13,
0789 -10.5,
0790 2.5);
0791 h_diffHitPatternNumberOfLostInnerHits =
0792 iBooker.book1D("diffHitPatternNumberOfLostPixelHits",
0793 "PackedCandidate::bestTrack() - reco::Track in hitPattern::numberOfLostHits(MISSING_INNER_HITS)",
0794 13,
0795 -10.5,
0796 2.5);
0797 h_diffHitPatternHasValidHitInFirstPixelBarrel =
0798 iBooker.book1D("diffHitPatternHasValidHitInFirstPixelBarrel",
0799 "PackedCandidate::bestTrack() - reco::Track in hitPattern::hasValidHitInFirstPixelBarrel",
0800 3,
0801 -1.5,
0802 1.5);
0803
0804 h_numberPixelLayersOverMax = iBooker.book1D(
0805 "numberPixelLayersOverMax", "Number of pixel layers over the maximum of PackedCandidate", 10, 0, 10);
0806 h_numberStripLayersOverMax = iBooker.book1D(
0807 "numberStripLayersOverMax", "Number of strip layers over the maximum of PackedCandidate", 10, 0, 10);
0808 h_numberLayersOverMax =
0809 iBooker.book1D("numberLayersOverMax", "Number of layers over the maximum of PackedCandidate", 20, 0, 20);
0810 h_numberPixelHitsOverMax =
0811 iBooker.book1D("numberPixelHitsOverMax", "Number of pixel hits over the maximum of PackedCandidate", 10, 0, 10);
0812 h_numberStripHitsOverMax =
0813 iBooker.book1D("numberStripHitsOverMax", "Number of strip hits over the maximum of PackedCandidate", 10, 0, 10);
0814 h_numberHitsOverMax =
0815 iBooker.book1D("numberHitsOverMax", "Number of hits over the maximum of PackedCandidate", 20, 0, 20);
0816 }
0817
0818 void PackedCandidateTrackValidator::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0819 edm::Handle<edm::View<reco::Track>> htracks;
0820 iEvent.getByToken(tracksToken_, htracks);
0821 const auto& tracks = *htracks;
0822
0823 edm::Handle<reco::VertexCollection> hvertices;
0824 iEvent.getByToken(verticesToken_, hvertices);
0825 const auto& vertices = *hvertices;
0826
0827 if (vertices.empty())
0828 return;
0829 const reco::Vertex& pv = vertices[0];
0830
0831 edm::Handle<edm::Association<pat::PackedCandidateCollection>> hassoc;
0832 iEvent.getByToken(trackToPackedCandidateToken_, hassoc);
0833 const auto& trackToPackedCandidate = *hassoc;
0834
0835 for (size_t i = 0; i < tracks.size(); ++i) {
0836 auto trackPtr = tracks.ptrAt(i);
0837 const reco::Track& track = *trackPtr;
0838 h_selectionFlow->Fill(sf_AllTracks);
0839
0840 pat::PackedCandidateRef pcRef = trackToPackedCandidate[trackPtr];
0841 if (pcRef.isNull()) {
0842 continue;
0843 }
0844 h_selectionFlow->Fill(sf_AssociatedToPC);
0845
0846
0847 if (pcRef->charge() == 0) {
0848 continue;
0849 }
0850 h_selectionFlow->Fill(sf_PCIsCharged);
0851
0852 const reco::Track* trackPcPtr = pcRef->bestTrack();
0853 if (!trackPcPtr) {
0854 continue;
0855 }
0856 h_selectionFlow->Fill(sf_PCHasTrack);
0857
0858
0859 if (std::abs(pcRef->pdgId()) == 11) {
0860 continue;
0861 }
0862 h_selectionFlow->Fill(sf_PCIsNotElectron);
0863
0864
0865 const reco::Track& trackPc = *trackPcPtr;
0866 if (trackPc.hitPattern().numberOfValidHits() == 0) {
0867 continue;
0868 }
0869 h_selectionFlow->Fill(sf_PCHasHits);
0870
0871 auto slimmedVertexRef = pcRef->vertexRef();
0872 const reco::Vertex& pcVertex = vertices[slimmedVertexRef.key()];
0873
0874 fillNoFlow(h_diffVx, trackPc.vx() - track.vx());
0875 fillNoFlow(h_diffVy, trackPc.vy() - track.vy());
0876 fillNoFlow(h_diffVz, trackPc.vz() - track.vz());
0877
0878
0879
0880
0881
0882
0883 double diffNormalizedChi2 = 0;
0884 if (trackPc.ndof() != 0) {
0885 h_selectionFlow->Fill(sf_PCNdofNot0);
0886 diffNormalizedChi2 = trackPc.normalizedChi2() - track.normalizedChi2();
0887 fillNoFlow(h_diffNormalizedChi2, diffNormalizedChi2);
0888 }
0889 fillNoFlow(h_diffNdof, trackPc.ndof() - track.ndof());
0890
0891 auto diffCharge = trackPc.charge() - track.charge();
0892 fillNoFlow(h_diffCharge, diffCharge);
0893 int diffHP = static_cast<int>(trackPc.quality(reco::TrackBase::highPurity)) -
0894 static_cast<int>(track.quality(reco::TrackBase::highPurity));
0895 fillNoFlow(h_diffIsHighPurity, diffHP);
0896
0897 const auto diffPt = diffRelative(trackPc.pt(), track.pt());
0898 const auto diffPhi = reco::deltaPhi(trackPc.phi(), track.phi());
0899 fillNoFlow(h_diffPt, diffPt);
0900 fillNoFlow(h_diffEta, trackPc.eta() - track.eta());
0901 fillNoFlow(h_diffPhi, diffPhi);
0902
0903 const auto diffDxyAssocPV =
0904 h_diffDxyAssocPV.fill(pcRef->dxy(), track.dxy(pcVertex.position()), [](double value) { return value * 100.; });
0905 const auto diffDzAssocPV = h_diffDzAssocPV.fill(
0906 pcRef->dzAssociatedPV(), track.dz(pcVertex.position()), [](double value) { return value * 100.; });
0907 const auto diffDxyPV = diffRelative(pcRef->dxy(pv.position()), track.dxy(pv.position()));
0908 const auto diffDzPV = diffRelative(pcRef->dz(pv.position()), track.dz(pv.position()));
0909 fillNoFlow(h_diffDxyPV, diffDxyPV);
0910 fillNoFlow(h_diffDzPV, diffDzPV);
0911 fillNoFlow(h_diffTrackDxyAssocPV, diffRelative(trackPc.dxy(pcVertex.position()), track.dxy(pcVertex.position())));
0912 fillNoFlow(h_diffTrackDzAssocPV, diffRelative(trackPc.dz(pcVertex.position()), track.dz(pcVertex.position())));
0913
0914 auto fillCov1 = [&](auto& hlp, const int i, const int j) {
0915 return hlp.fill(trackPc.covariance(i, j), track.covariance(i, j));
0916 };
0917 auto fillCov2 = [&](auto& hlp, const int i, const int j, std::function<double(double)> modifyPack) {
0918 return hlp.fill(trackPc.covariance(i, j), track.covariance(i, j), modifyPack);
0919 };
0920 auto fillCov3 = [&](auto& hlp,
0921 const int i,
0922 const int j,
0923 std::function<double(double)> modifyPack,
0924 std::function<double(double)> modifyUnpack) {
0925 return hlp.fill(trackPc.covariance(i, j), track.covariance(i, j), modifyPack, modifyUnpack);
0926 };
0927
0928 const auto pcPt = pcRef->pt();
0929 const auto diffCovQoverpQoverp = fillCov3(
0930 h_diffCovQoverpQoverp,
0931 reco::TrackBase::i_qoverp,
0932 reco::TrackBase::i_qoverp,
0933 [=](double val) { return val * pcPt * pcPt; },
0934 [=](double val) { return val / pcPt / pcPt; });
0935 const auto diffCovLambdaLambda =
0936 fillCov1(h_diffCovLambdaLambda, reco::TrackBase::i_lambda, reco::TrackBase::i_lambda);
0937 const auto diffCovLambdaDsz = fillCov1(h_diffCovLambdaDsz, reco::TrackBase::i_lambda, reco::TrackBase::i_dsz);
0938 const auto diffCovPhiPhi = fillCov3(
0939 h_diffCovPhiPhi,
0940 reco::TrackBase::i_phi,
0941 reco::TrackBase::i_phi,
0942 [=](double val) { return val * pcPt * pcPt; },
0943 [=](double val) { return val / pcPt / pcPt; });
0944 const auto diffCovPhiDxy = fillCov1(h_diffCovPhiDxy, reco::TrackBase::i_phi, reco::TrackBase::i_dxy);
0945 const auto diffCovDxyDxy = fillCov2(
0946 h_diffCovDxyDxy, reco::TrackBase::i_dxy, reco::TrackBase::i_dxy, [](double value) { return value * 10000.; });
0947 const auto diffCovDxyDsz = fillCov2(
0948 h_diffCovDxyDsz, reco::TrackBase::i_dxy, reco::TrackBase::i_dsz, [](double value) { return value * 10000.; });
0949 const auto diffCovDszDsz = fillCov2(
0950 h_diffCovDszDsz, reco::TrackBase::i_dsz, reco::TrackBase::i_dsz, [](double value) { return value * 10000.; });
0951
0952 if (isInRange(diffCovDszDsz.status())) {
0953 fillNoFlow(h_diffDszError, diffRelative(pcRef->dzError(), track.dszError()));
0954 fillNoFlow(h_diffDzError, diffRelative(pcRef->dzError(), track.dzError()));
0955 fillNoFlow(h_diffTrackDzError, diffRelative(trackPc.dzError(), track.dzError()));
0956 }
0957 if (isInRange(diffCovDxyDxy.status())) {
0958 fillNoFlow(h_diffDxyError, diffRelative(pcRef->dxyError(), track.dxyError()));
0959 fillNoFlow(h_diffTrackDxyError, diffRelative(trackPc.dxyError(), track.dxyError()));
0960 }
0961 fillNoFlow(h_diffPtError, diffRelative(trackPc.ptError(), track.ptError()));
0962 fillNoFlow(h_diffEtaError, diffRelative(trackPc.etaError(), track.etaError()));
0963
0964
0965 const auto trackNumberOfHits = track.hitPattern().numberOfValidHits();
0966 const auto trackNumberOfPixelHits = track.hitPattern().numberOfValidPixelHits();
0967 const auto trackNumberOfStripHits = track.hitPattern().numberOfValidStripHits();
0968 const auto pcNumberOfHits = pcRef->numberOfHits();
0969 const auto pcNumberOfPixelHits = pcRef->numberOfPixelHits();
0970 const auto pcNumberOfStripHits = pcNumberOfHits - pcNumberOfPixelHits;
0971 const auto trackNumberOfLayers = track.hitPattern().trackerLayersWithMeasurement();
0972 const auto trackNumberOfPixelLayers = track.hitPattern().pixelLayersWithMeasurement();
0973 const auto trackNumberOfStripLayers = track.hitPattern().stripLayersWithMeasurement();
0974 const auto pcNumberOfLayers = pcRef->trackerLayersWithMeasurement();
0975 const auto pcNumberOfPixelLayers = pcRef->pixelLayersWithMeasurement();
0976 const auto pcNumberOfStripLayers = pcRef->stripLayersWithMeasurement();
0977
0978
0979 const int pixelLayerOverflow = trackNumberOfPixelLayers > pat::PackedCandidate::trackPixelHitsMask
0980 ? trackNumberOfPixelLayers - pat::PackedCandidate::trackPixelHitsMask
0981 : 0;
0982 const int stripLayerOverflow = trackNumberOfStripLayers > pat::PackedCandidate::trackStripHitsMask
0983 ? trackNumberOfStripLayers - pat::PackedCandidate::trackStripHitsMask
0984 : 0;
0985 const int layerOverflow =
0986 trackNumberOfLayers > (pat::PackedCandidate::trackPixelHitsMask + pat::PackedCandidate::trackStripHitsMask)
0987 ? trackNumberOfLayers -
0988 (pat::PackedCandidate::trackPixelHitsMask + pat::PackedCandidate::trackStripHitsMask)
0989 : 0;
0990
0991
0992 const int pixelOverflow =
0993 trackNumberOfPixelHits - pcNumberOfPixelLayers > pat::PackedCandidate::trackPixelHitsMask
0994 ? trackNumberOfPixelHits - pcNumberOfPixelLayers - pat::PackedCandidate::trackPixelHitsMask
0995 : 0;
0996 const int stripOverflow =
0997 trackNumberOfStripHits - pcNumberOfStripLayers > pat::PackedCandidate::trackStripHitsMask
0998 ? trackNumberOfStripHits - pcNumberOfStripLayers - pat::PackedCandidate::trackStripHitsMask
0999 : 0;
1000 const int hitsOverflow =
1001 trackNumberOfHits - pcNumberOfLayers >
1002 (pat::PackedCandidate::trackPixelHitsMask + pat::PackedCandidate::trackStripHitsMask)
1003 ? trackNumberOfHits - pcNumberOfLayers -
1004 (pat::PackedCandidate::trackPixelHitsMask + pat::PackedCandidate::trackStripHitsMask)
1005 : 0;
1006
1007 const int pixelInducedStripOverflow =
1008 (trackNumberOfStripHits + pixelOverflow - pcNumberOfStripLayers) > pat::PackedCandidate::trackStripHitsMask
1009 ? (trackNumberOfStripHits + pixelOverflow - stripOverflow - pcNumberOfStripLayers) -
1010 pat::PackedCandidate::trackStripHitsMask
1011 : 0;
1012 h_numberPixelLayersOverMax->Fill(pixelLayerOverflow);
1013 h_numberStripLayersOverMax->Fill(stripLayerOverflow);
1014 h_numberLayersOverMax->Fill(layerOverflow);
1015 h_numberPixelHitsOverMax->Fill(pixelOverflow);
1016 h_numberStripHitsOverMax->Fill(stripOverflow);
1017 h_numberHitsOverMax->Fill(hitsOverflow);
1018
1019 int diffNumberOfPixelHits = 0;
1020 int diffNumberOfHits = 0;
1021 int diffNumberOfPixelLayers = 0;
1022 int diffNumberOfStripLayers = 0;
1023 if (pixelLayerOverflow) {
1024 diffNumberOfPixelLayers = pcNumberOfPixelLayers - pat::PackedCandidate::trackPixelHitsMask;
1025 } else {
1026 diffNumberOfPixelLayers = pcNumberOfPixelLayers - trackNumberOfPixelLayers;
1027 }
1028 if (pixelOverflow) {
1029 diffNumberOfPixelHits = pcNumberOfPixelHits - pcNumberOfPixelLayers - pat::PackedCandidate::trackPixelHitsMask;
1030 } else {
1031 diffNumberOfPixelHits = pcNumberOfPixelHits - trackNumberOfPixelHits;
1032 }
1033 if (stripLayerOverflow) {
1034 diffNumberOfStripLayers = pcNumberOfStripLayers - pat::PackedCandidate::trackStripHitsMask;
1035 } else {
1036 diffNumberOfStripLayers = pcNumberOfStripLayers - trackNumberOfStripLayers;
1037 }
1038 if (stripOverflow || pixelInducedStripOverflow || pixelOverflow) {
1039 int diffNumberOfStripHits = 0;
1040 if (stripOverflow || pixelInducedStripOverflow) {
1041 diffNumberOfStripHits = pcNumberOfStripHits - pat::PackedCandidate::trackStripHitsMask;
1042 } else if (pixelOverflow) {
1043 diffNumberOfStripHits = (pcNumberOfStripHits - pixelOverflow) - trackNumberOfStripHits;
1044 }
1045
1046 diffNumberOfHits = diffNumberOfPixelHits + diffNumberOfStripHits;
1047 } else {
1048 diffNumberOfHits = pcNumberOfHits - trackNumberOfHits;
1049 }
1050
1051 fillNoFlow(h_diffNumberOfPixelHits, diffNumberOfPixelHits);
1052 fillNoFlow(h_diffNumberOfHits, diffNumberOfHits);
1053 fillNoFlow(h_diffNumberOfPixelLayers, diffNumberOfPixelLayers);
1054 fillNoFlow(h_diffNumberOfStripLayers, diffNumberOfStripLayers);
1055
1056 int diffLostInnerHits = 0;
1057 const auto trackLostInnerHits = track.hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS);
1058 switch (pcRef->lostInnerHits()) {
1059 case pat::PackedCandidate::validHitInFirstPixelBarrelLayer:
1060 case pat::PackedCandidate::noLostInnerHits:
1061 diffLostInnerHits = -trackLostInnerHits;
1062 break;
1063 case pat::PackedCandidate::oneLostInnerHit:
1064 diffLostInnerHits = 1 - trackLostInnerHits;
1065 break;
1066 case pat::PackedCandidate::moreLostInnerHits:
1067 diffLostInnerHits = trackLostInnerHits >= 2 ? 0 : 2 - trackLostInnerHits;
1068 break;
1069 }
1070 fillNoFlow(h_diffLostInnerHits, diffLostInnerHits);
1071
1072
1073 auto diffHitPatternPixelLayersWithMeasurement =
1074 trackPc.hitPattern().pixelLayersWithMeasurement() - trackNumberOfPixelLayers;
1075 fillNoFlow(h_diffHitPatternPixelLayersWithMeasurement, diffHitPatternPixelLayersWithMeasurement);
1076 auto diffHitPatternStripLayersWithMeasurement =
1077 trackPc.hitPattern().stripLayersWithMeasurement() - trackNumberOfStripLayers;
1078 fillNoFlow(h_diffHitPatternStripLayersWithMeasurement, diffHitPatternStripLayersWithMeasurement);
1079 auto diffHitPatternTrackerLayersWithMeasurement =
1080 trackPc.hitPattern().trackerLayersWithMeasurement() - trackNumberOfLayers;
1081 fillNoFlow(h_diffHitPatternTrackerLayersWithMeasurement, diffHitPatternTrackerLayersWithMeasurement);
1082 auto diffHitPatternNumberOfValidPixelHits = trackPc.hitPattern().numberOfValidPixelHits() - trackNumberOfPixelHits;
1083 fillNoFlow(h_diffHitPatternNumberOfValidPixelHits, diffHitPatternNumberOfValidPixelHits);
1084 auto diffHitPatternNumberOfValidHits = trackPc.hitPattern().numberOfValidHits() - trackNumberOfHits;
1085 fillNoFlow(h_diffHitPatternNumberOfValidHits, diffHitPatternNumberOfValidHits);
1086 fillNoFlow(h_diffHitPatternNumberOfLostInnerHits,
1087 trackPc.hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) -
1088 track.hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS));
1089
1090
1091 int diffHitPatternHasValidHitInFirstPixelBarrel = 0;
1092 if (track.hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) == 0) {
1093 h_selectionFlow->Fill(sf_NoMissingInnerHits);
1094 diffHitPatternHasValidHitInFirstPixelBarrel =
1095 static_cast<int>(
1096 trackPc.hitPattern().hasValidHitInPixelLayer(PixelSubdetector::SubDetector::PixelBarrel, 1)) -
1097 static_cast<int>(track.hitPattern().hasValidHitInPixelLayer(PixelSubdetector::SubDetector::PixelBarrel, 1));
1098 fillNoFlow(h_diffHitPatternHasValidHitInFirstPixelBarrel, diffHitPatternHasValidHitInFirstPixelBarrel);
1099 }
1100
1101
1102 if (debug_ &&
1103 (diffNormalizedChi2 < -1 || diffNormalizedChi2 > 0 || diffCharge != 0 || diffHP != 0 ||
1104 std::abs(diffPhi) > 5e-4 || diffDxyAssocPV.outsideExpectedRange() || diffDzAssocPV.outsideExpectedRange() ||
1105 std::abs(diffDxyPV) > 0.05 || std::abs(diffDzPV) > 0.05 || diffCovQoverpQoverp.outsideExpectedRange() ||
1106 diffCovLambdaLambda.outsideExpectedRange() || diffCovLambdaDsz.outsideExpectedRange() ||
1107 diffCovPhiPhi.outsideExpectedRange() || diffCovPhiDxy.outsideExpectedRange() ||
1108 diffCovDxyDxy.outsideExpectedRange() || diffCovDxyDsz.outsideExpectedRange() ||
1109 diffCovDszDsz.outsideExpectedRange() || diffNumberOfPixelHits != 0 || diffNumberOfHits != 0 ||
1110 diffLostInnerHits != 0 || diffHitPatternHasValidHitInFirstPixelBarrel != 0)) {
1111 edm::LogInfo("PackedCandidateTrackValidator")
1112 << "Track " << i << " pt " << track.pt() << " eta " << track.eta() << " phi " << track.phi() << " chi2 "
1113 << track.chi2() << " ndof " << track.ndof() << "\n"
1114 << " ptError " << track.ptError() << " etaError " << track.etaError() << " phiError " << track.phiError()
1115 << " dxyError " << track.dxyError() << " dzError " << track.dzError() << "\n"
1116 << " refpoint " << track.referencePoint() << " momentum " << track.momentum() << "\n"
1117 << " dxy " << track.dxy() << " dz " << track.dz() << "\n"
1118 << " " << TrackAlgoPrinter(track) << " lost inner hits " << trackLostInnerHits << " lost outer hits "
1119 << track.hitPattern().numberOfLostHits(reco::HitPattern::MISSING_OUTER_HITS) << " hitpattern "
1120 << HitPatternPrinter(track) << " \n"
1121 << " PC " << pcRef.id() << ":" << pcRef.key() << " track pt " << trackPc.pt() << " eta " << trackPc.eta()
1122 << " phi " << trackPc.phi() << " (PC " << pcRef->phi() << ") chi2 " << trackPc.chi2() << " ndof "
1123 << trackPc.ndof() << " pdgId " << pcRef->pdgId() << " mass " << pcRef->mass() << "\n"
1124 << " ptError " << trackPc.ptError() << " etaError " << trackPc.etaError() << " phiError "
1125 << trackPc.phiError() << "\n"
1126 << " pc.vertex " << pcRef->vertex() << " momentum " << pcRef->momentum() << " track " << trackPc.momentum()
1127 << "\n"
1128 << " dxy " << trackPc.dxy() << " dz " << trackPc.dz() << " pc.dz " << pcRef->dz() << " dxyError "
1129 << trackPc.dxyError() << " dzError " << trackPc.dzError() << "\n"
1130 << " dxy(PV) " << trackPc.dxy(pv.position()) << " dz(PV) " << trackPc.dz(pv.position()) << " dxy(assocPV) "
1131 << trackPc.dxy(pcVertex.position()) << " dz(assocPV) " << trackPc.dz(pcVertex.position()) << "\n"
1132 << " (diff PackedCandidate track)"
1133 << " highPurity " << diffHP << " " << trackPc.quality(reco::TrackBase::highPurity) << " "
1134 << track.quality(reco::TrackBase::highPurity) << " charge " << diffCharge << " " << trackPc.charge() << " "
1135 << track.charge() << " normalizedChi2 " << diffNormalizedChi2 << " " << trackPc.normalizedChi2() << " "
1136 << track.normalizedChi2() << "\n "
1137 << " numberOfAllHits " << diffNumberOfHits << " " << pcNumberOfHits << " " << trackNumberOfHits
1138 << " numberOfPixelHits " << diffNumberOfPixelHits << " " << pcNumberOfPixelHits << " "
1139 << trackNumberOfPixelHits << " numberOfStripHits # " << pcNumberOfStripHits << " " << trackNumberOfStripHits
1140 << "\n "
1141 << " hitPattern.numberOfValidPixelHits " << diffHitPatternNumberOfValidPixelHits << " "
1142 << trackPc.hitPattern().numberOfValidPixelHits() << " " << track.hitPattern().numberOfValidPixelHits()
1143 << " hitPattern.numberOfValidHits " << diffHitPatternNumberOfValidHits << " "
1144 << trackPc.hitPattern().numberOfValidHits() << " " << track.hitPattern().numberOfValidHits()
1145 << " hitPattern.hasValidHitInFirstPixelBarrel " << diffHitPatternHasValidHitInFirstPixelBarrel << " "
1146 << trackPc.hitPattern().hasValidHitInPixelLayer(PixelSubdetector::SubDetector::PixelBarrel, 1) << " "
1147 << track.hitPattern().hasValidHitInPixelLayer(PixelSubdetector::SubDetector::PixelBarrel, 1) << "\n "
1148 << " lostInnerHits " << diffLostInnerHits << " " << pcRef->lostInnerHits() << " #"
1149 << " phi (5e-4) " << diffPhi << " " << trackPc.phi() << " " << track.phi() << "\n "
1150 << " dxy(assocPV) " << diffDxyAssocPV << "\n "
1151 << " dz(assocPV) " << diffDzAssocPV << "\n "
1152 << " dxy(PV) (0.05) " << diffDxyPV << " " << pcRef->dxy(pv.position()) << " " << track.dxy(pv.position())
1153 << "\n "
1154 << " dz(PV) (0.05) " << diffDzPV << " " << pcRef->dz(pv.position()) << " " << track.dz(pv.position()) << "\n "
1155 << " cov(qoverp, qoverp) " << diffCovQoverpQoverp << "\n "
1156 << " cov(lambda, lambda) " << diffCovLambdaLambda << "\n "
1157 << " cov(lambda, dsz) " << diffCovLambdaDsz << "\n "
1158 << " cov(phi, phi) " << diffCovPhiPhi << "\n "
1159 << " cov(phi, dxy) " << diffCovPhiDxy << "\n "
1160 << " cov(dxy, dxy) " << diffCovDxyDxy << "\n "
1161 << " cov(dxy, dsz) " << diffCovDxyDsz << "\n "
1162 << " cov(dsz, dsz) " << diffCovDszDsz;
1163 }
1164 }
1165 }
1166
1167 #include "FWCore/Framework/interface/MakerMacros.h"
1168 DEFINE_FWK_MODULE(PackedCandidateTrackValidator);