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
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 (*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
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 }
0171 }
0172 }
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);