diff --git a/DetectorDescription/DDCMS/data/testLogicalParts.xml b/DetectorDescription/DDCMS/data/testLogicalParts.xml
index e8133e05ff5bf..4429013c67077 100644
--- a/DetectorDescription/DDCMS/data/testLogicalParts.xml
+++ b/DetectorDescription/DDCMS/data/testLogicalParts.xml
@@ -126,7 +126,14 @@
-
+
+
+
+
+
+
+
+
diff --git a/DetectorDescription/DDCMS/data/testPosParts.xml b/DetectorDescription/DDCMS/data/testPosParts.xml
index 1b97f9814c6ee..26b4e63122198 100644
--- a/DetectorDescription/DDCMS/data/testPosParts.xml
+++ b/DetectorDescription/DDCMS/data/testPosParts.xml
@@ -184,5 +184,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DetectorDescription/DDCMS/data/testSolids.xml b/DetectorDescription/DDCMS/data/testSolids.xml
index 4813d6bc8cabd..6511a25c7104d 100644
--- a/DetectorDescription/DDCMS/data/testSolids.xml
+++ b/DetectorDescription/DDCMS/data/testSolids.xml
@@ -57,6 +57,8 @@
+
+
diff --git a/DetectorDescription/DDCMS/interface/DDDetector.h b/DetectorDescription/DDCMS/interface/DDDetector.h
index b1b8ec26125c7..8d6f49e8ed543 100644
--- a/DetectorDescription/DDCMS/interface/DDDetector.h
+++ b/DetectorDescription/DDCMS/interface/DDDetector.h
@@ -2,6 +2,7 @@
#define DetectorDescription_DDCMS_DDDetector_h
#include "DetectorDescription/DDCMS/interface/DDVectorRegistry.h"
+#include "DetectorDescription/DDCMS/interface/DDParsingContext.h"
#include
#include
#include
@@ -11,7 +12,7 @@ class TGeoManager;
namespace cms {
class DDDetector {
public:
- explicit DDDetector(const std::string&, const std::string&, bool bigXML = false);
+ explicit DDDetector(const std::string&, const std::string&, bool bigXML = false, bool makePayload = false);
DDDetector() = delete;
cms::DDVectorsMap const& vectors() const { return m_vectors; }
@@ -34,6 +35,8 @@ namespace cms {
dd4hep::Detector const* description() const { return m_description; }
+ DDParsingContext* m_context;
+
private:
void process(const std::string&);
void processXML(const std::string&);
diff --git a/DetectorDescription/DDCMS/interface/DDNamespace.h b/DetectorDescription/DDCMS/interface/DDNamespace.h
index ddadd38665444..8dadbefa6bf36 100644
--- a/DetectorDescription/DDCMS/interface/DDNamespace.h
+++ b/DetectorDescription/DDCMS/interface/DDNamespace.h
@@ -10,6 +10,12 @@
namespace cms {
+ namespace rotation_utils {
+ std::string rotHash(const Double_t* rot);
+ std::string rotHash(const dd4hep::Rotation3D& rot);
+ double roundBinary(double value);
+ } // namespace rotation_utils
+
class DDParsingContext;
using DDVectorsMap = std::unordered_map>;
@@ -57,9 +63,11 @@ namespace cms {
dd4hep::Solid addSolidNS(const std::string& name, dd4hep::Solid solid) const;
dd4hep::Assembly assembly(const std::string& name) const;
- dd4hep::Assembly addAssembly(dd4hep::Assembly asmb) const;
+ dd4hep::Assembly addAssembly(dd4hep::Assembly asmb, bool addSolid = true) const;
+ dd4hep::Assembly addAssemblySolid(dd4hep::Assembly assembly) const;
dd4hep::Volume volume(const std::string& name, bool exc = true) const;
+ dd4hep::Volume* getVolPtr(const std::string& name) const;
dd4hep::Volume addVolume(dd4hep::Volume vol) const;
dd4hep::Volume addVolumeNS(dd4hep::Volume vol) const;
diff --git a/DetectorDescription/DDCMS/interface/DDParsingContext.h b/DetectorDescription/DDCMS/interface/DDParsingContext.h
index d885a9efe36cd..ca95d16507f8b 100644
--- a/DetectorDescription/DDCMS/interface/DDParsingContext.h
+++ b/DetectorDescription/DDCMS/interface/DDParsingContext.h
@@ -6,22 +6,30 @@
#include
#include
#include
+#include
#include
namespace cms {
class DDParsingContext {
public:
- DDParsingContext(dd4hep::Detector& det) : description(det) {
+ DDParsingContext(dd4hep::Detector& det, bool makePayloadArg = false)
+ : makePayload(makePayloadArg), description(det) {
assemblies.reserve(100);
+ assemblySolids.reserve(100);
rotations.reserve(3000);
shapes.reserve(4000);
volumes.reserve(3000);
+ volPtrs.reserve(3000);
unresolvedMaterials.reserve(300);
unresolvedVectors.reserve(300);
unresolvedShapes.reserve(1000);
namespaces.emplace_back("");
+ if (makePayload) {
+ rotRevMap.reserve(3000);
+ allCompMaterials.reserve(400);
+ }
}
DDParsingContext() = delete;
@@ -64,16 +72,21 @@ namespace cms {
bool debug_namespaces = false;
bool debug_algorithms = false;
bool debug_specpars = false;
+ bool makePayload = false;
dd4hep::Detector& description;
std::unordered_map assemblies;
+ std::unordered_set assemblySolids;
std::unordered_map rotations;
+ std::unordered_map rotRevMap;
std::unordered_map shapes;
std::unordered_map volumes;
+ std::unordered_map volPtrs;
std::vector namespaces;
std::unordered_map> unresolvedMaterials;
+ std::unordered_map>> allCompMaterials;
std::unordered_map> unresolvedVectors;
std::unordered_map,
diff --git a/DetectorDescription/DDCMS/interface/DDSolidShapes.h b/DetectorDescription/DDCMS/interface/DDSolidShapes.h
index b101c795e7ab4..9db8af26f1d63 100644
--- a/DetectorDescription/DDCMS/interface/DDSolidShapes.h
+++ b/DetectorDescription/DDCMS/interface/DDSolidShapes.h
@@ -92,9 +92,11 @@ namespace cms {
ddcuttubs = 18,
ddextrudedpolygon = 19,
ddtrd1 = 20,
+ ddtrd2 = 21,
+ ddassembly = 22
};
- const std::array, 19> DDSolidShapeMap{
+ const std::array, 21> DDSolidShapeMap{
{{DDSolidShape::dd_not_init, "Solid not initialized"},
{DDSolidShape::ddbox, "Box"},
{DDSolidShape::ddtubs, "Tube"},
@@ -113,9 +115,11 @@ namespace cms {
{DDSolidShape::ddellipticaltube, "EllipticalTube"},
{DDSolidShape::ddcuttubs, "CutTube"},
{DDSolidShape::ddextrudedpolygon, "ExtrudedPolygon"},
- {DDSolidShape::ddtrd1, "Trd1"}}};
+ {DDSolidShape::ddtrd1, "Trd1"},
+ {DDSolidShape::ddtrd2, "Trd2"},
+ {DDSolidShape::ddassembly, "Assembly"}}};
- const std::array, 20> LegacySolidShapeMap{
+ const std::array, 21> LegacySolidShapeMap{
{{LegacySolidShape::dd_not_init, cms::DDSolidShape::dd_not_init},
{LegacySolidShape::ddbox, cms::DDSolidShape::ddbox},
{LegacySolidShape::ddtubs, cms::DDSolidShape::ddtubs},
@@ -135,7 +139,8 @@ namespace cms {
{LegacySolidShape::ddsphere, cms::DDSolidShape::ddsphere},
{LegacySolidShape::ddellipticaltube, cms::DDSolidShape::ddellipticaltube},
{LegacySolidShape::ddcuttubs, cms::DDSolidShape::ddcuttubs},
- {LegacySolidShape::ddextrudedpolygon, cms::DDSolidShape::ddextrudedpolygon}}};
+ {LegacySolidShape::ddextrudedpolygon, cms::DDSolidShape::ddextrudedpolygon},
+ {LegacySolidShape::ddassembly, cms::DDSolidShape::ddassembly}}};
} // namespace cms
diff --git a/DetectorDescription/DDCMS/plugins/DDDetectorESProducer.cc b/DetectorDescription/DDCMS/plugins/DDDetectorESProducer.cc
index a127205940127..9fff129717e2c 100644
--- a/DetectorDescription/DDCMS/plugins/DDDetectorESProducer.cc
+++ b/DetectorDescription/DDCMS/plugins/DDDetectorESProducer.cc
@@ -59,6 +59,7 @@ class DDDetectorESProducer : public ESProducer, public EventSetupRecordIntervalF
const string confGeomXMLFiles_;
const string rootDDName_;
const string label_;
+ const bool makePayload_;
edm::ESGetToken mfToken_;
edm::ESGetToken geomToken_;
};
@@ -68,7 +69,8 @@ DDDetectorESProducer::DDDetectorESProducer(const ParameterSet& iConfig)
appendToDataLabel_(iConfig.getParameter("appendToDataLabel")),
confGeomXMLFiles_(fromDB_ ? "none" : iConfig.getParameter("confGeomXMLFiles").fullPath()),
rootDDName_(iConfig.getParameter("rootDDName")),
- label_(iConfig.getParameter("label")) {
+ label_(iConfig.getParameter("label")),
+ makePayload_(iConfig.getParameter("makePayload")) {
usesResources({edm::ESSharedResourceNames::kDD4Hep});
if (rootDDName_ == "MagneticFieldVolumes:MAGF" || rootDDName_ == "cmsMagneticField:MAGF") {
auto c = setWhatProduced(this,
@@ -96,12 +98,14 @@ void DDDetectorESProducer::fillDescriptions(ConfigurationDescriptions& descripti
desc.add("rootDDName", "cms:OCMS");
desc.add("label", "");
desc.add("fromDB", false);
+ desc.add("makePayload", false);
descriptions.add("DDDetectorESProducer", desc);
edm::ParameterSetDescription descDB;
descDB.add("rootDDName", "cms:OCMS");
descDB.add("label", "Extended");
descDB.add("fromDB", true);
+ descDB.add("makePayload", false);
descriptions.add("DDDetectorESProducerFromDB", descDB);
}
@@ -131,13 +135,13 @@ DDDetectorESProducer::ReturnType DDDetectorESProducer::produceGeom(const IdealGe
return make_unique(label_, string(tb->begin(), tb->end()), true);
} else {
- return make_unique(appendToDataLabel_, confGeomXMLFiles_);
+ return make_unique(appendToDataLabel_, confGeomXMLFiles_, false, makePayload_);
}
}
DDDetectorESProducer::ReturnType DDDetectorESProducer::produce() {
LogVerbatim("Geometry") << "DDDetectorESProducer::Produce " << appendToDataLabel_;
- return make_unique(appendToDataLabel_, confGeomXMLFiles_);
+ return make_unique(appendToDataLabel_, confGeomXMLFiles_, false, makePayload_);
}
DEFINE_FWK_EVENTSETUP_SOURCE(DDDetectorESProducer);
diff --git a/DetectorDescription/DDCMS/plugins/dd4hep/DDDefinitions2Objects.cc b/DetectorDescription/DDCMS/plugins/dd4hep/DDDefinitions2Objects.cc
index fadc63983d531..fa3403c9b3923 100644
--- a/DetectorDescription/DDCMS/plugins/dd4hep/DDDefinitions2Objects.cc
+++ b/DetectorDescription/DDCMS/plugins/dd4hep/DDDefinitions2Objects.cc
@@ -29,6 +29,8 @@
#include
#include
+// #define EDM_ML_DEBUG 1
+
using namespace std;
using namespace dd4hep;
using namespace cms;
@@ -75,6 +77,7 @@ namespace dd4hep {
class SolidSection;
class DDLExtrudedPolygon;
class DDLShapeless;
+ class DDLAssembly;
class DDLTrapezoid;
class DDLEllipticalTube;
class DDLPseudoTrap;
@@ -202,6 +205,9 @@ namespace dd4hep {
/// Converter for tags
template <>
void Converter::operator()(xml_h element) const;
+ /// Converter for tags
+ template <>
+ void Converter::operator()(xml_h element) const;
/// Converter for tags
template <>
void Converter::operator()(xml_h element) const;
@@ -385,6 +391,9 @@ void Converter::operator()(xml_h element) const {
case hash("ShapelessSolid"):
Converter(description, ns.context(), optional)(solid);
break;
+ case hash("Assembly"):
+ Converter(description, ns.context(), optional)(solid);
+ break;
default:
throw std::runtime_error("Request to process unknown shape '" + xml_dim_t(solid).nameStr() + "' [" +
solid.tag() + "]");
@@ -600,6 +609,11 @@ void Converter::operator()(xml_h element) const {
double fraction = xfrac.fraction();
string fracname = ns.realName(xfrac_mat.nameStr());
+ if (ns.context()->makePayload) {
+ ns.context()->allCompMaterials[nam].first = density;
+ ns.context()->allCompMaterials[nam].second.emplace_back(
+ cms::DDParsingContext::CompositeMaterial(ns.prepend(fracname), fraction));
+ }
TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
if (frac_mat == nullptr) // Try to find it within this namespace
frac_mat = mgr.GetMaterial(ns.prepend(fracname).c_str());
@@ -791,6 +805,13 @@ void Converter::operator()(xml_h element) const {
string volName = ns.prepend(e.attr(_U(name)));
Solid solid = ns.solid(sol);
Material material = ns.material(mat);
+ if (ns.context()->assemblySolids.count(sol) == 1) {
+ // To match the general paradigm, an assembly starts as a solid,
+ // and then a logical part is made of the solid. However, the
+ // solid is just a dummy whose names tags it as an assembly.
+ ns.addAssembly(volName, false);
+ return;
+ }
#ifdef EDM_ML_DEBUG
Volume volume =
@@ -848,6 +869,55 @@ void Converter::operator()(xml_h element) const {
*tr = Transform3D(rot, pos);
}
+static void placeAssembly(Volume* parentPtr,
+ const string& parentName,
+ Volume* childPtr,
+ const string& childName,
+ int copy,
+ const Transform3D& transform,
+ cms::DDNamespace& ns) {
+#ifdef EDM_ML_DEBUG
+
+ printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
+ "DD4CMS",
+ "+++ Parent vol: %-24s Child: %-32s, copy:%d",
+ parentName.c_str(),
+ childName.c_str(),
+ copy);
+
+#endif
+
+ TGeoShape* shape = (*childPtr)->GetShape();
+ // Need to fix the daughter's BBox of assemblies, if the BBox was not calculated....
+ if (shape->IsA() == TGeoShapeAssembly::Class()) {
+ TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
+ if (std::fabs(as->GetDX()) < numeric_limits::epsilon() &&
+ std::fabs(as->GetDY()) < numeric_limits::epsilon() &&
+ std::fabs(as->GetDZ()) < numeric_limits::epsilon()) {
+ as->NeedsBBoxRecompute();
+ as->ComputeBBox();
+ }
+ }
+ TGeoNode* n;
+ TString nam_id = TString::Format("%s_%d", (*childPtr)->GetName(), copy);
+ n = static_cast((*parentPtr)->GetNode(nam_id));
+ if (n != nullptr) {
+ printout(ERROR, "PlacedVolume", "++ Attempt to add already existing node %s", (const char*)nam_id);
+ return;
+ }
+
+ PlacedVolume pv;
+ if ((*childPtr)->IsAssembly()) {
+ pv = parentPtr->placeVolume(ns.assembly(childName), copy, transform);
+ } else {
+ pv = parentPtr->placeVolume(*childPtr, copy, transform);
+ }
+
+ if (!pv.isValid()) {
+ printout(ERROR, "DD4CMS", "+++ Placement FAILED! Parent:%s Child:%s", parentName.c_str(), childName.c_str());
+ }
+}
+
/// Converter for tags
template <>
void Converter::operator()(xml_h element) const {
@@ -856,8 +926,13 @@ void Converter::operator()(xml_h element) const {
int copy = e.attr(DD_CMU(copyNumber));
string parentName = ns.prepend(ns.attr(e.child(DD_CMU(rParent)), _U(name)));
string childName = ns.prepend(ns.attr(e.child(DD_CMU(rChild)), _U(name)));
+ Transform3D transform;
+ Converter(description, param, &transform)(element);
+
Volume parent = ns.volume(parentName, false);
Volume child = ns.volume(childName, false);
+ Volume* parentPtr = ns.getVolPtr(parentName);
+ Volume* childPtr = ns.getVolPtr(childName);
#ifdef EDM_ML_DEBUG
@@ -875,11 +950,26 @@ void Converter::operator()(xml_h element) const {
if (!parent.isValid() && strchr(parentName.c_str(), NAMESPACE_SEP) == nullptr)
parentName = ns.prepend(parentName);
- parent = ns.volume(parentName);
+ parent = ns.volume(parentName, false);
+ if (parentPtr == nullptr)
+ parentPtr = ns.getVolPtr(parentName);
+ if (!parent.isValid() && parentPtr == nullptr)
+ throw runtime_error("Unknown volume identifier:" + parentName);
if (!child.isValid() && strchr(childName.c_str(), NAMESPACE_SEP) == nullptr)
childName = ns.prepend(childName);
child = ns.volume(childName, false);
+ if (childPtr == nullptr)
+ childPtr = ns.getVolPtr(childName);
+ if (childPtr != nullptr && parentPtr != nullptr && ((*parentPtr)->IsAssembly() || (*childPtr)->IsAssembly())) {
+ printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
+ "DD4CMS",
+ "***** Placing assembly parent %s, child %s",
+ parentName.c_str(),
+ childName.c_str());
+ placeAssembly(parentPtr, parentName, childPtr, childName, copy, transform, ns);
+ return;
+ }
#ifdef EDM_ML_DEBUG
@@ -897,9 +987,6 @@ void Converter::operator()(xml_h element) const {
PlacedVolume pv;
if (child.isValid()) {
- Transform3D transform;
- Converter(description, param, &transform)(element);
-
// FIXME: workaround for Reflection rotation
// copy from DDCore/src/Volumes.cpp to replace
// static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, int id, TGeoMatrix* transform)
@@ -924,7 +1011,7 @@ void Converter::operator()(xml_h element) const {
TString nam_id = TString::Format("%s_%d", child->GetName(), copy);
n = static_cast(parent->GetNode(nam_id));
if (n != nullptr) {
- printout(ERROR, "PlacedVolume", "++ Attempt to add already exiting node %s", (const char*)nam_id);
+ printout(ERROR, "PlacedVolume", "++ Attempt to add already existing node %s", (const char*)nam_id);
}
Rotation3D rot(transform.Rotation());
@@ -1609,7 +1696,7 @@ void Converter::operator()(xml_h element) const {
printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
"DD4CMS",
- "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Assembly%s",
+ "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Shapeless: %s",
nam.c_str());
#endif
@@ -1617,6 +1704,22 @@ void Converter::operator()(xml_h element) const {
ns.addSolid(nam, Box(1, 1, 1));
}
+/// Converter for tags
+template <>
+void Converter::operator()(xml_h element) const {
+ cms::DDNamespace ns(_param());
+ xml_dim_t e(element);
+ string nam = e.nameStr();
+
+#ifdef EDM_ML_DEBUG
+ printout(
+ ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS", "+ Assembly: Adding solid -> Assembly: %s", nam.c_str());
+#endif
+
+ ns.addSolid(nam, Box(nam, 1, 1, 1)); // Add a dummy solid to allow assembly to be treated like other volumes
+ ns.addAssemblySolid(nam);
+}
+
/// Converter for tags
template <>
void Converter::operator()(xml_h element) const {
@@ -1760,6 +1863,9 @@ void Converter::operator()(xml_h element) const {
Volume child = parent.divide(childName, static_cast(axesmap.at(axis)), numCopies, startInDeg, widthInDeg);
ns.context()->volumes[childName] = child;
+ // ns.context()->volPtrs[childName] = &(ns.context()->volumes[childName]);
+ // TGeoVolumeMulti objects not needed in volPtrs list, and they cause
+ // crash when IsAssembly() method is called on them.
#ifdef EDM_ML_DEBUG
@@ -1795,6 +1901,7 @@ void Converter::operator()(xml_h element) const {
Volume child = parent.divide(childName, static_cast(axesmap.at(axis)), nReplicas, -dy + offset + width, width);
ns.context()->volumes[childName] = child;
+ // ns.context()->volPtrs[childName] = &(ns.context()->volumes[childName]);
#ifdef EDM_ML_DEBUG
@@ -1809,7 +1916,6 @@ void Converter::operator()(xml_h element) const {
child->IsVolumeMulti() ? "YES" : "NO");
#endif
-
} else {
printout(ERROR, "DD4CMS", "++ FAILED Division of a %s is not implemented yet!", parent.solid().type());
}
@@ -2054,7 +2160,7 @@ void Converter::operator()(xml_h element) const {
static long load_dddefinition(Detector& det, xml_h element) {
xml_elt_t dddef(element);
if (dddef) {
- cms::DDParsingContext context(det);
+ cms::DDParsingContext& context = *det.extension();
cms::DDNamespace ns(context);
ns.addConstantNS("world_x", "101*m", "number");
ns.addConstantNS("world_y", "101*m", "number");
diff --git a/DetectorDescription/DDCMS/src/DDDetector.cc b/DetectorDescription/DDCMS/src/DDDetector.cc
index f9f97890e50bf..159f081d868cf 100644
--- a/DetectorDescription/DDCMS/src/DDDetector.cc
+++ b/DetectorDescription/DDCMS/src/DDDetector.cc
@@ -10,7 +10,8 @@
namespace cms {
- DDDetector::DDDetector(const std::string& tag, const std::string& fileName, bool bigXML) : m_tag(tag) {
+ DDDetector::DDDetector(const std::string& tag, const std::string& fileName, bool bigXML, bool makePayload)
+ : m_tag(tag) {
//We do not want to use any previously created TGeoManager but we do want to reset after we are done.
auto oldGeoManager = gGeoManager;
gGeoManager = nullptr;
@@ -19,6 +20,8 @@ namespace cms {
m_description = &dd4hep::Detector::getInstance(tag);
m_description->addExtension(&m_vectors);
+ m_context = new cms::DDParsingContext(*m_description, makePayload);
+ m_description->addExtension(m_context);
m_description->addExtension(&m_partsels);
m_description->addExtension(&m_specpars);
m_description->setStdConditions("NTP");
@@ -27,6 +30,8 @@ namespace cms {
processXML(fileName);
else
process(fileName);
+ if (makePayload == false) // context no longer needed if not making payloads
+ m_description->removeExtension();
}
void DDDetector::process(const std::string& fileName) {
@@ -38,6 +43,7 @@ namespace cms {
void DDDetector::processXML(const std::string& xml) {
edm::LogVerbatim("Geometry") << "DDDetector::processXML process string size " << xml.size() << " with max_size "
<< xml.max_size();
+ edm::LogVerbatim("Geometry") << "DDDetector::processXML XML string contents = " << xml.substr(0, 800);
std::string name("DD4hep_XMLProcessor");
dd4hep::xml::DocumentHolder doc(dd4hep::xml::DocumentHandler().parse(xml.c_str(), xml.length()));
diff --git a/DetectorDescription/DDCMS/src/DDFilteredView.cc b/DetectorDescription/DDCMS/src/DDFilteredView.cc
index d3b1726d9b37c..dcb2a0938f1ba 100644
--- a/DetectorDescription/DDCMS/src/DDFilteredView.cc
+++ b/DetectorDescription/DDCMS/src/DDFilteredView.cc
@@ -552,6 +552,9 @@ const std::vector DDFilteredView::parameters() const {
const cms::DDSolidShape DDFilteredView::shape() const {
assert(node_);
+ if ((volume().volume())->IsAssembly()) {
+ return (cms::DDSolidShape::ddbox); // Return dummy box
+ }
return cms::dd::value(cms::DDSolidShapeMap, std::string(node_->GetVolume()->GetShape()->GetTitle()));
}
@@ -859,7 +862,13 @@ std::string_view DDFilteredView::fullName() const {
return (node_ == nullptr ? std::string_view() : (volume().volume().name()));
}
-dd4hep::Solid DDFilteredView::solid() const { return (volume().volume().solid()); }
+dd4hep::Solid DDFilteredView::solid() const {
+ if ((volume().volume())->IsAssembly()) {
+ std::string solName(name());
+ return (dd4hep::Box(solName, 1., 1., 1.));
+ }
+ return (volume().volume().solid());
+}
unsigned short DDFilteredView::copyNum() const { return (volume().copyNumber()); }
diff --git a/DetectorDescription/DDCMS/src/DDNamespace.cc b/DetectorDescription/DDCMS/src/DDNamespace.cc
index 4628633f94895..a780974126d20 100644
--- a/DetectorDescription/DDCMS/src/DDNamespace.cc
+++ b/DetectorDescription/DDCMS/src/DDNamespace.cc
@@ -1,5 +1,6 @@
#include "DetectorDescription/DDCMS/interface/DDNamespace.h"
#include "DetectorDescription/DDCMS/interface/DDParsingContext.h"
+#include "DataFormats/Math/interface/Rounding.h"
#include "DD4hep/Path.h"
#include "DD4hep/Printout.h"
#include "XML/XML.h"
@@ -11,6 +12,35 @@
using namespace std;
using namespace cms;
+double cms::rotation_utils::roundBinary(double value) {
+ value = cms_rounding::roundIfNear0(value);
+ static constexpr double roundingVal = 1 << 14;
+ value = (round(value * roundingVal) / roundingVal);
+ // Set -0 to 0
+ return (cms_rounding::roundIfNear0(value));
+}
+
+std::string cms::rotation_utils::rotHash(const Double_t* rot) {
+ std::string hashVal;
+ for (int row = 0; row <= 2; ++row) {
+ for (int col = 0; col <= 2; ++col) {
+ hashVal += std::to_string(roundBinary(rot[(3 * row) + col]));
+ }
+ }
+ return (hashVal);
+}
+
+std::string cms::rotation_utils::rotHash(const dd4hep::Rotation3D& rot) {
+ std::string hashVal;
+ std::vector matrix;
+ matrix.assign(9, 0.);
+ rot.GetComponents(matrix.begin());
+ for (double val : matrix) {
+ hashVal += std::to_string(roundBinary(val));
+ }
+ return (hashVal);
+}
+
DDNamespace::DDNamespace(DDParsingContext* context, xml_h element) : m_context(context) {
dd4hep::Path path(xml_handler_t::system_path(element));
m_name = path.filename().substr(0, path.filename().rfind('.'));
@@ -120,6 +150,10 @@ dd4hep::Material DDNamespace::material(const string& name) const {
void DDNamespace::addRotation(const string& name, const dd4hep::Rotation3D& rot) const {
string n = prepend(name);
m_context->rotations[n] = rot;
+ if (m_context->makePayload) {
+ string hashVal = cms::rotation_utils::rotHash(rot);
+ m_context->rotRevMap[hashVal] = n;
+ }
}
const dd4hep::Rotation3D& DDNamespace::rotation(const string& name) const {
@@ -148,6 +182,7 @@ dd4hep::Volume DDNamespace::addVolumeNS(dd4hep::Volume vol) const {
dd4hep::Material m = vol.material();
vol->SetName(n.c_str());
m_context->volumes[n] = vol;
+ m_context->volPtrs[n] = &(m_context->volumes[n]);
const char* solidName = "Invalid solid";
if (s.isValid()) // Protect against seg fault
solidName = s.name(); // If Solid is not valid, s.name() will seg fault.
@@ -161,12 +196,12 @@ dd4hep::Volume DDNamespace::addVolumeNS(dd4hep::Volume vol) const {
return vol;
}
-/// Add rotation matrix to current namespace
dd4hep::Volume DDNamespace::addVolume(dd4hep::Volume vol) const {
string n = prepend(vol.name());
dd4hep::Solid s = vol.solid();
dd4hep::Material m = vol.material();
m_context->volumes[n] = vol;
+ m_context->volPtrs[n] = &(m_context->volumes[n]);
const char* solidName = "Invalid solid";
if (s.isValid()) // Protect against seg fault
solidName = s.name(); // If Solid is not valid, s.name() will seg fault.
@@ -181,11 +216,23 @@ dd4hep::Volume DDNamespace::addVolume(dd4hep::Volume vol) const {
return vol;
}
-dd4hep::Assembly DDNamespace::addAssembly(dd4hep::Assembly assembly) const {
+dd4hep::Assembly DDNamespace::addAssembly(dd4hep::Assembly assembly, bool addSolid) const {
string n = assembly.name();
m_context->assemblies[n] = assembly;
+ m_context->volPtrs[n] = &(m_context->assemblies[n]);
+ if (addSolid) { // In algorithms, Assembly solids are not added separately, so add it here
+ m_context->assemblySolids.emplace(n);
+ }
+ dd4hep::printout(
+ m_context->debug_volumes ? dd4hep::ALWAYS : dd4hep::DEBUG, "DD4CMS", "+++ Add assembly: %-38s", n.c_str());
+ return assembly;
+}
+
+dd4hep::Assembly DDNamespace::addAssemblySolid(dd4hep::Assembly assembly) const {
+ string n = prepend(assembly.name());
+ m_context->assemblySolids.emplace(n);
dd4hep::printout(
- m_context->debug_volumes ? dd4hep::ALWAYS : dd4hep::DEBUG, "DD4CMS", "+++ Add assembly:%-38s", assembly.name());
+ m_context->debug_volumes ? dd4hep::ALWAYS : dd4hep::DEBUG, "DD4CMS", "+++ Add assembly solid: %-38s", n.c_str());
return assembly;
}
@@ -218,6 +265,19 @@ dd4hep::Volume DDNamespace::volume(const string& name, bool exc) const {
return nullptr;
}
+dd4hep::Volume* DDNamespace::getVolPtr(const string& name) const {
+ auto i = m_context->volPtrs.find(name);
+ if (i != m_context->volPtrs.end()) {
+ return (*i).second;
+ }
+ if (name.front() == NAMESPACE_SEP) {
+ i = m_context->volPtrs.find(name.substr(1, name.size()));
+ if (i != m_context->volPtrs.end())
+ return (*i).second;
+ }
+ return nullptr;
+}
+
dd4hep::Solid DDNamespace::addSolidNS(const string& name, dd4hep::Solid solid) const {
dd4hep::printout(m_context->debug_shapes ? dd4hep::ALWAYS : dd4hep::DEBUG,
"DD4CMS",
diff --git a/DetectorDescription/DDCMS/test/DDSolidLegacyShapes.cppunit.cc b/DetectorDescription/DDCMS/test/DDSolidLegacyShapes.cppunit.cc
index 636f8e462d39b..dcfaca7b4fbfe 100644
--- a/DetectorDescription/DDCMS/test/DDSolidLegacyShapes.cppunit.cc
+++ b/DetectorDescription/DDCMS/test/DDSolidLegacyShapes.cppunit.cc
@@ -77,6 +77,9 @@ void testDDSolidLegacyShapes::checkDDSolidLegacyShapes() {
LegacySolidShape legacyShapeless = cms::dd::value(cms::LegacySolidShapeMap, cms::DDSolidShape::ddshapeless);
CPPUNIT_ASSERT(legacyShapeless == LegacySolidShape::ddshapeless);
+ LegacySolidShape legacyAssembly = cms::dd::value(cms::LegacySolidShapeMap, cms::DDSolidShape::ddassembly);
+ CPPUNIT_ASSERT(legacyAssembly == LegacySolidShape::ddassembly);
+
LegacySolidShape legacyPseudotrap = cms::dd::value(cms::LegacySolidShapeMap, cms::DDSolidShape::ddpseudotrap);
CPPUNIT_ASSERT(legacyPseudotrap == LegacySolidShape::ddpseudotrap);
@@ -96,8 +99,8 @@ void testDDSolidLegacyShapes::checkDDSolidLegacyShapes() {
cms::dd::value(cms::LegacySolidShapeMap, cms::DDSolidShape::ddextrudedpolygon);
CPPUNIT_ASSERT(legacyExtrudedpolygon == LegacySolidShape::ddextrudedpolygon);
- int ids[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 7, 5, 6, 6, 8, 6, 9, 9,
- 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19};
+ int ids[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 7, 5, 6, 6, 8, 6, 9, 9, 10,
+ 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 22};
int i = 0;
for (const auto it : LegacySolidShapeMap) {
CPPUNIT_ASSERT(static_cast(it.value) == ids[i++]);