File indexing completed on 2024-04-06 12:05:30
0001 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/Framework/interface/EventSetup.h"
0004 #include "FWCore/Framework/interface/ESTransientHandle.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "FWCore/Utilities/interface/ESGetToken.h"
0007 #include "FWCore/Framework/interface/ConsumesCollector.h"
0008 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0009 #include "FWCore/Framework/interface/MakerMacros.h"
0010 #include "DataFormats/Math/interface/angle_units.h"
0011 #include "DetectorDescription/OfflineDBLoader/interface/DDCoreToDDXMLOutput.h"
0012 #include "DetectorDescription/DDCMS/interface/DDAlgoArguments.h"
0013 #include "DetectorDescription/DDCMS/interface/DDCompactView.h"
0014 #include "DetectorDescription/DDCMS/interface/DDFilteredView.h"
0015 #include "DetectorDescription/DDCMS/interface/DDSolidShapes.h"
0016 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0017
0018 #include "TGeoManager.h"
0019
0020 #include <cstddef>
0021 #include <fstream>
0022 #include <iomanip>
0023 #include <map>
0024 #include <memory>
0025 #include <ostream>
0026 #include <set>
0027 #include <string>
0028 #include <utility>
0029 #include <vector>
0030
0031 class OutputDD4hepToDDL : public edm::one::EDAnalyzer<edm::one::WatchRuns> {
0032 public:
0033 explicit OutputDD4hepToDDL(const edm::ParameterSet &iConfig);
0034 ~OutputDD4hepToDDL() override;
0035
0036 void beginJob() override {}
0037 void beginRun(edm::Run const &iEvent, edm::EventSetup const &) override;
0038 void analyze(edm::Event const &iEvent, edm::EventSetup const &) override {}
0039 void endRun(edm::Run const &iEvent, edm::EventSetup const &) override {}
0040 void endJob() override {}
0041
0042 private:
0043 edm::ESGetToken<cms::DDCompactView, IdealGeometryRecord> cpvTokendd4hep_;
0044 std::string m_fname;
0045 std::ostream *m_xos;
0046 };
0047
0048 OutputDD4hepToDDL::OutputDD4hepToDDL(const edm::ParameterSet &iConfig)
0049 : cpvTokendd4hep_(esConsumes<edm::Transition::BeginRun>(edm::ESInputTag("", "make-payload"))), m_fname() {
0050 m_fname = iConfig.getUntrackedParameter<std::string>("fileName");
0051 if (m_fname.empty()) {
0052 m_xos = &std::cout;
0053 } else {
0054 m_xos = new std::ofstream(m_fname.c_str());
0055 }
0056 (*m_xos) << "<?xml version=\"1.0\"?>" << std::endl;
0057 (*m_xos) << "<DDDefinition>" << std::endl;
0058 }
0059
0060 OutputDD4hepToDDL::~OutputDD4hepToDDL() {
0061 (*m_xos) << "</DDDefinition>" << std::endl;
0062 (*m_xos) << std::endl;
0063 m_xos->flush();
0064 }
0065
0066 void OutputDD4hepToDDL::beginRun(const edm::Run &, edm::EventSetup const &es) {
0067 std::cout << "OutputDD4hepToDDL::beginRun" << std::endl;
0068
0069 edm::ESTransientHandle<cms::DDCompactView> cpv = es.getTransientHandle(cpvTokendd4hep_);
0070
0071 const cms::DDDetector *det = cpv->detector();
0072 const dd4hep::Detector &detector = *det->description();
0073 const dd4hep::SpecParRegistry &specStore = det->specpars();
0074
0075 DDCoreToDDXMLOutput out;
0076
0077 std::string rn = m_fname;
0078 size_t foundLastDot = rn.find_last_of('.');
0079 size_t foundLastSlash = rn.find_last_of('/');
0080 if (foundLastSlash > foundLastDot && foundLastSlash != std::string::npos) {
0081 std::cout << "What? last . before last / in path for filename... this should die..." << std::endl;
0082 }
0083 std::string ns_("none");
0084 if (foundLastDot != std::string::npos && foundLastSlash != std::string::npos) {
0085 ns_ = rn.substr(foundLastSlash, foundLastDot);
0086 } else if (foundLastDot != std::string::npos) {
0087 ns_ = rn.substr(0, foundLastDot);
0088 } else {
0089 std::cout << "What? no file name? Attempt at namespace =\"" << ns_ << "\" filename was " << m_fname << std::endl;
0090 }
0091 std::cout << "m_fname = " << m_fname << " namespace = " << ns_ << std::endl;
0092
0093 (*m_xos) << std::fixed << std::setprecision(5);
0094 cms::DDParsingContext *const parsingContext = detector.extension<cms::DDParsingContext>();
0095
0096 {
0097
0098 using namespace angle_units::operators;
0099 cms::DDNamespace nameSpace(*parsingContext);
0100 dd4hep::Rotation3D rotation(1., 0., 0., 0., 1., 0., 0., 0., -1.);
0101 rotation = rotation * dd4hep::RotationY(1._pi);
0102 nameSpace.addRotation("ebalgo:reflZRotY", rotation);
0103 }
0104
0105 (*m_xos) << "<PosPartSection label=\"" << ns_ << "\">" << std::endl;
0106 const TGeoManager &mgr = detector.manager();
0107 for (const auto &&iter : *mgr.GetListOfVolumes()) {
0108 auto *vol = dynamic_cast<TGeoVolume *>(iter);
0109 int numDaughters = vol->GetNdaughters();
0110 if (numDaughters > 0) {
0111 auto nodeArray = vol->GetNodes();
0112 for (int index = 0; index < numDaughters; ++index) {
0113 auto *node = dynamic_cast<TGeoNode *>((*nodeArray)[index]);
0114 auto *childVol = node->GetVolume();
0115 out.position(*vol, *node, childVol->GetName(), *parsingContext, *m_xos);
0116 }
0117 }
0118 }
0119 (*m_xos) << "</PosPartSection>" << std::endl;
0120
0121 (*m_xos) << "<MaterialSection label=\"" << ns_ << "\">" << std::endl;
0122 for (const auto &&iter : *mgr.GetListOfMaterials()) {
0123 out.element(dynamic_cast<const TGeoMaterial *>(iter), *m_xos);
0124 }
0125
0126 for (const auto &it : parsingContext->compMaterialsVec) {
0127 const std::string &matName = it.first;
0128 out.material(matName, it.second, parsingContext->compMaterialsRefs[matName], *m_xos);
0129 }
0130 (*m_xos) << "</MaterialSection>" << std::endl;
0131 (*m_xos) << "<RotationSection label=\"" << ns_ << "\">" << std::endl;
0132 (*m_xos) << std::fixed << std::setprecision(10);
0133
0134 for (const auto &rotPair : parsingContext->rotRevMap) {
0135 out.rotation(parsingContext->rotations[rotPair.second], *m_xos, *parsingContext, rotPair.second);
0136 }
0137 (*m_xos) << "</RotationSection>" << std::endl;
0138
0139 (*m_xos) << std::fixed << std::setprecision(5);
0140 (*m_xos) << "<SolidSection label=\"" << ns_ << "\">" << std::endl;
0141 for (const auto &&iter : *mgr.GetListOfShapes()) {
0142 auto *shape = dynamic_cast<TGeoShape *>(iter);
0143 if (shape->IsValid()) {
0144 dd4hep::Solid solid(shape);
0145 if (strlen(shape->GetTitle()) > 1) {
0146 out.solid(solid, *parsingContext, *m_xos);
0147 } else {
0148 std::string name(DDCoreToDDXMLOutput::trimShapeName(shape->GetName()));
0149 if (name != "Box" && name != "Tubs") {
0150 if (dd4hep::isA<dd4hep::Tube>(solid)) {
0151 shape->SetTitle("Tube");
0152 out.solid(solid, *parsingContext, *m_xos);
0153 } else if (dd4hep::isA<dd4hep::Box>(solid)) {
0154 shape->SetTitle("Box");
0155 out.solid(solid, *parsingContext, *m_xos);
0156 } else if (dd4hep::isA<dd4hep::Trd1>(solid)) {
0157 shape->SetTitle("Trd1");
0158 out.solid(solid, *parsingContext, *m_xos);
0159 } else
0160 std::cout << "Division solid not a box, trd1, or tube = " << solid.name() << std::endl;
0161 }
0162 }
0163 }
0164 }
0165 for (const auto &asmEntry : parsingContext->assemblySolids) {
0166 (*m_xos) << "<Assembly name=\"" << asmEntry << "\"/>" << std::endl;
0167 }
0168 (*m_xos) << "</SolidSection>" << std::endl;
0169
0170 (*m_xos) << "<LogicalPartSection label=\"" << ns_ << "\">" << std::endl;
0171 for (const auto &&iter : *mgr.GetListOfVolumes()) {
0172 auto *vol = dynamic_cast<TGeoVolume *>(iter);
0173
0174 if (vol->GetRefCount() > 0 && vol->IsAssembly() == false) {
0175 out.logicalPart(*vol, *m_xos);
0176 }
0177 }
0178 for (const auto &asEntry : parsingContext->assemblies) {
0179 out.logicalPart(asEntry.first, *m_xos);
0180 }
0181 (*m_xos) << "</LogicalPartSection>" << std::endl;
0182
0183 (*m_xos) << std::fixed << std::setprecision(10);
0184 (*m_xos) << "<SpecParSection label=\"" << ns_ << "\">" << std::endl;
0185 for (const auto &specPar : specStore.specpars) {
0186 out.specpar(specPar.first, specPar.second, *m_xos);
0187 }
0188 (*m_xos) << "</SpecParSection>" << std::endl;
0189 }
0190
0191 DEFINE_FWK_MODULE(OutputDD4hepToDDL);