CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:30:41 2009 for CMSSW by  doxygen 1.5.4