Back to home page

Project CMSSW displayed by LXR

 
 

    


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   /// is sv1 < sv2
0029   struct ddsvaluesCmp {
0030     bool operator()(const DDsvalues_type& sv1, const DDsvalues_type& sv2) const;
0031   };
0032 }  // namespace
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   // Temporary stores:
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       // ask for children of ddLP
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       }  // iterate over children
0170     }  // if (children)
0171   }  // iterate over graph nodes
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);