Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 13:02:44

0001 /** \file
0002  *
0003  *  \author N. Amapane - CERN
0004  */
0005 #include "CondFormats/Alignment/interface/DetectorGlobalPosition.h"
0006 #include "CondFormats/Alignment/interface/AlignmentErrorsExtended.h"
0007 #include "CondFormats/AlignmentRecord/interface/GlobalPositionRcd.h"
0008 #include "CondFormats/AlignmentRecord/interface/DTAlignmentRcd.h"
0009 #include "CondFormats/AlignmentRecord/interface/DTAlignmentErrorRcd.h"
0010 #include "CondFormats/AlignmentRecord/interface/DTAlignmentErrorExtendedRcd.h"
0011 #include "CondFormats/GeometryObjects/interface/RecoIdealGeometry.h"
0012 #include "DataFormats/GeometrySurface/interface/Plane.h"
0013 #include "DataFormats/GeometrySurface/interface/Bounds.h"
0014 #include "DataFormats/GeometrySurface/interface/RectangularPlaneBounds.h"
0015 #include "DetectorDescription/Core/interface/DDCompactView.h"
0016 #include "DetectorDescription/DDCMS/interface/DDSpecParRegistry.h"
0017 #include "DetectorDescription/DDCMS/interface/DDDetector.h"
0018 #include "DetectorDescription/DDCMS/interface/DDFilteredView.h"
0019 #include "DetectorDescription/DDCMS/interface/BenchmarkGrd.h"
0020 #include "FWCore/Framework/interface/ESTransientHandle.h"
0021 #include "FWCore/Framework/interface/ModuleFactory.h"
0022 #include "FWCore/Framework/interface/ESProducer.h"
0023 #include "FWCore/Framework/interface/ESProductHost.h"
0024 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0025 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0026 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0027 #include "FWCore/Utilities/interface/ESGetToken.h"
0028 #include "FWCore/Utilities/interface/ReusableObjectHolder.h"
0029 #include "Geometry/CommonTopologies/interface/GeometryAligner.h"
0030 #include "Geometry/Records/interface/DTRecoGeometryRcd.h"
0031 #include "Geometry/MuonNumbering/interface/MuonGeometryNumbering.h"
0032 #include "Geometry/MuonNumbering/interface/MuonGeometryConstants.h"
0033 #include "Geometry/Records/interface/MuonNumberingRecord.h"
0034 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0035 #include "Geometry/Records/interface/DDSpecParRegistryRcd.h"
0036 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0037 #include "Geometry/DTGeometry/interface/DTGeometry.h"
0038 #include "Geometry/DTGeometryBuilder/src/DTGeometryBuilderFromDDD.h"
0039 #include "Geometry/DTGeometryBuilder/src/DTGeometryBuilderFromDD4hep.h"
0040 #include "Geometry/DTGeometryBuilder/src/DTGeometryBuilderFromCondDB.h"
0041 
0042 #include <memory>
0043 #include <iostream>
0044 #include <iterator>
0045 #include <string>
0046 
0047 using namespace edm;
0048 using namespace std;
0049 
0050 class DTGeometryESModule : public edm::ESProducer {
0051 public:
0052   /// Constructor
0053   DTGeometryESModule(const edm::ParameterSet& p);
0054 
0055   /// Creation of configuration file
0056   static void fillDescriptions(edm::ConfigurationDescriptions&);
0057 
0058   /// Produce DTGeometry.
0059   std::shared_ptr<DTGeometry> produce(const MuonGeometryRecord& record);
0060 
0061 private:
0062   using HostType = edm::ESProductHost<DTGeometry, MuonNumberingRecord, DTRecoGeometryRcd>;
0063 
0064   void setupDDDGeometry(MuonNumberingRecord const&, std::shared_ptr<HostType>&);
0065   void setupDD4hepGeometry(MuonNumberingRecord const&, std::shared_ptr<HostType>&);
0066   void setupDBGeometry(DTRecoGeometryRcd const&, std::shared_ptr<HostType>&);
0067 
0068   edm::ReusableObjectHolder<HostType> holder_;
0069 
0070   edm::ESGetToken<Alignments, GlobalPositionRcd> globalPositionToken_;
0071   edm::ESGetToken<Alignments, DTAlignmentRcd> alignmentsToken_;
0072   edm::ESGetToken<AlignmentErrorsExtended, DTAlignmentErrorExtendedRcd> alignmentErrorsToken_;
0073   edm::ESGetToken<MuonGeometryConstants, IdealGeometryRecord> mdcToken_;
0074   edm::ESGetToken<DDCompactView, IdealGeometryRecord> cpvToken_;
0075   edm::ESGetToken<cms::DDDetector, IdealGeometryRecord> m_cpvToken;
0076   edm::ESGetToken<cms::DDSpecParRegistry, DDSpecParRegistryRcd> m_registryToken;
0077   edm::ESGetToken<RecoIdealGeometry, DTRecoGeometryRcd> rigToken_;
0078 
0079   const edm::ESInputTag m_tag;
0080   const std::string alignmentsLabel_;
0081   const std::string myLabel_;
0082   const std::string m_attribute;
0083   const std::string m_value;
0084   bool fromDDD_;
0085   bool fromDD4hep_;
0086   bool applyAlignment_;  // Switch to apply alignment corrections
0087 };
0088 
0089 DTGeometryESModule::DTGeometryESModule(const edm::ParameterSet& p)
0090     : m_tag(p.getParameter<edm::ESInputTag>("DDDetector")),
0091       alignmentsLabel_(p.getParameter<std::string>("alignmentsLabel")),
0092       myLabel_(p.getParameter<std::string>("appendToDataLabel")),
0093       m_attribute(p.getParameter<std::string>("attribute")),
0094       m_value(p.getParameter<std::string>("value")),
0095       fromDDD_(p.getParameter<bool>("fromDDD")),
0096       fromDD4hep_(p.getParameter<bool>("fromDD4hep")) {
0097   applyAlignment_ = p.getParameter<bool>("applyAlignment");
0098 
0099   auto cc = setWhatProduced(this);
0100   if (applyAlignment_) {
0101     globalPositionToken_ = cc.consumesFrom<Alignments, GlobalPositionRcd>(edm::ESInputTag{"", alignmentsLabel_});
0102     alignmentsToken_ = cc.consumesFrom<Alignments, DTAlignmentRcd>(edm::ESInputTag{"", alignmentsLabel_});
0103     alignmentErrorsToken_ =
0104         cc.consumesFrom<AlignmentErrorsExtended, DTAlignmentErrorExtendedRcd>(edm::ESInputTag{"", alignmentsLabel_});
0105   }
0106   if (fromDDD_) {
0107     mdcToken_ = cc.consumesFrom<MuonGeometryConstants, IdealGeometryRecord>(edm::ESInputTag{});
0108     cpvToken_ = cc.consumesFrom<DDCompactView, IdealGeometryRecord>(edm::ESInputTag{});
0109   } else if (fromDD4hep_) {
0110     mdcToken_ = cc.consumesFrom<MuonGeometryConstants, IdealGeometryRecord>(edm::ESInputTag{});
0111     m_cpvToken = cc.consumesFrom<cms::DDDetector, IdealGeometryRecord>(m_tag);
0112     m_registryToken = cc.consumesFrom<cms::DDSpecParRegistry, DDSpecParRegistryRcd>(m_tag);
0113   } else {
0114     rigToken_ = cc.consumesFrom<RecoIdealGeometry, DTRecoGeometryRcd>(edm::ESInputTag{});
0115   }
0116 
0117   edm::LogVerbatim("Geometry") << "@SUB=DTGeometryESModule Label '" << myLabel_ << "' "
0118                                << (applyAlignment_ ? "looking for" : "IGNORING") << " alignment labels '"
0119                                << alignmentsLabel_ << "'.";
0120 }
0121 
0122 void DTGeometryESModule::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0123   //
0124   // This cfi should be included to build the DT geometry model.
0125   //
0126   edm::ParameterSetDescription desc;
0127   desc.add<bool>("fromDDD", true);
0128   desc.add<bool>("fromDD4hep", false);
0129   desc.add<edm::ESInputTag>("DDDetector", edm::ESInputTag("", ""));
0130   desc.add<std::string>("alignmentsLabel", "");
0131   desc.add<std::string>("appendToDataLabel", "");
0132   desc.add<std::string>("attribute", "MuStructure");
0133   desc.add<std::string>("value", "MuonBarrelDT");
0134   desc.add<bool>("applyAlignment", true);
0135   descriptions.add("DTGeometryESModule", desc);
0136 }
0137 
0138 std::shared_ptr<DTGeometry> DTGeometryESModule::produce(const MuonGeometryRecord& record) {
0139   auto host = holder_.makeOrGet([]() { return new HostType; });
0140 
0141   if (fromDDD_) {
0142     host->ifRecordChanges<MuonNumberingRecord>(record, [this, &host](auto const& rec) { setupDDDGeometry(rec, host); });
0143   } else if (fromDD4hep_) {
0144     host->ifRecordChanges<MuonNumberingRecord>(record,
0145                                                [this, &host](auto const& rec) { setupDD4hepGeometry(rec, host); });
0146   } else {
0147     host->ifRecordChanges<DTRecoGeometryRcd>(record, [this, &host](auto const& rec) { setupDBGeometry(rec, host); });
0148   }
0149   //
0150   // Called whenever the alignments or alignment errors change
0151   //
0152   if (applyAlignment_) {
0153     // applyAlignment_ is scheduled for removal.
0154     // Ideal geometry obtained by using 'fake alignment' (with applyAlignment_ = true)
0155     const auto& globalPosition = record.get(globalPositionToken_);
0156     const auto& alignments = record.get(alignmentsToken_);
0157     const auto& alignmentErrors = record.get(alignmentErrorsToken_);
0158     // Only apply alignment if values exist
0159     if (alignments.empty() && alignmentErrors.empty() && globalPosition.empty()) {
0160       edm::LogVerbatim("Geometry") << "@SUB=DTGeometryRecord::produce Alignment(Error)s and global position (label '"
0161                                    << alignmentsLabel_ << "') empty: Geometry producer (label '" << myLabel_
0162                                    << "') assumes fake and does not apply.";
0163     } else {
0164       GeometryAligner aligner;
0165       aligner.applyAlignments<DTGeometry>(
0166           &(*host), &alignments, &alignmentErrors, align::DetectorGlobalPosition(globalPosition, DetId(DetId::Muon)));
0167     }
0168   }
0169 
0170   return host;  // automatically converts to std::shared_ptr<DTGeometry>
0171 }
0172 
0173 void DTGeometryESModule::setupDDDGeometry(const MuonNumberingRecord& record, std::shared_ptr<HostType>& host) {
0174   //
0175   // Called whenever the muon numbering (or ideal geometry) changes
0176   //
0177 
0178   host->clear();
0179 
0180   const auto& mdc = record.get(mdcToken_);
0181   edm::ESTransientHandle<DDCompactView> cpv = record.getTransientHandle(cpvToken_);
0182 
0183   DTGeometryBuilderFromDDD builder;
0184   builder.build(*host, cpv.product(), mdc);
0185 }
0186 
0187 void DTGeometryESModule::setupDD4hepGeometry(const MuonNumberingRecord& record, std::shared_ptr<HostType>& host) {
0188   host->clear();
0189 
0190   const auto& mdc = record.get(mdcToken_);
0191   edm::ESTransientHandle<cms::DDDetector> cpv = record.getTransientHandle(m_cpvToken);
0192   ESTransientHandle<cms::DDSpecParRegistry> registry = record.getTransientHandle(m_registryToken);
0193 
0194   cms::DDSpecParRefs myReg;
0195   registry->filter(myReg, m_attribute, m_value);
0196 
0197   DTGeometryBuilderFromDD4hep builder;
0198   builder.build(*host, cpv.product(), mdc, myReg);
0199 }
0200 
0201 void DTGeometryESModule::setupDBGeometry(const DTRecoGeometryRcd& record, std::shared_ptr<HostType>& host) {
0202   //
0203   // Called whenever the muon numbering (or ideal geometry) changes
0204   //
0205 
0206   host->clear();
0207 
0208   const auto& rig = record.get(rigToken_);
0209 
0210   DTGeometryBuilderFromCondDB builder;
0211   builder.build(host, rig);
0212 }
0213 
0214 DEFINE_FWK_EVENTSETUP_MODULE(DTGeometryESModule);