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 
27 
28 
33 
35 
38 
40 
41 #include<algorithm>
42 #include<functional>
43 
45 
46 using namespace edm;
47 using namespace std;
48 
49 namespace {
50  BaseCkfTrajectoryBuilder *createBaseCkfTrajectoryBuilder(const edm::ParameterSet& pset, edm::ConsumesCollector& iC) {
51  return BaseCkfTrajectoryBuilderFactory::get()->create(pset.getParameter<std::string>("ComponentType"), pset, iC);
52  }
53 }
54 
55 namespace cms{
56  CkfTrackCandidateMakerBase::CkfTrackCandidateMakerBase(edm::ParameterSet const& conf, edm::ConsumesCollector && iC) :
57  theTrackCandidateOutput(true),
58  theTrajectoryOutput(false),
59  useSplitting(conf.getParameter<bool>("useHitsSplitting")),
60  doSeedingRegionRebuilding(conf.getParameter<bool>("doSeedingRegionRebuilding")),
61  cleanTrajectoryAfterInOut(conf.getParameter<bool>("cleanTrajectoryAfterInOut")),
62  reverseTrajectories(conf.existsAs<bool>("reverseTrajectories") && conf.getParameter<bool>("reverseTrajectories")),
63  theMaxNSeeds(conf.getParameter<unsigned int>("maxNSeeds")),
64  theTrajectoryBuilder(createBaseCkfTrajectoryBuilder(conf.getParameter<edm::ParameterSet>("TrajectoryBuilderPSet"), iC)),
65  theTrajectoryCleanerName(conf.getParameter<std::string>("TrajectoryCleaner")),
66  theTrajectoryCleaner(0),
67  theInitialState(new TransientInitialStateEstimator(conf.getParameter<ParameterSet>("TransientInitialStateEstimatorParameters"))),
68  theMagFieldName(conf.exists("SimpleMagneticField") ? conf.getParameter<std::string>("SimpleMagneticField") : ""),
69  theNavigationSchoolName(conf.getParameter<std::string>("NavigationSchool")),
70  theNavigationSchool(0),
71  theSeedCleaner(0),
72  maxSeedsBeforeCleaning_(0),
73  theMTELabel(iC.consumes<MeasurementTrackerEvent>(conf.getParameter<edm::InputTag>("MeasurementTrackerEvent"))),
74  skipClusters_(false)
75  {
76  //produces<TrackCandidateCollection>();
77  // old configuration totally descoped.
78  // if (!conf.exists("src"))
79  // theSeedLabel = InputTag(conf_.getParameter<std::string>("SeedProducer"),conf_.getParameter<std::string>("SeedLabel"));
80  // else
82  if ( conf.exists("maxSeedsBeforeCleaning") )
83  maxSeedsBeforeCleaning_=conf.getParameter<unsigned int>("maxSeedsBeforeCleaning");
84 
85  if (conf.existsAs<edm::InputTag>("clustersToSkip")) {
86  skipClusters_ = true;
87  maskPixels_ = iC.consumes<PixelClusterMask>(conf.getParameter<edm::InputTag>("clustersToSkip"));
88  maskStrips_ = iC.consumes<StripClusterMask>(conf.getParameter<edm::InputTag>("clustersToSkip"));
89  }
90 
91  std::string cleaner = conf.getParameter<std::string>("RedundantSeedCleaner");
92  if (cleaner == "SeedCleanerByHitPosition") {
94  } else if (cleaner == "SeedCleanerBySharedInput") {
96  } else if (cleaner == "CachingSeedCleanerByHitPosition") {
98  } else if (cleaner == "CachingSeedCleanerBySharedInput") {
99  int numHitsForSeedCleaner = conf.existsAs<int>("numHitsForSeedCleaner") ?
100  conf.getParameter<int>("numHitsForSeedCleaner") : 4;
101  int onlyPixelHits = conf.existsAs<bool>("onlyPixelHitsForSeedCleaner") ?
102  conf.getParameter<bool>("onlyPixelHitsForSeedCleaner") : false;
103  theSeedCleaner = new CachingSeedCleanerBySharedInput(numHitsForSeedCleaner,onlyPixelHits);
104  } else if (cleaner == "none") {
105  theSeedCleaner = 0;
106  } else {
107  throw cms::Exception("RedundantSeedCleaner not found", cleaner);
108  }
109 
110 
111  }
112 
113 
114  // Virtual destructor needed.
116  if (theSeedCleaner) delete theSeedCleaner;
117  }
118 
120  {
121  /* no op*/
122  }
123 
125 
126  //services
129  // edm::ESInputTag mfESInputTag(mfName);
130  // es.get<IdealMagneticFieldRecord>().get(mfESInputTag,theMagField );
131 
132  edm::ESHandle<TrajectoryCleaner> trajectoryCleanerH;
133  es.get<TrajectoryCleaner::Record>().get(theTrajectoryCleanerName, trajectoryCleanerH);
134  theTrajectoryCleaner= trajectoryCleanerH.product();
135 
136  edm::ESHandle<NavigationSchool> navigationSchoolH;
137  es.get<NavigationSchoolRecord>().get(theNavigationSchoolName, navigationSchoolH);
138  theNavigationSchool = navigationSchoolH.product();
139  theTrajectoryBuilder->setNavigationSchool(theNavigationSchool);
140  }
141 
142  // Functions that gets called by framework every event
144  {
145  // getting objects from the EventSetup
146  setEventSetup( es );
147 
148  // set the correct navigation
149  // NavigationSetter setter( *theNavigationSchool);
150 
151  // propagator
152  edm::ESHandle<Propagator> thePropagator;
153  es.get<TrackingComponentsRecord>().get("AnyDirectionAnalyticalPropagator",
154  thePropagator);
155 
156  // method for Debugging
158 
159  // Step A: set Event for the TrajectoryBuilder
161  e.getByToken(theMTELabel, data);
162 
163  std::auto_ptr<MeasurementTrackerEvent> dataWithMasks;
164  if (skipClusters_) {
166  e.getByToken(maskPixels_, pixelMask);
168  e.getByToken(maskStrips_, stripMask);
169  dataWithMasks.reset(new MeasurementTrackerEvent(*data, *stripMask, *pixelMask));
170  //std::cout << "Trajectory builder " << conf_.getParameter<std::string>("@module_label") << " created with masks, " << std::endl;
171  theTrajectoryBuilder->setEvent(e, es, &*dataWithMasks);
172  } else {
173  //std::cout << "Trajectory builder " << conf_.getParameter<std::string>("@module_label") << " created without masks, " << std::endl;
174  theTrajectoryBuilder->setEvent(e, es, &*data);
175  }
176  // TISE ES must be set here due to dependence on theTrajectoryBuilder
177  theInitialState->setEventSetup( es, static_cast<TkTransientTrackingRecHitBuilder const *>(theTrajectoryBuilder->hitBuilder())->cloner() );
178 
179  // Step B: Retrieve seeds
180 
182  e.getByToken(theSeedLabel, collseed);
183 
184  // Step C: Create empty output collection
185  std::auto_ptr<TrackCandidateCollection> output(new TrackCandidateCollection);
186  std::auto_ptr<std::vector<Trajectory> > outputT (new std::vector<Trajectory>());
187 
188  if ( (*collseed).size()>theMaxNSeeds ) {
189  LogError("TooManySeeds")<<"Exceeded maximum numeber of seeds! theMaxNSeeds="<<theMaxNSeeds<<" nSeed="<<(*collseed).size();
190  if (theTrackCandidateOutput){ e.put(output);}
191  if (theTrajectoryOutput){e.put(outputT);}
192  return;
193  }
194 
195  // Step D: Invoke the building algorithm
196  if ((*collseed).size()>0){
197 
198  unsigned int lastCleanResult=0;
199  vector<Trajectory> rawResult;
200  rawResult.reserve(collseed->size() * 4);
201 
202  if (theSeedCleaner) theSeedCleaner->init( &rawResult );
203 
204  // method for debugging
206 
207  vector<Trajectory> theTmpTrajectories;
208 
209  // Loop over seeds
210  size_t collseed_size = collseed->size();
211  for (size_t j = 0; j < collseed_size; j++){
212 
213  LogDebug("CkfPattern") << "======== Begin to look for trajectories from seed " << j << " ========"<<endl;
214 
215  // Check if seed hits already used by another track
216  if (theSeedCleaner && !theSeedCleaner->good( &((*collseed)[j])) ) {
217  LogDebug("CkfTrackCandidateMakerBase")<<" Seed cleaning kills seed "<<j;
218  continue;
219  }
220 
221  // Build trajectory from seed outwards
222  theTmpTrajectories.clear();
223  auto const & startTraj = theTrajectoryBuilder->buildTrajectories( (*collseed)[j], theTmpTrajectories, nullptr );
224 
225 
226  LogDebug("CkfPattern") << "======== In-out trajectory building found " << theTmpTrajectories.size()
227  << " trajectories from seed " << j << " ========"<<endl
228  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
229 
231 
232  // Select the best trajectory from this seed (declare others invalid)
233  theTrajectoryCleaner->clean(theTmpTrajectories);
234 
235  LogDebug("CkfPattern") << "======== In-out trajectory cleaning gave the following valid trajectories from seed "
236  << j << " ========"<<endl
237  << PrintoutHelper::dumpCandidates(theTmpTrajectories);
238  }
239 
240  // Optionally continue building trajectory back through
241  // seed and if possible further inwards.
242 
244  theTrajectoryBuilder->rebuildTrajectories(startTraj,(*collseed)[j],theTmpTrajectories);
245 
246  LogDebug("CkfPattern") << "======== Out-in trajectory building found " << theTmpTrajectories.size()
247  << " valid/invalid trajectories from seed " << j << " ========"<<endl
248  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
249  }
250 
251 
252  // Select the best trajectory from this seed (after seed region rebuilding, can be more than one)
253  theTrajectoryCleaner->clean(theTmpTrajectories);
254 
255  LogDebug("CkfPattern") << "======== Trajectory cleaning gave the following valid trajectories from seed "
256  << j << " ========"<<endl
257  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
258 
259  for(vector<Trajectory>::iterator it=theTmpTrajectories.begin();
260  it!=theTmpTrajectories.end(); it++){
261  if( it->isValid() ) {
262  it->setSeedRef(collseed->refAt(j));
263  // Store trajectory
264  rawResult.push_back(std::move(*it));
265  // Tell seed cleaner which hits this trajectory used.
266  //TO BE FIXED: this cut should be configurable via cfi file
267  if (theSeedCleaner && rawResult.back().foundHits()>3) theSeedCleaner->add( &rawResult.back() );
268  //if (theSeedCleaner ) theSeedCleaner->add( & (*it) );
269  }
270  }
271 
272  theTmpTrajectories.clear();
273 
274  LogDebug("CkfPattern") << "rawResult trajectories found so far = " << rawResult.size();
275 
276  if ( maxSeedsBeforeCleaning_ >0 && rawResult.size() > maxSeedsBeforeCleaning_+lastCleanResult) {
277  theTrajectoryCleaner->clean(rawResult);
278  rawResult.erase(std::remove_if(rawResult.begin()+lastCleanResult,rawResult.end(),
279  std::not1(std::mem_fun_ref(&Trajectory::isValid))),
280  rawResult.end());
281  lastCleanResult=rawResult.size();
282  }
283 
284  }
285  // end of loop over seeds
286 
288 
289  // std::cout << "VICkfPattern " << "rawResult trajectories found = " << rawResult.size() << std::endl;
290 
291 
292  // Step E: Clean the results to avoid duplicate tracks
293  // Rejected ones just flagged as invalid.
294  theTrajectoryCleaner->clean(rawResult);
295 
296  LogDebug("CkfPattern") << "======== Final cleaning of entire event found " << rawResult.size()
297  << " valid/invalid trajectories ======="<<endl
298  <<PrintoutHelper::dumpCandidates(rawResult);
299 
300  LogDebug("CkfPattern") << "removing invalid trajectories.";
301 
302  vector<Trajectory> & unsmoothedResult(rawResult);
303  unsmoothedResult.erase(std::remove_if(unsmoothedResult.begin(),unsmoothedResult.end(),
304  std::not1(std::mem_fun_ref(&Trajectory::isValid))),
305  unsmoothedResult.end());
306 
307  // If requested, reverse the trajectories creating a new 1-hit seed on the last measurement of the track
308  if (reverseTrajectories) {
309  for (auto it = unsmoothedResult.begin(), ed = unsmoothedResult.end(); it != ed; ++it) {
310  // reverse the trajectory only if it has valid hit on the last measurement (should happen)
311  if (it->lastMeasurement().updatedState().isValid() &&
312  it->lastMeasurement().recHit().get() != 0 &&
313  it->lastMeasurement().recHit()->isValid()) {
314  // I can't use reverse in place, because I want to change the seed
315  // 1) reverse propagation direction
316  PropagationDirection direction = it->direction();
317  if (direction == alongMomentum) direction = oppositeToMomentum;
318  else if (direction == oppositeToMomentum) direction = alongMomentum;
319  // 2) make a seed
320  TrajectoryStateOnSurface const & initState = it->lastMeasurement().updatedState();
321  auto initId = it->lastMeasurement().recHitR().rawId();
324  hits.push_back(it->lastMeasurement().recHit()->hit()->clone());
325  boost::shared_ptr<const TrajectorySeed> seed(new TrajectorySeed(state, std::move(hits), direction));
326  // 3) make a trajectory
327  Trajectory trajectory(seed, direction);
328  trajectory.setNLoops(it->nLoops());
329  trajectory.setSeedRef(it->seedRef());
330  // 4) push states in reversed order
331  Trajectory::DataContainer &meas = it->measurements();
332  for (auto itmeas = meas.rbegin(), endmeas = meas.rend(); itmeas != endmeas; ++itmeas) {
333  trajectory.push(std::move(*itmeas));
334  }
335  // replace
336  (*it)= std::move(trajectory);
337  } else {
338  edm::LogWarning("CkfPattern_InvalidLastMeasurement") << "Last measurement of the trajectory is invalid, cannot reverse it";
339  }
340  }
341  }
342 
343 
344  int viTotHits=0;
345 
347  // Step F: Convert to TrackCandidates
348  output->reserve(unsmoothedResult.size());
349  Traj2TrackHits t2t(theTrajectoryBuilder->hitBuilder(),true);
350 
351  for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin();
352  it != unsmoothedResult.end(); ++it) {
353 
354  LogDebug("CkfPattern") << "copying "<<(useSplitting?"splitted":"un-splitted")<<" hits from trajectory";
356  if(it->direction() != alongMomentum) LogDebug("CkfPattern") << "not along momentum... " << std::endl;
357  t2t(*it,recHits,useSplitting);
358 
359  viTotHits+=recHits.size();
360 
361  LogDebug("CkfPattern") << "getting initial state.";
362  const bool doBackFit = (!doSeedingRegionRebuilding) & (!reverseTrajectories);
363  std::pair<TrajectoryStateOnSurface, const GeomDet*> && initState = theInitialState->innerState( *it , doBackFit);
364 
365  // temporary protection againt invalid initial states
366  if ( !initState.first.isValid() || initState.second == nullptr || edm::isNotFinite(initState.first.globalPosition().x())) {
367  //cout << "invalid innerState, will not make TrackCandidate" << endl;
368  continue;
369  }
370 
371  PTrajectoryStateOnDet state;
372  if(useSplitting && (initState.second != recHits.front().det()) && recHits.front().det() ){
373  LogDebug("CkfPattern") << "propagating to hit front in case of splitting.";
374  TrajectoryStateOnSurface && propagated = thePropagator->propagate(initState.first,recHits.front().det()->surface());
375  if (!propagated.isValid()) continue;
377  recHits.front().rawId());
378  }
379  else state = trajectoryStateTransform::persistentState( initState.first,
380  initState.second->geographicalId().rawId());
381  LogDebug("CkfPattern") << "pushing a TrackCandidate.";
382  output->emplace_back(recHits,it->seed(),state,it->seedRef(),it->nLoops());
383  }
384  }//output trackcandidates
385 
387  es.get<TrackerDigiGeometryRecord>().get(tracker);
388  LogTrace("CkfPattern|TrackingRegressionTest") << "========== CkfTrackCandidateMaker Info =========="
389  << "number of Seed: " << collseed->size()<<endl
390  <<PrintoutHelper::regressionTest(*tracker,unsmoothedResult);
391 
392  assert(viTotHits>=0); // just to use it...
393  // std::cout << "VICkfPattern result " << output->size() << " " << viTotHits << std::endl;
394 
395  if (theTrajectoryOutput){ outputT->swap(unsmoothedResult);}
396 
397  }// end of ((*collseed).size()>0)
398 
399  // method for debugging
401 
402  // Step G: write output to file
403  if (theTrackCandidateOutput){ e.put(output);}
404  if (theTrajectoryOutput){e.put(outputT);}
405  }
406 
407 }
408 
#define LogDebug(id)
T getParameter(std::string const &) const
static std::string dumpCandidates(collection &candidates)
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:184
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
edm::EDGetTokenT< StripClusterMask > maskStrips_
std::vector< TrackCandidate > TrackCandidateCollection
std::unique_ptr< TransientInitialStateEstimator > theInitialState
size_type size() const
Definition: OwnVector.h:248
void setNLoops(signed char value)
Definition: Trajectory.h:332
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.
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
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.
static std::string regressionTest(const TrackerGeometry &tracker, std::vector< Trajectory > &unsmoothedResult)
void push_back(D *&d)
Definition: OwnVector.h:274
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
const GeomDet * det() const
virtual void produceBase(edm::Event &e, const edm::EventSetup &es)
std::unique_ptr< BaseCkfTrajectoryBuilder > theTrajectoryBuilder
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
bool isValid() const
Definition: Trajectory.h:269
const T & get() const
Definition: EventSetup.h:55
T const * product() const
Definition: ESHandle.h:62
void setSeedRef(const edm::RefToBase< TrajectorySeed > &seedRef)
Definition: Trajectory.h:308
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
volatile std::atomic< bool > shutdown_flag false
void push(const TrajectoryMeasurement &tm)
Definition: Trajectory.cc:30
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 ...
reference front()
Definition: OwnVector.h:349
id_type rawId() const
T get(const Candidate &c)
Definition: component.h:55
Definition: Run.h:41
edm::ESHandle< MagneticField > theMagField