13 #include "GeoModelHelpers/TransformToStringConverter.h"
15 #include "Acts/ActsVersion.hpp"
16 #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp"
17 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
18 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
19 #include "Acts/Visualization/GeometryView3D.hpp"
20 #include "Acts/Detector/DetectorVolume.hpp"
21 #include "Acts/Detector/PortalGenerators.hpp"
22 #include "Acts/Material/HomogeneousVolumeMaterial.hpp"
23 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
24 #include "Acts/Material/MaterialSlab.hpp"
25 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
26 #include "Acts/Navigation/InternalNavigation.hpp"
27 #include "Acts/Navigation/NavigationDelegates.hpp"
28 #include "Acts/Navigation/NavigationState.hpp"
29 #include "Acts/Visualization/ObjVisualization3D.hpp"
30 #include "Acts/Detector/MultiWireStructureBuilder.hpp"
31 #include "Acts/Geometry/GeometryIdentifier.hpp"
32 #include "Acts/Plugins/GeoModel/GeoModelMaterialConverter.hpp"
33 #include "Acts/Plugins/GeoModel/GeoModelToDetectorVolume.hpp"
34 #include "Acts/Surfaces/TrapezoidBounds.hpp"
35 #include "Acts/Surfaces/RectangleBounds.hpp"
36 #include "Acts/Surfaces/ConvexPolygonBounds.hpp"
37 #include "Acts/Surfaces/PlaneSurface.hpp"
39 #include <GeoModelKernel/GeoSimplePolygonBrep.h>
40 #include <GeoModelKernel/GeoShapeSubtraction.h>
41 #include <GeoModelKernel/GeoBox.h>
42 #include <GeoModelKernel/GeoTrd.h>
43 #include "GeoModelHelpers/getChildNodesWithTrf.h"
48 #include <GeoModelHelpers/StringUtils.h>
57 str = GeoStrUtils::replaceExpInString(
str,
" ",
"_");
58 str = GeoStrUtils::replaceExpInString(
str,
"-",
"M");
72 ATH_MSG_DEBUG(
"ACTS version is: v"<< Acts::VersionMajor <<
"." << Acts::VersionMinor <<
"." << Acts::VersionPatch <<
" [" << Acts::CommitHash <<
"]");
74 return StatusCode::SUCCESS;
81 std::vector< volumePtr > detectorVolumeBoundingVolumes{};
82 std::vector< volumePtr > detectorVolumePassiveVolumes{};
84 detectorVolumeBoundingVolumes.reserve(chambers.size());
85 std::vector<surfacePtr> surfaces{};
86 std::vector<surfacePtr> materialSurfaces{};
88 auto portalGenerator = Acts::Experimental::defaultPortalAndSubPortalGenerator();
89 unsigned int numChambers = chambers.size();
96 std::shared_ptr<Acts::TrapezoidVolumeBounds> bounds =
chamber->bounds();
97 materialSurfaces.push_back(material);
98 std::pair<std::vector<volumePtr>, std::vector<surfacePtr>> readoutElements =
100 readoutElements.second.push_back(material);
101 volumePtr detectorVolume = Acts::Experimental::DetectorVolumeFactory::construct(portalGenerator,
104 chamber->localToGlobalTrans(*gctx),
105 bounds, readoutElements.second,
106 readoutElements.first,
107 Acts::Experimental::tryAllSubVolumes(),
108 Acts::Experimental::tryAllPortalsAndSurfaces());
110 detectorVolume->assignGeometryId(Acts::GeometryIdentifier{}.setLayer(numChambers--));
113 Acts::ObjVisualization3D
helper;
114 Acts::GeometryView3D::drawDetectorVolume(
helper, *detectorVolume, gctx->
context());
118 detectorVolumeBoundingVolumes.push_back(std::move(detectorVolume));
119 readoutElements.first.clear();
120 readoutElements.second.clear();
124 Acts::ObjVisualization3D
helper;
125 for (
const auto& surf : materialSurfaces){
126 Acts::GeometryView3D::drawSurface(
helper, *surf, gctx->
context());
128 helper.write(
"materialSurfaces.obj");
132 ATH_MSG_VERBOSE(
"Number of detector volumes: "<< detectorVolumeBoundingVolumes.size());
133 ATH_MSG_VERBOSE(
"Number of chamber passives volumes: "<< detectorVolumePassiveVolumes.size());
134 std::vector<GeoChildNodeWithTrf> childNodes = getChildrenWithRef(
m_detMgr->
getTreeTop(0),
false);
135 std::set<std::string> skipNodes{
"MuonBarrel",
"NSW",
"MuonEndcap_sideA",
"MuonEndcap_sideC",
"TGCSystem"};
136 for (
const GeoChildNodeWithTrf&
node : childNodes){
138 if(skipNodes.count(
node.nodeName)) {
145 ATH_MSG_VERBOSE(
"Number of total passive volumes: "<< detectorVolumePassiveVolumes.size());
149 Acts::ObjVisualization3D
helper;
150 for (
const auto& vol : detectorVolumePassiveVolumes){
151 Acts::GeometryView3D::drawDetectorVolume(
helper, *vol, gctx->
context());
158 detectorVolumeBoundingVolumes.insert(detectorVolumeBoundingVolumes.end(), detectorVolumePassiveVolumes.begin(), detectorVolumePassiveVolumes.end());
160 std::unique_ptr<Acts::CutoutCylinderVolumeBounds> msBounds = std::make_unique<Acts::CutoutCylinderVolumeBounds>(0, 4000, 14500, 22500, 3200);
161 volumePtr msDetectorVolume = Acts::Experimental::DetectorVolumeFactory::construct(
162 portalGenerator, gctx->
context(),
"Muon Spectrometer Envelope",
163 Acts::Transform3::Identity(), std::move(msBounds), surfaces,
164 detectorVolumeBoundingVolumes, Acts::Experimental::tryAllSubVolumes(),
165 Acts::Experimental::tryAllPortalsAndSurfaces());
166 msDetectorVolume->assignGeometryId(Acts::GeometryIdentifier{}.setVolume(15));
170 Acts::ObjVisualization3D
helper;
171 Acts::GeometryView3D::drawDetectorVolume(
helper, *msDetectorVolume, gctx->
context());
176 Acts::Experimental::DetectorComponent::PortalContainer portalContainer;
177 for (
auto [
ip,
p] : Acts::enumerate(msDetectorVolume->portalPtrs())) {
178 portalContainer[
ip] =
p;
180 detectorVolumeBoundingVolumes.push_back(msDetectorVolume);
181 return Acts::Experimental::DetectorComponent{
182 {detectorVolumeBoundingVolumes},
184 {{msDetectorVolume}, Acts::Experimental::tryAllSubVolumes()}};
187 std::pair<std::vector<volumePtr>,std::vector<surfacePtr>>
190 std::pair<unsigned int, unsigned int> chId)
const{
192 std::vector<volumePtr> readoutDetectorVolumes{};
193 std::vector<surfacePtr> readoutSurfaces{};
194 if(!
m_buildSensitives)
return std::make_pair(readoutDetectorVolumes, readoutSurfaces);
195 Acts::GeometryIdentifier::Value surfId{1};
196 Acts::GeometryIdentifier::Value mdtId{1};
201 switch (ele->detectorType()) {
206 std::vector<surfacePtr> surfaces{};
208 for(
unsigned int lay=1; lay<=mdtReadoutEle->numLayers(); ++lay){
209 for(
unsigned int tube=1;
tube<=mdtReadoutEle->numTubesInLay(); ++
tube){
211 if (!mdtReadoutEle->isValid(measHash))
continue;
212 surfacePtr surface = mdtReadoutEle->surfacePtr(measHash);
213 surface->assignGeometryId(Acts::GeometryIdentifier{}.setLayer(chId.first).setVolume(chId.second).setBoundary(mdtId).setSensitive(++surfId));
214 surfaces.push_back(surface);
222 Acts::Experimental::MultiWireStructureBuilder::Config mlCfg{};
223 mlCfg.name =
m_idHelperSvc->toStringDetEl(mdtReadoutEle->identify());
224 mlCfg.mlSurfaces = std::move(surfaces);
225 mlCfg.transform = mdtTransform;
227 using BoundsV = Acts::TrapezoidVolumeBounds::BoundValues;
228 mlCfg.mlBounds= mdtBounds->values();
230 -mdtBounds->get(BoundsV::eHalfLengthXnegY),
231 mdtBounds->get(BoundsV::eHalfLengthXposY),
232 std::lround(2*mdtBounds->get(BoundsV::eHalfLengthXposY)/
parameters.tubePitch), 0
u),
234 -mdtBounds->get(BoundsV::eHalfLengthY),
235 mdtBounds->get(BoundsV::eHalfLengthY),
236 std::lround(2*mdtBounds->get(BoundsV::eHalfLengthY)/
parameters.tubePitch), 0
u)};
238 Acts::Experimental::MultiWireStructureBuilder mdtBuilder(mlCfg);
240 mdtVolume->assignGeometryId(Acts::GeometryIdentifier{}.setLayer(chId.first).setVolume(chId.second).setBoundary(mdtId++));
241 readoutDetectorVolumes.push_back(mdtVolume);
248 std::vector<surfacePtr> detSurfaces = ele->getSurfaces();
250 surf->assignGeometryId(Acts::GeometryIdentifier{}.setLayer(chId.first).setVolume(chId.second).setSensitive(++surfId));
251 readoutSurfaces.push_back(std::move(surf));
259 return std::make_pair(std::move(readoutDetectorVolumes), std::move(readoutSurfaces));
265 const int totalMaterials,
268 const float thickness =
chamber.halfZ() * 2;
269 PVConstLink parentVolume =
chamber.readoutEles().front()->getMaterialGeom()->getParent();
270 std::pair<MaterialPtr, double> geoMaterials =
getMaterial(parentVolume);
271 const Acts::Material aMat = Acts::GeoModel::geoMaterialConverter(*geoMaterials.first);
273 std::shared_ptr<Acts::PlaneSurface> surface = Acts::Surface::makeShared<Acts::PlaneSurface>(chamberTransform, bounds);
274 Acts::MaterialSlab slab{aMat, thickness};
275 std::shared_ptr<Acts::HomogeneousSurfaceMaterial> material = std::make_shared<Acts::HomogeneousSurfaceMaterial>(slab);
276 surface->assignSurfaceMaterial(material);
277 surface->assignGeometryId(Acts::GeometryIdentifier{}.setVolume(29).setSensitive(totalMaterials));
281 std::pair<MuonDetectorBuilderTool::MaterialPtr, double>
283 std::vector<std::pair<MaterialPtr, double>> materialContent{};
287 double totalVolume{0.};
288 double totalMass{0.};
289 for(
const auto& [material, volume] : materialContent){
290 totalVolume += volume;
291 totalMass += volume * material->getDensity();
295 auto blendedMaterial = make_intrusive<GeoMaterial>(
"BlendedMaterial", totalMass/totalVolume);
296 for(
const auto& [material, volume] : materialContent){
297 blendedMaterial->add(material, material->getDensity() * volume / totalMass);
299 blendedMaterial->lock();
300 return {blendedMaterial, totalVolume};
306 for(std::size_t
c=0;
c < vol->getNChildVols(); ++
c){
307 const PVConstLink child = vol->getChildVol(
c);
308 double childVol = child->getLogVol()->getShape()->volume();
314 if(!
checkDummyMaterial(vol)) materialContent.emplace_back(vol->getLogVol()->getMaterial(), volume);
318 static const std::unordered_set<std::string> dummyMaterials{
324 const std::string materialName = vol->getLogVol()->getMaterial()->getName();
325 return dummyMaterials.find(materialName) != dummyMaterials.end();
329 const GeoChildNodeWithTrf&
node,
330 const std::string&
name,
331 std::vector<volumePtr>& passiveVolumes,
333 std::vector<GeoChildNodeWithTrf>
children = getChildrenWithRef(
node.volume,
false);
334 for(
const GeoChildNodeWithTrf& childNode :
children){
342 const GeoShape* shape =
node.volume->getLogVol()->getShape();
343 const GeoMaterial* geoMaterial =
node.volume->getLogVol()->getMaterial();
344 const Acts::Material aMat = Acts::GeoModel::geoMaterialConverter(*geoMaterial);
345 std::shared_ptr<Acts::HomogeneousVolumeMaterial> material = std::make_shared<Acts::HomogeneousVolumeMaterial>(aMat);
348 volume->assignGeometryId(Acts::GeometryIdentifier{}.setVolume(30).setSensitive(passiveVolumes.size()));
349 volume->assignVolumeMaterial(material);
350 passiveVolumes.push_back(volume);