CMS 3D CMS Logo

CkfTrajectoryBuilder.cc
Go to the documentation of this file.
2 
5 
7 
11 
18 
20 
22 
28 
29 using namespace std;
30 
32  : CkfTrajectoryBuilder(conf,
33  iC,
34  BaseCkfTrajectoryBuilder::createTrajectoryFilter(
35  conf.getParameter<edm::ParameterSet>("trajectoryFilter"), iC)) {}
36 
39  std::unique_ptr<TrajectoryFilter> filter)
40  : BaseCkfTrajectoryBuilder(conf, iC, std::move(filter)) {
41  theMaxCand = conf.getParameter<int>("maxCand");
42  theLostHitPenalty = conf.getParameter<double>("lostHitPenalty");
43  theFoundHitBonus = conf.getParameter<double>("foundHitBonus");
44  theMinHitForDoubleBonus = conf.getParameter<int>("minHitForDoubleBonus");
45  theIntermediateCleaning = conf.getParameter<bool>("intermediateCleaning");
46  theAlwaysUseInvalidHits = conf.getParameter<bool>("alwaysUseInvalidHits");
47 }
48 
51  iDesc.add<int>("maxCand", 5);
52  iDesc.add<double>("lostHitPenalty", 30.);
53  iDesc.add<double>("foundHitBonus", 0.);
54  iDesc.add<int>("minHitForDoubleBonus", 8888);
55  iDesc.add<bool>("intermediateCleaning", true);
56  iDesc.add<bool>("alwaysUseInvalidHits", true);
57 
59  psdTF.addNode(edm::PluginDescription<TrajectoryFilterFactory>("ComponentType", true));
60  iDesc.add<edm::ParameterSetDescription>("trajectoryFilter", psdTF);
61 }
62 
64 
67  result.reserve(5);
69  return result;
70 }
71 
74  unsigned int tmp;
75  buildTrajectories(seed, result, tmp, nullptr);
76 }
77 
80  unsigned int& nCandPerSeed,
81  const TrajectoryFilter*) const {
82  if (theMeasurementTracker == nullptr) {
83  throw cms::Exception("LogicError")
84  << "Asking to create trajectories to an un-initialized CkfTrajectoryBuilder.\nYou have to call clone(const "
85  "MeasurementTrackerEvent *data) and then call trajectories on it instead.\n";
86  }
87 
89 
90  nCandPerSeed = limitedCandidates(seed, startingTraj, result);
91 }
92 
94  TempTrajectory& startingTraj,
95  TrajectoryContainer& result) const {
97  candidates.push_back(startingTraj);
98  std::shared_ptr<const TrajectorySeed> sharedSeed(new TrajectorySeed(seed));
99  return limitedCandidates(sharedSeed, candidates, result);
100 }
101 
102 unsigned int CkfTrajectoryBuilder::limitedCandidates(const std::shared_ptr<const TrajectorySeed>& sharedSeed,
104  TrajectoryContainer& result) const {
105  unsigned int nIter = 1;
106  unsigned int nCands = 0; // ignore startingTraj
107  unsigned int prevNewCandSize = 0;
108  TempTrajectoryContainer newCand; // = TrajectoryContainer();
109  newCand.reserve(theMaxCand);
110 
111  auto score = [&](TempTrajectory const& a) {
112  auto bonus = theFoundHitBonus;
113  bonus += a.foundHits() > theMinHitForDoubleBonus ? bonus : 0;
114  return a.chiSquared() + a.lostHits() * theLostHitPenalty - bonus * a.foundHits();
115  };
116 
117  auto trajCandLess = [&](TempTrajectory const& a, TempTrajectory const& b) { return score(a) < score(b); };
118 
119  while (!candidates.empty()) {
120  newCand.clear();
121  bool full = 0;
122  for (auto traj = candidates.begin(); traj != candidates.end(); traj++) {
123  std::vector<TM> meas;
124  findCompatibleMeasurements(*sharedSeed, *traj, meas);
125 
126  // --- method for debugging
129  return nCands;
130  // ---
131 
132  if (meas.empty()) {
133  addToResult(sharedSeed, *traj, result);
134  } else {
135  std::vector<TM>::const_iterator last;
137  last = meas.end();
138  else {
139  if (meas.front().recHit()->isValid()) {
140  last = find_if(meas.begin(), meas.end(), [](auto const& meas) { return !meas.recHit()->isValid(); });
141  } else
142  last = meas.end();
143  }
144 
145  for (auto itm = meas.begin(); itm != last; itm++) {
146  TempTrajectory newTraj = *traj;
147  updateTrajectory(newTraj, std::move(*itm));
148 
149  if (toBeContinued(newTraj)) {
150  if (full) {
151  bool better = trajCandLess(newTraj, newCand.front());
152  if (better) {
153  // replace worst
154  std::pop_heap(newCand.begin(), newCand.end(), trajCandLess);
155  newCand.back().swap(newTraj);
156  std::push_heap(newCand.begin(), newCand.end(), trajCandLess);
157  } // else? no need to add it just to remove it later!
158  } else {
159  newCand.push_back(std::move(newTraj));
160  full = (int)newCand.size() == theMaxCand;
161  if (full)
162  std::make_heap(newCand.begin(), newCand.end(), trajCandLess);
163  }
164  } else {
165  addToResult(sharedSeed, newTraj, result);
167  }
168  }
169  }
170 
171  // account only new candidates, i.e.
172  // - 1 candidate -> 1 candidate, don't increase count
173  // - 1 candidate -> 2 candidates, increase count by 1
174  nCands += newCand.size() - prevNewCandSize;
175  prevNewCandSize = newCand.size();
176 
177  assert((int)newCand.size() <= theMaxCand);
178  if (full)
179  assert((int)newCand.size() == theMaxCand);
180  } // end loop on candidates
181 
182  // no reason to sort (no sorting in Grouped version!)
185 
186  candidates.swap(newCand);
187 
188  LogDebug("CkfPattern") << result.size() << " candidates after " << nIter++ << " CKF iteration: \n"
189  << PrintoutHelper::dumpCandidates(result) << "\n " << candidates.size()
190  << " running candidates are: \n"
192  }
193  return nCands;
194 }
195 
197  auto&& predictedState = tm.predictedState();
198  auto&& hit = tm.recHit();
199  if (hit->isValid()) {
200  auto&& upState = theUpdator->update(predictedState, *hit);
201  traj.emplace(predictedState, std::move(upState), hit, tm.estimate(), tm.layer());
202  } else {
203  traj.emplace(predictedState, hit, 0, tm.layer());
204  }
205 }
206 
208  const TempTrajectory& traj,
209  std::vector<TrajectoryMeasurement>& result) const {
210  int invalidHits = 0;
211  //Use findStateAndLayers which handles the hitless seed use case
212  std::pair<TSOS, std::vector<const DetLayer*> >&& stateAndLayers = findStateAndLayers(seed, traj);
213  if (stateAndLayers.second.empty())
214  return;
215 
216  auto layerBegin = stateAndLayers.second.begin();
217  auto layerEnd = stateAndLayers.second.end();
218  LogDebug("CkfPattern") << "looping on " << stateAndLayers.second.size() << " layers.";
219  const Propagator* fwdPropagator = forwardPropagator(seed);
220  for (auto il = layerBegin; il != layerEnd; il++) {
221  LogDebug("CkfPattern") << "looping on a layer in findCompatibleMeasurements.\n last layer: " << traj.lastLayer()
222  << " current layer: " << (*il);
223 
224  TSOS stateToUse = stateAndLayers.first;
225  //Added protection before asking for the lastLayer on the trajectory
226  if UNLIKELY (!traj.empty() && (*il) == traj.lastLayer()) {
227  LogDebug("CkfPattern") << " self propagating in findCompatibleMeasurements.\n from: \n" << stateToUse;
228  //self navigation case
229  // go to a middle point first
231  GlobalPoint center(0, 0, 0);
232  stateToUse = middle.extrapolate(stateToUse, center, *fwdPropagator);
233 
234  if (!stateToUse.isValid())
235  continue;
236  LogDebug("CkfPattern") << "to: " << stateToUse;
237  }
238 
239  LayerMeasurements layerMeasurements(theMeasurementTracker->measurementTracker(), *theMeasurementTracker);
240  std::vector<TrajectoryMeasurement>&& tmp =
241  layerMeasurements.measurements((**il), stateToUse, *fwdPropagator, *theEstimator);
242 
243  if (!tmp.empty()) {
244  if (result.empty())
245  result.swap(tmp);
246  else {
247  // keep one dummy TM at the end, skip the others
248  result.insert(
249  result.end() - invalidHits, std::make_move_iterator(tmp.begin()), std::make_move_iterator(tmp.end()));
250  }
251  invalidHits++;
252  }
253  }
254 
255  // sort the final result, keep dummy measurements at the end
256  if (result.size() > 1) {
257  std::sort(result.begin(), result.end() - invalidHits, TrajMeasLessEstim());
258  }
259 
260  LogDebug("CkfPattern") << "starting from:\n"
261  << "x: " << stateAndLayers.first.globalPosition() << "\n"
262  << "p: " << stateAndLayers.first.globalMomentum() << "\n"
264 
265 #ifdef DEBUG_INVALID
266  bool afterInvalid = false;
267  for (vector<TM>::const_iterator i = result.begin(); i != result.end(); i++) {
268  if (!i->recHit().isValid())
269  afterInvalid = true;
270  if (afterInvalid && i->recHit().isValid()) {
271  edm::LogError("CkfPattern") << "CkfTrajectoryBuilder error: valid hit after invalid!";
272  }
273  }
274 #endif
275 }
void updateTrajectory(TempTrajectory &traj, TM &&tm) const
void emplace(Args &&... args)
StateAndLayers findStateAndLayers(const TrajectorySeed &seed, const TempTrajectory &traj) const
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
static std::string dumpCandidates(collection &candidates)
std::vector< Trajectory > TrajectoryContainer
TempTrajectory createStartingTrajectory(const TrajectorySeed &seed) const
unsigned int limitedCandidates(const TrajectorySeed &seed, TempTrajectory &startingTraj, TrajectoryContainer &result) const
static void clean(TempTrajectoryContainer &tracks)
TrajectoryStateOnSurface extrapolate(const FreeTrajectoryState &fts, const GlobalPoint &vtx) const
extrapolation with default (=geometrical) propagator
bool toBeContinued(TempTrajectory &traj, bool inOut=false) const
const TrajectoryStateUpdator * theUpdator
ParameterDescriptionNode * addNode(ParameterDescriptionNode const &node)
CkfTrajectoryBuilder(const edm::ParameterSet &conf, edm::ConsumesCollector iC)
Log< level::Error, false > LogError
assert(be >=bs)
static std::string dumpMeasurements(const std::vector< TrajectoryMeasurement > &v)
TrajectoryContainer trajectories(const TrajectorySeed &seed) const override
trajectories building starting from a seed
static void fillPSetDescription(edm::ParameterSetDescription &iDesc)
virtual TrajectoryStateOnSurface update(const TrajectoryStateOnSurface &, const TrackingRecHit &) const =0
const TransientTrackingRecHitBuilder * theTTRHBuilder
Definition: GenABIO.cc:168
virtual bool analyzeMeasurementsDebugger(Trajectory &traj, const std::vector< TrajectoryMeasurement > &meas, const MeasurementTrackerEvent *theMeasurementTracker, const Propagator *theForwardPropagator, const Chi2MeasurementEstimatorBase *theEstimator, const TransientTrackingRecHitBuilder *theTTRHBuilder) const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
static void fillPSetDescription(edm::ParameterSetDescription &iDesc)
const MeasurementTrackerEvent * theMeasurementTracker
std::vector< TempTrajectory > TempTrajectoryContainer
const DetLayer * lastLayer() const
Redundant method, returns the layer of lastMeasurement() .
double b
Definition: hdecay.h:120
virtual void findCompatibleMeasurements(const TrajectorySeed &seed, const TempTrajectory &traj, std::vector< TrajectoryMeasurement > &result) const
HLT enums.
void addToResult(std::shared_ptr< const TrajectorySeed > const &seed, TempTrajectory &traj, TrajectoryContainer &result, bool inOut=false) const
double a
Definition: hdecay.h:121
const Propagator * forwardPropagator(const TrajectorySeed &seed) const
#define UNLIKELY(x)
Definition: Likely.h:21
void setEvent_(const edm::Event &iEvent, const edm::EventSetup &iSetup) override
tmp
align.sh
Definition: createJobs.py:716
int theMaxCand
set Event for the internal MeasurementTracker data member
std::vector< Trajectory > TrajectoryContainer
def move(src, dest)
Definition: eostools.py:511
const Chi2MeasurementEstimatorBase * theEstimator
Definition: event.py:1
bool empty() const
True if trajectory has no measurements.
void buildTrajectories(const TrajectorySeed &, TrajectoryContainer &ret, unsigned int &nCandPerSeed, const TrajectoryFilter *) const override
#define LogDebug(id)