Back to home page

Project CMSSW displayed by LXR

 
 

    


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);  // Precison to 1e-5 mm
0094   cms::DDParsingContext *const parsingContext = detector.extension<cms::DDParsingContext>();
0095 
0096   {
0097     // Add rotation for reference and to ease validation
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   // Output composite materials
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);  // Rounds angles to integer values w/o loss of accuracy
0133   // rotRevMap has the unique rotations
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") {  // Skip solids with degenerate names
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     // Skip unused logical parts and assemblies, which are listed separately
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);  // Some Tracker values specified to 1e-9
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);