From cde01ea1ac604cf209bfb069a3c7aafdf1b9c2b4 Mon Sep 17 00:00:00 2001
From: Vadim Kostyukhin <vkost@cern.ch>
Date: Thu, 15 Jun 2023 17:13:28 +0200
Subject: [PATCH] Annealing for robust fit and decouple from b-tagging

Annealing for robust fit

Use small annealing in vertex fits with robust option depending on the fit iteration number.
This should speed up convergence and help to avoid fake minima.
---
 .../python/InDetVKalVxInJetToolConfig.py      | 11 +++++--
 .../src/InDetVKalVxInJetTool.cxx              |  2 +-
 Tools/WorkflowTestRunner/python/References.py |  8 ++---
 .../python/TrkVKalVrtFitterConfig.py          | 12 +++++++
 .../TrkVKalVrtCore/TrkVKalVrtCore.h           |  1 +
 .../TrkVKalVrtCore/src/CFit.cxx               | 27 +++++++++-------
 .../TrkVKalVrtCore/src/CFitCascade.cxx        |  6 ++--
 .../TrkVKalVrtCore/src/RobTest.cxx            | 32 ++++---------------
 .../TrkVKalVrtCore/src/TrkVKalVrtCoreBase.cxx |  6 ++--
 .../TrkVKalVrtFitter/TrkVKalVrtFitter.h       |  2 ++
 .../TrkVKalVrtFitter/src/SetFitOptions.cxx    |  2 ++
 .../TrkVKalVrtFitter/src/TrkVKalVrtFitter.cxx |  6 +++-
 12 files changed, 63 insertions(+), 52 deletions(-)

diff --git a/InnerDetector/InDetConfig/python/InDetVKalVxInJetToolConfig.py b/InnerDetector/InDetConfig/python/InDetVKalVxInJetToolConfig.py
index 1018e623e3d..0951ff76d46 100644
--- a/InnerDetector/InDetConfig/python/InDetVKalVxInJetToolConfig.py
+++ b/InnerDetector/InDetConfig/python/InDetVKalVxInJetToolConfig.py
@@ -12,8 +12,8 @@ def TCTDecorCheckInToolCfg(flags, name="TCTDecorCheckInTool", **kwargs):
     kwargs.setdefault("JetCollection","AntiKt4EMPFlowJets")
     
     from TrkConfig.TrkVKalVrtFitterConfig import TrkVKalVrtFitterCfg
-    VertexFitterTool = acc.popToolsAndMerge(TrkVKalVrtFitterCfg(flags,"VertexFitterTool"))
-    kwargs.setdefault("TrackClassificationTool",acc.popToolsAndMerge(InDetTrkInJetTypeCfg(flags,name="TrkInJetType",JetCollection=kwargs["JetCollection"],VertexFitterTool=VertexFitterTool)))
+    VertexFitter = acc.popToolsAndMerge(TrkVKalVrtFitterCfg(flags,"VKalVrtFitter"))
+    kwargs.setdefault("TrackClassificationTool",acc.popToolsAndMerge(InDetTrkInJetTypeCfg(flags,name="TrkInJetType",JetCollection=kwargs["JetCollection"],VertexFitterTool=VertexFitter)))
                  
     acc.addEventAlgo(CompFactory.TCTDecorCheckInTool(name, **kwargs))
     return acc
@@ -28,12 +28,17 @@ def InDetTrkInJetTypeCfg(flags, name="TrkInJetType", **kwargs):
 def InDetVKalVxInJetToolCfg(flags, name="InDetVKalVxInJetTool", **kwargs):
     acc = ComponentAccumulator()
 
+    from TrkConfig.TrkVKalVrtFitterConfig import BTAG_TrkVKalVrtFitterCfg
+    VertexFitter = acc.popToolsAndMerge(BTAG_TrkVKalVrtFitterCfg(flags,"VKalVrtFitter"))
+
     if "TrackClassTool" not in kwargs:
          kwargs.setdefault("TrackClassTool", acc.popToolsAndMerge(
-             InDetTrkInJetTypeCfg(flags)))
+             InDetTrkInJetTypeCfg(flags,VertexFitterTool=VertexFitter)))
 
     kwargs.setdefault("ExistIBL", flags.GeoModel.Run in [LHCPeriod.Run2, LHCPeriod.Run3])
     kwargs.setdefault("getNegativeTag", "Flip" in name)
+    kwargs.setdefault("UseFrozenVersion", True)
+    kwargs.setdefault("VertexFitterTool", VertexFitter)
 
     if flags.GeoModel.Run >= LHCPeriod.Run4:
         from InDetConfig.InDetEtaDependentCutsConfig import IDEtaDependentCuts_SV1_SvcCfg
diff --git a/InnerDetector/InDetRecTools/InDetVKalVxInJetTool/src/InDetVKalVxInJetTool.cxx b/InnerDetector/InDetRecTools/InDetVKalVxInJetTool/src/InDetVKalVxInJetTool.cxx
index 7087a95117d..ed7d47d3097 100755
--- a/InnerDetector/InDetRecTools/InDetVKalVxInJetTool/src/InDetVKalVxInJetTool.cxx
+++ b/InnerDetector/InDetRecTools/InDetVKalVxInJetTool/src/InDetVKalVxInJetTool.cxx
@@ -49,7 +49,7 @@ InDetVKalVxInJetTool::InDetVKalVxInJetTool(const std::string& type,
     m_zTrkErrorCut(5.0),
     m_cutBVrtScore(0.015),
     m_vrt2TrMassLimit(4000.),
-    m_useFrozenVersion(true),
+    m_useFrozenVersion(false),
     m_fillHist(false),
     m_existIBL(true),
     m_RobustFit(1),
diff --git a/Tools/WorkflowTestRunner/python/References.py b/Tools/WorkflowTestRunner/python/References.py
index 3c21cdfcd41..37dd1035217 100644
--- a/Tools/WorkflowTestRunner/python/References.py
+++ b/Tools/WorkflowTestRunner/python/References.py
@@ -22,8 +22,8 @@ references_map = {
     "d1726": "v1",
     "d1759": "v1",
     # Reco
-    "q442": "v1",
-    "q443": "v1",
-    "q445": "v1",
-    "q449": "v1",
+    "q442": "v2",
+    "q443": "v2",
+    "q445": "v2",
+    "q449": "v2",
 }
diff --git a/Tracking/TrkConfig/python/TrkVKalVrtFitterConfig.py b/Tracking/TrkConfig/python/TrkVKalVrtFitterConfig.py
index c00acab1e2f..dcd0a161a61 100644
--- a/Tracking/TrkConfig/python/TrkVKalVrtFitterConfig.py
+++ b/Tracking/TrkConfig/python/TrkVKalVrtFitterConfig.py
@@ -63,3 +63,15 @@ def V0VKalVrtFitterCfg(flags, name="V0VKalVrtFitter", **kwargs):
 def JpsiV0VertexFitCfg(flags, name="JpsiV0VertexFit", **kwargs):
     kwargs.setdefault("CascadeCnstPrecision", 1e-6)
     return BPHY_TrkVKalVrtFitterCfg(flags, name, **kwargs)
+
+def BTAG_TrkVKalVrtFitterCfg(flags, name="BTAG_TrkVKalVrtFitter",**kwargs):
+    from MagFieldServices.MagFieldServicesConfig import AtlasFieldCacheCondAlgCfg
+    acc = AtlasFieldCacheCondAlgCfg(flags) # To produce AtlasFieldCacheCondObj
+    myargs = kwargs.copy()
+    myargs.setdefault("FirstMeasuredPoint", False)
+    myargs.setdefault("FrozenVersionForBTagging", True)
+    if "Extrapolator" in myargs:
+       del myargs["Extrapolator"]
+    acc.setPrivateTools(CompFactory.Trk.TrkVKalVrtFitter(name, **myargs))
+    return acc
+
diff --git a/Tracking/TrkVertexFitter/TrkVKalVrtCore/TrkVKalVrtCore/TrkVKalVrtCore.h b/Tracking/TrkVertexFitter/TrkVKalVrtCore/TrkVKalVrtCore/TrkVKalVrtCore.h
index 4175700b91b..d17cada6233 100755
--- a/Tracking/TrkVertexFitter/TrkVKalVrtCore/TrkVKalVrtCore/TrkVKalVrtCore.h
+++ b/Tracking/TrkVertexFitter/TrkVKalVrtCore/TrkVKalVrtCore/TrkVKalVrtCore.h
@@ -89,6 +89,7 @@ namespace Trk {
        CascadeEvent * m_cascadeEvent=nullptr;       
      public:
        ForCFT vk_forcft;
+       bool m_frozenVersionForBTagging = false;
   };
 
 } // end of namespace bracket
diff --git a/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/CFit.cxx b/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/CFit.cxx
index 3e986e0d7e0..900a36593db 100755
--- a/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/CFit.cxx
+++ b/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/CFit.cxx
@@ -169,7 +169,7 @@ int fitVertex(VKVertex * vk)
     extern int cfInv5(double *cov, double *wgt );
     extern void cfTrkCovarCorr(double *cov);
     extern void applyConstraints(VKVertex * vk);
-    extern void robtest(VKVertex * , long int );
+    extern void robtest(VKVertex * , int ifl, int nIteration=10);
 
 //
 //    New datastructure
@@ -312,8 +312,8 @@ int fitVertex(VKVertex * vk)
 	    trk = vk->TrackList[tk].get(); protectCurvatureSign( trk->refPerig[4], trk->fitP[2] , trk->WgtM);
         }
 /*--------------------------------  Now the fit itself -----------------*/
-	if (vrtForCFT.irob != 0) {robtest(vk, 0);}  // ROBUSTIFICATION new data structure
-	if (vrtForCFT.irob != 0) {robtest(vk, 1);}  // ROBUSTIFICATION new data structure
+	if (vrtForCFT.irob != 0) {robtest(vk, 0, it);}  // ROBUSTIFICATION new data structure
+	if (vrtForCFT.irob != 0) {robtest(vk, 1, it);}  // ROBUSTIFICATION new data structure
         for( tk=0; tk<NTRK; tk++){
 	  trk = vk->TrackList[tk].get(); 
 	  trk->iniP[0]=trk->cnstP[0]=trk->fitP[0];   //use fitted track parameters as initial guess
@@ -339,7 +339,7 @@ int fitVertex(VKVertex * vk)
 	chi22s = chi21s * 1.01 + 10.; //for safety 
 	if ( vShift < 10.*vkalShiftToTrigExtrapolation) {              // REASONABLE DISPLACEMENT - RECALCULATE
 /* ROBUSTIFICATION */
-	  if (vrtForCFT.irob != 0) {robtest(vk, 1);}  // ROBUSTIFICATION new data structure
+	  if (vrtForCFT.irob != 0) {robtest(vk, 1, it+1);}  // ROBUSTIFICATION new data structure
 //Reset mag.field
           for( i=0; i<3; i++) dparst[i]=vk->refIterV[i]+vk->fitV[i]; // fitted vertex at global frame
           vrtForCFT.localbmag=myMagFld.getMagFld(dparst,(vk->vk_fitterControl).get());
@@ -382,14 +382,17 @@ int fitVertex(VKVertex * vk)
   /*---------------------Normal convergence--------------------*/
         double PrecLimit = std::min(chi22s*1.e-4, vrtForCFT.IterationPrecision);
 //std::cout<<"Convergence="<< chi2df <<"<"<<PrecLimit<<" cnst="<<cnstRemnants<<"<"<<ConstraintAccuracy<<'\n';
-	if ((chi2df < PrecLimit) && (vShift < 0.001) && it>1 && (cnstRemnants<ConstraintAccuracy)){
-	   double dstFromExtrapPnt=sqrt(vk->fitV[0]*vk->fitV[0] + vk->fitV[1]*vk->fitV[1]+ vk->fitV[2]*vk->fitV[2]);
-	   if( dstFromExtrapPnt>vkalShiftToTrigExtrapolation/2. && it < vrtForCFT.IterationNumber-15){
-	     forcedExtrapolation=true;
-	     continue;          // Make another extrapolation exactly to found vertex position
-           }
-	   break;
-        }
+	if(     ( vk->vk_fitterControl->m_frozenVersionForBTagging &&  it>1 )
+	     || (!vk->vk_fitterControl->m_frozenVersionForBTagging && (it>3||vrtForCFT.irob==0) ) ){
+	  if((chi2df < PrecLimit) && (vShift < 0.001) && (cnstRemnants<ConstraintAccuracy)){
+	    double dstFromExtrapPnt=sqrt(vk->fitV[0]*vk->fitV[0] + vk->fitV[1]*vk->fitV[1]+ vk->fitV[2]*vk->fitV[2]);
+	    if( dstFromExtrapPnt>vkalShiftToTrigExtrapolation/2. && it < vrtForCFT.IterationNumber-15){
+	      forcedExtrapolation=true;
+	      continue;          // Make another extrapolation exactly to found vertex position
+            }
+	    break;
+          }
+	}
 	chi2min = std::min(chi2min,chi22s);
 	if ((chi2min*100. < chi22s) && (chi22s>std::max( (2*NTRK-3)*10., 100.)) && (it>5)){
 	   //std::cout<<" DIVERGENCE="<<chi22s<<" Ratio="<<chi22s/chi2min<<'\n';
diff --git a/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/CFitCascade.cxx b/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/CFitCascade.cxx
index b80ecd1b39f..151bc5540b0 100755
--- a/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/CFitCascade.cxx
+++ b/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/CFitCascade.cxx
@@ -41,7 +41,7 @@ extern std::array<double, 4> getFitParticleMom( const VKTrack *, double);
 extern void setFittedMatrices(const double * , long int , std::vector<int> &, std::vector< std::vector<double> > &, CascadeEvent& );
 extern std::vector<double> transformCovar(int , double **, const std::vector<double>& );
 extern double cfVrtDstSig( VKVertex * , bool );
-extern void robtest(VKVertex * , long int );
+extern void robtest(VKVertex * , int ifl, int nIteration=10);
 
 extern int fixPseudoTrackPt(long int NPar, double * fullMtx, double * LSide, CascadeEvent&);
 extern void getNewCov(const double *OldCov, const double* Der, double* Cov, long int DIM) noexcept;
@@ -368,8 +368,8 @@ int processCascade(CascadeEvent & cascadeEvent_ )
           vpderiv(vk->passWithTrkCov, vk->FVC.Charge, dparst, vk->fitCovXYZMom, 
              vk->FVC.vrt, vk->FVC.covvrt, vk->FVC.cvder, vk->FVC.ywgt, vk->FVC.rv0, (vk->vk_fitterControl).get());
        }
-       if (vk->vk_fitterControl->vk_forcft.irob != 0) {robtest(vk, 0);}  // ROBUSTIFICATION new data structure
-       if (vk->vk_fitterControl->vk_forcft.irob != 0) {robtest(vk, 1);}  // ROBUSTIFICATION new data structure
+       if (vk->vk_fitterControl->vk_forcft.irob != 0) {robtest(vk, 0, Iter);}  // ROBUSTIFICATION new data structure
+       if (vk->vk_fitterControl->vk_forcft.irob != 0) {robtest(vk, 1, Iter);}  // ROBUSTIFICATION new data structure
        IERR = fitVertexCascade( vk, 1 );   if(IERR) break;              //with passNear for last vertex in cascade if needed
        IERR = setVTrackMass(vk);           if(IERR) break;               //mass of combined particle
 //
diff --git a/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/RobTest.cxx b/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/RobTest.cxx
index e7bb9533102..44ee7e8fd82 100755
--- a/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/RobTest.cxx
+++ b/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/RobTest.cxx
@@ -9,12 +9,10 @@
 
 namespace Trk {
 
-
-//extern void digx(double*, double*, double*, long int , long int );
  
 extern void vkGetEigVect(const double ci[], double d[], double vect[], int n);
 
-void robtest(VKVertex * vk, long int ifl)
+void robtest(VKVertex * vk, int ifl, int nIteration=10)
 {
     long int i, j, k, kk, it;
     double rob, res, c[5], darg, absX, roba[5];
@@ -40,26 +38,15 @@ void robtest(VKVertex * vk, long int ifl)
     double    Scl = vk->vk_fitterControl->vk_forcft.RobustScale;  //Tuning constant
     double    C;                          // Breakdown constant
 
+    if(!vk->vk_fitterControl->m_frozenVersionForBTagging)Scl *= (1.+exp(3.-nIteration)); //Annealing
+
     if ( ifl == 0) {                               /* FILLING OF EIGENVALUES AND VECTORS */
-	for (it = 0; it < NTRK ; ++it) {               /* RESTORE MATRIX */
+        for (it = 0; it < NTRK ; ++it) {               /* RESTORE MATRIX */
             VKTrack *trk=vk->TrackList[it].get();
             if(trk->Id < 0) continue;  // Not a real track
-	    //k = 0;   double dest[5][5];
-	    //for (i = 0; i < 5; ++i) {
-	    //for (j = 0; j <= i; ++j) {
-	    //      dest[i][j] = trk->WgtM[k];
-	    //      dest[j][i] = trk->WgtM[k];
-	    //	  ++k;
-	    //	}
-	    //}
-	    //digx(&dest[0][0], &(vk->TrackList[it]->e[0]), &(vk->TrackList[it]->v[0][0]), 5, 1);
             vkGetEigVect(trk->WgtM, trk->e ,&(trk->v[0][0]), 5);
-	}
-//std::cout.precision(9); std::cout<<"Rob="<<irob<<'\n';
-//std::cout<<" Ini="<<vk->TrackList[0]->WgtM[0]<<", "<<vk->TrackList[0]->WgtM[1]<<", "<<vk->TrackList[0]->WgtM[2]
-//            <<", "<<vk->TrackList[0]->WgtM[3]<<", "<<vk->TrackList[0]->WgtM[4]<<", "<<vk->TrackList[0]->WgtM[5]
-//            <<", "<<vk->TrackList[0]->WgtM[6]<<", "<<vk->TrackList[0]->WgtM[7]<<", "<<vk->TrackList[0]->WgtM[8]<<'\n';
-	return;
+        }
+        return;
     }
 /* -- */
     double    halfPi=M_PI/2.;
@@ -74,9 +61,6 @@ void robtest(VKVertex * vk, long int ifl)
           c[3] +=   trk->rmnd[k] * trk->v[3][k];
           c[4] +=   trk->rmnd[k] * trk->v[4][k];
         }
-//std::cout<<"rm="<<trk->rmnd[0]<<", "<<trk->rmnd[1]<<", "<<trk->rmnd[2]<<
-//            ", "<<trk->rmnd[3]<<", "<<trk->rmnd[4]<<", "<<'\n';
-//std::cout<<" c="<<c[0]<<", "<<c[1]<<", "<<c[2]<<", "<<c[3]<<", "<<c[4]<<", "<<'\n';
 	for (k = 0; k < 5; ++k) {
 	  darg = c[k]*c[k]*trk->e[k];
 	  if(darg < 1.e-10) darg = 1.e-10;
@@ -102,7 +86,6 @@ void robtest(VKVertex * vk, long int ifl)
           roba[k] = rob;
           if(rob>0.99)roba[k] = 1.; //To improve precision
 	}
-//std::cout<<"robn="<<roba[0]<<", "<<roba[1]<<", "<<roba[2]<<", "<<roba[3]<<", "<<roba[4]<<", "<<irob<<'\n';
 	for (i = 0; i < 5; ++i) if(roba[i]<1.e-3)roba[i]=1.e-3;
 	kk = 0;
 	for (i = 0; i < 5; ++i) {
@@ -118,9 +101,6 @@ void robtest(VKVertex * vk, long int ifl)
 	vk->vk_fitterControl->vk_forcft.robres[it] = roba[0] * roba[1] * roba[2] * roba[3] * roba[4];
 	if(vk->vk_fitterControl->vk_forcft.robres[it]>1.)vk->vk_fitterControl->vk_forcft.robres[it]=1.;
     }
-//std::cout<<" Fin="<<vk->TrackList[0]->WgtM[0]<<", "<<vk->TrackList[0]->WgtM[1]<<", "<<vk->TrackList[0]->WgtM[2]
-//            <<", "<<vk->TrackList[0]->WgtM[3]<<", "<<vk->TrackList[0]->WgtM[4]<<", "<<vk->TrackList[0]->WgtM[5]
-//            <<", "<<vk->TrackList[0]->WgtM[6]<<", "<<vk->TrackList[0]->WgtM[7]<<", "<<vk->TrackList[0]->WgtM[8]<<'\n';
 } 
 
 
diff --git a/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/TrkVKalVrtCoreBase.cxx b/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/TrkVKalVrtCoreBase.cxx
index d2562b6a246..408bb7f04d6 100644
--- a/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/TrkVKalVrtCoreBase.cxx
+++ b/Tracking/TrkVertexFitter/TrkVKalVrtCore/src/TrkVKalVrtCoreBase.cxx
@@ -30,7 +30,8 @@ namespace Trk {
       m_vrtMassTot(-1),
       m_vrtMassError(-1),
       m_cascadeEvent(nullptr),
-      vk_forcft()
+      vk_forcft(),
+      m_frozenVersionForBTagging(false)
   { 
   }
   VKalVrtControl::VKalVrtControl(const VKalVrtControl & src)
@@ -38,7 +39,8 @@ namespace Trk {
       m_vrtMassTot(src.m_vrtMassTot),
       m_vrtMassError(src.m_vrtMassError),
       m_cascadeEvent(src.m_cascadeEvent),
-      vk_forcft(src.vk_forcft)
+      vk_forcft(src.vk_forcft),
+      m_frozenVersionForBTagging(src.m_frozenVersionForBTagging)
   { 
   }
 
diff --git a/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/TrkVKalVrtFitter.h b/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/TrkVKalVrtFitter.h
index 6f39d20a34f..bc42604898d 100755
--- a/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/TrkVKalVrtFitter.h
+++ b/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/TrkVKalVrtFitter.h
@@ -351,6 +351,7 @@ namespace Trk{
         bool m_useZPointingCnst;
         bool m_usePassNear;
         bool m_usePassWithTrkErr;
+	bool m_frozenVersionForBTagging;
         void initCnstList();
 
         //  Track material effects control
@@ -426,6 +427,7 @@ namespace Trk{
         bool m_useZPointingCnst = false;
         bool m_usePassNear = false;
         bool m_usePassWithTrkErr = false;
+        bool m_frozenVersionForBTagging = false;
 
         std::vector<double> m_VertexForConstraint;
         std::vector<double> m_CovVrtForConstraint;
diff --git a/Tracking/TrkVertexFitter/TrkVKalVrtFitter/src/SetFitOptions.cxx b/Tracking/TrkVertexFitter/TrkVKalVrtFitter/src/SetFitOptions.cxx
index 35a4dbd4a50..d1c4c391ee7 100755
--- a/Tracking/TrkVertexFitter/TrkVKalVrtFitter/src/SetFitOptions.cxx
+++ b/Tracking/TrkVertexFitter/TrkVKalVrtFitter/src/SetFitOptions.cxx
@@ -57,6 +57,8 @@ namespace Trk{
     if(state.m_usePassNear)      state.m_vkalFitControl.setUsePassNear(1);
     if(state.m_usePassWithTrkErr)state.m_vkalFitControl.setUsePassNear(2);
 
+    if(state.m_frozenVersionForBTagging)state.m_vkalFitControl.m_frozenVersionForBTagging=true;
+
     if(m_IterationPrecision>0.) state.m_vkalFitControl.setIterationPrec(m_IterationPrecision);
     if(m_IterationNumber)  state.m_vkalFitControl.setIterationNum(m_IterationNumber);
  }
diff --git a/Tracking/TrkVertexFitter/TrkVKalVrtFitter/src/TrkVKalVrtFitter.cxx b/Tracking/TrkVertexFitter/TrkVKalVrtFitter/src/TrkVKalVrtFitter.cxx
index 3f9a92c60f4..3d3fa1f9143 100755
--- a/Tracking/TrkVertexFitter/TrkVKalVrtFitter/src/TrkVKalVrtFitter.cxx
+++ b/Tracking/TrkVertexFitter/TrkVKalVrtFitter/src/TrkVKalVrtFitter.cxx
@@ -54,7 +54,8 @@ TrkVKalVrtFitter:: TrkVKalVrtFitter(const std::string& type,
     m_usePointingCnst(false),
     m_useZPointingCnst(false),
     m_usePassNear(false),
-    m_usePassWithTrkErr(false)
+    m_usePassWithTrkErr(false),
+    m_frozenVersionForBTagging(false)
    {
     declareInterface<IVertexFitter>(this);
     declareInterface<ITrkVKalVrtFitter>(this);
@@ -93,6 +94,7 @@ TrkVKalVrtFitter:: TrkVKalVrtFitter(const std::string& type,
     declareProperty("useZPointingCnst",       m_useZPointingCnst);
     declareProperty("usePassNearCnst",        m_usePassNear);
     declareProperty("usePassWithTrkErrCnst",  m_usePassWithTrkErr);
+    declareProperty("FrozenVersionForBTagging",  m_frozenVersionForBTagging);
 //
 
 /*--------------------------------------------------------------------------*/
@@ -177,6 +179,7 @@ StatusCode TrkVKalVrtFitter::initialize()
     if(msgLvl(MSG::DEBUG))msg(MSG::DEBUG)<< "TrkVKalVrtFitter initialize() successful" << endmsg;
     if(msgLvl(MSG::DEBUG)){
        msg(MSG::DEBUG)<< "TrkVKalVrtFitter configuration:" << endmsg;
+       msg(MSG::DEBUG)<< "   Frozen version for BTagging:          "<< m_frozenVersionForBTagging <<endmsg;
        msg(MSG::DEBUG)<< "   A priori vertex constraint:           "<< m_useAprioriVertex <<endmsg;
        msg(MSG::DEBUG)<< "   Angle dTheta=0 constraint:            "<< m_useThetaCnst <<endmsg;
        msg(MSG::DEBUG)<< "   Angle dPhi=0 constraint:              "<< m_usePhiCnst <<endmsg;
@@ -254,6 +257,7 @@ void TrkVKalVrtFitter::initState (const EventContext& ctx, State& state) const
   state.m_Robustness = m_Robustness;
   state.m_RobustScale = m_RobustScale;
   state.m_MassInputParticles = m_c_MassInputParticles;
+  state.m_frozenVersionForBTagging = m_frozenVersionForBTagging;
 }
 
 /** Interface for MeasuredPerigee with starting point */
-- 
GitLab