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
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 
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  LocalPoint sw2(sw.x(), y);
208  sw = sw2;
209  }
210 
211  return sw;
212 }
213 
214 LocalPoint CSCLayerGeometry::intersectionOfTwoLines( std::pair<float, float> p1, std::pair<float, float> p2 ) const {
215 
216  // Calculate the point of intersection of two straight lines (in 2-dim)
217  // input arguments are pair(m1,c1) and pair(m2,c2) where m=slope, c=intercept (y=mx+c)
218  // BEWARE! Do not call with m1 = m2 ! No trapping !
219 
220  float m1 = p1.first;
221  float c1 = p1.second;
222  float m2 = p2.first;
223  float c2 = p2.second;
224  float x = (c2-c1)/(m1-m2);
225  float y = (m1*c2-m2*c1)/(m1-m2);
226  return LocalPoint( x, y );
227 }
228 
229 
230 LocalError CSCLayerGeometry::localError( int strip, float sigmaStrip, float sigmaWire ) const {
231  // Input sigmas are expected to be in _distance units_
232  // - uncertainty in strip measurement (typically from Gatti fit, value is in local x units)
233  // - uncertainty in wire measurement (along direction perpendicular to wires)
234 
235  float wangle = this->wireAngle();
236  float strangle = this->stripAngle( strip );
237 
238  float sinAngdif = sin(strangle-wangle);
239  float sinAngdif2 = sinAngdif * sinAngdif;
240 
241  float du = sigmaStrip/sin(strangle); // sigmaStrip is just x-component of strip error
242  float dv = sigmaWire;
243 
244  // The notation is
245  // wsins = wire resol * sin(strip angle)
246  // wcoss = wire resol * cos(strip angle)
247  // ssinw = strip resol * sin(wire angle)
248  // scosw = strip resol * cos(wire angle)
249 
250  float wsins = dv * sin(strangle);
251  float wcoss = dv * cos(strangle);
252  float ssinw = du * sin(wangle);
253  float scosw = du * cos(wangle);
254 
255  float dx2 = (scosw*scosw + wcoss*wcoss)/sinAngdif2;
256  float dy2 = (ssinw*ssinw + wsins*wsins)/sinAngdif2;
257  float dxy = (scosw*ssinw + wcoss*wsins)/sinAngdif2;
258 
259  return LocalError(dx2, dxy, dy2);
260 }
261 
262 bool CSCLayerGeometry::inside( const Local3DPoint& lp ) const {
263  bool result = false;
264  const float epsilon = 1.e-06;
265  if ( fabs( lp.z() ) < thickness()/2. ) { // thickness of TPB is that of gas layer
266  std::pair<float, float> ylims = yLimitsOfStripPlane();
267  if ( (lp.y() > ylims.first) && (lp.y() < ylims.second) ) {
268  // 'strip' returns float value between 0. and float(Nstrips) and value outside
269  // is set to 0. or float(Nstrips)... add a conservative precision of 'epsilon'
270  if ( ( theStripTopology->strip(lp) > epsilon ) &&
271  ( theStripTopology->strip(lp) < (numberOfStrips() - epsilon) ) ) result = true;
272  }
273  }
274  return result;
275 }
276 
277 bool CSCLayerGeometry::inside( const Local2DPoint& lp ) const {
278  LocalPoint lp2( lp.x(), lp.y(), 0. );
279  return inside( lp2 );
280 }
281 
282 bool CSCLayerGeometry::inside( const Local3DPoint& lp, const LocalError& le, float scale ) const {
283  // Effectively consider that the LocalError components extend the area which is acceptable.
284  // Form a little box centered on the point, with x, y diameters defined by the errors
285  // and require that ALL four corners of the box fall outside the strip region for failure
286 
287  // Note that LocalError is 2-dim x,y and doesn't supply a z error
288  float deltaX = scale*sqrt(le.xx());
289  float deltaY = scale*sqrt(le.yy());
290 
291  LocalPoint lp1( lp.x()-deltaX, lp.y()-deltaY, lp.z() );
292  LocalPoint lp2( lp.x()-deltaX, lp.y()+deltaY, lp.z() );
293  LocalPoint lp3( lp.x()+deltaX, lp.y()+deltaY, lp.z() );
294  LocalPoint lp4( lp.x()+deltaX, lp.y()-deltaY, lp.z() );
295 
296  return ( inside(lp1) || inside(lp2) || inside(lp3) || inside(lp4) );
297 }
298 
300  delete theStripTopology;
301  theStripTopology = newTopology;
302 }
303 
304 std::ostream & operator<<(std::ostream & stream, const CSCLayerGeometry & lg) {
305  stream << "LayerGeometry " << std::endl
306  << "------------- " << std::endl
307  << "numberOfStrips " << lg.numberOfStrips() << std::endl
308  << "numberOfWires " << lg.numberOfWires() << std::endl
309  << "numberOfWireGroups " << lg.numberOfWireGroups() << std::endl
310  << "wireAngle (rad) " << lg.wireAngle() << std::endl
311  // << "wireAngle (deg) " << lg.theWireAngle << std::endl
312  // << "sin(wireAngle) " << lg.theWireSin << std::endl
313  // << "cos(wireAngle) " << lg.theWireCos << std::endl
314  << "wirePitch " << lg.wirePitch() << std::endl
315  << "stripPitch " << lg.stripPitch() << std::endl
316  // << "numberOfWiresPerGroup " << lg.theNumberOfWiresPerGroup << std::endl
317  // << "numberOfWiresInLastGroup " << lg.theNumberOfWiresInLastGroup << std::endl
318  // << "wireOffset " << lg.theWireOffset << std::endl
319  // << "whereStripsMeet " << lg.whereStripsMeet << std::endl;
320  << "hBottomEdge " << lg.hBottomEdge << std::endl
321  << "hTopEdge " << lg.hTopEdge << std::endl
322  << "apothem " << lg.apothem << std::endl
323  << "length (should be 2xapothem) " << lg.length() << std::endl
324  << "thickness " << lg.thickness() << std::endl;
325  return stream;
326 }
327 
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:45
void strip(std::string &input, const std::string &blanks=" \n\t")
Definition: stringTools.cc:16
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
float lengthOfWireGroup(int wireGroup) const
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
T y() const
Definition: PV3DBase.h:62
#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
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:121
float yOfWire(float wire, float x=0.) const
float yy() const
Definition: LocalError.h:26
T sqrt(T t)
Definition: SSEVec.h:46
T z() const
Definition: PV3DBase.h:63
tuple result
Definition: query.py:137
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:107
LocalPoint localCenterOfWireGroup(int wireGroup) const
std::pair< float, float > equationOfStrip(float strip) const
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
const double epsilon
Definition: DDAxes.h:10
float stripAngle(float strip) const
T x() const
Definition: PV2DBase.h:44
T x() const
Definition: PV3DBase.h:61
float stripAngle(int strip) const
void setTopology(CSCStripTopology *topology)
T w() const
virtual float strip(const LocalPoint &) const