File indexing completed on 2024-05-23 03:13:33
0001 #include <algorithm>
0002 #include <array>
0003
0004 #include "GroupedCkfTrajectoryBuilder.h"
0005 #include "TrajectorySegmentBuilder.h"
0006
0007 #include "TrackingTools/DetLayers/interface/DetLayer.h"
0008 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
0009
0010 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
0011 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
0012 #include "TrackingTools/TrackFitters/interface/KFTrajectoryFitter.h"
0013 #include "GroupedTrajCandLess.h"
0014 #include "TrackingTools/TrajectoryFiltering/interface/RegionalTrajectoryFilter.h"
0015 #include "TrackingTools/TrajectoryFiltering/interface/TrajectoryFilterFactory.h"
0016 #include "TrackingTools/PatternTools/interface/TempTrajectory.h"
0017 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
0018 #include "RecoTracker/MeasurementDet/interface/MeasurementTrackerEvent.h"
0019 #include "TrackingTools/MeasurementDet/interface/LayerMeasurements.h"
0020 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
0021 #include "TrackingTools/DetLayers/interface/DetGroup.h"
0022 #include "RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h"
0023 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
0024 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHitBuilder.h"
0025 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
0026
0027 #include "TrackingTools/PatternTools/interface/TrajectoryStateUpdator.h"
0028 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
0029 #include "TrackingTools/PatternTools/interface/Trajectory.h"
0030 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
0031 #include "TrackingTools/TrajectoryState/interface/BasicSingleTrajectoryState.h"
0032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0033 #include "FWCore/ParameterSet/interface/PluginDescription.h"
0034 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0035 #include "TrackingTools/PatternTools/interface/TransverseImpactPointExtrapolator.h"
0036
0037 #include "RecoTracker/TransientTrackingRecHit/interface/TkTransientTrackingRecHitBuilder.h"
0038
0039
0040 #include "TrackingTools/TrajectoryCleaning/interface/TrajectoryCleanerBySharedHits.h"
0041
0042 #include "TrackingTools/TrajectoryCleaning/interface/FastTrajectoryCleaner.h"
0043
0044
0045 #include "TrackingTools/GeomPropagators/interface/HelixBarrelCylinderCrossing.h"
0046 #include "TrackingTools/GeomPropagators/interface/HelixBarrelPlaneCrossingByCircle.h"
0047 #include "TrackingTools/GeomPropagators/interface/HelixArbitraryPlaneCrossing.h"
0048
0049 #include "DataFormats/TrackerRecHit2D/interface/OmniClusterRef.h"
0050
0051
0052
0053 namespace {
0054 #ifdef STAT_TSB
0055 struct StatCount {
0056 long long totSeed;
0057 long long totTraj;
0058 long long totRebuilt;
0059 long long totInvCand;
0060 void zero() { totSeed = totTraj = totRebuilt = totInvCand = 0; }
0061 void traj(long long t) { totTraj += t; }
0062 void seed() { ++totSeed; }
0063 void rebuilt(long long t) { totRebuilt += t; }
0064 void invalid() { ++totInvCand; }
0065 void print() const {
0066 std::cout << "GroupedCkfTrajectoryBuilder stat\nSeed/Traj/Rebuilt " << totSeed << '/' << totTraj << '/'
0067 << totRebuilt << std::endl;
0068 }
0069 StatCount() { zero(); }
0070 ~StatCount() { print(); }
0071 };
0072 StatCount statCount;
0073
0074 #else
0075 struct StatCount {
0076 void traj(long long) {}
0077 void seed() {}
0078 void rebuilt(long long) {}
0079 void invalid() {}
0080 };
0081 CMS_THREAD_SAFE StatCount statCount;
0082 #endif
0083
0084 }
0085
0086 using namespace std;
0087
0088
0089
0090
0091
0092 #ifdef STANDARD_INTERMEDIARYCLEAN
0093 #include "RecoTracker/CkfPattern/interface/IntermediateTrajectoryCleaner.h"
0094 #endif
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 namespace {
0109
0110 thread_local GroupedCkfTrajectoryBuilder::TempTrajectoryContainer work_;
0111
0112 }
0113
0114 GroupedCkfTrajectoryBuilder::GroupedCkfTrajectoryBuilder(const edm::ParameterSet& conf, edm::ConsumesCollector& iC)
0115 : BaseCkfTrajectoryBuilder(conf,
0116 iC,
0117 BaseCkfTrajectoryBuilder::createTrajectoryFilter(
0118 conf.getParameter<edm::ParameterSet>("trajectoryFilter"), iC),
0119 conf.getParameter<bool>("useSameTrajFilter")
0120 ? BaseCkfTrajectoryBuilder::createTrajectoryFilter(
0121 conf.getParameter<edm::ParameterSet>("trajectoryFilter"), iC)
0122 : BaseCkfTrajectoryBuilder::createTrajectoryFilter(
0123 conf.getParameter<edm::ParameterSet>("inOutTrajectoryFilter"), iC)) {
0124
0125
0126 theMaxCand = conf.getParameter<int>("maxCand");
0127 theLostHitPenalty = conf.getParameter<double>("lostHitPenalty");
0128 theFoundHitBonus = conf.getParameter<double>("foundHitBonus");
0129 theIntermediateCleaning = conf.getParameter<bool>("intermediateCleaning");
0130 theAlwaysUseInvalid = conf.getParameter<bool>("alwaysUseInvalidHits");
0131 theLockHits = conf.getParameter<bool>("lockHits");
0132 theBestHitOnly = conf.getParameter<bool>("bestHitOnly");
0133 theMinNrOf2dHitsForRebuild = 2;
0134 theRequireSeedHitsInRebuild = conf.getParameter<bool>("requireSeedHitsInRebuild");
0135 theKeepOriginalIfRebuildFails = conf.getParameter<bool>("keepOriginalIfRebuildFails");
0136 theMinNrOfHitsForRebuild = max(0, conf.getParameter<int>("minNrOfHitsForRebuild"));
0137 maxPt2ForLooperReconstruction = conf.getParameter<double>("maxPtForLooperReconstruction");
0138 maxPt2ForLooperReconstruction *= maxPt2ForLooperReconstruction;
0139 maxDPhiForLooperReconstruction = conf.getParameter<double>("maxDPhiForLooperReconstruction");
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 }
0152
0153 void GroupedCkfTrajectoryBuilder::fillPSetDescription(edm::ParameterSetDescription& iDesc) {
0154 BaseCkfTrajectoryBuilder::fillPSetDescription(iDesc);
0155
0156 iDesc.add<bool>("useSameTrajFilter", true);
0157 iDesc.add<int>("maxCand", 5);
0158 iDesc.add<double>("lostHitPenalty", 30.);
0159 iDesc.add<double>("foundHitBonus", 10.);
0160 iDesc.add<bool>("intermediateCleaning", true);
0161 iDesc.add<bool>("alwaysUseInvalidHits", true);
0162 iDesc.add<bool>("lockHits", true);
0163 iDesc.add<bool>("bestHitOnly", true);
0164 iDesc.add<bool>("requireSeedHitsInRebuild", true);
0165 iDesc.add<bool>("keepOriginalIfRebuildFails", false);
0166 iDesc.add<int>("minNrOfHitsForRebuild", 5);
0167 iDesc.add<double>("maxPtForLooperReconstruction", 0.);
0168 iDesc.add<double>("maxDPhiForLooperReconstruction", 2.0);
0169
0170 edm::ParameterSetDescription psdTJ1;
0171 psdTJ1.addNode(edm::PluginDescription<TrajectoryFilterFactory>("ComponentType", true));
0172 iDesc.add<edm::ParameterSetDescription>("trajectoryFilter", psdTJ1);
0173
0174 edm::ParameterSetDescription psdTJ2;
0175 psdTJ2.addNode(edm::PluginDescription<TrajectoryFilterFactory>("ComponentType", true));
0176 iDesc.add<edm::ParameterSetDescription>("inOutTrajectoryFilter", psdTJ2);
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186 void GroupedCkfTrajectoryBuilder::setEvent_(const edm::Event& event, const edm::EventSetup& iSetup) {}
0187
0188 GroupedCkfTrajectoryBuilder::TrajectoryContainer GroupedCkfTrajectoryBuilder::trajectories(
0189 const TrajectorySeed& seed) const {
0190 TrajectoryContainer ret;
0191 ret.reserve(10);
0192 unsigned int tmp;
0193 buildTrajectories(seed, ret, tmp, nullptr);
0194 return ret;
0195 }
0196
0197 GroupedCkfTrajectoryBuilder::TrajectoryContainer GroupedCkfTrajectoryBuilder::trajectories(
0198 const TrajectorySeed& seed, const TrackingRegion& region) const {
0199 TrajectoryContainer ret;
0200 ret.reserve(10);
0201 unsigned int tmp;
0202 RegionalTrajectoryFilter regionalCondition(region);
0203 buildTrajectories(seed, ret, tmp, ®ionalCondition);
0204 return ret;
0205 }
0206
0207 void GroupedCkfTrajectoryBuilder::trajectories(const TrajectorySeed& seed,
0208 GroupedCkfTrajectoryBuilder::TrajectoryContainer& ret) const {
0209 unsigned int tmp;
0210 buildTrajectories(seed, ret, tmp, nullptr);
0211 }
0212
0213 void GroupedCkfTrajectoryBuilder::trajectories(const TrajectorySeed& seed,
0214 GroupedCkfTrajectoryBuilder::TrajectoryContainer& ret,
0215 const TrackingRegion& region) const {
0216 RegionalTrajectoryFilter regionalCondition(region);
0217 unsigned int tmp;
0218 buildTrajectories(seed, ret, tmp, ®ionalCondition);
0219 }
0220
0221 void GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(const TrajectorySeed& seed, TrajectoryContainer& result) const {
0222 rebuildTrajectories(seed, result);
0223 }
0224
0225 void GroupedCkfTrajectoryBuilder::rebuildTrajectories(const TrajectorySeed& seed, TrajectoryContainer& result) const {
0226 TempTrajectoryContainer work;
0227
0228 TrajectoryContainer final;
0229
0230
0231 std::shared_ptr<const TrajectorySeed> sharedSeed;
0232 if (result.empty())
0233 sharedSeed.reset(new TrajectorySeed(seed));
0234 else
0235 sharedSeed = result.front().sharedSeed();
0236
0237 work.reserve(result.size());
0238 for (auto&& traj : result)
0239 if (traj.isValid())
0240 work.emplace_back(std::move(traj));
0241
0242 rebuildSeedingRegion(seed, work);
0243
0244
0245 FastTrajectoryCleaner cleaner(theFoundHitBonus, theLostHitPenalty, false);
0246 cleaner.clean(work);
0247
0248 for (auto const& it : work)
0249 if (it.isValid()) {
0250 final.push_back(it.toTrajectory());
0251 final.back().setSharedSeed(sharedSeed);
0252 }
0253
0254 result.swap(final);
0255
0256 statCount.rebuilt(result.size());
0257 }
0258
0259 void GroupedCkfTrajectoryBuilder::buildTrajectories(const TrajectorySeed& seed,
0260 GroupedCkfTrajectoryBuilder::TrajectoryContainer& result,
0261 unsigned int& nCandPerSeed,
0262 const TrajectoryFilter* regionalCondition) const {
0263 if (theMeasurementTracker == nullptr) {
0264 throw cms::Exception("LogicError")
0265 << "Asking to create trajectories to an un-initialized GroupedCkfTrajectoryBuilder.\nYou have to call "
0266 "clone(const MeasurementTrackerEvent *data) and then call trajectories on it instead.\n";
0267 }
0268
0269 statCount.seed();
0270
0271
0272
0273
0274 analyseSeed(seed);
0275
0276 TempTrajectory const& startingTraj = createStartingTrajectory(seed);
0277
0278 work_.clear();
0279 const bool inOut = true;
0280 nCandPerSeed = groupedLimitedCandidates(seed, startingTraj, regionalCondition, forwardPropagator(seed), inOut, work_);
0281 if (work_.empty())
0282 return;
0283
0284
0285 FastTrajectoryCleaner cleaner(theFoundHitBonus, theLostHitPenalty);
0286 cleaner.clean(work_);
0287
0288 std::shared_ptr<const TrajectorySeed> pseed(new TrajectorySeed(seed));
0289 for (auto const& it : work_)
0290 if (it.isValid()) {
0291 result.push_back(it.toTrajectory());
0292 result.back().setSharedSeed(pseed);
0293 }
0294 work_.clear();
0295 if (work_.capacity() > work_MaxSize_) {
0296 TempTrajectoryContainer().swap(work_);
0297 work_.reserve(work_MaxSize_ / 2);
0298 }
0299
0300 analyseResult(result);
0301
0302 LogDebug("CkfPattern") << "GroupedCkfTrajectoryBuilder: returning result of size " << result.size();
0303 statCount.traj(result.size());
0304
0305 #ifdef VI_DEBUG
0306 int kt = 0;
0307 for (auto const& traj : result) {
0308 int chit[7] = {};
0309 for (auto const& tm : traj.measurements()) {
0310 auto const& hit = tm.recHitR();
0311 if (!hit.isValid())
0312 ++chit[0];
0313 if (hit.det() == nullptr)
0314 ++chit[1];
0315 if (trackerHitRTTI::isUndef(hit))
0316 continue;
0317 if (hit.dimension() != 2) {
0318 ++chit[2];
0319 } else if (trackerHitRTTI::isFromDet(hit)) {
0320 auto const& thit = static_cast<BaseTrackerRecHit const&>(hit);
0321 auto const& clus = thit.firstClusterRef();
0322 if (clus.isPixel())
0323 ++chit[3];
0324 else if (thit.isMatched()) {
0325 ++chit[4];
0326 } else if (thit.isProjected()) {
0327 ++chit[5];
0328 } else {
0329 ++chit[6];
0330 }
0331 }
0332 }
0333
0334 std::cout << "ckf " << kt++ << ": ";
0335 for (auto c : chit)
0336 std::cout << c << '/';
0337 std::cout << std::endl;
0338 }
0339 #endif
0340 }
0341
0342 unsigned int GroupedCkfTrajectoryBuilder::groupedLimitedCandidates(const TrajectorySeed& seed,
0343 TempTrajectory const& startingTraj,
0344 const TrajectoryFilter* regionalCondition,
0345 const Propagator* propagator,
0346 bool inOut,
0347 TempTrajectoryContainer& result) const {
0348 unsigned int nIter = 1;
0349 unsigned int nCands = 0;
0350 unsigned int prevNewCandSize = 0;
0351 TempTrajectoryContainer candidates;
0352 TempTrajectoryContainer newCand;
0353 newCand.reserve(theMaxCand);
0354 candidates.push_back(startingTraj);
0355
0356 while (!candidates.empty()) {
0357 newCand.clear();
0358 for (TempTrajectoryContainer::iterator traj = candidates.begin(); traj != candidates.end(); traj++) {
0359 if (!advanceOneLayer(seed, *traj, regionalCondition, propagator, inOut, newCand, result)) {
0360 LogDebug("CkfPattern") << "GCTB: terminating after advanceOneLayer==false";
0361 continue;
0362 }
0363
0364 LogDebug("CkfPattern") << "newCand(1): after advanced one layer:\n" << PrintoutHelper::dumpCandidates(newCand);
0365
0366
0367
0368 nCands += newCand.size() - prevNewCandSize;
0369 prevNewCandSize = newCand.size();
0370
0371 assert((int)newCand.size() <= theMaxCand);
0372 }
0373
0374 LogDebug("CkfPattern") << "newCand.size() at end = " << newCand.size();
0375
0376 if (theIntermediateCleaning) {
0377 #ifdef STANDARD_INTERMEDIARYCLEAN
0378 IntermediateTrajectoryCleaner::clean(newCand);
0379 #else
0380 groupedIntermediaryClean(newCand);
0381 #endif
0382 }
0383 candidates.swap(newCand);
0384
0385 LogDebug("CkfPattern") << "candidates(3): " << result.size() << " candidates after " << nIter++
0386 << " groupedCKF iteration: \n"
0387 << PrintoutHelper::dumpCandidates(result) << "\n " << candidates.size()
0388 << " running candidates are: \n"
0389 << PrintoutHelper::dumpCandidates(candidates);
0390 }
0391
0392 return nCands;
0393 }
0394
0395 #ifdef EDM_ML_DEBUG
0396 std::string whatIsTheNextStep(TempTrajectory const& traj,
0397 std::pair<TrajectoryStateOnSurface, std::vector<const DetLayer*> >& stateAndLayers) {
0398 std::stringstream buffer;
0399 vector<const DetLayer*>& nl = stateAndLayers.second;
0400
0401
0402
0403
0404 const BarrelDetLayer* sbdl = dynamic_cast<const BarrelDetLayer*>(traj.lastLayer());
0405 const ForwardDetLayer* sfdl = dynamic_cast<const ForwardDetLayer*>(traj.lastLayer());
0406 if (sbdl) {
0407 buffer << "Started from " << traj.lastLayer() << " r=" << sbdl->specificSurface().radius()
0408 << " phi=" << sbdl->specificSurface().phi() << endl;
0409 } else if (sfdl) {
0410 buffer << "Started from " << traj.lastLayer() << " z " << sfdl->specificSurface().position().z() << " phi "
0411 << sfdl->specificSurface().phi() << endl;
0412 }
0413 buffer << "Trying to go to";
0414 for (vector<const DetLayer*>::iterator il = nl.begin(); il != nl.end(); il++) {
0415
0416 const BarrelDetLayer* bdl = dynamic_cast<const BarrelDetLayer*>(*il);
0417 const ForwardDetLayer* fdl = dynamic_cast<const ForwardDetLayer*>(*il);
0418
0419 if (bdl)
0420 buffer << " r " << bdl->specificSurface().radius() << endl;
0421 if (fdl)
0422 buffer << " z " << fdl->specificSurface().position().z() << endl;
0423
0424 }
0425 return buffer.str();
0426 }
0427
0428 std::string whatIsTheStateToUse(TrajectoryStateOnSurface& initial,
0429 TrajectoryStateOnSurface& stateToUse,
0430 const DetLayer* l) {
0431 std::stringstream buffer;
0432 buffer << "GCTB: starting from "
0433 << " r / phi / z = " << stateToUse.globalPosition().perp() << " / " << stateToUse.globalPosition().phi()
0434 << " / " << stateToUse.globalPosition().z()
0435 << " , pt / phi / pz /charge = " << stateToUse.globalMomentum().perp() << " / "
0436 << stateToUse.globalMomentum().phi() << " / " << stateToUse.globalMomentum().z() << " / "
0437 << stateToUse.charge() << " for layer at " << l << endl;
0438 buffer << " errors:";
0439 for (int i = 0; i < 5; i++)
0440 buffer << " " << sqrt(stateToUse.curvilinearError().matrix()(i, i));
0441 buffer << endl;
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452 return buffer.str();
0453 }
0454 #endif
0455
0456 bool GroupedCkfTrajectoryBuilder::advanceOneLayer(const TrajectorySeed& seed,
0457 TempTrajectory& traj,
0458 const TrajectoryFilter* regionalCondition,
0459 const Propagator* propagator,
0460 bool inOut,
0461 TempTrajectoryContainer& newCand,
0462 TempTrajectoryContainer& result) const {
0463 std::pair<TSOS, std::vector<const DetLayer*> >&& stateAndLayers = findStateAndLayers(seed, traj);
0464
0465 bool full = (int)newCand.size() == theMaxCand;
0466 auto lessTraj = GroupedTrajCandLess(theLostHitPenalty, theFoundHitBonus);
0467
0468 if (maxPt2ForLooperReconstruction > 0) {
0469 if (
0470
0471 traj.lastLayer()->location() == 0) {
0472 float pt2 = stateAndLayers.first.globalMomentum().perp2();
0473 if (pt2 < maxPt2ForLooperReconstruction && pt2 > (0.3f * 0.3f))
0474 stateAndLayers.second.push_back(traj.lastLayer());
0475 }
0476 }
0477
0478 auto layerBegin = stateAndLayers.second.begin();
0479 auto layerEnd = stateAndLayers.second.end();
0480
0481
0482
0483
0484
0485
0486 #ifdef EDM_ML_DEBUG
0487 LogDebug("CkfPattern") << whatIsTheNextStep(traj, stateAndLayers);
0488 #endif
0489
0490 bool foundSegments(false);
0491 bool foundNewCandidates(false);
0492 for (auto il = layerBegin; il != layerEnd; il++) {
0493 TSOS stateToUse = stateAndLayers.first;
0494
0495 double dPhiCacheForLoopersReconstruction(0);
0496 if UNLIKELY (!traj.empty() && (*il) == traj.lastLayer()) {
0497 if (maxPt2ForLooperReconstruction > 0) {
0498
0499
0500 const BarrelDetLayer* sbdl = dynamic_cast<const BarrelDetLayer*>(traj.lastLayer());
0501 if (sbdl) {
0502 HelixBarrelCylinderCrossing cylinderCrossing(stateToUse.globalPosition(),
0503 stateToUse.globalMomentum(),
0504 stateToUse.transverseCurvature(),
0505 propagator->propagationDirection(),
0506 sbdl->specificSurface());
0507 if (!cylinderCrossing.hasSolution())
0508 continue;
0509 GlobalPoint starting = stateToUse.globalPosition();
0510 GlobalPoint target1 = cylinderCrossing.position1();
0511 GlobalPoint target2 = cylinderCrossing.position2();
0512
0513 GlobalPoint farther =
0514 fabs(starting.phi() - target1.phi()) > fabs(starting.phi() - target2.phi()) ? target1 : target2;
0515
0516 const Bounds& bounds(sbdl->specificSurface().bounds());
0517 float length = 0.5f * bounds.length();
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533 if (fabs(farther.z()) * 0.95f > length)
0534 continue;
0535
0536 Geom::Phi<float> tmpDphi = target1.phi() - target2.phi();
0537 if (std::abs(tmpDphi) > maxDPhiForLooperReconstruction)
0538 continue;
0539 GlobalPoint target(0.5f * (target1.basicVector() + target2.basicVector()));
0540
0541
0542 TransverseImpactPointExtrapolator extrapolator;
0543 stateToUse = extrapolator.extrapolate(stateToUse, target, *propagator);
0544 if (!stateToUse.isValid())
0545 continue;
0546
0547
0548 dPhiCacheForLoopersReconstruction = std::abs(tmpDphi);
0549 traj.incrementLoops();
0550 } else {
0551 continue;
0552 }
0553 } else {
0554
0555 LogDebug("CkfPattern") << " self propagating in advanceOneLayer.\n from: \n" << stateToUse;
0556
0557
0558 TransverseImpactPointExtrapolator middle;
0559 GlobalPoint center(0, 0, 0);
0560 stateToUse = middle.extrapolate(stateToUse, center, *(forwardPropagator(seed)));
0561
0562 if (!stateToUse.isValid())
0563 continue;
0564 LogDebug("CkfPattern") << "to: " << stateToUse;
0565 }
0566 }
0567
0568
0569 LayerMeasurements layerMeasurements(theMeasurementTracker->measurementTracker(), *theMeasurementTracker);
0570 TrajectorySegmentBuilder layerBuilder(
0571 &layerMeasurements, **il, *propagator, *theUpdator, *theEstimator, theLockHits, theBestHitOnly, theMaxCand);
0572
0573 #ifdef EDM_ML_DEBUG
0574 LogDebug("CkfPattern") << whatIsTheStateToUse(stateAndLayers.first, stateToUse, *il);
0575 #endif
0576
0577 auto&& segments = layerBuilder.segments(stateToUse);
0578
0579 LogDebug("CkfPattern") << "GCTB: number of segments = " << segments.size();
0580
0581 if (!segments.empty())
0582 foundSegments = true;
0583
0584 for (auto is = segments.begin(); is != segments.end(); is++) {
0585
0586
0587
0588 auto const& measurements = is->measurements();
0589 if (!theAlwaysUseInvalid && is != segments.begin() && measurements.size() == 1 &&
0590 (measurements.front().recHit()->getType() == TrackingRecHit::missing))
0591 break;
0592
0593
0594 bool toBeRejected(false);
0595 for (auto revIt = measurements.rbegin(); revIt != measurements.rend(); --revIt) {
0596
0597 for (auto newTrajMeasIt = traj.measurements().rbegin(); newTrajMeasIt != traj.measurements().rend();
0598 --newTrajMeasIt) {
0599
0600 if (revIt->recHitR().geographicalId() == newTrajMeasIt->recHitR().geographicalId() &&
0601 (revIt->recHitR().geographicalId() != DetId(0))) {
0602 toBeRejected = true;
0603 goto rejected;
0604 }
0605
0606 }
0607 }
0608
0609 rejected:;
0610 if (toBeRejected) {
0611 #ifdef VI_DEBUG
0612 cout << "WARNING: neglect candidate because it contains the same hit twice \n";
0613 cout << "-- discarded track's pt,eta,#found/lost: "
0614 << traj.lastMeasurement().updatedState().globalMomentum().perp() << " , "
0615 << traj.lastMeasurement().updatedState().globalMomentum().eta() << " , " << traj.foundHits() << '/'
0616 << traj.lostHits() << "\n";
0617 #endif
0618 traj.setDPhiCacheForLoopersReconstruction(dPhiCacheForLoopersReconstruction);
0619 continue;
0620 }
0621
0622
0623
0624
0625
0626 TempTrajectory newTraj(traj);
0627 traj.setDPhiCacheForLoopersReconstruction(dPhiCacheForLoopersReconstruction);
0628 newTraj.join(*is);
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638 if (toBeContinued(newTraj, inOut)) {
0639
0640
0641 LogDebug("CkfPattern") << "GCTB: adding updated trajectory to candidates: inOut=" << inOut
0642 << " hits=" << newTraj.foundHits();
0643
0644 newTraj.setStopReason(StopReason::NOT_STOPPED);
0645 if (full) {
0646 bool better = lessTraj(newTraj, newCand.front());
0647 if (better) {
0648
0649 foundNewCandidates = true;
0650 std::pop_heap(newCand.begin(), newCand.end(), lessTraj);
0651 newCand.back().swap(newTraj);
0652 std::push_heap(newCand.begin(), newCand.end(), lessTraj);
0653 }
0654 } else {
0655 newCand.push_back(std::move(newTraj));
0656 foundNewCandidates = true;
0657 full = (int)newCand.size() == theMaxCand;
0658 if (full)
0659 std::make_heap(newCand.begin(), newCand.end(), lessTraj);
0660 }
0661 } else {
0662
0663
0664 LogDebug("CkfPattern") << "GCTB: adding completed trajectory to results if passes cuts: inOut=" << inOut
0665 << " hits=" << newTraj.foundHits();
0666 moveToResult(std::move(newTraj), result, inOut);
0667 }
0668 }
0669 }
0670
0671 if (!foundSegments) {
0672 LogDebug("CkfPattern") << "GCTB: adding input trajectory to result";
0673 if (!stateAndLayers.second.empty())
0674 traj.setStopReason(StopReason::NO_SEGMENTS_FOR_VALID_LAYERS);
0675 addToResult(traj, result, inOut);
0676 }
0677 return foundNewCandidates;
0678 }
0679
0680 namespace {
0681
0682
0683 struct LayersInTraj {
0684 static constexpr int N = 3;
0685 TempTrajectory* traj;
0686 std::array<DetLayer const*, N> layers;
0687 int tot;
0688 void fill(TempTrajectory& t) {
0689 traj = &t;
0690 tot = 0;
0691 const TempTrajectory::DataContainer& measurements = traj->measurements();
0692
0693 auto currl = layers[tot] = measurements.back().layer();
0694 TempTrajectory::DataContainer::const_iterator ifirst = measurements.rbegin();
0695 --ifirst;
0696 for (TempTrajectory::DataContainer::const_iterator im = ifirst; im != measurements.rend(); --im) {
0697 if (im->layer() != currl) {
0698 ++tot;
0699 currl = im->layer();
0700 if (tot < N)
0701 layers[tot] = currl;
0702 }
0703 }
0704 ++tot;
0705 }
0706
0707
0708
0709
0710
0711 };
0712 }
0713
0714
0715 void GroupedCkfTrajectoryBuilder::groupedIntermediaryClean(TempTrajectoryContainer& theTrajectories) const {
0716
0717
0718 if (theTrajectories.empty())
0719 return;
0720
0721 LayersInTraj layers[theTrajectories.size()];
0722 int ntraj = 0;
0723 for (auto& t : theTrajectories) {
0724 if (t.isValid() && t.lastMeasurement().recHitR().isValid())
0725 layers[ntraj++].fill(t);
0726 }
0727
0728 if (ntraj < 2)
0729 return;
0730
0731 for (int ifirst = 0; ifirst != ntraj - 1; ++ifirst) {
0732 auto firstTraj = layers[ifirst].traj;
0733 if (!firstTraj->isValid())
0734 continue;
0735 const TempTrajectory::DataContainer& firstMeasurements = firstTraj->measurements();
0736
0737 int firstLayerSize = layers[ifirst].tot;
0738 if (firstLayerSize < 4)
0739 continue;
0740 auto const& firstLayers = layers[ifirst].layers;
0741
0742 for (int isecond = ifirst + 1; isecond != ntraj; ++isecond) {
0743 auto secondTraj = layers[isecond].traj;
0744 if (!secondTraj->isValid())
0745 continue;
0746
0747 const TempTrajectory::DataContainer& secondMeasurements = secondTraj->measurements();
0748
0749 int secondLayerSize = layers[isecond].tot;
0750
0751
0752
0753 if (firstLayerSize != secondLayerSize)
0754 continue;
0755 auto const& secondLayers = layers[isecond].layers;
0756 if (firstLayers[0] != secondLayers[0] || firstLayers[1] != secondLayers[1] || firstLayers[2] != secondLayers[2])
0757 continue;
0758
0759 TempTrajectory::DataContainer::const_iterator im1 = firstMeasurements.rbegin();
0760 TempTrajectory::DataContainer::const_iterator im2 = secondMeasurements.rbegin();
0761
0762
0763
0764 bool unequal(false);
0765 const DetLayer* layerPtr = firstLayers[0];
0766 while (im1 != firstMeasurements.rend() && im2 != secondMeasurements.rend()) {
0767 if (im1->layer() != layerPtr || im2->layer() != layerPtr)
0768 break;
0769 if (!(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
0770 !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some)) {
0771
0772 unequal = true;
0773 break;
0774 }
0775 --im1;
0776 --im2;
0777 }
0778 if (im1 == firstMeasurements.rend() || im2 == secondMeasurements.rend() || im1->layer() == layerPtr ||
0779 im2->layer() == layerPtr || unequal)
0780 continue;
0781
0782
0783
0784
0785 layerPtr = firstLayers[1];
0786 bool firstValid(true);
0787 while (im1 != firstMeasurements.rend() && im1->layer() == layerPtr) {
0788 if (!im1->recHit()->isValid())
0789 firstValid = false;
0790 --im1;
0791 }
0792 bool secondValid(true);
0793 while (im2 != secondMeasurements.rend() && im2->layer() == layerPtr) {
0794 if (!im2->recHit()->isValid())
0795 secondValid = false;
0796 --im2;
0797 }
0798 if (!tkxor(firstValid, secondValid))
0799 continue;
0800
0801
0802
0803 unequal = false;
0804 layerPtr = firstLayers[2];
0805 while (im1 != firstMeasurements.rend() && im2 != secondMeasurements.rend()) {
0806 if (im1->layer() != layerPtr || im2->layer() != layerPtr)
0807 break;
0808 if (!(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
0809 !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some)) {
0810
0811 unequal = true;
0812 break;
0813 }
0814 --im1;
0815 --im2;
0816 }
0817 if (im1 == firstMeasurements.rend() || im2 == secondMeasurements.rend() || im1->layer() == layerPtr ||
0818 im2->layer() == layerPtr || unequal)
0819 continue;
0820
0821 if (!firstValid) {
0822 firstTraj->invalidate();
0823 break;
0824 } else {
0825 secondTraj->invalidate();
0826 break;
0827 }
0828 }
0829 }
0830
0831
0832
0833
0834
0835
0836
0837
0838 theTrajectories.erase(
0839 std::remove_if(theTrajectories.begin(), theTrajectories.end(), std::not_fn(&TempTrajectory::isValid)),
0840 theTrajectories.end());
0841 }
0842
0843 void GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(const TrajectorySeed& seed,
0844 TempTrajectoryContainer& result) const {
0845
0846
0847
0848
0849
0850 LogDebug("CkfPattern") << "Starting to rebuild " << result.size() << " tracks";
0851
0852
0853
0854
0855 auto hitCloner = static_cast<TkTransientTrackingRecHitBuilder const*>(hitBuilder())->cloner();
0856 KFTrajectoryFitter fitter(backwardPropagator(seed), &updator(), &estimator(), 3, nullptr, &hitCloner);
0857
0858 std::vector<const TrackingRecHit*> seedHits;
0859
0860 unsigned int nSeed = seed.nHits();
0861
0862 TempTrajectoryContainer rebuiltTrajectories;
0863
0864 for (TempTrajectoryContainer::iterator it = result.begin(); it != result.end(); it++) {
0865
0866
0867
0868 assert(it->isValid());
0869 auto&& reFitted = backwardFit(*it, nSeed, fitter, seedHits);
0870 if UNLIKELY (!reFitted.isValid()) {
0871 rebuiltTrajectories.push_back(std::move(*it));
0872 LogDebug("CkfPattern") << "RebuildSeedingRegion skipped as backward fit failed";
0873
0874 continue;
0875 }
0876
0877
0878
0879
0880
0881 int nRebuilt = rebuildSeedingRegion(seed, seedHits, reFitted, rebuiltTrajectories);
0882
0883
0884
0885 for (size_t i = rebuiltTrajectories.size() - 1; i < rebuiltTrajectories.size() - nRebuilt - 1; --i) {
0886 rebuiltTrajectories[i].setStopReason(it->stopReason());
0887 }
0888
0889 if (nRebuilt == 0 && !theKeepOriginalIfRebuildFails)
0890 it->invalidate();
0891
0892 if (nRebuilt < 0)
0893 rebuiltTrajectories.push_back(std::move(*it));
0894 }
0895
0896
0897
0898 result.swap(rebuiltTrajectories);
0899 result.erase(std::remove_if(result.begin(), result.end(), std::not_fn(&TempTrajectory::isValid)), result.end());
0900 }
0901
0902 int GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(const TrajectorySeed& seed,
0903 const std::vector<const TrackingRecHit*>& seedHits,
0904 TempTrajectory& candidate,
0905 TempTrajectoryContainer& result) const {
0906
0907
0908
0909
0910
0911
0912
0913 TempTrajectoryContainer rebuiltTrajectories;
0914 #ifdef DBG2_GCTB
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936
0937
0938 cout << "Before backward building: #measurements = " << candidate.measurements().size();
0939 #endif
0940
0941
0942
0943
0944 const bool inOut = false;
0945 groupedLimitedCandidates(seed, candidate, nullptr, backwardPropagator(seed), inOut, rebuiltTrajectories);
0946
0947 LogDebug("CkfPattern") << " After backward building: " << PrintoutHelper::dumpCandidates(rebuiltTrajectories);
0948
0949
0950
0951
0952 int nrOfTrajectories(0);
0953 bool orig_ok = false;
0954
0955
0956 for (TempTrajectoryContainer::iterator it = rebuiltTrajectories.begin(); it != rebuiltTrajectories.end(); it++) {
0957 TempTrajectory::DataContainer newMeasurements(it->measurements());
0958
0959
0960
0961 if (theRequireSeedHitsInRebuild) {
0962 orig_ok = true;
0963
0964 if (newMeasurements.size() <= candidate.measurements().size()) {
0965 LogDebug("CkfPattern") << "newMeasurements.size()<=candidate.measurements().size()";
0966 continue;
0967 }
0968
0969
0970
0971 if (!verifyHits(newMeasurements.rbegin(), newMeasurements.size() - candidate.measurements().size(), seedHits)) {
0972 LogDebug("CkfPattern") << "seed hits not found in rebuild";
0973 continue;
0974 }
0975 }
0976
0977
0978
0979
0980 nrOfTrajectories++;
0981 result.emplace_back(seed.direction(), seed.nHits());
0982 TempTrajectory& reversedTrajectory = result.back();
0983 reversedTrajectory.setNLoops(it->nLoops());
0984 for (TempTrajectory::DataContainer::const_iterator im = newMeasurements.rbegin(), ed = newMeasurements.rend();
0985 im != ed;
0986 --im) {
0987 reversedTrajectory.push(*im);
0988 }
0989
0990 LogDebug("CkgPattern") << "New traj direction = " << reversedTrajectory.direction() << "\n"
0991 << PrintoutHelper::dumpMeasurements(reversedTrajectory.measurements());
0992 }
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002
1003 if ((nrOfTrajectories == 0) && orig_ok) {
1004 nrOfTrajectories = -1;
1005 }
1006 return nrOfTrajectories;
1007 }
1008
1009 TempTrajectory GroupedCkfTrajectoryBuilder::backwardFit(TempTrajectory& candidate,
1010 unsigned int nSeed,
1011 const TrajectoryFitter& fitter,
1012 std::vector<const TrackingRecHit*>& remainingHits) const {
1013
1014
1015
1016 remainingHits.clear();
1017
1018 LogDebug("CkfPattern") << "nSeed " << nSeed << endl
1019 << "Old traj direction = " << candidate.direction() << endl
1020 << PrintoutHelper::dumpMeasurements(candidate.measurements());
1021
1022
1023
1024
1025
1026
1027
1028
1029 unsigned int nHit(0);
1030
1031
1032
1033
1034 unsigned int nHitMin = std::max(candidate.foundHits() - nSeed, theMinNrOfHitsForRebuild);
1035
1036
1037 if UNLIKELY (nHitMin < theMinNrOfHitsForRebuild)
1038 return TempTrajectory();
1039
1040 LogDebug("CkfPattern") << "Sizes: " << candidate.measurements().size() << " / ";
1041
1042
1043
1044 Trajectory fwdTraj(oppositeDirection(candidate.direction()));
1045 fwdTraj.setNLoops(candidate.nLoops());
1046
1047
1048
1049 const DetLayer* bwdDetLayer[candidate.measurements().size()];
1050 int nl = 0;
1051 for (auto const& tm : candidate.measurements()) {
1052 const TrackingRecHit* hit = tm.recHitR().hit();
1053
1054
1055
1056 if (nHit < nHitMin) {
1057 fwdTraj.push(tm);
1058 bwdDetLayer[nl++] = tm.layer();
1059
1060
1061
1062 if LIKELY (hit->isValid()) {
1063 nHit++;
1064
1065
1066
1067 }
1068 }
1069
1070
1071
1072
1073 else if (hit->isValid()) {
1074
1075 remainingHits.push_back(hit);
1076 }
1077 }
1078
1079
1080
1081 if UNLIKELY (nHit < nHitMin)
1082 return TempTrajectory();
1083
1084
1085
1086
1087 TrajectoryStateOnSurface firstTsos(fwdTraj.firstMeasurement().updatedState());
1088
1089 firstTsos.rescaleError(10.);
1090
1091 Trajectory&& bwdFitted =
1092 fitter.fitOne(TrajectorySeed({}, {}, oppositeDirection(candidate.direction())), fwdTraj.recHits(), firstTsos);
1093 if UNLIKELY (!bwdFitted.isValid())
1094 return TempTrajectory();
1095
1096 LogDebug("CkfPattern") << "Obtained bwdFitted trajectory with measurement size " << bwdFitted.measurements().size();
1097 TempTrajectory fitted(fwdTraj.direction(), nSeed);
1098 fitted.setNLoops(fwdTraj.nLoops());
1099 vector<TM> const& tmsbf = bwdFitted.measurements();
1100 int iDetLayer = 0;
1101
1102
1103
1104
1105 for (vector<TM>::const_iterator im = tmsbf.begin(); im != tmsbf.end(); im++) {
1106 fitted.emplace((*im).forwardPredictedState(),
1107 (*im).backwardPredictedState(),
1108 (*im).updatedState(),
1109 (*im).recHit(),
1110 (*im).estimate(),
1111 bwdDetLayer[iDetLayer]);
1112
1113 LogDebug("CkfPattern") << PrintoutHelper::dumpMeasurement(*im);
1114 iDetLayer++;
1115 }
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127 return fitted;
1128 }
1129
1130 bool GroupedCkfTrajectoryBuilder::verifyHits(TempTrajectory::DataContainer::const_iterator rbegin,
1131 size_t maxDepth,
1132 const std::vector<const TrackingRecHit*>& hits) const {
1133
1134
1135
1136 LogDebug("CkfPattern") << "Checking for " << hits.size() << " hits in " << maxDepth << " measurements" << endl;
1137
1138 auto rend = rbegin;
1139 while (maxDepth > 0) {
1140 --maxDepth;
1141 --rend;
1142 }
1143 for (auto ir = hits.begin(); ir != hits.end(); ir++) {
1144
1145 bool foundHit(false);
1146 for (auto im = rbegin; im != rend; --im) {
1147 if (im->recHit()->isValid() && (*ir)->sharesInput(im->recHit()->hit(), TrackingRecHit::some)) {
1148 foundHit = true;
1149 break;
1150 }
1151 }
1152 if (!foundHit)
1153 return false;
1154 }
1155 return true;
1156 }