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