Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:35:58

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/Framework/interface/MakerMacros.h"
0007 #include "DetectorDescription/OfflineDBLoader/interface/DDCoreToDDXMLOutput.h"
0008 #include "DetectorDescription/Core/interface/DDCompactView.h"
0009 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0010 #include "DetectorDescription/Core/interface/DDMaterial.h"
0011 #include "DetectorDescription/Core/interface/DDPosData.h"
0012 #include "DetectorDescription/Core/interface/DDSolid.h"
0013 #include "DetectorDescription/Core/interface/DDSolidShapes.h"
0014 #include "DetectorDescription/Core/interface/DDTransform.h"
0015 #include "DetectorDescription/Core/interface/DDsvalues.h"
0016 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0017 
0018 #include <cstddef>
0019 #include <fstream>
0020 #include <iomanip>
0021 #include <map>
0022 #include <memory>
0023 #include <ostream>
0024 #include <set>
0025 #include <string>
0026 #include <utility>
0027 #include <vector>
0028 
0029 namespace {
0030   /// is sv1 < sv2
0031   struct ddsvaluesCmp {
0032     bool operator()(const DDsvalues_type& sv1, const DDsvalues_type& sv2) const;
0033   };
0034 }  // namespace
0035 
0036 class OutputDDToDDL : public edm::one::EDAnalyzer<edm::one::WatchRuns> {
0037 public:
0038   explicit OutputDDToDDL(const edm::ParameterSet& iConfig);
0039   ~OutputDDToDDL() override;
0040 
0041   void beginJob() override {}
0042   void beginRun(edm::Run const& iEvent, edm::EventSetup const&) override;
0043   void analyze(edm::Event const& iEvent, edm::EventSetup const&) override {}
0044   void endRun(edm::Run const& iEvent, edm::EventSetup const&) override {}
0045   void endJob() override {}
0046 
0047 private:
0048   void addToMatStore(const DDMaterial& mat, std::set<DDMaterial>& matStore);
0049   void addToSolStore(const DDSolid& sol, std::set<DDSolid>& solStore, std::set<DDRotation>& rotStore);
0050   void addToSpecStore(const DDLogicalPart& lp,
0051                       std::map<const DDsvalues_type, std::set<const DDPartSelection*>, ddsvaluesCmp>& specStore);
0052 
0053   int m_rotNumSeed;
0054   std::string m_fname;
0055   std::ostream* m_xos;
0056   edm::ESGetToken<DDCompactView, IdealGeometryRecord> ddToken_;
0057 };
0058 
0059 bool ddsvaluesCmp::operator()(const DDsvalues_type& sv1, const DDsvalues_type& sv2) const {
0060   if (sv1.size() < sv2.size())
0061     return true;
0062   if (sv2.size() < sv1.size())
0063     return false;
0064 
0065   size_t ind = 0;
0066   for (; ind < sv1.size(); ++ind) {
0067     if (sv1[ind].first < sv2[ind].first)
0068       return true;
0069     if (sv2[ind].first < sv1[ind].first)
0070       return false;
0071     if (sv1[ind].second < sv2[ind].second)
0072       return true;
0073     if (sv2[ind].second < sv1[ind].second)
0074       return false;
0075   }
0076   return false;
0077 }
0078 
0079 OutputDDToDDL::OutputDDToDDL(const edm::ParameterSet& iConfig) : m_fname() {
0080   m_rotNumSeed = iConfig.getParameter<int>("rotNumSeed");
0081   m_fname = iConfig.getUntrackedParameter<std::string>("fileName");
0082   if (m_fname.empty()) {
0083     m_xos = &std::cout;
0084   } else {
0085     m_xos = new std::ofstream(m_fname.c_str());
0086   }
0087   (*m_xos) << "<?xml version=\"1.0\"?>" << std::endl;
0088   (*m_xos) << "<DDDefinition xmlns=\"http://www.cern.ch/cms/DDL\"" << std::endl;
0089   (*m_xos) << " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" << std::endl;
0090   (*m_xos) << "xsi:schemaLocation=\"http://www.cern.ch/cms/DDL ../../../DetectorDescription/Schema/DDLSchema.xsd\">"
0091            << std::endl;
0092   (*m_xos) << std::fixed << std::setprecision(18);
0093 
0094   ddToken_ = esConsumes<DDCompactView, IdealGeometryRecord, edm::Transition::BeginRun>();
0095 }
0096 
0097 OutputDDToDDL::~OutputDDToDDL() {
0098   (*m_xos) << "</DDDefinition>" << std::endl;
0099   (*m_xos) << std::endl;
0100   m_xos->flush();
0101 }
0102 
0103 void OutputDDToDDL::beginRun(const edm::Run&, edm::EventSetup const& es) {
0104   std::cout << "OutputDDToDDL::beginRun" << std::endl;
0105 
0106   edm::ESTransientHandle<DDCompactView> pDD = es.getTransientHandle(ddToken_);
0107 
0108   using Graph = DDCompactView::Graph;
0109   using adjl_iterator = Graph::const_adj_iterator;
0110 
0111   const auto& gra = pDD->graph();
0112   // temporary stores:
0113   std::set<DDLogicalPart> lpStore;
0114   std::set<DDMaterial> matStore;
0115   std::set<DDSolid> solStore;
0116   // 2009-08-19: MEC: I've tried this with set<DDPartSelection> and
0117   // had to write operator< for DDPartSelection and DDPartSelectionLevel
0118   // the output from such an effort is different than this one.
0119   std::map<const DDsvalues_type, std::set<const DDPartSelection*>, ddsvaluesCmp> specStore;
0120   std::set<DDRotation> rotStore;
0121 
0122   DDCoreToDDXMLOutput out;
0123 
0124   std::string rn = m_fname;
0125   size_t foundLastDot = rn.find_last_of('.');
0126   size_t foundLastSlash = rn.find_last_of('/');
0127   if (foundLastSlash > foundLastDot && foundLastSlash != std::string::npos) {
0128     std::cout << "What? last . before last / in path for filename... this should die..." << std::endl;
0129   }
0130   if (foundLastDot != std::string::npos && foundLastSlash != std::string::npos) {
0131     out.ns_ = rn.substr(foundLastSlash, foundLastDot);
0132   } else if (foundLastDot != std::string::npos) {
0133     out.ns_ = rn.substr(0, foundLastDot);
0134   } else {
0135     std::cout << "What? no file name? Attempt at namespace =\"" << out.ns_ << "\" filename was " << m_fname
0136               << std::endl;
0137   }
0138   std::cout << "m_fname = " << m_fname << " namespace = " << out.ns_ << std::endl;
0139   std::string ns_ = out.ns_;
0140 
0141   (*m_xos) << std::fixed << std::setprecision(18);
0142 
0143   adjl_iterator git = gra.begin();
0144   adjl_iterator gend = gra.end();
0145 
0146   (*m_xos) << "<PosPartSection label=\"" << ns_ << "\">" << std::endl;
0147   git = gra.begin();
0148   for (; git != gend; ++git) {
0149     const DDLogicalPart& ddLP = gra.nodeData(git);
0150     if (lpStore.find(ddLP) != lpStore.end()) {
0151       addToSpecStore(ddLP, specStore);
0152     }
0153     lpStore.insert(ddLP);
0154     addToMatStore(ddLP.material(), matStore);
0155     addToSolStore(ddLP.solid(), solStore, rotStore);
0156     if (!git->empty()) {
0157       // ask for children of ddLP
0158       auto cit = git->begin();
0159       auto cend = git->end();
0160       for (; cit != cend; ++cit) {
0161         const DDLogicalPart& ddcurLP = gra.nodeData(cit->first);
0162         if (lpStore.find(ddcurLP) != lpStore.end()) {
0163           addToSpecStore(ddcurLP, specStore);
0164         }
0165         lpStore.insert(ddcurLP);
0166         addToMatStore(ddcurLP.material(), matStore);
0167         addToSolStore(ddcurLP.solid(), solStore, rotStore);
0168         rotStore.insert(gra.edgeData(cit->second)->ddrot());
0169         out.position(ddLP, ddcurLP, gra.edgeData(cit->second), m_rotNumSeed, *m_xos);
0170       }  // iterate over children
0171     }  // if (children)
0172   }  // iterate over graph nodes
0173 
0174   (*m_xos) << "</PosPartSection>" << std::endl;
0175 
0176   (*m_xos) << std::scientific << std::setprecision(18);
0177 
0178   (*m_xos) << "<MaterialSection label=\"" << ns_ << "\">" << std::endl;
0179   for (const auto& it : matStore) {
0180     if (!it.isDefined().second)
0181       continue;
0182     out.material(it, *m_xos);
0183   }
0184   (*m_xos) << "</MaterialSection>" << std::endl;
0185   (*m_xos) << "<RotationSection label=\"" << ns_ << "\">" << std::endl;
0186   (*m_xos) << std::fixed << std::setprecision(18);
0187   std::set<DDRotation>::iterator rit(rotStore.begin()), red(rotStore.end());
0188   for (; rit != red; ++rit) {
0189     if (!rit->isDefined().second)
0190       continue;
0191     if (rit->toString() != ":") {
0192       const DDRotation& r(*rit);
0193       out.rotation(r, *m_xos);
0194     }
0195   }
0196   (*m_xos) << "</RotationSection>" << std::endl;
0197 
0198   (*m_xos) << std::fixed << std::setprecision(18);
0199   std::set<DDSolid>::const_iterator sit(solStore.begin()), sed(solStore.end());
0200   (*m_xos) << "<SolidSection label=\"" << ns_ << "\">" << std::endl;
0201   for (; sit != sed; ++sit) {
0202     if (!sit->isDefined().second)
0203       continue;
0204     out.solid(*sit, *m_xos);
0205   }
0206   (*m_xos) << "</SolidSection>" << std::endl;
0207 
0208   std::set<DDLogicalPart>::iterator lpit(lpStore.begin()), lped(lpStore.end());
0209   (*m_xos) << "<LogicalPartSection label=\"" << ns_ << "\">" << std::endl;
0210   for (; lpit != lped; ++lpit) {
0211     if (!lpit->isDefined().first)
0212       continue;
0213     const DDLogicalPart& lp = *lpit;
0214     out.logicalPart(lp, *m_xos);
0215   }
0216   (*m_xos) << "</LogicalPartSection>" << std::endl;
0217 
0218   (*m_xos) << std::fixed << std::setprecision(18);
0219   std::map<DDsvalues_type, std::set<const DDPartSelection*> >::const_iterator mit(specStore.begin()),
0220       mend(specStore.end());
0221   (*m_xos) << "<SpecParSection label=\"" << ns_ << "\">" << std::endl;
0222   for (; mit != mend; ++mit) {
0223     out.specpar(*mit, *m_xos);
0224   }
0225   (*m_xos) << "</SpecParSection>" << std::endl;
0226 }
0227 
0228 void OutputDDToDDL::addToMatStore(const DDMaterial& mat, std::set<DDMaterial>& matStore) {
0229   matStore.insert(mat);
0230   if (mat.noOfConstituents() != 0) {
0231     int findex(0);
0232     while (findex < mat.noOfConstituents()) {
0233       if (matStore.find(mat.constituent(findex).first) == matStore.end()) {
0234         addToMatStore(mat.constituent(findex).first, matStore);
0235       }
0236       ++findex;
0237     }
0238   }
0239 }
0240 
0241 void OutputDDToDDL::addToSolStore(const DDSolid& sol, std::set<DDSolid>& solStore, std::set<DDRotation>& rotStore) {
0242   solStore.insert(sol);
0243   if (sol.shape() == DDSolidShape::ddunion || sol.shape() == DDSolidShape::ddsubtraction ||
0244       sol.shape() == DDSolidShape::ddintersection) {
0245     const DDBooleanSolid& bs(sol);
0246     if (solStore.find(bs.solidA()) == solStore.end()) {
0247       addToSolStore(bs.solidA(), solStore, rotStore);
0248     }
0249     if (solStore.find(bs.solidB()) == solStore.end()) {
0250       addToSolStore(bs.solidB(), solStore, rotStore);
0251     }
0252     rotStore.insert(bs.rotation());
0253   }
0254 }
0255 
0256 void OutputDDToDDL::addToSpecStore(
0257     const DDLogicalPart& lp,
0258     std::map<const DDsvalues_type, std::set<const DDPartSelection*>, ddsvaluesCmp>& specStore) {
0259   for (auto spit : lp.attachedSpecifics()) {
0260     specStore[*spit.second].insert(spit.first);
0261   }
0262 }
0263 
0264 DEFINE_FWK_MODULE(OutputDDToDDL);