File indexing completed on 2022-04-22 22:55:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
0058
0059
0060
0061
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
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
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 }
0121
0122
0123
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
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
0148
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
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
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
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
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
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,
0290 params[1] / deg,
0291 params[2] / deg,
0292 params[3] / cm,
0293 params[4] / cm,
0294 params[5] / cm,
0295 params[6] / deg,
0296 params[7] / cm,
0297 params[8] / cm,
0298 params[9] / cm,
0299 params[10] / deg);
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
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;
0361
0362 if (atMinusZ) {
0363 x = pt.x1();
0364 } else {
0365 x = pt.x2();
0366 }
0367 double halfOpeningAngle = asin(x / std::abs(r)) / deg;
0368 double displacement = 0;
0369 double startPhi = 0;
0370
0371
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;
0377 h = pt.y1() < pt.y2() ? pt.y2() : pt.y1();
0378 h += h / 20.;
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,
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
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
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);
0497
0498
0499 double boxZ(1.1 * zHalf);
0500
0501
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
0508 TGeoRotation rot;
0509 rot.RotateX(90);
0510 rot.RotateZ(alpha / deg);
0511
0512
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
0540
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
0638
0639
0640
0641
0642
0643 DEFINE_FWK_EVENTSETUP_MODULE(TGeoMgrFromDdd);