File indexing completed on 2024-04-06 12:14:24
0001
0002
0003 #include <Geometry/CSCGeometry/interface/CSCGeometry.h>
0004 #include <Geometry/CSCGeometry/interface/CSCLayerGeometry.h>
0005
0006 #include <Geometry/CSCGeometry/src/CSCUngangedStripTopology.h>
0007 #include <Geometry/CSCGeometry/src/CSCGangedStripTopology.h>
0008 #include <Geometry/CSCGeometry/interface/CSCWireGroupPackage.h>
0009
0010 #include <FWCore/MessageLogger/interface/MessageLogger.h>
0011
0012 #include "DataFormats/Math/interface/GeantUnits.h"
0013
0014 #include <algorithm>
0015 #include <iostream>
0016
0017 using namespace geant_units;
0018 using namespace geant_units::operators;
0019
0020
0021
0022
0023 CSCLayerGeometry::CSCLayerGeometry(const CSCGeometry* geom,
0024 int iChamberType,
0025 const TrapezoidalPlaneBounds& bounds,
0026 int nstrips,
0027 float stripOffset,
0028 float stripPhiPitch,
0029 float whereStripsMeet,
0030 float extentOfStripPlane,
0031 float yCentreOfStripPlane,
0032 const CSCWireGroupPackage& wg,
0033 float wireAngleInDegrees,
0034 double yOfFirstWire,
0035 float hThickness)
0036 : TrapezoidalPlaneBounds(
0037 bounds.widthAtHalfLength() - bounds.width() / 2., bounds.width() / 2., bounds.length() / 2., hThickness),
0038 theWireTopology(nullptr),
0039 theStripTopology(nullptr),
0040 hBottomEdge(bounds.widthAtHalfLength() - bounds.width() / 2.),
0041 hTopEdge(bounds.width() / 2.),
0042 apothem(bounds.length() / 2.),
0043 myName("CSCLayerGeometry"),
0044 chamberType(iChamberType) {
0045 LogTrace("CSCLayerGeometry|CSC") << myName << ": being constructed, this=" << this;
0046
0047
0048 bool gangedME1A = (iChamberType == 1 && geom->gangedStrips());
0049
0050 CSCStripTopology* aStripTopology = new CSCUngangedStripTopology(
0051 nstrips, stripPhiPitch, extentOfStripPlane, whereStripsMeet, stripOffset, yCentreOfStripPlane);
0052
0053 if (gangedME1A) {
0054 theStripTopology = new CSCGangedStripTopology(*aStripTopology, 16);
0055 delete aStripTopology;
0056 } else {
0057 theStripTopology = aStripTopology;
0058 }
0059
0060 if (!geom->realWireGeometry()) {
0061
0062 float wangler = convertDegToRad(wireAngleInDegrees);
0063 float wireCos = cos(wangler);
0064 float wireSin = sin(wangler);
0065 float y2 = apothem * wireCos + hBottomEdge * fabs(wireSin);
0066 float wireSpacing = convertMmToCm(wg.wireSpacing);
0067 float wireOffset = -y2 + wireSpacing / 2.;
0068 yOfFirstWire = wireOffset / wireCos;
0069 }
0070
0071 theWireTopology = new CSCWireTopology(wg, yOfFirstWire, wireAngleInDegrees);
0072 LogTrace("CSCLayerGeometry|CSC") << myName << ": constructed: " << *this;
0073 }
0074
0075 CSCLayerGeometry::CSCLayerGeometry(const CSCLayerGeometry& melg)
0076 : TrapezoidalPlaneBounds(melg.hBottomEdge, melg.hTopEdge, melg.apothem, 0.5 * melg.thickness()),
0077 theWireTopology(nullptr),
0078 theStripTopology(nullptr),
0079 hBottomEdge(melg.hBottomEdge),
0080 hTopEdge(melg.hTopEdge),
0081 apothem(melg.apothem),
0082 chamberType(melg.chamberType) {
0083
0084 if (melg.theStripTopology)
0085 theStripTopology = melg.theStripTopology->clone();
0086
0087 if (melg.theWireTopology)
0088 theWireTopology = new CSCWireTopology(*(melg.theWireTopology));
0089 }
0090
0091 CSCLayerGeometry& CSCLayerGeometry::operator=(const CSCLayerGeometry& melg) {
0092 if (&melg != this) {
0093 delete theStripTopology;
0094 if (melg.theStripTopology)
0095 theStripTopology = melg.theStripTopology->clone();
0096 else
0097 theStripTopology = nullptr;
0098
0099 delete theWireTopology;
0100 if (melg.theWireTopology)
0101 theWireTopology = new CSCWireTopology(*(melg.theWireTopology));
0102 else
0103 theWireTopology = nullptr;
0104
0105 hBottomEdge = melg.hBottomEdge;
0106 hTopEdge = melg.hTopEdge;
0107 apothem = melg.apothem;
0108 }
0109 return *this;
0110 }
0111
0112 CSCLayerGeometry::~CSCLayerGeometry() {
0113 LogTrace("CSCLayerGeometry|CSC") << myName << ": being destroyed, this=" << this
0114 << "\nDeleting theStripTopology=" << theStripTopology
0115 << " and theWireTopology=" << theWireTopology;
0116 delete theStripTopology;
0117 delete theWireTopology;
0118 }
0119
0120 LocalPoint CSCLayerGeometry::stripWireIntersection(int strip, float wire) const {
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 float ms = tan(stripAngle(strip));
0133 float mw = tan(wireAngle());
0134 float xs = xOfStrip(strip);
0135 float xi = (ms * xs + yOfWire(wire)) / (ms - mw);
0136 float yi = ms * (xi - xs);
0137
0138 return LocalPoint(xi, yi);
0139 }
0140
0141 LocalPoint CSCLayerGeometry::stripWireGroupIntersection(int strip, int wireGroup) const {
0142
0143 float middleWire = middleWireOfGroup(wireGroup);
0144 return stripWireIntersection(strip, middleWire);
0145 }
0146
0147 float CSCLayerGeometry::stripAngle(int strip) const {
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 return 0.5_pi - theStripTopology->stripAngle(strip - 0.5);
0161 }
0162
0163 LocalPoint CSCLayerGeometry::localCenterOfWireGroup(int wireGroup) const {
0164
0165
0166
0167
0168 if (fabs(wireAngle()) < 1.E-6) {
0169 float y = yOfWireGroup(wireGroup);
0170 return LocalPoint(0., y);
0171 } else {
0172
0173 float w = middleWireOfGroup(wireGroup);
0174 std::vector<float> store = theWireTopology->wireValues(w);
0175 return LocalPoint(store[0], store[1]);
0176 }
0177 }
0178
0179 float CSCLayerGeometry::lengthOfWireGroup(int wireGroup) const {
0180
0181 float w = middleWireOfGroup(wireGroup);
0182 std::vector<float> store = theWireTopology->wireValues(w);
0183 return store[2];
0184 }
0185
0186 std::pair<LocalPoint, float> CSCLayerGeometry::possibleRecHitPosition(float s, int w1, int w2) const {
0187 LocalPoint sw1 = intersectionOfStripAndWire(s, w1);
0188 LocalPoint sw2 = intersectionOfStripAndWire(s, w2);
0189
0190
0191 LocalPoint midpt((sw1.x() + sw2.x()) / 2., (sw1.y() + sw2.y()) / 2);
0192
0193
0194 float length = sqrt((sw1.x() - sw2.x()) * (sw1.x() - sw2.x()) + (sw1.y() - sw2.y()) * (sw1.y() - sw2.y()));
0195
0196 return std::pair<LocalPoint, float>(midpt, length);
0197 }
0198
0199 LocalPoint CSCLayerGeometry::intersectionOfStripAndWire(float s, int w) const {
0200 std::pair<float, float> pw = theWireTopology->equationOfWire(static_cast<float>(w));
0201 std::pair<float, float> ps = theStripTopology->equationOfStrip(s);
0202 LocalPoint sw = intersectionOfTwoLines(ps, pw);
0203
0204
0205
0206 if (!(theWireTopology->insideYOfWirePlane(sw.y()))) {
0207 float y = theWireTopology->restrictToYOfWirePlane(sw.y());
0208
0209 float x = sw.x() + (y - sw.y()) * tan(theStripTopology->stripAngle(s));
0210 sw = LocalPoint(x, y);
0211 }
0212
0213 return sw;
0214 }
0215
0216 LocalPoint CSCLayerGeometry::intersectionOfTwoLines(std::pair<float, float> p1, std::pair<float, float> p2) const {
0217
0218
0219
0220
0221 float m1 = p1.first;
0222 float c1 = p1.second;
0223 float m2 = p2.first;
0224 float c2 = p2.second;
0225 float x = (c2 - c1) / (m1 - m2);
0226 float y = (m1 * c2 - m2 * c1) / (m1 - m2);
0227 return LocalPoint(x, y);
0228 }
0229
0230 LocalError CSCLayerGeometry::localError(int strip, float sigmaStrip, float sigmaWire) const {
0231
0232
0233
0234
0235 float wangle = this->wireAngle();
0236 float strangle = this->stripAngle(strip);
0237
0238 float sinAngdif = sin(strangle - wangle);
0239 float sinAngdif2 = sinAngdif * sinAngdif;
0240
0241 float du = sigmaStrip / sin(strangle);
0242 float dv = sigmaWire;
0243
0244
0245
0246
0247
0248
0249
0250 float wsins = dv * sin(strangle);
0251 float wcoss = dv * cos(strangle);
0252 float ssinw = du * sin(wangle);
0253 float scosw = du * cos(wangle);
0254
0255 float dx2 = (scosw * scosw + wcoss * wcoss) / sinAngdif2;
0256 float dy2 = (ssinw * ssinw + wsins * wsins) / sinAngdif2;
0257 float dxy = (scosw * ssinw + wcoss * wsins) / sinAngdif2;
0258
0259 return LocalError(dx2, dxy, dy2);
0260 }
0261
0262 bool CSCLayerGeometry::inside(const Local3DPoint& lp) const {
0263 bool result = false;
0264 const float epsilon = 1.e-06;
0265 if (fabs(lp.z()) < thickness() / 2.) {
0266 std::pair<float, float> ylims = yLimitsOfStripPlane();
0267 if ((lp.y() > ylims.first) && (lp.y() < ylims.second)) {
0268
0269
0270 if ((theStripTopology->strip(lp) > epsilon) && (theStripTopology->strip(lp) < (numberOfStrips() - epsilon)))
0271 result = true;
0272 }
0273 }
0274 return result;
0275 }
0276
0277 bool CSCLayerGeometry::inside(const Local2DPoint& lp) const {
0278 LocalPoint lp2(lp.x(), lp.y(), 0.);
0279 return inside(lp2);
0280 }
0281
0282 bool CSCLayerGeometry::inside(const Local3DPoint& lp, const LocalError& le, float scale) const {
0283
0284
0285
0286
0287
0288 float deltaX = scale * sqrt(le.xx());
0289 float deltaY = scale * sqrt(le.yy());
0290
0291 LocalPoint lp1(lp.x() - deltaX, lp.y() - deltaY, lp.z());
0292 LocalPoint lp2(lp.x() - deltaX, lp.y() + deltaY, lp.z());
0293 LocalPoint lp3(lp.x() + deltaX, lp.y() + deltaY, lp.z());
0294 LocalPoint lp4(lp.x() + deltaX, lp.y() - deltaY, lp.z());
0295
0296 return (inside(lp1) || inside(lp2) || inside(lp3) || inside(lp4));
0297 }
0298
0299 void CSCLayerGeometry::setTopology(CSCStripTopology* newTopology) {
0300 delete theStripTopology;
0301 theStripTopology = newTopology;
0302 }
0303
0304 std::ostream& operator<<(std::ostream& stream, const CSCLayerGeometry& lg) {
0305 stream << "LayerGeometry " << std::endl
0306 << "------------- " << std::endl
0307 << "numberOfStrips " << lg.numberOfStrips() << std::endl
0308 << "numberOfWires " << lg.numberOfWires() << std::endl
0309 << "numberOfWireGroups " << lg.numberOfWireGroups() << std::endl
0310 << "wireAngle (rad) " << lg.wireAngle()
0311 << std::endl
0312
0313
0314
0315 << "wirePitch " << lg.wirePitch() << std::endl
0316 << "stripPitch " << lg.stripPitch()
0317 << std::endl
0318
0319
0320
0321
0322 << "hBottomEdge " << lg.hBottomEdge << std::endl
0323 << "hTopEdge " << lg.hTopEdge << std::endl
0324 << "apothem " << lg.apothem << std::endl
0325 << "length (should be 2xapothem) " << lg.length() << std::endl
0326 << "thickness " << lg.thickness() << std::endl;
0327 return stream;
0328 }