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/SystemOfUnits.h>
00014
00015 #include <algorithm>
00016 #include <iostream>
00017 #include <cmath>
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
00031
00032 apothem = bounds.length() / 2.;
00033 hTopEdge = bounds.width() / 2.;
00034 hBottomEdge = bounds.widthAtHalfLength() - hTopEdge;
00035
00036
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
00053 float wangler = wireAngleInDegrees*degree;
00054 float wireCos = cos(wangler);
00055 float wireSin = sin(wangler);
00056 float y2 = apothem * wireCos + hBottomEdge * fabs(wireSin);
00057 float wireSpacing = wg.wireSpacing/10.;
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
00074 if (melg.theStripTopology) theStripTopology = melg.theStripTopology->clone();
00075
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
00115
00116
00117
00118
00119
00120
00121
00122
00123
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
00137 float middleWire = middleWireOfGroup( wireGroup );
00138 return stripWireIntersection(strip, middleWire);
00139 }
00140
00141 float CSCLayerGeometry::stripAngle(int strip) const
00142 {
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 return M_PI_2 - theStripTopology->stripAngle(strip-0.5);
00156 }
00157
00158 LocalPoint CSCLayerGeometry::localCenterOfWireGroup( int wireGroup ) const {
00159
00160
00161
00162
00163
00164 if ( fabs(wireAngle() ) < 1.E-6 ) {
00165 float y = yOfWireGroup( wireGroup );
00166 return LocalPoint( 0., y );
00167 }
00168 else {
00169
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
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
00189 LocalPoint midpt( (sw1.x()+sw2.x())/2., (sw1.y()+sw2.y())/2 );
00190
00191
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
00205
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
00218
00219
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
00233
00234
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);
00243 float dv = sigmaWire;
00244
00245
00246
00247
00248
00249
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
00276
00277
00278 << "wirePitch " << lg.wirePitch() << std::endl
00279 << "stripPitch " << lg.stripPitch() << std::endl
00280
00281
00282
00283
00284 << "hBottomEdge " << lg.hBottomEdge << std::endl
00285 << "hTopEdge " << lg.hTopEdge << std::endl
00286 << "apothem " << lg.apothem << std::endl;
00287 return stream;
00288 }
00289