29 #include "TGeoManager.h"
30 #include "TGeoMatrix.h"
31 #include "TGeoCompositeShape.h"
35 #include "TGeoBoolNode.h"
39 #include "TGeoTorus.h"
43 #include "Math/GenVector/RotationX.h"
44 #include "Math/GenVector/RotationZ.h"
46 #include "CLHEP/Units/GlobalSystemOfUnits.h"
91 : m_level(pset.getUntrackedParameter<int>(
"level")),
92 m_verbose(pset.getUntrackedParameter<bool>(
"verbose")),
93 m_fullname(pset.getUntrackedParameter<bool>(
"fullName")),
94 viewToken_(setWhatProduced(this).consumes()) {}
98 desc.
addUntracked<
int>(
"level", 10)->setComment(
"How deep into the geometry hierarchy should the conversion go.");
100 desc.
addUntracked<
bool>(
"fullName",
true)->setComment(
"use fillname() instead of name() when generating node names");
102 conf.
add(
"TGeoMgrFromDdd", desc);
112 iRot.GetComponents(elements);
114 r.SetMatrix(elements);
116 TGeoTranslation
t(iTrans.x() / cm, iTrans.y() / cm, iTrans.z() / cm);
118 return new TGeoCombiTrans(
t, r);
131 if (!viewH.isValid()) {
132 return std::unique_ptr<TGeoManager>();
135 TGeoManager* geo_mgr =
new TGeoManager(
"cmsGeo",
"CMS Detector");
137 if (gGeoIdentity ==
nullptr) {
138 gGeoIdentity =
new TGeoIdentity(
"Identity");
141 std::cout <<
"about to initialize the DDCompactView walker"
142 <<
" with a root node " << viewH->root() << std::endl;
144 auto walker = viewH->walker();
145 auto info = walker.current();
150 if (!walker.firstChild()) {
151 return std::unique_ptr<TGeoManager>();
157 if (top ==
nullptr) {
158 return std::unique_ptr<TGeoManager>();
161 geo_mgr->SetTopVolume(top);
163 top->SetVisibility(kFALSE);
164 top->SetLineColor(kBlue);
166 std::vector<TGeoVolume*> parentStack;
167 parentStack.push_back(top);
170 auto info = walker.current();
173 std::cout <<
"parentStack of size " << parentStack.size() << std::endl;
174 auto num = (
info.second !=
nullptr) ?
info.second->copyno() : 0;
182 if (
nullptr != child &&
info.second !=
nullptr) {
183 parentStack.back()->AddNode(
185 child->SetLineColor(kBlue);
187 if (
info.second ==
nullptr) {
191 if (
nullptr == child || childAlreadyExists ||
m_level ==
int(parentStack.size())) {
192 if (
nullptr != child) {
193 child->SetLineColor(kRed);
196 if (!walker.nextSibling()) {
197 while (walker.parent()) {
198 parentStack.pop_back();
199 if (walker.nextSibling()) {
205 if (walker.firstChild()) {
206 parentStack.push_back(child);
208 if (!walker.nextSibling()) {
209 while (walker.parent()) {
210 parentStack.pop_back();
211 if (walker.nextSibling()) {
218 }
while (!parentStack.empty());
220 geo_mgr->CloseGeometry();
222 geo_mgr->DefaultColors();
229 return std::unique_ptr<TGeoManager>(geo_mgr);
237 edm::LogVerbatim(
"TGeoMgrFromDdd") <<
"with name: " << iName <<
" and solid: " << iSolid;
241 throw cms::Exception(
"TGeoMgrFromDdd::createShape * solid " + iName +
" is not declared * ");
243 throw cms::Exception(
"TGeoMgrFromDdd::createShape * solid " + defined.first->name() +
" is not defined *");
246 if (rSolid ==
nullptr) {
247 const std::vector<double>&
params = iSolid.parameters();
248 switch (iSolid.shape()) {
250 rSolid =
new TGeoBBox(iName.c_str(), params[0] / cm, params[1] / cm, params[2] / cm);
253 rSolid =
new TGeoConeSeg(iName.c_str(),
260 params[6] / deg + params[5] / deg);
264 rSolid =
new TGeoTubeSeg(iName.c_str(),
269 params[3] / deg + params[4] / deg);
273 rSolid =
new TGeoCtub(iName.c_str(),
278 params[3] / deg + params[4] / deg,
287 rSolid =
new TGeoTrap(iName.c_str(),
301 rSolid =
new TGeoPcon(iName.c_str(), params[0] / deg, params[1] / deg, (params.size() - 2) / 3);
303 std::vector<double>
temp(params.size() + 1);
304 temp.reserve(params.size() + 1);
305 temp[0] = params[0] / deg;
306 temp[1] = params[1] / deg;
307 temp[2] = (params.size() - 2) / 3;
308 std::copy(params.begin() + 2, params.end(),
temp.begin() + 3);
309 for (std::vector<double>::iterator it =
temp.begin() + 3; it !=
temp.end(); ++it) {
312 rSolid->SetDimensions(&(*(
temp.begin())));
316 rSolid =
new TGeoPgon(
317 iName.c_str(), params[1] / deg, params[2] / deg,
static_cast<int>(params[0]), (params.size() - 3) / 3);
319 std::vector<double>
temp(params.size() + 1);
320 temp[0] = params[1] / deg;
321 temp[1] = params[2] / deg;
323 temp[3] = (params.size() - 3) / 3;
324 std::copy(params.begin() + 3, params.end(), temp.begin() + 4);
325 for (std::vector<double>::iterator it = temp.begin() + 4; it != temp.end(); ++it) {
328 rSolid->SetDimensions(&(*(temp.begin())));
333 std::vector<double>
x = extrPgon.
xVec();
334 std::transform(x.begin(), x.end(), x.begin(), [](
double d) {
return d / cm; });
335 std::vector<double>
y = extrPgon.
yVec();
336 std::transform(y.begin(), y.end(), y.begin(), [](
double d) {
return d / cm; });
337 std::vector<double>
z = extrPgon.
zVec();
338 std::vector<double> zx = extrPgon.
zxVec();
339 std::vector<double> zy = extrPgon.
zyVec();
340 std::vector<double> zscale = extrPgon.
zscaleVec();
342 TGeoXtru* mySolid =
new TGeoXtru(z.size());
343 mySolid->DefinePolygon(x.size(), &(*x.begin()), &(*y.begin()));
344 for (
size_t i = 0;
i < params[0]; ++
i) {
345 mySolid->DefineSection(
i, z[
i] / cm, zx[
i] / cm, zy[
i] / cm, zscale[
i]);
359 bool intersec =
false;
366 double halfOpeningAngle = asin(x /
std::abs(r)) / deg;
367 double displacement = 0;
376 h = pt.
y1() < pt.
y2() ? pt.
y2() : pt.
y1();
380 startPhi = 90. - halfOpeningAngle;
383 startPhi = -90. - halfOpeningAngle;
385 }
else if (r > 0 &&
std::abs(r) >= x) {
388 startPhi = 270. - halfOpeningAngle;
392 startPhi = 90. - halfOpeningAngle;
396 throw cms::Exception(
"Check parameters of the PseudoTrap! name=" + name);
399 std::unique_ptr<TGeoShape> trap(
400 new TGeoTrd2(name.c_str(), pt.
x1() / cm, pt.
x2() / cm, pt.
y1() / cm, pt.
y2() / cm, pt.
halfZ() / cm));
402 std::unique_ptr<TGeoShape> tubs(
new TGeoTubeSeg(name.c_str(),
407 startPhi + halfOpeningAngle * 2.));
409 TGeoSubtraction* sub =
new TGeoSubtraction(
411 rSolid =
new TGeoCompositeShape(iName.c_str(), sub);
413 std::unique_ptr<TGeoShape> box(
new TGeoBBox(1.1 * x / cm, 1.1 * h / cm,
sqrt(r * r - x * x) / cm));
415 TGeoSubtraction* sub =
new TGeoSubtraction(
418 std::unique_ptr<TGeoShape> tubicCap(
new TGeoCompositeShape(iName.c_str(), sub));
420 TGeoUnion* boolS =
new TGeoUnion(
423 rSolid =
new TGeoCompositeShape(iName.c_str(), boolS);
430 rSolid =
new TGeoTorus(iName.c_str(),
441 throw cms::Exception(
"GeomConvert") <<
"conversion to DDBooleanSolid failed";
448 if (
nullptr != left.get() &&
nullptr != right.get()) {
449 TGeoSubtraction* sub =
450 new TGeoSubtraction(left.release(),
454 rSolid =
new TGeoCompositeShape(iName.c_str(), sub);
461 throw cms::Exception(
"GeomConvert") <<
"conversion to DDTruncTubs failed";
463 double rIn(tt.
rIn());
464 double rOut(tt.
rOut());
465 double zHalf(tt.
zHalf());
474 if (rIn <= 0 || rOut <= 0 || cutAtStart <= 0 || cutAtDelta <= 0) {
475 std::string s =
"TruncTubs " + name +
": 0 <= rIn,cutAtStart,rOut,cutAtDelta,rOut violated!";
479 std::string s =
"TruncTubs " + name +
": rIn<rOut violated!";
482 if (startPhi != 0.) {
483 std::string s =
"TruncTubs " + name +
": startPhi != 0 not supported!";
488 double r(cutAtStart);
489 double R(cutAtDelta);
492 std::unique_ptr<TGeoShape> tubs(
493 new TGeoTubeSeg(name.c_str(), rIn / cm, rOut / cm, zHalf / cm, startPhi,
deltaPhi / deg));
495 double boxX(rOut), boxY(rOut);
498 double boxZ(1.1 * zHalf);
503 double cos_alpha = cath / hypo;
504 double alpha = -acos(cos_alpha);
509 rot.RotateZ(alpha / deg);
514 xBox = r + boxX /
sin(fabs(alpha));
516 xBox = -(boxX /
sin(fabs(alpha)) -
r);
518 std::unique_ptr<TGeoShape> box(
new TGeoBBox(name.c_str(), boxX / cm, boxZ / cm, boxY / cm));
520 TGeoTranslation trans(xBox / cm, 0., 0.);
522 TGeoSubtraction* sub =
523 new TGeoSubtraction(tubs.release(), box.release(),
nullptr,
new TGeoCombiTrans(trans, rot));
525 rSolid =
new TGeoCompositeShape(iName.c_str(), sub);
531 throw cms::Exception(
"GeomConvert") <<
"conversion to DDBooleanSolid failed";
540 if (
nullptr != left.get() &&
nullptr != right.get()) {
541 TGeoUnion* boolS =
new TGeoUnion(left.release(),
545 rSolid =
new TGeoCompositeShape(iName.c_str(), boolS);
552 throw cms::Exception(
"GeomConvert") <<
"conversion to DDBooleanSolid failed";
559 if (
nullptr != left.get() &&
nullptr != right.get()) {
560 TGeoIntersection* boolS =
561 new TGeoIntersection(left.release(),
565 rSolid =
new TGeoCompositeShape(iName.c_str(), boolS);
572 throw cms::Exception(
"GeomConvert") <<
"conversion to DDEllipticalTube failed";
574 rSolid =
new TGeoEltu(iName.c_str(), params[0] / cm, params[1] / cm, params[2] / cm);
582 if (rSolid ==
nullptr) {
583 edm::LogError(
"TGeoMgrFromDdd") <<
"COULD NOT MAKE " << iName <<
" of a shape " << iSolid;
586 edm::LogVerbatim(
"TGeoMgrFromDdd") <<
"solid " << iName <<
" has been created.";
598 if (geo_med ==
nullptr) {
600 geo_med =
new TGeoMedium(mat_name.c_str(), 0, geo_mat);
604 v =
new TGeoVolume(iName.c_str(), solid, geo_med);
615 if (mat ==
nullptr) {
623 mat =
new TGeoMaterial(mat_name.c_str(), iMaterial.
a() * mole /
g, iMaterial.
z(), iMaterial.
density() * cm3 /
g);
Log< level::Info, true > LogVerbatim
double a() const
returns the atomic mass
double cutAtStart(void) const
truncation at begin of the tube-section
TGeoMaterial * createMaterial(const DDMaterial &iMaterial)
bool cutInside(void) const
true, if truncation is on the inner side of the tube-section
A truncated tube section.
double zHalf(void) const
half of the z-Axis
double y2(void) const
half length along y on +z
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
double deltaPhi(void) const
angular span of the tube-section
DDMaterial is used to define and access material information.
const TGeoMgrFromDdd & operator=(const TGeoMgrFromDdd &)=delete
std::unique_ptr< TGeoManager > ReturnType
m_verbose(ps.getUntrackedParameter< bool >("verbose"))
Sin< T >::type sin(const T &t)
double rTorus(void) const
double cutAtDelta(void) const
truncation at end of the tube-section
std::vector< double > yVec(void) const
double rIn(void) const
inner radius
ESTransientHandle< ProductT > getTransientHandle(ESGetToken< ProductT, DepRecordT > const &iToken) const
std::vector< double > zyVec(void) const
DDTranslation translation(void) const
Log< level::Error, false > LogError
TGeoCombiTrans * createPlacement(const Rotation3D &iRot, const Position &iTrans)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
A DDSolid represents the shape of a part.
double y1(void) const
half length along y on -z
DDSolid solidB(void) const
std::vector< double > xVec(void) const
double z() const
retruns the atomic number
const edm::ESGetToken< DDCompactView, IdealGeometryRecord > viewToken_
static const char *const name(DDSolidShape s)
DDRotation rotation(void) const
ROOT::Math::Rotation3D DDRotationMatrix
A DDRotationMatrix is currently implemented with a ROOT Rotation3D.
TGeoVolume * createVolume(const std::string &iName, const DDSolid &iSolid, const DDMaterial &iMaterial)
bool atMinusZ(void) const
true, if cut-out or rounding is on the -z side
double halfZ(void) const
half of the z-Axis
Cos< T >::type cos(const T &t)
std::map< std::string, TGeoShape * > nameToShape_
const std::string fullname() const
FractionV::value_type constituent(int i) const
returns the i-th compound material and its fraction-mass
Abs< T >::type abs(const T &t)
ReturnType produce(const DisplayGeomRecord &)
TGeoShape * createShape(const std::string &iName, const DDSolid &iSolid)
DDSolid solidA(void) const
TGeoMgrFromDdd(const edm::ParameterSet &)
double startPhi(void) const
std::vector< double > zVec(void) const
std::vector< double > zxVec(void) const
std::map< std::string, TGeoMaterial * > nameToMaterial_
double density() const
returns the density
double deltaPhi(void) const
std::map< std::string, TGeoVolume * > nameToVolume_
int noOfConstituents() const
returns the number of compound materials or 0 for elementary materials
#define DEFINE_FWK_EVENTSETUP_MODULE(type)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
double startPhi(void) const
angular start of the tube-section
TGeoManager * createManager(int level)
std::map< std::string, TGeoMedium * > nameToMedium_
std::pair< const N *, bool > def_type
static void fillDescriptions(edm::ConfigurationDescriptions &)
double x2(void) const
half length along x on +z
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
double rOut(void) const
outer radius
std::vector< double > zscaleVec(void) const
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
const std::string & name() const
Returns the name.
double x1(void) const
half length along x on -z
DDRotationMatrix & matrix()
double radius(void) const
radius of the cut-out (neg.) or rounding (pos.)