00001
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/GlobalSystemOfUnits.h"
00014
00015 #include <algorithm>
00016 #include <iostream>
00017 #include <cmath>
00018
00019
00020
00021
00022 CSCLayerGeometry::CSCLayerGeometry( const CSCGeometry* geom, int iChamberType,
00023 const TrapezoidalPlaneBounds& bounds,
00024 int nstrips, float stripOffset, float stripPhiPitch,
00025 float whereStripsMeet, float extentOfStripPlane, float yCentreOfStripPlane,
00026 const CSCWireGroupPackage& wg, float wireAngleInDegrees, double yOfFirstWire, float hThickness )
00027 : TrapezoidalPlaneBounds( bounds.widthAtHalfLength() - bounds.width()/2., bounds.width()/2., bounds.length()/2., hThickness ),
00028 theWireTopology( 0 ), theStripTopology( 0 ),
00029 hBottomEdge( bounds.widthAtHalfLength() - bounds.width()/2. ),
00030 hTopEdge( bounds.width()/2. ), apothem( bounds.length()/2. ),
00031 myName( "CSCLayerGeometry" ), chamberType( iChamberType ) {
00032
00033 LogTrace("CSCLayerGeometry|CSC") << myName <<": being constructed, this=" << this;
00034
00035
00036 bool gangedME1A = ( iChamberType == 1 && geom->gangedStrips() );
00037
00038 CSCStripTopology* aStripTopology =
00039 new CSCUngangedStripTopology(nstrips, stripPhiPitch,
00040 extentOfStripPlane, whereStripsMeet, stripOffset, yCentreOfStripPlane );
00041
00042 if ( gangedME1A ) {
00043 theStripTopology = new CSCGangedStripTopology( *aStripTopology, 16 );
00044 delete aStripTopology;
00045 }
00046 else {
00047 theStripTopology = aStripTopology;
00048 }
00049
00050 if ( ! geom->realWireGeometry() ) {
00051
00052 float wangler = wireAngleInDegrees*degree;
00053 float wireCos = cos(wangler);
00054 float wireSin = sin(wangler);
00055 float y2 = apothem * wireCos + hBottomEdge * fabs(wireSin);
00056 float wireSpacing = wg.wireSpacing/10.;
00057 float wireOffset = -y2 + wireSpacing/2.;
00058 yOfFirstWire = wireOffset/wireCos;
00059 }
00060
00061 theWireTopology = new CSCWireTopology( wg, yOfFirstWire, wireAngleInDegrees );
00062 LogTrace("CSCLayerGeometry|CSC") << myName <<": constructed: "<< *this;
00063 }
00064
00065 CSCLayerGeometry::CSCLayerGeometry(const CSCLayerGeometry& melg) :
00066 TrapezoidalPlaneBounds(melg.hBottomEdge, melg.hTopEdge, melg.apothem,
00067 0.5 * melg.thickness() ),
00068 theWireTopology(0), theStripTopology(0),
00069 hBottomEdge(melg.hBottomEdge), hTopEdge(melg.hTopEdge),
00070 apothem(melg.apothem)
00071 {
00072
00073 if (melg.theStripTopology) theStripTopology = melg.theStripTopology->clone();
00074
00075 if (melg.theWireTopology) theWireTopology = new CSCWireTopology(*(melg.theWireTopology));
00076 }
00077
00078 CSCLayerGeometry& CSCLayerGeometry::operator=(const CSCLayerGeometry& melg)
00079 {
00080 if ( &melg != this ) {
00081 delete theStripTopology;
00082 if ( melg.theStripTopology )
00083 theStripTopology=melg.theStripTopology->clone();
00084 else
00085 theStripTopology=0;
00086
00087 delete theWireTopology;
00088 if ( melg.theWireTopology )
00089 theWireTopology=new CSCWireTopology(*(melg.theWireTopology));
00090 else
00091 theWireTopology=0;
00092
00093 hBottomEdge = melg.hBottomEdge;
00094 hTopEdge = melg.hTopEdge;
00095 apothem = melg.apothem;
00096 }
00097 return *this;
00098 }
00099
00100 CSCLayerGeometry::~CSCLayerGeometry()
00101 {
00102 LogTrace("CSCLayerGeometry|CSC") << myName << ": being destroyed, this=" << this <<
00103 "\nDeleting theStripTopology=" << theStripTopology <<
00104 " and theWireTopology=" << theWireTopology;
00105 delete theStripTopology;
00106 delete theWireTopology;
00107 }
00108
00109
00110 LocalPoint
00111 CSCLayerGeometry::stripWireIntersection( int strip, float wire ) const
00112 {
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 float ms = tan( stripAngle(strip) );
00125 float mw = tan( wireAngle() );
00126 float xs = xOfStrip(strip);
00127 float xi = ( ms * xs + yOfWire(wire) ) / ( ms - mw );
00128 float yi = ms * (xi - xs );
00129
00130 return LocalPoint(xi, yi);
00131 }
00132
00133 LocalPoint CSCLayerGeometry::stripWireGroupIntersection( int strip, int wireGroup) const
00134 {
00135
00136 float middleWire = middleWireOfGroup( wireGroup );
00137 return stripWireIntersection(strip, middleWire);
00138 }
00139
00140 float CSCLayerGeometry::stripAngle(int strip) const
00141 {
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 return M_PI_2 - theStripTopology->stripAngle(strip-0.5);
00155 }
00156
00157 LocalPoint CSCLayerGeometry::localCenterOfWireGroup( int wireGroup ) const {
00158
00159
00160
00161
00162
00163 if ( fabs(wireAngle() ) < 1.E-6 ) {
00164 float y = yOfWireGroup( wireGroup );
00165 return LocalPoint( 0., y );
00166 }
00167 else {
00168
00169 float w = middleWireOfGroup( wireGroup );
00170 std::vector<float> store = theWireTopology->wireValues( w );
00171 return LocalPoint( store[0], store[1] );
00172 }
00173 }
00174
00175 float CSCLayerGeometry::lengthOfWireGroup( int wireGroup ) const {
00176
00177 float w = middleWireOfGroup( wireGroup );
00178 std::vector<float> store = theWireTopology->wireValues( w );
00179 return store[2];
00180 }
00181
00182 std::pair<LocalPoint, float> CSCLayerGeometry::possibleRecHitPosition( float s, int w1, int w2 ) const {
00183
00184 LocalPoint sw1 = intersectionOfStripAndWire( s, w1 );
00185 LocalPoint sw2 = intersectionOfStripAndWire( s, w2 );
00186
00187
00188 LocalPoint midpt( (sw1.x()+sw2.x())/2., (sw1.y()+sw2.y())/2 );
00189
00190
00191 float length = sqrt( (sw1.x()-sw2.x())*(sw1.x()-sw2.x()) +
00192 (sw1.y()-sw2.y())*(sw1.y()-sw2.y()) );
00193
00194 return std::pair<LocalPoint,float>( midpt, length );
00195 }
00196
00197 LocalPoint CSCLayerGeometry::intersectionOfStripAndWire( float s, int w) const {
00198
00199 std::pair<float, float> pw = theWireTopology->equationOfWire( static_cast<float>(w) );
00200 std::pair<float, float> ps = theStripTopology->equationOfStrip( s );
00201 LocalPoint sw = intersectionOfTwoLines( ps, pw );
00202
00203
00204
00205 if ( !(theWireTopology->insideYOfWirePlane( sw.y() ) ) ) {
00206 float y = theWireTopology->restrictToYOfWirePlane( sw.y() );
00207 LocalPoint sw2(sw.x(), y);
00208 sw = sw2;
00209 }
00210
00211 return sw;
00212 }
00213
00214 LocalPoint CSCLayerGeometry::intersectionOfTwoLines( std::pair<float, float> p1, std::pair<float, float> p2 ) const {
00215
00216
00217
00218
00219
00220 float m1 = p1.first;
00221 float c1 = p1.second;
00222 float m2 = p2.first;
00223 float c2 = p2.second;
00224 float x = (c2-c1)/(m1-m2);
00225 float y = (m1*c2-m2*c1)/(m1-m2);
00226 return LocalPoint( x, y );
00227 }
00228
00229
00230 LocalError CSCLayerGeometry::localError( int strip, float sigmaStrip, float sigmaWire ) const {
00231
00232
00233
00234
00235 float wangle = this->wireAngle();
00236 float strangle = this->stripAngle( strip );
00237
00238 float sinAngdif = sin(strangle-wangle);
00239 float sinAngdif2 = sinAngdif * sinAngdif;
00240
00241 float du = sigmaStrip/sin(strangle);
00242 float dv = sigmaWire;
00243
00244
00245
00246
00247
00248
00249
00250 float wsins = dv * sin(strangle);
00251 float wcoss = dv * cos(strangle);
00252 float ssinw = du * sin(wangle);
00253 float scosw = du * cos(wangle);
00254
00255 float dx2 = (scosw*scosw + wcoss*wcoss)/sinAngdif2;
00256 float dy2 = (ssinw*ssinw + wsins*wsins)/sinAngdif2;
00257 float dxy = (scosw*ssinw + wcoss*wsins)/sinAngdif2;
00258
00259 return LocalError(dx2, dxy, dy2);
00260 }
00261
00262 bool CSCLayerGeometry::inside( const Local3DPoint& lp ) const {
00263 bool result = false;
00264 const float epsilon = 1.e-06;
00265 if ( fabs( lp.z() ) < thickness()/2. ) {
00266 std::pair<float, float> ylims = yLimitsOfStripPlane();
00267 if ( (lp.y() > ylims.first) && (lp.y() < ylims.second) ) {
00268
00269
00270 if ( ( theStripTopology->strip(lp) > epsilon ) &&
00271 ( theStripTopology->strip(lp) < (numberOfStrips() - epsilon) ) ) result = true;
00272 }
00273 }
00274 return result;
00275 }
00276
00277 bool CSCLayerGeometry::inside( const Local2DPoint& lp ) const {
00278 LocalPoint lp2( lp.x(), lp.y(), 0. );
00279 return inside( lp2 );
00280 }
00281
00282 bool CSCLayerGeometry::inside( const Local3DPoint& lp, const LocalError& le, float scale ) const {
00283
00284
00285
00286
00287
00288 float deltaX = scale*sqrt(le.xx());
00289 float deltaY = scale*sqrt(le.yy());
00290
00291 LocalPoint lp1( lp.x()-deltaX, lp.y()-deltaY, lp.z() );
00292 LocalPoint lp2( lp.x()-deltaX, lp.y()+deltaY, lp.z() );
00293 LocalPoint lp3( lp.x()+deltaX, lp.y()+deltaY, lp.z() );
00294 LocalPoint lp4( lp.x()+deltaX, lp.y()-deltaY, lp.z() );
00295
00296 return ( inside(lp1) || inside(lp2) || inside(lp3) || inside(lp4) );
00297 }
00298
00299 void CSCLayerGeometry::setTopology( CSCStripTopology * newTopology ) {
00300 delete theStripTopology;
00301 theStripTopology = newTopology;
00302 }
00303
00304 std::ostream & operator<<(std::ostream & stream, const CSCLayerGeometry & lg) {
00305 stream << "LayerGeometry " << std::endl
00306 << "------------- " << std::endl
00307 << "numberOfStrips " << lg.numberOfStrips() << std::endl
00308 << "numberOfWires " << lg.numberOfWires() << std::endl
00309 << "numberOfWireGroups " << lg.numberOfWireGroups() << std::endl
00310 << "wireAngle (rad) " << lg.wireAngle() << std::endl
00311
00312
00313
00314 << "wirePitch " << lg.wirePitch() << std::endl
00315 << "stripPitch " << lg.stripPitch() << std::endl
00316
00317
00318
00319
00320 << "hBottomEdge " << lg.hBottomEdge << std::endl
00321 << "hTopEdge " << lg.hTopEdge << std::endl
00322 << "apothem " << lg.apothem << std::endl
00323 << "length (should be 2xapothem) " << lg.length() << std::endl
00324 << "thickness " << lg.thickness() << std::endl;
00325 return stream;
00326 }
00327