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"
45 #include <Acts/Utilities/AxisDefinitions.hpp>
49 #include <GeoModelHelpers/StringUtils.h>
58 str = GeoStrUtils::replaceExpInString(
str,
" ",
"_");
59 str = GeoStrUtils::replaceExpInString(
str,
"-",
"M");
73 ATH_MSG_DEBUG(
"ACTS version is: v"<< Acts::VersionMajor <<
"." << Acts::VersionMinor <<
"." << Acts::VersionPatch <<
" [" << Acts::CommitHash <<
"]");
75 return StatusCode::SUCCESS;
82 std::vector< volumePtr > detectorVolumeBoundingVolumes{};
83 std::vector< volumePtr > detectorVolumePassiveVolumes{};
85 detectorVolumeBoundingVolumes.reserve(chambers.size());
86 std::vector<surfacePtr> surfaces{};
87 std::vector<surfacePtr> materialSurfaces{};
89 auto portalGenerator = Acts::Experimental::defaultPortalAndSubPortalGenerator();
90 unsigned int numChambers = chambers.size();
97 std::shared_ptr<Acts::TrapezoidVolumeBounds> bounds =
chamber->bounds();
98 materialSurfaces.push_back(material);
99 std::pair<std::vector<volumePtr>, std::vector<surfacePtr>> readoutElements =
101 readoutElements.second.push_back(material);
102 volumePtr detectorVolume = Acts::Experimental::DetectorVolumeFactory::construct(portalGenerator,
105 chamber->localToGlobalTrans(*gctx),
106 bounds, readoutElements.second,
107 readoutElements.first,
108 Acts::Experimental::tryAllSubVolumes(),
109 Acts::Experimental::tryAllPortalsAndSurfaces());
111 detectorVolume->assignGeometryId(Acts::GeometryIdentifier{}.withLayer(numChambers--));
114 Acts::ObjVisualization3D
helper;
115 Acts::GeometryView3D::drawDetectorVolume(
helper, *detectorVolume, gctx->
context());
119 detectorVolumeBoundingVolumes.push_back(std::move(detectorVolume));
120 readoutElements.first.clear();
121 readoutElements.second.clear();
125 Acts::ObjVisualization3D
helper;
126 for (
const auto& surf : materialSurfaces){
127 Acts::GeometryView3D::drawSurface(
helper, *surf, gctx->
context());
129 helper.write(
"materialSurfaces.obj");
133 ATH_MSG_VERBOSE(
"Number of detector volumes: "<< detectorVolumeBoundingVolumes.size());
134 ATH_MSG_VERBOSE(
"Number of chamber passives volumes: "<< detectorVolumePassiveVolumes.size());
135 std::vector<GeoChildNodeWithTrf> childNodes = getChildrenWithRef(
m_detMgr->
getTreeTop(0),
false);
136 std::set<std::string> skipNodes{
"MuonBarrel",
"NSW",
"MuonEndcap_sideA",
"MuonEndcap_sideC",
"TGCSystem"};
137 for (
const GeoChildNodeWithTrf&
node : childNodes){
139 if(skipNodes.count(
node.nodeName)) {
146 ATH_MSG_VERBOSE(
"Number of total passive volumes: "<< detectorVolumePassiveVolumes.size());
150 Acts::ObjVisualization3D
helper;
151 for (
const auto& vol : detectorVolumePassiveVolumes){
152 Acts::GeometryView3D::drawDetectorVolume(
helper, *vol, gctx->
context());
159 detectorVolumeBoundingVolumes.insert(detectorVolumeBoundingVolumes.end(), detectorVolumePassiveVolumes.begin(), detectorVolumePassiveVolumes.end());
161 std::unique_ptr<Acts::CutoutCylinderVolumeBounds> msBounds = std::make_unique<Acts::CutoutCylinderVolumeBounds>(0, 4000, 14500, 22500, 3200);
162 volumePtr msDetectorVolume = Acts::Experimental::DetectorVolumeFactory::construct(
163 portalGenerator, gctx->
context(),
"Muon Spectrometer Envelope",
164 Acts::Transform3::Identity(), std::move(msBounds), surfaces,
165 detectorVolumeBoundingVolumes, Acts::Experimental::tryAllSubVolumes(),
166 Acts::Experimental::tryAllPortalsAndSurfaces());
167 msDetectorVolume->assignGeometryId(Acts::GeometryIdentifier{}.withVolume(15));
171 Acts::ObjVisualization3D
helper;
172 Acts::GeometryView3D::drawDetectorVolume(
helper, *msDetectorVolume, gctx->
context());
177 Acts::Experimental::DetectorComponent::PortalContainer portalContainer;
178 for (
auto [
ip,
p] : Acts::enumerate(msDetectorVolume->portalPtrs())) {
179 portalContainer[
ip] =
p;
181 detectorVolumeBoundingVolumes.push_back(msDetectorVolume);
182 return Acts::Experimental::DetectorComponent{
183 {detectorVolumeBoundingVolumes},
185 {{msDetectorVolume}, Acts::Experimental::tryAllSubVolumes()}};
188 std::pair<std::vector<volumePtr>,std::vector<surfacePtr>>
191 std::pair<unsigned int, unsigned int> chId)
const{
193 std::vector<volumePtr> readoutDetectorVolumes{};
194 std::vector<surfacePtr> readoutSurfaces{};
195 if(!
m_buildSensitives)
return std::make_pair(readoutDetectorVolumes, readoutSurfaces);
196 Acts::GeometryIdentifier::Value surfId{1};
197 Acts::GeometryIdentifier::Value mdtId{1};
202 switch (ele->detectorType()) {
207 std::vector<surfacePtr> surfaces{};
209 for(
unsigned int lay=1; lay<=mdtReadoutEle->numLayers(); ++lay){
210 for(
unsigned int tube=1;
tube<=mdtReadoutEle->numTubesInLay(); ++
tube){
212 if (!mdtReadoutEle->isValid(measHash))
continue;
213 surfacePtr surface = mdtReadoutEle->surfacePtr(measHash);
214 surface->assignGeometryId(Acts::GeometryIdentifier{}.withLayer(chId.first).withVolume(chId.second).withBoundary(mdtId).withSensitive(++surfId));
215 surfaces.push_back(surface);
223 Acts::Experimental::MultiWireStructureBuilder::Config mlCfg{};
224 mlCfg.name =
m_idHelperSvc->toStringDetEl(mdtReadoutEle->identify());
225 mlCfg.mlSurfaces = std::move(surfaces);
226 mlCfg.transform = mdtTransform;
228 using BoundsV = Acts::TrapezoidVolumeBounds::BoundValues;
229 mlCfg.mlBounds= mdtBounds->values();
231 mlCfg.mlBinning = {{{Acts::AxisDirection::AxisY, Acts::AxisBoundaryType::Bound,
232 -mdtBounds->get(BoundsV::eHalfLengthY),
233 mdtBounds->get(BoundsV::eHalfLengthY),
234 static_cast<std::size_t
>(std::lround(2*mdtBounds->get(BoundsV::eHalfLengthY)/
parameters.tubePitch))}, 2
u},
235 {{Acts::AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound,
236 -mdtBounds->get(BoundsV::eHalfLengthZ),
237 mdtBounds->get(BoundsV::eHalfLengthZ),
238 static_cast<std::size_t
>(std::lround(2*mdtBounds->get(BoundsV::eHalfLengthZ)/
parameters.tubePitch))}, 1
u}};
240 Acts::Experimental::MultiWireStructureBuilder mdtBuilder(mlCfg);
242 mdtVolume->assignGeometryId(Acts::GeometryIdentifier{}.withLayer(chId.first).withVolume(chId.second).withBoundary(mdtId++));
243 readoutDetectorVolumes.push_back(mdtVolume);
250 std::vector<surfacePtr> detSurfaces = ele->getSurfaces();
252 surf->assignGeometryId(Acts::GeometryIdentifier{}.withLayer(chId.first).withVolume(chId.second).withSensitive(++surfId));
253 readoutSurfaces.push_back(std::move(surf));
261 return std::make_pair(std::move(readoutDetectorVolumes), std::move(readoutSurfaces));
267 const int totalMaterials,
270 const float thickness =
chamber.halfZ() * 2;
271 PVConstLink parentVolume =
chamber.readoutEles().front()->getMaterialGeom()->getParent();
272 std::pair<MaterialPtr, double> geoMaterials =
getMaterial(parentVolume);
273 const Acts::Material aMat = Acts::GeoModel::geoMaterialConverter(*geoMaterials.first);
275 std::shared_ptr<Acts::PlaneSurface> surface = Acts::Surface::makeShared<Acts::PlaneSurface>(chamberTransform, bounds);
276 Acts::MaterialSlab slab{aMat, thickness};
277 std::shared_ptr<Acts::HomogeneousSurfaceMaterial> material = std::make_shared<Acts::HomogeneousSurfaceMaterial>(slab);
278 surface->assignSurfaceMaterial(material);
279 surface->assignGeometryId(Acts::GeometryIdentifier{}.withVolume(29).withSensitive(totalMaterials));
283 std::pair<MuonDetectorBuilderTool::MaterialPtr, double>
285 std::vector<std::pair<MaterialPtr, double>> materialContent{};
289 double totalVolume{0.};
290 double totalMass{0.};
291 for(
const auto& [material, volume] : materialContent){
292 totalVolume += volume;
293 totalMass += volume * material->getDensity();
297 auto blendedMaterial = make_intrusive<GeoMaterial>(
"BlendedMaterial", totalMass/totalVolume);
298 for(
const auto& [material, volume] : materialContent){
299 blendedMaterial->add(material, material->getDensity() * volume / totalMass);
301 blendedMaterial->lock();
302 return {blendedMaterial, totalVolume};
308 for(std::size_t
c=0;
c < vol->getNChildVols(); ++
c){
309 const PVConstLink child = vol->getChildVol(
c);
310 double childVol = child->getLogVol()->getShape()->volume();
316 if(!
checkDummyMaterial(vol)) materialContent.emplace_back(vol->getLogVol()->getMaterial(), volume);
320 static const std::unordered_set<std::string> dummyMaterials{
326 const std::string materialName = vol->getLogVol()->getMaterial()->getName();
327 return dummyMaterials.find(materialName) != dummyMaterials.end();
331 const GeoChildNodeWithTrf&
node,
332 const std::string&
name,
333 std::vector<volumePtr>& passiveVolumes,
335 std::vector<GeoChildNodeWithTrf>
children = getChildrenWithRef(
node.volume,
false);
336 for(
const GeoChildNodeWithTrf& childNode :
children){
344 const GeoShape* shape =
node.volume->getLogVol()->getShape();
345 const GeoMaterial* geoMaterial =
node.volume->getLogVol()->getMaterial();
346 const Acts::Material aMat = Acts::GeoModel::geoMaterialConverter(*geoMaterial);
347 std::shared_ptr<Acts::HomogeneousVolumeMaterial> material = std::make_shared<Acts::HomogeneousVolumeMaterial>(aMat);
350 volume->assignGeometryId(Acts::GeometryIdentifier{}.withVolume(30).withSensitive(passiveVolumes.size()));
351 volume->assignVolumeMaterial(material);
352 passiveVolumes.push_back(volume);