Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-23 03:13:33

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