CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoVertex/KinematicFit/interface/KinematicConstrainedVertexFitterT.h

Go to the documentation of this file.
00001 #ifndef KinematicConstrainedVertexFitterT_H
00002 #define KinematicConstrainedVertexFitterT_H
00003 
00004 #include "RecoVertex/KinematicFitPrimitives/interface/RefCountedKinematicTree.h"
00005 #include "RecoVertex/KinematicFitPrimitives/interface/MultiTrackKinematicConstraintT.h"
00006 #include "RecoVertex/VertexTools/interface/LinearizationPointFinder.h"
00007 #include "RecoVertex/KinematicFit/interface/KinematicConstrainedVertexUpdatorT.h"
00008 #include "RecoVertex/KinematicFit/interface/VertexKinematicConstraintT.h"
00009 
00010 #include "RecoVertex/KinematicFit/interface/ConstrainedTreeBuilderT.h"
00011 
00012 #include "MagneticField/Engine/interface/MagneticField.h"
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014 
00024 template < int nTrk, int nConstraint> class KinematicConstrainedVertexFitterT{
00025 
00026 public:
00027   
00031   explicit KinematicConstrainedVertexFitterT(const MagneticField* ifield);
00032   
00036   KinematicConstrainedVertexFitterT(const MagneticField* ifield, const LinearizationPointFinder& fnd);
00037   
00038   ~KinematicConstrainedVertexFitterT();
00039   
00045   void setParameters(const edm::ParameterSet& pSet);
00046   
00051   RefCountedKinematicTree fit(const std::vector<RefCountedKinematicParticle> &part) {
00052     return fit(part, 0, 0);
00053   }
00054   
00058   RefCountedKinematicTree fit(const std::vector<RefCountedKinematicParticle> &part,
00059                               MultiTrackKinematicConstraintT< nTrk, nConstraint> * cs) {
00060     return fit(part, cs, 0);
00061   };
00062   
00066   RefCountedKinematicTree fit(const std::vector<RefCountedKinematicParticle> &part,
00067                               MultiTrackKinematicConstraintT< nTrk, nConstraint> * cs,
00068                               GlobalPoint * pt);
00069   
00070   //return the number of iterations
00071  int getNit() const;
00072   //return the value of the constraint equation
00073   float getCSum() const;
00074   
00075 private:
00076   
00077   void defaultParameters();
00078   
00079   const MagneticField* field;
00080   LinearizationPointFinder * finder;                                   
00081   KinematicConstrainedVertexUpdatorT<nTrk,nConstraint> * updator;
00082   VertexKinematicConstraintT * vCons;
00083   ConstrainedTreeBuilderT * tBuilder;
00084 
00085   float theMaxDelta; //maximum (delta parameter)^2/(sigma parameter)^2 per iteration for convergence
00086   int theMaxStep;                                      
00087   float theMaxReducedChiSq; //max of initial (after 2 iterations) chisq/dof value
00088   float theMinChiSqImprovement; //minimum required improvement in chisq to avoid fit termination for cases exceeding theMaxReducedChiSq
00089 
00090 
00091   int iterations;
00092   float csum;
00093 };
00094 
00095 
00096 #include "RecoVertex/KinematicFit/interface/InputSort.h"
00097 #include "RecoVertex/LinearizationPointFinders/interface/DefaultLinearizationPointFinder.h"
00098 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicVertexFactory.h"
00099 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00100 
00101 
00102 
00103 template < int nTrk, int nConstraint> 
00104 KinematicConstrainedVertexFitterT< nTrk, nConstraint>::KinematicConstrainedVertexFitterT(const MagneticField* ifield) : 
00105   field(ifield)
00106 {
00107   finder = new DefaultLinearizationPointFinder();
00108   vCons = new VertexKinematicConstraintT();
00109   updator = new KinematicConstrainedVertexUpdatorT<nTrk,nConstraint>();
00110   tBuilder = new ConstrainedTreeBuilderT;
00111   defaultParameters();
00112   iterations = -1;
00113   csum = -1000.0;
00114 }
00115 
00116 template < int nTrk, int nConstraint> 
00117 KinematicConstrainedVertexFitterT< nTrk, nConstraint>::KinematicConstrainedVertexFitterT(const MagneticField* ifield, const LinearizationPointFinder& fnd) : 
00118   field(ifield)
00119 {
00120   finder = fnd.clone();
00121   vCons = new VertexKinematicConstraintT();
00122   updator = new KinematicConstrainedVertexUpdatorT<nTrk,nConstraint>();
00123   tBuilder = new ConstrainedTreeBuilderT;
00124   defaultParameters();
00125   iterations = -1;
00126   csum = -1000.0;
00127 }
00128 
00129 template < int nTrk, int nConstraint> 
00130 KinematicConstrainedVertexFitterT< nTrk, nConstraint>::~KinematicConstrainedVertexFitterT()
00131 {
00132   delete finder;
00133   delete vCons;
00134   delete updator;
00135   delete tBuilder;
00136 }
00137 
00138 template < int nTrk, int nConstraint> 
00139 void KinematicConstrainedVertexFitterT< nTrk, nConstraint>::setParameters(const edm::ParameterSet& pSet)
00140 {
00141   theMaxDelta = pSet.getParameter<double>("maxDelta");
00142   theMaxStep = pSet.getParameter<int>("maxNbrOfIterations");
00143   theMaxReducedChiSq = pSet.getParameter<double>("maxReducedChiSq");
00144   theMinChiSqImprovement = pSet.getParameter<double>("minChiSqImprovement");
00145 }
00146 
00147 template < int nTrk, int nConstraint> 
00148 void KinematicConstrainedVertexFitterT< nTrk, nConstraint>::defaultParameters()
00149 {
00150   theMaxDelta = 0.01;
00151   theMaxStep = 1000;
00152   theMaxReducedChiSq = 225.;
00153   theMinChiSqImprovement = 50.;
00154  
00155 }
00156 
00157 template < int nTrk, int nConstraint> 
00158 RefCountedKinematicTree 
00159 KinematicConstrainedVertexFitterT< nTrk, nConstraint>::fit(const std::vector<RefCountedKinematicParticle> &part,
00160                                                            MultiTrackKinematicConstraintT< nTrk, nConstraint> * cs,
00161                                                            GlobalPoint * pt)
00162 {
00163    assert( nConstraint==0 || cs!=0);
00164    if(part.size()!=nTrk) throw VertexException("KinematicConstrainedVertexFitterT::input states are not nTrk");
00165   
00166   //sorting out the input particles
00167   InputSort iSort;
00168   std::pair<std::vector<RefCountedKinematicParticle>, std::vector<FreeTrajectoryState> > input = iSort.sort(part);
00169   const std::vector<RefCountedKinematicParticle> & particles  = input.first;
00170   const std::vector<FreeTrajectoryState> & fStates = input.second;
00171   
00172   // linearization point:
00173   GlobalPoint linPoint  = (pt!=0) ? *pt :  finder->getLinearizationPoint(fStates);
00174   
00175   //initial parameters:
00176   ROOT::Math::SVector<double,3+7*nTrk> inPar; //3+ 7*ntracks
00177   ROOT::Math::SVector<double,3+7*nTrk> finPar; //3+ 7*ntracks
00178   
00179   ROOT::Math::SMatrix<double, 3+7*nTrk,3+7*nTrk ,ROOT::Math::MatRepSym<double,3+7*nTrk> > inCov;
00180   
00181   //making initial vector of parameters and initial particle-related covariance
00182   int nSt = 0;
00183   std::vector<KinematicState> lStates(nTrk);
00184   for(std::vector<RefCountedKinematicParticle>::const_iterator i = particles.begin(); i!=particles.end(); i++)
00185     {
00186       lStates[nSt] = (*i)->stateAtPoint(linPoint);
00187       KinematicState const & state = lStates[nSt];
00188       if (!state.isValid()) {
00189         LogDebug("KinematicConstrainedVertexFitter")
00190           << "State is invalid at point: "<<linPoint<<std::endl;
00191         return ReferenceCountingPointer<KinematicTree>(new KinematicTree());
00192       }
00193       inPar.Place_at(state.kinematicParameters().vector(),3+7*nSt);
00194       inCov.Place_at(state.kinematicParametersError().matrix(),3 + 7*nSt,3 + 7*nSt);
00195       ++nSt;
00196     }
00197   
00198   //initial vertex error matrix components (huge error method)
00199   //and vertex related initial vector components
00200   double in_er = 100.;
00201   inCov(0,0) = in_er;
00202   inCov(1,1) = in_er;
00203   inCov(2,2) = in_er;
00204   
00205   inPar(0) = linPoint.x();
00206   inPar(1) = linPoint.y();
00207   inPar(2) = linPoint.z();
00208   
00209   //constraint equations value and number of iterations
00210   double eq;
00211   int nit = 0;
00212   iterations = 0;
00213   csum = 0.0;
00214   
00215   GlobalPoint lPoint  = linPoint;
00216   RefCountedKinematicVertex rVtx;
00217   ROOT::Math::SMatrix<double, 3+7*nTrk,3+7*nTrk ,ROOT::Math::MatRepSym<double,3+7*nTrk> > refCCov;
00218   
00219   double chisq = 1e6;
00220   bool convergence = false;
00221   
00222   //iterarions over the updator: each time updated parameters
00223   //are taken as new linearization point
00224   do{
00225     eq = 0.;
00226     refCCov = inCov;
00227     std::vector<KinematicState> oldStates = lStates;
00228     GlobalVector mf = field->inInverseGeV(lPoint);
00229     rVtx = updator->update(inPar,refCCov,lStates,lPoint,mf,cs);
00230     if (particles.size() != lStates.size() || rVtx == 0) {
00231       LogDebug("KinematicConstrainedVertexFitter")
00232         << "updator failure\n";
00233       return ReferenceCountingPointer<KinematicTree>(new KinematicTree());
00234     }
00235     
00236     double newchisq = rVtx->chiSquared();
00237     if ( nit>2 && newchisq > theMaxReducedChiSq*rVtx->degreesOfFreedom() && (newchisq-chisq) > (-theMinChiSqImprovement) ) {
00238       LogDebug("KinematicConstrainedVertexFitter")
00239         << "bad chisq and insufficient improvement, bailing\n";
00240       return ReferenceCountingPointer<KinematicTree>(new KinematicTree());
00241     }
00242     chisq = newchisq;
00243     
00244     
00245     
00246     const GlobalPoint &newPoint = rVtx->position();
00247     
00248     double maxDelta = 0.0;
00249     
00250     double deltapos[3];
00251     deltapos[0] = newPoint.x() - lPoint.x();
00252     deltapos[1] = newPoint.y() - lPoint.y();
00253     deltapos[2] = newPoint.z() - lPoint.z();
00254     for (int i=0; i<3; ++i) {
00255       double delta = deltapos[i]*deltapos[i]/rVtx->error().matrix_new()(i,i);
00256       if (delta>maxDelta) maxDelta = delta;
00257     }
00258     
00259     for (std::vector<KinematicState>::const_iterator itold = oldStates.begin(), itnew = lStates.begin();
00260          itnew!=lStates.end(); ++itold,++itnew) {
00261       for (int i=0; i<7; ++i) {
00262         double deltapar = itnew->kinematicParameters()(i) - itold->kinematicParameters()(i);
00263         double delta = deltapar*deltapar/itnew->kinematicParametersError().matrix()(i,i);
00264         if (delta>maxDelta) maxDelta = delta;
00265       }
00266     }
00267     
00268     lPoint = newPoint;
00269     
00270     nit++;
00271     convergence = maxDelta<theMaxDelta || (nit==theMaxStep && maxDelta<4.0*theMaxDelta);
00272     
00273   }while(nit<theMaxStep && !convergence);
00274 
00275   if (!convergence) {
00276     return ReferenceCountingPointer<KinematicTree>(new KinematicTree());
00277   } 
00278   
00279   // std::cout << "new full cov matrix" << std::endl;
00280   // std::cout << refCCov << std::endl;  
00281   
00282   iterations = nit;
00283   csum = eq;
00284   
00285   return  tBuilder->buildTree<nTrk>(particles, lStates, rVtx, refCCov);
00286   
00287 }
00288 
00289 template < int nTrk, int nConstraint> 
00290 int KinematicConstrainedVertexFitterT< nTrk, nConstraint>::getNit() const {
00291   return iterations;
00292 }
00293 
00294 template < int nTrk, int nConstraint> 
00295 float KinematicConstrainedVertexFitterT< nTrk, nConstraint>::getCSum() const {
00296   return csum;
00297 }
00298 
00299 #endif