00001 #include <memory>
00002 #include <string>
00003
00004 #include "DataFormats/Common/interface/Handle.h"
00005 #include "FWCore/Framework/interface/ESHandle.h"
00006 #include "FWCore/Framework/interface/EventSetup.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "FWCore/Utilities/interface/isFinite.h"
00009
00010 #include "DataFormats/Common/interface/OwnVector.h"
00011 #include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
00012 #include "DataFormats/Common/interface/View.h"
00013
00014 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00015
00016 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00017 #include "TrackingTools/TrajectoryCleaning/interface/TrajectoryCleanerBySharedHits.h"
00018 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00019 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00020
00021 #include "RecoTracker/CkfPattern/interface/CkfTrackCandidateMakerBase.h"
00022 #include "RecoTracker/CkfPattern/interface/TransientInitialStateEstimator.h"
00023 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00024 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00025
00026
00027 #include "RecoTracker/CkfPattern/interface/SeedCleanerByHitPosition.h"
00028 #include "RecoTracker/CkfPattern/interface/CachingSeedCleanerByHitPosition.h"
00029 #include "RecoTracker/CkfPattern/interface/SeedCleanerBySharedInput.h"
00030 #include "RecoTracker/CkfPattern/interface/CachingSeedCleanerBySharedInput.h"
00031
00032 #include "RecoTracker/Record/interface/NavigationSchoolRecord.h"
00033 #include "TrackingTools/DetLayers/interface/NavigationSchool.h"
00034
00035 #include<algorithm>
00036 #include<functional>
00037
00038 #include "RecoTracker/CkfPattern/interface/PrintoutHelper.h"
00039
00040 using namespace edm;
00041 using namespace std;
00042
00043 namespace cms{
00044 CkfTrackCandidateMakerBase::CkfTrackCandidateMakerBase(edm::ParameterSet const& conf) :
00045
00046 conf_(conf),
00047 theTrackCandidateOutput(true),
00048 theTrajectoryOutput(false),
00049 useSplitting(conf.getParameter<bool>("useHitsSplitting")),
00050 doSeedingRegionRebuilding(conf.getParameter<bool>("doSeedingRegionRebuilding")),
00051 cleanTrajectoryAfterInOut(conf.getParameter<bool>("cleanTrajectoryAfterInOut")),
00052 reverseTrajectories(conf.existsAs<bool>("reverseTrajectories") && conf.getParameter<bool>("reverseTrajectories")),
00053 theMaxNSeeds(conf.getParameter<unsigned int>("maxNSeeds")),
00054 theTrajectoryBuilderName(conf.getParameter<std::string>("TrajectoryBuilder")),
00055 theTrajectoryBuilder(0),
00056 theTrajectoryCleanerName(conf.getParameter<std::string>("TrajectoryCleaner")),
00057 theTrajectoryCleaner(0),
00058 theInitialState(0),
00059 theNavigationSchoolName(conf.getParameter<std::string>("NavigationSchool")),
00060 theNavigationSchool(0),
00061 theSeedCleaner(0),
00062 maxSeedsBeforeCleaning_(0)
00063 {
00064
00065
00066
00067
00068
00069 theSeedLabel= conf.getParameter<edm::InputTag>("src");
00070 if ( conf.exists("maxSeedsBeforeCleaning") )
00071 maxSeedsBeforeCleaning_=conf.getParameter<unsigned int>("maxSeedsBeforeCleaning");
00072
00073 std::string cleaner = conf_.getParameter<std::string>("RedundantSeedCleaner");
00074 if (cleaner == "SeedCleanerByHitPosition") {
00075 theSeedCleaner = new SeedCleanerByHitPosition();
00076 } else if (cleaner == "SeedCleanerBySharedInput") {
00077 theSeedCleaner = new SeedCleanerBySharedInput();
00078 } else if (cleaner == "CachingSeedCleanerByHitPosition") {
00079 theSeedCleaner = new CachingSeedCleanerByHitPosition();
00080 } else if (cleaner == "CachingSeedCleanerBySharedInput") {
00081 int numHitsForSeedCleaner = conf_.existsAs<int>("numHitsForSeedCleaner") ?
00082 conf_.getParameter<int>("numHitsForSeedCleaner") : 4;
00083 int onlyPixelHits = conf_.existsAs<bool>("onlyPixelHitsForSeedCleaner") ?
00084 conf_.getParameter<bool>("onlyPixelHitsForSeedCleaner") : false;
00085 theSeedCleaner = new CachingSeedCleanerBySharedInput(numHitsForSeedCleaner,onlyPixelHits);
00086 } else if (cleaner == "none") {
00087 theSeedCleaner = 0;
00088 } else {
00089 throw cms::Exception("RedundantSeedCleaner not found", cleaner);
00090 }
00091
00092
00093 }
00094
00095
00096
00097 CkfTrackCandidateMakerBase::~CkfTrackCandidateMakerBase() {
00098 delete theInitialState;
00099 if (theSeedCleaner) delete theSeedCleaner;
00100 }
00101
00102 void CkfTrackCandidateMakerBase::beginRunBase (edm::Run & r, EventSetup const & es)
00103 {
00104
00105 }
00106
00107 void CkfTrackCandidateMakerBase::setEventSetup( const edm::EventSetup& es ) {
00108
00109
00110 es.get<TrackerRecoGeometryRecord>().get( theGeomSearchTracker );
00111 es.get<IdealMagneticFieldRecord>().get( theMagField );
00112
00113 if (!theInitialState){
00114
00115
00116 ParameterSet tise_params = conf_.getParameter<ParameterSet>("TransientInitialStateEstimatorParameters") ;
00117 theInitialState = new TransientInitialStateEstimator( es,tise_params);
00118 }
00119
00120 theInitialState->setEventSetup( es );
00121
00122 edm::ESHandle<TrajectoryCleaner> trajectoryCleanerH;
00123 es.get<TrajectoryCleaner::Record>().get(theTrajectoryCleanerName, trajectoryCleanerH);
00124 theTrajectoryCleaner= trajectoryCleanerH.product();
00125
00126 edm::ESHandle<NavigationSchool> navigationSchoolH;
00127 es.get<NavigationSchoolRecord>().get(theNavigationSchoolName, navigationSchoolH);
00128 theNavigationSchool = navigationSchoolH.product();
00129
00130
00131 edm::ESHandle<TrajectoryBuilder> theTrajectoryBuilderHandle;
00132 es.get<CkfComponentsRecord>().get(theTrajectoryBuilderName,theTrajectoryBuilderHandle);
00133 theTrajectoryBuilder = dynamic_cast<const BaseCkfTrajectoryBuilder*>(theTrajectoryBuilderHandle.product());
00134 assert(theTrajectoryBuilder);
00135 }
00136
00137
00138 void CkfTrackCandidateMakerBase::produceBase(edm::Event& e, const edm::EventSetup& es)
00139 {
00140
00141 setEventSetup( es );
00142
00143
00144 NavigationSetter setter( *theNavigationSchool);
00145
00146
00147 edm::ESHandle<Propagator> thePropagator;
00148 es.get<TrackingComponentsRecord>().get("AnyDirectionAnalyticalPropagator",
00149 thePropagator);
00150
00151
00152 printHitsDebugger(e);
00153
00154
00155 theTrajectoryBuilder->setEvent(e);
00156
00157
00158
00159 edm::Handle<View<TrajectorySeed> > collseed;
00160 e.getByLabel(theSeedLabel, collseed);
00161
00162
00163 std::auto_ptr<TrackCandidateCollection> output(new TrackCandidateCollection);
00164 std::auto_ptr<std::vector<Trajectory> > outputT (new std::vector<Trajectory>());
00165
00166 if ( (*collseed).size()>theMaxNSeeds ) {
00167 LogError("TooManySeeds")<<"Exceeded maximum numeber of seeds! theMaxNSeeds="<<theMaxNSeeds<<" nSeed="<<(*collseed).size();
00168 if (theTrackCandidateOutput){ e.put(output);}
00169 if (theTrajectoryOutput){e.put(outputT);}
00170 theTrajectoryBuilder->unset();
00171 return;
00172 }
00173
00174
00175 if ((*collseed).size()>0){
00176
00177 unsigned int lastCleanResult=0;
00178 vector<Trajectory> rawResult;
00179 rawResult.reserve(collseed->size() * 4);
00180
00181 if (theSeedCleaner) theSeedCleaner->init( &rawResult );
00182
00183
00184 countSeedsDebugger();
00185
00186 vector<Trajectory> theTmpTrajectories;
00187
00188
00189 size_t collseed_size = collseed->size();
00190 for (size_t j = 0; j < collseed_size; j++){
00191
00192
00193 if (theSeedCleaner && !theSeedCleaner->good( &((*collseed)[j])) ) {
00194 LogDebug("CkfTrackCandidateMakerBase")<<" Seed cleaning kills seed "<<j;
00195 continue;
00196 }
00197
00198
00199 theTmpTrajectories.clear();
00200 auto const & startTraj = theTrajectoryBuilder->buildTrajectories( (*collseed)[j], theTmpTrajectories, nullptr );
00201
00202
00203 LogDebug("CkfPattern") << "======== In-out trajectory building found " << theTmpTrajectories.size()
00204 << " trajectories from seed " << j << " ========"<<endl
00205 <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
00206
00207 if (cleanTrajectoryAfterInOut) {
00208
00209
00210 theTrajectoryCleaner->clean(theTmpTrajectories);
00211
00212 LogDebug("CkfPattern") << "======== In-out trajectory cleaning gave the following valid trajectories from seed "
00213 << j << " ========"<<endl
00214 << PrintoutHelper::dumpCandidates(theTmpTrajectories);
00215 }
00216
00217
00218
00219
00220 if (doSeedingRegionRebuilding) {
00221 theTrajectoryBuilder->rebuildTrajectories(startTraj,(*collseed)[j],theTmpTrajectories);
00222
00223 LogDebug("CkfPattern") << "======== Out-in trajectory building found " << theTmpTrajectories.size()
00224 << " valid/invalid trajectories from seed " << j << " ========"<<endl
00225 <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
00226 }
00227
00228
00229
00230 theTrajectoryCleaner->clean(theTmpTrajectories);
00231
00232 LogDebug("CkfPattern") << "======== Trajectory cleaning gave the following valid trajectories from seed "
00233 << j << " ========"<<endl
00234 <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
00235
00236 for(vector<Trajectory>::iterator it=theTmpTrajectories.begin();
00237 it!=theTmpTrajectories.end(); it++){
00238 if( it->isValid() ) {
00239 it->setSeedRef(collseed->refAt(j));
00240
00241 rawResult.push_back(*it);
00242
00243
00244 if (theSeedCleaner && it->foundHits()>3) theSeedCleaner->add( & (*it) );
00245
00246 }
00247 }
00248
00249 theTmpTrajectories.clear();
00250
00251 LogDebug("CkfPattern") << "rawResult trajectories found so far = " << rawResult.size();
00252
00253 if ( maxSeedsBeforeCleaning_ >0 && rawResult.size() > maxSeedsBeforeCleaning_+lastCleanResult) {
00254 theTrajectoryCleaner->clean(rawResult);
00255 rawResult.erase(std::remove_if(rawResult.begin(),rawResult.end(),
00256 std::not1(std::mem_fun_ref(&Trajectory::isValid))),
00257 rawResult.end());
00258 lastCleanResult=rawResult.size();
00259 }
00260
00261 }
00262
00263
00264 if (theSeedCleaner) theSeedCleaner->done();
00265
00266
00267
00268 theTrajectoryCleaner->clean(rawResult);
00269
00270 LogDebug("CkfPattern") << "======== Final cleaning of entire event found " << rawResult.size()
00271 << " valid/invalid trajectories ======="<<endl
00272 <<PrintoutHelper::dumpCandidates(rawResult);
00273
00274 LogDebug("CkfPattern") << "removing invalid trajectories.";
00275
00276 vector<Trajectory> & unsmoothedResult(rawResult);
00277 unsmoothedResult.erase(std::remove_if(unsmoothedResult.begin(),unsmoothedResult.end(),
00278 std::not1(std::mem_fun_ref(&Trajectory::isValid))),
00279 unsmoothedResult.end());
00280
00281
00282 if (reverseTrajectories) {
00283 vector<Trajectory> reversed;
00284 reversed.reserve(unsmoothedResult.size());
00285 for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin(), ed = unsmoothedResult.end(); it != ed; ++it) {
00286
00287 if (it->lastMeasurement().updatedState().isValid() &&
00288 it->lastMeasurement().recHit().get() != 0 &&
00289 it->lastMeasurement().recHit()->isValid()) {
00290
00291
00292 PropagationDirection direction = it->direction();
00293 if (direction == alongMomentum) direction = oppositeToMomentum;
00294 else if (direction == oppositeToMomentum) direction = alongMomentum;
00295
00296 TrajectoryStateOnSurface initState = it->lastMeasurement().updatedState();
00297 DetId initDetId = it->lastMeasurement().recHit()->geographicalId();
00298 PTrajectoryStateOnDet state = trajectoryStateTransform::persistentState( initState, initDetId.rawId());
00299 TrajectorySeed::recHitContainer hits;
00300 hits.push_back(*it->lastMeasurement().recHit()->hit());
00301 boost::shared_ptr<const TrajectorySeed> seed(new TrajectorySeed(state, hits, direction));
00302
00303 Trajectory trajectory(seed, direction);
00304 trajectory.setNLoops(it->nLoops());
00305 trajectory.setSeedRef(it->seedRef());
00306
00307 const Trajectory::DataContainer &meas = it->measurements();
00308 for (Trajectory::DataContainer::const_reverse_iterator itmeas = meas.rbegin(), endmeas = meas.rend(); itmeas != endmeas; ++itmeas) {
00309 trajectory.push(*itmeas);
00310 }
00311 reversed.push_back(trajectory);
00312 } else {
00313 edm::LogWarning("CkfPattern_InvalidLastMeasurement") << "Last measurement of the trajectory is invalid, cannot reverse it";
00314 reversed.push_back(*it);
00315 }
00316 }
00317 unsmoothedResult.swap(reversed);
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327 if (theTrackCandidateOutput){
00328
00329 output->reserve(unsmoothedResult.size());
00330 for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin();
00331 it != unsmoothedResult.end(); ++it) {
00332
00333 Trajectory::RecHitContainer thits;
00334
00335 LogDebug("CkfPattern") << "retrieving "<<(useSplitting?"splitted":"un-splitted")<<" hits from trajectory";
00336 it->recHitsV(thits,useSplitting);
00337 OwnVector<TrackingRecHit> recHits;
00338 recHits.reserve(thits.size());
00339 LogDebug("CkfPattern") << "cloning hits into new collection.";
00340 for (Trajectory::RecHitContainer::const_iterator hitIt = thits.begin();
00341 hitIt != thits.end(); ++hitIt) {
00342 recHits.push_back( (**hitIt).hit()->clone());
00343 }
00344
00345 LogDebug("CkfPattern") << "getting initial state.";
00346 const bool doBackFit = !doSeedingRegionRebuilding && !reverseTrajectories;
00347 std::pair<TrajectoryStateOnSurface, const GeomDet*> initState =
00348 theInitialState->innerState( *it , doBackFit);
00349
00350
00351 if (! initState.first.isValid() || initState.second == 0 || edm::isNotFinite(initState.first.globalPosition().x())) {
00352
00353 continue;
00354 }
00355
00356 PTrajectoryStateOnDet state;
00357 if(useSplitting && (initState.second != thits.front()->det()) && thits.front()->det() ){
00358 LogDebug("CkfPattern") << "propagating to hit front in case of splitting.";
00359 TrajectoryStateOnSurface propagated = thePropagator->propagate(initState.first,thits.front()->det()->surface());
00360 if (!propagated.isValid()) continue;
00361 state = trajectoryStateTransform::persistentState(propagated,
00362 thits.front()->det()->geographicalId().rawId());
00363 }
00364 else state = trajectoryStateTransform::persistentState( initState.first,
00365 initState.second->geographicalId().rawId());
00366 LogDebug("CkfPattern") << "pushing a TrackCandidate.";
00367 output->push_back(TrackCandidate(recHits,it->seed(),state,it->seedRef(),it->nLoops() ) );
00368 }
00369 }
00370
00371 edm::ESHandle<TrackerGeometry> tracker;
00372 es.get<TrackerDigiGeometryRecord>().get(tracker);
00373 LogTrace("CkfPattern|TrackingRegressionTest") << "========== CkfTrackCandidateMaker Info =========="
00374 << "number of Seed: " << collseed->size()<<endl
00375 <<PrintoutHelper::regressionTest(*tracker,unsmoothedResult);
00376
00377
00378
00379 if (theTrajectoryOutput){ outputT->swap(unsmoothedResult);}
00380
00381 }
00382
00383
00384 deleteAssocDebugger();
00385
00386
00387 if (theTrackCandidateOutput){ e.put(output);}
00388 if (theTrajectoryOutput){e.put(outputT);}
00389
00390
00391 theTrajectoryBuilder->unset();
00392 }
00393
00394 }
00395