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