CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCLayerGeometry.cc
Go to the documentation of this file.
1 // This is CSCLayerGeometry.cc
2 
5 
9 
10 
12 
13 #include "CLHEP/Units/GlobalSystemOfUnits.h"
14 
15 #include <algorithm>
16 #include <iostream>
17 #include <cmath> // for M_PI_2 via math.h, as long as appropriate compiler flag switched on to allow acces
18 
19 // Complicated initialization list since the chamber Bounds passed in must have its thickness reset to that of the layer
20 // Note for half-widths, t + b = 2w and the TPB only has accessors for t and w so b = 2w - t
21 
23  const TrapezoidalPlaneBounds& bounds,
24  int nstrips, float stripOffset, float stripPhiPitch,
25  float whereStripsMeet, float extentOfStripPlane, float yCentreOfStripPlane,
26  const CSCWireGroupPackage& wg, float wireAngleInDegrees, double yOfFirstWire, float hThickness )
27  : TrapezoidalPlaneBounds( bounds.widthAtHalfLength() - bounds.width()/2., bounds.width()/2., bounds.length()/2., hThickness ),
28  theWireTopology( 0 ), theStripTopology( 0 ),
29  hBottomEdge( bounds.widthAtHalfLength() - bounds.width()/2. ),
30  hTopEdge( bounds.width()/2. ), apothem( bounds.length()/2. ),
31  myName( "CSCLayerGeometry" ), chamberType( iChamberType ) {
32 
33  LogTrace("CSCLayerGeometry|CSC") << myName <<": being constructed, this=" << this;
34 
35  // Ganged strips in ME1A?
36  bool gangedME1A = ( iChamberType == 1 && geom->gangedStrips() );
37 
38  CSCStripTopology* aStripTopology =
39  new CSCUngangedStripTopology(nstrips, stripPhiPitch,
40  extentOfStripPlane, whereStripsMeet, stripOffset, yCentreOfStripPlane );
41 
42  if ( gangedME1A ) {
43  theStripTopology = new CSCGangedStripTopology( *aStripTopology, 16 );
44  delete aStripTopology;
45  }
46  else {
47  theStripTopology = aStripTopology;
48  }
49 
50  if ( ! geom->realWireGeometry() ) {
51  // Approximate ORCA_8_8_0 and earlier calculated geometry...
52  float wangler = wireAngleInDegrees*degree; // convert angle to radians
53  float wireCos = cos(wangler);
54  float wireSin = sin(wangler);
55  float y2 = apothem * wireCos + hBottomEdge * fabs(wireSin);
56  float wireSpacing = wg.wireSpacing/10.; // in cm
57  float wireOffset = -y2 + wireSpacing/2.;
58  yOfFirstWire = wireOffset/wireCos;
59  }
60 
61  theWireTopology = new CSCWireTopology( wg, yOfFirstWire, wireAngleInDegrees );
62  LogTrace("CSCLayerGeometry|CSC") << myName <<": constructed: "<< *this;
63 }
64 
66  TrapezoidalPlaneBounds(melg.hBottomEdge, melg.hTopEdge, melg.apothem,
67  0.5 * melg.thickness() ),
68  theWireTopology(0), theStripTopology(0),
69  hBottomEdge(melg.hBottomEdge), hTopEdge(melg.hTopEdge),
70  apothem(melg.apothem), chamberType(melg.chamberType)
71 {
72  // CSCStripTopology is abstract, so need clone()
74  // CSCWireTopology is concrete, so direct copy
76 }
77 
79 {
80  if ( &melg != this ) {
81  delete theStripTopology;
82  if ( melg.theStripTopology )
84  else
86 
87  delete theWireTopology;
88  if ( melg.theWireTopology )
90  else
92 
93  hBottomEdge = melg.hBottomEdge;
94  hTopEdge = melg.hTopEdge;
95  apothem = melg.apothem;
96  }
97  return *this;
98 }
99 
101 {
102  LogTrace("CSCLayerGeometry|CSC") << myName << ": being destroyed, this=" << this <<
103  "\nDeleting theStripTopology=" << theStripTopology <<
104  " and theWireTopology=" << theWireTopology;
105  delete theStripTopology;
106  delete theWireTopology;
107 }
108 
109 
110 LocalPoint
111 CSCLayerGeometry::stripWireIntersection( int strip, float wire ) const
112 {
113  // This allows _float_ wire no. so that we can calculate the
114  // intersection of a strip with the mid point of a wire group
115  // containing an even no. of wires (which is not an actual wire),
116  // as well as for a group containing an odd no. of wires.
117 
118  // Equation of wire and strip as straight lines in local xy
119  // y = mx + c where m = tan(angle w.r.t. x axis)
120  // At the intersection x = -(cs-cw)/(ms-mw)
121  // At y=0, 0 = ms * xOfStrip(strip) + cs => cs = -ms*xOfStrip
122  // At x=0, yOfWire(wire) = 0 + cw => cw = yOfWire
123 
124  float ms = tan( stripAngle(strip) );
125  float mw = tan( wireAngle() );
126  float xs = xOfStrip(strip);
127  float xi = ( ms * xs + yOfWire(wire) ) / ( ms - mw );
128  float yi = ms * (xi - xs );
129 
130  return LocalPoint(xi, yi);
131 }
132 
134 {
135  // middleWire is only an actual wire for a group with an odd no. of wires
136  float middleWire = middleWireOfGroup( wireGroup );
137  return stripWireIntersection(strip, middleWire);
138 }
139 
140 float CSCLayerGeometry::stripAngle(int strip) const
141 {
142  // Cleverly subtly change meaning of stripAngle once more.
143  // In TrapezoidalStripTopology it is angle measured
144  // counter-clockwise from y axis.
145  // In APTST and RST it is angle measured
146  // clockwise from y axis.
147  // Output of this function is measured counter-clockwise
148  // from x-axis, so it is a conventional 2-dim azimuthal angle
149  // in the (x,y) local coordinates
150 
151  // We want angle at centre of strip (strip N covers
152  // *float* range N-1 to N-epsilon)
153 
154  return M_PI_2 - theStripTopology->stripAngle(strip-0.5);
155 }
156 
158 
159  // It can use CSCWireTopology::yOfWireGroup for y,
160  // But x requires mixing with 'extent' of wire plane
161 
162  // If the wires are NOT tilted, default to simple calculation...
163  if ( fabs(wireAngle() ) < 1.E-6 ) {
164  float y = yOfWireGroup( wireGroup );
165  return LocalPoint( 0., y );
166  }
167  else {
168  // w is "wire" at the center of the wire group
169  float w = middleWireOfGroup( wireGroup );
170  std::vector<float> store = theWireTopology->wireValues( w );
171  return LocalPoint( store[0], store[1] );
172  }
173 }
174 
175 float CSCLayerGeometry::lengthOfWireGroup( int wireGroup ) const {
176  // Return length of 'wire' in the middle of the wire group
177  float w = middleWireOfGroup( wireGroup );
178  std::vector<float> store = theWireTopology->wireValues( w );
179  return store[2];
180 }
181 
182 std::pair<LocalPoint, float> CSCLayerGeometry::possibleRecHitPosition( float s, int w1, int w2 ) const {
183 
184  LocalPoint sw1 = intersectionOfStripAndWire( s, w1 );
185  LocalPoint sw2 = intersectionOfStripAndWire( s, w2 );
186 
187  // Average the two points
188  LocalPoint midpt( (sw1.x()+sw2.x())/2., (sw1.y()+sw2.y())/2 );
189 
190  // Length of strip crossing this group of wires
191  float length = sqrt( (sw1.x()-sw2.x())*(sw1.x()-sw2.x()) +
192  (sw1.y()-sw2.y())*(sw1.y()-sw2.y()) );
193 
194  return std::pair<LocalPoint,float>( midpt, length );
195 }
196 
198 
199  std::pair<float, float> pw = theWireTopology->equationOfWire( static_cast<float>(w) );
200  std::pair<float, float> ps = theStripTopology->equationOfStrip( s );
201  LocalPoint sw = intersectionOfTwoLines( ps, pw );
202 
203  // If point falls outside wire plane, at extremes in local y,
204  // replace its y by that of appropriate edge of wire plane
205  if ( !(theWireTopology->insideYOfWirePlane( sw.y() ) ) ) {
206  float y = theWireTopology->restrictToYOfWirePlane( sw.y() );
207  // and adjust x to match new y
208  float x = sw.x() + (y - sw.y())*tan(theStripTopology->stripAngle(s));
209  sw = LocalPoint(x, y);
210  }
211 
212  return sw;
213 }
214 
215 LocalPoint CSCLayerGeometry::intersectionOfTwoLines( std::pair<float, float> p1, std::pair<float, float> p2 ) const {
216 
217  // Calculate the point of intersection of two straight lines (in 2-dim)
218  // input arguments are pair(m1,c1) and pair(m2,c2) where m=slope, c=intercept (y=mx+c)
219  // BEWARE! Do not call with m1 = m2 ! No trapping !
220 
221  float m1 = p1.first;
222  float c1 = p1.second;
223  float m2 = p2.first;
224  float c2 = p2.second;
225  float x = (c2-c1)/(m1-m2);
226  float y = (m1*c2-m2*c1)/(m1-m2);
227  return LocalPoint( x, y );
228 }
229 
230 
231 LocalError CSCLayerGeometry::localError( int strip, float sigmaStrip, float sigmaWire ) const {
232  // Input sigmas are expected to be in _distance units_
233  // - uncertainty in strip measurement (typically from Gatti fit, value is in local x units)
234  // - uncertainty in wire measurement (along direction perpendicular to wires)
235 
236  float wangle = this->wireAngle();
237  float strangle = this->stripAngle( strip );
238 
239  float sinAngdif = sin(strangle-wangle);
240  float sinAngdif2 = sinAngdif * sinAngdif;
241 
242  float du = sigmaStrip/sin(strangle); // sigmaStrip is just x-component of strip error
243  float dv = sigmaWire;
244 
245  // The notation is
246  // wsins = wire resol * sin(strip angle)
247  // wcoss = wire resol * cos(strip angle)
248  // ssinw = strip resol * sin(wire angle)
249  // scosw = strip resol * cos(wire angle)
250 
251  float wsins = dv * sin(strangle);
252  float wcoss = dv * cos(strangle);
253  float ssinw = du * sin(wangle);
254  float scosw = du * cos(wangle);
255 
256  float dx2 = (scosw*scosw + wcoss*wcoss)/sinAngdif2;
257  float dy2 = (ssinw*ssinw + wsins*wsins)/sinAngdif2;
258  float dxy = (scosw*ssinw + wcoss*wsins)/sinAngdif2;
259 
260  return LocalError(dx2, dxy, dy2);
261 }
262 
263 bool CSCLayerGeometry::inside( const Local3DPoint& lp ) const {
264  bool result = false;
265  const float epsilon = 1.e-06;
266  if ( fabs( lp.z() ) < thickness()/2. ) { // thickness of TPB is that of gas layer
267  std::pair<float, float> ylims = yLimitsOfStripPlane();
268  if ( (lp.y() > ylims.first) && (lp.y() < ylims.second) ) {
269  // 'strip' returns float value between 0. and float(Nstrips) and value outside
270  // is set to 0. or float(Nstrips)... add a conservative precision of 'epsilon'
271  if ( ( theStripTopology->strip(lp) > epsilon ) &&
272  ( theStripTopology->strip(lp) < (numberOfStrips() - epsilon) ) ) result = true;
273  }
274  }
275  return result;
276 }
277 
278 bool CSCLayerGeometry::inside( const Local2DPoint& lp ) const {
279  LocalPoint lp2( lp.x(), lp.y(), 0. );
280  return inside( lp2 );
281 }
282 
283 bool CSCLayerGeometry::inside( const Local3DPoint& lp, const LocalError& le, float scale ) const {
284  // Effectively consider that the LocalError components extend the area which is acceptable.
285  // Form a little box centered on the point, with x, y diameters defined by the errors
286  // and require that ALL four corners of the box fall outside the strip region for failure
287 
288  // Note that LocalError is 2-dim x,y and doesn't supply a z error
289  float deltaX = scale*sqrt(le.xx());
290  float deltaY = scale*sqrt(le.yy());
291 
292  LocalPoint lp1( lp.x()-deltaX, lp.y()-deltaY, lp.z() );
293  LocalPoint lp2( lp.x()-deltaX, lp.y()+deltaY, lp.z() );
294  LocalPoint lp3( lp.x()+deltaX, lp.y()+deltaY, lp.z() );
295  LocalPoint lp4( lp.x()+deltaX, lp.y()-deltaY, lp.z() );
296 
297  return ( inside(lp1) || inside(lp2) || inside(lp3) || inside(lp4) );
298 }
299 
301  delete theStripTopology;
302  theStripTopology = newTopology;
303 }
304 
305 std::ostream & operator<<(std::ostream & stream, const CSCLayerGeometry & lg) {
306  stream << "LayerGeometry " << std::endl
307  << "------------- " << std::endl
308  << "numberOfStrips " << lg.numberOfStrips() << std::endl
309  << "numberOfWires " << lg.numberOfWires() << std::endl
310  << "numberOfWireGroups " << lg.numberOfWireGroups() << std::endl
311  << "wireAngle (rad) " << lg.wireAngle() << std::endl
312  // << "wireAngle (deg) " << lg.theWireAngle << std::endl
313  // << "sin(wireAngle) " << lg.theWireSin << std::endl
314  // << "cos(wireAngle) " << lg.theWireCos << std::endl
315  << "wirePitch " << lg.wirePitch() << std::endl
316  << "stripPitch " << lg.stripPitch() << std::endl
317  // << "numberOfWiresPerGroup " << lg.theNumberOfWiresPerGroup << std::endl
318  // << "numberOfWiresInLastGroup " << lg.theNumberOfWiresInLastGroup << std::endl
319  // << "wireOffset " << lg.theWireOffset << std::endl
320  // << "whereStripsMeet " << lg.whereStripsMeet << std::endl;
321  << "hBottomEdge " << lg.hBottomEdge << std::endl
322  << "hTopEdge " << lg.hTopEdge << std::endl
323  << "apothem " << lg.apothem << std::endl
324  << "length (should be 2xapothem) " << lg.length() << std::endl
325  << "thickness " << lg.thickness() << std::endl;
326  return stream;
327 }
328 
LocalPoint stripWireGroupIntersection(int strip, int wireGroup) const
float xx() const
Definition: LocalError.h:24
std::pair< LocalPoint, float > possibleRecHitPosition(float s, int w1, int w2) const
std::pair< float, float > equationOfWire(float wire) const
T y() const
Definition: PV2DBase.h:46
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
float lengthOfWireGroup(int wireGroup) const
const double w
Definition: UKUtility.cc:23
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
T y() const
Definition: PV3DBase.h:63
#define M_PI_2
int numberOfStrips() const
CSCStripTopology * theStripTopology
std::pair< float, float > yLimitsOfStripPlane() const
float stripPitch() const
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:187
int numberOfWireGroups() const
CSCLayerGeometry(const CSCGeometry *geom, int iChamberType, const TrapezoidalPlaneBounds &bounds, int nstrips, float stripOffset, float stripPhiPitch, float whereStripsMeet, float extentOfStripPlane, float yCentreOfStripPlane, const CSCWireGroupPackage &wg, float wireAngleInDegrees, double yOfFirstWire, float hThickness)
float yOfWireGroup(int wireGroup, float x=0.) const
LocalError localError(int strip, float sigmaStrip, float sigmaWire) const
float wireAngle() const
tuple result
Definition: mps_fire.py:95
LocalPoint intersectionOfTwoLines(std::pair< float, float > p1, std::pair< float, float > p2) const
float xOfStrip(int strip, float y=0.) const
bool insideYOfWirePlane(float y) const
virtual float thickness() const
LocalPoint intersectionOfStripAndWire(float s, int w) const
virtual CSCStripTopology * clone() const =0
bool realWireGeometry() const
Definition: CSCGeometry.h:125
float yOfWire(float wire, float x=0.) const
float yy() const
Definition: LocalError.h:26
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
float middleWireOfGroup(int wireGroup) const
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
int numberOfWires() const
virtual ~CSCLayerGeometry()
CSCWireTopology * theWireTopology
double p2[4]
Definition: TauolaWrapper.h:90
#define LogTrace(id)
const std::string myName
std::vector< float > wireValues(float wire) const
bool gangedStrips() const
Definition: CSCGeometry.h:111
LocalPoint localCenterOfWireGroup(int wireGroup) const
std::pair< float, float > equationOfStrip(float strip) const
susybsm::MuonSegment ms
Definition: classes.h:31
LocalPoint stripWireIntersection(int strip, float wire) const
float restrictToYOfWirePlane(float y) const
double p1[4]
Definition: TauolaWrapper.h:89
Local3DPoint LocalPoint
Definition: LocalPoint.h:11
float wirePitch() const
bool inside(const Local3DPoint &, const LocalError &, float scale=1.f) const
CSCLayerGeometry & operator=(const CSCLayerGeometry &)
virtual float length() const
float stripAngle(float strip) const
T x() const
Definition: PV2DBase.h:45
T x() const
Definition: PV3DBase.h:62
float stripAngle(int strip) const
void setTopology(CSCStripTopology *topology)
virtual float strip(const LocalPoint &) const