File indexing completed on 2024-05-10 02:20:52
0001
0002
0003
0004
0005 #include "Geometry/RPCGeometryBuilder/src/RPCGeometryBuilderFromCondDB.h"
0006 #include "Geometry/RPCGeometry/interface/RPCGeometry.h"
0007 #include "Geometry/RPCGeometry/interface/RPCRollSpecs.h"
0008
0009 #include <DetectorDescription/Core/interface/DDFilter.h>
0010 #include <DetectorDescription/Core/interface/DDFilteredView.h>
0011 #include <DetectorDescription/Core/interface/DDSolid.h>
0012
0013 #include "Geometry/MuonNumbering/interface/MuonGeometryConstants.h"
0014 #include "Geometry/MuonNumbering/interface/MuonBaseNumber.h"
0015 #include "Geometry/MuonNumbering/interface/RPCNumberingScheme.h"
0016
0017 #include "DataFormats/GeometrySurface/interface/RectangularPlaneBounds.h"
0018 #include "DataFormats/GeometrySurface/interface/TrapezoidalPlaneBounds.h"
0019 #include "Geometry/CommonTopologies/interface/TrapezoidalStripTopology.h"
0020
0021 #include "DataFormats/GeometryVector/interface/Basic3DVector.h"
0022
0023 #include <CLHEP/Units/SystemOfUnits.h>
0024
0025 #include <iostream>
0026 #include <algorithm>
0027
0028 using CLHEP::cm;
0029
0030 RPCGeometryBuilderFromCondDB::RPCGeometryBuilderFromCondDB() {}
0031
0032 RPCGeometryBuilderFromCondDB::~RPCGeometryBuilderFromCondDB() {}
0033
0034 RPCGeometry* RPCGeometryBuilderFromCondDB::build(const RecoIdealGeometry& rgeo) {
0035 const std::vector<DetId>& detids(rgeo.detIds());
0036 RPCGeometry* geometry = new RPCGeometry();
0037
0038 for (unsigned int id = 0; id < detids.size(); ++id) {
0039 RPCDetId rpcid(detids[id]);
0040 RPCDetId chid(rpcid.region(), rpcid.ring(), rpcid.station(), rpcid.sector(), rpcid.layer(), rpcid.subsector(), 0);
0041
0042 const auto tranStart = rgeo.tranStart(id);
0043 const auto shapeStart = rgeo.shapeStart(id);
0044 const auto rotStart = rgeo.rotStart(id);
0045 const std::string& name = *rgeo.strStart(id);
0046
0047 Surface::PositionType pos(*(tranStart) / cm, *(tranStart + 1) / cm, *(tranStart + 2) / cm);
0048
0049 Surface::RotationType rot(*(rotStart + 0),
0050 *(rotStart + 1),
0051 *(rotStart + 2),
0052 *(rotStart + 3),
0053 *(rotStart + 4),
0054 *(rotStart + 5),
0055 *(rotStart + 6),
0056 *(rotStart + 7),
0057 *(rotStart + 8));
0058
0059 RPCRollSpecs* rollspecs = nullptr;
0060 Bounds* bounds = nullptr;
0061
0062 if (rgeo.shapeEnd(id) - shapeStart == 4) {
0063 const float width = *(shapeStart + 0) / cm;
0064 const float length = *(shapeStart + 1) / cm;
0065 const float thickness = *(shapeStart + 2) / cm;
0066 const float nstrip = *(shapeStart + 3);
0067
0068 bounds = new RectangularPlaneBounds(width, length, thickness);
0069 const std::vector<float> pars = {width, length, nstrip};
0070
0071 rollspecs = new RPCRollSpecs(GeomDetEnumerators::RPCBarrel, name, pars);
0072
0073 } else {
0074 const float be = *(shapeStart + 0) / cm;
0075 const float te = *(shapeStart + 1) / cm;
0076 const float ap = *(shapeStart + 2) / cm;
0077 const float ti = *(shapeStart + 3) / cm;
0078 const float nstrip = *(shapeStart + 4);
0079
0080 bounds = new TrapezoidalPlaneBounds(be, te, ap, ti);
0081 const std::vector<float> pars = {be, te, ap, nstrip};
0082
0083 rollspecs = new RPCRollSpecs(GeomDetEnumerators::RPCEndcap, name, pars);
0084
0085
0086 Basic3DVector<float> newX(1., 0., 0.);
0087 Basic3DVector<float> newY(0., 0., 1.);
0088
0089 newY *= -1;
0090 Basic3DVector<float> newZ(0., 1., 0.);
0091 rot.rotateAxes(newX, newY, newZ);
0092 }
0093
0094 BoundPlane* bp = new BoundPlane(pos, rot, bounds);
0095 ReferenceCountingPointer<BoundPlane> surf(bp);
0096 RPCRoll* r = new RPCRoll(rpcid, surf, rollspecs);
0097 geometry->add(r);
0098
0099 auto rls = chids.find(chid);
0100 if (rls == chids.end())
0101 rls = chids.insert(std::make_pair(chid, std::list<RPCRoll*>())).first;
0102 rls->second.emplace_back(r);
0103 }
0104
0105
0106 for (auto& ich : chids) {
0107 const RPCDetId& chid = ich.first;
0108 const auto& rls = ich.second;
0109
0110
0111 BoundPlane* bp = nullptr;
0112 if (!rls.empty()) {
0113
0114 const auto& refSurf = (*rls.begin())->surface();
0115 if (chid.region() == 0) {
0116 float corners[6] = {0, 0, 0, 0, 0, 0};
0117 for (auto rl : rls) {
0118 const double h2 = rl->surface().bounds().length() / 2;
0119 const double w2 = rl->surface().bounds().width() / 2;
0120 const auto x1y1AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(-w2, -h2, 0)));
0121 const auto x2y2AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(+w2, +h2, 0)));
0122 corners[0] = std::min(corners[0], x1y1AtRef.x());
0123 corners[1] = std::min(corners[1], x1y1AtRef.y());
0124 corners[2] = std::max(corners[2], x2y2AtRef.x());
0125 corners[3] = std::max(corners[3], x2y2AtRef.y());
0126
0127 corners[4] = std::min(corners[4], x1y1AtRef.z());
0128 corners[5] = std::max(corners[5], x1y1AtRef.z());
0129 }
0130 const LocalPoint lpOfCentre((corners[0] + corners[2]) / 2, (corners[1] + corners[3]) / 2, 0);
0131 const auto gpOfCentre = refSurf.toGlobal(lpOfCentre);
0132 auto bounds = new RectangularPlaneBounds(
0133 (corners[2] - corners[0]) / 2, (corners[3] - corners[1]) / 2, (corners[5] - corners[4]) + 0.5);
0134 bp = new BoundPlane(gpOfCentre, refSurf.rotation(), bounds);
0135 } else {
0136 float cornersLo[3] = {0, 0, 0}, cornersHi[3] = {0, 0, 0};
0137 float cornersZ[2] = {0, 0};
0138 for (auto rl : rls) {
0139 const double h2 = rl->surface().bounds().length() / 2;
0140 const double w2 = rl->surface().bounds().width() / 2;
0141 const auto& topo = dynamic_cast<const TrapezoidalStripTopology&>(rl->specificTopology());
0142 const double r = topo.radius();
0143 const double wAtLo = w2 / r * (r - h2);
0144 const double wAtHi = w2 / r * (r + h2);
0145
0146 const auto x1y1AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(-wAtLo, -h2, 0)));
0147 const auto x2y1AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(+wAtLo, -h2, 0)));
0148 const auto x1y2AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(-wAtHi, +h2, 0)));
0149 const auto x2y2AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(+wAtHi, +h2, 0)));
0150
0151 cornersLo[0] = std::min(cornersLo[0], x1y1AtRef.x());
0152 cornersLo[1] = std::max(cornersLo[1], x2y1AtRef.x());
0153 cornersLo[2] = std::min(cornersLo[2], x1y1AtRef.y());
0154
0155 cornersHi[0] = std::min(cornersHi[0], x1y2AtRef.x());
0156 cornersHi[1] = std::max(cornersHi[1], x2y2AtRef.x());
0157 cornersHi[2] = std::max(cornersHi[2], x1y2AtRef.y());
0158
0159 cornersZ[0] = std::min(cornersZ[0], x1y1AtRef.z());
0160 cornersZ[1] = std::max(cornersZ[1], x1y1AtRef.z());
0161 }
0162 const LocalPoint lpOfCentre((cornersHi[0] + cornersHi[1]) / 2, (cornersLo[2] + cornersHi[2]) / 2, 0);
0163 const auto gpOfCentre = refSurf.toGlobal(lpOfCentre);
0164 auto bounds = new TrapezoidalPlaneBounds((cornersLo[1] - cornersLo[0]) / 2,
0165 (cornersHi[1] - cornersHi[0]) / 2,
0166 (cornersHi[2] - cornersLo[2]) / 2,
0167 (cornersZ[1] - cornersZ[0]) + 0.5);
0168 bp = new BoundPlane(gpOfCentre, refSurf.rotation(), bounds);
0169 }
0170 }
0171
0172 ReferenceCountingPointer<BoundPlane> surf(bp);
0173
0174 RPCChamber* ch = new RPCChamber(chid, surf);
0175
0176 for (auto rl : rls)
0177 ch->add(rl);
0178
0179 geometry->add(ch);
0180 }
0181 return geometry;
0182 }