CMS 3D CMS Logo

CSCLayerGeometry.cc
Go to the documentation of this file.
1 // This is CSCLayerGeometry.cc
2 
5 
9 
11 
13 
14 #include <algorithm>
15 #include <iostream>
16 
17 using namespace geant_units;
18 using namespace geant_units::operators;
19 
20 // Complicated initialization list since the chamber Bounds passed in must have its thickness reset to that of the layer
21 // Note for half-widths, t + b = 2w and the TPB only has accessors for t and w so b = 2w - t
22 
24  int iChamberType,
26  int nstrips,
27  float stripOffset,
28  float stripPhiPitch,
29  float whereStripsMeet,
30  float extentOfStripPlane,
31  float yCentreOfStripPlane,
32  const CSCWireGroupPackage& wg,
33  float wireAngleInDegrees,
34  double yOfFirstWire,
35  float hThickness)
37  bounds.widthAtHalfLength() - bounds.width() / 2., bounds.width() / 2., bounds.length() / 2., hThickness),
38  theWireTopology(nullptr),
39  theStripTopology(nullptr),
40  hBottomEdge(bounds.widthAtHalfLength() - bounds.width() / 2.),
41  hTopEdge(bounds.width() / 2.),
42  apothem(bounds.length() / 2.),
43  myName("CSCLayerGeometry"),
44  chamberType(iChamberType) {
45  LogTrace("CSCLayerGeometry|CSC") << myName << ": being constructed, this=" << this;
46 
47  // Ganged strips in ME1A?
48  bool gangedME1A = (iChamberType == 1 && geom->gangedStrips());
49 
50  CSCStripTopology* aStripTopology = new CSCUngangedStripTopology(
51  nstrips, stripPhiPitch, extentOfStripPlane, whereStripsMeet, stripOffset, yCentreOfStripPlane);
52 
53  if (gangedME1A) {
54  theStripTopology = new CSCGangedStripTopology(*aStripTopology, 16);
55  delete aStripTopology;
56  } else {
57  theStripTopology = aStripTopology;
58  }
59 
60  if (!geom->realWireGeometry()) {
61  // Approximate ORCA_8_8_0 and earlier calculated geometry...
62  float wangler = convertDegToRad(wireAngleInDegrees);
63  float wireCos = cos(wangler);
64  float wireSin = sin(wangler);
65  float y2 = apothem * wireCos + hBottomEdge * fabs(wireSin);
66  float wireSpacing = convertMmToCm(wg.wireSpacing);
67  float wireOffset = -y2 + wireSpacing / 2.;
68  yOfFirstWire = wireOffset / wireCos;
69  }
70 
71  theWireTopology = new CSCWireTopology(wg, yOfFirstWire, wireAngleInDegrees);
72  LogTrace("CSCLayerGeometry|CSC") << myName << ": constructed: " << *this;
73 }
74 
76  : TrapezoidalPlaneBounds(melg.hBottomEdge, melg.hTopEdge, melg.apothem, 0.5 * melg.thickness()),
77  theWireTopology(nullptr),
78  theStripTopology(nullptr),
79  hBottomEdge(melg.hBottomEdge),
80  hTopEdge(melg.hTopEdge),
81  apothem(melg.apothem),
82  chamberType(melg.chamberType) {
83  // CSCStripTopology is abstract, so need clone()
84  if (melg.theStripTopology)
86  // CSCWireTopology is concrete, so direct copy
87  if (melg.theWireTopology)
89 }
90 
92  if (&melg != this) {
93  delete theStripTopology;
94  if (melg.theStripTopology)
96  else
97  theStripTopology = nullptr;
98 
99  delete theWireTopology;
100  if (melg.theWireTopology)
102  else
103  theWireTopology = nullptr;
104 
105  hBottomEdge = melg.hBottomEdge;
106  hTopEdge = melg.hTopEdge;
107  apothem = melg.apothem;
108  }
109  return *this;
110 }
111 
113  LogTrace("CSCLayerGeometry|CSC") << myName << ": being destroyed, this=" << this
114  << "\nDeleting theStripTopology=" << theStripTopology
115  << " and theWireTopology=" << theWireTopology;
116  delete theStripTopology;
117  delete theWireTopology;
118 }
119 
121  // This allows _float_ wire no. so that we can calculate the
122  // intersection of a strip with the mid point of a wire group
123  // containing an even no. of wires (which is not an actual wire),
124  // as well as for a group containing an odd no. of wires.
125 
126  // Equation of wire and strip as straight lines in local xy
127  // y = mx + c where m = tan(angle w.r.t. x axis)
128  // At the intersection x = -(cs-cw)/(ms-mw)
129  // At y=0, 0 = ms * xOfStrip(strip) + cs => cs = -ms*xOfStrip
130  // At x=0, yOfWire(wire) = 0 + cw => cw = yOfWire
131 
132  float ms = tan(stripAngle(strip));
133  float mw = tan(wireAngle());
134  float xs = xOfStrip(strip);
135  float xi = (ms * xs + yOfWire(wire)) / (ms - mw);
136  float yi = ms * (xi - xs);
137 
138  return LocalPoint(xi, yi);
139 }
140 
142  // middleWire is only an actual wire for a group with an odd no. of wires
143  float middleWire = middleWireOfGroup(wireGroup);
144  return stripWireIntersection(strip, middleWire);
145 }
146 
148  // Cleverly subtly change meaning of stripAngle once more.
149  // In TrapezoidalStripTopology it is angle measured
150  // counter-clockwise from y axis.
151  // In APTST and RST it is angle measured
152  // clockwise from y axis.
153  // Output of this function is measured counter-clockwise
154  // from x-axis, so it is a conventional 2-dim azimuthal angle
155  // in the (x,y) local coordinates
156 
157  // We want angle at centre of strip (strip N covers
158  // *float* range N-1 to N-epsilon)
159 
160  return 0.5_pi - theStripTopology->stripAngle(strip - 0.5);
161 }
162 
164  // It can use CSCWireTopology::yOfWireGroup for y,
165  // But x requires mixing with 'extent' of wire plane
166 
167  // If the wires are NOT tilted, default to simple calculation...
168  if (fabs(wireAngle()) < 1.E-6) {
169  float y = yOfWireGroup(wireGroup);
170  return LocalPoint(0., y);
171  } else {
172  // w is "wire" at the center of the wire group
173  float w = middleWireOfGroup(wireGroup);
174  std::vector<float> store = theWireTopology->wireValues(w);
175  return LocalPoint(store[0], store[1]);
176  }
177 }
178 
179 float CSCLayerGeometry::lengthOfWireGroup(int wireGroup) const {
180  // Return length of 'wire' in the middle of the wire group
181  float w = middleWireOfGroup(wireGroup);
182  std::vector<float> store = theWireTopology->wireValues(w);
183  return store[2];
184 }
185 
186 std::pair<LocalPoint, float> CSCLayerGeometry::possibleRecHitPosition(float s, int w1, int w2) const {
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()) + (sw1.y() - sw2.y()) * (sw1.y() - sw2.y()));
195 
196  return std::pair<LocalPoint, float>(midpt, length);
197 }
198 
200  std::pair<float, float> pw = theWireTopology->equationOfWire(static_cast<float>(w));
201  std::pair<float, float> ps = theStripTopology->equationOfStrip(s);
202  LocalPoint sw = intersectionOfTwoLines(ps, pw);
203 
204  // If point falls outside wire plane, at extremes in local y,
205  // replace its y by that of appropriate edge of wire plane
206  if (!(theWireTopology->insideYOfWirePlane(sw.y()))) {
207  float y = theWireTopology->restrictToYOfWirePlane(sw.y());
208  // and adjust x to match new y
209  float x = sw.x() + (y - sw.y()) * tan(theStripTopology->stripAngle(s));
210  sw = LocalPoint(x, y);
211  }
212 
213  return sw;
214 }
215 
216 LocalPoint CSCLayerGeometry::intersectionOfTwoLines(std::pair<float, float> p1, std::pair<float, float> p2) const {
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 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'
271  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()
311  << 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()
317  << std::endl
318  // << "numberOfWiresPerGroup " << lg.theNumberOfWiresPerGroup << std::endl
319  // << "numberOfWiresInLastGroup " << lg.theNumberOfWiresInLastGroup << std::endl
320  // << "wireOffset " << lg.theWireOffset << std::endl
321  // << "whereStripsMeet " << lg.whereStripsMeet << std::endl;
322  << "hBottomEdge " << lg.hBottomEdge << std::endl
323  << "hTopEdge " << lg.hTopEdge << std::endl
324  << "apothem " << lg.apothem << std::endl
325  << "length (should be 2xapothem) " << lg.length() << std::endl
326  << "thickness " << lg.thickness() << std::endl;
327  return stream;
328 }
LocalPoint localCenterOfWireGroup(int wireGroup) const
std::pair< float, float > equationOfWire(float wire) const
float lengthOfWireGroup(int wireGroup) const
LocalPoint intersectionOfTwoLines(std::pair< float, float > p1, std::pair< float, float > p2) const
std::vector< float > wireValues(float wire) const
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:30
constexpr double convertDegToRad(NumType degrees)
Definition: angle_units.h:27
~CSCLayerGeometry() override
float middleWireOfGroup(int wireGroup) const
std::pair< float, float > equationOfStrip(float strip) const
float restrictToYOfWirePlane(float y) const
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
float stripOffset(void) const
T w() const
T z() const
Definition: PV3DBase.h:61
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
CSCStripTopology * theStripTopology
T x() const
Definition: PV2DBase.h:43
float strip(const LocalPoint &) const override
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
float stripAngle(int strip) 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)
#define LogTrace(id)
T y() const
Definition: PV2DBase.h:44
float yy() const
Definition: LocalError.h:24
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
std::pair< LocalPoint, float > possibleRecHitPosition(float s, int w1, int w2) const
virtual CSCStripTopology * clone() const =0
float strip(const LocalPoint &lp) const
float stripPitch() const
int numberOfStrips() const
T sqrt(T t)
Definition: SSEVec.h:19
int numberOfWireGroups() const
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
std::ostream & operator<<(std::ostream &stream, const CSCLayerGeometry &lg)
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
std::pair< float, float > yLimitsOfStripPlane() const
float yOfWireGroup(int wireGroup, float x=0.) const
CSCWireTopology * theWireTopology
float length() const override
int wireGroup(int wire) const
int numberOfWires() const
const std::string myName
float wirePitch() const
float stripPhiPitch() const
constexpr NumType convertMmToCm(NumType millimeters)
Definition: angle_units.h:44
LocalPoint intersectionOfStripAndWire(float s, int w) const
LocalPoint stripWireIntersection(int strip, float wire) const
float yOfWire(float wire, float x=0.) const
LocalPoint stripWireGroupIntersection(int strip, int wireGroup) const
bool insideYOfWirePlane(float y) const
float thickness() const override
CSCLayerGeometry & operator=(const CSCLayerGeometry &)
float xOfStrip(int strip, float y=0.) const
LocalError localError(int strip, float sigmaStrip, float sigmaWire) const
bool inside(const Local3DPoint &, const LocalError &, float scale=1.f) const override
void setTopology(CSCStripTopology *topology)
float xx() const
Definition: LocalError.h:22
float wireAngle() const
float stripAngle(float strip) const override