File indexing completed on 2025-01-30 09:16:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/Detector.h>
0016 #include <DD4hep/GeoHandler.h>
0017 #include <DD4hep/detail/ObjectsInterna.h>
0018
0019
0020 #include <TGeoManager.h>
0021 #include <TGeoCompositeShape.h>
0022 #include <TGeoBoolNode.h>
0023 #include <TClass.h>
0024
0025
0026 #include <algorithm>
0027 #include <iostream>
0028
0029 using namespace dd4hep;
0030
0031 namespace {
0032
0033 void collectSolid(detail::GeoHandler::GeometryInfo& geo,
0034 const std::string& name,
0035 const std::string& node,
0036 TGeoShape* shape,
0037 TGeoMatrix* matrix)
0038 {
0039 if ( 0 == ::strncmp(shape->GetName(), "TGeo", 4) ) {
0040 shape->SetName(name.c_str());
0041 }
0042 if ( shape->IsA() == TGeoCompositeShape::Class() ) {
0043 const TGeoCompositeShape* s = (const TGeoCompositeShape*) shape;
0044 const TGeoBoolNode* boolean = s->GetBoolNode();
0045 collectSolid(geo, name + "_left", name + "_left", boolean->GetLeftShape(), boolean->GetLeftMatrix());
0046 collectSolid(geo, name + "_right", name + "_right", boolean->GetRightShape(), boolean->GetRightMatrix());
0047 }
0048 if(geo.solid_set.emplace(shape).second) {
0049 geo.solids.push_back(shape);
0050 }
0051 geo.trafos.emplace_back(node, matrix);
0052 }
0053 }
0054
0055
0056 detail::GeoHandler::GeoHandler() {
0057 m_data = new std::map<int, std::vector<const TGeoNode*> >();
0058 m_set_data = new std::map<int, std::set<const TGeoNode*> >();
0059 }
0060
0061
0062 detail::GeoHandler::GeoHandler(std::map<int, std::vector<const TGeoNode*> >* ptr,
0063 std::map<int, std::set<const TGeoNode*> >* ptr_set,
0064 std::map<const TGeoNode*, std::vector<TGeoNode*> >* daus)
0065 : m_data(ptr), m_set_data(ptr_set), m_daughters(daus)
0066 {
0067 }
0068
0069
0070 detail::GeoHandler::~GeoHandler() {
0071 if (m_data)
0072 delete m_data;
0073 if (m_set_data)
0074 delete m_set_data;
0075
0076 m_data = nullptr;
0077 m_set_data = nullptr;
0078 }
0079
0080 std::map<int, std::vector<const TGeoNode*> >* detail::GeoHandler::release() {
0081
0082 std::map<int, std::vector<const TGeoNode*> >* d = m_data;
0083 m_data = nullptr;
0084
0085
0086
0087
0088 delete m_set_data;
0089 m_set_data = nullptr;
0090
0091 return d;
0092 }
0093
0094
0095 bool detail::GeoHandler::setPropagateRegions(bool value) {
0096 bool old = m_propagateRegions;
0097 m_propagateRegions = value;
0098 return old;
0099 }
0100
0101 detail::GeoHandler& detail::GeoHandler::collect(DetElement element) {
0102 DetElement par = element.parent();
0103 TGeoNode* par_node = par.isValid() ? par.placement().ptr() : nullptr;
0104 m_data->clear();
0105 m_set_data->clear();
0106 return i_collect(par_node, element.placement().ptr(), 0, Region(), LimitSet());
0107 }
0108
0109 detail::GeoHandler& detail::GeoHandler::collect(DetElement element, GeometryInfo& info) {
0110 DetElement par = element.parent();
0111 TGeoNode* par_node = par.isValid() ? par.placement().ptr() : nullptr;
0112 m_data->clear();
0113 m_set_data->clear();
0114 i_collect(par_node, element.placement().ptr(), 0, Region(), LimitSet());
0115 for ( auto i = m_data->rbegin(); i != m_data->rend(); ++i ) {
0116 const auto& mapped = (*i).second;
0117 for ( const TGeoNode* n : mapped ) {
0118 TGeoVolume* v = n->GetVolume();
0119 if ( v ) {
0120 Material mat(v->GetMedium());
0121 Volume vol(v);
0122
0123 if ( info.volumeSet.find(vol) == info.volumeSet.end() ) {
0124 info.volumeSet.emplace(vol);
0125 info.volumes.emplace_back(vol);
0126 }
0127 if ( mat.isValid() )
0128 info.materials.emplace(mat);
0129 if (dynamic_cast<Volume::Object*>(v)) {
0130 VisAttr vis = vol.visAttributes();
0131
0132
0133
0134
0135 if (vis.isValid())
0136 info.vis.emplace(vis);
0137
0138
0139
0140 }
0141 collectSolid(info, v->GetName(), n->GetName(), v->GetShape(), n->GetMatrix());
0142 }
0143 }
0144 }
0145 return *this;
0146 }
0147
0148 detail::GeoHandler& detail::GeoHandler::i_collect(const TGeoNode* ,
0149 const TGeoNode* current,
0150 int level, Region rg, LimitSet ls)
0151 {
0152 TGeoVolume* vol = current->GetVolume();
0153 TObjArray* nodes = vol->GetNodes();
0154 Volume volume = vol;
0155 Region region = volume.region();
0156 LimitSet limits = volume.limitSet();
0157
0158 if ( m_propagateRegions ) {
0159 if ( !region.isValid() && rg.isValid() ) {
0160 region = rg;
0161 volume.setRegion(region);
0162 }
0163 if ( !limits.isValid() && ls.isValid() ) {
0164 limits = ls;
0165 volume.setLimitSet(limits);
0166 }
0167 }
0168
0169
0170 if ( (*m_set_data)[level].emplace(current).second ) {
0171 (*m_data)[level].push_back(current);
0172 }
0173 int num = nodes ? nodes->GetEntriesFast() : 0;
0174 for (int i = 0; i < num; ++i)
0175 i_collect(current, (TGeoNode*)nodes->At(i), level + 1, region, limits);
0176
0177 if ( m_daughters && m_daughters->find(current) == m_daughters->end() ) {
0178 auto [idau,success] = m_daughters->emplace(current, std::vector<TGeoNode*>());
0179 for (int i = 0; i < num; ++i)
0180 idau->second.push_back((TGeoNode*)nodes->At(i));
0181 }
0182 return *this;
0183 }
0184
0185
0186 detail::GeoScan::GeoScan(DetElement e) {
0187 m_data = GeoHandler().collect(e).release();
0188 }
0189
0190
0191 detail::GeoScan::GeoScan(DetElement e, bool propagate) {
0192 GeoHandler h;
0193 h.setPropagateRegions(propagate);
0194 m_data = h.collect(e).release();
0195 }
0196
0197
0198 detail::GeoScan::~GeoScan() {
0199 if (m_data)
0200 delete m_data;
0201 m_data = 0;
0202 }
0203
0204
0205 detail::GeoScan& detail::GeoScan::operator()() {
0206 return *this;
0207 }
0208