File indexing completed on 2022-12-02 10:36:00
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
0031 struct ddsvaluesCmp {
0032 bool operator()(const DDsvalues_type& sv1, const DDsvalues_type& sv2) const;
0033 };
0034 }
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
0113 std::set<DDLogicalPart> lpStore;
0114 std::set<DDMaterial> matStore;
0115 std::set<DDSolid> solStore;
0116
0117
0118
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
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 }
0173 }
0174 }
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 const 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);