ATLAS Offline Software
MuonInertMaterialBuilderImpl.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 // Muon
6 
7 // MuonSpectrometer include
10 
11 // STD
12 #include <fstream>
13 #include <iostream>
14 #include <map>
15 
16 #include "GeoModelKernel/GeoShape.h"
17 #include "GeoModelKernel/GeoVolumeCursor.h"
18 
19 // constructor
21  const std::string& t, const std::string& n, const IInterface* p)
22  : AthAlgTool(t, n, p), Trk::TrackingVolumeManipulator() {}
23 
24 // Athena standard methods
25 // initialize
27 
28  if (m_simplifyToLayers) {
29  ATH_MSG_INFO(" option Simplify(Muon)GeometryToLayers no longer maintained ");
30  }
31  ATH_MSG_INFO( " initialize() successful");
32  return StatusCode::SUCCESS;
33 }
34 
36  Muon::MuonInertMaterialBuilderImpl::buildDetachedTrackingVolumesImpl(const PVConstLink treeTop, bool blend) const {
37 
38  if (!treeTop) {
39  throw std::runtime_error("No tree top has been parsed");
40  }
41  // collect inert material objects
42  DetachedVolVec mInert{};
43  // retrieve muon station prototypes from GeoModel
44  auto msTypes = buildDetachedTrackingVolumeTypes(treeTop, blend);
45  ATH_MSG_DEBUG(" obtained " << msTypes.size() << " prototypes");
46 
47 
48  for (auto& [msTV, transforms]: msTypes) {
49  std::string msTypeName = msTV->name();
50  for (Amg::Transform3D& combTr : transforms) {
51  std::unique_ptr<Trk::DetachedTrackingVolume> newStat{msTV->clone(msTypeName, combTr)};
52  mInert.push_back(std::move(newStat));
53  }
54  }
55  ATH_MSG_DEBUG(" returns " << mInert.size() << " objects (detached volumes)");
56 
57  return mInert;
58 }
59 
60 
63 
66  GeoVolumeCursor vol(top);
67  while (!vol.atEnd()) {
68  const GeoVPhysVol* cv = vol.getVolume();
69  const GeoLogVol* clv = cv->getLogVol();
70  const std::string_view vname = clv->getName();
71  if (vname.size() > 7 && vname.substr(vname.size() - 7, 7) ==
72  "Station") { // do nothing, active station
73  } else {
74  bool accepted = true;
75  if (vname.substr(0, 3) == "BAR" || vname.substr(0, 2) == "BT" ||
76  vname.substr(0, 6) == "EdgeBT" || vname.substr(0, 6) == "HeadBT"){
77  accepted = m_buildBT;
78  } else if (vname.substr(0, 3) == "ECT") {
79  accepted = m_buildECT;
80  } else if (vname.substr(0, 4) == "Feet" ||
81  (vname.size() > 7 && (vname.substr(3, 4) == "Feet" || vname.substr(4, 4) == "Feet"))) {
82  accepted = m_buildFeets;
83  } else if (vname.substr(0, 4) == "Rail") {
84  accepted = m_buildRails > 0;
85  } else if (vname.substr(0, 1) == "J") {
86  accepted = m_buildShields > 0;
87  // NSW build inertmaterial for spacer frame, aluminium HUB, NJD disk
88  // and A plate
89  } else if (vname.substr(0, 3) == "NSW" && vname.substr(1, 6) == "Spacer") {
90  accepted = m_buildNSWInert;
91  } else if (vname.substr(0, 3) == "NSW" && vname.substr(1, 2) == "Al") {
92  accepted = m_buildNSWInert;
93  } else if (vname.substr(0, 3) == "NJD"){
94  accepted = m_buildNSWInert;
95  } else if (vname.substr(0, 1) == "A" && vname.substr(1, 5) == "Plate"){
96  accepted = m_buildNSWInert;
97  // strange NSW will be anyway build
98  } else if (vname.substr(0, 1) != "J") {
99  accepted = m_buildSupports > 0;
100  }
101  if (!accepted) {
102  ATH_MSG_VERBOSE(" INERT muon object found and rejected :" << vname);
103  vol.next();
104  continue;
105  }
106  ATH_MSG_VERBOSE(" INERT muon object found and accepted :" << vname);
107 
108  if (msg().level() == MSG::VERBOSE)
109  printInfo(cv);
110 
111  std::vector<std::pair<const GeoVPhysVol*, std::vector<Amg::Transform3D>>> vols;
112 
113  bool simpleTree = false;
114  if (!cv->getNChildVols()) {
115  if (!m_gmBrowser.findNamePattern(cv, "Sensitive")) {
116  std::vector<Amg::Transform3D> volTr;
117  volTr.push_back(vol.getTransform());
118  vols.emplace_back(cv, volTr);
119  simpleTree = true;
120  }
121  } else {
122  getObjsForTranslation(cv, Amg::Transform3D::Identity(), vols);
123  }
124 
125  for (auto& [physVol, physVolTrfs]: vols) {
126  std::string protoName(vname);
127  if (!simpleTree)
128  protoName += physVol->getLogVol()->getName();
129  ATH_MSG_VERBOSE(" check in:"<< protoName << ", made of "
130  << physVol->getLogVol()->getMaterial()->getName()
131  << " x0 " << physVol->getLogVol()->getMaterial()->getRadLength()
132  << "," << physVol->getLogVol()->getShape()->type());
133 
134  bool found = false;
135  for (auto& obj : objs) {
136  if (protoName == obj.first->name()) { // found in another branch already ?
137  found = true;
138  if (simpleTree) {
139  obj.second.push_back(vol.getTransform());
140  } else {
141  obj.second.insert(obj.second.end(),
142  std::make_move_iterator(physVolTrfs.begin()),
143  std::make_move_iterator(physVolTrfs.end()));
144  }
145  }
146  }
147  if (found) {
148  continue;
149  }
150  // envelope creation & simplification done with
151  // TrkDetDescrGeoModelCnv helpers
152  auto newType = m_volumeConverter.translate(physVol, m_simplify, blend, m_blendLimit);
153  if (newType) {
154  const std::string volName = newType->volumeName();
155  auto typeDet = std::make_unique<Trk::DetachedTrackingVolume>(volName, newType.release());
156  objs.emplace_back(std::move(typeDet), std::move(physVolTrfs));
157  } else {
158  ATH_MSG_WARNING("volume not translated: " << vname);
159  }
160  } // end new object
161  }
162  vol.next();
163  }
164 
165  int count = 0;
166  for (auto& obj : objs)
167  count += obj.second.size();
168 
169  ATH_MSG_DEBUG(" returns " << objs.size()<< " prototypes, to be cloned into " << count << " objects");
170 
171  return objs;
172 }
173 
175  const GeoVPhysVol* pv) const {
176  const GeoLogVol* lv = pv->getLogVol();
177  ATH_MSG_VERBOSE("New Muon Inert Object:"
178  << lv->getName() << ", made of "
179  << lv->getMaterial()->getName() << " x0 "
180  << lv->getMaterial()->getRadLength() << ","
181  << lv->getShape()->type());
182  m_geoShapeConverter.decodeShape(lv->getShape());
183  printChildren(pv);
184 }
185 
187  const GeoVPhysVol* pv) const {
188  // subcomponents
189  unsigned int nc = pv->getNChildVols();
190  for (unsigned int ic = 0; ic < nc; ic++) {
191  Amg::Transform3D transf = pv->getXToChildVol(ic);
192 
193  const GeoVPhysVol* cv = &(*(pv->getChildVol(ic)));
194  const GeoLogVol* clv = cv->getLogVol();
195  ATH_MSG_VERBOSE(" ");
197  "subcomponent:"
198  << ic << ":" << clv->getName() << ", made of "
199  << clv->getMaterial()->getName() << " x0 "
200  << clv->getMaterial()->getRadLength() << " , "
201  << clv->getShape()->type() << "," << transf.translation().x() << " "
202  << transf.translation().y() << " " << transf.translation().z());
203 
204  m_geoShapeConverter.decodeShape(clv->getShape());
205 
206  printChildren(cv);
207  }
208 }
209 
211  const GeoVPhysVol* pv, const Amg::Transform3D& transform,
212  std::vector<std::pair<const GeoVPhysVol*, std::vector<Amg::Transform3D>>>&
213  vols) const {
214  // subcomponents
215  unsigned int nc = pv->getNChildVols();
216  ATH_MSG_VERBOSE(" INERT getObjsForTranslation from:"
217  << pv->getLogVol()->getName() << ","
218  << pv->getLogVol()->getMaterial()->getName()
219  << ", looping over " << nc << " children");
220  for (unsigned int ic = 0; ic < nc; ic++) {
221  Amg::Transform3D transf = pv->getXToChildVol(ic);
222  const GeoVPhysVol* cv = &(*(pv->getChildVol(ic)));
223  const GeoLogVol* clv = cv->getLogVol();
224  if (clv->getMaterial()->getDensity() > 0. &&
225  m_gmBrowser.findNamePattern(cv, "Sensitive"))
226  continue; // skip sensitive material branches
227  if (!cv->getNChildVols()) {
228  bool found = false;
229  for (auto& vol : vols) {
230  if (clv->getName() == vol.first->getLogVol()->getName()) {
231  if (m_gmBrowser.compareGeoVolumes(cv, vol.first, 1.e-3) !=
232  0)
234  "INERT name branch matching differences detected "
235  "in:"
236  << clv->getName());
237  found = true;
238  vol.second.push_back(transform * transf);
239  break;
240  }
241  }
242  if (!found) {
243  std::vector<Amg::Transform3D> volTr;
244  volTr.push_back(transform * transf);
245  vols.emplace_back(cv, volTr);
246  ATH_MSG_VERBOSE("INERT new volume added:"
247  << clv->getName() << ","
248  << clv->getMaterial()->getName());
249  if (msg().level() <= MSG::VERBOSE)
250  printInfo(cv);
251  }
252  } else {
253  getObjsForTranslation(cv, transform * transf, vols);
254  }
255  }
256 }
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Muon::MuonInertMaterialBuilderImpl::initialize
virtual StatusCode initialize() override
AlgTool initialize method.
Definition: MuonInertMaterialBuilderImpl.cxx:26
Muon::MuonInertMaterialBuilderImpl::MuonInertMaterialBuilderImpl
MuonInertMaterialBuilderImpl(const std::string &, const std::string &, const IInterface *)
Constructor.
Definition: MuonInertMaterialBuilderImpl.cxx:20
Muon::MuonInertMaterialBuilderImpl::buildDetachedTrackingVolumeTypes
DetachedVolumeVecWithTrfs buildDetachedTrackingVolumeTypes(const PVConstLink top, bool blend) const
Definition: MuonInertMaterialBuilderImpl.cxx:62
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
Muon::MuonInertMaterialBuilderImpl::DetachedVolumeVecWithTrfs
std::vector< std::pair< std::unique_ptr< Trk::DetachedTrackingVolume >, std::vector< Amg::Transform3D > >> DetachedVolumeVecWithTrfs
Method creating material object prototypes.
Definition: MuonInertMaterialBuilderImpl.h:71
Muon::MuonInertMaterialBuilderImpl::getObjsForTranslation
void getObjsForTranslation(const GeoVPhysVol *pv, const Amg::Transform3D &, std::vector< std::pair< const GeoVPhysVol *, std::vector< Amg::Transform3D >>> &vols) const
Method extracting material objects from GeoModel tree.
Definition: MuonInertMaterialBuilderImpl.cxx:210
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
checkFileSG.objs
list objs
Definition: checkFileSG.py:93
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
Muon::MuonInertMaterialBuilderImpl::DetachedVolVec
std::vector< std::unique_ptr< Trk::DetachedTrackingVolume > > DetachedVolVec
Definition: MuonInertMaterialBuilderImpl.h:58
MuonInertMaterialBuilderImpl.h
grepfile.ic
int ic
Definition: grepfile.py:33
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Muon::MuonInertMaterialBuilderImpl::printInfo
void printInfo(const GeoVPhysVol *pv) const
Dump from GeoModel tree
Definition: MuonInertMaterialBuilderImpl.cxx:174
Muon::MuonInertMaterialBuilderImpl::printChildren
void printChildren(const GeoVPhysVol *pv) const
Definition: MuonInertMaterialBuilderImpl.cxx:186
MuonStationTypeBuilder.h
MuonDetectorManager.h
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.changerun.pv
pv
Definition: changerun.py:81
Muon::MuonInertMaterialBuilderImpl::buildDetachedTrackingVolumesImpl
DetachedVolVec buildDetachedTrackingVolumesImpl(const PVConstLink treeTop, bool blend) const
Definition: MuonInertMaterialBuilderImpl.cxx:36
top
@ top
Definition: TruthClasses.h:64
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
AthAlgTool
Definition: AthAlgTool.h:26
python.PyAthena.obj
obj
Definition: PyAthena.py:132
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
plotBeamSpotMon.nc
int nc
Definition: plotBeamSpotMon.py:83