Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-04-22 22:55:37

0001 // -*- C++ -*-
0002 //
0003 // Package:     Geometry
0004 // Class  :     TGeoMgrFromDdd
0005 //
0006 // Implementation:
0007 //     [Notes on implementation]
0008 //
0009 // Original Author:
0010 //         Created:  Fri Jul  2 16:11:42 CEST 2010
0011 //
0012 
0013 #include "FWCore/Framework/interface/ESProducer.h"
0014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0015 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0016 #include "FWCore/Framework/interface/EventSetup.h"
0017 #include "FWCore/Framework/interface/ESTransientHandle.h"
0018 #include "FWCore/Framework/interface/ModuleFactory.h"
0019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0020 
0021 #include "DetectorDescription/Core/interface/DDCompactView.h"
0022 #include "DetectorDescription/Core/interface/DDSolid.h"
0023 #include "DetectorDescription/Core/interface/DDMaterial.h"
0024 
0025 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0026 
0027 #include "Fireworks/Geometry/interface/DisplayGeomRecord.h"
0028 
0029 #include "TGeoManager.h"
0030 #include "TGeoMatrix.h"
0031 #include "TGeoCompositeShape.h"
0032 #include "TGeoPcon.h"
0033 #include "TGeoPgon.h"
0034 #include "TGeoCone.h"
0035 #include "TGeoBoolNode.h"
0036 #include "TGeoTube.h"
0037 #include "TGeoArb8.h"
0038 #include "TGeoTrd2.h"
0039 #include "TGeoTorus.h"
0040 #include "TGeoEltu.h"
0041 #include "TGeoXtru.h"
0042 
0043 #include "Math/GenVector/RotationX.h"
0044 #include "Math/GenVector/RotationZ.h"
0045 
0046 #include "CLHEP/Units/GlobalSystemOfUnits.h"
0047 #include <cmath>
0048 
0049 class TGeoMgrFromDdd : public edm::ESProducer {
0050 public:
0051   TGeoMgrFromDdd(const edm::ParameterSet&);
0052   TGeoMgrFromDdd(const TGeoMgrFromDdd&) = delete;
0053   const TGeoMgrFromDdd& operator=(const TGeoMgrFromDdd&) = delete;
0054 
0055   using ReturnType = std::unique_ptr<TGeoManager>;
0056 
0057   // ---------- const member functions ---------------------
0058 
0059   // ---------- static member functions --------------------
0060 
0061   // ---------- member functions ---------------------------
0062 
0063   ReturnType produce(const DisplayGeomRecord&);
0064 
0065   static void fillDescriptions(edm::ConfigurationDescriptions&);
0066 
0067 private:
0068   TGeoManager* createManager(int level);
0069 
0070   TGeoShape* createShape(const std::string& iName, const DDSolid& iSolid);
0071   TGeoVolume* createVolume(const std::string& iName, const DDSolid& iSolid, const DDMaterial& iMaterial);
0072   TGeoMaterial* createMaterial(const DDMaterial& iMaterial);
0073 
0074   // ---------- member data --------------------------------
0075 
0076   const int m_level;
0077   const bool m_verbose;
0078   const bool m_fullname;
0079   std::string m_TGeoName;
0080   std::string m_TGeoTitle;
0081 
0082   std::map<std::string, TGeoShape*> nameToShape_;
0083   std::map<std::string, TGeoVolume*> nameToVolume_;
0084   std::map<std::string, TGeoMaterial*> nameToMaterial_;
0085   std::map<std::string, TGeoMedium*> nameToMedium_;
0086 
0087   const edm::ESGetToken<DDCompactView, IdealGeometryRecord> viewToken_;
0088 };
0089 
0090 TGeoMgrFromDdd::TGeoMgrFromDdd(const edm::ParameterSet& pset)
0091     : m_level(pset.getUntrackedParameter<int>("level")),
0092       m_verbose(pset.getUntrackedParameter<bool>("verbose")),
0093       m_fullname(pset.getUntrackedParameter<bool>("fullName")),
0094       viewToken_(setWhatProduced(this).consumes()) {}
0095 
0096 void TGeoMgrFromDdd::fillDescriptions(edm::ConfigurationDescriptions& conf) {
0097   edm::ParameterSetDescription desc;
0098   desc.addUntracked<int>("level", 10)->setComment("How deep into the geometry hierarchy should the conversion go.");
0099   desc.addUntracked<bool>("verbose", false);
0100   desc.addUntracked<bool>("fullName", true)->setComment("use fillname() instead of name() when generating node names");
0101 
0102   conf.add("TGeoMgrFromDdd", desc);
0103 }
0104 
0105 //==============================================================================
0106 // Local helpers
0107 //==============================================================================
0108 
0109 namespace {
0110   TGeoCombiTrans* createPlacement(const DDRotationMatrix& iRot, const DDTranslation& iTrans) {
0111     double elements[9];
0112     iRot.GetComponents(elements);
0113     TGeoRotation r;
0114     r.SetMatrix(elements);
0115 
0116     TGeoTranslation t(iTrans.x() / cm, iTrans.y() / cm, iTrans.z() / cm);
0117 
0118     return new TGeoCombiTrans(t, r);
0119   }
0120 }  // namespace
0121 
0122 //==============================================================================
0123 // public member functions
0124 //==============================================================================
0125 
0126 TGeoMgrFromDdd::ReturnType TGeoMgrFromDdd::produce(const DisplayGeomRecord& iRecord) {
0127   using namespace edm;
0128 
0129   ESTransientHandle<DDCompactView> viewH = iRecord.getTransientHandle(viewToken_);
0130 
0131   if (!viewH.isValid()) {
0132     return std::unique_ptr<TGeoManager>();
0133   }
0134 
0135   TGeoManager* geo_mgr = new TGeoManager("cmsGeo", "CMS Detector");
0136   // NOTE: the default constructor does not create the identity matrix
0137   if (gGeoIdentity == nullptr) {
0138     gGeoIdentity = new TGeoIdentity("Identity");
0139   }
0140 
0141   std::cout << "about to initialize the DDCompactView walker"
0142             << " with a root node " << viewH->root() << std::endl;
0143 
0144   auto walker = viewH->walker();
0145   auto info = walker.current();
0146 
0147   // The top most item is actually the volume holding both the
0148   // geometry AND the magnetic field volumes!
0149   walker.firstChild();
0150   if (!walker.firstChild()) {
0151     return std::unique_ptr<TGeoManager>();
0152   }
0153 
0154   TGeoVolume* top = (m_fullname ? createVolume(info.first.name().fullname(), info.first.solid(), info.first.material())
0155                                 : createVolume(info.first.name().name(), info.first.solid(), info.first.material()));
0156 
0157   if (top == nullptr) {
0158     return std::unique_ptr<TGeoManager>();
0159   }
0160 
0161   geo_mgr->SetTopVolume(top);
0162   // ROOT chokes unless colors are assigned
0163   top->SetVisibility(kFALSE);
0164   top->SetLineColor(kBlue);
0165 
0166   std::vector<TGeoVolume*> parentStack;
0167   parentStack.push_back(top);
0168 
0169   do {
0170     auto info = walker.current();
0171 
0172     if (m_verbose) {
0173       std::cout << "parentStack of size " << parentStack.size() << std::endl;
0174       auto num = (info.second != nullptr) ? info.second->copyno() : 0;
0175       std::cout << info.first.name() << " " << num << " " << DDSolidShapesName::name(info.first.solid().shape())
0176                 << std::endl;
0177     }
0178 
0179     std::string name = m_fullname ? info.first.name().fullname() : info.first.name().name();
0180     bool childAlreadyExists = (nullptr != nameToVolume_[name]);
0181     TGeoVolume* child = createVolume(name, info.first.solid(), info.first.material());
0182     if (nullptr != child && info.second != nullptr) {
0183       parentStack.back()->AddNode(
0184           child, info.second->copyno(), createPlacement(info.second->rotation(), info.second->translation()));
0185       child->SetLineColor(kBlue);
0186     } else {
0187       if (info.second == nullptr) {
0188         break;
0189       }
0190     }
0191     if (nullptr == child || childAlreadyExists || m_level == int(parentStack.size())) {
0192       if (nullptr != child) {
0193         child->SetLineColor(kRed);
0194       }
0195       //stop descending
0196       if (!walker.nextSibling()) {
0197         while (walker.parent()) {
0198           parentStack.pop_back();
0199           if (walker.nextSibling()) {
0200             break;
0201           }
0202         }
0203       }
0204     } else {
0205       if (walker.firstChild()) {
0206         parentStack.push_back(child);
0207       } else {
0208         if (!walker.nextSibling()) {
0209           while (walker.parent()) {
0210             parentStack.pop_back();
0211             if (walker.nextSibling()) {
0212               break;
0213             }
0214           }
0215         }
0216       }
0217     }
0218   } while (!parentStack.empty());
0219 
0220   geo_mgr->CloseGeometry();
0221 
0222   geo_mgr->DefaultColors();
0223 
0224   nameToShape_.clear();
0225   nameToVolume_.clear();
0226   nameToMaterial_.clear();
0227   nameToMedium_.clear();
0228 
0229   return std::unique_ptr<TGeoManager>(geo_mgr);
0230 }
0231 
0232 //==============================================================================
0233 // private member functions
0234 //==============================================================================
0235 
0236 TGeoShape* TGeoMgrFromDdd::createShape(const std::string& iName, const DDSolid& iSolid) {
0237   edm::LogVerbatim("TGeoMgrFromDdd") << "createShape with name: " << iName
0238                                      << " and solid: " << iSolid.name().fullname();
0239 
0240   DDBase<DDName, DDI::Solid*>::def_type defined(iSolid.isDefined());
0241   if (!defined.first)
0242     throw cms::Exception("TGeoMgrFromDdd::createShape * solid " + iName + " is not declared * ");
0243   if (!defined.second)
0244     throw cms::Exception("TGeoMgrFromDdd::createShape * solid " + defined.first->name() + " is not defined *");
0245 
0246   TGeoShape* rSolid = nameToShape_[iName];
0247   if (rSolid == nullptr) {
0248     const std::vector<double>& params = iSolid.parameters();
0249     switch (iSolid.shape()) {
0250       case DDSolidShape::ddbox:
0251         rSolid = new TGeoBBox(iName.c_str(), params[0] / cm, params[1] / cm, params[2] / cm);
0252         break;
0253       case DDSolidShape::ddcons:
0254         rSolid = new TGeoConeSeg(iName.c_str(),
0255                                  params[0] / cm,
0256                                  params[1] / cm,
0257                                  params[2] / cm,
0258                                  params[3] / cm,
0259                                  params[4] / cm,
0260                                  params[5] / deg,
0261                                  params[6] / deg + params[5] / deg);
0262         break;
0263       case DDSolidShape::ddtubs:
0264         //Order in params is  zhalf,rIn,rOut,startPhi,deltaPhi
0265         rSolid = new TGeoTubeSeg(iName.c_str(),
0266                                  params[1] / cm,
0267                                  params[2] / cm,
0268                                  params[0] / cm,
0269                                  params[3] / deg,
0270                                  params[3] / deg + params[4] / deg);
0271         break;
0272       case DDSolidShape::ddcuttubs:
0273         //Order in params is  zhalf,rIn,rOut,startPhi,deltaPhi,lx,ly,lz,tx,ty,tz
0274         rSolid = new TGeoCtub(iName.c_str(),
0275                               params[1] / cm,
0276                               params[2] / cm,
0277                               params[0] / cm,
0278                               params[3] / deg,
0279                               params[3] / deg + params[4] / deg,
0280                               params[5],
0281                               params[6],
0282                               params[7],
0283                               params[8],
0284                               params[9],
0285                               params[10]);
0286         break;
0287       case DDSolidShape::ddtrap:
0288         rSolid = new TGeoTrap(iName.c_str(),
0289                               params[0] / cm,     //dz
0290                               params[1] / deg,    //theta
0291                               params[2] / deg,    //phi
0292                               params[3] / cm,     //dy1
0293                               params[4] / cm,     //dx1
0294                               params[5] / cm,     //dx2
0295                               params[6] / deg,    //alpha1
0296                               params[7] / cm,     //dy2
0297                               params[8] / cm,     //dx3
0298                               params[9] / cm,     //dx4
0299                               params[10] / deg);  //alpha2
0300         break;
0301       case DDSolidShape::ddpolycone_rrz:
0302         rSolid = new TGeoPcon(iName.c_str(), params[0] / deg, params[1] / deg, (params.size() - 2) / 3);
0303         {
0304           std::vector<double> temp(params.size() + 1);
0305           temp.reserve(params.size() + 1);
0306           temp[0] = params[0] / deg;
0307           temp[1] = params[1] / deg;
0308           temp[2] = (params.size() - 2) / 3;
0309           std::copy(params.begin() + 2, params.end(), temp.begin() + 3);
0310           for (std::vector<double>::iterator it = temp.begin() + 3; it != temp.end(); ++it) {
0311             *it /= cm;
0312           }
0313           rSolid->SetDimensions(&(*(temp.begin())));
0314         }
0315         break;
0316       case DDSolidShape::ddpolyhedra_rrz:
0317         rSolid = new TGeoPgon(
0318             iName.c_str(), params[1] / deg, params[2] / deg, static_cast<int>(params[0]), (params.size() - 3) / 3);
0319         {
0320           std::vector<double> temp(params.size() + 1);
0321           temp[0] = params[1] / deg;
0322           temp[1] = params[2] / deg;
0323           temp[2] = params[0];
0324           temp[3] = (params.size() - 3) / 3;
0325           std::copy(params.begin() + 3, params.end(), temp.begin() + 4);
0326           for (std::vector<double>::iterator it = temp.begin() + 4; it != temp.end(); ++it) {
0327             *it /= cm;
0328           }
0329           rSolid->SetDimensions(&(*(temp.begin())));
0330         }
0331         break;
0332       case DDSolidShape::ddextrudedpolygon: {
0333         DDExtrudedPolygon extrPgon(iSolid);
0334         std::vector<double> x = extrPgon.xVec();
0335         std::transform(x.begin(), x.end(), x.begin(), [](double d) { return d / cm; });
0336         std::vector<double> y = extrPgon.yVec();
0337         std::transform(y.begin(), y.end(), y.begin(), [](double d) { return d / cm; });
0338         std::vector<double> z = extrPgon.zVec();
0339         std::vector<double> zx = extrPgon.zxVec();
0340         std::vector<double> zy = extrPgon.zyVec();
0341         std::vector<double> zscale = extrPgon.zscaleVec();
0342 
0343         TGeoXtru* mySolid = new TGeoXtru(z.size());
0344         mySolid->DefinePolygon(x.size(), &(*x.begin()), &(*y.begin()));
0345         for (size_t i = 0; i < params[0]; ++i) {
0346           mySolid->DefineSection(i, z[i] / cm, zx[i] / cm, zy[i] / cm, zscale[i]);
0347         }
0348 
0349         rSolid = mySolid;
0350       } break;
0351       case DDSolidShape::ddpseudotrap: {
0352         //implementation taken from SimG4Core/Geometry/src/DDG4SolidConverter.cc
0353         const static DDRotationMatrix s_rot(ROOT::Math::RotationX(90. * deg));
0354         DDPseudoTrap pt(iSolid);
0355 
0356         double r = pt.radius();
0357         bool atMinusZ = pt.atMinusZ();
0358         double x = 0;
0359         double h = 0;
0360         bool intersec = false;  // union or intersection solid
0361 
0362         if (atMinusZ) {
0363           x = pt.x1();  // tubs radius
0364         } else {
0365           x = pt.x2();  // tubs radius
0366         }
0367         double halfOpeningAngle = asin(x / std::abs(r)) / deg;
0368         double displacement = 0;
0369         double startPhi = 0;
0370         /* calculate the displacement of the tubs w.r.t. to the trap,
0371            determine the opening angle of the tubs */
0372         double delta = sqrt(r * r - x * x);
0373         std::string name = m_fullname ? pt.name().fullname() : pt.name().name();
0374 
0375         if (r < 0 && std::abs(r) >= x) {
0376           intersec = true;                            // intersection solid
0377           h = pt.y1() < pt.y2() ? pt.y2() : pt.y1();  // tubs half height
0378           h += h / 20.;                               // enlarge a bit - for subtraction solid
0379           if (atMinusZ) {
0380             displacement = -pt.halfZ() - delta;
0381             startPhi = 90. - halfOpeningAngle;
0382           } else {
0383             displacement = pt.halfZ() + delta;
0384             startPhi = -90. - halfOpeningAngle;
0385           }
0386         } else if (r > 0 && std::abs(r) >= x) {
0387           if (atMinusZ) {
0388             displacement = -pt.halfZ() + delta;
0389             startPhi = 270. - halfOpeningAngle;
0390             h = pt.y1();
0391           } else {
0392             displacement = pt.halfZ() - delta;
0393             startPhi = 90. - halfOpeningAngle;
0394             h = pt.y2();
0395           }
0396         } else {
0397           throw cms::Exception("Check parameters of the PseudoTrap! name=" + name);
0398         }
0399 
0400         std::unique_ptr<TGeoShape> trap(
0401             new TGeoTrd2(name.c_str(), pt.x1() / cm, pt.x2() / cm, pt.y1() / cm, pt.y2() / cm, pt.halfZ() / cm));
0402 
0403         std::unique_ptr<TGeoShape> tubs(new TGeoTubeSeg(name.c_str(),
0404                                                         0.,
0405                                                         std::abs(r) / cm,  // radius cannot be negative!!!
0406                                                         h / cm,
0407                                                         startPhi,
0408                                                         startPhi + halfOpeningAngle * 2.));
0409         if (intersec) {
0410           TGeoSubtraction* sub = new TGeoSubtraction(
0411               trap.release(), tubs.release(), nullptr, createPlacement(s_rot, DDTranslation(0., 0., displacement)));
0412           rSolid = new TGeoCompositeShape(iName.c_str(), sub);
0413         } else {
0414           std::unique_ptr<TGeoShape> box(new TGeoBBox(1.1 * x / cm, 1.1 * h / cm, sqrt(r * r - x * x) / cm));
0415 
0416           TGeoSubtraction* sub = new TGeoSubtraction(
0417               tubs.release(), box.release(), nullptr, createPlacement(s_rot, DDTranslation(0., 0., 0.)));
0418 
0419           std::unique_ptr<TGeoShape> tubicCap(new TGeoCompositeShape(iName.c_str(), sub));
0420 
0421           TGeoUnion* boolS = new TGeoUnion(
0422               trap.release(), tubicCap.release(), nullptr, createPlacement(s_rot, DDTranslation(0., 0., displacement)));
0423 
0424           rSolid = new TGeoCompositeShape(iName.c_str(), boolS);
0425         }
0426 
0427         break;
0428       }
0429       case DDSolidShape::ddtorus: {
0430         DDTorus solid(iSolid);
0431         rSolid = new TGeoTorus(iName.c_str(),
0432                                solid.rTorus() / cm,
0433                                solid.rMin() / cm,
0434                                solid.rMax() / cm,
0435                                solid.startPhi() / deg,
0436                                solid.deltaPhi() / deg);
0437         break;
0438       }
0439       case DDSolidShape::ddsubtraction: {
0440         DDBooleanSolid boolSolid(iSolid);
0441         if (!boolSolid) {
0442           throw cms::Exception("GeomConvert") << "conversion to DDBooleanSolid failed";
0443         }
0444 
0445         std::string nameA = m_fullname ? boolSolid.solidA().name().fullname() : boolSolid.solidA().name().name();
0446         std::string nameB = m_fullname ? boolSolid.solidB().name().fullname() : boolSolid.solidB().name().name();
0447         std::unique_ptr<TGeoShape> left(createShape(nameA, boolSolid.solidA()));
0448         std::unique_ptr<TGeoShape> right(createShape(nameB, boolSolid.solidB()));
0449         if (nullptr != left.get() && nullptr != right.get()) {
0450           TGeoSubtraction* sub =
0451               new TGeoSubtraction(left.release(),
0452                                   right.release(),
0453                                   nullptr,
0454                                   createPlacement(boolSolid.rotation().matrix(), boolSolid.translation()));
0455           rSolid = new TGeoCompositeShape(iName.c_str(), sub);
0456         }
0457         break;
0458       }
0459       case DDSolidShape::ddtrunctubs: {
0460         DDTruncTubs tt(iSolid);
0461         if (!tt) {
0462           throw cms::Exception("GeomConvert") << "conversion to DDTruncTubs failed";
0463         }
0464         double rIn(tt.rIn());
0465         double rOut(tt.rOut());
0466         double zHalf(tt.zHalf());
0467         double startPhi(tt.startPhi());
0468         double deltaPhi(tt.deltaPhi());
0469         double cutAtStart(tt.cutAtStart());
0470         double cutAtDelta(tt.cutAtDelta());
0471         bool cutInside(bool(tt.cutInside()));
0472         std::string name = m_fullname ? tt.name().fullname() : tt.name().name();
0473 
0474         // check the parameters
0475         if (rIn <= 0 || rOut <= 0 || cutAtStart <= 0 || cutAtDelta <= 0) {
0476           std::string s = "TruncTubs " + name + ": 0 <= rIn,cutAtStart,rOut,cutAtDelta,rOut violated!";
0477           throw cms::Exception(s);
0478         }
0479         if (rIn >= rOut) {
0480           std::string s = "TruncTubs " + name + ": rIn<rOut violated!";
0481           throw cms::Exception(s);
0482         }
0483         if (startPhi != 0.) {
0484           std::string s = "TruncTubs " + name + ": startPhi != 0 not supported!";
0485           throw cms::Exception(s);
0486         }
0487 
0488         startPhi = 0.;
0489         double r(cutAtStart);
0490         double R(cutAtDelta);
0491 
0492         // Note: startPhi is always 0.0
0493         std::unique_ptr<TGeoShape> tubs(
0494             new TGeoTubeSeg(name.c_str(), rIn / cm, rOut / cm, zHalf / cm, startPhi, deltaPhi / deg));
0495 
0496         double boxX(rOut), boxY(rOut);  // exaggerate dimensions - does not matter, it's subtracted!
0497 
0498         // width of the box > width of the tubs
0499         double boxZ(1.1 * zHalf);
0500 
0501         // angle of the box w.r.t. tubs
0502         double cath = r - R * cos(deltaPhi);
0503         double hypo = sqrt(r * r + R * R - 2. * r * R * cos(deltaPhi));
0504         double cos_alpha = cath / hypo;
0505         double alpha = -acos(cos_alpha);
0506 
0507         // rotationmatrix of box w.r.t. tubs
0508         TGeoRotation rot;
0509         rot.RotateX(90);
0510         rot.RotateZ(alpha / deg);
0511 
0512         // center point of the box
0513         double xBox;
0514         if (!cutInside) {
0515           xBox = r + boxX / sin(fabs(alpha));
0516         } else {
0517           xBox = -(boxX / sin(fabs(alpha)) - r);
0518         }
0519         std::unique_ptr<TGeoShape> box(new TGeoBBox(name.c_str(), boxX / cm, boxZ / cm, boxY / cm));
0520 
0521         TGeoTranslation trans(xBox / cm, 0., 0.);
0522 
0523         TGeoSubtraction* sub =
0524             new TGeoSubtraction(tubs.release(), box.release(), nullptr, new TGeoCombiTrans(trans, rot));
0525 
0526         rSolid = new TGeoCompositeShape(iName.c_str(), sub);
0527         break;
0528       }
0529       case DDSolidShape::ddunion: {
0530         DDBooleanSolid boolSolid(iSolid);
0531         if (!boolSolid) {
0532           throw cms::Exception("GeomConvert") << "conversion to DDBooleanSolid failed";
0533         }
0534 
0535         std::string nameA = m_fullname ? boolSolid.solidA().name().fullname() : boolSolid.solidA().name().name();
0536         std::string nameB = m_fullname ? boolSolid.solidB().name().fullname() : boolSolid.solidB().name().name();
0537         std::unique_ptr<TGeoShape> left(createShape(nameA, boolSolid.solidA()));
0538         std::unique_ptr<TGeoShape> right(createShape(nameB, boolSolid.solidB()));
0539         //DEBUGGING
0540         //break;
0541         if (nullptr != left.get() && nullptr != right.get()) {
0542           TGeoUnion* boolS = new TGeoUnion(left.release(),
0543                                            right.release(),
0544                                            nullptr,
0545                                            createPlacement(boolSolid.rotation().matrix(), boolSolid.translation()));
0546           rSolid = new TGeoCompositeShape(iName.c_str(), boolS);
0547         }
0548         break;
0549       }
0550       case DDSolidShape::ddintersection: {
0551         DDBooleanSolid boolSolid(iSolid);
0552         if (!boolSolid) {
0553           throw cms::Exception("GeomConvert") << "conversion to DDBooleanSolid failed";
0554         }
0555 
0556         std::string nameA = m_fullname ? boolSolid.solidA().name().fullname() : boolSolid.solidA().name().name();
0557         std::string nameB = m_fullname ? boolSolid.solidB().name().fullname() : boolSolid.solidB().name().name();
0558         std::unique_ptr<TGeoShape> left(createShape(nameA, boolSolid.solidA()));
0559         std::unique_ptr<TGeoShape> right(createShape(nameB, boolSolid.solidB()));
0560         if (nullptr != left.get() && nullptr != right.get()) {
0561           TGeoIntersection* boolS =
0562               new TGeoIntersection(left.release(),
0563                                    right.release(),
0564                                    nullptr,
0565                                    createPlacement(boolSolid.rotation().matrix(), boolSolid.translation()));
0566           rSolid = new TGeoCompositeShape(iName.c_str(), boolS);
0567         }
0568         break;
0569       }
0570       case DDSolidShape::ddellipticaltube: {
0571         DDEllipticalTube eSolid(iSolid);
0572         if (!eSolid) {
0573           throw cms::Exception("GeomConvert") << "conversion to DDEllipticalTube failed";
0574         }
0575         rSolid = new TGeoEltu(iName.c_str(), params[0] / cm, params[1] / cm, params[2] / cm);
0576         break;
0577       }
0578       default:
0579         break;
0580     }
0581     nameToShape_[iName] = rSolid;
0582   }
0583   if (rSolid == nullptr) {
0584     edm::LogError("TGeoMgrFromDdd") << "COULD NOT MAKE " << iName << " of a shape " << iSolid;
0585   }
0586 
0587   edm::LogVerbatim("TGeoMgrFromDdd") << "solid " << iName << " has been created.";
0588 
0589   return rSolid;
0590 }
0591 
0592 TGeoVolume* TGeoMgrFromDdd::createVolume(const std::string& iName, const DDSolid& iSolid, const DDMaterial& iMaterial) {
0593   edm::LogVerbatim("TGeoMgrFromDdd") << "createVolume with name: " << iName
0594                                      << " and solid: " << iSolid.name().fullname() << " and material "
0595                                      << iMaterial.name().fullname();
0596   TGeoVolume* v = nameToVolume_[iName];
0597   if (v == nullptr) {
0598     TGeoShape* solid =
0599         m_fullname ? createShape(iSolid.name().fullname(), iSolid) : createShape(iSolid.name().name(), iSolid);
0600     std::string mat_name = m_fullname ? iMaterial.name().fullname() : iMaterial.name().name();
0601     TGeoMedium* geo_med = nameToMedium_[mat_name];
0602     if (geo_med == nullptr) {
0603       TGeoMaterial* geo_mat = createMaterial(iMaterial);
0604       geo_med = new TGeoMedium(mat_name.c_str(), 0, geo_mat);
0605       nameToMedium_[mat_name] = geo_med;
0606     }
0607     if (solid) {
0608       v = new TGeoVolume(iName.c_str(), solid, geo_med);
0609     }
0610     nameToVolume_[iName] = v;
0611   }
0612   return v;
0613 }
0614 
0615 TGeoMaterial* TGeoMgrFromDdd::createMaterial(const DDMaterial& iMaterial) {
0616   std::string mat_name = m_fullname ? iMaterial.name().fullname() : iMaterial.name().name();
0617   edm::LogVerbatim("TGeoMgrFromDdd") << "createMateriale with name: " << mat_name;
0618   TGeoMaterial* mat = nameToMaterial_[mat_name];
0619 
0620   if (mat == nullptr) {
0621     if (iMaterial.noOfConstituents() > 0) {
0622       TGeoMixture* mix = new TGeoMixture(mat_name.c_str(), iMaterial.noOfConstituents(), iMaterial.density() * cm3 / g);
0623       for (int i = 0; i < iMaterial.noOfConstituents(); ++i) {
0624         mix->AddElement(createMaterial(iMaterial.constituent(i).first), iMaterial.constituent(i).second);
0625       }
0626       mat = mix;
0627     } else {
0628       mat = new TGeoMaterial(mat_name.c_str(), iMaterial.a() * mole / g, iMaterial.z(), iMaterial.density() * cm3 / g);
0629     }
0630     nameToMaterial_[mat_name] = mat;
0631   }
0632 
0633   return mat;
0634 }
0635 
0636 //
0637 // const member functions
0638 //
0639 
0640 //
0641 // static member functions
0642 //
0643 DEFINE_FWK_EVENTSETUP_MODULE(TGeoMgrFromDdd);