CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CkfTrackCandidateMakerBase.cc
Go to the documentation of this file.
1 #include <memory>
2 #include <string>
3 
10 
14 
16 
21 
26 
27 
32 
34 
37 
38 #include<algorithm>
39 #include<functional>
40 
42 
43 using namespace edm;
44 using namespace std;
45 
46 namespace cms{
47  CkfTrackCandidateMakerBase::CkfTrackCandidateMakerBase(edm::ParameterSet const& conf, edm::ConsumesCollector && iC) :
48 
49  conf_(conf),
50  theTrackCandidateOutput(true),
51  theTrajectoryOutput(false),
52  useSplitting(conf.getParameter<bool>("useHitsSplitting")),
53  doSeedingRegionRebuilding(conf.getParameter<bool>("doSeedingRegionRebuilding")),
54  cleanTrajectoryAfterInOut(conf.getParameter<bool>("cleanTrajectoryAfterInOut")),
55  reverseTrajectories(conf.existsAs<bool>("reverseTrajectories") && conf.getParameter<bool>("reverseTrajectories")),
56  theMaxNSeeds(conf.getParameter<unsigned int>("maxNSeeds")),
57  theTrajectoryBuilderName(conf.getParameter<std::string>("TrajectoryBuilder")),
58  theTrajectoryBuilder(0),
59  theTrajectoryCleanerName(conf.getParameter<std::string>("TrajectoryCleaner")),
60  theTrajectoryCleaner(0),
61  theInitialState(0),
62  theNavigationSchoolName(conf.getParameter<std::string>("NavigationSchool")),
63  theNavigationSchool(0),
64  theSeedCleaner(0),
65  maxSeedsBeforeCleaning_(0),
66  theMTELabel(iC.consumes<MeasurementTrackerEvent>(conf.getParameter<edm::InputTag>("MeasurementTrackerEvent"))),
67  skipClusters_(false)
68  {
69  //produces<TrackCandidateCollection>();
70  // old configuration totally descoped.
71  // if (!conf.exists("src"))
72  // theSeedLabel = InputTag(conf_.getParameter<std::string>("SeedProducer"),conf_.getParameter<std::string>("SeedLabel"));
73  // else
75  if ( conf.exists("maxSeedsBeforeCleaning") )
76  maxSeedsBeforeCleaning_=conf.getParameter<unsigned int>("maxSeedsBeforeCleaning");
77 
78  if (conf.existsAs<edm::InputTag>("clustersToSkip")) {
79  skipClusters_ = true;
80  maskPixels_ = iC.consumes<PixelClusterMask>(conf.getParameter<edm::InputTag>("clustersToSkip"));
81  maskStrips_ = iC.consumes<StripClusterMask>(conf.getParameter<edm::InputTag>("clustersToSkip"));
82  maskStripsLazy_ = iC.consumes<StripClusterLazyMask>(conf.getParameter<edm::InputTag>("clustersToSkip"));
83  }
84 
85  std::string cleaner = conf_.getParameter<std::string>("RedundantSeedCleaner");
86  if (cleaner == "SeedCleanerByHitPosition") {
88  } else if (cleaner == "SeedCleanerBySharedInput") {
90  } else if (cleaner == "CachingSeedCleanerByHitPosition") {
92  } else if (cleaner == "CachingSeedCleanerBySharedInput") {
93  int numHitsForSeedCleaner = conf_.existsAs<int>("numHitsForSeedCleaner") ?
94  conf_.getParameter<int>("numHitsForSeedCleaner") : 4;
95  int onlyPixelHits = conf_.existsAs<bool>("onlyPixelHitsForSeedCleaner") ?
96  conf_.getParameter<bool>("onlyPixelHitsForSeedCleaner") : false;
97  theSeedCleaner = new CachingSeedCleanerBySharedInput(numHitsForSeedCleaner,onlyPixelHits);
98  } else if (cleaner == "none") {
99  theSeedCleaner = 0;
100  } else {
101  throw cms::Exception("RedundantSeedCleaner not found", cleaner);
102  }
103 
104 
105  }
106 
107 
108  // Virtual destructor needed.
110  delete theInitialState;
111  if (theSeedCleaner) delete theSeedCleaner;
112  }
113 
115  {
116  /* no op*/
117  }
118 
120 
121  //services
123  std::string mfName = "";
124  if (conf_.exists("SimpleMagneticField"))
125  mfName = conf_.getParameter<std::string>("SimpleMagneticField");
126  es.get<IdealMagneticFieldRecord>().get(mfName,theMagField );
127  // edm::ESInputTag mfESInputTag(mfName);
128  // es.get<IdealMagneticFieldRecord>().get(mfESInputTag,theMagField );
129 
130  if (!theInitialState){
131  // constructor uses the EventSetup, it must be in the setEventSetup were it has a proper value.
132  // get nested parameter set for the TransientInitialStateEstimator
133  ParameterSet tise_params = conf_.getParameter<ParameterSet>("TransientInitialStateEstimatorParameters") ;
134  theInitialState = new TransientInitialStateEstimator( es,tise_params);
135  }
136 
138 
139  edm::ESHandle<TrajectoryCleaner> trajectoryCleanerH;
140  es.get<TrajectoryCleaner::Record>().get(theTrajectoryCleanerName, trajectoryCleanerH);
141  theTrajectoryCleaner= trajectoryCleanerH.product();
142 
143  edm::ESHandle<NavigationSchool> navigationSchoolH;
144  es.get<NavigationSchoolRecord>().get(theNavigationSchoolName, navigationSchoolH);
145  theNavigationSchool = navigationSchoolH.product();
146 
147  // set the TrajectoryBuilder
148  edm::ESHandle<TrajectoryBuilder> theTrajectoryBuilderHandle;
149  es.get<CkfComponentsRecord>().get(theTrajectoryBuilderName,theTrajectoryBuilderHandle);
150  theTrajectoryBuilder = dynamic_cast<const BaseCkfTrajectoryBuilder*>(theTrajectoryBuilderHandle.product());
151  assert(theTrajectoryBuilder);
152  }
153 
154  // Functions that gets called by framework every event
156  {
157  // getting objects from the EventSetup
158  setEventSetup( es );
159 
160  // set the correct navigation
162 
163  // propagator
164  edm::ESHandle<Propagator> thePropagator;
165  es.get<TrackingComponentsRecord>().get("AnyDirectionAnalyticalPropagator",
166  thePropagator);
167 
168  // method for Debugging
170 
171  // Step A: set Event for the TrajectoryBuilder
173  e.getByToken(theMTELabel, data);
174 
175  std::auto_ptr<BaseCkfTrajectoryBuilder> trajectoryBuilder;
176  std::auto_ptr<MeasurementTrackerEvent> dataWithMasks;
177  if (skipClusters_) {
179  e.getByToken(maskPixels_, pixelMask);
180  if (data->isStripRegional()) {
182  e.getByToken(maskStripsLazy_, stripMask);
183  dataWithMasks.reset(new MeasurementTrackerEvent(*data, *stripMask, *pixelMask));
184  } else {
186  e.getByToken(maskStrips_, stripMask);
187  dataWithMasks.reset(new MeasurementTrackerEvent(*data, *stripMask, *pixelMask));
188  }
189  //std::cout << "Trajectory builder " << conf_.getParameter<std::string>("@module_label") << " created with masks, " << (!data->isStripRegional() ? "offline": "onDemand") << std::endl;
190  trajectoryBuilder.reset(theTrajectoryBuilder->clone(&*dataWithMasks));
191  } else {
192  //std::cout << "Trajectory builder " << conf_.getParameter<std::string>("@module_label") << " created without masks, " << (!data->isStripRegional() ? "offline": "onDemand") << std::endl;
193  trajectoryBuilder.reset(theTrajectoryBuilder->clone(&*data));
194  }
195 
196  // Step B: Retrieve seeds
197 
199  e.getByToken(theSeedLabel, collseed);
200 
201  // Step C: Create empty output collection
202  std::auto_ptr<TrackCandidateCollection> output(new TrackCandidateCollection);
203  std::auto_ptr<std::vector<Trajectory> > outputT (new std::vector<Trajectory>());
204 
205  if ( (*collseed).size()>theMaxNSeeds ) {
206  LogError("TooManySeeds")<<"Exceeded maximum numeber of seeds! theMaxNSeeds="<<theMaxNSeeds<<" nSeed="<<(*collseed).size();
207  if (theTrackCandidateOutput){ e.put(output);}
208  if (theTrajectoryOutput){e.put(outputT);}
209  return;
210  }
211 
212  // Step D: Invoke the building algorithm
213  if ((*collseed).size()>0){
214 
215  unsigned int lastCleanResult=0;
216  vector<Trajectory> rawResult;
217  rawResult.reserve(collseed->size() * 4);
218 
219  if (theSeedCleaner) theSeedCleaner->init( &rawResult );
220 
221  // method for debugging
223 
224  vector<Trajectory> theTmpTrajectories;
225 
226  // Loop over seeds
227  size_t collseed_size = collseed->size();
228  for (size_t j = 0; j < collseed_size; j++){
229 
230  LogDebug("CkfPattern") << "======== Begin to look for trajectories from seed " << j << " ========"<<endl;
231 
232  // Check if seed hits already used by another track
233  if (theSeedCleaner && !theSeedCleaner->good( &((*collseed)[j])) ) {
234  LogDebug("CkfTrackCandidateMakerBase")<<" Seed cleaning kills seed "<<j;
235  continue;
236  }
237 
238  // Build trajectory from seed outwards
239  theTmpTrajectories.clear();
240  auto const & startTraj = trajectoryBuilder->buildTrajectories( (*collseed)[j], theTmpTrajectories, nullptr );
241 
242 
243  LogDebug("CkfPattern") << "======== In-out trajectory building found " << theTmpTrajectories.size()
244  << " trajectories from seed " << j << " ========"<<endl
245  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
246 
248 
249  // Select the best trajectory from this seed (declare others invalid)
250  theTrajectoryCleaner->clean(theTmpTrajectories);
251 
252  LogDebug("CkfPattern") << "======== In-out trajectory cleaning gave the following valid trajectories from seed "
253  << j << " ========"<<endl
254  << PrintoutHelper::dumpCandidates(theTmpTrajectories);
255  }
256 
257  // Optionally continue building trajectory back through
258  // seed and if possible further inwards.
259 
261  trajectoryBuilder->rebuildTrajectories(startTraj,(*collseed)[j],theTmpTrajectories);
262 
263  LogDebug("CkfPattern") << "======== Out-in trajectory building found " << theTmpTrajectories.size()
264  << " valid/invalid trajectories from seed " << j << " ========"<<endl
265  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
266  }
267 
268 
269  // Select the best trajectory from this seed (after seed region rebuilding, can be more than one)
270  theTrajectoryCleaner->clean(theTmpTrajectories);
271 
272  LogDebug("CkfPattern") << "======== Trajectory cleaning gave the following valid trajectories from seed "
273  << j << " ========"<<endl
274  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
275 
276  for(vector<Trajectory>::iterator it=theTmpTrajectories.begin();
277  it!=theTmpTrajectories.end(); it++){
278  if( it->isValid() ) {
279  it->setSeedRef(collseed->refAt(j));
280  // Store trajectory
281  rawResult.push_back(*it);
282  // Tell seed cleaner which hits this trajectory used.
283  //TO BE FIXED: this cut should be configurable via cfi file
284  if (theSeedCleaner && it->foundHits()>3) theSeedCleaner->add( & (*it) );
285  //if (theSeedCleaner ) theSeedCleaner->add( & (*it) );
286  }
287  }
288 
289  theTmpTrajectories.clear();
290 
291  LogDebug("CkfPattern") << "rawResult trajectories found so far = " << rawResult.size();
292 
293  if ( maxSeedsBeforeCleaning_ >0 && rawResult.size() > maxSeedsBeforeCleaning_+lastCleanResult) {
294  theTrajectoryCleaner->clean(rawResult);
295  rawResult.erase(std::remove_if(rawResult.begin(),rawResult.end(),
296  std::not1(std::mem_fun_ref(&Trajectory::isValid))),
297  rawResult.end());
298  lastCleanResult=rawResult.size();
299  }
300 
301  }
302  // end of loop over seeds
303 
305 
306  // Step E: Clean the results to avoid duplicate tracks
307  // Rejected ones just flagged as invalid.
308  theTrajectoryCleaner->clean(rawResult);
309 
310  LogDebug("CkfPattern") << "======== Final cleaning of entire event found " << rawResult.size()
311  << " valid/invalid trajectories ======="<<endl
312  <<PrintoutHelper::dumpCandidates(rawResult);
313 
314  LogDebug("CkfPattern") << "removing invalid trajectories.";
315 
316  vector<Trajectory> & unsmoothedResult(rawResult);
317  unsmoothedResult.erase(std::remove_if(unsmoothedResult.begin(),unsmoothedResult.end(),
318  std::not1(std::mem_fun_ref(&Trajectory::isValid))),
319  unsmoothedResult.end());
320 
321  // If requested, reverse the trajectories creating a new 1-hit seed on the last measurement of the track
322  if (reverseTrajectories) {
323  vector<Trajectory> reversed;
324  reversed.reserve(unsmoothedResult.size());
325  for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin(), ed = unsmoothedResult.end(); it != ed; ++it) {
326  // reverse the trajectory only if it has valid hit on the last measurement (should happen)
327  if (it->lastMeasurement().updatedState().isValid() &&
328  it->lastMeasurement().recHit().get() != 0 &&
329  it->lastMeasurement().recHit()->isValid()) {
330  // I can't use reverse in place, because I want to change the seed
331  // 1) reverse propagation direction
332  PropagationDirection direction = it->direction();
333  if (direction == alongMomentum) direction = oppositeToMomentum;
334  else if (direction == oppositeToMomentum) direction = alongMomentum;
335  // 2) make a seed
336  TrajectoryStateOnSurface initState = it->lastMeasurement().updatedState();
337  DetId initDetId = it->lastMeasurement().recHit()->geographicalId();
340  hits.push_back(*it->lastMeasurement().recHit()->hit());
341  boost::shared_ptr<const TrajectorySeed> seed(new TrajectorySeed(state, hits, direction));
342  // 3) make a trajectory
343  Trajectory trajectory(seed, direction);
344  trajectory.setNLoops(it->nLoops());
345  trajectory.setSeedRef(it->seedRef());
346  // 4) push states in reversed order
347  const Trajectory::DataContainer &meas = it->measurements();
348  for (Trajectory::DataContainer::const_reverse_iterator itmeas = meas.rbegin(), endmeas = meas.rend(); itmeas != endmeas; ++itmeas) {
349  trajectory.push(*itmeas);
350  }
351  reversed.push_back(trajectory);
352  } else {
353  edm::LogWarning("CkfPattern_InvalidLastMeasurement") << "Last measurement of the trajectory is invalid, cannot reverse it";
354  reversed.push_back(*it);
355  }
356  }
357  unsmoothedResult.swap(reversed);
358  }
359 
360  // for (vector<Trajectory>::const_iterator itraw = rawResult.begin();
361  // itraw != rawResult.end(); itraw++) {
362  //if((*itraw).isValid()) unsmoothedResult.push_back( *itraw);
363  //}
364 
365  //analyseCleanedTrajectories(unsmoothedResult);
366 
368  // Step F: Convert to TrackCandidates
369  output->reserve(unsmoothedResult.size());
370  for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin();
371  it != unsmoothedResult.end(); ++it) {
372 
374  //it->recHitsV(thits);
375  LogDebug("CkfPattern") << "retrieving "<<(useSplitting?"splitted":"un-splitted")<<" hits from trajectory";
376  it->recHitsV(thits,useSplitting);
378  recHits.reserve(thits.size());
379  LogDebug("CkfPattern") << "cloning hits into new collection.";
380  for (Trajectory::RecHitContainer::const_iterator hitIt = thits.begin();
381  hitIt != thits.end(); ++hitIt) {
382  recHits.push_back( (**hitIt).hit()->clone());
383  }
384 
385  LogDebug("CkfPattern") << "getting initial state.";
386  const bool doBackFit = !doSeedingRegionRebuilding && !reverseTrajectories;
387  std::pair<TrajectoryStateOnSurface, const GeomDet*> initState =
388  theInitialState->innerState( *it , doBackFit);
389 
390  // temporary protection againt invalid initial states
391  if (! initState.first.isValid() || initState.second == 0 || edm::isNotFinite(initState.first.globalPosition().x())) {
392  //cout << "invalid innerState, will not make TrackCandidate" << endl;
393  continue;
394  }
395 
396  PTrajectoryStateOnDet state;
397  if(useSplitting && (initState.second != thits.front()->det()) && thits.front()->det() ){
398  LogDebug("CkfPattern") << "propagating to hit front in case of splitting.";
399  TrajectoryStateOnSurface propagated = thePropagator->propagate(initState.first,thits.front()->det()->surface());
400  if (!propagated.isValid()) continue;
402  thits.front()->det()->geographicalId().rawId());
403  }
404  else state = trajectoryStateTransform::persistentState( initState.first,
405  initState.second->geographicalId().rawId());
406  LogDebug("CkfPattern") << "pushing a TrackCandidate.";
407  output->push_back(TrackCandidate(recHits,it->seed(),state,it->seedRef(),it->nLoops() ) );
408  }
409  }//output trackcandidates
410 
412  es.get<TrackerDigiGeometryRecord>().get(tracker);
413  LogTrace("CkfPattern|TrackingRegressionTest") << "========== CkfTrackCandidateMaker Info =========="
414  << "number of Seed: " << collseed->size()<<endl
415  <<PrintoutHelper::regressionTest(*tracker,unsmoothedResult);
416 
417 
418 
419  if (theTrajectoryOutput){ outputT->swap(unsmoothedResult);}
420 
421  }// end of ((*collseed).size()>0)
422 
423  // method for debugging
425 
426  // Step G: write output to file
427  if (theTrackCandidateOutput){ e.put(output);}
428  if (theTrajectoryOutput){e.put(outputT);}
429  }
430 
431 }
432 
#define LogDebug(id)
T getParameter(std::string const &) const
static std::string dumpCandidates(collection &candidates)
void setEventSetup(const edm::EventSetup &es)
Call this at each event until this object will come from the EventSetup as it should.
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:184
const BaseCkfTrajectoryBuilder * theTrajectoryBuilder
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
edm::EDGetTokenT< StripClusterMask > maskStrips_
std::vector< TrackCandidate > TrackCandidateCollection
void setNLoops(signed char value)
Definition: Trajectory.h:334
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
bool exists(std::string const &parameterName) const
checks if a parameter exists
virtual void printHitsDebugger(edm::Event &e)
edm::ESHandle< GeometricSearchTracker > theGeomSearchTracker
PropagationDirection
virtual void done()=0
Tells the cleaner that the seeds are finished, and so it can clear any cache it has.
virtual void add(const Trajectory *traj)=0
Informs the cleaner that a new trajectory has been made, in case the cleaner keeps a local collection...
virtual bool good(const TrajectorySeed *seed)=0
Returns true if the seed is not overlapping with another trajectory.
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
static std::string regressionTest(const TrackerGeometry &tracker, std::vector< Trajectory > &unsmoothedResult)
void push_back(D *&d)
Definition: OwnVector.h:273
edm::EDGetTokenT< PixelClusterMask > maskPixels_
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:42
bool isNotFinite(T x)
Definition: isFinite.h:10
const TrajectoryCleaner * theTrajectoryCleaner
const NavigationSchool * theNavigationSchool
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:116
virtual void produceBase(edm::Event &e, const edm::EventSetup &es)
virtual void clean(TrajectoryContainer &) const
edm::EDGetTokenT< MeasurementTrackerEvent > theMTELabel
int j
Definition: DBlmapReader.cc:9
#define LogTrace(id)
edm::EDGetTokenT< edm::View< TrajectorySeed > > theSeedLabel
tuple conf
Definition: dbtoconf.py:185
Definition: DetId.h:18
bool isValid() const
Definition: Trajectory.h:271
ConstRecHitContainer RecHitContainer
Definition: Trajectory.h:44
const T & get() const
Definition: EventSetup.h:55
T const * product() const
Definition: ESHandle.h:62
TransientInitialStateEstimator * theInitialState
void setSeedRef(const edm::RefToBase< TrajectorySeed > &seedRef)
Definition: Trajectory.h:310
void setEventSetup(const edm::EventSetup &es)
Initialize EventSetup objects at each event.
virtual void beginRunBase(edm::Run const &, edm::EventSetup const &es)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
edm::EDGetTokenT< StripClusterLazyMask > maskStripsLazy_
virtual BaseCkfTrajectoryBuilder * clone(const MeasurementTrackerEvent *data) const =0
volatile std::atomic< bool > shutdown_flag false
void push(const TrajectoryMeasurement &tm)
Definition: Trajectory.cc:35
std::pair< TrajectoryStateOnSurface, const GeomDet * > innerState(const Trajectory &traj, bool doBackFit=true) const
virtual void init(const std::vector< Trajectory > *vect)=0
Provides the cleaner a pointer to the vector where trajectories are stored, in case it does not want ...
void reserve(size_t)
Definition: OwnVector.h:267
Definition: Run.h:41
edm::ESHandle< MagneticField > theMagField