Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-01-21 23:31:24

0001 /*
0002 //\class GEMGeometryBuilder
0003 
0004  Description: GEM Geometry builder from DD and DD4hep
0005               DD4hep part added to the original old file (DD version) made by M. Maggi (INFN Bari)
0006               Sergio Lo Meo (sergio.lo.meo@cern.ch) following what Ianna Osburne made for DTs (DD4hep migration)
0007               Updated by Sunanda Banerjee (Fermilab) to make it working for dd4hep
0008               Updated:  7 August 2020 
0009               Updated by Ian J. Watson (ian.james.watson@cern.ch) to allow GE2/1 demonstrator to be built
0010               Updated: 7 December 2021
0011 */
0012 #include "Geometry/GEMGeometryBuilder/src/GEMGeometryBuilder.h"
0013 #include "Geometry/GEMGeometry/interface/GEMGeometry.h"
0014 #include "Geometry/GEMGeometry/interface/GEMEtaPartitionSpecs.h"
0015 
0016 #include "DetectorDescription/Core/interface/DDFilter.h"
0017 #include "DetectorDescription/Core/interface/DDFilteredView.h"
0018 #include "DetectorDescription/Core/interface/DDSolid.h"
0019 #include "DetectorDescription/DDCMS/interface/DDFilteredView.h"
0020 #include "DetectorDescription/DDCMS/interface/DDCompactView.h"
0021 
0022 #include "Geometry/MuonNumbering/interface/MuonGeometryNumbering.h"
0023 #include "Geometry/MuonNumbering/interface/MuonBaseNumber.h"
0024 #include "Geometry/MuonNumbering/interface/MuonGeometryConstants.h"
0025 #include "Geometry/MuonNumbering/interface/GEMNumberingScheme.h"
0026 
0027 #include "DataFormats/GeometrySurface/interface/TrapezoidalPlaneBounds.h"
0028 #include "DataFormats/GeometryVector/interface/Basic3DVector.h"
0029 
0030 #include "DetectorDescription/DDCMS/interface/DDSpecParRegistry.h"
0031 
0032 #include "DataFormats/Math/interface/GeantUnits.h"
0033 
0034 #include <algorithm>
0035 #include <iostream>
0036 #include <string>
0037 
0038 using namespace geant_units::operators;
0039 
0040 //#define EDM_ML_DEBUG
0041 
0042 GEMGeometryBuilder::GEMGeometryBuilder() {}
0043 
0044 GEMGeometryBuilder::~GEMGeometryBuilder() {}
0045 
0046 // DDD
0047 void GEMGeometryBuilder::build(GEMGeometry& theGeometry,
0048                                const DDCompactView* cview,
0049                                const MuonGeometryConstants& muonConstants) {
0050   std::string attribute = "MuStructure";
0051   std::string value = "MuonEndCapGEM";
0052 
0053   // Asking only for the MuonGEM's
0054   DDSpecificsMatchesValueFilter filterGE2{DDValue(attribute, value, 0.0)};
0055   DDFilteredView fvGE2(*cview, filterGE2);
0056 
0057   MuonGeometryNumbering mdddnum(muonConstants);
0058   GEMNumberingScheme gemNum(muonConstants);
0059 
0060   // Check for the demonstrator geometry (only 1 chamber of GE2/1)
0061   int nGE21 = 0;
0062   bool doSuper = fvGE2.firstChild();
0063   while (doSuper) {
0064     // getting chamber id from eta partitions
0065     fvGE2.firstChild();
0066     fvGE2.firstChild();
0067     int rawidCh = gemNum.baseNumberToUnitNumber(mdddnum.geoHistoryToBaseNumber(fvGE2.geoHistory()));
0068     GEMDetId detIdCh = GEMDetId(rawidCh);
0069     if (detIdCh.station() == 2)
0070       nGE21++;
0071 
0072     // back to chambers
0073     fvGE2.parent();
0074     fvGE2.parent();
0075     doSuper = fvGE2.nextSibling();
0076   }
0077   bool demonstratorGeometry = nGE21 == 1;
0078 
0079 #ifdef EDM_ML_DEBUG
0080   edm::LogVerbatim("Geometry") << "Found " << nGE21 << " GE2/1 chambers. Demonstrator geometry on? "
0081                                << demonstratorGeometry;
0082 #endif
0083 
0084   // Asking only for the MuonGEM's
0085   DDSpecificsMatchesValueFilter filter{DDValue(attribute, value, 0.0)};
0086   DDFilteredView fv(*cview, filter);
0087 
0088 #ifdef EDM_ML_DEBUG
0089   edm::LogVerbatim("Geometry") << "Building the geometry service";
0090   edm::LogVerbatim("Geometry") << "About to run through the GEM structure\n"
0091                                << " First logical part " << fv.logicalPart().name().name();
0092 #endif
0093   doSuper = fv.firstChild();
0094 
0095 #ifdef EDM_ML_DEBUG
0096   edm::LogVerbatim("Geometry") << "doSuperChamber = " << doSuper << " with " << fv.geoHistory() << " Levels "
0097                                << mdddnum.geoHistoryToBaseNumber(fv.geoHistory()).getLevels();
0098   ;
0099 #endif
0100   // loop over superchambers
0101   std::vector<GEMSuperChamber*> superChambers;
0102   while (doSuper) {
0103     // getting chamber id from eta partitions
0104     fv.firstChild();
0105     fv.firstChild();
0106 
0107 #ifdef EDM_ML_DEBUG
0108     edm::LogVerbatim("Geometry") << "MuonGeometry 1 " << fv.geoHistory() << " Levels "
0109                                  << mdddnum.geoHistoryToBaseNumber(fv.geoHistory()).getLevels();
0110 #endif
0111     int rawidCh = gemNum.baseNumberToUnitNumber(mdddnum.geoHistoryToBaseNumber(fv.geoHistory()));
0112     GEMDetId detIdCh = GEMDetId(rawidCh);
0113 
0114     // back to chambers
0115 
0116     fv.parent();
0117     fv.parent();
0118 #ifdef EDM_ML_DEBUG
0119     edm::LogVerbatim("Geometry") << "MuonGeometry 2 " << fv.geoHistory() << " Levels "
0120                                  << mdddnum.geoHistoryToBaseNumber(fv.geoHistory()).getLevels();
0121     gemNum.baseNumberToUnitNumber(mdddnum.geoHistoryToBaseNumber(fv.geoHistory()));
0122 #endif
0123     // currently there is no superchamber in the geometry
0124     // only 2 chambers are present separated by a gap.
0125     // making superchamber out of the first chamber layer including the gap between chambers
0126 
0127     // In Run 3 we also have a GE2/1 station at layer 2. We make sure
0128     // the superchamber gets built but also we build on the first
0129     // layer for the other stations so the superchamber is in the
0130     // right position there.
0131     if ((detIdCh.layer() == 1) || (detIdCh.layer() == 2 and detIdCh.station() == 2 and demonstratorGeometry)) {
0132       GEMSuperChamber* gemSuperChamber = buildSuperChamber(fv, detIdCh);
0133       superChambers.push_back(gemSuperChamber);
0134     }
0135     GEMChamber* gemChamber = ((detIdCh.station() == GEMDetId::minStationId0) ? nullptr : buildChamber(fv, detIdCh));
0136 
0137     // loop over chambers
0138     // only 1 chamber
0139     bool doChambers = fv.firstChild();
0140     bool loopExecuted = false;
0141 
0142     while (doChambers) {
0143       loopExecuted = true;
0144 
0145       if (detIdCh.station() == GEMDetId::minStationId0) {
0146         fv.firstChild();
0147         int rawId = gemNum.baseNumberToUnitNumber(mdddnum.geoHistoryToBaseNumber(fv.geoHistory()));
0148         GEMDetId detId = GEMDetId(rawId);
0149         fv.parent();
0150 #ifdef EDM_ML_DEBUG
0151         edm::LogVerbatim("Geometry") << "MuonGeometry 3 " << fv.geoHistory() << " Levels "
0152                                      << mdddnum.geoHistoryToBaseNumber(fv.geoHistory()).getLevels();
0153         gemNum.baseNumberToUnitNumber(mdddnum.geoHistoryToBaseNumber(fv.geoHistory()));
0154 #endif
0155         gemChamber = buildChamber(fv, detId);
0156       }
0157 
0158       // loop over GEMEtaPartitions
0159       bool doEtaPart = fv.firstChild();
0160 
0161       while (doEtaPart) {
0162 #ifdef EDM_ML_DEBUG
0163         edm::LogVerbatim("Geometry") << "MuonGeometry 4 " << fv.geoHistory() << " Levels "
0164                                      << mdddnum.geoHistoryToBaseNumber(fv.geoHistory()).getLevels();
0165 #endif
0166         int rawid = gemNum.baseNumberToUnitNumber(mdddnum.geoHistoryToBaseNumber(fv.geoHistory()));
0167         GEMDetId detId = GEMDetId(rawid);
0168         GEMEtaPartition* etaPart = buildEtaPartition(fv, detId);
0169         gemChamber->add(etaPart);
0170         theGeometry.add(etaPart);
0171         doEtaPart = fv.nextSibling();
0172       }
0173 
0174       fv.parent();
0175 
0176       theGeometry.add(gemChamber);
0177 
0178       doChambers = fv.nextSibling();
0179     }
0180     fv.parent();
0181 
0182     doSuper = fv.nextSibling();
0183 
0184     if (!loopExecuted) {
0185       delete gemChamber;
0186     }
0187   }
0188 
0189   buildRegions(theGeometry, superChambers, demonstratorGeometry);
0190 }
0191 
0192 GEMSuperChamber* GEMGeometryBuilder::buildSuperChamber(DDFilteredView& fv, GEMDetId detId) const {
0193 #ifdef EDM_ML_DEBUG
0194   edm::LogVerbatim("Geometry") << "buildSuperChamber " << fv.logicalPart().name().name() << " " << detId;
0195 #endif
0196   DDBooleanSolid solid = (DDBooleanSolid)(fv.logicalPart().solid());
0197   bool ge0Station = detId.station() == GEMDetId::minStationId0;
0198   std::vector<double> dpar = ge0Station ? solid.parameters() : solid.solidA().parameters();
0199 
0200   double dy = convertMmToCm(dpar[0]);   //length is along local Y
0201   double dz = convertMmToCm(dpar[3]);   // thickness is long local Z
0202   double dx1 = convertMmToCm(dpar[4]);  // bottom width is along local X
0203   double dx2 = convertMmToCm(dpar[8]);  // top width is along local X
0204 
0205   if (!ge0Station) {
0206     const int nch = 2;
0207     const double chgap = 2.105;
0208 
0209     dpar = solid.solidB().parameters();
0210 
0211     dz += convertMmToCm(dpar[3]);  // chamber thickness
0212     dz *= nch;                     // 2 chambers in superchamber
0213     dz += chgap;                   // gap between chambers
0214   }
0215 
0216   bool isOdd = detId.chamber() % 2;
0217   RCPBoundPlane surf(boundPlane(fv, new TrapezoidalPlaneBounds(dx1, dx2, dy, dz), isOdd));
0218 
0219 #ifdef EDM_ML_DEBUG
0220   edm::LogVerbatim("Geometry") << "size " << dx1 << " " << dx2 << " " << dy << " " << dz;
0221 #endif
0222   GEMSuperChamber* superChamber = new GEMSuperChamber(detId.superChamberId(), surf);
0223   return superChamber;
0224 }
0225 
0226 GEMChamber* GEMGeometryBuilder::buildChamber(DDFilteredView& fv, GEMDetId detId) const {
0227 #ifdef EDM_ML_DEBUG
0228   edm::LogVerbatim("Geometry") << "buildChamber " << fv.logicalPart().name().name() << " " << detId;
0229 #endif
0230   DDBooleanSolid solid = (DDBooleanSolid)(fv.logicalPart().solid());
0231   bool ge0Station = detId.station() == GEMDetId::minStationId0;
0232   std::vector<double> dpar = ge0Station ? solid.parameters() : solid.solidA().parameters();
0233 
0234   double dy = convertMmToCm(dpar[0]);   //length is along local Y
0235   double dz = convertMmToCm(dpar[3]);   // thickness is long local Z
0236   double dx1 = convertMmToCm(dpar[4]);  // bottom width is along local X
0237   double dx2 = convertMmToCm(dpar[8]);  // top width is along local X
0238 
0239   if (!ge0Station) {
0240     dpar = solid.solidB().parameters();
0241     dz += convertMmToCm(dpar[3]);  // chamber thickness
0242   }
0243 
0244   bool isOdd = ge0Station ? false : detId.chamber() % 2;
0245 
0246   RCPBoundPlane surf(boundPlane(fv, new TrapezoidalPlaneBounds(dx1, dx2, dy, dz), isOdd));
0247 
0248 #ifdef EDM_ML_DEBUG
0249   edm::LogVerbatim("Geometry") << "size " << dx1 << " " << dx2 << " " << dy << " " << dz;
0250 #endif
0251   GEMChamber* chamber = new GEMChamber(detId.chamberId(), surf);
0252   return chamber;
0253 }
0254 
0255 GEMEtaPartition* GEMGeometryBuilder::buildEtaPartition(DDFilteredView& fv, GEMDetId detId) const {
0256 #ifdef EDM_ML_DEBUG
0257   edm::LogVerbatim("Geometry") << "buildEtaPartition " << fv.logicalPart().name().name() << " " << detId;
0258 #endif
0259   // EtaPartition specific parameter (nstrips and npads)
0260   DDValue numbOfStrips("nStrips");
0261   DDValue numbOfPads("nPads");
0262   DDValue delPhi("dPhi");
0263   std::vector<const DDsvalues_type*> specs(fv.specifics());
0264   std::vector<const DDsvalues_type*>::iterator is = specs.begin();
0265   double nStrips = 0., nPads = 0., dPhi = 0.;
0266   for (; is != specs.end(); is++) {
0267     if (DDfetch(*is, numbOfStrips))
0268       nStrips = numbOfStrips.doubles()[0];
0269     if (DDfetch(*is, numbOfPads))
0270       nPads = numbOfPads.doubles()[0];
0271     if (DDfetch(*is, delPhi))
0272       dPhi = delPhi.doubles()[0];
0273   }
0274 #ifdef EDM_ML_DEBUG
0275   edm::LogVerbatim("Geometry") << ((nStrips == 0.) ? ("No nStrips found!!")
0276                                                    : ("Number of strips: " + std::to_string(nStrips)));
0277   edm::LogVerbatim("Geometry") << ((nPads == 0.) ? ("No nPads found!!") : ("Number of pads: " + std::to_string(nPads)));
0278 #endif
0279   // EtaPartition specific parameter (size)
0280   std::vector<double> dpar = fv.logicalPart().solid().parameters();
0281 
0282   double be = convertMmToCm(dpar[4]);  // half bottom edge
0283   double te = convertMmToCm(dpar[8]);  // half top edge
0284   double ap = convertMmToCm(dpar[0]);  // half apothem
0285   double ti = 0.4;                     // half thickness
0286 
0287   std::vector<float> pars;
0288   pars.emplace_back(be);
0289   pars.emplace_back(te);
0290   pars.emplace_back(ap);
0291   pars.emplace_back(nStrips);
0292   pars.emplace_back(nPads);
0293   pars.emplace_back(dPhi);
0294 
0295   bool isOdd = detId.chamber() % 2;
0296   RCPBoundPlane surf(boundPlane(fv, new TrapezoidalPlaneBounds(be, te, ap, ti), isOdd));
0297   std::string name = fv.logicalPart().name().name();
0298   GEMEtaPartitionSpecs* e_p_specs = new GEMEtaPartitionSpecs(GeomDetEnumerators::GEM, name, pars);
0299 
0300 #ifdef EDM_ML_DEBUG
0301   edm::LogVerbatim("Geometry") << "size " << be << " " << te << " " << ap << " " << ti;
0302 #endif
0303   GEMEtaPartition* etaPartition = new GEMEtaPartition(detId, surf, e_p_specs);
0304   return etaPartition;
0305 }
0306 
0307 GEMGeometryBuilder::RCPBoundPlane GEMGeometryBuilder::boundPlane(const DDFilteredView& fv,
0308                                                                  Bounds* bounds,
0309                                                                  bool isOddChamber) const {
0310   // extract the position
0311   const DDTranslation& trans(fv.translation());
0312   const Surface::PositionType posResult(convertMmToCm(trans.x()), convertMmToCm(trans.y()), convertMmToCm(trans.z()));
0313 
0314   // now the rotation
0315   const DDRotationMatrix& rotation = fv.rotation();
0316   DD3Vector x, y, z;
0317   rotation.GetComponents(x, y, z);
0318 
0319   Surface::RotationType rotResult(float(x.X()),
0320                                   float(x.Y()),
0321                                   float(x.Z()),
0322                                   float(y.X()),
0323                                   float(y.Y()),
0324                                   float(y.Z()),
0325                                   float(z.X()),
0326                                   float(z.Y()),
0327                                   float(z.Z()));
0328 
0329   //Change of axes for the forward
0330   Basic3DVector<float> newX(1., 0., 0.);
0331   Basic3DVector<float> newY(0., 0., -1.);
0332   Basic3DVector<float> newZ(0., 1., 0.);
0333 
0334   rotResult.rotateAxes(newX, newY, newZ);
0335 
0336   return RCPBoundPlane(new BoundPlane(posResult, rotResult, bounds));
0337 }
0338 
0339 // DD4hep
0340 
0341 void GEMGeometryBuilder::build(GEMGeometry& theGeometry,
0342                                const cms::DDCompactView* cview,
0343                                const MuonGeometryConstants& muonConstants) {
0344   std::string attribute = "MuStructure";
0345   std::string value = "MuonEndCapGEM";
0346   const cms::DDFilter filterGE2(attribute, value);
0347   cms::DDFilteredView fvGE2(*cview, filterGE2);
0348 
0349   MuonGeometryNumbering mdddnum(muonConstants);
0350   GEMNumberingScheme gemNum(muonConstants);
0351   static constexpr uint32_t levelChamb = 7;
0352   int chamb(0), region(0);
0353   int theLevelPart = muonConstants.getValue("level");
0354   int theRingLevel = muonConstants.getValue("mg_ring") / theLevelPart;
0355   int theSectorLevel = muonConstants.getValue("mg_sector") / theLevelPart;
0356 
0357   // Check for the demonstrator geometry (only 1 chamber of GE2/1)
0358   int nGE21 = 0;
0359   while (fvGE2.firstChild()) {
0360     const auto& history = fvGE2.history();
0361     MuonBaseNumber num(mdddnum.geoHistoryToBaseNumber(history));
0362     GEMDetId detId(gemNum.baseNumberToUnitNumber(num));
0363     if (detId.station() == GEMDetId::minStationId0) {
0364     } else {
0365       if (fvGE2.level() == levelChamb) {
0366         if (detId.station() == 2)
0367           nGE21++;
0368       }
0369     }
0370   }
0371 
0372   bool demonstratorGeometry = nGE21 == 1;
0373 #ifdef EDM_ML_DEBUG
0374   edm::LogVerbatim("Geometry") << "Found " << nGE21 << " GE2/1 chambers. Demonstrator geometry on? "
0375                                << demonstratorGeometry;
0376 #endif
0377 
0378   const cms::DDFilter filter(attribute, value);
0379   cms::DDFilteredView fv(*cview, filter);
0380   std::vector<GEMSuperChamber*> superChambers;
0381   std::vector<GEMChamber*> chambers;
0382 
0383   while (fv.firstChild()) {
0384     const auto& history = fv.history();
0385     MuonBaseNumber num(mdddnum.geoHistoryToBaseNumber(history));
0386     GEMDetId detId(gemNum.baseNumberToUnitNumber(num));
0387 #ifdef EDM_ML_DEBUG
0388     edm::LogVerbatim("Geometry") << fv.name() << " with " << history.tags.size() << " Levels and ID " << detId
0389                                  << " Mask " << std::hex << GEMDetId::chamberIdMask << std::dec << " and "
0390                                  << GEMDetId(((detId.rawId()) & GEMDetId::chamberIdMask)) << " Levels " << theRingLevel
0391                                  << ":" << theSectorLevel << ":" << history.tags.size() << ":" << fv.level();
0392     for (unsigned int k = 0; k < history.tags.size(); ++k)
0393       edm::LogVerbatim("Geometry") << "[" << k << "] Tag " << history.tags[k] << " Offset " << history.offsets[k]
0394                                    << " copy " << history.copyNos[k];
0395 #endif
0396 
0397     if (detId.station() == GEMDetId::minStationId0) {
0398       if (num.getLevels() == theRingLevel) {
0399         if (detId.region() != region) {
0400           region = detId.region();
0401           chamb = 0;
0402         }
0403         ++chamb;
0404         detId = GEMDetId(detId.region(), detId.ring(), detId.station(), detId.layer(), chamb, 0);
0405         GEMSuperChamber* gemSuperChamber = buildSuperChamber(fv, detId);
0406         superChambers.emplace_back(gemSuperChamber);
0407       } else if (num.getLevels() == theSectorLevel) {
0408         GEMChamber* gemChamber = buildChamber(fv, detId);
0409         chambers.emplace_back(gemChamber);
0410       } else {
0411         GEMEtaPartition* etaPart = buildEtaPartition(fv, detId);
0412         theGeometry.add(etaPart);
0413       }
0414     } else {
0415       if (fv.level() == levelChamb) {
0416         if ((detId.layer() == 1) || (detId.layer() == 2 and detId.station() == 2 and demonstratorGeometry)) {
0417           GEMSuperChamber* gemSuperChamber = buildSuperChamber(fv, detId);
0418           superChambers.emplace_back(gemSuperChamber);
0419         }
0420         GEMChamber* gemChamber = buildChamber(fv, detId);
0421         chambers.emplace_back(gemChamber);
0422       } else if (num.getLevels() > theSectorLevel) {
0423         GEMEtaPartition* etaPart = buildEtaPartition(fv, detId);
0424         theGeometry.add(etaPart);
0425       }
0426     }
0427   }
0428 
0429   auto& partitions = theGeometry.etaPartitions();
0430   for (auto& gemChamber : chambers) {
0431     uint32_t id0 = ((gemChamber->id().rawId()) & GEMDetId::chamberIdMask);
0432     for (auto& etaPart : partitions) {
0433       if (((etaPart->id().rawId()) & GEMDetId::chamberIdMask) == id0) {
0434         gemChamber->add(etaPart);
0435       }
0436     }
0437     theGeometry.add(gemChamber);
0438   }
0439 
0440   buildRegions(theGeometry, superChambers, demonstratorGeometry);
0441 }
0442 
0443 GEMSuperChamber* GEMGeometryBuilder::buildSuperChamber(cms::DDFilteredView& fv, GEMDetId detId) const {
0444   cms::DDSolid solid(fv.solid());
0445   auto solidA = solid.solidA();
0446   std::vector<double> dpar = solidA.dimensions();
0447 
0448   double dy = k_ScaleFromDD4hep * dpar[3];   //length is along local Y
0449   double dz = k_ScaleFromDD4hep * dpar[2];   // thickness is long local Z
0450   double dx1 = k_ScaleFromDD4hep * dpar[0];  // bottom width is along local X
0451   double dx2 = k_ScaleFromDD4hep * dpar[1];  // top width is along loc
0452 
0453   auto solidB = solid.solidB();
0454   dpar = solidB.dimensions();
0455   const int nch = 2;
0456   const double chgap = 2.105;
0457 
0458   dz += (k_ScaleFromDD4hep * dpar[2]);  // chamber thickness
0459   dz *= nch;                            // 2 chambers in superchamber
0460   dz += chgap;                          // gap between chambers
0461 
0462   bool isOdd = detId.chamber() % 2;
0463   RCPBoundPlane surf(boundPlane(fv, new TrapezoidalPlaneBounds(dx1, dx2, dy, dz), isOdd));
0464 
0465   GEMSuperChamber* superChamber = new GEMSuperChamber(detId.superChamberId(), surf);
0466   return superChamber;
0467 }
0468 
0469 GEMChamber* GEMGeometryBuilder::buildChamber(cms::DDFilteredView& fv, GEMDetId detId) const {
0470   cms::DDSolid solid(fv.solid());
0471   auto solidA = solid.solidA();
0472   std::vector<double> dpar = solidA.dimensions();
0473 
0474   double dy = k_ScaleFromDD4hep * dpar[3];   //length is along local Y
0475   double dz = k_ScaleFromDD4hep * dpar[2];   // thickness is long local Z
0476   double dx1 = k_ScaleFromDD4hep * dpar[0];  // bottom width is along local X
0477   double dx2 = k_ScaleFromDD4hep * dpar[1];  // top width is along local X
0478 
0479   auto solidB = solid.solidB();
0480   dpar = solidB.dimensions();
0481 
0482   dz += (k_ScaleFromDD4hep * dpar[2]);  // chamber thickness
0483 
0484   bool isOdd = detId.chamber() % 2;
0485   RCPBoundPlane surf(boundPlane(fv, new TrapezoidalPlaneBounds(dx1, dx2, dy, dz), isOdd));
0486 
0487   GEMChamber* chamber = new GEMChamber(detId.chamberId(), surf);
0488   return chamber;
0489 }
0490 
0491 GEMEtaPartition* GEMGeometryBuilder::buildEtaPartition(cms::DDFilteredView& fv, GEMDetId detId) const {
0492   // EtaPartition specific parameter (nstrips and npads)
0493 
0494   auto nStrips = fv.get<double>("nStrips");
0495   auto nPads = fv.get<double>("nPads");
0496   auto dPhi = fv.get<double>("dPhi");
0497   // EtaPartition specific parameter (size)
0498 
0499   std::vector<double> dpar = fv.parameters();
0500 
0501   double ti = 0.4;  // half thickness
0502 
0503   const std::vector<float> pars{float(k_ScaleFromDD4hep * dpar[0]),
0504                                 float(k_ScaleFromDD4hep * dpar[1]),
0505                                 float(k_ScaleFromDD4hep * dpar[3]),
0506                                 float(nStrips),
0507                                 float(nPads),
0508                                 float(dPhi)};
0509 
0510   bool isOdd = detId.chamber() % 2;
0511   RCPBoundPlane surf(
0512       boundPlane(fv,
0513                  new TrapezoidalPlaneBounds(
0514                      k_ScaleFromDD4hep * dpar[0], k_ScaleFromDD4hep * dpar[1], k_ScaleFromDD4hep * dpar[3], ti),
0515                  isOdd));
0516 
0517   std::string_view name = fv.name();
0518 
0519   GEMEtaPartitionSpecs* e_p_specs = new GEMEtaPartitionSpecs(GeomDetEnumerators::GEM, std::string(name), pars);
0520 
0521   GEMEtaPartition* etaPartition = new GEMEtaPartition(detId, surf, e_p_specs);
0522   return etaPartition;
0523 }
0524 
0525 GEMGeometryBuilder::RCPBoundPlane GEMGeometryBuilder::boundPlane(const cms::DDFilteredView& fv,
0526                                                                  Bounds* bounds,
0527                                                                  bool isOddChamber) const {
0528   // extract the position
0529   const Double_t* tran = fv.trans();
0530   Surface::PositionType posResult(
0531       k_ScaleFromDD4hep * tran[0], k_ScaleFromDD4hep * tran[1], k_ScaleFromDD4hep * tran[2]);
0532 
0533   // now the rotation
0534   DDRotationMatrix rota;
0535   fv.rot(rota);
0536   DD3Vector x, y, z;
0537   rota.GetComponents(x, y, z);
0538   Surface::RotationType rotResult(float(x.X()),
0539                                   float(x.Y()),
0540                                   float(x.Z()),
0541                                   float(y.X()),
0542                                   float(y.Y()),
0543                                   float(y.Z()),
0544                                   float(z.X()),
0545                                   float(z.Y()),
0546                                   float(z.Z()));
0547 
0548   //Change of axes for the forward
0549   Basic3DVector<float> newX(1., 0., 0.);
0550   Basic3DVector<float> newY(0., 0., -1.);
0551   Basic3DVector<float> newZ(0., 1., 0.);
0552 
0553   rotResult.rotateAxes(newX, newY, newZ);
0554 
0555   return RCPBoundPlane(new BoundPlane(posResult, rotResult, bounds));
0556 }
0557 
0558 void GEMGeometryBuilder::buildRegions(GEMGeometry& theGeometry,
0559                                       const std::vector<GEMSuperChamber*>& superChambers,
0560                                       bool demonstratorGeometry) {
0561   // construct the regions, stations and rings.
0562   for (int re = -1; re <= 1; re = re + 2) {
0563     GEMRegion* region = new GEMRegion(re);
0564     for (int st = GEMDetId::minStationId0; st <= GEMDetId::maxStationId; ++st) {
0565       bool ge0Station = st == GEMDetId::minStationId0;
0566       GEMStation* station = new GEMStation(re, st);
0567       std::string sign(re == -1 ? "-" : "");
0568       std::string suffix = ge0Station ? "" : "/1";
0569       std::string name = "GE" + sign + std::to_string(st) + suffix;
0570       station->setName(name);
0571       bool foundSuperChamber = false;
0572       for (int ri = 1; ri <= 1; ++ri) {
0573         GEMRing* ring = new GEMRing(re, st, ri);
0574         for (auto superChamber : superChambers) {
0575           const GEMDetId detId(superChamber->id());
0576           if (detId.region() != re || detId.station() != st || detId.ring() != ri)
0577             continue;
0578 
0579           foundSuperChamber = true;
0580           int nlayers = ge0Station ? GEMDetId::maxLayerId0 : GEMDetId::maxLayerId;
0581 
0582           // GEMDetId::minLayerId is to id the superchamber, so minLayerId+1 is the first layer
0583           for (int la = GEMDetId::minLayerId + 1; la <= nlayers; ++la) {
0584             GEMDetId chId(detId.region(), detId.ring(), detId.station(), la, detId.chamber(), 0);
0585             auto chamber = theGeometry.chamber(chId);
0586             if (!chamber) {
0587               // this particular layer 1 chamber *should* be missing in the demonstrator geometry (we only have layer 2)
0588               if (!demonstratorGeometry or
0589                   not(chId.region() == 1 and chId.station() == 2 and chId.chamber() == 16 and chId.layer() == 1)) {
0590                 edm::LogWarning("GEMGeometryBuilder") << "Missing chamber " << chId;
0591               }
0592             } else {
0593               superChamber->add(chamber);
0594             }
0595           }
0596           ring->add(superChamber);
0597           theGeometry.add(superChamber);
0598 #ifdef EDM_ML_DEBUG
0599           edm::LogVerbatim("Geometry") << "Adding super chamber " << detId << " to ring: "
0600                                        << "re " << re << " st " << st << " ri " << ri;
0601 #endif
0602         }
0603 #ifdef EDM_ML_DEBUG
0604         edm::LogVerbatim("Geometry") << "Adding ring " << ri << " to station "
0605                                      << "re " << re << " st " << st;
0606 #endif
0607         if (foundSuperChamber) {
0608           station->add(ring);
0609           theGeometry.add(ring);
0610         }
0611       }
0612       if (!foundSuperChamber) {
0613 #ifdef EDM_ML_DEBUG
0614         edm::LogVerbatim("Geometry") << "No superchamber found: re:" << re << " st:" << st;
0615 #endif
0616         delete station;
0617       } else {
0618 #ifdef EDM_ML_DEBUG
0619         edm::LogVerbatim("Geometry") << "Adding station " << st << " to region " << re;
0620 #endif
0621         region->add(station);
0622         theGeometry.add(station);
0623       }
0624     }
0625 #ifdef EDM_ML_DEBUG
0626     edm::LogVerbatim("Geometry") << "Adding region " << re << " to the geometry ";
0627 #endif
0628     theGeometry.add(region);
0629   }
0630 }