Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:49:01

0001 /** Implementation of the RPC Geometry Builder from DDD stored in CondDB
0002  *
0003  *  \author M. Maggi - INFN Bari
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/GlobalSystemOfUnits.h"
0024 
0025 #include <iostream>
0026 #include <algorithm>
0027 
0028 RPCGeometryBuilderFromCondDB::RPCGeometryBuilderFromCondDB() {}
0029 
0030 RPCGeometryBuilderFromCondDB::~RPCGeometryBuilderFromCondDB() {}
0031 
0032 RPCGeometry* RPCGeometryBuilderFromCondDB::build(const RecoIdealGeometry& rgeo) {
0033   const std::vector<DetId>& detids(rgeo.detIds());
0034   RPCGeometry* geometry = new RPCGeometry();
0035 
0036   for (unsigned int id = 0; id < detids.size(); ++id) {
0037     RPCDetId rpcid(detids[id]);
0038     RPCDetId chid(rpcid.region(), rpcid.ring(), rpcid.station(), rpcid.sector(), rpcid.layer(), rpcid.subsector(), 0);
0039 
0040     const auto tranStart = rgeo.tranStart(id);
0041     const auto shapeStart = rgeo.shapeStart(id);
0042     const auto rotStart = rgeo.rotStart(id);
0043     const std::string& name = *rgeo.strStart(id);
0044 
0045     Surface::PositionType pos(*(tranStart) / cm, *(tranStart + 1) / cm, *(tranStart + 2) / cm);
0046     // CLHEP way
0047     Surface::RotationType rot(*(rotStart + 0),
0048                               *(rotStart + 1),
0049                               *(rotStart + 2),
0050                               *(rotStart + 3),
0051                               *(rotStart + 4),
0052                               *(rotStart + 5),
0053                               *(rotStart + 6),
0054                               *(rotStart + 7),
0055                               *(rotStart + 8));
0056 
0057     RPCRollSpecs* rollspecs = nullptr;
0058     Bounds* bounds = nullptr;
0059 
0060     if (rgeo.shapeEnd(id) - shapeStart == 4) {
0061       const float width = *(shapeStart + 0) / cm;
0062       const float length = *(shapeStart + 1) / cm;
0063       const float thickness = *(shapeStart + 2) / cm;
0064       const float nstrip = *(shapeStart + 3);
0065 
0066       bounds = new RectangularPlaneBounds(width, length, thickness);
0067       const std::vector<float> pars = {width, length, nstrip};
0068 
0069       rollspecs = new RPCRollSpecs(GeomDetEnumerators::RPCBarrel, name, pars);
0070 
0071     } else {
0072       const float be = *(shapeStart + 0) / cm;
0073       const float te = *(shapeStart + 1) / cm;
0074       const float ap = *(shapeStart + 2) / cm;
0075       const float ti = *(shapeStart + 3) / cm;
0076       const float nstrip = *(shapeStart + 4);
0077 
0078       bounds = new TrapezoidalPlaneBounds(be, te, ap, ti);
0079       const std::vector<float> pars = {be, te, ap, nstrip};
0080 
0081       rollspecs = new RPCRollSpecs(GeomDetEnumerators::RPCEndcap, name, pars);
0082 
0083       //Change of axes for the forward
0084       Basic3DVector<float> newX(1., 0., 0.);
0085       Basic3DVector<float> newY(0., 0., 1.);
0086 
0087       newY *= -1;
0088       Basic3DVector<float> newZ(0., 1., 0.);
0089       rot.rotateAxes(newX, newY, newZ);
0090     }
0091 
0092     BoundPlane* bp = new BoundPlane(pos, rot, bounds);
0093     ReferenceCountingPointer<BoundPlane> surf(bp);
0094     RPCRoll* r = new RPCRoll(rpcid, surf, rollspecs);
0095     geometry->add(r);
0096 
0097     auto rls = chids.find(chid);
0098     if (rls == chids.end())
0099       rls = chids.insert(std::make_pair(chid, std::list<RPCRoll*>())).first;
0100     rls->second.emplace_back(r);
0101   }
0102 
0103   // Create the RPCChambers and store them on the Geometry
0104   for (auto& ich : chids) {
0105     const RPCDetId& chid = ich.first;
0106     const auto& rls = ich.second;
0107 
0108     // compute the overall boundplane.
0109     BoundPlane* bp = nullptr;
0110     if (!rls.empty()) {
0111       // First set the baseline plane to calculate relative poisions
0112       const auto& refSurf = (*rls.begin())->surface();
0113       if (chid.region() == 0) {
0114         float corners[6] = {0, 0, 0, 0, 0, 0};
0115         for (auto rl : rls) {
0116           const double h2 = rl->surface().bounds().length() / 2;
0117           const double w2 = rl->surface().bounds().width() / 2;
0118           const auto x1y1AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(-w2, -h2, 0)));
0119           const auto x2y2AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(+w2, +h2, 0)));
0120           corners[0] = std::min(corners[0], x1y1AtRef.x());
0121           corners[1] = std::min(corners[1], x1y1AtRef.y());
0122           corners[2] = std::max(corners[2], x2y2AtRef.x());
0123           corners[3] = std::max(corners[3], x2y2AtRef.y());
0124 
0125           corners[4] = std::min(corners[4], x1y1AtRef.z());
0126           corners[5] = std::max(corners[5], x1y1AtRef.z());
0127         }
0128         const LocalPoint lpOfCentre((corners[0] + corners[2]) / 2, (corners[1] + corners[3]) / 2, 0);
0129         const auto gpOfCentre = refSurf.toGlobal(lpOfCentre);
0130         auto bounds = new RectangularPlaneBounds(
0131             (corners[2] - corners[0]) / 2, (corners[3] - corners[1]) / 2, (corners[5] - corners[4]) + 0.5);
0132         bp = new BoundPlane(gpOfCentre, refSurf.rotation(), bounds);
0133       } else {
0134         float cornersLo[3] = {0, 0, 0}, cornersHi[3] = {0, 0, 0};
0135         float cornersZ[2] = {0, 0};
0136         for (auto rl : rls) {
0137           const double h2 = rl->surface().bounds().length() / 2;
0138           const double w2 = rl->surface().bounds().width() / 2;
0139           const auto& topo = dynamic_cast<const TrapezoidalStripTopology&>(rl->specificTopology());
0140           const double r = topo.radius();
0141           const double wAtLo = w2 / r * (r - h2);
0142           const double wAtHi = w2 / r * (r + h2);
0143 
0144           const auto x1y1AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(-wAtLo, -h2, 0)));
0145           const auto x2y1AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(+wAtLo, -h2, 0)));
0146           const auto x1y2AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(-wAtHi, +h2, 0)));
0147           const auto x2y2AtRef = refSurf.toLocal(rl->toGlobal(LocalPoint(+wAtHi, +h2, 0)));
0148 
0149           cornersLo[0] = std::min(cornersLo[0], x1y1AtRef.x());
0150           cornersLo[1] = std::max(cornersLo[1], x2y1AtRef.x());
0151           cornersLo[2] = std::min(cornersLo[2], x1y1AtRef.y());
0152 
0153           cornersHi[0] = std::min(cornersHi[0], x1y2AtRef.x());
0154           cornersHi[1] = std::max(cornersHi[1], x2y2AtRef.x());
0155           cornersHi[2] = std::max(cornersHi[2], x1y2AtRef.y());
0156 
0157           cornersZ[0] = std::min(cornersZ[0], x1y1AtRef.z());
0158           cornersZ[1] = std::max(cornersZ[1], x1y1AtRef.z());
0159         }
0160         const LocalPoint lpOfCentre((cornersHi[0] + cornersHi[1]) / 2, (cornersLo[2] + cornersHi[2]) / 2, 0);
0161         const auto gpOfCentre = refSurf.toGlobal(lpOfCentre);
0162         auto bounds = new TrapezoidalPlaneBounds((cornersLo[1] - cornersLo[0]) / 2,
0163                                                  (cornersHi[1] - cornersHi[0]) / 2,
0164                                                  (cornersHi[2] - cornersLo[2]) / 2,
0165                                                  (cornersZ[1] - cornersZ[0]) + 0.5);
0166         bp = new BoundPlane(gpOfCentre, refSurf.rotation(), bounds);
0167       }
0168     }
0169 
0170     ReferenceCountingPointer<BoundPlane> surf(bp);
0171     // Create the chamber
0172     RPCChamber* ch = new RPCChamber(chid, surf);
0173     // Add the rolls to rhe chamber
0174     for (auto rl : rls)
0175       ch->add(rl);
0176     // Add the chamber to the geometry
0177     geometry->add(ch);
0178   }
0179   return geometry;
0180 }