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