CMS 3D CMS Logo

CSCLayerGeometry.cc

Go to the documentation of this file.
00001 // This is CSCLayerGeometry.cc
00002 
00003 #include <Geometry/CSCGeometry/interface/CSCGeometry.h>
00004 #include <Geometry/CSCGeometry/interface/CSCLayerGeometry.h>
00005 
00006 #include <Geometry/CSCGeometry/src/CSCUngangedStripTopology.h>
00007 #include <Geometry/CSCGeometry/src/CSCGangedStripTopology.h>
00008 #include <Geometry/CSCGeometry/src/CSCWireGroupPackage.h>
00009 
00010 
00011 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00012 
00013 #include <CLHEP/Units/SystemOfUnits.h>
00014 
00015 #include <algorithm>
00016 #include <iostream>
00017 #include <cmath> // for M_PI_2 via math.h, as long as appropriate compiler flag switched on to allow acces
00018 
00019 CSCLayerGeometry::CSCLayerGeometry( const CSCGeometry* geom, int iChamberType,
00020          const TrapezoidalPlaneBounds& bounds,
00021          int nstrips, float stripOffset, float stripPhiPitch,
00022          float whereStripsMeet, float extentOfStripPlane, float yCentreOfStripPlane,
00023          const CSCWireGroupPackage& wg, float wireAngleInDegrees, double yOfFirstWire )
00024   :   TrapezoidalPlaneBounds( bounds ), theWireTopology( 0 ),
00025       theStripTopology( 0 ), myName( "CSCLayerGeometry" ), 
00026       chamberType( iChamberType ) {
00027 
00028   LogTrace("CSC") << myName <<": being constructed, this=" << this;
00029 
00030   // For simplicity cache the base class TPB dims even though they could be
00031   // retrieved indirectly through the TPB public interface
00032   apothem     = bounds.length() / 2.;  
00033   hTopEdge    = bounds.width() / 2.;
00034   hBottomEdge = bounds.widthAtHalfLength() - hTopEdge; // t+b=2w
00035 
00036   // Ganged strips in ME1A?
00037   bool gangedME1A = ( iChamberType == 1 && geom->gangedStrips() );
00038 
00039   CSCStripTopology* aStripTopology = 
00040         new CSCUngangedStripTopology(nstrips, stripPhiPitch,
00041             extentOfStripPlane, whereStripsMeet, stripOffset, yCentreOfStripPlane );
00042 
00043   if ( gangedME1A ) {
00044     theStripTopology = new CSCGangedStripTopology( *aStripTopology, 16 );
00045     delete aStripTopology;
00046   }
00047   else {
00048     theStripTopology = aStripTopology;
00049   }
00050 
00051   if ( ! geom->realWireGeometry() ) {
00052     // Approximate ORCA_8_8_0 and earlier calculated geometry...
00053     float wangler = wireAngleInDegrees*degree; // convert angle to radians
00054     float wireCos = cos(wangler);
00055     float wireSin = sin(wangler);
00056     float y2 = apothem * wireCos + hBottomEdge * fabs(wireSin);
00057     float wireSpacing = wg.wireSpacing/10.; // in cm
00058     float wireOffset = -y2 + wireSpacing/2.;
00059     yOfFirstWire = wireOffset/wireCos;
00060   }
00061 
00062   theWireTopology = new CSCWireTopology( wg, yOfFirstWire, wireAngleInDegrees );
00063 
00064 } 
00065 
00066 CSCLayerGeometry::CSCLayerGeometry(const CSCLayerGeometry& melg) :
00067   TrapezoidalPlaneBounds(melg.hBottomEdge, melg.hTopEdge, melg.apothem,
00068                          0.5 * melg.thickness() ),
00069   theWireTopology(0), theStripTopology(0), 
00070   hBottomEdge(melg.hBottomEdge), hTopEdge(melg.hTopEdge),
00071   apothem(melg.apothem)
00072 {
00073   // CSCStripTopology is abstract, so need clone()
00074   if (melg.theStripTopology) theStripTopology = melg.theStripTopology->clone();
00075   // CSCWireTopology is concrete, so direct copy
00076   if (melg.theWireTopology) theWireTopology = new CSCWireTopology(*(melg.theWireTopology));
00077 }
00078 
00079 CSCLayerGeometry& CSCLayerGeometry::operator=(const CSCLayerGeometry& melg)
00080 {
00081   if ( &melg != this ) {
00082     delete theStripTopology;
00083     if ( melg.theStripTopology )
00084       theStripTopology=melg.theStripTopology->clone();
00085     else
00086       theStripTopology=0;
00087 
00088     delete theWireTopology;
00089     if ( melg.theWireTopology )
00090       theWireTopology=new CSCWireTopology(*(melg.theWireTopology));
00091     else
00092       theWireTopology=0;
00093 
00094     hBottomEdge     = melg.hBottomEdge;
00095     hTopEdge        = melg.hTopEdge;
00096     apothem         = melg.apothem;
00097   }
00098   return *this;
00099 }
00100 
00101 CSCLayerGeometry::~CSCLayerGeometry()
00102 {
00103   LogTrace("CSC") << myName << ": being destroyed, this=" << this << 
00104     "\nDeleting theStripTopology=" << theStripTopology << 
00105     " and theWireTopology=" << theWireTopology;
00106   delete theStripTopology;
00107   delete theWireTopology;
00108 }
00109 
00110 
00111 LocalPoint 
00112 CSCLayerGeometry::stripWireIntersection( int strip, float wire ) const
00113 {
00114   // This allows _float_ wire no. so that we can calculate the
00115   // intersection of a strip with the mid point of a wire group 
00116   // containing an even no. of wires (which is not an actual wire),
00117   // as well as for a group containing an odd no. of wires.
00118 
00119   // Equation of wire and strip as straight lines in local xy
00120   // y = mx + c where m = tan(angle w.r.t. x axis)
00121   // At the intersection x = -(cs-cw)/(ms-mw)
00122   // At y=0, 0 = ms * xOfStrip(strip) + cs => cs = -ms*xOfStrip
00123   // At x=0, yOfWire(wire) = 0 + cw => cw = yOfWire
00124 
00125   float ms = tan( stripAngle(strip) );
00126   float mw = tan( wireAngle() );
00127   float xs = xOfStrip(strip);
00128   float xi = ( ms * xs + yOfWire(wire) ) / ( ms - mw );
00129   float yi = ms * (xi - xs );
00130 
00131   return LocalPoint(xi, yi);
00132 }
00133 
00134 LocalPoint CSCLayerGeometry::stripWireGroupIntersection( int strip, int wireGroup) const
00135 {
00136   // middleWire is only an actual wire for a group with an odd no. of wires
00137   float middleWire = middleWireOfGroup( wireGroup );
00138   return stripWireIntersection(strip, middleWire);
00139 }
00140 
00141 float CSCLayerGeometry::stripAngle(int strip) const 
00142 {
00143   // Cleverly subtly change meaning of stripAngle once more.
00144   // In TrapezoidalStripTopology it is angle measured
00145   // counter-clockwise from y axis. 
00146   // In APTST and RST it is angle measured 
00147   // clockwise from y axis.
00148   // Output of this function is measured counter-clockwise 
00149   // from x-axis, so it is a conventional 2-dim azimuthal angle
00150   // in the (x,y) local coordinates
00151 
00152   // We want angle at centre of strip (strip N covers
00153   // *float* range N-1 to N-epsilon)
00154 
00155   return M_PI_2 - theStripTopology->stripAngle(strip-0.5);
00156 }
00157 
00158 LocalPoint CSCLayerGeometry::localCenterOfWireGroup( int wireGroup ) const {
00159 
00160   // It can use CSCWireTopology::yOfWireGroup for y,
00161   // But x requires mixing with 'extent' of wire plane
00162 
00163   // If the wires are NOT tilted, default to simple calculation...
00164   if ( fabs(wireAngle() ) < 1.E-6 )  {
00165     float y = yOfWireGroup( wireGroup );
00166     return LocalPoint( 0., y );
00167   }
00168   else {
00169     // w is "wire" at the center of the wire group
00170     float w = middleWireOfGroup( wireGroup );
00171     std::vector<float> store = theWireTopology->wireValues( w );
00172     return LocalPoint( store[0], store[1] );
00173   }
00174 }
00175 
00176 float CSCLayerGeometry::lengthOfWireGroup( int wireGroup ) const {
00177   // Return length of 'wire' in the middle of the wire group
00178    float w = middleWireOfGroup( wireGroup );
00179    std::vector<float> store = theWireTopology->wireValues( w );
00180    return store[2];
00181 }
00182 
00183 std::pair<LocalPoint, float> CSCLayerGeometry::possibleRecHitPosition( float s, int w1, int w2 ) const {
00184         
00185   LocalPoint sw1 = intersectionOfStripAndWire( s, w1 );
00186   LocalPoint sw2 = intersectionOfStripAndWire( s, w2 );
00187                 
00188   // Average the two points
00189   LocalPoint midpt( (sw1.x()+sw2.x())/2., (sw1.y()+sw2.y())/2 );
00190         
00191   // Length of strip crossing this group of wires
00192   float length = sqrt( (sw1.x()-sw2.x())*(sw1.x()-sw2.x()) + 
00193                      (sw1.y()-sw2.y())*(sw1.y()-sw2.y()) );
00194         
00195   return std::pair<LocalPoint,float>( midpt, length );
00196 }
00197 
00198 LocalPoint CSCLayerGeometry::intersectionOfStripAndWire( float s, int w) const {
00199         
00200   std::pair<float, float> pw = theWireTopology->equationOfWire( static_cast<float>(w) );
00201   std::pair<float, float> ps = theStripTopology->equationOfStrip( s );
00202   LocalPoint sw = intersectionOfTwoLines( ps, pw );
00203         
00204   // If point falls outside wire plane, at extremes in local y, 
00205   // replace its y by that of appropriate edge of wire plane
00206   if ( !(theWireTopology->insideYOfWirePlane( sw.y() ) ) ) {
00207      float y  = theWireTopology->restrictToYOfWirePlane( sw.y() );
00208      LocalPoint sw2(sw.x(), y);
00209      sw = sw2;
00210   }
00211         
00212   return sw;
00213 }
00214 
00215 LocalPoint CSCLayerGeometry::intersectionOfTwoLines( std::pair<float, float> p1, std::pair<float, float> p2 ) const {
00216 
00217   // Calculate the point of intersection of two straight lines (in 2-dim)
00218   // input arguments are pair(m1,c1) and pair(m2,c2) where m=slope, c=intercept (y=mx+c)
00219   // BEWARE! Do not call with m1 = m2 ! No trapping !
00220 
00221   float m1 = p1.first;
00222   float c1 = p1.second;
00223   float m2 = p2.first;
00224   float c2 = p2.second;
00225   float x = (c2-c1)/(m1-m2);
00226   float y = (m1*c2-m2*c1)/(m1-m2);
00227   return LocalPoint( x, y );
00228 }
00229 
00230 
00231 LocalError CSCLayerGeometry::localError( int strip, float sigmaStrip, float sigmaWire ) const {
00232   // Input sigmas are expected to be in _distance units_
00233   // - uncertainty in strip measurement (typically from Gatti fit, value is in local x units)
00234   // - uncertainty in wire measurement (along direction perpendicular to wires)
00235 
00236   float wangle   = this->wireAngle();
00237   float strangle = this->stripAngle( strip );
00238 
00239   float sinAngdif  = sin(strangle-wangle);
00240   float sinAngdif2 = sinAngdif * sinAngdif;
00241   
00242   float du = sigmaStrip/sin(strangle); // sigmaStrip is just x-component of strip error
00243   float dv = sigmaWire;
00244 
00245   // The notation is
00246   // wsins = wire resol  * sin(strip angle)
00247   // wcoss = wire resol  * cos(strip angle)
00248   // ssinw = strip resol * sin(wire angle)
00249   // scosw = strip resol * cos(wire angle)
00250 
00251   float wsins = dv * sin(strangle);
00252   float wcoss = dv * cos(strangle);
00253   float ssinw = du * sin(wangle);
00254   float scosw = du * cos(wangle);
00255 
00256   float dx2 = (scosw*scosw + wcoss*wcoss)/sinAngdif2;
00257   float dy2 = (ssinw*ssinw + wsins*wsins)/sinAngdif2;
00258   float dxy = (scosw*ssinw + wcoss*wsins)/sinAngdif2;
00259           
00260   return LocalError(dx2, dxy, dy2);
00261 }
00262     
00263 void CSCLayerGeometry::setTopology( CSCStripTopology * newTopology ) {
00264    delete theStripTopology;
00265    theStripTopology = newTopology;
00266 }
00267 
00268 std::ostream & operator<<(std::ostream & stream, const CSCLayerGeometry & lg) {
00269   stream << "LayerGeometry " << std::endl
00270          << "------------- " << std::endl
00271          << "numberOfStrips        " << lg.numberOfStrips() << std::endl
00272          << "numberOfWires         " << lg.numberOfWires() << std::endl
00273          << "numberOfWireGroups    " << lg.numberOfWireGroups() << std::endl
00274          << "wireAngle  (rad)      " << lg.wireAngle() << std::endl
00275     //         << "wireAngle  (deg)      " << lg.theWireAngle << std::endl
00276     //         << "sin(wireAngle)        " << lg.theWireSin << std::endl
00277     //         << "cos(wireAngle)        " << lg.theWireCos << std::endl
00278          << "wirePitch             " << lg.wirePitch() << std::endl
00279          << "stripPitch            " << lg.stripPitch() << std::endl
00280     //         << "numberOfWiresPerGroup " << lg.theNumberOfWiresPerGroup << std::endl
00281     //         << "numberOfWiresInLastGroup " << lg.theNumberOfWiresInLastGroup << std::endl
00282     //         << "wireOffset            " << lg.theWireOffset << std::endl
00283     //         << "whereStripsMeet       " << lg.whereStripsMeet << std::endl;
00284          << "hBottomEdge           " << lg.hBottomEdge << std::endl
00285          << "hTopEdge              " << lg.hTopEdge << std::endl
00286          << "apothem               " << lg.apothem << std::endl;
00287     return stream;
00288 }
00289 

Generated on Tue Jun 9 17:37:20 2009 for CMSSW by  doxygen 1.5.4