Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-25 01:48:57

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   Graph::index_type i = 0;
0146   (*m_xos) << "<PosPartSection label=\"" << ns_ << "\">\n";
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     ++i;
0157     if (!git->empty()) {
0158       // ask for children of ddLP
0159       auto cit = git->begin();
0160       auto cend = git->end();
0161       for (; cit != cend; ++cit) {
0162         const DDLogicalPart& ddcurLP = gra.nodeData(cit->first);
0163         if (lpStore.find(ddcurLP) != lpStore.end()) {
0164           addToSpecStore(ddcurLP, specStore);
0165         }
0166         lpStore.insert(ddcurLP);
0167         addToMatStore(ddcurLP.material(), matStore);
0168         addToSolStore(ddcurLP.solid(), solStore, rotStore);
0169         rotStore.insert(gra.edgeData(cit->second)->ddrot());
0170         out.position(ddLP, ddcurLP, gra.edgeData(cit->second), m_rotNumSeed, *m_xos);
0171       }  // iterate over children
0172     }    // if (children)
0173   }      // iterate over graph nodes
0174 
0175   (*m_xos) << "</PosPartSection>\n";
0176 
0177   (*m_xos) << std::scientific << std::setprecision(18);
0178   std::set<DDMaterial>::const_iterator it(matStore.begin()), ed(matStore.end());
0179   (*m_xos) << "<MaterialSection label=\"" << ns_ << "\">\n";
0180   for (; it != ed; ++it) {
0181     if (!it->isDefined().second)
0182       continue;
0183     out.material(*it, *m_xos);
0184   }
0185   (*m_xos) << "</MaterialSection>\n";
0186 
0187   (*m_xos) << "<RotationSection label=\"" << ns_ << "\">\n";
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>\n";
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_ << "\">\n";
0203   for (; sit != sed; ++sit) {
0204     if (!sit->isDefined().second)
0205       continue;
0206     out.solid(*sit, *m_xos);
0207   }
0208   (*m_xos) << "</SolidSection>\n";
0209 
0210   std::set<DDLogicalPart>::iterator lpit(lpStore.begin()), lped(lpStore.end());
0211   (*m_xos) << "<LogicalPartSection label=\"" << ns_ << "\">\n";
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>\n";
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_ << "\">\n";
0224   for (; mit != mend; ++mit) {
0225     out.specpar(*mit, *m_xos);
0226   }
0227   (*m_xos) << "</SpecParSection>\n";
0228 }
0229 
0230 void OutputMagneticFieldDDToDDL::addToMatStore(const DDMaterial& mat, std::set<DDMaterial>& matStore) {
0231   matStore.insert(mat);
0232   if (mat.noOfConstituents() != 0) {
0233     DDMaterial::FractionV::value_type frac;
0234     int findex(0);
0235     while (findex < mat.noOfConstituents()) {
0236       if (matStore.find(mat.constituent(findex).first) == matStore.end()) {
0237         addToMatStore(mat.constituent(findex).first, matStore);
0238       }
0239       ++findex;
0240     }
0241   }
0242 }
0243 
0244 void OutputMagneticFieldDDToDDL::addToSolStore(const DDSolid& sol,
0245                                                std::set<DDSolid>& solStore,
0246                                                std::set<DDRotation>& rotStore) {
0247   solStore.insert(sol);
0248   if (sol.shape() == DDSolidShape::ddunion || sol.shape() == DDSolidShape::ddsubtraction ||
0249       sol.shape() == DDSolidShape::ddintersection) {
0250     const DDBooleanSolid& bs(sol);
0251     if (solStore.find(bs.solidA()) == solStore.end()) {
0252       addToSolStore(bs.solidA(), solStore, rotStore);
0253     }
0254     if (solStore.find(bs.solidB()) == solStore.end()) {
0255       addToSolStore(bs.solidB(), solStore, rotStore);
0256     }
0257     rotStore.insert(bs.rotation());
0258   }
0259 }
0260 
0261 void OutputMagneticFieldDDToDDL::addToSpecStore(
0262     const DDLogicalPart& lp,
0263     std::map<const DDsvalues_type, std::set<const DDPartSelection*>, ddsvaluesCmp>& specStore) {
0264   std::vector<std::pair<const DDPartSelection*, const DDsvalues_type*> >::const_iterator spit(
0265       lp.attachedSpecifics().begin()),
0266       spend(lp.attachedSpecifics().end());
0267   for (; spit != spend; ++spit) {
0268     specStore[*spit->second].insert(spit->first);
0269   }
0270 }
0271 
0272 DEFINE_FWK_MODULE(OutputMagneticFieldDDToDDL);