Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-02-08 06:27:48

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   Graph::index_type i = 0;
0147   (*m_xos) << "<PosPartSection label=\"" << ns_ << "\">" << std::endl;
0148   git = gra.begin();
0149   for (; git != gend; ++git) {
0150     const DDLogicalPart& ddLP = gra.nodeData(git);
0151     if (lpStore.find(ddLP) != lpStore.end()) {
0152       addToSpecStore(ddLP, specStore);
0153     }
0154     lpStore.insert(ddLP);
0155     addToMatStore(ddLP.material(), matStore);
0156     addToSolStore(ddLP.solid(), solStore, rotStore);
0157     ++i;
0158     if (!git->empty()) {
0159       // ask for children of ddLP
0160       auto cit = git->begin();
0161       auto cend = git->end();
0162       for (; cit != cend; ++cit) {
0163         const DDLogicalPart& ddcurLP = gra.nodeData(cit->first);
0164         if (lpStore.find(ddcurLP) != lpStore.end()) {
0165           addToSpecStore(ddcurLP, specStore);
0166         }
0167         lpStore.insert(ddcurLP);
0168         addToMatStore(ddcurLP.material(), matStore);
0169         addToSolStore(ddcurLP.solid(), solStore, rotStore);
0170         rotStore.insert(gra.edgeData(cit->second)->ddrot());
0171         out.position(ddLP, ddcurLP, gra.edgeData(cit->second), m_rotNumSeed, *m_xos);
0172       }  // iterate over children
0173     }    // if (children)
0174   }      // iterate over graph nodes
0175 
0176   (*m_xos) << "</PosPartSection>" << std::endl;
0177 
0178   (*m_xos) << std::scientific << std::setprecision(18);
0179 
0180   (*m_xos) << "<MaterialSection label=\"" << ns_ << "\">" << std::endl;
0181   for (const auto& it : matStore) {
0182     if (!it.isDefined().second)
0183       continue;
0184     out.material(it, *m_xos);
0185   }
0186   (*m_xos) << "</MaterialSection>" << std::endl;
0187   (*m_xos) << "<RotationSection label=\"" << ns_ << "\">" << std::endl;
0188   (*m_xos) << std::fixed << std::setprecision(18);
0189   std::set<DDRotation>::iterator rit(rotStore.begin()), red(rotStore.end());
0190   for (; rit != red; ++rit) {
0191     if (!rit->isDefined().second)
0192       continue;
0193     if (rit->toString() != ":") {
0194       DDRotation r(*rit);
0195       out.rotation(r, *m_xos);
0196     }
0197   }
0198   (*m_xos) << "</RotationSection>" << std::endl;
0199 
0200   (*m_xos) << std::fixed << std::setprecision(18);
0201   std::set<DDSolid>::const_iterator sit(solStore.begin()), sed(solStore.end());
0202   (*m_xos) << "<SolidSection label=\"" << ns_ << "\">" << std::endl;
0203   for (; sit != sed; ++sit) {
0204     if (!sit->isDefined().second)
0205       continue;
0206     out.solid(*sit, *m_xos);
0207   }
0208   (*m_xos) << "</SolidSection>" << std::endl;
0209 
0210   std::set<DDLogicalPart>::iterator lpit(lpStore.begin()), lped(lpStore.end());
0211   (*m_xos) << "<LogicalPartSection label=\"" << ns_ << "\">" << std::endl;
0212   for (; lpit != lped; ++lpit) {
0213     if (!lpit->isDefined().first)
0214       continue;
0215     const DDLogicalPart& lp = *lpit;
0216     out.logicalPart(lp, *m_xos);
0217   }
0218   (*m_xos) << "</LogicalPartSection>" << std::endl;
0219 
0220   (*m_xos) << std::fixed << std::setprecision(18);
0221   std::map<DDsvalues_type, std::set<const DDPartSelection*> >::const_iterator mit(specStore.begin()),
0222       mend(specStore.end());
0223   (*m_xos) << "<SpecParSection label=\"" << ns_ << "\">" << std::endl;
0224   for (; mit != mend; ++mit) {
0225     out.specpar(*mit, *m_xos);
0226   }
0227   (*m_xos) << "</SpecParSection>" << std::endl;
0228 }
0229 
0230 void OutputDDToDDL::addToMatStore(const DDMaterial& mat, std::set<DDMaterial>& matStore) {
0231   matStore.insert(mat);
0232   if (mat.noOfConstituents() != 0) {
0233     int findex(0);
0234     while (findex < mat.noOfConstituents()) {
0235       if (matStore.find(mat.constituent(findex).first) == matStore.end()) {
0236         addToMatStore(mat.constituent(findex).first, matStore);
0237       }
0238       ++findex;
0239     }
0240   }
0241 }
0242 
0243 void OutputDDToDDL::addToSolStore(const DDSolid& sol, std::set<DDSolid>& solStore, std::set<DDRotation>& rotStore) {
0244   solStore.insert(sol);
0245   if (sol.shape() == DDSolidShape::ddunion || sol.shape() == DDSolidShape::ddsubtraction ||
0246       sol.shape() == DDSolidShape::ddintersection) {
0247     const DDBooleanSolid& bs(sol);
0248     if (solStore.find(bs.solidA()) == solStore.end()) {
0249       addToSolStore(bs.solidA(), solStore, rotStore);
0250     }
0251     if (solStore.find(bs.solidB()) == solStore.end()) {
0252       addToSolStore(bs.solidB(), solStore, rotStore);
0253     }
0254     rotStore.insert(bs.rotation());
0255   }
0256 }
0257 
0258 void OutputDDToDDL::addToSpecStore(
0259     const DDLogicalPart& lp,
0260     std::map<const DDsvalues_type, std::set<const DDPartSelection*>, ddsvaluesCmp>& specStore) {
0261   for (auto spit : lp.attachedSpecifics()) {
0262     specStore[*spit.second].insert(spit.first);
0263   }
0264 }
0265 
0266 DEFINE_FWK_MODULE(OutputDDToDDL);