CMS 3D CMS Logo

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