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(std::vector<RefCountedKinematicParticle> part) {
00052 return fit(part, 0, 0);
00053 }
00054
00058 RefCountedKinematicTree fit(std::vector<RefCountedKinematicParticle> part,
00059 MultiTrackKinematicConstraintT< nTrk, nConstraint> * cs) {
00060 return fit(part, cs, 0);
00061 };
00062
00066 RefCountedKinematicTree fit(std::vector<RefCountedKinematicParticle> part,
00067 MultiTrackKinematicConstraintT< nTrk, nConstraint> * cs,
00068 GlobalPoint * pt);
00069
00070
00071 int getNit() const;
00072
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;
00086 int theMaxStep;
00087 float theMaxReducedChiSq;
00088 float theMinChiSqImprovement;
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(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
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
00173 GlobalPoint linPoint = (pt!=0) ? *pt : finder->getLinearizationPoint(fStates);
00174
00175
00176 ROOT::Math::SVector<double,3+7*nTrk> inPar;
00177 ROOT::Math::SVector<double,3+7*nTrk> finPar;
00178
00179 ROOT::Math::SMatrix<double, 3+7*nTrk,3+7*nTrk ,ROOT::Math::MatRepSym<double,3+7*nTrk> > inCov;
00180
00181
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
00199
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
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
00223
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()) {
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
00280
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