CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/DataFormats/DTRecHit/src/DTRecSegment4D.cc

Go to the documentation of this file.
00001 
00009 /* This Class Header */
00010 #include "DataFormats/DTRecHit/interface/DTRecSegment4D.h"
00011 
00012 /* Collaborating Class Header */
00013 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
00014 #include "FWCore/Utilities/interface/Exception.h"
00015 /* C++ Headers */
00016 
00017 
00018 
00019 DTRecSegment4D::DTRecSegment4D(const DTChamberRecSegment2D& phiSeg,
00020                                const DTSLRecSegment2D& zedSeg,  
00021                                const LocalPoint& posZInCh,
00022                                const LocalVector& dirZInCh):
00023   RecSegment(phiSeg.chamberId()), 
00024   theProjection(full),
00025   thePhiSeg(phiSeg),
00026   theZedSeg(zedSeg),
00027   theDimension(4)
00028 {
00029   // Check consistency of 2 sub-segments
00030   if(DTChamberId(phiSeg.geographicalId().rawId()) != DTChamberId(zedSeg.geographicalId().rawId()))
00031     throw cms::Exception("DTRecSegment4D")
00032       <<"the z Segment and the phi segment have different chamber id"<<std::endl;
00033 
00034   // The position of 2D segments are defined in the SL frame: I must first
00035   // extrapolate that position at the Chamber reference plane
00036   LocalPoint posZAt0 = posZInCh +
00037     dirZInCh * (-posZInCh.z())/cos(dirZInCh.theta());
00038 
00039 
00040   thePosition=LocalPoint(phiSeg.localPosition().x(),posZAt0.y(),0.);
00041   LocalVector dirPhiInCh=phiSeg.localDirection();
00042 
00043   // given the actual definition of chamber refFrame, (with z poiniting to IP),
00044   // the zed component of direction is negative.
00045   theDirection=LocalVector(dirPhiInCh.x()/fabs(dirPhiInCh.z()),
00046                            dirZInCh.y()/fabs(dirZInCh.z()),
00047                            -1.);
00048   theDirection=theDirection.unit();
00049 
00050   // set cov matrix
00051   theCovMatrix=AlgebraicSymMatrix(4);
00052   theCovMatrix[0][0]=phiSeg.covMatrix()[0][0]; //sigma (dx/dz)
00053   theCovMatrix[0][2]=phiSeg.covMatrix()[0][1]; //cov(dx/dz,x)
00054   theCovMatrix[2][2]=phiSeg.covMatrix()[1][1]; //sigma (x)
00055   setCovMatrixForZed(posZInCh);
00056 }
00057 
00058 
00059 DTRecSegment4D::DTRecSegment4D(const DTChamberRecSegment2D& phiSeg) :
00060   RecSegment(phiSeg.chamberId()), 
00061   theProjection(phi),
00062   thePhiSeg(phiSeg),
00063   theZedSeg(DTSLRecSegment2D()),
00064   theDimension(2)
00065 {
00066   thePosition=thePhiSeg.localPosition();
00067   
00068   theDirection=thePhiSeg.localDirection();
00069 
00070   // set cov matrix
00071   theCovMatrix=AlgebraicSymMatrix(4);
00072   theCovMatrix[0][0]=phiSeg.covMatrix()[0][0]; //sigma (dx/dz)
00073   theCovMatrix[0][2]=phiSeg.covMatrix()[0][1]; //cov(dx/dz,x)
00074   theCovMatrix[2][2]=phiSeg.covMatrix()[1][1]; //sigma (x)
00075 }
00076 
00077 
00078 DTRecSegment4D::DTRecSegment4D(const DTSLRecSegment2D& zedSeg,
00079                                const LocalPoint& posZInCh,
00080                                const LocalVector& dirZInCh) :
00081   RecSegment(zedSeg.superLayerId().chamberId()),
00082   theProjection(Z),
00083   thePhiSeg(DTChamberRecSegment2D()),
00084   theZedSeg(zedSeg),
00085   theDimension(2)
00086 {
00087   
00088   LocalPoint posZAt0=posZInCh+
00089     dirZInCh*(-posZInCh.z()/cos(dirZInCh.theta()));
00090   
00091   thePosition=posZAt0;
00092   theDirection = dirZInCh;
00093 
00094   // set cov matrix
00095   theCovMatrix=AlgebraicSymMatrix(4);
00096   setCovMatrixForZed(posZInCh);
00097 }
00098 
00099 
00100 DTRecSegment4D::~DTRecSegment4D() {}
00101 
00102 
00103 AlgebraicVector DTRecSegment4D::parameters() const {
00104   if (dimension()==4) {
00105     // (dx/dz,dy/dz,x,y)
00106     AlgebraicVector result(4);
00107     result[2] = thePosition.x();
00108     result[3] = thePosition.y();
00109     result[0] = theDirection.x()/theDirection.z();
00110     result[1] = theDirection.y()/theDirection.z();    
00111     return result;
00112   } 
00113 
00114   AlgebraicVector result(2);
00115   if (theProjection==phi) {
00116     // (dx/dz,x)  
00117     result[1] = thePosition.x();
00118     result[0] = theDirection.x()/theDirection.z();
00119   } else if (theProjection==Z) {
00120     // (dy/dz,y) (note we are in the chamber r.f.)
00121     result[1] = thePosition.y();
00122     result[0] = theDirection.y()/theDirection.z();
00123   }
00124   return result;
00125 }
00126 
00127 
00128 AlgebraicSymMatrix DTRecSegment4D::parametersError() const { 
00129 
00130   if (dimension()==4) {
00131     return theCovMatrix;
00132   }
00133 
00134   AlgebraicSymMatrix result(2);
00135   if (theProjection==phi) {
00136     result[0][0] = theCovMatrix[0][0]; //S(dx/dz)
00137     result[0][1] = theCovMatrix[0][2]; //Cov(dx/dz,x)
00138     result[1][1] = theCovMatrix[2][2]; //S(x)
00139   } else if (theProjection==Z) {
00140     result[0][0] = theCovMatrix[1][1]; //S(dy/dz)
00141     result[0][1] = theCovMatrix[1][3]; //Cov(dy/dz,y)
00142     result[1][1] = theCovMatrix[3][3]; //S(y)
00143   }
00144   return result;
00145 }
00146 
00147 
00148 AlgebraicMatrix DTRecSegment4D::projectionMatrix() const {
00149   static bool isInitialized=false;
00150   static AlgebraicMatrix the4DProjectionMatrix(4, 5, 0); 
00151   static AlgebraicMatrix the2DPhiProjMatrix(2, 5, 0);
00152   static AlgebraicMatrix the2DZProjMatrix(2, 5, 0);
00153 
00154   if (!isInitialized) {
00155     the4DProjectionMatrix[0][1] = 1;
00156     the4DProjectionMatrix[1][2] = 1;
00157     the4DProjectionMatrix[2][3] = 1;
00158     the4DProjectionMatrix[3][4] = 1;
00159 
00160     the2DPhiProjMatrix[0][1] = 1;
00161     the2DPhiProjMatrix[1][3] = 1;
00162 
00163     the2DZProjMatrix[0][2] = 1;
00164     the2DZProjMatrix[1][4] = 1;
00165 
00166     isInitialized= true;
00167   }
00168 
00169   if (dimension()==4) { 
00170     return the4DProjectionMatrix;
00171   } else if (theProjection==phi) {
00172     return the2DPhiProjMatrix;
00173   } else if (theProjection==Z) {
00174     return the2DZProjMatrix;
00175   } else {
00176     return AlgebraicMatrix();
00177   }
00178 }
00179 
00180 
00181 LocalError DTRecSegment4D::localPositionError() const {
00182   return LocalError(theCovMatrix[2][2],theCovMatrix[2][3],theCovMatrix[3][3]);
00183 }
00184 
00185 
00186 LocalError DTRecSegment4D::localDirectionError() const {
00187   return LocalError(theCovMatrix[0][0],theCovMatrix[0][1],theCovMatrix[1][1]);
00188 }
00189 
00190 
00191 double DTRecSegment4D::chi2() const {
00192   double result=0;
00193   if (hasPhi()) result+=thePhiSeg.chi2();
00194   if (hasZed()) result+=theZedSeg.chi2();
00195   return result;
00196 }
00197 
00198 
00199 int DTRecSegment4D::degreesOfFreedom() const {
00200   int result=0;
00201   if (hasPhi()) result+=thePhiSeg.degreesOfFreedom();
00202   if (hasZed()) result+=theZedSeg.degreesOfFreedom();
00203   return result;
00204 }
00205 
00206 
00207 void DTRecSegment4D::setCovMatrixForZed(const LocalPoint& posZInCh){
00208   // Warning!!! the covariance matrix for Theta SL segment is defined in the SL
00209   // reference frame, here that in the Chamber ref frame must be used.
00210   // For direction, no problem, but the position is extrapolated, so we must
00211   // propagate the error properly.
00212 
00213   // many thanks to Paolo Ronchese for the help in deriving the formulas!
00214 
00215   // y=m*z+q in SL frame
00216   // y=m'*z+q' in CH frame
00217 
00218   // var(m') = var(m)
00219   theCovMatrix[1][1] = theZedSeg.parametersError()[0][0]; //sigma (dy/dz)
00220 
00221   // cov(m',q') = DeltaZ*Var(m) + Cov(m,q)
00222   theCovMatrix[1][3] =
00223     posZInCh.z()*theZedSeg.parametersError()[0][0]+
00224     theZedSeg.parametersError()[0][1]; //cov(dy/dz,y)
00225 
00226   // Var(q') = DeltaZ^2*Var(m) + Var(q) + 2*DeltaZ*Cov(m,q)
00227   // cout << "Var(q') = DeltaZ^2*Var(m) + Var(q) + 2*DeltaZ*Cov(m,q)" << endl;
00228   // cout << "Var(q')= " << posZInCh.z()*posZInCh.z() << "*" <<
00229   //   theZedSeg.parametersError()[0][0] << " + " << 
00230   //   theZedSeg.parametersError()[1][1] << " + " << 
00231   //   2*posZInCh.z() << "*" << theZedSeg.parametersError()[0][1] ;
00232   theCovMatrix[3][3] =
00233     2.*(posZInCh.z()*posZInCh.z())*theZedSeg.parametersError()[0][0] +
00234     theZedSeg.parametersError()[1][1] +
00235     2.*posZInCh.z()*theZedSeg.parametersError()[0][1];
00236   // cout << " = " << theCovMatrix[3][3] << endl;
00237 }
00238 
00239 std::ostream& operator<<(std::ostream& os, const DTRecSegment4D& seg) {
00240   os << "Pos " << seg.localPosition() << 
00241     " Dir: " << seg.localDirection() <<
00242     " dim: " << seg.dimension() <<
00243     " chi2/ndof: " << seg.chi2() << "/" << seg.degreesOfFreedom() << " :";
00244   if (seg.hasPhi()) os << seg.phiSegment()->recHits().size();
00245   else os << 0;
00246   os << ":";
00247   if (seg.hasZed()) os << seg.zSegment()->recHits().size();
00248   else os << 0;
00249   return os;
00250 }
00251 
00252 
00254 std::vector<const TrackingRecHit*> DTRecSegment4D::recHits() const{
00255   std::vector<const TrackingRecHit*> pointersOfRecHits; 
00256 
00257   if (hasPhi()) pointersOfRecHits.push_back(phiSegment());
00258   if (hasZed()) pointersOfRecHits.push_back(zSegment());
00259 
00260   return pointersOfRecHits;
00261 }
00262 
00263 
00265 std::vector<TrackingRecHit*> DTRecSegment4D::recHits(){
00266 
00267   std::vector<TrackingRecHit*> pointersOfRecHits; 
00268 
00269   if (hasPhi()) pointersOfRecHits.push_back(phiSegment());
00270   if (hasZed()) pointersOfRecHits.push_back(zSegment());
00271   
00272   return pointersOfRecHits;
00273 }
00274 
00275 
00276 DTChamberId DTRecSegment4D::chamberId() const {
00277   return DTChamberId(geographicalId());
00278 }