@@ -142,6 +142,7 @@ class DCAFitterN
142142 void setMinParamChange (float x = 1e-3 ) { mMinParamChange = x > 1e-4 ? x : 1 .e -4 ; }
143143 void setMinRelChi2Change (float r = 0.9 ) { mMinRelChi2Change = r > 0.1 ? r : 999 .; }
144144 void setUseAbsDCA (bool v) { mUseAbsDCA = v; }
145+ void setMaxDistance2ToMerge (float v) { mMaxDist2ToMergeSeeds = v; }
145146
146147 int getNCandidates () const { return mCurHyp ; }
147148 int getMaxIter () const { return mMaxIter ; }
@@ -150,6 +151,7 @@ class DCAFitterN
150151 float getMaxChi2 () const { return mMaxChi2 ; }
151152 float getMinParamChange () const { return mMinParamChange ; }
152153 float getBz () const { return mBz ; }
154+ float getMaxDistance2ToMerge () const { return mMaxDist2ToMergeSeeds ; }
153155 bool getUseAbsDCA () const { return mUseAbsDCA ; }
154156 bool getPropagateToPCA () const { return mPropagateToPCA ; }
155157
@@ -187,7 +189,11 @@ class DCAFitterN
187189 assign (i + 1 , args...);
188190 }
189191
190- void clear () { mCurHyp = 0 ; }
192+ void clear ()
193+ {
194+ mCurHyp = 0 ;
195+ mAllowAltPreference = true ;
196+ }
191197
192198 static void setTrackPos (Vec3D& pnt, const Track& tr)
193199 {
@@ -224,7 +230,8 @@ class DCAFitterN
224230 std::array<int , MAXHYP> mOrder {0 };
225231 int mCurHyp = 0 ;
226232 int mCrossIDCur = 0 ;
227- int mCrossIDAlt = 1 ;
233+ int mCrossIDAlt = -1 ;
234+ bool mAllowAltPreference = true ; // if the fit converges to alternative PCA seed, abandon the current one
228235 bool mUseAbsDCA = false ; // use abs. distance minimization rather than chi2
229236 bool mPropagateToPCA = true ; // create tracks version propagated to PCA
230237 int mMaxIter = 20 ; // max number of iterations
@@ -234,6 +241,7 @@ class DCAFitterN
234241 float mMinParamChange = 1e-3 ; // stop iterations if largest change of any X is smaller than this
235242 float mMinRelChi2Change = 0.9 ; // stop iterations is chi2/chi2old > this
236243 float mMaxChi2 = 100 ; // abs cut on chi2 or abs distance
244+ float mMaxDist2ToMergeSeeds = 1 .; // merge 2 seeds to their average if their distance^2 is below the threshold
237245
238246 ClassDefNV (DCAFitterN, 1 );
239247};
@@ -256,14 +264,23 @@ int DCAFitterN<N, Args...>::process(const Tr&... args)
256264 if (mUseAbsDCA ) {
257265 calcRMatrices (); // needed for fast residuals derivatives calculation in case of abs. distance minimization
258266 }
267+ if (mCrossings .nDCA == MAXHYP) { // if there are 2 candidates and they are too close, chose their mean as a starting point
268+ auto dst2 = (mCrossings .xDCA [0 ] - mCrossings .xDCA [1 ]) * (mCrossings .xDCA [0 ] - mCrossings .xDCA [1 ]) +
269+ (mCrossings .yDCA [0 ] - mCrossings .yDCA [1 ]) * (mCrossings .yDCA [0 ] - mCrossings .yDCA [1 ]);
270+ if (dst2 < mMaxDist2ToMergeSeeds ) {
271+ mCrossings .nDCA = 1 ;
272+ mCrossings .xDCA [0 ] = 0.5 * (mCrossings .xDCA [0 ] + mCrossings .xDCA [1 ]);
273+ mCrossings .xDCA [0 ] = 0.5 * (mCrossings .xDCA [0 ] + mCrossings .xDCA [1 ]);
274+ }
275+ }
259276 // check all crossings
260277 for (int ic = 0 ; ic < mCrossings .nDCA ; ic++) {
261278 // check if radius is acceptable
262279 if (mCrossings .xDCA [ic] * mCrossings .xDCA [ic] + mCrossings .yDCA [ic] * mCrossings .yDCA [ic] > mMaxR2 ) {
263280 continue ;
264281 }
265282 mCrossIDCur = ic;
266- mCrossIDAlt = mCrossings .nDCA == 2 ? 1 - ic : -1 ; // works for max 2 crossings
283+ mCrossIDAlt = ( mCrossings .nDCA == 2 && mAllowAltPreference ) ? 1 - ic : -1 ; // works for max 2 crossings
267284 mNIters [mCurHyp ] = 0 ;
268285 mTrPropDone [mCurHyp ] = false ;
269286 mChi2 [mCurHyp ] = -1 .;
@@ -698,6 +715,7 @@ bool DCAFitterN<N, Args...>::minimizeChi2()
698715 }
699716 calcPCA (); // updated PCA
700717 if (mCrossIDAlt >= 0 && closerToAlternative ()) {
718+ mAllowAltPreference = false ;
701719 return false ;
702720 }
703721 calcTrackResiduals (); // updated residuals
@@ -750,6 +768,7 @@ bool DCAFitterN<N, Args...>::minimizeChi2NoErr()
750768 }
751769 calcPCANoErr (); // updated PCA
752770 if (mCrossIDAlt >= 0 && closerToAlternative ()) {
771+ mAllowAltPreference = false ;
753772 return false ;
754773 }
755774 calcTrackResiduals (); // updated residuals
0 commit comments