CMS 3D CMS Logo

OutputDD4hepToDDL.cc
Go to the documentation of this file.
17 
18 #include "TGeoManager.h"
19 
20 #include <cstddef>
21 #include <fstream>
22 #include <iomanip>
23 #include <map>
24 #include <memory>
25 #include <ostream>
26 #include <set>
27 #include <string>
28 #include <utility>
29 #include <vector>
30 
31 class OutputDD4hepToDDL : public edm::one::EDAnalyzer<edm::one::WatchRuns> {
32 public:
33  explicit OutputDD4hepToDDL(const edm::ParameterSet &iConfig);
34  ~OutputDD4hepToDDL() override;
35 
36  void beginJob() override {}
37  void beginRun(edm::Run const &iEvent, edm::EventSetup const &) override;
38  void analyze(edm::Event const &iEvent, edm::EventSetup const &) override {}
39  void endRun(edm::Run const &iEvent, edm::EventSetup const &) override {}
40  void endJob() override {}
41 
42 private:
45  std::ostream *m_xos;
46 };
47 
49  : cpvTokendd4hep_(esConsumes<edm::Transition::BeginRun>(edm::ESInputTag("", "make-payload"))), m_fname() {
50  m_fname = iConfig.getUntrackedParameter<std::string>("fileName");
51  if (m_fname.empty()) {
52  m_xos = &std::cout;
53  } else {
54  m_xos = new std::ofstream(m_fname.c_str());
55  }
56  (*m_xos) << "<?xml version=\"1.0\"?>" << std::endl;
57  (*m_xos) << "<DDDefinition>" << std::endl;
58 }
59 
61  (*m_xos) << "</DDDefinition>" << std::endl;
62  (*m_xos) << std::endl;
63  m_xos->flush();
64 }
65 
67  std::cout << "OutputDD4hepToDDL::beginRun" << std::endl;
68 
70 
71  const cms::DDDetector *det = cpv->detector();
72  const dd4hep::Detector &detector = *det->description();
73  const dd4hep::SpecParRegistry &specStore = det->specpars();
74 
76 
77  std::string rn = m_fname;
78  size_t foundLastDot = rn.find_last_of('.');
79  size_t foundLastSlash = rn.find_last_of('/');
80  if (foundLastSlash > foundLastDot && foundLastSlash != std::string::npos) {
81  std::cout << "What? last . before last / in path for filename... this should die..." << std::endl;
82  }
83  std::string ns_("none");
84  if (foundLastDot != std::string::npos && foundLastSlash != std::string::npos) {
85  ns_ = rn.substr(foundLastSlash, foundLastDot);
86  } else if (foundLastDot != std::string::npos) {
87  ns_ = rn.substr(0, foundLastDot);
88  } else {
89  std::cout << "What? no file name? Attempt at namespace =\"" << ns_ << "\" filename was " << m_fname << std::endl;
90  }
91  std::cout << "m_fname = " << m_fname << " namespace = " << ns_ << std::endl;
92 
93  (*m_xos) << std::fixed << std::setprecision(5); // Precison to 1e-5 mm
94  cms::DDParsingContext *const parsingContext = detector.extension<cms::DDParsingContext>();
95 
96  {
97  // Add rotation for reference and to ease validation
98  using namespace angle_units::operators;
99  cms::DDNamespace nameSpace(*parsingContext);
100  dd4hep::Rotation3D rotation(1., 0., 0., 0., 1., 0., 0., 0., -1.);
101  rotation = rotation * dd4hep::RotationY(1._pi);
102  nameSpace.addRotation("ebalgo:reflZRotY", rotation);
103  }
104 
105  (*m_xos) << "<PosPartSection label=\"" << ns_ << "\">" << std::endl;
106  const TGeoManager &mgr = detector.manager();
107  for (const auto &&iter : *mgr.GetListOfVolumes()) {
108  auto *vol = dynamic_cast<TGeoVolume *>(iter);
109  int numDaughters = vol->GetNdaughters();
110  if (numDaughters > 0) {
111  auto nodeArray = vol->GetNodes();
112  for (int index = 0; index < numDaughters; ++index) {
113  auto *node = dynamic_cast<TGeoNode *>((*nodeArray)[index]);
114  auto *childVol = node->GetVolume();
115  out.position(*vol, *node, childVol->GetName(), *parsingContext, *m_xos);
116  }
117  }
118  }
119  (*m_xos) << "</PosPartSection>" << std::endl;
120 
121  (*m_xos) << "<MaterialSection label=\"" << ns_ << "\">" << std::endl;
122  for (const auto &&iter : *mgr.GetListOfMaterials()) {
123  out.element(dynamic_cast<const TGeoMaterial *>(iter), *m_xos);
124  }
125  // Output composite materials
126  for (const auto &it : parsingContext->compMaterialsVec) {
127  const std::string &matName = it.first;
128  out.material(matName, it.second, parsingContext->compMaterialsRefs[matName], *m_xos);
129  }
130  (*m_xos) << "</MaterialSection>" << std::endl;
131  (*m_xos) << "<RotationSection label=\"" << ns_ << "\">" << std::endl;
132  (*m_xos) << std::fixed << std::setprecision(10); // Rounds angles to integer values w/o loss of accuracy
133  // rotRevMap has the unique rotations
134  for (const auto &rotPair : parsingContext->rotRevMap) {
135  out.rotation(parsingContext->rotations[rotPair.second], *m_xos, *parsingContext, rotPair.second);
136  }
137  (*m_xos) << "</RotationSection>" << std::endl;
138 
139  (*m_xos) << std::fixed << std::setprecision(5);
140  (*m_xos) << "<SolidSection label=\"" << ns_ << "\">" << std::endl;
141  for (const auto &&iter : *mgr.GetListOfShapes()) {
142  auto *shape = dynamic_cast<TGeoShape *>(iter);
143  if (shape->IsValid()) {
144  dd4hep::Solid solid(shape);
145  if (strlen(shape->GetTitle()) > 1) {
146  out.solid(solid, *parsingContext, *m_xos);
147  } else {
149  if (name != "Box" && name != "Tubs") { // Skip solids with degenerate names
150  if (dd4hep::isA<dd4hep::Tube>(solid)) {
151  shape->SetTitle("Tube");
152  out.solid(solid, *parsingContext, *m_xos);
153  } else if (dd4hep::isA<dd4hep::Box>(solid)) {
154  shape->SetTitle("Box");
155  out.solid(solid, *parsingContext, *m_xos);
156  } else if (dd4hep::isA<dd4hep::Trd1>(solid)) {
157  shape->SetTitle("Trd1");
158  out.solid(solid, *parsingContext, *m_xos);
159  } else
160  std::cout << "Division solid not a box, trd1, or tube = " << solid.name() << std::endl;
161  }
162  }
163  }
164  }
165  for (const auto &asmEntry : parsingContext->assemblySolids) {
166  (*m_xos) << "<Assembly name=\"" << asmEntry << "\"/>" << std::endl;
167  }
168  (*m_xos) << "</SolidSection>" << std::endl;
169 
170  (*m_xos) << "<LogicalPartSection label=\"" << ns_ << "\">" << std::endl;
171  for (const auto &&iter : *mgr.GetListOfVolumes()) {
172  auto *vol = dynamic_cast<TGeoVolume *>(iter);
173  // Skip unused logical parts and assemblies, which are listed separately
174  if (vol->GetRefCount() > 0 && vol->IsAssembly() == false) {
175  out.logicalPart(*vol, *m_xos);
176  }
177  }
178  for (const auto &asEntry : parsingContext->assemblies) {
179  out.logicalPart(asEntry.first, *m_xos);
180  }
181  (*m_xos) << "</LogicalPartSection>" << std::endl;
182 
183  (*m_xos) << std::fixed << std::setprecision(10); // Some Tracker values specified to 1e-9
184  (*m_xos) << "<SpecParSection label=\"" << ns_ << "\">" << std::endl;
185  for (const auto &specPar : specStore.specpars) {
186  out.specpar(specPar.first, specPar.second, *m_xos);
187  }
188  (*m_xos) << "</SpecParSection>" << std::endl;
189 }
190 
std::vector< std::pair< std::string, double > > compMaterialsVec
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
void beginJob() override
dd4hep::Detector const * description() const
Definition: DDDetector.h:35
void endJob() override
std::unordered_map< std::string, dd4hep::Rotation3D > rotations
static std::string trimShapeName(const std::string &solidName)
const cms::DDDetector * detector() const
Definition: DDCompactView.h:34
~OutputDD4hepToDDL() override
std::unordered_map< std::string, std::string > rotRevMap
void beginRun(edm::Run const &iEvent, edm::EventSetup const &) override
T getUntrackedParameter(std::string const &, T const &) const
OutputDD4hepToDDL(const edm::ParameterSet &iConfig)
int iEvent
Definition: GenABIO.cc:224
void addRotation(const std::string &name, const dd4hep::Rotation3D &rot) const
Definition: DDNamespace.cc:170
void analyze(edm::Event const &iEvent, edm::EventSetup const &) override
Transition
Definition: Transition.h:12
edm::ESGetToken< cms::DDCompactView, IdealGeometryRecord > cpvTokendd4hep_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::unordered_map< std::string, dd4hep::Assembly > assemblies
std::unordered_map< std::string, std::vector< CompositeMaterial > > compMaterialsRefs
HLT enums.
ESTransientHandle< T > getTransientHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:162
std::ostream * m_xos
void endRun(edm::Run const &iEvent, edm::EventSetup const &) override
dd4hep::SpecParRegistry const & specpars() const
Definition: DDDetector.h:21
std::unordered_set< std::string > assemblySolids
Definition: Run.h:45