/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Geometry/CSCGeometry/src/CSCLayerGeometry.cc
328 строк
13 KB
Shahzad Malik Muzaffar
[Geometry] Move public headers on to interface directory
04 авг 2021, 11:32
04 авг 2021, 11:32
1251d71
Код
Авторство
О чём код?
// This is CSCLayerGeometry.cc #include <Geometry/CSCGeometry/interface/CSCGeometry.h> #include <Geometry/CSCGeometry/interface/CSCLayerGeometry.h> #include <Geometry/CSCGeometry/src/CSCUngangedStripTopology.h> #include <Geometry/CSCGeometry/src/CSCGangedStripTopology.h> #include <Geometry/CSCGeometry/interface/CSCWireGroupPackage.h> #include <FWCore/MessageLogger/interface/MessageLogger.h> #include "DataFormats/Math/interface/GeantUnits.h" #include <algorithm> #include <iostream> using namespace geant_units; using namespace geant_units::operators; // Complicated initialization list since the chamber Bounds passed in must have its thickness reset to that of the layer // Note for half-widths, t + b = 2w and the TPB only has accessors for t and w so b = 2w - t CSCLayerGeometry::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) : TrapezoidalPlaneBounds( bounds.widthAtHalfLength() - bounds.width() / 2., bounds.width() / 2., bounds.length() / 2., hThickness), theWireTopology(nullptr), theStripTopology(nullptr), hBottomEdge(bounds.widthAtHalfLength() - bounds.width() / 2.), hTopEdge(bounds.width() / 2.), apothem(bounds.length() / 2.), myName("CSCLayerGeometry"), chamberType(iChamberType) { LogTrace("CSCLayerGeometry|CSC") << myName << ": being constructed, this=" << this; // Ganged strips in ME1A? bool gangedME1A = (iChamberType == 1 && geom->gangedStrips()); CSCStripTopology* aStripTopology = new CSCUngangedStripTopology( nstrips, stripPhiPitch, extentOfStripPlane, whereStripsMeet, stripOffset, yCentreOfStripPlane); if (gangedME1A) { theStripTopology = new CSCGangedStripTopology(*aStripTopology, 16); delete aStripTopology; } else { theStripTopology = aStripTopology; } if (!geom->realWireGeometry()) { // Approximate ORCA_8_8_0 and earlier calculated geometry... float wangler = convertDegToRad(wireAngleInDegrees); float wireCos = cos(wangler); float wireSin = sin(wangler); float y2 = apothem * wireCos + hBottomEdge * fabs(wireSin); float wireSpacing = convertMmToCm(wg.wireSpacing); float wireOffset = -y2 + wireSpacing / 2.; yOfFirstWire = wireOffset / wireCos; } theWireTopology = new CSCWireTopology(wg, yOfFirstWire, wireAngleInDegrees); LogTrace("CSCLayerGeometry|CSC") << myName << ": constructed: " << *this; } CSCLayerGeometry::CSCLayerGeometry(const CSCLayerGeometry& melg) : TrapezoidalPlaneBounds(melg.hBottomEdge, melg.hTopEdge, melg.apothem, 0.5 * melg.thickness()), theWireTopology(nullptr), theStripTopology(nullptr), hBottomEdge(melg.hBottomEdge), hTopEdge(melg.hTopEdge), apothem(melg.apothem), chamberType(melg.chamberType) { // CSCStripTopology is abstract, so need clone() if (melg.theStripTopology) theStripTopology = melg.theStripTopology->clone(); // CSCWireTopology is concrete, so direct copy if (melg.theWireTopology) theWireTopology = new CSCWireTopology(*(melg.theWireTopology)); } CSCLayerGeometry& CSCLayerGeometry::operator=(const CSCLayerGeometry& melg) { if (&melg != this) { delete theStripTopology; if (melg.theStripTopology) theStripTopology = melg.theStripTopology->clone(); else theStripTopology = nullptr; delete theWireTopology; if (melg.theWireTopology) theWireTopology = new CSCWireTopology(*(melg.theWireTopology)); else theWireTopology = nullptr; hBottomEdge = melg.hBottomEdge; hTopEdge = melg.hTopEdge; apothem = melg.apothem; } return *this; } CSCLayerGeometry::~CSCLayerGeometry() { LogTrace("CSCLayerGeometry|CSC") << myName << ": being destroyed, this=" << this << "\nDeleting theStripTopology=" << theStripTopology << " and theWireTopology=" << theWireTopology; delete theStripTopology; delete theWireTopology; } LocalPoint CSCLayerGeometry::stripWireIntersection(int strip, float wire) const { // This allows _float_ wire no. so that we can calculate the // intersection of a strip with the mid point of a wire group // containing an even no. of wires (which is not an actual wire), // as well as for a group containing an odd no. of wires. // Equation of wire and strip as straight lines in local xy // y = mx + c where m = tan(angle w.r.t. x axis) // At the intersection x = -(cs-cw)/(ms-mw) // At y=0, 0 = ms * xOfStrip(strip) + cs => cs = -ms*xOfStrip // At x=0, yOfWire(wire) = 0 + cw => cw = yOfWire float ms = tan(stripAngle(strip)); float mw = tan(wireAngle()); float xs = xOfStrip(strip); float xi = (ms * xs + yOfWire(wire)) / (ms - mw); float yi = ms * (xi - xs); return LocalPoint(xi, yi); } LocalPoint CSCLayerGeometry::stripWireGroupIntersection(int strip, int wireGroup) const { // middleWire is only an actual wire for a group with an odd no. of wires float middleWire = middleWireOfGroup(wireGroup); return stripWireIntersection(strip, middleWire); } float CSCLayerGeometry::stripAngle(int strip) const { // Cleverly subtly change meaning of stripAngle once more. // In TrapezoidalStripTopology it is angle measured // counter-clockwise from y axis. // In APTST and RST it is angle measured // clockwise from y axis. // Output of this function is measured counter-clockwise // from x-axis, so it is a conventional 2-dim azimuthal angle // in the (x,y) local coordinates // We want angle at centre of strip (strip N covers // *float* range N-1 to N-epsilon) return 0.5_pi - theStripTopology->stripAngle(strip - 0.5); } LocalPoint CSCLayerGeometry::localCenterOfWireGroup(int wireGroup) const { // It can use CSCWireTopology::yOfWireGroup for y, // But x requires mixing with 'extent' of wire plane // If the wires are NOT tilted, default to simple calculation... if (fabs(wireAngle()) < 1.E-6) { float y = yOfWireGroup(wireGroup); return LocalPoint(0., y); } else { // w is "wire" at the center of the wire group float w = middleWireOfGroup(wireGroup); std::vector<float> store = theWireTopology->wireValues(w); return LocalPoint(store[0], store[1]); } } float CSCLayerGeometry::lengthOfWireGroup(int wireGroup) const { // Return length of 'wire' in the middle of the wire group float w = middleWireOfGroup(wireGroup); std::vector<float> store = theWireTopology->wireValues(w); return store[2]; } std::pair<LocalPoint, float> CSCLayerGeometry::possibleRecHitPosition(float s, int w1, int w2) const { LocalPoint sw1 = intersectionOfStripAndWire(s, w1); LocalPoint sw2 = intersectionOfStripAndWire(s, w2); // Average the two points LocalPoint midpt((sw1.x() + sw2.x()) / 2., (sw1.y() + sw2.y()) / 2); // Length of strip crossing this group of wires float length = sqrt((sw1.x() - sw2.x()) * (sw1.x() - sw2.x()) + (sw1.y() - sw2.y()) * (sw1.y() - sw2.y())); return std::pair<LocalPoint, float>(midpt, length); } LocalPoint CSCLayerGeometry::intersectionOfStripAndWire(float s, int w) const { std::pair<float, float> pw = theWireTopology->equationOfWire(static_cast<float>(w)); std::pair<float, float> ps = theStripTopology->equationOfStrip(s); LocalPoint sw = intersectionOfTwoLines(ps, pw); // If point falls outside wire plane, at extremes in local y, // replace its y by that of appropriate edge of wire plane if (!(theWireTopology->insideYOfWirePlane(sw.y()))) { float y = theWireTopology->restrictToYOfWirePlane(sw.y()); // and adjust x to match new y float x = sw.x() + (y - sw.y()) * tan(theStripTopology->stripAngle(s)); sw = LocalPoint(x, y); } return sw; } LocalPoint CSCLayerGeometry::intersectionOfTwoLines(std::pair<float, float> p1, std::pair<float, float> p2) const { // Calculate the point of intersection of two straight lines (in 2-dim) // input arguments are pair(m1,c1) and pair(m2,c2) where m=slope, c=intercept (y=mx+c) // BEWARE! Do not call with m1 = m2 ! No trapping ! float m1 = p1.first; float c1 = p1.second; float m2 = p2.first; float c2 = p2.second; float x = (c2 - c1) / (m1 - m2); float y = (m1 * c2 - m2 * c1) / (m1 - m2); return LocalPoint(x, y); } LocalError CSCLayerGeometry::localError(int strip, float sigmaStrip, float sigmaWire) const { // Input sigmas are expected to be in _distance units_ // - uncertainty in strip measurement (typically from Gatti fit, value is in local x units) // - uncertainty in wire measurement (along direction perpendicular to wires) float wangle = this->wireAngle(); float strangle = this->stripAngle(strip); float sinAngdif = sin(strangle - wangle); float sinAngdif2 = sinAngdif * sinAngdif; float du = sigmaStrip / sin(strangle); // sigmaStrip is just x-component of strip error float dv = sigmaWire; // The notation is // wsins = wire resol * sin(strip angle) // wcoss = wire resol * cos(strip angle) // ssinw = strip resol * sin(wire angle) // scosw = strip resol * cos(wire angle) float wsins = dv * sin(strangle); float wcoss = dv * cos(strangle); float ssinw = du * sin(wangle); float scosw = du * cos(wangle); float dx2 = (scosw * scosw + wcoss * wcoss) / sinAngdif2; float dy2 = (ssinw * ssinw + wsins * wsins) / sinAngdif2; float dxy = (scosw * ssinw + wcoss * wsins) / sinAngdif2; return LocalError(dx2, dxy, dy2); } bool CSCLayerGeometry::inside(const Local3DPoint& lp) const { bool result = false; const float epsilon = 1.e-06; if (fabs(lp.z()) < thickness() / 2.) { // thickness of TPB is that of gas layer std::pair<float, float> ylims = yLimitsOfStripPlane(); if ((lp.y() > ylims.first) && (lp.y() < ylims.second)) { // 'strip' returns float value between 0. and float(Nstrips) and value outside // is set to 0. or float(Nstrips)... add a conservative precision of 'epsilon' if ((theStripTopology->strip(lp) > epsilon) && (theStripTopology->strip(lp) < (numberOfStrips() - epsilon))) result = true; } } return result; } bool CSCLayerGeometry::inside(const Local2DPoint& lp) const { LocalPoint lp2(lp.x(), lp.y(), 0.); return inside(lp2); } bool CSCLayerGeometry::inside(const Local3DPoint& lp, const LocalError& le, float scale) const { // Effectively consider that the LocalError components extend the area which is acceptable. // Form a little box centered on the point, with x, y diameters defined by the errors // and require that ALL four corners of the box fall outside the strip region for failure // Note that LocalError is 2-dim x,y and doesn't supply a z error float deltaX = scale * sqrt(le.xx()); float deltaY = scale * sqrt(le.yy()); LocalPoint lp1(lp.x() - deltaX, lp.y() - deltaY, lp.z()); LocalPoint lp2(lp.x() - deltaX, lp.y() + deltaY, lp.z()); LocalPoint lp3(lp.x() + deltaX, lp.y() + deltaY, lp.z()); LocalPoint lp4(lp.x() + deltaX, lp.y() - deltaY, lp.z()); return (inside(lp1) || inside(lp2) || inside(lp3) || inside(lp4)); } void CSCLayerGeometry::setTopology(CSCStripTopology* newTopology) { delete theStripTopology; theStripTopology = newTopology; } std::ostream& operator<<(std::ostream& stream, const CSCLayerGeometry& lg) { stream << "LayerGeometry " << std::endl << "------------- " << std::endl << "numberOfStrips " << lg.numberOfStrips() << std::endl << "numberOfWires " << lg.numberOfWires() << std::endl << "numberOfWireGroups " << lg.numberOfWireGroups() << std::endl << "wireAngle (rad) " << lg.wireAngle() << std::endl // << "wireAngle (deg) " << lg.theWireAngle << std::endl // << "sin(wireAngle) " << lg.theWireSin << std::endl // << "cos(wireAngle) " << lg.theWireCos << std::endl << "wirePitch " << lg.wirePitch() << std::endl << "stripPitch " << lg.stripPitch() << std::endl // << "numberOfWiresPerGroup " << lg.theNumberOfWiresPerGroup << std::endl // << "numberOfWiresInLastGroup " << lg.theNumberOfWiresInLastGroup << std::endl // << "wireOffset " << lg.theWireOffset << std::endl // << "whereStripsMeet " << lg.whereStripsMeet << std::endl; << "hBottomEdge " << lg.hBottomEdge << std::endl << "hTopEdge " << lg.hTopEdge << std::endl << "apothem " << lg.apothem << std::endl << "length (should be 2xapothem) " << lg.length() << std::endl << "thickness " << lg.thickness() << std::endl; return stream; }