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()
override {}
61 KFFittingSmootherParam(conf),
62 theFitter(aFitter.
clone()),
63 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 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 if (!tm.updatedState ().curvilinearError ().posDef())
return false;
170 auto const &
m = tm.updatedState ().curvilinearError ().matrix();
171 for (
int i=0;i<5;++
i)
189 const RecHitContainer&
hits,
193 LogDebug(
"TrackFitters") <<
"In KFFittingSmoother::fit";
195 print(
"firstPred ", firstPredTsos);
199 RecHitContainer myHits =
hits;
203 Trajectory smoothed = smoothingStep(theFitter->fitOne(aSeed, myHits, firstPredTsos));
210 for (
unsigned int j=0;j<myHits.size();j++) {
211 if (myHits[j]->det())
212 LogTrace(
"TrackFitters") <<
"hit #:" << j+1 <<
" rawId=" << myHits[j]->det()->geographicalId().rawId()
213 <<
" validity=" << myHits[j]->isValid();
215 LogTrace(
"TrackFitters") <<
"hit #:" << j+1 <<
" Hit with no Det information";
219 #if defined(VI_DEBUG) || defined(EDM_ML_DEBUG) 227 if ( !smoothed.
isValid() || (hasNaN = !checkForNans(smoothed)) || ( smoothed.
foundHits() < theMinNumberOfHits ) ) {
228 if(hasNaN)
edm::LogWarning(
"TrackNaN")<<
"Track has NaN or the cov is not pos-definite";
229 if ( smoothed.
foundHits() < theMinNumberOfHits )
LogTrace(
"TrackFitters") <<
"smoothed.foundHits()<theMinNumberOfHits";
230 DPRINT(
"TrackFitters") <<
"smoothed invalid => trajectory rejected with nhits/chi2 " << smoothed.
foundHits() <<
'/' << smoothed.
chiSquared() <<
"\n";
231 if (rejectTracksFlag) {
235 DPRINT(
"TrackFitters") <<
"smoothed invalid => returning orignal trajectory with nhits/chi2 " << smoothed.
foundHits() <<
'/' << smoothed.
chiSquared() <<
"\n";
241 LogTrace(
"TrackFitters") <<
"dump hits after smoothing";
243 for (Trajectory::DataContainer::iterator it=meas.begin();it!=meas.end();++it) {
244 LogTrace(
"TrackFitters") <<
"hit #" << meas.end()-it-1 <<
" validity=" << it->recHit()->isValid()
245 <<
" det=" << it->recHit()->geographicalId().rawId();
251 DPRINT(
"TrackFitters") <<
"lost hits. before/after: " << myHits.size() <<
'/' << smoothed.
measurements().size()<<
"\n";
253 if ( theEstimateCut <= 0)
break;
264 if (tm.estimate()>theEstimateCut
265 && tm.recHitR().det()!=
nullptr 267 if (ind<lastValid && tm.recHitR().det()!=
nullptr && tm.recHitR().isValid()) lastValid=ind;
273 DPRINT(
"TrackFitters") <<
"size/found/outliers list " << smoothed.
measurements().size() <<
'/' << smoothed.
foundHits() <<
' ' << nbad <<
": ";
274 for (
auto i=0
U;
i<nbad; ++
i)
PRINT << bad[
i] <<
',';
281 int(nbad)>theMaxNumberOfOutliers ||
282 float(nbad) > theMaxFractionOutliers*
float(smoothed.
foundHits())
284 DPRINT(
"TrackFitters") <<
"smoothed low quality => trajectory with nhits/chi2 " << smoothed.
foundHits() <<
'/' << smoothed.
chiSquared() <<
"\n";
285 PRINT <<
"try to remove " << lastValid << std::endl;
302 bad[nbad++]=lastValid;
308 assert(smoothed.
measurements().size() <= myHits.size());
312 assert(smoothed.
measurements().size() == myHits.size());
317 auto NHits = myHits.size();
321 for (
auto i=0
U;
i<nbad; ++
i) {
323 assert(myHits[j]->geographicalId() == smoothed.
measurements()[bad[
i]].recHitR().geographicalId());
324 auto removedHit = myHits[j];
326 smoothedCand[
i] = smoothingStep(theFitter->fitOne(aSeed, myHits, firstPredTsos));
327 myHits[j] = removedHit;
328 if (smoothedCand[
i].isValid() && smoothedCand[
i].chiSquared()<
minChi2) {
329 minChi2 = smoothedCand[
i].chiSquared();
335 DPRINT(
"TrackFitters") <<
"New trajectories all invalid"<<
"\n";
339 DPRINT(
"TrackFitters") <<
"outlier removed " << bad[
loc] <<
'/' << minChi2 <<
" was " << smoothed.
chiSquared()<<
"\n";
343 DPRINT(
"TrackFitters") <<
"removing outlier makes chi2 worse " << minChi2 <<
'/' << smoothed.
chiSquared() <<
"\nOri: ";
345 PRINT << tm.recHitR().geographicalId() <<
'/' << tm.estimate() <<
' ';
347 for (
auto const & tm : smoothedCand[
loc].measurements() )
348 PRINT << tm.recHitR().geographicalId() <<
'/' << tm.estimate() <<
' ';
360 DPRINT(
"TrackFitters") <<
"new trajectory with nhits/chi2 " << smoothed.
foundHits() <<
'/' << smoothed.
chiSquared() <<
"\n";
366 if ( breakTrajWith2ConsecutiveMissing ) {
367 unsigned int firstinvalid = myHits.size();
368 for (
unsigned int j=0; j<myHits.size()-1; ++j )
372 && ( (myHits[j ]->geographicalId().rawId()&(~3)) != (myHits[j+1]->geographicalId().rawId()&(~3) ) )
376 DPRINT(
"TrackFitters") <<
"Found two consecutive missing hits. First invalid: " << firstinvalid <<
"\n";
383 if (firstinvalid != myHits.size()) {
384 myHits.erase(myHits.begin()+firstinvalid,myHits.end());
385 smoothed = smoothingStep(theFitter->fitOne(aSeed, myHits, firstPredTsos));
394 if ( noInvalidHitsBeginEnd
399 LogTrace(
"TrackFitters") <<
"Last measurement is invalid";
406 LogTrace(
"TrackFitters") <<
"First measurement is in`valid";
409 auto it = meas.begin();
410 for ( ; it!=meas.end(); ++it )
411 if ( it->recHitR().isValid() )
break;
414 for (
auto itt=it+1; itt!=meas.end();++itt)
423 LogTrace(
"TrackFitters") <<
"end: returning smoothed trajectory with chi2=" 441 const RecHitContainer& hits,
fitType type)
const{
444 "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.
constexpr bool isNotFinite(T x)
GlobalPoint globalPosition() const
S & print(S &os, JobReport::InputFile const &f)
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
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
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