CMS 3D CMS Logo

CosmicMuonSmoother.cc
Go to the documentation of this file.
1 
14 
23 
25 
26 using namespace edm;
27 using namespace std;
28 
29 //
30 // constructor
31 //
33  theUpdator = new KFUpdator;
36  thePropagatorAlongName = par.getParameter<string>("PropagatorAlong");
37  thePropagatorOppositeName = par.getParameter<string>("PropagatorOpposite");
38  theErrorRescaling = par.getParameter<double>("RescalingFactor");
39 
40  category_ = "Muon|RecoMuon|CosmicMuon|CosmicMuonSmoother";
41 }
42 
43 //
44 // destructor
45 //
47  if (theUpdator)
48  delete theUpdator;
49  if (theUtilities)
50  delete theUtilities;
51  if (theEstimator)
52  delete theEstimator;
53 }
54 
55 //
56 // fit and smooth trajectory
57 //
59  std::vector<Trajectory>&& fitted = fit(t);
60  if (fitted.empty())
61  return Trajectory();
62  std::vector<Trajectory>&& smoothed = smooth(fitted);
63  return smoothed.empty() ? Trajectory() : smoothed.front();
64 }
65 
66 //
67 // fit and smooth trajectory
68 //
69 std::vector<Trajectory> CosmicMuonSmoother::trajectories(const TrajectorySeed& seed,
71  const TrajectoryStateOnSurface& firstPredTsos) const {
72  if (hits.empty() || !firstPredTsos.isValid())
73  return vector<Trajectory>();
74 
75  LogTrace(category_) << "trajectory begin (seed hits tsos)";
76 
77  TrajectoryStateOnSurface firstTsos = firstPredTsos;
79 
80  LogTrace(category_) << "first TSOS: " << firstTsos;
81 
82  vector<Trajectory> fitted = fit(seed, hits, firstTsos);
83  LogTrace(category_) << "fitted: " << fitted.size();
84  vector<Trajectory> smoothed = smooth(fitted);
85  LogTrace(category_) << "smoothed: " << smoothed.size();
86 
87  return smoothed;
88 }
89 
90 //
91 // fit trajectory
92 //
93 vector<Trajectory> CosmicMuonSmoother::fit(const Trajectory& t) const {
94  if (t.empty())
95  return vector<Trajectory>();
96 
97  LogTrace(category_) << "fit begin (trajectory) ";
98 
100  if (!firstTsos.isValid()) {
101  LogTrace(category_) << "Error: firstTsos invalid. ";
102  return vector<Trajectory>();
103  }
104 
105  LogTrace(category_) << "firstTsos: " << firstTsos;
106 
107  ConstRecHitContainer hits = t.recHits();
108  LogTrace(category_) << "hits: " << hits.size();
109  LogTrace(category_) << "hit front" << hits.front()->globalPosition() << " hit back" << hits.back()->globalPosition();
110 
111  sortHitsAlongMom(hits, firstTsos);
112 
113  LogTrace(category_) << "after sorting hit front" << hits.front()->globalPosition() << " hit back"
114  << hits.back()->globalPosition();
115 
116  return fit(t.seed(), hits, firstTsos);
117 }
118 
119 //
120 // fit trajectory
121 //
122 vector<Trajectory> CosmicMuonSmoother::fit(const TrajectorySeed& seed,
123  const ConstRecHitContainer& hits,
124  const TrajectoryStateOnSurface& firstPredTsos) const {
125  LogTrace(category_) << "fit begin (seed, hit, tsos).";
126 
127  if (hits.empty()) {
128  LogTrace(category_) << "Error: empty hits container.";
129  return vector<Trajectory>();
130  }
131 
132  Trajectory myTraj(seed, alongMomentum);
133 
134  TrajectoryStateOnSurface predTsos(firstPredTsos);
135  LogTrace(category_) << "first pred TSOS: " << predTsos;
136 
137  if (!predTsos.isValid()) {
138  LogTrace(category_) << "Error: firstTsos invalid.";
139  return vector<Trajectory>();
140  }
141  TrajectoryStateOnSurface currTsos;
142 
143  if (hits.front()->isValid()) {
144  // FIXME FIXME CLONE !!!
145  // TrackingRecHit::RecHitPointer preciseHit = hits.front()->clone(predTsos);
146  const auto& preciseHit = hits.front();
147 
148  LogTrace(category_) << "first hit is at det " << hits.front()->det()->surface().position();
149 
150  currTsos = theUpdator->update(predTsos, *preciseHit);
151  if (!currTsos.isValid()) {
152  edm::LogWarning(category_) << "an updated state is not valid. killing the trajectory.";
153  return vector<Trajectory>();
154  }
156  predTsos, currTsos, hits.front(), theEstimator->estimate(predTsos, *hits.front()).second));
157  if (currTsos.isValid())
158  LogTrace(category_) << "first curr TSOS: " << currTsos;
159 
160  } else {
161  currTsos = predTsos;
162  myTraj.push(TrajectoryMeasurement(predTsos, hits.front()));
163  }
164  //const TransientTrackingRecHit& firsthit = *hits.front();
165 
166  for (ConstRecHitContainer::const_iterator ihit = hits.begin() + 1; ihit != hits.end(); ++ihit) {
167  if (!(**ihit).isValid()) {
168  LogTrace(category_) << "Error: invalid hit.";
169  continue;
170  }
171  if (currTsos.isValid() && currTsos.globalMomentum().mag2() > 1e-18f) {
172  LogTrace(category_) << "current pos " << currTsos.globalPosition() << "mom " << currTsos.globalMomentum();
173  } else {
174  LogTrace(category_) << "current state invalid or momentum is too low";
175  //logically, there's no way out: can't expect a valid result out of an invalid state
176  LogTrace(category_) << "Input state is not valid. This loop over hits is doomed: breaking out";
177  break;
178  }
179 
180  predTsos = propagatorAlong()->propagate(currTsos, (**ihit).det()->surface());
181  LogTrace(category_) << "predicted state propagate directly " << predTsos.isValid();
182 
183  if (!predTsos.isValid()) {
184  LogTrace(category_) << "step-propagating from " << currTsos.globalPosition()
185  << " to position: " << (*ihit)->globalPosition();
186  predTsos = theUtilities->stepPropagate(currTsos, (*ihit), *propagatorAlong());
187  }
188  if (!predTsos.isValid() && (fabs(theService->magneticField()->inTesla(GlobalPoint(0, 0, 0)).z()) < 0.01) &&
189  (theService->propagator("StraightLinePropagator").isValid())) {
190  LogTrace(category_) << "straight-line propagating from " << currTsos.globalPosition()
191  << " to position: " << (*ihit)->globalPosition();
192  predTsos = theService->propagator("StraightLinePropagator")->propagate(currTsos, (**ihit).det()->surface());
193  }
194  if (predTsos.isValid()) {
195  LogTrace(category_) << "predicted pos " << predTsos.globalPosition() << "mom " << predTsos.globalMomentum();
196  } else {
197  LogTrace(category_) << "predicted state invalid";
198  }
199  if (!predTsos.isValid() || predTsos.globalPosition().mag2() > 1.e12) {
200  LogTrace(category_) << "Error: predTsos is still invalid or too far in forward fit.";
201  // return vector<Trajectory>();
202  continue;
203  } else if ((**ihit).isValid()) {
204  // FIXME FIXME CLONE !!!
205  // update (FIXME!)
206  // TransientTrackingRecHit::RecHitPointer preciseHit = (**ihit).clone(predTsos);
207  const auto& preciseHit = *ihit;
208 
209  if (!preciseHit->isValid()) {
210  currTsos = predTsos;
211  myTraj.push(TrajectoryMeasurement(predTsos, *ihit));
212  } else {
213  currTsos = theUpdator->update(predTsos, *preciseHit);
214  if (!currTsos.isValid()) {
215  edm::LogWarning(category_) << "an updated state is not valid. killing the trajectory.";
216  return vector<Trajectory>();
217  }
219  predTsos, currTsos, preciseHit, theEstimator->estimate(predTsos, *preciseHit).second));
220  }
221  } else {
222  currTsos = predTsos;
223  myTraj.push(TrajectoryMeasurement(predTsos, *ihit));
224  }
225  }
226 
227  std::vector<TrajectoryMeasurement> mytms = myTraj.measurements();
228  LogTrace(category_) << "fit result " << mytms.size();
229  for (std::vector<TrajectoryMeasurement>::const_iterator itm = mytms.begin(); itm != mytms.end(); ++itm) {
230  LogTrace(category_) << "updated pos " << itm->updatedState().globalPosition() << "mom "
231  << itm->updatedState().globalMomentum();
232  }
233 
234  return vector<Trajectory>(1, myTraj);
235 }
236 
237 //
238 // smooth trajectory
239 //
240 vector<Trajectory> CosmicMuonSmoother::smooth(const vector<Trajectory>& tc) const {
241  vector<Trajectory> result;
242 
243  for (vector<Trajectory>::const_iterator it = tc.begin(); it != tc.end(); ++it) {
244  vector<Trajectory> smoothed = smooth(*it);
245  result.insert(result.end(), smoothed.begin(), smoothed.end());
246  }
247 
248  return result;
249 }
250 
251 //
252 // smooth trajectory
253 //
254 vector<Trajectory> CosmicMuonSmoother::smooth(const Trajectory& t) const {
255  if (t.empty()) {
256  LogTrace(category_) << "Error: smooth: empty trajectory.";
257  return vector<Trajectory>();
258  }
259 
260  Trajectory myTraj(t.seed(), oppositeToMomentum);
261 
262  vector<TrajectoryMeasurement> avtm = t.measurements();
263 
264  if (avtm.size() < 2) {
265  LogTrace(category_) << "Error: smooth: too little TM. ";
266  return vector<Trajectory>();
267  }
268 
269  TrajectoryStateOnSurface predTsos = avtm.back().forwardPredictedState();
271 
272  if (!predTsos.isValid()) {
273  LogTrace(category_) << "Error: smooth: first TSOS from back invalid. ";
274  return vector<Trajectory>();
275  }
276 
277  TrajectoryStateOnSurface currTsos;
278 
279  // first smoothed TrajectoryMeasurement is last fitted
280  if (avtm.back().recHit()->isValid()) {
281  currTsos = theUpdator->update(predTsos, (*avtm.back().recHit()));
282  if (!currTsos.isValid()) {
283  edm::LogWarning(category_) << "an updated state is not valid. killing the trajectory.";
284  return vector<Trajectory>();
285  }
286  myTraj.push(TrajectoryMeasurement(avtm.back().forwardPredictedState(),
287  predTsos,
288  avtm.back().updatedState(),
289  avtm.back().recHit(),
290  avtm.back().estimate() //,
291  /*avtm.back().layer()*/),
292  avtm.back().estimate());
293 
294  } else {
295  currTsos = predTsos;
296  myTraj.push(TrajectoryMeasurement(avtm.back().forwardPredictedState(),
297  avtm.back().recHit() //,
298  /*avtm.back().layer()*/));
299  }
300 
302 
303  for (vector<TrajectoryMeasurement>::reverse_iterator itm = avtm.rbegin() + 1; itm != avtm.rend() - 1; ++itm) {
304  if (currTsos.isValid()) {
305  LogTrace(category_) << "current pos " << currTsos.globalPosition() << "mom " << currTsos.globalMomentum();
306  } else {
307  LogTrace(category_) << "current state invalid";
308  }
309 
310  predTsos = propagatorOpposite()->propagate(currTsos, (*itm).recHit()->det()->surface());
311 
312  if (!predTsos.isValid()) {
313  LogTrace(category_) << "step-propagating from " << currTsos.globalPosition()
314  << " to position: " << (*itm).recHit()->globalPosition();
315  predTsos = theUtilities->stepPropagate(currTsos, (*itm).recHit(), *propagatorOpposite());
316  }
317  if (predTsos.isValid()) {
318  LogTrace(category_) << "predicted pos " << predTsos.globalPosition() << "mom " << predTsos.globalMomentum();
319  } else {
320  LogTrace(category_) << "predicted state invalid";
321  }
322 
323  if (!predTsos.isValid()) {
324  LogTrace(category_) << "Error: predTsos is still invalid backward smooth.";
325  return vector<Trajectory>();
326  // continue;
327  } else if ((*itm).recHit()->isValid()) {
328  //update
329  currTsos = theUpdator->update(predTsos, (*(*itm).recHit()));
330  if (!currTsos.isValid()) {
331  edm::LogWarning(category_) << "an updated state is not valid. killing the trajectory.";
332  return vector<Trajectory>();
333  }
334  TrajectoryStateOnSurface combTsos = combiner(predTsos, (*itm).forwardPredictedState());
335  if (!combTsos.isValid()) {
336  LogTrace(category_) << "Error: smooth: combining pred TSOS failed. ";
337  return vector<Trajectory>();
338  }
339 
340  TrajectoryStateOnSurface smooTsos = combiner((*itm).updatedState(), predTsos);
341 
342  if (!smooTsos.isValid()) {
343  LogTrace(category_) << "Error: smooth: combining smooth TSOS failed. ";
344  return vector<Trajectory>();
345  }
346 
347  myTraj.push(TrajectoryMeasurement((*itm).forwardPredictedState(),
348  predTsos,
349  smooTsos,
350  (*itm).recHit(),
351  theEstimator->estimate(combTsos, (*(*itm).recHit())).second //,
352  /*(*itm).layer()*/),
353  (*itm).estimate());
354  } else {
355  currTsos = predTsos;
356  TrajectoryStateOnSurface combTsos = combiner(predTsos, (*itm).forwardPredictedState());
357 
358  if (!combTsos.isValid()) {
359  LogTrace(category_) << "Error: smooth: combining TSOS failed. ";
360  return vector<Trajectory>();
361  }
362 
363  myTraj.push(TrajectoryMeasurement((*itm).forwardPredictedState(),
364  predTsos,
365  combTsos,
366  (*itm).recHit() //,
367  /*(*itm).layer()*/));
368  }
369  }
370 
371  // last smoothed TrajectoryMeasurement is last filtered
372  predTsos = propagatorOpposite()->propagate(currTsos, avtm.front().recHit()->det()->surface());
373 
374  if (!predTsos.isValid()) {
375  LogTrace(category_) << "Error: last predict TSOS failed, use original one. ";
376  // return vector<Trajectory>();
377  myTraj.push(TrajectoryMeasurement(avtm.front().forwardPredictedState(), avtm.front().recHit()));
378  } else {
379  if (avtm.front().recHit()->isValid()) {
380  //update
381  currTsos = theUpdator->update(predTsos, (*avtm.front().recHit()));
382  if (currTsos.isValid())
383  myTraj.push(TrajectoryMeasurement(avtm.front().forwardPredictedState(),
384  predTsos,
385  currTsos,
386  avtm.front().recHit(),
387  theEstimator->estimate(predTsos, (*avtm.front().recHit())).second //,
388  /*avtm.front().layer()*/),
389  avtm.front().estimate());
390  }
391  }
392  LogTrace(category_) << "myTraj foundHits. " << myTraj.foundHits();
393 
394  if (myTraj.foundHits() >= 3)
395  return vector<Trajectory>(1, myTraj);
396  else {
397  LogTrace(category_) << "Error: smooth: No enough hits in trajctory. ";
398  return vector<Trajectory>();
399  }
400 }
401 
403  if (t.empty())
404  return TrajectoryStateOnSurface();
405 
406  if (!t.firstMeasurement().updatedState().isValid() || !t.lastMeasurement().updatedState().isValid())
407  return TrajectoryStateOnSurface();
408 
410 
411  bool beamhaloFlag = (t.firstMeasurement().updatedState().globalMomentum().eta() > 4.0 ||
412  t.lastMeasurement().updatedState().globalMomentum().eta() > 4.0);
413 
414  if (!beamhaloFlag) { //initialState is the top one
415  if (t.firstMeasurement().updatedState().globalPosition().y() >
416  t.lastMeasurement().updatedState().globalPosition().y()) {
417  result = t.firstMeasurement().updatedState();
418  } else {
419  result = t.lastMeasurement().updatedState();
420  }
421  if (result.globalMomentum().y() > 1.0) //top tsos should pointing down
422  theUtilities->reverseDirection(result, &*theService->magneticField());
423  } else {
424  if (t.firstMeasurement().updatedState().globalPosition().z() *
425  t.lastMeasurement().updatedState().globalPosition().z() >
426  0) { //same side
427  if (fabs(t.firstMeasurement().updatedState().globalPosition().z()) >
428  fabs(t.lastMeasurement().updatedState().globalPosition().z())) {
429  result = t.firstMeasurement().updatedState();
430  } else {
431  result = t.lastMeasurement().updatedState();
432  }
433  } else { //different sides
434 
435  if (fabs(t.firstMeasurement().updatedState().globalPosition().eta()) >
436  fabs(t.lastMeasurement().updatedState().globalPosition().eta())) {
437  result = t.firstMeasurement().updatedState();
438  } else {
439  result = t.lastMeasurement().updatedState();
440  }
441  }
442  }
443 
444  return result;
445 }
446 
448  if (hits.size() < 2)
449  return;
450  float dis1 = (hits.front()->globalPosition() - tsos.globalPosition()).mag();
451  float dis2 = (hits.back()->globalPosition() - tsos.globalPosition()).mag();
452 
453  if (dis1 > dis2)
454  std::reverse(hits.begin(), hits.end());
455 
456  return;
457 }
void reverseDirection(TrajectoryStateOnSurface &, const MagneticField *) const
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
const MuonServiceProxy * theService
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
Trajectory trajectory(const Trajectory &) const override
T mag2() const
Definition: PV3DBase.h:63
const SurfaceType & surface() const
TrajectoryStateOnSurface propagate(STA const &state, SUR const &surface) const
Definition: Propagator.h:50
#define LogTrace(id)
DataContainer const & measurements() const
Definition: Trajectory.h:178
std::vector< Trajectory > smooth(const std::vector< Trajectory > &) const
const Chi2MeasurementEstimator * theEstimator
U second(std::pair< T, U > const &p)
const Propagator * propagatorOpposite() const
GlobalPoint globalPosition() const
TrajectoryStateOnSurface update(const TrajectoryStateOnSurface &, const TrackingRecHit &) const override
Definition: KFUpdator.cc:177
const CosmicMuonUtilities * theUtilities
TrajectoryStateOnSurface stepPropagate(const TrajectoryStateOnSurface &, const ConstRecHitPointer &, const Propagator &) const
TrajectoryStateOnSurface initialState(const Trajectory &) const
double f[11][100]
std::string thePropagatorAlongName
std::vector< Trajectory > fit(const Trajectory &) const
const KFUpdator * theUpdator
void sortHitsAlongMom(ConstRecHitContainer &hits, const TrajectoryStateOnSurface &) const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
GlobalVector globalMomentum() const
~CosmicMuonSmoother() override
const Propagator * propagatorAlong() const
HLT enums.
TrajectoryContainer trajectories(const Trajectory &traj) const override
CosmicMuonSmoother(const edm::ParameterSet &, const MuonServiceProxy *service)
TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer
Log< level::Warning, false > LogWarning
void push(const TrajectoryMeasurement &tm)
Definition: Trajectory.cc:50
std::string thePropagatorOppositeName