Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:37:56

0001 #include "DataFormats/Common/interface/Handle.h"
0002 #include "FWCore/Framework/interface/EventSetup.h"
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 #include "FWCore/ParameterSet/interface/PluginDescription.h"
0005 #include "FWCore/Utilities/interface/isFinite.h"
0006 #include "FWCore/Utilities/interface/ESInputTag.h"
0007 
0008 #include "DataFormats/Common/interface/OwnVector.h"
0009 #include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
0010 #include "DataFormats/Common/interface/View.h"
0011 #include "DataFormats/TrackReco/interface/SeedStopInfo.h"
0012 
0013 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0014 
0015 #include "TrackingTools/PatternTools/interface/Trajectory.h"
0016 #include "TrackingTools/TrajectoryCleaning/interface/TrajectoryCleanerBySharedHits.h"
0017 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
0018 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
0019 
0020 #include "RecoTracker/CkfPattern/interface/CkfTrackCandidateMakerBase.h"
0021 #include "RecoTracker/CkfPattern/interface/TransientInitialStateEstimator.h"
0022 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
0023 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
0024 #include "RecoTracker/CkfPattern/interface/BaseCkfTrajectoryBuilderFactory.h"
0025 
0026 #include "RecoTracker/CkfPattern/interface/CachingSeedCleanerBySharedInput.h"
0027 
0028 #include "RecoTracker/MeasurementDet/interface/MeasurementTrackerEvent.h"
0029 
0030 #include "RecoTracker/Record/interface/NavigationSchoolRecord.h"
0031 #include "TrackingTools/DetLayers/interface/NavigationSchool.h"
0032 
0033 #include "RecoTracker/TransientTrackingRecHit/interface/Traj2TrackHits.h"
0034 
0035 #include <algorithm>
0036 #include <functional>
0037 
0038 // #define VI_SORTSEED
0039 // #define VI_REPRODUCIBLE
0040 // #define VI_TBB
0041 
0042 #include <thread>
0043 #ifdef VI_TBB
0044 #include "oneapi/tbb/parallel_for.h"
0045 #endif
0046 
0047 #include "RecoTracker/CkfPattern/interface/PrintoutHelper.h"
0048 
0049 using namespace edm;
0050 using namespace std;
0051 
0052 namespace {
0053   std::unique_ptr<BaseCkfTrajectoryBuilder> createBaseCkfTrajectoryBuilder(const edm::ParameterSet& pset,
0054                                                                            edm::ConsumesCollector& iC) {
0055     return BaseCkfTrajectoryBuilderFactory::get()->create(pset.getParameter<std::string>("ComponentType"), pset, iC);
0056   }
0057 }  // namespace
0058 
0059 namespace cms {
0060   CkfTrackCandidateMakerBase::CkfTrackCandidateMakerBase(edm::ParameterSet const& conf, edm::ConsumesCollector&& iC)
0061       : theTrackCandidateOutput(true),
0062         theTrajectoryOutput(false),
0063         useSplitting(conf.getParameter<bool>("useHitsSplitting")),
0064         doSeedingRegionRebuilding(conf.getParameter<bool>("doSeedingRegionRebuilding")),
0065         cleanTrajectoryAfterInOut(conf.getParameter<bool>("cleanTrajectoryAfterInOut")),
0066         reverseTrajectories(conf.getParameter<bool>("reverseTrajectories")),
0067         theMaxNSeeds(conf.getParameter<unsigned int>("maxNSeeds")),
0068         theTrajectoryBuilder(
0069             createBaseCkfTrajectoryBuilder(conf.getParameter<edm::ParameterSet>("TrajectoryBuilderPSet"), iC)),
0070         theTrajectoryCleanerToken(
0071             iC.esConsumes(edm::ESInputTag("", conf.getParameter<std::string>("TrajectoryCleaner")))),
0072         theTrajectoryCleaner(nullptr),
0073         theInitialState(std::make_unique<TransientInitialStateEstimator>(
0074             conf.getParameter<ParameterSet>("TransientInitialStateEstimatorParameters"), iC)),
0075         theNavigationSchoolToken(
0076             iC.esConsumes(edm::ESInputTag("", conf.getParameter<std::string>("NavigationSchool")))),
0077         theNavigationSchool(nullptr),
0078         thePropagatorToken(iC.esConsumes(edm::ESInputTag("", "AnyDirectionAnalyticalPropagator"))),
0079 #ifdef VI_REPRODUCIBLE
0080         maxSeedsBeforeCleaning_(0),
0081 #else
0082         maxSeedsBeforeCleaning_(conf.getParameter<unsigned int>("maxSeedsBeforeCleaning")),
0083 #endif
0084         theMTELabel(iC.consumes<MeasurementTrackerEvent>(conf.getParameter<edm::InputTag>("MeasurementTrackerEvent"))),
0085         clustersToSkipTag_(conf.getParameter<edm::InputTag>("clustersToSkip")),
0086         skipClusters_(!clustersToSkipTag_.label().empty()),
0087         phase2ClustersToSkipTag_(conf.getParameter<edm::InputTag>("phase2clustersToSkip")),
0088         skipPhase2Clusters_(!phase2ClustersToSkipTag_.label().empty()) {
0089     theSeedLabel = iC.consumes<edm::View<TrajectorySeed>>(conf.getParameter<edm::InputTag>("src"));
0090 
0091     if (skipClusters_) {
0092       maskPixels_ = iC.consumes<PixelClusterMask>(clustersToSkipTag_);
0093       maskStrips_ = iC.consumes<StripClusterMask>(clustersToSkipTag_);
0094     }
0095     //FIXME:: just temporary solution for phase2!
0096     if (skipPhase2Clusters_) {
0097       maskPixels_ = iC.consumes<PixelClusterMask>(phase2ClustersToSkipTag_);
0098       maskPhase2OTs_ = iC.consumes<Phase2OTClusterMask>(phase2ClustersToSkipTag_);
0099     }
0100 #ifndef VI_REPRODUCIBLE
0101     std::string cleaner = conf.getParameter<std::string>("RedundantSeedCleaner");
0102     if (cleaner == "CachingSeedCleanerBySharedInput") {
0103       int numHitsForSeedCleaner = conf.getParameter<int>("numHitsForSeedCleaner");
0104       bool onlyPixelHits = conf.getParameter<bool>("onlyPixelHitsForSeedCleaner");
0105       theSeedCleaner = std::make_unique<CachingSeedCleanerBySharedInput>(numHitsForSeedCleaner, onlyPixelHits);
0106     } else if (cleaner != "none") {
0107       throw cms::Exception("RedundantSeedCleaner not found, please use CachingSeedCleanerBySharedInput ro none",
0108                            cleaner);
0109     }
0110 #endif
0111 
0112 #ifdef EDM_ML_DEBUG
0113     if (theTrackCandidateOutput) {
0114       theTrackerToken = iC.esConsumes();
0115     }
0116 #endif
0117 
0118 #ifdef VI_REPRODUCIBLE
0119     std::cout << "CkfTrackCandidateMaker in reproducible setting" << std::endl;
0120     assert(nullptr == theSeedCleaner);
0121     assert(0 >= maxSeedsBeforeCleaning_);
0122 #endif
0123   }
0124 
0125   // Virtual destructor needed.
0126   CkfTrackCandidateMakerBase::~CkfTrackCandidateMakerBase() noexcept(false) {}
0127 
0128   void CkfTrackCandidateMakerBase::beginRunBase(edm::Run const& r, EventSetup const& es) { /* no op*/ }
0129 
0130   void CkfTrackCandidateMakerBase::setEventSetup(const edm::EventSetup& es) {
0131     //services
0132     theTrajectoryCleaner = &es.getData(theTrajectoryCleanerToken);
0133 
0134     theNavigationSchool = &es.getData(theNavigationSchoolToken);
0135     theTrajectoryBuilder->setNavigationSchool(theNavigationSchool);
0136   }
0137 
0138   // Functions that gets called by framework every event
0139   void CkfTrackCandidateMakerBase::produceBase(edm::Event& e, const edm::EventSetup& es) {
0140     // getting objects from the EventSetup
0141     setEventSetup(es);
0142 
0143     // set the correct navigation
0144     // NavigationSetter setter( *theNavigationSchool);
0145 
0146     // propagator
0147     auto const& propagator = es.getData(thePropagatorToken);
0148 
0149     // method for Debugging
0150     printHitsDebugger(e);
0151 
0152     // Step A: set Event for the TrajectoryBuilder
0153     edm::Handle<MeasurementTrackerEvent> data;
0154     e.getByToken(theMTELabel, data);
0155 
0156     std::unique_ptr<MeasurementTrackerEvent> dataWithMasks;
0157     if (skipClusters_) {
0158       edm::Handle<PixelClusterMask> pixelMask;
0159       e.getByToken(maskPixels_, pixelMask);
0160       edm::Handle<StripClusterMask> stripMask;
0161       e.getByToken(maskStrips_, stripMask);
0162       dataWithMasks = std::make_unique<MeasurementTrackerEvent>(*data, *stripMask, *pixelMask);
0163       //std::cout << "Trajectory builder " << conf_.getParameter<std::string>("@module_label") << " created with masks " << std::endl;
0164       theTrajectoryBuilder->setEvent(e, es, &*dataWithMasks);
0165     } else if (skipPhase2Clusters_) {
0166       //FIXME:just temporary solution for phase2!
0167       edm::Handle<PixelClusterMask> pixelMask;
0168       e.getByToken(maskPixels_, pixelMask);
0169       edm::Handle<Phase2OTClusterMask> phase2OTMask;
0170       e.getByToken(maskPhase2OTs_, phase2OTMask);
0171       dataWithMasks = std::make_unique<MeasurementTrackerEvent>(*data, *pixelMask, *phase2OTMask);
0172       //std::cout << "Trajectory builder " << conf_.getParameter<std::string>("@module_label") << " created with phase2 masks " << std::endl;
0173       theTrajectoryBuilder->setEvent(e, es, &*dataWithMasks);
0174     } else {
0175       //std::cout << "Trajectory builder " << conf_.getParameter<std::string>("@module_label") << " created without masks " << std::endl;
0176       theTrajectoryBuilder->setEvent(e, es, &*data);
0177     }
0178     // TISE ES must be set here due to dependence on theTrajectoryBuilder
0179     theInitialState->setEventSetup(
0180         es, static_cast<TkTransientTrackingRecHitBuilder const*>(theTrajectoryBuilder->hitBuilder())->cloner());
0181 
0182     // Step B: Retrieve seeds
0183 
0184     edm::Handle<View<TrajectorySeed>> collseed;
0185     e.getByToken(theSeedLabel, collseed);
0186 
0187     // Step C: Create empty output collection
0188     auto output = std::make_unique<TrackCandidateCollection>();
0189     auto outputT = std::make_unique<std::vector<Trajectory>>();
0190     auto outputSeedStopInfos = std::make_unique<std::vector<SeedStopInfo>>(collseed->size());
0191 
0192     if ((*collseed).size() > theMaxNSeeds) {
0193       LogError("TooManySeeds") << "Exceeded maximum numeber of seeds! theMaxNSeeds=" << theMaxNSeeds
0194                                << " nSeed=" << (*collseed).size();
0195       if (theTrackCandidateOutput) {
0196         e.put(std::move(output));
0197       }
0198       if (theTrajectoryOutput) {
0199         e.put(std::move(outputT));
0200       }
0201       e.put(std::move(outputSeedStopInfos));
0202       return;
0203     }
0204 
0205     // Step D: Invoke the building algorithm
0206     if (!(*collseed).empty()) {
0207       unsigned int lastCleanResult = 0;
0208       std::vector<Trajectory> rawResult;
0209       rawResult.reserve(collseed->size() * 4);
0210 
0211       if (theSeedCleaner)
0212         theSeedCleaner->init(&rawResult);
0213 
0214       // method for debugging
0215       countSeedsDebugger();
0216 
0217       // the mutex
0218       std::mutex theMutex;
0219       using Lock = std::unique_lock<std::mutex>;
0220 
0221       // Loop over seeds
0222       size_t collseed_size = collseed->size();
0223 
0224       unsigned int indeces[collseed_size];
0225       for (auto i = 0U; i < collseed_size; ++i)
0226         indeces[i] = i;
0227 
0228 #ifdef VI_SORTSEED
0229       // std::random_shuffle(indeces,indeces+collseed_size);
0230 
0231       // here only for reference: does not seems to help
0232 
0233       auto const& seeds = *collseed;
0234 
0235       float val[collseed_size];
0236       for (auto i = 0U; i < collseed_size; ++i) {
0237         val[i] = seeds[i].startingState().pt();
0238       };
0239       //  { val[i] =  std::abs((*seeds[i].recHits().first).surface()->eta());}
0240 
0241       /*
0242       unsigned long long val[collseed_size];
0243       for (auto i=0U; i< collseed_size; ++i) {
0244         if (seeds[i].nHits()<2) { val[i]=0; continue;}
0245         auto h = seeds[i].recHits().first;
0246         auto const & hit = static_cast<BaseTrackerRecHit const&>(*h);
0247         val[i] = hit.firstClusterRef().key();
0248         if (++h != seeds[i].recHits().second) {
0249           auto const & hit = static_cast<BaseTrackerRecHit const&>(*h);
0250           val[i] |= (unsigned long long)(hit.firstClusterRef().key())<<32;
0251         }
0252       }
0253       */
0254       std::sort(indeces, indeces + collseed_size, [&](unsigned int i, unsigned int j) { return val[i] < val[j]; });
0255 
0256       // std::cout << spt(indeces[0]) << ' ' << spt(indeces[collseed_size-1]) << std::endl;
0257 #endif
0258 
0259       std::atomic<unsigned int> ntseed(0);
0260       auto theLoop = [&](size_t ii) {
0261         auto j = indeces[ii];
0262 
0263         ntseed++;
0264 
0265         // to be moved inside a par section (how with tbb??)
0266         std::vector<Trajectory> theTmpTrajectories;
0267 
0268         LogDebug("CkfPattern") << "======== Begin to look for trajectories from seed " << j << " ========\n";
0269 
0270         {
0271           Lock lock(theMutex);
0272           // Check if seed hits already used by another track
0273           if (theSeedCleaner && !theSeedCleaner->good(&((*collseed)[j]))) {
0274             LogDebug("CkfTrackCandidateMakerBase") << " Seed cleaning kills seed " << j;
0275             (*outputSeedStopInfos)[j].setStopReason(SeedStopReason::SEED_CLEANING);
0276             return;  // from the lambda!
0277           }
0278         }
0279 
0280         // Build trajectory from seed outwards
0281         theTmpTrajectories.clear();
0282         unsigned int nCandPerSeed = 0;
0283         theTrajectoryBuilder->buildTrajectories((*collseed)[j], theTmpTrajectories, nCandPerSeed, nullptr);
0284         {
0285           Lock lock(theMutex);
0286           (*outputSeedStopInfos)[j].setCandidatesPerSeed(nCandPerSeed);
0287           if (theTmpTrajectories.empty()) {
0288             (*outputSeedStopInfos)[j].setStopReason(SeedStopReason::NO_TRAJECTORY);
0289             return;  // from the lambda!
0290           }
0291         }
0292 
0293         LogDebug("CkfPattern") << "======== In-out trajectory building found " << theTmpTrajectories.size()
0294                                << " trajectories from seed " << j << " ========\n"
0295                                << PrintoutHelper::dumpCandidates(theTmpTrajectories);
0296 
0297         if (cleanTrajectoryAfterInOut) {
0298           // Select the best trajectory from this seed (declare others invalid)
0299           theTrajectoryCleaner->clean(theTmpTrajectories);
0300 
0301           LogDebug("CkfPattern") << "======== In-out trajectory cleaning gave the following "
0302                                  << theTmpTrajectories.size() << " valid trajectories from seed " << j << " ========\n"
0303                                  << PrintoutHelper::dumpCandidates(theTmpTrajectories);
0304         }
0305 
0306         // Optionally continue building trajectory back through
0307         // seed and if possible further inwards.
0308 
0309         if (doSeedingRegionRebuilding) {
0310           theTrajectoryBuilder->rebuildTrajectories((*collseed)[j], theTmpTrajectories);
0311 
0312           LogDebug("CkfPattern") << "======== Out-in trajectory building found " << theTmpTrajectories.size()
0313                                  << " valid/invalid trajectories from seed " << j << " ========\n"
0314                                  << PrintoutHelper::dumpCandidates(theTmpTrajectories);
0315           if (theTmpTrajectories.empty()) {
0316             Lock lock(theMutex);
0317             (*outputSeedStopInfos)[j].setStopReason(SeedStopReason::SEED_REGION_REBUILD);
0318             return;
0319           }
0320         }
0321 
0322         // Select the best trajectory from this seed (after seed region rebuilding, can be more than one)
0323         theTrajectoryCleaner->clean(theTmpTrajectories);
0324 
0325         LogDebug("CkfPattern") << "======== Trajectory cleaning gave the following " << theTmpTrajectories.size()
0326                                << " valid trajectories from seed " << j << " ========\n"
0327                                << PrintoutHelper::dumpCandidates(theTmpTrajectories);
0328 
0329         {
0330           Lock lock(theMutex);
0331           for (vector<Trajectory>::iterator it = theTmpTrajectories.begin(); it != theTmpTrajectories.end(); it++) {
0332             if (it->isValid()) {
0333               it->setSeedRef(collseed->refAt(j));
0334               (*outputSeedStopInfos)[j].setStopReason(SeedStopReason::NOT_STOPPED);
0335               // Store trajectory
0336               rawResult.push_back(std::move(*it));
0337               // Tell seed cleaner which hits this trajectory used.
0338               //TO BE FIXED: this cut should be configurable via cfi file
0339               if (theSeedCleaner && rawResult.back().foundHits() > 3)
0340                 theSeedCleaner->add(&rawResult.back());
0341               //if (theSeedCleaner ) theSeedCleaner->add( & (*it) );
0342             }
0343           }
0344         }
0345 
0346         theTmpTrajectories.clear();
0347 
0348         LogDebug("CkfPattern") << "rawResult trajectories found so far = " << rawResult.size();
0349 
0350         {
0351           Lock lock(theMutex);
0352           if (maxSeedsBeforeCleaning_ > 0 && rawResult.size() > maxSeedsBeforeCleaning_ + lastCleanResult) {
0353             theTrajectoryCleaner->clean(rawResult);
0354             rawResult.erase(
0355                 std::remove_if(rawResult.begin() + lastCleanResult, rawResult.end(), std::not_fn(&Trajectory::isValid)),
0356                 rawResult.end());
0357             lastCleanResult = rawResult.size();
0358           }
0359         }
0360       };
0361       // end of loop over seeds
0362 
0363 #ifdef VI_TBB
0364       tbb::parallel_for(0UL, collseed_size, 1UL, theLoop);
0365 #else
0366 #ifdef VI_OMP
0367 #pragma omp parallel for schedule(dynamic, 4)
0368 #endif
0369       for (size_t j = 0; j < collseed_size; j++) {
0370         theLoop(j);
0371       }
0372 #endif
0373       assert(ntseed == collseed_size);
0374       if (theSeedCleaner)
0375         theSeedCleaner->done();
0376 
0377         // std::cout << "VICkfPattern " << "rawResult trajectories found = " << rawResult.size() << " in " << ntseed << " seeds " << collseed_size << std::endl;
0378 
0379 #ifdef VI_REPRODUCIBLE
0380       // sort trajectory
0381       std::sort(rawResult.begin(), rawResult.end(), [](const Trajectory& a, const Trajectory& b) {
0382         return a.seedRef().key() < b.seedRef().key();
0383       });
0384       //{ return a.chiSquared()*b.ndof() < b.chiSquared()*a.ndof();});
0385 #endif
0386 
0387       // Step E: Clean the results to avoid duplicate tracks
0388       // Rejected ones just flagged as invalid.
0389       theTrajectoryCleaner->clean(rawResult);
0390 
0391       LogDebug("CkfPattern") << "======== Final cleaning of entire event found " << rawResult.size()
0392                              << " valid/invalid trajectories =======" << endl
0393                              << PrintoutHelper::dumpCandidates(rawResult);
0394 
0395       LogDebug("CkfPattern") << "removing invalid trajectories.";
0396 
0397       // Assuming here that theLoop() gives at most one Trajectory per seed
0398       for (const auto& traj : rawResult) {
0399         if (!traj.isValid()) {
0400           const auto seedIndex = traj.seedRef().key();
0401           if ((*outputSeedStopInfos)[seedIndex].stopReason() == SeedStopReason::NOT_STOPPED) {
0402             (*outputSeedStopInfos)[seedIndex].setStopReason(SeedStopReason::FINAL_CLEAN);
0403           }
0404         }
0405       }
0406 
0407       vector<Trajectory>& unsmoothedResult(rawResult);
0408       unsmoothedResult.erase(
0409           std::remove_if(unsmoothedResult.begin(), unsmoothedResult.end(), std::not_fn(&Trajectory::isValid)),
0410           unsmoothedResult.end());
0411       unsmoothedResult.shrink_to_fit();
0412       // If requested, reverse the trajectories creating a new 1-hit seed on the last measurement of the track
0413       if (reverseTrajectories) {
0414         for (auto it = unsmoothedResult.begin(), ed = unsmoothedResult.end(); it != ed; ++it) {
0415           // reverse the trajectory only if it has valid hit on the last measurement (should happen)
0416           if (it->lastMeasurement().updatedState().isValid() && it->lastMeasurement().recHit().get() != nullptr &&
0417               it->lastMeasurement().recHit()->isValid()) {
0418             // I can't use reverse in place, because I want to change the seed
0419             // 1) reverse propagation direction
0420             PropagationDirection direction = it->direction();
0421             if (direction == alongMomentum)
0422               direction = oppositeToMomentum;
0423             else if (direction == oppositeToMomentum)
0424               direction = alongMomentum;
0425             // 2) make a seed
0426             TrajectoryStateOnSurface const& initState = it->lastMeasurement().updatedState();
0427             auto initId = it->lastMeasurement().recHitR().rawId();
0428             PTrajectoryStateOnDet&& state = trajectoryStateTransform::persistentState(initState, initId);
0429             TrajectorySeed::RecHitContainer hits;
0430             hits.push_back(it->lastMeasurement().recHit()->hit()->clone());
0431             // 3) make a trajectory
0432             Trajectory trajectory{std::make_shared<TrajectorySeed>(state, std::move(hits), direction), direction};
0433             trajectory.setNLoops(it->nLoops());
0434             trajectory.setSeedRef(it->seedRef());
0435             trajectory.setStopReason(it->stopReason());
0436             // 4) push states in reversed order
0437             Trajectory::DataContainer& meas = it->measurements();
0438             trajectory.reserve(meas.size());
0439             for (auto itmeas = meas.rbegin(), endmeas = meas.rend(); itmeas != endmeas; ++itmeas) {
0440               trajectory.push(std::move(*itmeas));
0441             }
0442             // replace
0443             (*it) = std::move(trajectory);
0444           } else {
0445             edm::LogWarning("CkfPattern_InvalidLastMeasurement")
0446                 << "Last measurement of the trajectory is invalid, cannot reverse it";
0447           }
0448         }
0449       }
0450 
0451       int viTotHits = 0;
0452 
0453       if (theTrackCandidateOutput) {
0454         // Step F: Convert to TrackCandidates
0455         output->reserve(unsmoothedResult.size());
0456         Traj2TrackHits t2t(theTrajectoryBuilder->hitBuilder(), true);
0457 
0458         for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin(); it != unsmoothedResult.end(); ++it) {
0459           LogDebug("CkfPattern") << "copying " << (useSplitting ? "splitted" : "un-splitted")
0460                                  << " hits from trajectory";
0461           edm::OwnVector<TrackingRecHit> recHits;
0462           if (it->direction() != alongMomentum)
0463             LogDebug("CkfPattern") << "not along momentum... " << std::endl;
0464           t2t(*it, recHits, useSplitting);
0465 
0466           viTotHits += recHits.size();
0467 
0468           LogDebug("CkfPattern") << "getting initial state.";
0469           Trajectory trialTrajectory = (*it);
0470           std::pair<TrajectoryStateOnSurface, const GeomDet*> initState;
0471           bool failed = false;
0472 
0473           do {
0474             // Drop last hit if previous backFitter was not successful
0475             if (failed) {
0476               LogDebug("CkfPattern") << "removing last hit";
0477               trialTrajectory.pop();
0478               LogDebug("CkfPattern") << "hits remaining " << trialTrajectory.foundHits();
0479             }
0480 
0481             // Get inner state
0482             const bool doBackFit = (!doSeedingRegionRebuilding) & (!reverseTrajectories);
0483             initState = theInitialState->innerState(trialTrajectory, doBackFit);
0484 
0485             // Check if that was successful
0486             failed = (!initState.first.isValid()) || initState.second == nullptr ||
0487                      edm::isNotFinite(initState.first.globalPosition().x());
0488           } while (failed && trialTrajectory.foundHits() > 3);
0489 
0490           if (failed) {
0491             const auto seedIndex = it->seedRef().key();
0492             (*outputSeedStopInfos)[seedIndex].setStopReason(SeedStopReason::SMOOTHING_FAILED);
0493             continue;
0494           }
0495 
0496           PTrajectoryStateOnDet state;
0497           if (useSplitting && (initState.second != recHits.front().det()) && recHits.front().det()) {
0498             LogDebug("CkfPattern") << "propagating to hit front in case of splitting.";
0499             TrajectoryStateOnSurface&& propagated =
0500                 propagator.propagate(initState.first, recHits.front().det()->surface());
0501             if (!propagated.isValid())
0502               continue;
0503             state = trajectoryStateTransform::persistentState(propagated, recHits.front().rawId());
0504           } else
0505             state =
0506                 trajectoryStateTransform::persistentState(initState.first, initState.second->geographicalId().rawId());
0507           LogDebug("CkfPattern") << "pushing a TrackCandidate.";
0508           output->emplace_back(recHits, it->seed(), state, it->seedRef(), it->nLoops(), (uint8_t)it->stopReason());
0509         }
0510       }  //output trackcandidates
0511 
0512       LogTrace("CkfPattern|TrackingRegressionTest")
0513           << "========== CkfTrackCandidateMaker Info =========="
0514           << "number of Seed: " << collseed->size() << '\n'
0515           << PrintoutHelper::regressionTest(es.getData(theTrackerToken), unsmoothedResult);
0516 
0517       assert(viTotHits >= 0);  // just to use it...
0518       // std::cout << "VICkfPattern result " << output->size() << " " << viTotHits << std::endl;
0519 
0520       if (theTrajectoryOutput) {
0521         outputT->swap(unsmoothedResult);
0522       }
0523 
0524     }  // end of ((*collseed).size()>0)
0525 
0526     // method for debugging
0527     deleteAssocDebugger();
0528 
0529     // Step G: write output to file
0530     if (theTrackCandidateOutput) {
0531       e.put(std::move(output));
0532     }
0533     if (theTrajectoryOutput) {
0534       e.put(std::move(outputT));
0535     }
0536     e.put(std::move(outputSeedStopInfos));
0537   }
0538 
0539   void CkfTrackCandidateMakerBase::fillPSetDescription(edm::ParameterSetDescription& desc) {
0540     desc.add<bool>("cleanTrajectoryAfterInOut", true);
0541     desc.add<bool>("doSeedingRegionRebuilding", true);
0542     desc.add<bool>("onlyPixelHitsForSeedCleaner", false);
0543     desc.add<bool>("reverseTrajectories", false);
0544     desc.add<bool>("useHitsSplitting", true);
0545     desc.add<edm::InputTag>("MeasurementTrackerEvent", edm::InputTag("MeasurementTrackerEvent"));
0546     desc.add<edm::InputTag>("src", edm::InputTag("globalMixedSeeds"));
0547 
0548     desc.add<edm::InputTag>("clustersToSkip", edm::InputTag(""));
0549     desc.add<edm::InputTag>("phase2clustersToSkip", edm::InputTag(""));
0550 
0551     edm::ParameterSetDescription psdTB;
0552     psdTB.addNode(edm::PluginDescription<BaseCkfTrajectoryBuilderFactory>("ComponentType", true));
0553     desc.add<edm::ParameterSetDescription>("TrajectoryBuilderPSet", psdTB);
0554 
0555     edm::ParameterSetDescription psd1;
0556     psd1.add<std::string>("propagatorAlongTISE", "PropagatorWithMaterial");
0557     psd1.add<std::string>("propagatorOppositeTISE", "PropagatorWithMaterialOpposite");
0558     psd1.add<int>("numberMeasurementsForFit", 4);
0559     desc.add<edm::ParameterSetDescription>("TransientInitialStateEstimatorParameters", psd1);
0560 
0561     desc.add<int>("numHitsForSeedCleaner", 4);
0562     desc.add<std::string>("NavigationSchool", "SimpleNavigationSchool");
0563     desc.add<std::string>("RedundantSeedCleaner", "CachingSeedCleanerBySharedInput");
0564     desc.add<std::string>("TrajectoryCleaner", "TrajectoryCleanerBySharedHits");
0565     desc.add<unsigned int>("maxNSeeds", 500000);
0566     desc.add<unsigned int>("maxSeedsBeforeCleaning", 0);
0567   }
0568 }  // namespace cms