CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoVertex/BeamSpotProducer/src/FcnBeamSpotFitPV.cc

Go to the documentation of this file.
00001 #include "RecoVertex/BeamSpotProducer/interface/FcnBeamSpotFitPV.h"
00002 #include "Math/SVector.h"
00003 #include "Math/SMatrix.h"
00004 // #include "Math/SMatrixDfwd.h"
00005 //#include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 
00007 using namespace std;
00008 
00009 //
00010 // constructor from vertex data
00011 //
00012 FcnBeamSpotFitPV::FcnBeamSpotFitPV(const vector<BeamSpotFitPVData>& data) : 
00013   data_(data), errorDef_(1.) { 
00014   //
00015   // default: no additional cuts
00016   //
00017   lowerLimits_[0] = lowerLimits_[1] = lowerLimits_[2] = -1.e30;
00018   upperLimits_[0] = upperLimits_[1] = upperLimits_[2] =  1.e30;
00019 }
00020 
00021 void 
00022 FcnBeamSpotFitPV::setLimits (float xmin, float xmax,
00023                           float ymin, float ymax,
00024                           float zmin, float zmax) 
00025 {
00026   lowerLimits_[0] = xmin;
00027   lowerLimits_[1] = ymin;
00028   lowerLimits_[2] = zmin;
00029   upperLimits_[0] = xmax;
00030   upperLimits_[1] = ymax;
00031   upperLimits_[2] = zmax;
00032 }
00033 
00034 unsigned int
00035 FcnBeamSpotFitPV::nrOfVerticesUsed () const
00036 {
00037   //
00038   // count vertices imposing the current limits
00039   //
00040   unsigned int nVtx = 0;
00041   double v1(0);
00042   double v2(0);
00043   double v3(0);
00044   for ( vector<BeamSpotFitPVData>::const_iterator ipv=data_.begin();
00045         ipv!=data_.end(); ++ipv ) {
00046     v1 = (*ipv).position[0];
00047     if ( v1<lowerLimits_[0] || v1>upperLimits_[0] )  continue;
00048     v2 = (*ipv).position[1];
00049     if ( v2<lowerLimits_[1] || v2>upperLimits_[1] )  continue;
00050     v3 = (*ipv).position[2];
00051     if ( v3<lowerLimits_[2] || v3>upperLimits_[2] )  continue;
00052 
00053     ++nVtx;
00054   }
00055 
00056   return nVtx;
00057 }
00058 
00059 double
00060 FcnBeamSpotFitPV::operator() (const std::vector<double>& pars) const
00061 {
00062   //
00063   // fit parameters
00064   //
00065   double vb1 = pars[0];
00066   double vb2 = pars[1];
00067   double vb3 = pars[2];
00068   double sigb1 = pars[3]; 
00069   double corrb12 = pars[4];
00070   double sigb2 = pars[5];
00071   double dxdz = pars[6];
00072   double dydz = pars[7];
00073   double sigb3 = pars[8];
00074   double escale = pars[9];
00075   //
00076   // covariance matrix of the beamspot distribution
00077   //
00078   typedef ROOT::Math::SVector<double,3> Vector3D;
00079   typedef ROOT::Math::SMatrix<double,3,3,ROOT::Math::MatRepSym<double,3> > Matrix3D;
00080   Matrix3D covb;
00081   double varb1 = sigb1*sigb1;
00082   double varb2 = sigb2*sigb2;
00083   double varb3 = sigb3*sigb3;
00084 // parametrisation: rotation (dx/dz, dy/dz); covxy
00085   covb(0,0) = varb1;
00086   covb(1,0) = covb(0,1) = corrb12*sigb1*sigb2;
00087   covb(1,1) = varb2;
00088   covb(2,0) = covb(0,2) = dxdz*(varb3-varb1)-dydz*covb(1,0);
00089   covb(2,1) = covb(1,2) = dydz*(varb3-varb2)-dxdz*covb(1,0);
00090   covb(2,2) = varb3;
00091 
00092   //
00093   // calculation of the likelihood function
00094   //
00095   double sumLL(0);
00096   double v1(0);
00097   double v2(0);
00098   double v3(0);
00099   double ev1(0);
00100   double corr12(0);
00101   double ev2(0);
00102   double corr13(0);
00103   double corr23(0);
00104   double ev3(0);
00105   //
00106   // vertex - beamspot difference and total covariance matrix
00107   //
00108   Vector3D dv;
00109   Matrix3D cov;
00110   Matrix3D wgt;
00111   //
00112   // iteration over vertices
00113   //
00114   for ( vector<BeamSpotFitPVData>::const_iterator ipv=data_.begin();
00115         ipv!=data_.end(); ++ipv ) {
00116     //
00117     // additional selection
00118     //
00119     v1 = (*ipv).position[0];
00120     if ( v1<lowerLimits_[0] || v1>upperLimits_[0] )  continue;
00121     v2 = (*ipv).position[1];
00122     if ( v2<lowerLimits_[1] || v2>upperLimits_[1] )  continue;
00123     v3 = (*ipv).position[2];
00124     if ( v3<lowerLimits_[2] || v3>upperLimits_[2] )  continue;
00125     //
00126     // vertex errors (after scaling) and correlations
00127     //
00128     ev1 = (*ipv).posError[0];
00129     corr12 = (*ipv).posCorr[0];
00130     ev2 = (*ipv).posError[1];
00131     corr13 = (*ipv).posCorr[1];
00132     corr23 = (*ipv).posCorr[2];
00133     ev3 = (*ipv).posError[2];
00134     ev1 *= escale;
00135     ev2 *= escale;
00136     ev3 *= escale;
00137     //
00138     // vertex covariance matrix
00139     //
00140     cov(0,0) = ev1*ev1;
00141     cov(1,0) = cov(0,1) = ev1*ev2*corr12;
00142     cov(1,1) = ev2*ev2;
00143     cov(2,0) = cov(0,2) = ev1*ev3*corr13;
00144     cov(2,1) = cov(1,2) = ev2*ev3*corr23;
00145     cov(2,2) = ev3*ev3;
00146     //
00147     // total covariance and weight matrix
00148     //
00149     cov += covb;
00150     int ifail;
00151     wgt = cov.Inverse(ifail);
00152     if ( ifail ) {
00153       //edm::LogWarning("FcnBeamSpotFitPV") 
00154       cout << "Inversion failed" << endl;
00155       return -1.e30;
00156     }
00157     //
00158     // difference of vertex and beamspot positions
00159     //
00160     dv(0) = v1 - vb1;
00161     dv(1) = v2 - vb2;
00162     dv(2) = v3 - vb3;
00163     //
00164     // exponential term and normalization
00165     // (neglecting the additional cut)
00166     //
00167     sumLL += ROOT::Math::Similarity(dv,wgt);
00168     double det;
00169     cov.Det2(det);
00170     sumLL += log(det);
00171   }
00172 
00173   return sumLL;
00174 }
00175