Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-01-13 01:44:03

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         auto const& startTraj =
0285             theTrajectoryBuilder->buildTrajectories((*collseed)[j], theTmpTrajectories, nCandPerSeed, nullptr);
0286         {
0287           Lock lock(theMutex);
0288           (*outputSeedStopInfos)[j].setCandidatesPerSeed(nCandPerSeed);
0289           if (theTmpTrajectories.empty()) {
0290             (*outputSeedStopInfos)[j].setStopReason(SeedStopReason::NO_TRAJECTORY);
0291             return;  // from the lambda!
0292           }
0293         }
0294 
0295         LogDebug("CkfPattern") << "======== In-out trajectory building found " << theTmpTrajectories.size()
0296                                << " trajectories from seed " << j << " ========\n"
0297                                << PrintoutHelper::dumpCandidates(theTmpTrajectories);
0298 
0299         if (cleanTrajectoryAfterInOut) {
0300           // Select the best trajectory from this seed (declare others invalid)
0301           theTrajectoryCleaner->clean(theTmpTrajectories);
0302 
0303           LogDebug("CkfPattern") << "======== In-out trajectory cleaning gave the following "
0304                                  << theTmpTrajectories.size() << " valid trajectories from seed " << j << " ========\n"
0305                                  << PrintoutHelper::dumpCandidates(theTmpTrajectories);
0306         }
0307 
0308         // Optionally continue building trajectory back through
0309         // seed and if possible further inwards.
0310 
0311         if (doSeedingRegionRebuilding) {
0312           theTrajectoryBuilder->rebuildTrajectories(startTraj, (*collseed)[j], theTmpTrajectories);
0313 
0314           LogDebug("CkfPattern") << "======== Out-in trajectory building found " << theTmpTrajectories.size()
0315                                  << " valid/invalid trajectories from seed " << j << " ========\n"
0316                                  << PrintoutHelper::dumpCandidates(theTmpTrajectories);
0317           if (theTmpTrajectories.empty()) {
0318             Lock lock(theMutex);
0319             (*outputSeedStopInfos)[j].setStopReason(SeedStopReason::SEED_REGION_REBUILD);
0320             return;
0321           }
0322         }
0323 
0324         // Select the best trajectory from this seed (after seed region rebuilding, can be more than one)
0325         theTrajectoryCleaner->clean(theTmpTrajectories);
0326 
0327         LogDebug("CkfPattern") << "======== Trajectory cleaning gave the following " << theTmpTrajectories.size()
0328                                << " valid trajectories from seed " << j << " ========\n"
0329                                << PrintoutHelper::dumpCandidates(theTmpTrajectories);
0330 
0331         {
0332           Lock lock(theMutex);
0333           for (vector<Trajectory>::iterator it = theTmpTrajectories.begin(); it != theTmpTrajectories.end(); it++) {
0334             if (it->isValid()) {
0335               it->setSeedRef(collseed->refAt(j));
0336               (*outputSeedStopInfos)[j].setStopReason(SeedStopReason::NOT_STOPPED);
0337               // Store trajectory
0338               rawResult.push_back(std::move(*it));
0339               // Tell seed cleaner which hits this trajectory used.
0340               //TO BE FIXED: this cut should be configurable via cfi file
0341               if (theSeedCleaner && rawResult.back().foundHits() > 3)
0342                 theSeedCleaner->add(&rawResult.back());
0343               //if (theSeedCleaner ) theSeedCleaner->add( & (*it) );
0344             }
0345           }
0346         }
0347 
0348         theTmpTrajectories.clear();
0349 
0350         LogDebug("CkfPattern") << "rawResult trajectories found so far = " << rawResult.size();
0351 
0352         {
0353           Lock lock(theMutex);
0354           if (maxSeedsBeforeCleaning_ > 0 && rawResult.size() > maxSeedsBeforeCleaning_ + lastCleanResult) {
0355             theTrajectoryCleaner->clean(rawResult);
0356             rawResult.erase(
0357                 std::remove_if(rawResult.begin() + lastCleanResult, rawResult.end(), std::not_fn(&Trajectory::isValid)),
0358                 rawResult.end());
0359             lastCleanResult = rawResult.size();
0360           }
0361         }
0362       };
0363       // end of loop over seeds
0364 
0365 #ifdef VI_TBB
0366       tbb::parallel_for(0UL, collseed_size, 1UL, theLoop);
0367 #else
0368 #ifdef VI_OMP
0369 #pragma omp parallel for schedule(dynamic, 4)
0370 #endif
0371       for (size_t j = 0; j < collseed_size; j++) {
0372         theLoop(j);
0373       }
0374 #endif
0375       assert(ntseed == collseed_size);
0376       if (theSeedCleaner)
0377         theSeedCleaner->done();
0378 
0379         // std::cout << "VICkfPattern " << "rawResult trajectories found = " << rawResult.size() << " in " << ntseed << " seeds " << collseed_size << std::endl;
0380 
0381 #ifdef VI_REPRODUCIBLE
0382       // sort trajectory
0383       std::sort(rawResult.begin(), rawResult.end(), [](const Trajectory& a, const Trajectory& b) {
0384         return a.seedRef().key() < b.seedRef().key();
0385       });
0386       //{ return a.chiSquared()*b.ndof() < b.chiSquared()*a.ndof();});
0387 #endif
0388 
0389       // Step E: Clean the results to avoid duplicate tracks
0390       // Rejected ones just flagged as invalid.
0391       theTrajectoryCleaner->clean(rawResult);
0392 
0393       LogDebug("CkfPattern") << "======== Final cleaning of entire event found " << rawResult.size()
0394                              << " valid/invalid trajectories =======" << endl
0395                              << PrintoutHelper::dumpCandidates(rawResult);
0396 
0397       LogDebug("CkfPattern") << "removing invalid trajectories.";
0398 
0399       // Assuming here that theLoop() gives at most one Trajectory per seed
0400       for (const auto& traj : rawResult) {
0401         if (!traj.isValid()) {
0402           const auto seedIndex = traj.seedRef().key();
0403           if ((*outputSeedStopInfos)[seedIndex].stopReason() == SeedStopReason::NOT_STOPPED) {
0404             (*outputSeedStopInfos)[seedIndex].setStopReason(SeedStopReason::FINAL_CLEAN);
0405           }
0406         }
0407       }
0408 
0409       vector<Trajectory>& unsmoothedResult(rawResult);
0410       unsmoothedResult.erase(
0411           std::remove_if(unsmoothedResult.begin(), unsmoothedResult.end(), std::not_fn(&Trajectory::isValid)),
0412           unsmoothedResult.end());
0413       unsmoothedResult.shrink_to_fit();
0414       // If requested, reverse the trajectories creating a new 1-hit seed on the last measurement of the track
0415       if (reverseTrajectories) {
0416         for (auto it = unsmoothedResult.begin(), ed = unsmoothedResult.end(); it != ed; ++it) {
0417           // reverse the trajectory only if it has valid hit on the last measurement (should happen)
0418           if (it->lastMeasurement().updatedState().isValid() && it->lastMeasurement().recHit().get() != nullptr &&
0419               it->lastMeasurement().recHit()->isValid()) {
0420             // I can't use reverse in place, because I want to change the seed
0421             // 1) reverse propagation direction
0422             PropagationDirection direction = it->direction();
0423             if (direction == alongMomentum)
0424               direction = oppositeToMomentum;
0425             else if (direction == oppositeToMomentum)
0426               direction = alongMomentum;
0427             // 2) make a seed
0428             TrajectoryStateOnSurface const& initState = it->lastMeasurement().updatedState();
0429             auto initId = it->lastMeasurement().recHitR().rawId();
0430             PTrajectoryStateOnDet&& state = trajectoryStateTransform::persistentState(initState, initId);
0431             TrajectorySeed::RecHitContainer hits;
0432             hits.push_back(it->lastMeasurement().recHit()->hit()->clone());
0433             // 3) make a trajectory
0434             Trajectory trajectory{std::make_shared<TrajectorySeed>(state, std::move(hits), direction), direction};
0435             trajectory.setNLoops(it->nLoops());
0436             trajectory.setSeedRef(it->seedRef());
0437             trajectory.setStopReason(it->stopReason());
0438             // 4) push states in reversed order
0439             Trajectory::DataContainer& meas = it->measurements();
0440             trajectory.reserve(meas.size());
0441             for (auto itmeas = meas.rbegin(), endmeas = meas.rend(); itmeas != endmeas; ++itmeas) {
0442               trajectory.push(std::move(*itmeas));
0443             }
0444             // replace
0445             (*it) = std::move(trajectory);
0446           } else {
0447             edm::LogWarning("CkfPattern_InvalidLastMeasurement")
0448                 << "Last measurement of the trajectory is invalid, cannot reverse it";
0449           }
0450         }
0451       }
0452 
0453       int viTotHits = 0;
0454 
0455       if (theTrackCandidateOutput) {
0456         // Step F: Convert to TrackCandidates
0457         output->reserve(unsmoothedResult.size());
0458         Traj2TrackHits t2t(theTrajectoryBuilder->hitBuilder(), true);
0459 
0460         for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin(); it != unsmoothedResult.end(); ++it) {
0461           LogDebug("CkfPattern") << "copying " << (useSplitting ? "splitted" : "un-splitted")
0462                                  << " hits from trajectory";
0463           edm::OwnVector<TrackingRecHit> recHits;
0464           if (it->direction() != alongMomentum)
0465             LogDebug("CkfPattern") << "not along momentum... " << std::endl;
0466           t2t(*it, recHits, useSplitting);
0467 
0468           viTotHits += recHits.size();
0469 
0470           LogDebug("CkfPattern") << "getting initial state.";
0471           Trajectory trialTrajectory = (*it);
0472           std::pair<TrajectoryStateOnSurface, const GeomDet*> initState;
0473           bool failed = false;
0474 
0475           do {
0476             // Drop last hit if previous backFitter was not successful
0477             if (failed) {
0478               LogDebug("CkfPattern") << "removing last hit";
0479               trialTrajectory.pop();
0480               LogDebug("CkfPattern") << "hits remaining " << trialTrajectory.foundHits();
0481             }
0482 
0483             // Get inner state
0484             const bool doBackFit = (!doSeedingRegionRebuilding) & (!reverseTrajectories);
0485             initState = theInitialState->innerState(trialTrajectory, doBackFit);
0486 
0487             // Check if that was successful
0488             failed = (!initState.first.isValid()) || initState.second == nullptr ||
0489                      edm::isNotFinite(initState.first.globalPosition().x());
0490           } while (failed && trialTrajectory.foundHits() > 3);
0491 
0492           if (failed) {
0493             const auto seedIndex = it->seedRef().key();
0494             (*outputSeedStopInfos)[seedIndex].setStopReason(SeedStopReason::SMOOTHING_FAILED);
0495             continue;
0496           }
0497 
0498           PTrajectoryStateOnDet state;
0499           if (useSplitting && (initState.second != recHits.front().det()) && recHits.front().det()) {
0500             LogDebug("CkfPattern") << "propagating to hit front in case of splitting.";
0501             TrajectoryStateOnSurface&& propagated =
0502                 propagator.propagate(initState.first, recHits.front().det()->surface());
0503             if (!propagated.isValid())
0504               continue;
0505             state = trajectoryStateTransform::persistentState(propagated, recHits.front().rawId());
0506           } else
0507             state =
0508                 trajectoryStateTransform::persistentState(initState.first, initState.second->geographicalId().rawId());
0509           LogDebug("CkfPattern") << "pushing a TrackCandidate.";
0510           output->emplace_back(recHits, it->seed(), state, it->seedRef(), it->nLoops(), (uint8_t)it->stopReason());
0511         }
0512       }  //output trackcandidates
0513 
0514       LogTrace("CkfPattern|TrackingRegressionTest")
0515           << "========== CkfTrackCandidateMaker Info =========="
0516           << "number of Seed: " << collseed->size() << '\n'
0517           << PrintoutHelper::regressionTest(es.getData(theTrackerToken), unsmoothedResult);
0518 
0519       assert(viTotHits >= 0);  // just to use it...
0520       // std::cout << "VICkfPattern result " << output->size() << " " << viTotHits << std::endl;
0521 
0522       if (theTrajectoryOutput) {
0523         outputT->swap(unsmoothedResult);
0524       }
0525 
0526     }  // end of ((*collseed).size()>0)
0527 
0528     // method for debugging
0529     deleteAssocDebugger();
0530 
0531     // Step G: write output to file
0532     if (theTrackCandidateOutput) {
0533       e.put(std::move(output));
0534     }
0535     if (theTrajectoryOutput) {
0536       e.put(std::move(outputT));
0537     }
0538     e.put(std::move(outputSeedStopInfos));
0539   }
0540 
0541   void CkfTrackCandidateMakerBase::fillPSetDescription(edm::ParameterSetDescription& desc) {
0542     desc.add<bool>("cleanTrajectoryAfterInOut", true);
0543     desc.add<bool>("doSeedingRegionRebuilding", true);
0544     desc.add<bool>("onlyPixelHitsForSeedCleaner", false);
0545     desc.add<bool>("reverseTrajectories", false);
0546     desc.add<bool>("useHitsSplitting", true);
0547     desc.add<edm::InputTag>("MeasurementTrackerEvent", edm::InputTag("MeasurementTrackerEvent"));
0548     desc.add<edm::InputTag>("src", edm::InputTag("globalMixedSeeds"));
0549 
0550     desc.add<edm::InputTag>("clustersToSkip", edm::InputTag(""));
0551     desc.add<edm::InputTag>("phase2clustersToSkip", edm::InputTag(""));
0552 
0553     edm::ParameterSetDescription psdTB;
0554     psdTB.addNode(edm::PluginDescription<BaseCkfTrajectoryBuilderFactory>("ComponentType", true));
0555     desc.add<edm::ParameterSetDescription>("TrajectoryBuilderPSet", psdTB);
0556 
0557     edm::ParameterSetDescription psd1;
0558     psd1.add<std::string>("propagatorAlongTISE", "PropagatorWithMaterial");
0559     psd1.add<std::string>("propagatorOppositeTISE", "PropagatorWithMaterialOpposite");
0560     psd1.add<int>("numberMeasurementsForFit", 4);
0561     desc.add<edm::ParameterSetDescription>("TransientInitialStateEstimatorParameters", psd1);
0562 
0563     desc.add<int>("numHitsForSeedCleaner", 4);
0564     desc.add<std::string>("NavigationSchool", "SimpleNavigationSchool");
0565     desc.add<std::string>("RedundantSeedCleaner", "CachingSeedCleanerBySharedInput");
0566     desc.add<std::string>("TrajectoryCleaner", "TrajectoryCleanerBySharedHits");
0567     desc.add<unsigned int>("maxNSeeds", 500000);
0568     desc.add<unsigned int>("maxSeedsBeforeCleaning", 0);
0569   }
0570 }  // namespace cms