File indexing completed on 2024-04-06 12:28:11
0001 #include "TkGluedMeasurementDet.h"
0002 #include "TrackingTools/MeasurementDet/interface/MeasurementDetException.h"
0003 #include "RecoTracker/TransientTrackingRecHit/interface/TSiStripMatchedRecHit.h"
0004 #include "Geometry/CommonDetUnit/interface/GluedGeomDet.h"
0005 #include "RecoLocalTracker/SiStripRecHitConverter/interface/SiStripRecHitMatcher.h"
0006 #include "NonPropagatingDetMeasurements.h"
0007 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
0008 #include "TrackingTools/TransientTrackingRecHit/interface/TrackingRecHitProjector.h"
0009 #include "RecoTracker/TransientTrackingRecHit/interface/ProjectedRecHit2D.h"
0010 #include "RecHitPropagator.h"
0011 #include "TrackingTools/TransientTrackingRecHit/interface/InvalidTransientRecHit.h"
0012 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0013
0014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0015
0016 #include <functional>
0017 #include <iostream>
0018 #include <memory>
0019 #include <typeinfo>
0020
0021 namespace {
0022 inline std::pair<LocalPoint, LocalError> projectedPos(const TrackingRecHit& hit,
0023 const GeomDet& det,
0024 const GlobalVector& gdir,
0025 const StripClusterParameterEstimator* cpe) {
0026 const BoundPlane& gluedPlane = det.surface();
0027 const BoundPlane& hitPlane = hit.det()->surface();
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 double delta = gluedPlane.localZ(hitPlane.position());
0041 LocalVector ldir = gluedPlane.toLocal(gdir);
0042 LocalPoint lhitPos = gluedPlane.toLocal(hit.globalPosition());
0043 LocalPoint projectedHitPos = lhitPos - ldir * delta / ldir.z();
0044
0045 LocalVector hitXAxis = gluedPlane.toLocal(hitPlane.toGlobal(LocalVector(1, 0, 0)));
0046 LocalError hitErr = hit.localPositionError();
0047 if (gluedPlane.normalVector().dot(hitPlane.normalVector()) < 0) {
0048
0049 hitErr = LocalError(hitErr.xx(), -hitErr.xy(), hitErr.yy());
0050 }
0051 LocalError rotatedError = hitErr.rotate(hitXAxis.x(), hitXAxis.y());
0052
0053 return std::make_pair(projectedHitPos, rotatedError);
0054 }
0055 }
0056
0057
0058 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
0059
0060 using namespace std;
0061
0062 TkGluedMeasurementDet::TkGluedMeasurementDet(const GluedGeomDet* gdet,
0063 const SiStripRecHitMatcher* matcher,
0064 const StripClusterParameterEstimator* cpe)
0065 : MeasurementDet(gdet),
0066 theMatcher(matcher),
0067 theCPE(cpe),
0068 theMonoDet(nullptr),
0069 theStereoDet(nullptr),
0070 theTopology(nullptr) {}
0071
0072 void TkGluedMeasurementDet::init(const MeasurementDet* monoDet,
0073 const MeasurementDet* stereoDet,
0074 const TrackerTopology* tTopo) {
0075 theMonoDet = dynamic_cast<const TkStripMeasurementDet*>(monoDet);
0076 theStereoDet = dynamic_cast<const TkStripMeasurementDet*>(stereoDet);
0077 theTopology = tTopo;
0078
0079 if ((theMonoDet == nullptr) || (theStereoDet == nullptr)) {
0080 throw MeasurementDetException(
0081 "TkGluedMeasurementDet ERROR: Trying to glue a det which is not a TkStripMeasurementDet");
0082 }
0083 }
0084
0085 TkGluedMeasurementDet::RecHitContainer TkGluedMeasurementDet::recHits(const TrajectoryStateOnSurface& ts,
0086 const MeasurementTrackerEvent& data) const {
0087 RecHitContainer result;
0088 HitCollectorForRecHits collector(&fastGeomDet(), theMatcher, theCPE, result);
0089 collectRecHits(ts, data, collector);
0090 return result;
0091 }
0092
0093
0094 bool TkGluedMeasurementDet::recHits(SimpleHitContainer& result,
0095 const TrajectoryStateOnSurface& stateOnThisDet,
0096 const MeasurementEstimator& est,
0097 const MeasurementTrackerEvent& data) const {
0098 if UNLIKELY ((!theMonoDet->isActive(data)) && (!theStereoDet->isActive(data)))
0099 return false;
0100 auto oldSize = result.size();
0101 HitCollectorForSimpleHits collector(&fastGeomDet(), theMatcher, theCPE, stateOnThisDet, est, result);
0102 collectRecHits(stateOnThisDet, data, collector);
0103
0104 return result.size() > oldSize;
0105 }
0106
0107 bool TkGluedMeasurementDet::measurements(const TrajectoryStateOnSurface& stateOnThisDet,
0108 const MeasurementEstimator& est,
0109 const MeasurementTrackerEvent& data,
0110 TempMeasurements& result) const {
0111 if UNLIKELY ((!theMonoDet->isActive(data)) && (!theStereoDet->isActive(data))) {
0112
0113 result.add(theInactiveHit, 0.F);
0114 return true;
0115 }
0116
0117 auto oldSize = result.size();
0118
0119 HitCollectorForFastMeasurements collector(&fastGeomDet(), theMatcher, theCPE, stateOnThisDet, est, result);
0120 collectRecHits(stateOnThisDet, data, collector);
0121
0122 if (result.size() > oldSize)
0123 return true;
0124
0125 auto id = geomDet().geographicalId().subdetId() - 3;
0126 auto l = theTopology->tobLayer(geomDet().geographicalId());
0127 bool killHIP = (1 == l) && (2 == id);
0128 killHIP &= stateOnThisDet.globalMomentum().perp2() > est.minPt2ForHitRecoveryInGluedDet();
0129 if (killHIP) {
0130 result.add(theInactiveHit, 0.F);
0131 return true;
0132 }
0133
0134
0135 const BoundPlane& gluedPlane = geomDet().surface();
0136 if (
0137 stateOnThisDet.hasError() &&
0138 (
0139
0140 (theMonoDet->isActive(data) &&
0141 (theMonoDet->hasAllGoodChannels() || testStrips(stateOnThisDet, gluedPlane, *theMonoDet)))
0142 &&
0143 (theStereoDet->isActive(data) &&
0144 (theStereoDet->hasAllGoodChannels() || testStrips(stateOnThisDet, gluedPlane, *theStereoDet)))
0145 )
0146 ) {
0147 result.add(theMissingHit, 0.F);
0148 return false;
0149 }
0150 result.add(theInactiveHit, 0.F);
0151 return true;
0152 }
0153
0154 struct take_address {
0155 template <typename T>
0156 const T* operator()(const T& val) const {
0157 return &val;
0158 }
0159 };
0160
0161 #ifdef DOUBLE_MATCH
0162 template <typename Collector>
0163 void TkGluedMeasurementDet::collectRecHits(const TrajectoryStateOnSurface& ts,
0164 const MeasurementTrackerEvent& data,
0165 Collector& collector) const {
0166 doubleMatch(ts, data, collector);
0167 }
0168 #else
0169 template <typename Collector>
0170 void TkGluedMeasurementDet::collectRecHits(const TrajectoryStateOnSurface& ts,
0171 const MeasurementTrackerEvent& data,
0172 Collector& collector) const {
0173
0174
0175
0176 RecHitContainer monoHits = theMonoDet->recHits(ts, data);
0177 GlobalVector glbDir = (ts.isValid() ? ts.globalParameters().momentum() : position() - GlobalPoint(0, 0, 0));
0178
0179
0180
0181
0182
0183 if (monoHits.empty()) {
0184
0185 projectOnGluedDet(collector, theStereoDet->recHits(ts, data), glbDir);
0186 } else {
0187
0188 std::vector<SiStripRecHit2D> simpleSteroHitsByValue;
0189 theStereoDet->simpleRecHits(ts, data, simpleSteroHitsByValue);
0190
0191 if (simpleSteroHitsByValue.empty()) {
0192 projectOnGluedDet(collector, monoHits, glbDir);
0193 } else {
0194 LocalVector tkDir = (ts.isValid() ? ts.localDirection() : surface().toLocal(position() - GlobalPoint(0, 0, 0)));
0195 SiStripRecHitMatcher::SimpleHitCollection vsStereoHits;
0196 vsStereoHits.resize(simpleSteroHitsByValue.size());
0197 std::transform(
0198 simpleSteroHitsByValue.begin(), simpleSteroHitsByValue.end(), vsStereoHits.begin(), take_address());
0199
0200
0201 for (RecHitContainer::const_iterator monoHit = monoHits.begin(); monoHit != monoHits.end(); ++monoHit) {
0202 const TrackingRecHit* tkhit = (**monoHit).hit();
0203 const SiStripRecHit2D* verySpecificMonoHit = reinterpret_cast<const SiStripRecHit2D*>(tkhit);
0204 theMatcher->match(verySpecificMonoHit,
0205 vsStereoHits.begin(),
0206 vsStereoHits.end(),
0207 collector.collector(),
0208 &specificGeomDet(),
0209 tkDir);
0210
0211 if (collector.hasNewMatchedHits()) {
0212 collector.clearNewMatchedHitsFlag();
0213 } else {
0214 collector.addProjected(**monoHit, glbDir);
0215 }
0216 }
0217 }
0218
0219 }
0220 }
0221 #endif
0222
0223 #include <cstdint>
0224 #ifdef VI_STAT
0225 #include <cstdio>
0226 #endif
0227 namespace {
0228 struct Stat {
0229 #ifdef VI_STAT
0230 double totCall = 0;
0231 double totMono = 0;
0232 double totStereo = 0;
0233 double totComb = 0;
0234 double totMatched = 0;
0235 double filtMono = 0;
0236 double filtStereo = 0;
0237 double filtComb = 0;
0238 double matchT = 0;
0239 double matchF = 0;
0240 double singleF = 0;
0241 double zeroM = 0;
0242 double zeroS = 0;
0243
0244 void match(uint64_t t) {
0245 if (t != 0)
0246 ++matchT;
0247 totMatched += t;
0248 }
0249 void operator()(uint64_t m, uint64_t s, uint64_t fm, uint64_t fs) {
0250 ++totCall;
0251 totMono += m;
0252 totStereo += s;
0253 totComb += m * s;
0254 filtMono += fm;
0255 filtStereo += fs;
0256 filtComb += fm * fs;
0257 if (fm == 0)
0258 ++zeroM;
0259 if (fs == 0)
0260 ++zeroS;
0261 if (fm != 0 && fs != 0)
0262 ++matchF;
0263 if (fm != 0 || fs != 0)
0264 ++singleF;
0265 }
0266 ~Stat() {
0267 if (totCall > 0)
0268 printf("Matches:%d/%d/%d/%d/%d/%d : %f/%f/%f/%f/%f/%f/%f\n",
0269 int(totCall),
0270 int(matchF),
0271 int(singleF - matchF),
0272 int(matchT),
0273 int(zeroM),
0274 int(zeroS),
0275 totMono / totCall,
0276 totStereo / totCall,
0277 totComb / totCall,
0278 totMatched / matchT,
0279 filtMono / totCall,
0280 filtStereo / totCall,
0281 filtComb / matchF);
0282 }
0283 #else
0284 Stat() {}
0285 void match(uint64_t) const {}
0286 void operator()(uint64_t, uint64_t, uint64_t, uint64_t) const {}
0287 #endif
0288 };
0289 #ifndef VI_STAT
0290 const
0291 #endif
0292 Stat stat;
0293 }
0294
0295 TkGluedMeasurementDet::RecHitContainer TkGluedMeasurementDet::projectOnGluedDet(
0296 const RecHitContainer& hits, const TrajectoryStateOnSurface& ts) const {
0297 RecHitContainer result;
0298 for (auto const& hit : hits) {
0299 auto&& vl = projectedPos(*hit, fastGeomDet(), ts.globalParameters().momentum(), theCPE);
0300 auto&& phit = std::make_shared<ProjectedSiStripRecHit2D>(
0301 vl.first, vl.second, fastGeomDet(), static_cast<SiStripRecHit2D const&>(*hit));
0302 result.push_back(std::move(phit));
0303 }
0304 return result;
0305 }
0306
0307 template <typename Collector>
0308 void TkGluedMeasurementDet::projectOnGluedDet(Collector& collector,
0309 const RecHitContainer& hits,
0310 const GlobalVector& gdir) const {
0311 for (RecHitContainer::const_iterator ihit = hits.begin(); ihit != hits.end(); ihit++) {
0312 collector.addProjected(**ihit, gdir);
0313 }
0314 }
0315
0316 TkGluedMeasurementDet::RecHitContainer TkGluedMeasurementDet::projectOnGluedDet(
0317 std::vector<SiStripRecHit2D> const& hits, const TrajectoryStateOnSurface& ts) const {
0318 RecHitContainer result;
0319 for (auto const& hit : hits) {
0320 auto&& vl = projectedPos(hit, fastGeomDet(), ts.globalParameters().momentum(), theCPE);
0321 auto&& phit = std::make_shared<ProjectedSiStripRecHit2D>(
0322 vl.first, vl.second, fastGeomDet(), static_cast<SiStripRecHit2D const&>(hit));
0323 result.push_back(std::move(phit));
0324 }
0325 return result;
0326 }
0327
0328 template <typename Collector>
0329 void TkGluedMeasurementDet::projectOnGluedDet(Collector& collector,
0330 std::vector<SiStripRecHit2D> const& hits,
0331 const GlobalVector& gdir) const {
0332 for (auto const& hit : hits)
0333 collector.addProjected(hit, gdir);
0334 }
0335
0336 void TkGluedMeasurementDet::checkProjection(const TrajectoryStateOnSurface& ts,
0337 const RecHitContainer& monoHits,
0338 const RecHitContainer& stereoHits) const {
0339 for (RecHitContainer::const_iterator i = monoHits.begin(); i != monoHits.end(); ++i) {
0340 checkHitProjection(**i, ts, fastGeomDet());
0341 }
0342 for (RecHitContainer::const_iterator i = stereoHits.begin(); i != stereoHits.end(); ++i) {
0343 checkHitProjection(**i, ts, fastGeomDet());
0344 }
0345 }
0346
0347 void TkGluedMeasurementDet::checkHitProjection(const TrackingRecHit& hit,
0348 const TrajectoryStateOnSurface& ts,
0349 const GeomDet& det) const {
0350 auto&& vl = projectedPos(hit, det, ts.globalParameters().momentum(), theCPE);
0351 ProjectedSiStripRecHit2D projectedHit(vl.first, vl.second, det, static_cast<SiStripRecHit2D const&>(hit));
0352
0353 RecHitPropagator prop;
0354 TrajectoryStateOnSurface propState = prop.propagate(hit, det.surface(), ts);
0355
0356 if ((projectedHit.localPosition() - propState.localPosition()).mag() > 0.0001f) {
0357 std::cout << "PROBLEM: projected and propagated hit positions differ by "
0358 << (projectedHit.localPosition() - propState.localPosition()).mag() << std::endl;
0359 }
0360
0361 LocalError le1 = projectedHit.localPositionError();
0362 LocalError le2 = propState.localError().positionError();
0363 double eps = 1.e-5;
0364 double cutoff = 1.e-4;
0365 double maxdiff = std::max(
0366 std::max(fabs(le1.xx() - le2.xx()) / (cutoff + le1.xx()), fabs(le1.xy() - le2.xy()) / (cutoff + fabs(le1.xy()))),
0367 fabs(le1.yy() - le2.yy()) / (cutoff + le1.xx()));
0368 if (maxdiff > eps) {
0369 std::cout << "PROBLEM: projected and propagated hit errors differ by " << maxdiff << std::endl;
0370 }
0371 }
0372
0373 bool TkGluedMeasurementDet::testStrips(const TrajectoryStateOnSurface& tsos,
0374 const BoundPlane& gluedPlane,
0375 const TkStripMeasurementDet& mdet) const {
0376
0377 const GeomDet& det = mdet.fastGeomDet();
0378 const BoundPlane& stripPlane = det.surface();
0379
0380
0381 LocalError err = tsos.localError().positionError();
0382
0383
0384
0385
0386
0387
0388 GlobalVector gdir = tsos.globalParameters().momentum();
0389
0390 LocalPoint slp = stripPlane.toLocal(tsos.globalPosition());
0391 LocalVector sld = stripPlane.toLocal(gdir);
0392
0393 double delta = stripPlane.localZ(tsos.globalPosition());
0394 LocalPoint pos = slp - sld * delta / sld.z();
0395
0396
0397 LocalVector hitXAxis = stripPlane.toLocal(gluedPlane.toGlobal(LocalVector(1, 0, 0)));
0398 if (stripPlane.normalVector().dot(gluedPlane.normalVector()) < 0) {
0399
0400 err = LocalError(err.xx(), -err.xy(), err.yy());
0401 }
0402 LocalError rotatedError = err.rotate(hitXAxis.x(), hitXAxis.y());
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416 const StripTopology& topo = mdet.specificGeomDet().specificTopology();
0417 float utraj = topo.measurementPosition(pos).x();
0418 float uerr = std::sqrt(topo.measurementError(pos, rotatedError).uu());
0419 return mdet.testStrips(utraj, uerr);
0420 }
0421
0422 TkGluedMeasurementDet::HitCollectorForRecHits::HitCollectorForRecHits(const GeomDet* geomDet,
0423 const SiStripRecHitMatcher* matcher,
0424 const StripClusterParameterEstimator* cpe,
0425 RecHitContainer& target)
0426 : geomDet_(geomDet),
0427 matcher_(matcher),
0428 cpe_(cpe),
0429 target_(target),
0430 collector_(std::bind(&HitCollectorForRecHits::add, std::ref(*this), std::placeholders::_1)),
0431 hasNewHits_(false) {}
0432
0433 TkGluedMeasurementDet::HitCollectorForSimpleHits::HitCollectorForSimpleHits(
0434 const GeomDet* geomDet,
0435 const SiStripRecHitMatcher* matcher,
0436 const StripClusterParameterEstimator* cpe,
0437 const TrajectoryStateOnSurface& stateOnThisDet,
0438 const MeasurementEstimator& est,
0439 SimpleHitContainer& target)
0440 : geomDet_(geomDet),
0441 matcher_(matcher),
0442 cpe_(cpe),
0443 stateOnThisDet_(stateOnThisDet),
0444 est_(est),
0445 target_(target),
0446 collector_(std::bind(&HitCollectorForSimpleHits::add, std::ref(*this), std::placeholders::_1)),
0447 hasNewHits_(false) {}
0448
0449 void TkGluedMeasurementDet::HitCollectorForRecHits::addProjected(const TrackingRecHit& hit, const GlobalVector& gdir) {
0450 auto&& vl = projectedPos(hit, *geomDet_, gdir, cpe_);
0451 auto&& phit = std::make_shared<ProjectedSiStripRecHit2D>(
0452 vl.first, vl.second, *geomDet_, static_cast<SiStripRecHit2D const&>(hit));
0453 target_.push_back(std::move(phit));
0454 }
0455
0456 void TkGluedMeasurementDet::HitCollectorForSimpleHits::add(SiStripMatchedRecHit2D const& hit2d) {
0457 hasNewHits_ = true;
0458 if (!est_.preFilter(stateOnThisDet_,
0459 ClusterFilterPayload(hit2d.geographicalId(), &hit2d.monoCluster(), &hit2d.stereoCluster())))
0460 return;
0461 hasNewHits_ = true;
0462
0463 std::pair<bool, double> diffEst = est_.estimate(stateOnThisDet_, hit2d);
0464 if (diffEst.first)
0465 target_.emplace_back(new SiStripMatchedRecHit2D(hit2d));
0466 }
0467
0468 void TkGluedMeasurementDet::HitCollectorForSimpleHits::addProjected(const TrackingRecHit& hit,
0469 const GlobalVector& gdir) {
0470 auto const& thit = reinterpret_cast<TrackerSingleRecHit const&>(hit);
0471 if (!est_.preFilter(stateOnThisDet_, ClusterFilterPayload(hit.geographicalId(), &thit.stripCluster())))
0472 return;
0473
0474
0475 auto&& vl = projectedPos(hit, *geomDet_, gdir, cpe_);
0476 std::unique_ptr<ProjectedSiStripRecHit2D> phit(
0477 new ProjectedSiStripRecHit2D(vl.first, vl.second, *geomDet_, static_cast<SiStripRecHit2D const&>(hit)));
0478 std::pair<bool, double> diffEst = est_.estimate(stateOnThisDet_, *phit);
0479 if (diffEst.first) {
0480 target_.emplace_back(phit.release());
0481 }
0482 }
0483
0484 TkGluedMeasurementDet::HitCollectorForFastMeasurements::HitCollectorForFastMeasurements(
0485 const GeomDet* geomDet,
0486 const SiStripRecHitMatcher* matcher,
0487 const StripClusterParameterEstimator* cpe,
0488 const TrajectoryStateOnSurface& stateOnThisDet,
0489 const MeasurementEstimator& est,
0490 TempMeasurements& target)
0491 : geomDet_(geomDet),
0492 matcher_(matcher),
0493 cpe_(cpe),
0494 stateOnThisDet_(stateOnThisDet),
0495 est_(est),
0496 target_(target),
0497 collector_(std::bind(&HitCollectorForFastMeasurements::add, std::ref(*this), std::placeholders::_1)),
0498 hasNewHits_(false) {}
0499
0500 void TkGluedMeasurementDet::HitCollectorForFastMeasurements::add(SiStripMatchedRecHit2D const& hit2d) {
0501
0502 hasNewHits_ = true;
0503 if (!est_.preFilter(stateOnThisDet_,
0504 ClusterFilterPayload(hit2d.geographicalId(), &hit2d.monoCluster(), &hit2d.stereoCluster())))
0505 return;
0506 hasNewHits_ = true;
0507
0508 std::pair<bool, double> diffEst = est_.estimate(stateOnThisDet_, hit2d);
0509 if (diffEst.first)
0510 target_.add(hit2d.cloneSH(), diffEst.second);
0511 }
0512
0513 void TkGluedMeasurementDet::HitCollectorForFastMeasurements::addProjected(const TrackingRecHit& hit,
0514 const GlobalVector& gdir) {
0515 auto const& thit = reinterpret_cast<TrackerSingleRecHit const&>(hit);
0516 if (!est_.preFilter(stateOnThisDet_, ClusterFilterPayload(hit.geographicalId(), &thit.stripCluster())))
0517 return;
0518
0519
0520 auto&& vl = projectedPos(hit, *geomDet_, gdir, cpe_);
0521 auto&& phit = std::make_shared<ProjectedSiStripRecHit2D>(
0522 vl.first, vl.second, *geomDet_, static_cast<SiStripRecHit2D const&>(hit));
0523
0524 std::pair<bool, double> diffEst = est_.estimate(stateOnThisDet_, *phit);
0525 if (diffEst.first) {
0526 target_.add(phit, diffEst.second);
0527 }
0528 }
0529
0530 #ifdef DOUBLE_MATCH
0531 #include "doubleMatch.icc"
0532 #endif