CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
KFFittingSmoother.cc
Go to the documentation of this file.
2 // #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
9 
10 // ggiurgiu@fnal.gov: Add headers needed to cut on pixel hit probability
14 
15 using namespace std;
16 
18 {
19  delete theSmoother;
20  delete theFitter;
21 }
22 
23 vector<Trajectory> KFFittingSmoother::fit(const Trajectory& t) const
24 {
25  vector<Trajectory> smoothed;
26  if ( t.isValid() )
27  {
28  vector<Trajectory> fitted = fitter()->fit(t);
29  smoothingStep(fitted, smoothed);
30  }
31  return smoothed;
32 }
33 
34 vector<Trajectory> KFFittingSmoother::fit(const TrajectorySeed& aSeed,
35  const RecHitContainer& hits,
36  const TrajectoryStateOnSurface& firstPredTsos) const
37 {
38  LogDebug("TrackFitters") << "In KFFittingSmoother::fit";
39 
40  //if(hits.empty()) return vector<Trajectory>(); // gio: moved later to optimize return value
41 
42  bool hasoutliers;
43  bool has_low_pixel_prob; // ggiurgiu@fnal.gov: Add flag for pixel hits with low template probability
44 
45  // ggiurgiu@fnal.gov: If log(Prob) < -15.0 or if Prob <= 0.0 then set log(Prob) = -15.0
46  double log_pixel_probability_lower_limit = -15.0;
47 
48  RecHitContainer myHits = hits;
49  vector<Trajectory> smoothed;
50  vector<Trajectory> tmp_first;
51 
52  do
53  {
54  if ( hits.empty() )
55  {
56  smoothed.clear();
57  break;
58  }
59 
60  //if no outliers the fit is done only once
61  //for (unsigned int j=0;j<myHits.size();j++) {
62  //if (myHits[j]->det())
63  //LogTrace("TrackFitters") << "hit #:" << j+1 << " rawId=" << myHits[j]->det()->geographicalId().rawId()
64  //<< " validity=" << myHits[j]->isValid();
65  //else
66  //LogTrace("TrackFitters") << "hit #:" << j+1 << " Hit with no Det information";
67  //}
68 
69  hasoutliers = false;
70  has_low_pixel_prob = false; // ggiurgiu@fnal.gov
71 
72  double cut = theEstimateCut;
73 
74  double log_pixel_prob_cut = theLogPixelProbabilityCut; // ggiurgiu@fnal.gov
75 
76 
77  unsigned int outlierId = 0;
78  const GeomDet* outlierDet = 0;
79 
80  unsigned int low_pixel_prob_Id = 0; // ggiurgiu@fnal.gov
81  const GeomDet* low_pixel_prob_Det = 0; // ggiurgiu@fnal.gov
82 
83  //call the fitter
84  vector<Trajectory> fitted = fitter()->fit(aSeed, myHits, firstPredTsos);
85  //call the smoother
86  smoothed.clear();
87  smoothingStep(fitted, smoothed);
88 
89  //if (tmp_first.size()==0) tmp_first = smoothed; moved later
90 
91  if ( smoothed.empty() )
92  {
93  if ( rejectTracksFlag )
94  {
95  LogTrace("TrackFitters") << "smoothed.size()==0 => trajectory rejected";
96  //return vector<Trajectory>(); // break is enough to get this
97  }
98  else
99  {
100  LogTrace("TrackFitters") << "smoothed.size()==0 => returning orignal trajectory" ;
101  smoothed.swap(tmp_first); // if first attempt, tmp_first would be empty anyway
102  }
103  break;
104  }
105  //else {
106  //LogTrace("TrackFitters") << "dump hits after smoothing";
107  //Trajectory::DataContainer meas = smoothed[0].measurements();
108  //for (Trajectory::DataContainer::iterator it=meas.begin();it!=meas.end();++it) {
109  //LogTrace("TrackFitters") << "hit #" << meas.end()-it-1 << " validity=" << it->recHit()->isValid()
110  //<< " det=" << it->recHit()->geographicalId().rawId();
111  //}
112  //}
113 
114  if ( theEstimateCut > 0 || log_pixel_prob_cut > log_pixel_probability_lower_limit )
115  {
116  if ( smoothed[0].foundHits() < theMinNumberOfHits )
117  {
118  if ( rejectTracksFlag )
119  {
120  LogTrace("TrackFitters") << "smoothed[0].foundHits()<theMinNumberOfHits => trajectory rejected";
121  smoothed.clear();
122  //return vector<Trajectory>(); // break is enough
123  }
124  else
125  {
126  // it might be it's the first step
127  if ( !tmp_first.empty() )
128  {
129  tmp_first.swap(smoothed);
130  }
131 
132  LogTrace("TrackFitters")
133  << "smoothed[0].foundHits()<theMinNumberOfHits => returning orignal trajectory with chi2="
134  << smoothed[0].chiSquared() ;
135  }
136  break;
137  }
138 
139  // Check if there are outliers or low probability pixel rec hits
140  const std::vector<TrajectoryMeasurement> & vtm = smoothed[0].measurements();
141 
142  double log_pixel_hit_probability = -999999.9;
143 
144  for (std::vector<TrajectoryMeasurement>::const_iterator tm=vtm.begin(); tm!=vtm.end();tm++)
145  {
146  double estimate = tm->estimate();
147 
148  // --- here is the block of code about generic chi2-based Outlier Rejection ---
149  if ( estimate > cut )
150  {
151  hasoutliers = true;
152  cut = estimate;
153  outlierId = tm->recHit()->geographicalId().rawId();
154  outlierDet = tm->recHit()->det();
155  }
156  // --- here the block of code about generic chi2-based Outlier Rejection ends ---
157 
158 
159  // --- here is the block of code about PXL Outlier Rejection ---
160  if(log_pixel_prob_cut > log_pixel_probability_lower_limit){
161  // TO BE FIXED: the following code should really be moved into an external class or
162  // at least in a separate function. Current solution is ugly!
163  // The KFFittingSmoother shouldn't handle the details of
164  // Outliers identification and rejection. It shoudl just fit tracks.
165 
166  // ggiurgiu@fnal.gov: Get pixel hit probability here
168  unsigned int testSubDetID = ( hit->geographicalId().subdetId() );
169 
170  if ( hit->isValid() &&
171  hit->geographicalId().det() == DetId::Tracker &&
172  ( testSubDetID == PixelSubdetector::PixelBarrel ||
173  testSubDetID == PixelSubdetector::PixelEndcap )
174  )
175  {
176  // get the enclosed persistent hit
177  const TrackingRecHit* persistentHit = hit->hit();
178 
179  // check if it's not null, and if it's a valid pixel hit
180  if ( !persistentHit == 0 &&
181  typeid(*persistentHit) == typeid(SiPixelRecHit) )
182  {
183 
184  // tell the C++ compiler that the hit is a pixel hit
185  const SiPixelRecHit* pixhit = dynamic_cast<const SiPixelRecHit*>( hit->hit() );
186 
187  double pixel_hit_probability = (float)pixhit->clusterProbability(0);
188 
189  if ( pixel_hit_probability < 0.0 )
190  LogDebug("From KFFittingSmoother.cc")
191  << "Wraning : Negative pixel hit probability !!!! Will set the probability to 10^{-15} !!!" << endl;
192 
193  if ( pixel_hit_probability <= 0.0 || log10( pixel_hit_probability ) < log_pixel_probability_lower_limit )
194  log_pixel_hit_probability = log_pixel_probability_lower_limit;
195  else
196  log_pixel_hit_probability = log10( pixel_hit_probability );
197 
198  if ( log_pixel_hit_probability < log_pixel_prob_cut )
199  {
200  has_low_pixel_prob = true;
201  log_pixel_prob_cut = log_pixel_hit_probability;
202  low_pixel_prob_Id = tm->recHit()->geographicalId().rawId();
203  low_pixel_prob_Det = tm->recHit()->det();
204  }
205 
206  } // if ( !persistentHit == 0 && ... )
207 
208  } // if ( hit->isValid() && ... )
209  }
210  // --- here the block of code about PXL Outlier Rejection ends ---
211 
212 
213  } // for (std::vector<TrajectoryMeasurement>::const_iterator tm=vtm.begin(); tm!=vtm.end(); tm++)
214 
215 
216  if ( hasoutliers || has_low_pixel_prob )
217  { // Reject outliers and pixel hits with low probability
218 
219  // Replace outlier hit or low probability pixel hit with invalid hit
220  for ( unsigned int j=0; j<myHits.size(); ++j )
221  {
222  if ( hasoutliers && outlierId == myHits[j]->geographicalId().rawId() )
223  {
224  LogTrace("TrackFitters") << "Rejecting outlier hit with estimate " << cut << " at position "
225  << j << " with rawId=" << myHits[j]->geographicalId().rawId();
226  LogTrace("TrackFitters") << "The fit will be repeated without the outlier";
228  }
229  else if ( has_low_pixel_prob && low_pixel_prob_Id == myHits[j]->geographicalId().rawId() )
230  {
231  LogTrace("TrackFitters") << "Rejecting low proability pixel hit with log_pixel_prob_cut = "
232  << log_pixel_prob_cut << " at position "
233  << j << " with rawId =" << myHits[j]->geographicalId().rawId();
234  LogTrace("TrackFitters") << "The fit will be repeated without the outlier";
235  myHits[j] = InvalidTransientRecHit::build(low_pixel_prob_Det, TrackingRecHit::missing);
236  }
237 
238  } // for ( unsigned int j=0; j<myHits.size(); ++j)
239 
240  // Look if there are two consecutive invalid hits
241  if ( breakTrajWith2ConsecutiveMissing )
242  {
243  unsigned int firstinvalid = myHits.size()-1;
244  for ( unsigned int j=0; j<myHits.size()-1; ++j )
245  {
246  if ( ((myHits[j ]->type() == TrackingRecHit::missing) && (myHits[j ]->geographicalId().rawId() != 0)) &&
247  ((myHits[j+1]->type() == TrackingRecHit::missing) && (myHits[j+1]->geographicalId().rawId() != 0)) )
248  {
249  firstinvalid = j;
250  LogTrace("TrackFitters") << "Found two consecutive missing hits. First invalid: " << firstinvalid;
251  break;
252  }
253  }
254 
255  //reject all the hits after the last valid before two consecutive invalid (missing) hits
256  //hits are sorted in the same order as in the track candidate FIXME??????
257  myHits.erase(myHits.begin()+firstinvalid,myHits.end());
258 
259  }
260 
261  } // if ( hasoutliers || has_low_pixel_prob )
262 
263  } // if ( theEstimateCut > 0 ... )
264 
265  if ( ( hasoutliers || // otherwise there won't be a 'next' loop where tmp_first could be useful
266  has_low_pixel_prob ) && // ggiurgiu@fnal.gov
267  !rejectTracksFlag && // othewrise we won't ever need tmp_first
268  tmp_first.empty() )
269  { // only at first step
270  smoothed.swap(tmp_first);
271  }
272 
273  } // do
274  while ( hasoutliers || has_low_pixel_prob ); // ggiurgiu@fnal.gov
275 
276  if ( !smoothed.empty() )
277  {
278  if ( noInvalidHitsBeginEnd )
279  {
280  // discard latest dummy measurements
281  if ( !smoothed[0].empty() &&
282  !smoothed[0].lastMeasurement().recHit()->isValid() )
283  LogTrace("TrackFitters") << "Last measurement is invalid";
284 
285  while ( !smoothed[0].empty() &&
286  !smoothed[0].lastMeasurement().recHit()->isValid() )
287  smoothed[0].pop();
288 
289  //remove the invalid hits at the begin of the trajectory
290  if ( !smoothed[0].firstMeasurement().recHit()->isValid() )
291  {
292  LogTrace("TrackFitters") << "First measurement is invalid";
293  Trajectory tmpTraj(smoothed[0].seed(),smoothed[0].direction());
294  Trajectory::DataContainer meas = smoothed[0].measurements();
295 
296  Trajectory::DataContainer::iterator it;//first valid hit
297  for ( it=meas.begin(); it!=meas.end(); ++it )
298  {
299  if ( !it->recHit()->isValid() )
300  continue;
301  else break;
302  }
303  tmpTraj.push(*it,smoothed[0].chiSquared());//push the first valid measurement and set the same global chi2
304 
305  for (Trajectory::DataContainer::iterator itt=it+1; itt!=meas.end();++itt)
306  {
307  tmpTraj.push(*itt,0);//add all the other measurements
308  }
309 
310  smoothed.clear();
311  smoothed.push_back(tmpTraj);
312 
313  } // if ( !smoothed[0].firstMeasurement().recHit()->isValid() )
314 
315  } // if ( noInvalidHitsBeginEnd )
316 
317  LogTrace("TrackFitters") << "end: returning smoothed trajectory with chi2="
318  << smoothed[0].chiSquared() ;
319 
320  //LogTrace("TrackFitters") << "dump hits before return";
321  //Trajectory::DataContainer meas = smoothed[0].measurements();
322  //for (Trajectory::DataContainer::iterator it=meas.begin();it!=meas.end();++it) {
323  //LogTrace("TrackFitters") << "hit #" << meas.end()-it-1 << " validity=" << it->recHit()->isValid()
324  //<< " det=" << it->recHit()->geographicalId().rawId();
325  //}
326 
327  }
328 
329  return smoothed;
330 
331 }
332 
333 
334 void
335 KFFittingSmoother::smoothingStep(vector<Trajectory>& fitted, vector<Trajectory> &smoothed) const
336 {
337 
338  for(vector<Trajectory>::iterator it = fitted.begin(); it != fitted.end();
339  it++) {
340  vector<Trajectory> mysmoothed = smoother()->trajectories(*it);
341  smoothed.insert(smoothed.end(), mysmoothed.begin(), mysmoothed.end());
342  }
343  LogDebug("TrackFitters") << "In KFFittingSmoother::smoothingStep "<<smoothed.size();
344 }
345 
346 vector<Trajectory> KFFittingSmoother::fit(const TrajectorySeed& aSeed,
347  const RecHitContainer& hits) const{
348 
349  throw cms::Exception("TrackFitters",
350  "KFFittingSmoother::fit(TrajectorySeed, <TransientTrackingRecHit>) not implemented");
351 
352  return vector<Trajectory>();
353 }
#define LogDebug(id)
type
Definition: HCALResponse.h:22
float clusterProbability(unsigned int flags=0) const
static RecHitPointer build(const GeomDet *geom, Type type=TrackingRecHit::missing, const DetLayer *layer=0)
virtual std::vector< Trajectory > fit(const Trajectory &t) const
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:42
int j
Definition: DBlmapReader.cc:9
void smoothingStep(std::vector< Trajectory > &fitted, std::vector< Trajectory > &smoothed) const
virtual ~KFFittingSmoother()
#define LogTrace(id)
tuple cut
Definition: align_tpl.py:88
bool isValid() const
Definition: Trajectory.h:225
Trajectory::RecHitContainer RecHitContainer
void push(const TrajectoryMeasurement &tm)
Definition: Trajectory.cc:35
Our base class.
Definition: SiPixelRecHit.h:27