24 struct KFFittingSmootherParam {
27 theEstimateCut(conf.getParameter<double>(
"EstimateCut"))
28 ,theMaxFractionOutliers(conf.getParameter<double>(
"MaxFractionOutliers"))
29 ,theMaxNumberOfOutliers(conf.getParameter<
int>(
"MaxNumberOfOutliers"))
30 ,theNoOutliersBeginEnd(conf.getParameter<bool>(
"NoOutliersBeginEnd"))
31 ,theMinDof(conf.getParameter<
int>(
"MinDof"))
32 ,theMinNumberOfHits(conf.getParameter<
int>(
"MinNumberOfHits"))
33 ,rejectTracksFlag(conf.getParameter<bool>(
"RejectTracks"))
34 ,breakTrajWith2ConsecutiveMissing(conf.getParameter<bool>(
"BreakTrajWith2ConsecutiveMissing"))
35 ,noInvalidHitsBeginEnd(conf.getParameter<bool>(
"NoInvalidHitsBeginEnd"))
38 double theEstimateCut;
40 float theMaxFractionOutliers;
41 int theMaxNumberOfOutliers;
42 bool theNoOutliersBeginEnd;
45 int theMinNumberOfHits;
46 bool rejectTracksFlag;
47 bool breakTrajWith2ConsecutiveMissing;
48 bool noInvalidHitsBeginEnd;
53 class KFFittingSmoother final :
public TrajectoryFitter,
private KFFittingSmootherParam {
56 ~KFFittingSmoother() {}
62 KFFittingSmootherParam(conf),
63 theFitter(aFitter.
clone()),
64 theSmoother(aSmoother.
clone())
70 desc.
add<
double>(
"EstimateCut",-1);
71 desc.
add<
double>(
"MaxFractionOutliers",0.3);
72 desc.add<
int>(
"MaxNumberOfOutliers",3);
73 desc.add<
int>(
"MinDof",2);
74 desc.add<
bool>(
"NoOutliersBeginEnd",
false);
75 desc.add<
int>(
"MinNumberOfHits",5);
76 desc.add<
bool>(
"RejectTracks",
true);
77 desc.add<
bool>(
"BreakTrajWith2ConsecutiveMissing",
true);
78 desc.add<
bool>(
"NoInvalidHitsBeginEnd",
true);
79 desc.add<
double>(
"LogPixelProbabilityCut",0);
86 const RecHitContainer&
hits,
94 std::unique_ptr<TrajectoryFitter>
clone()
const override {
95 return std::unique_ptr<TrajectoryFitter>(
96 new KFFittingSmoother(*theFitter,
103 virtual void setHitCloner(
TkCloner const *
hc)
override {
104 theFitter->setHitCloner(hc);
105 theSmoother->setHitCloner(hc);
110 KFFittingSmootherParam
const &
other) :
111 KFFittingSmootherParam(other),
112 theFitter(aFitter.
clone()),
113 theSmoother(aSmoother.
clone())
119 if (theEstimateCut>0) {
121 while (!fitted.empty() && fitted.foundHits()>=theMinNumberOfHits &&
122 ( !fitted.lastMeasurement().recHitR().isValid()
123 || ( fitted.lastMeasurement().recHitR().det()!=
nullptr && fitted.lastMeasurement().estimate()>theEstimateCut)
127 if (fitted.foundHits() < theMinNumberOfHits )
return Trajectory();
129 return theSmoother->trajectory(fitted);
134 const std::unique_ptr<TrajectoryFitter> theFitter;
135 const std::unique_ptr<TrajectorySmoother> theSmoother;
139 static bool checkForNans(
const Trajectory &theTraj);
141 friend class KFFittingSmootherESProducer;
149 #define DPRINT(x) std::cout << x << ": " 150 #define PRINT std::cout 152 #define DPRINT(x) LogTrace(x) 153 #define PRINT LogTrace("") 158 return smoothingStep(theFitter->fitOne(t,type));
161 bool KFFittingSmoother::checkForNans(
const Trajectory & theTraj)
165 for (
auto const & tm : vtm) {
167 auto const &
v = tm.updatedState ().localParameters ().vector();
169 auto const &
m = tm.updatedState ().curvilinearError ().matrix();
170 for (
int i=0;i<5;++
i)
188 const RecHitContainer&
hits,
192 LogDebug(
"TrackFitters") <<
"In KFFittingSmoother::fit";
194 print(
"firstPred ", firstPredTsos);
198 RecHitContainer myHits =
hits;
202 Trajectory smoothed = smoothingStep(theFitter->fitOne(aSeed, myHits, firstPredTsos));
209 for (
unsigned int j=0;j<myHits.size();j++) {
210 if (myHits[j]->det())
211 LogTrace(
"TrackFitters") <<
"hit #:" << j+1 <<
" rawId=" << myHits[j]->det()->geographicalId().rawId()
212 <<
" validity=" << myHits[j]->isValid();
214 LogTrace(
"TrackFitters") <<
"hit #:" << j+1 <<
" Hit with no Det information";
218 #if defined(VI_DEBUG) || defined(EDM_ML_DEBUG) 226 if ( !smoothed.
isValid() || (hasNaN = !checkForNans(smoothed)) || ( smoothed.
foundHits() < theMinNumberOfHits ) ) {
228 if ( smoothed.
foundHits() < theMinNumberOfHits )
LogTrace(
"TrackFitters") <<
"smoothed.foundHits()<theMinNumberOfHits";
229 DPRINT(
"TrackFitters") <<
"smoothed invalid => trajectory rejected with nhits/chi2 " << smoothed.
foundHits() <<
'/' << smoothed.
chiSquared() <<
"\n";
230 if (rejectTracksFlag) {
234 DPRINT(
"TrackFitters") <<
"smoothed invalid => returning orignal trajectory with nhits/chi2 " << smoothed.
foundHits() <<
'/' << smoothed.
chiSquared() <<
"\n";
240 LogTrace(
"TrackFitters") <<
"dump hits after smoothing";
242 for (Trajectory::DataContainer::iterator it=meas.begin();it!=meas.end();++it) {
243 LogTrace(
"TrackFitters") <<
"hit #" << meas.end()-it-1 <<
" validity=" << it->recHit()->isValid()
244 <<
" det=" << it->recHit()->geographicalId().rawId();
250 DPRINT(
"TrackFitters") <<
"lost hits. before/after: " << myHits.size() <<
'/' << smoothed.
measurements().size()<<
"\n";
252 if ( theEstimateCut <= 0)
break;
263 if (tm.estimate()>theEstimateCut
264 && tm.recHitR().det()!=
nullptr 266 if (ind<lastValid && tm.recHitR().det()!=
nullptr && tm.recHitR().isValid()) lastValid=ind;
272 DPRINT(
"TrackFitters") <<
"size/found/outliers list " << smoothed.
measurements().size() <<
'/' << smoothed.
foundHits() <<
' ' << nbad <<
": ";
273 for (
auto i=0
U;
i<nbad; ++
i)
PRINT << bad[
i] <<
',';
280 int(nbad)>theMaxNumberOfOutliers ||
281 float(nbad) > theMaxFractionOutliers*
float(smoothed.
foundHits())
283 DPRINT(
"TrackFitters") <<
"smoothed low quality => trajectory with nhits/chi2 " << smoothed.
foundHits() <<
'/' << smoothed.
chiSquared() <<
"\n";
284 PRINT <<
"try to remove " << lastValid << std::endl;
301 bad[nbad++]=lastValid;
307 assert(smoothed.
measurements().size() <= myHits.size());
311 assert(smoothed.
measurements().size() == myHits.size());
316 auto NHits = myHits.size();
320 for (
auto i=0
U;
i<nbad; ++
i) {
322 assert(myHits[j]->geographicalId() == smoothed.
measurements()[bad[
i]].recHitR().geographicalId());
323 auto removedHit = myHits[j];
325 smoothedCand[
i] = smoothingStep(theFitter->fitOne(aSeed, myHits, firstPredTsos));
326 myHits[j] = removedHit;
327 if (smoothedCand[
i].isValid() && smoothedCand[
i].chiSquared()<
minChi2) {
328 minChi2 = smoothedCand[
i].chiSquared();
334 DPRINT(
"TrackFitters") <<
"New trajectories all invalid"<<
"\n";
338 DPRINT(
"TrackFitters") <<
"outlier removed " << bad[
loc] <<
'/' << minChi2 <<
" was " << smoothed.
chiSquared()<<
"\n";
342 DPRINT(
"TrackFitters") <<
"removing outlier makes chi2 worse " << minChi2 <<
'/' << smoothed.
chiSquared() <<
"\nOri: ";
344 PRINT << tm.recHitR().geographicalId() <<
'/' << tm.estimate() <<
' ';
346 for (
auto const & tm : smoothedCand[
loc].measurements() )
347 PRINT << tm.recHitR().geographicalId() <<
'/' << tm.estimate() <<
' ';
359 DPRINT(
"TrackFitters") <<
"new trajectory with nhits/chi2 " << smoothed.
foundHits() <<
'/' << smoothed.
chiSquared() <<
"\n";
365 if ( breakTrajWith2ConsecutiveMissing ) {
366 unsigned int firstinvalid = myHits.size();
367 for (
unsigned int j=0; j<myHits.size()-1; ++j )
371 && ( (myHits[j ]->geographicalId().rawId()&(~3)) != (myHits[j+1]->geographicalId().rawId()&(~3) ) )
375 DPRINT(
"TrackFitters") <<
"Found two consecutive missing hits. First invalid: " << firstinvalid <<
"\n";
382 if (firstinvalid != myHits.size()) {
383 myHits.erase(myHits.begin()+firstinvalid,myHits.end());
384 smoothed = smoothingStep(theFitter->fitOne(aSeed, myHits, firstPredTsos));
393 if ( noInvalidHitsBeginEnd
398 LogTrace(
"TrackFitters") <<
"Last measurement is invalid";
405 LogTrace(
"TrackFitters") <<
"First measurement is in`valid";
408 auto it = meas.begin();
409 for ( ; it!=meas.end(); ++it )
410 if ( it->recHitR().isValid() )
break;
413 for (
auto itt=it+1; itt!=meas.end();++itt)
422 LogTrace(
"TrackFitters") <<
"end: returning smoothed trajectory with chi2=" 440 const RecHitContainer& hits,
fitType type)
const{
443 "KFFittingSmoother::fit(TrajectorySeed, <TransientTrackingRecHit>) not implemented");
bool empty() const
True if trajectory has no measurements.
TrajectorySeed const & seed() const
Access to the seed used to reconstruct the Trajectory.
std::string print(const Track &, edm::Verbosity=edm::Concise)
Track print utility.
GlobalPoint globalPosition() const
PropagationDirection const & direction() const
DataContainer const & measurements() const
std::vector< TrajectoryMeasurement > DataContainer
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
TrajectoryMeasurement const & lastMeasurement() const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
TrajectoryMeasurement const & firstMeasurement() const
double signedInverseMomentum() const
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
ConstRecHitPointer::element_type const & recHitR() const
GlobalVector globalMomentum() const
TrajectoryStateOnSurface const & updatedState() const
#define declareDynArray(T, n, x)
double transverseCurvature() const