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