Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-11-09 23:31:55

0001 /*
0002 // \class CSCGeometryParsFromDDD
0003 //
0004 //  Description: CSC Geometry Pars for DD4hep
0005 //              
0006 //
0007 // \author Sergio Lo Meo (sergio.lo.meo@cern.ch) following what Ianna Osburne made for DTs (DD4hep migration)
0008 //         Created:  Thu, 05 March 2020 
0009 //         Modified: Thu, 04 June 2020, following what made in PR #30047               
0010 //         Modified: Wed, 23 December 2020 
0011 //         Original author: Tim Cox
0012 */
0013 #include "Geometry/CSCGeometryBuilder/interface/CSCGeometryParsFromDD.h"
0014 #include "DetectorDescription/Core/interface/DDFilteredView.h"
0015 #include "DetectorDescription/Core/interface/DDSolid.h"
0016 #include "Geometry/CSCGeometry/interface/CSCChamberSpecs.h"
0017 #include "Geometry/MuonNumbering/interface/CSCNumberingScheme.h"
0018 #include "Geometry/MuonNumbering/interface/MuonBaseNumber.h"
0019 #include "Geometry/MuonNumbering/interface/MuonGeometryNumbering.h"
0020 #include "Geometry/MuonNumbering/interface/MuonGeometryConstants.h"
0021 #include "Geometry/CSCGeometry/interface/CSCWireGroupPackage.h"
0022 #include "CondFormats/GeometryObjects/interface/CSCRecoDigiParameters.h"
0023 #include "CondFormats/GeometryObjects/interface/RecoIdealGeometry.h"
0024 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0025 #include "DetectorDescription/DDCMS/interface/DDFilteredView.h"
0026 #include "DetectorDescription/DDCMS/interface/DDCompactView.h"
0027 #include "DataFormats/Math/interface/CMSUnits.h"
0028 #include "DataFormats/Math/interface/GeantUnits.h"
0029 #include "DataFormats/Math/interface/Rounding.h"
0030 
0031 using namespace std;
0032 using namespace cms_units::operators;
0033 using namespace geant_units::operators;
0034 
0035 CSCGeometryParsFromDD::CSCGeometryParsFromDD() : myName("CSCGeometryParsFromDD") {}
0036 
0037 CSCGeometryParsFromDD::~CSCGeometryParsFromDD() {}
0038 
0039 //ddd
0040 
0041 bool CSCGeometryParsFromDD::build(const DDCompactView* cview,
0042                                   const MuonGeometryConstants& muonConstants,
0043                                   RecoIdealGeometry& rig,
0044                                   CSCRecoDigiParameters& rdp) {
0045   std::string attribute = "MuStructure";  // could come from outside
0046   std::string value = "MuonEndcapCSC";    // could come from outside
0047 
0048   // Asking for a specific section of the MuStructure
0049 
0050   DDSpecificsMatchesValueFilter filter{DDValue(attribute, value, 0.0)};
0051 
0052   DDFilteredView fv(*cview, filter);
0053 
0054   bool doSubDets = fv.firstChild();
0055 
0056   if (!doSubDets) {
0057     edm::LogError("CSCGeometryParsFromDD")
0058         << "Can not proceed, no CSC parts found with the filter.  The current node is: " << fv.logicalPart().toString();
0059     return false;
0060   }
0061   int noOfAnonParams = 0;
0062   std::vector<const DDsvalues_type*> spec = fv.specifics();
0063   std::vector<const DDsvalues_type*>::const_iterator spit = spec.begin();
0064   std::vector<double> uparvals;
0065   std::vector<double> fpar;
0066   std::vector<double> dpar;
0067   std::vector<double> gtran(3);
0068   std::vector<double> grmat(9);
0069   std::vector<double> trm(9);
0070 
0071   edm::LogVerbatim("CSCGeometryParsFromDD") << "(0) CSCGeometryParsFromDD - DDD ";
0072 
0073   while (doSubDets) {
0074     spec = fv.specifics();
0075     spit = spec.begin();
0076 
0077     // get numbering information early for possible speed up of code.
0078 
0079     LogTrace(myName) << myName << ": create numbering scheme...";
0080 
0081     MuonGeometryNumbering mdn(muonConstants);
0082     MuonBaseNumber mbn = mdn.geoHistoryToBaseNumber(fv.geoHistory());
0083     CSCNumberingScheme mens(muonConstants);
0084 
0085     LogTrace(myName) << myName << ": find detid...";
0086 
0087     int id = mens.baseNumberToUnitNumber(mbn);  //@@ FIXME perhaps should return CSCDetId itself?
0088 
0089     LogTrace(myName) << myName << ": raw id for this detector is " << id << ", octal " << std::oct << id << ", hex "
0090                      << std::hex << id << std::dec;
0091 
0092     CSCDetId detid = CSCDetId(id);
0093     int jendcap = detid.endcap();
0094     int jstation = detid.station();
0095     int jring = detid.ring();
0096     int jchamber = detid.chamber();
0097     int jlayer = detid.layer();
0098 
0099     edm::LogVerbatim("CSCGeometryParsFromDD")
0100         << "(1) detId: " << id << " jendcap: " << jendcap << " jstation: " << jstation << " jring: " << jring
0101         << " jchamber: " << jchamber << " jlayer: " << jlayer;
0102 
0103     // Package up the wire group info as it's decoded
0104     CSCWireGroupPackage wg;
0105     uparvals.clear();
0106     LogDebug(myName) << "size of spec=" << spec.size();
0107 
0108     // if the specs are made no need to get all this stuff!
0109     int chamberType = CSCChamberSpecs::whatChamberType(jstation, jring);
0110 
0111     LogDebug(myName) << "Chamber Type: " << chamberType;
0112     size_t ct = 0;
0113     bool chSpecsAlreadyExist = false;
0114     for (; ct < rdp.pChamberType.size(); ++ct) {
0115       if (chamberType == rdp.pChamberType[ct]) {
0116         break;
0117       }
0118     }
0119     if (ct < rdp.pChamberType.size() && rdp.pChamberType[ct] == chamberType) {
0120       // it was found, therefore no need to load all the intermediate stuff from DD.
0121       LogDebug(myName) << "already found a " << chamberType << " at index " << ct;
0122 
0123       chSpecsAlreadyExist = true;
0124     } else {
0125       for (; spit != spec.end(); spit++) {
0126         DDsvalues_type::const_iterator it = (**spit).begin();
0127         for (; it != (**spit).end(); it++) {
0128           LogDebug(myName) << "it->second.name()=" << it->second.name();
0129           if (it->second.name() == "upar") {
0130             uparvals.emplace_back(it->second.doubles().size());
0131             for (double i : it->second.doubles()) {
0132               uparvals.emplace_back(i);
0133             }
0134 
0135             LogDebug(myName) << "found upars ";
0136           } else if (it->second.name() == "NoOfAnonParams") {
0137             noOfAnonParams = static_cast<int>(it->second.doubles()[0]);
0138           } else if (it->second.name() == "NumWiresPerGrp") {
0139             for (double i : it->second.doubles()) {
0140               wg.wiresInEachGroup.emplace_back(int(i));
0141             }
0142             LogDebug(myName) << "found upars " << std::endl;
0143           } else if (it->second.name() == "NumGroups") {
0144             for (double i : it->second.doubles()) {
0145               wg.consecutiveGroups.emplace_back(int(i));
0146             }
0147           } else if (it->second.name() == "WireSpacing") {
0148             wg.wireSpacing = it->second.doubles()[0];
0149             edm::LogVerbatim("CSCGeometryParsFromDD") << "(2) wireSpacing: " << wg.wireSpacing;
0150           } else if (it->second.name() == "AlignmentPinToFirstWire") {
0151             wg.alignmentPinToFirstWire = it->second.doubles()[0];
0152             edm::LogVerbatim("CSCGeometryParsFromDD") << "(3) alignmentPinToFirstWire: " << wg.alignmentPinToFirstWire;
0153           } else if (it->second.name() == "TotNumWireGroups") {
0154             wg.numberOfGroups = int(it->second.doubles()[0]);
0155           } else if (it->second.name() == "LengthOfFirstWire") {
0156             wg.narrowWidthOfWirePlane = it->second.doubles()[0];
0157             edm::LogVerbatim("CSCGeometryParsFromDD") << "(4) narrowWidthOfWirePlane: " << wg.narrowWidthOfWirePlane;
0158           } else if (it->second.name() == "LengthOfLastWire") {
0159             wg.wideWidthOfWirePlane = it->second.doubles()[0];
0160             edm::LogVerbatim("CSCGeometryParsFromDD") << "(5) wideWidthOfWirePlane: " << wg.wideWidthOfWirePlane;
0161           } else if (it->second.name() == "RadialExtentOfWirePlane") {
0162             wg.lengthOfWirePlane = it->second.doubles()[0];
0163             edm::LogVerbatim("CSCGeometryParsFromDD") << "(6) lengthOfWirePlane: " << wg.lengthOfWirePlane;
0164           }
0165         }
0166       }
0167 
0168       /** stuff: using a constructed wg to deconstruct it and put it in db... alternative?
0169       use temporary (not wg!) storage.
0170       
0171       format as inserted is best documented by the actualy emplace_back statements below.
0172       
0173       fupar size now becomes origSize+6+wg.wiresInEachGroup.size()+wg.consecutiveGroups.size()
0174       **/
0175       uparvals.emplace_back(wg.wireSpacing);
0176 
0177       uparvals.emplace_back(wg.alignmentPinToFirstWire);
0178       uparvals.emplace_back(wg.numberOfGroups);
0179       uparvals.emplace_back(wg.narrowWidthOfWirePlane);
0180       uparvals.emplace_back(wg.wideWidthOfWirePlane);
0181       uparvals.emplace_back(wg.lengthOfWirePlane);
0182       uparvals.emplace_back(wg.wiresInEachGroup.size());
0183       for (CSCWireGroupPackage::Container::const_iterator it = wg.wiresInEachGroup.begin();
0184            it != wg.wiresInEachGroup.end();
0185            ++it) {
0186         uparvals.emplace_back(*it);
0187       }
0188       for (CSCWireGroupPackage::Container::const_iterator it = wg.consecutiveGroups.begin();
0189            it != wg.consecutiveGroups.end();
0190            ++it) {
0191         uparvals.emplace_back(*it);
0192       }
0193 
0194       /** end stuff **/
0195     }
0196 
0197     fpar.clear();
0198 
0199     if (fv.logicalPart().solid().shape() == DDSolidShape::ddsubtraction) {
0200       const DDSubtraction& first = fv.logicalPart().solid();
0201       const DDSubtraction& second = first.solidA();
0202       const DDSolid& third = second.solidA();
0203       dpar = third.parameters();
0204       std::transform(
0205           dpar.begin(), dpar.end(), dpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0206 
0207     } else {
0208       dpar = fv.logicalPart().solid().parameters();
0209       std::transform(
0210           dpar.begin(), dpar.end(), dpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0211     }
0212 
0213     LogTrace(myName) << myName << ": noOfAnonParams=" << noOfAnonParams;
0214     LogTrace(myName) << myName << ": fill fpar...";
0215     LogTrace(myName) << myName << ": dpars are... " << convertMmToCm(dpar[4]) << ", " << convertMmToCm(dpar[8]) << ", "
0216                      << convertMmToCm(dpar[3]) << ", " << convertMmToCm(dpar[0]);
0217     edm::LogVerbatim("CSCGeometryParsFromDD")
0218         << "(7) dpar[4]: " << convertMmToCm(dpar[4]) << " dpar[8]:  " << convertMmToCm(dpar[8])
0219         << " dpar[3]: " << convertMmToCm(dpar[3]) << " dpar[0]: " << convertMmToCm(dpar[0]);
0220 
0221     fpar.emplace_back(convertMmToCm(dpar[4]));
0222     fpar.emplace_back(convertMmToCm(dpar[8]));
0223     fpar.emplace_back(convertMmToCm(dpar[3]));
0224     fpar.emplace_back(convertMmToCm(dpar[0]));
0225 
0226     LogTrace(myName) << myName << ": fill gtran...";
0227 
0228     gtran[0] = (float)1.0 * (convertMmToCm(fv.translation().X()));
0229     gtran[1] = (float)1.0 * (convertMmToCm(fv.translation().Y()));
0230     gtran[2] = (float)1.0 * (convertMmToCm(fv.translation().Z()));
0231 
0232     LogTrace(myName) << myName << ": gtran[0]=" << gtran[0] << ", gtran[1]=" << gtran[1] << ", gtran[2]=" << gtran[2];
0233 
0234     edm::LogVerbatim("CSCGeometryParsFromDD")
0235         << "(8) gtran[0]: " << gtran[0] << " gtran[1]: " << gtran[1] << " gtran[2]: " << gtran[2];
0236 
0237     LogTrace(myName) << myName << ": fill grmat...";
0238 
0239     fv.rotation().GetComponents(trm.begin(), trm.end());
0240     size_t rotindex = 0;
0241     for (size_t i = 0; i < 9; ++i) {
0242       grmat[i] = (float)1.0 * trm[rotindex];
0243       rotindex = rotindex + 3;
0244       if ((i + 1) % 3 == 0) {
0245         rotindex = (i + 1) / 3;
0246       }
0247     }
0248     LogTrace(myName) << myName << ": looking for wire group info for layer "
0249                      << "E" << CSCDetId::endcap(id) << " S" << CSCDetId::station(id) << " R" << CSCDetId::ring(id)
0250                      << " C" << CSCDetId::chamber(id) << " L" << CSCDetId::layer(id);
0251 
0252     if (wg.numberOfGroups != 0) {
0253       LogTrace(myName) << myName << ": fv.geoHistory:      = " << fv.geoHistory();
0254       LogTrace(myName) << myName << ": TotNumWireGroups     = " << wg.numberOfGroups;
0255       LogTrace(myName) << myName << ": WireSpacing          = " << wg.wireSpacing;
0256       LogTrace(myName) << myName << ": AlignmentPinToFirstWire = " << wg.alignmentPinToFirstWire;
0257       LogTrace(myName) << myName << ": Narrow width of wire plane = " << wg.narrowWidthOfWirePlane;
0258       LogTrace(myName) << myName << ": Wide width of wire plane = " << wg.wideWidthOfWirePlane;
0259       LogTrace(myName) << myName << ": Length in y of wire plane = " << wg.lengthOfWirePlane;
0260       LogTrace(myName) << myName << ": wg.consecutiveGroups.size() = " << wg.consecutiveGroups.size();
0261       LogTrace(myName) << myName << ": wg.wiresInEachGroup.size() = " << wg.wiresInEachGroup.size();
0262       LogTrace(myName) << myName << ": \tNumGroups\tWiresInGroup";
0263       for (size_t i = 0; i < wg.consecutiveGroups.size(); i++) {
0264         LogTrace(myName) << myName << " \t" << wg.consecutiveGroups[i] << "\t\t" << wg.wiresInEachGroup[i];
0265       }
0266     } else {
0267       LogTrace(myName) << myName << ": DDD is MISSING SpecPars for wire groups";
0268     }
0269     LogTrace(myName) << myName << ": end of wire group info. ";
0270 
0271     LogTrace(myName) << myName << ":_z_ E" << jendcap << " S" << jstation << " R" << jring << " C" << jchamber << " L"
0272                      << jlayer << " gx=" << gtran[0] << ", gy=" << gtran[1] << ", gz=" << gtran[2]
0273                      << " thickness=" << fpar[2] * 2.;
0274 
0275     if (jlayer == 0) {  // Can only build chambers if we're filtering them
0276 
0277       LogTrace(myName) << myName << ":_z_ frame=" << uparvals[31] / 10. << " gap=" << uparvals[32] / 10.
0278                        << " panel=" << uparvals[33] / 10. << " offset=" << uparvals[34] / 10.;
0279 
0280       if (jstation == 1 && jring == 1) {
0281         // set up params for ME1a and ME1b and call buildChamber *for each*
0282         // Both get the full ME11 dimensions
0283 
0284         // detid is for ME11 and that's what we're using for ME1b in the software
0285 
0286         std::transform(gtran.begin(), gtran.end(), gtran.begin(), [](double i) -> double {
0287           return cms_rounding::roundIfNear0(i);
0288         });
0289         std::transform(grmat.begin(), grmat.end(), grmat.begin(), [](double i) -> double {
0290           return cms_rounding::roundIfNear0(i);
0291         });
0292         std::transform(
0293             fpar.begin(), fpar.end(), fpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0294 
0295         rig.insert(id, gtran, grmat, fpar);
0296         if (!chSpecsAlreadyExist) {
0297           LogDebug(myName) << " inserting chamber type " << chamberType << std::endl;
0298           rdp.pChamberType.emplace_back(chamberType);
0299           rdp.pUserParOffset.emplace_back(rdp.pfupars.size());
0300           rdp.pUserParSize.emplace_back(uparvals.size());
0301           std::copy(uparvals.begin(), uparvals.end(), std::back_inserter(rdp.pfupars));
0302         }
0303 
0304         // No. of anonymous parameters per chamber type should be read from cscSpecs file...
0305         // Only required for ME11 splitting into ME1a and ME1b values,
0306         // If it isn't seen may as well try to get further but this value will depend
0307         // on structure of the file so may not even match!
0308         const int kNoOfAnonParams = 35;
0309         if (noOfAnonParams == 0) {
0310           noOfAnonParams = kNoOfAnonParams;
0311         }  // in case it wasn't seen
0312 
0313         // copy ME1a params from back to the front
0314         std::copy(
0315             uparvals.begin() + noOfAnonParams + 1, uparvals.begin() + (2 * noOfAnonParams) + 2, uparvals.begin() + 1);
0316 
0317         CSCDetId detid1a = CSCDetId(jendcap, 1, 4, jchamber, 0);  // reset to ME1A
0318 
0319         std::transform(gtran.begin(), gtran.end(), gtran.begin(), [](double i) -> double {
0320           return cms_rounding::roundIfNear0(i);
0321         });
0322         std::transform(grmat.begin(), grmat.end(), grmat.begin(), [](double i) -> double {
0323           return cms_rounding::roundIfNear0(i);
0324         });
0325         std::transform(
0326             fpar.begin(), fpar.end(), fpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0327 
0328         rig.insert(detid1a.rawId(), gtran, grmat, fpar);
0329         int chtypeA = CSCChamberSpecs::whatChamberType(1, 4);
0330         ct = 0;
0331         for (; ct < rdp.pChamberType.size(); ++ct) {
0332           if (chtypeA == rdp.pChamberType[ct]) {
0333             break;
0334           }
0335         }
0336         if (ct < rdp.pChamberType.size() && rdp.pChamberType[ct] == chtypeA) {
0337           // then its in already, don't put it
0338           LogDebug(myName) << "found chamber type " << chtypeA << " so don't put it in! ";
0339         } else {
0340           LogDebug(myName) << " inserting chamber type " << chtypeA;
0341           rdp.pChamberType.emplace_back(chtypeA);
0342           rdp.pUserParOffset.emplace_back(rdp.pfupars.size());
0343           rdp.pUserParSize.emplace_back(uparvals.size());
0344           std::copy(uparvals.begin(), uparvals.end(), std::back_inserter(rdp.pfupars));
0345         }
0346 
0347       } else {
0348         std::transform(gtran.begin(), gtran.end(), gtran.begin(), [](double i) -> double {
0349           return cms_rounding::roundIfNear0(i);
0350         });
0351         std::transform(grmat.begin(), grmat.end(), grmat.begin(), [](double i) -> double {
0352           return cms_rounding::roundIfNear0(i);
0353         });
0354         std::transform(
0355             fpar.begin(), fpar.end(), fpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0356         rig.insert(id, gtran, grmat, fpar);
0357         if (!chSpecsAlreadyExist) {
0358           LogDebug(myName) << " inserting chamber type " << chamberType;
0359           rdp.pChamberType.emplace_back(chamberType);
0360           rdp.pUserParOffset.emplace_back(rdp.pfupars.size());
0361           rdp.pUserParSize.emplace_back(uparvals.size());
0362           std::copy(uparvals.begin(), uparvals.end(), std::back_inserter(rdp.pfupars));
0363         }
0364       }
0365 
0366     }  // filtering chambers.
0367 
0368     doSubDets = fv.next();
0369   }
0370   return true;
0371 }
0372 
0373 // dd4hep
0374 bool CSCGeometryParsFromDD::build(const cms::DDCompactView* cview,
0375                                   const MuonGeometryConstants& muonConstants,
0376                                   RecoIdealGeometry& rig,
0377                                   CSCRecoDigiParameters& rdp) {
0378   const std::string attribute = "MuStructure";
0379   const std::string value = "MuonEndcapCSC";
0380   const cms::DDSpecParRegistry& mypar = cview->specpars();
0381   const cms::DDFilter filter(attribute, value);
0382   cms::DDFilteredView fv(*cview, filter);
0383 
0384   int noOfAnonParams = 0;
0385 
0386   std::vector<double> uparvals;
0387   std::vector<double> fpar;
0388   std::vector<double> dpar;
0389   std::vector<double> gtran(3);
0390   std::vector<double> grmat(9);
0391   std::vector<double> trm(9);
0392 
0393   edm::LogVerbatim("CSCGeometryParsFromDD") << "(0) CSCGeometryParsFromDD - DD4hep ";
0394 
0395   while (fv.firstChild()) {
0396     MuonGeometryNumbering mbn(muonConstants);
0397     CSCNumberingScheme cscnum(muonConstants);
0398     int id = cscnum.baseNumberToUnitNumber(mbn.geoHistoryToBaseNumber(fv.history()));
0399     CSCDetId detid = CSCDetId(id);
0400 
0401     int jendcap = detid.endcap();
0402     int jstation = detid.station();
0403     int jring = detid.ring();
0404     int jchamber = detid.chamber();
0405     int jlayer = detid.layer();
0406 
0407     edm::LogVerbatim("CSCGeometryParsFromDD")
0408         << "(1) detId: " << id << " jendcap: " << jendcap << " jstation: " << jstation << " jring: " << jring
0409         << " jchamber: " << jchamber << " jlayer: " << jlayer;
0410 
0411     // Package up the wire group info as it's decoded
0412     CSCWireGroupPackage wg;
0413     uparvals.clear();
0414 
0415     // if the specs are made no need to get all this stuff!
0416     int chamberType = CSCChamberSpecs::whatChamberType(jstation, jring);
0417 
0418     size_t ct = 0;
0419     bool chSpecsAlreadyExist = false;
0420 
0421     for (; ct < rdp.pChamberType.size(); ++ct) {
0422       if (chamberType == rdp.pChamberType[ct]) {
0423         break;
0424       }
0425     }
0426 
0427     if (ct < rdp.pChamberType.size() && rdp.pChamberType[ct] == chamberType) {
0428       chSpecsAlreadyExist = true;
0429     } else {
0430       std::string_view my_name_bis = fv.name();
0431       std::string my_name_tris = std::string(my_name_bis);
0432       std::vector<std::string_view> namesInPath = mypar.names("//" + my_name_tris);
0433       std::string my_string = "ChamberSpecs_";
0434       int index = -1;
0435       for (vector<string_view>::size_type i = 0; i < namesInPath.size(); ++i) {
0436         std::size_t found = namesInPath[i].find(my_string);
0437         if (found != std::string::npos)
0438           index = i;
0439       }
0440       uparvals = fv.get<std::vector<double>>(std::string(namesInPath[index]), "upar");
0441 
0442       auto it = uparvals.begin();
0443       it = uparvals.insert(it, uparvals.size());
0444       auto noofanonparams = fv.get<double>("NoOfAnonParams");
0445       noOfAnonParams = static_cast<int>(noofanonparams);
0446 
0447       for (auto i : fv.get<std::vector<double>>(std::string(namesInPath[index]), "NumWiresPerGrp")) {
0448         wg.wiresInEachGroup.emplace_back(int(i));
0449       }
0450 
0451       for (auto i : fv.get<std::vector<double>>(std::string(namesInPath[index]), "NumGroups")) {
0452         wg.consecutiveGroups.emplace_back(int(i));
0453       }
0454 
0455       auto wirespacing = fv.get<double>("WireSpacing");
0456       wg.wireSpacing = static_cast<double>(wirespacing / dd4hep::mm);
0457       edm::LogVerbatim("CSCGeometryParsFromDD") << "(2) wireSpacing: " << wg.wireSpacing;
0458 
0459       auto alignmentpintofirstwire = fv.get<double>("AlignmentPinToFirstWire");
0460       wg.alignmentPinToFirstWire = static_cast<double>(alignmentpintofirstwire / dd4hep::mm);
0461       edm::LogVerbatim("CSCGeometryParsFromDD") << "(3) alignmentPinToFirstWire: " << wg.alignmentPinToFirstWire;
0462 
0463       auto totnumwiregroups = fv.get<double>("TotNumWireGroups");
0464       wg.numberOfGroups = static_cast<int>(totnumwiregroups);
0465 
0466       auto lengthoffirstwire = fv.get<double>("LengthOfFirstWire");
0467       wg.narrowWidthOfWirePlane = static_cast<double>(lengthoffirstwire / dd4hep::mm);
0468       edm::LogVerbatim("CSCGeometryParsFromDD") << "(4) narrowWidthOfWirePlane: " << wg.narrowWidthOfWirePlane;
0469 
0470       auto lengthoflastwire = fv.get<double>("LengthOfLastWire");
0471       wg.wideWidthOfWirePlane = static_cast<double>(lengthoflastwire / dd4hep::mm);
0472       edm::LogVerbatim("CSCGeometryParsFromDD") << "(5) wideWidthOfWirePlane: " << wg.wideWidthOfWirePlane;
0473 
0474       auto radialextentofwireplane = fv.get<double>("RadialExtentOfWirePlane");
0475       wg.lengthOfWirePlane = static_cast<double>(radialextentofwireplane / dd4hep::mm);
0476       edm::LogVerbatim("CSCGeometryParsFromDD") << "(6) lengthOfWirePlane: " << wg.lengthOfWirePlane;
0477 
0478       uparvals.emplace_back(wg.wireSpacing);
0479       uparvals.emplace_back(wg.alignmentPinToFirstWire);
0480       uparvals.emplace_back(wg.numberOfGroups);
0481       uparvals.emplace_back(wg.narrowWidthOfWirePlane);
0482       uparvals.emplace_back(wg.wideWidthOfWirePlane);
0483       uparvals.emplace_back(wg.lengthOfWirePlane);
0484       uparvals.emplace_back(wg.wiresInEachGroup.size());
0485 
0486       for (CSCWireGroupPackage::Container::const_iterator it = wg.wiresInEachGroup.begin();
0487            it != wg.wiresInEachGroup.end();
0488            ++it) {
0489         uparvals.emplace_back(*it);
0490       }
0491       for (CSCWireGroupPackage::Container::const_iterator it = wg.consecutiveGroups.begin();
0492            it != wg.consecutiveGroups.end();
0493            ++it) {
0494         uparvals.emplace_back(*it);
0495       }
0496 
0497       /** end stuff **/
0498     }
0499 
0500     fpar.clear();
0501 
0502     std::string my_title(fv.solid()->GetTitle());
0503 
0504     if (my_title == "Subtraction") {
0505       cms::DDSolid mysolid(fv.solid());
0506       auto solidA = mysolid.solidA();
0507       std::vector<double> dpar = solidA.dimensions();
0508 
0509       std::transform(
0510           dpar.begin(), dpar.end(), dpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0511 
0512       fpar.emplace_back((dpar[1] / dd4hep::cm));
0513       fpar.emplace_back((dpar[2] / dd4hep::cm));
0514       fpar.emplace_back((dpar[3] / dd4hep::cm));
0515       fpar.emplace_back((dpar[4] / dd4hep::cm));
0516       edm::LogVerbatim("CSCGeometryParsFromDD")
0517           << "(7) - Subtraction - dpar[1] (ddd dpar[4]): " << dpar[1] / dd4hep::cm
0518           << " (ddd dpar[8]):  " << dpar[2] / dd4hep::cm << " dpar[3] (as ddd): " << dpar[3] / dd4hep::cm
0519           << " dpar[4] (ddd dpar[0]): " << dpar[4] / dd4hep::cm;
0520     } else {
0521       dpar = fv.parameters();
0522 
0523       std::transform(
0524           dpar.begin(), dpar.end(), dpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0525 
0526       fpar.emplace_back((dpar[0] / dd4hep::cm));
0527       fpar.emplace_back((dpar[1] / dd4hep::cm));
0528       fpar.emplace_back((dpar[2] / dd4hep::cm));
0529       fpar.emplace_back((dpar[3] / dd4hep::cm));
0530       edm::LogVerbatim("CSCGeometryParsFromDD")
0531           << "(7)Bis - Else - dpar[0]: " << dpar[0] / dd4hep::cm << " dpar[1]: " << dpar[1] / dd4hep::cm
0532           << " dpar[2]:  " << dpar[2] / dd4hep::cm << " dpar[3]: " << dpar[3] / dd4hep::cm;
0533     }
0534 
0535     gtran[0] = static_cast<float>(fv.translation().X() / dd4hep::cm);
0536     gtran[1] = static_cast<float>(fv.translation().Y() / dd4hep::cm);
0537     gtran[2] = static_cast<float>(fv.translation().Z() / dd4hep::cm);
0538 
0539     edm::LogVerbatim("CSCGeometryParsFromDD")
0540         << "(8) gtran[0]: " << gtran[0] / dd4hep::cm << " gtran[1]: " << gtran[1] / dd4hep::cm
0541         << " gtran[2]: " << gtran[2] / dd4hep::cm;
0542 
0543     std::transform(
0544         gtran.begin(), gtran.end(), gtran.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0545 
0546     fv.rotation().GetComponents(trm.begin(), trm.end());
0547     size_t rotindex = 0;
0548     for (size_t i = 0; i < 9; ++i) {
0549       grmat[i] = static_cast<float>(trm[rotindex]);
0550       rotindex = rotindex + 3;
0551       if ((i + 1) % 3 == 0) {
0552         rotindex = (i + 1) / 3;
0553       }
0554     }
0555 
0556     if (wg.numberOfGroups == 0) {
0557       LogTrace(myName) << myName << " wg.numberOfGroups == 0 ";
0558     }
0559 
0560     if (jlayer == 0) {  // Can only build chambers if we're filtering them
0561 
0562       if (jstation == 1 && jring == 1) {
0563         std::transform(gtran.begin(), gtran.end(), gtran.begin(), [](double i) -> double {
0564           return cms_rounding::roundIfNear0(i);
0565         });
0566 
0567         std::transform(grmat.begin(), grmat.end(), grmat.begin(), [](double i) -> double {
0568           return cms_rounding::roundIfNear0(i);
0569         });
0570 
0571         std::transform(
0572             fpar.begin(), fpar.end(), fpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0573 
0574         rig.insert(id, gtran, grmat, fpar);
0575         if (!chSpecsAlreadyExist) {
0576           rdp.pChamberType.emplace_back(chamberType);
0577           rdp.pUserParOffset.emplace_back(rdp.pfupars.size());
0578           rdp.pUserParSize.emplace_back(uparvals.size());
0579           std::copy(uparvals.begin(), uparvals.end(), std::back_inserter(rdp.pfupars));
0580         }
0581 
0582         // No. of anonymous parameters per chamber type should be read from cscSpecs file...
0583         // Only required for ME11 splitting into ME1a and ME1b values,
0584         // If it isn't seen may as well try to get further but this value will depend
0585         // on structure of the file so may not even match!
0586         const int kNoOfAnonParams = 35;
0587         if (noOfAnonParams == 0) {
0588           noOfAnonParams = kNoOfAnonParams;
0589         }  // in case it wasn't seen
0590 
0591         // copy ME1a params from back to the front
0592         std::copy(
0593             uparvals.begin() + noOfAnonParams + 1, uparvals.begin() + (2 * noOfAnonParams) + 2, uparvals.begin() + 1);
0594 
0595         CSCDetId detid1a = CSCDetId(jendcap, 1, 4, jchamber, 0);  // reset to ME1A
0596 
0597         std::transform(gtran.begin(), gtran.end(), gtran.begin(), [](double i) -> double {
0598           return cms_rounding::roundIfNear0(i);
0599         });
0600 
0601         std::transform(grmat.begin(), grmat.end(), grmat.begin(), [](double i) -> double {
0602           return cms_rounding::roundIfNear0(i);
0603         });
0604 
0605         std::transform(
0606             fpar.begin(), fpar.end(), fpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0607 
0608         rig.insert(detid1a.rawId(), gtran, grmat, fpar);
0609         int chtypeA = CSCChamberSpecs::whatChamberType(1, 4);
0610         ct = 0;
0611         for (; ct < rdp.pChamberType.size(); ++ct) {
0612           if (chtypeA == rdp.pChamberType[ct]) {
0613             break;
0614           }
0615         }
0616         if (ct < rdp.pChamberType.size() && rdp.pChamberType[ct] == chtypeA) {
0617           // then its in already, don't put it
0618           LogTrace(myName) << myName << " ct < rdp.pChamberType.size() && rdp.pChamberType[ct] == chtypeA ";
0619         } else {
0620           rdp.pChamberType.emplace_back(chtypeA);
0621           rdp.pUserParOffset.emplace_back(rdp.pfupars.size());
0622           rdp.pUserParSize.emplace_back(uparvals.size());
0623           std::copy(uparvals.begin(), uparvals.end(), std::back_inserter(rdp.pfupars));
0624         }
0625 
0626       } else {
0627         std::transform(gtran.begin(), gtran.end(), gtran.begin(), [](double i) -> double {
0628           return cms_rounding::roundIfNear0(i);
0629         });
0630 
0631         std::transform(grmat.begin(), grmat.end(), grmat.begin(), [](double i) -> double {
0632           return cms_rounding::roundIfNear0(i);
0633         });
0634 
0635         std::transform(
0636             fpar.begin(), fpar.end(), fpar.begin(), [](double i) -> double { return cms_rounding::roundIfNear0(i); });
0637 
0638         rig.insert(id, gtran, grmat, fpar);
0639         if (!chSpecsAlreadyExist) {
0640           rdp.pChamberType.emplace_back(chamberType);
0641           rdp.pUserParOffset.emplace_back(rdp.pfupars.size());
0642           rdp.pUserParSize.emplace_back(uparvals.size());
0643           std::copy(uparvals.begin(), uparvals.end(), std::back_inserter(rdp.pfupars));
0644         }
0645       }
0646 
0647     }  // filtering chambers.
0648   }
0649 
0650   return true;
0651 }