Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:14:25

0001 /*
0002 // \class CSCGeometryESModule
0003 //
0004 //  Description: CSC ESModule for DD4hep
0005 //              
0006 //
0007 // \author Sergio Lo Meo (sergio.lo.meo@cern.ch) following what Ianna Osborne made for DTs (DD4hep migration)
0008 //         Created:  Thu, 05 March 2020 
0009 //         Modified: Thu, 04 June 2020, following what made in PR #30047               
0010 //
0011 //         Original author: Tim Cox
0012 */
0013 
0014 #include "FWCore/Framework/interface/ESProducer.h"
0015 #include "FWCore/Framework/interface/ESProductHost.h"
0016 #include "FWCore/Framework/interface/ESTransientHandle.h"
0017 #include "FWCore/Framework/interface/ModuleFactory.h"
0018 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0019 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0020 #include "FWCore/Utilities/interface/ESGetToken.h"
0021 #include "FWCore/Utilities/interface/ReusableObjectHolder.h"
0022 #include "Geometry/CSCGeometryBuilder/src/CSCGeometryBuilderFromDDD.h"
0023 #include "Geometry/CSCGeometryBuilder/src/CSCGeometryBuilder.h"
0024 #include "Geometry/CSCGeometry/interface/CSCGeometry.h"
0025 #include "Geometry/CSCGeometry/interface/CSCChamberSpecs.h"
0026 #include "Geometry/CommonTopologies/interface/GeometryAligner.h"
0027 #include "Geometry/MuonNumbering/interface/MuonGeometryConstants.h"
0028 #include "Geometry/Records/interface/MuonNumberingRecord.h"
0029 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0030 #include "DetectorDescription/Core/interface/DDCompactView.h"
0031 #include "DetectorDescription/DDCMS/interface/DDCompactView.h"
0032 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0033 #include "Geometry/Records/interface/CSCRecoGeometryRcd.h"
0034 #include "Geometry/Records/interface/CSCRecoDigiParametersRcd.h"
0035 #include "Geometry/MuonNumbering/interface/MuonGeometryConstants.h"
0036 #include "CondFormats/GeometryObjects/interface/RecoIdealGeometry.h"
0037 #include "CondFormats/GeometryObjects/interface/CSCRecoDigiParameters.h"
0038 
0039 // Alignments
0040 #include "CondFormats/Alignment/interface/DetectorGlobalPosition.h"
0041 #include "CondFormats/Alignment/interface/AlignmentErrorsExtended.h"
0042 #include "CondFormats/AlignmentRecord/interface/GlobalPositionRcd.h"
0043 #include "CondFormats/AlignmentRecord/interface/CSCAlignmentRcd.h"
0044 #include "CondFormats/AlignmentRecord/interface/CSCAlignmentErrorExtendedRcd.h"
0045 
0046 #include <memory>
0047 #include <string>
0048 
0049 class CSCGeometryESModule : public edm::ESProducer {
0050 public:
0051   /// Constructor
0052   CSCGeometryESModule(const edm::ParameterSet& p);
0053 
0054   /// Creation of configuration file
0055   static void fillDescriptions(edm::ConfigurationDescriptions&);
0056 
0057   /// Produce CSCGeometry
0058   std::shared_ptr<CSCGeometry> produce(const MuonGeometryRecord& record);
0059 
0060 private:
0061   using HostType = edm::ESProductHost<CSCGeometry, IdealGeometryRecord, CSCRecoGeometryRcd, CSCRecoDigiParametersRcd>;
0062 
0063   void initCSCGeometry_(const MuonGeometryRecord&, std::shared_ptr<HostType>& host);
0064 
0065   edm::ReusableObjectHolder<HostType> holder_;
0066   // DDD
0067   edm::ESGetToken<DDCompactView, IdealGeometryRecord> cpvToken_;
0068   edm::ESGetToken<MuonGeometryConstants, IdealGeometryRecord> mdcToken_;
0069   //dd4hep
0070   edm::ESGetToken<cms::DDCompactView, IdealGeometryRecord> cpvTokendd4hep_;
0071 
0072   edm::ESGetToken<RecoIdealGeometry, CSCRecoGeometryRcd> rigToken_;
0073   edm::ESGetToken<CSCRecoDigiParameters, CSCRecoDigiParametersRcd> rdpToken_;
0074 
0075   edm::ESGetToken<Alignments, GlobalPositionRcd> globalPositionToken_;
0076   edm::ESGetToken<Alignments, CSCAlignmentRcd> alignmentsToken_;
0077   edm::ESGetToken<AlignmentErrorsExtended, CSCAlignmentErrorExtendedRcd> alignmentErrorsToken_;
0078 
0079   // Flags for controlling geometry modelling during build of CSCGeometry
0080   bool useRealWireGeometry_;
0081   bool useOnlyWiresInME1a_;
0082   bool useGangedStripsInME1a_;
0083   bool useCentreTIOffsets_;
0084   bool debugV_;
0085   bool applyAlignment_;  // Switch to apply alignment corrections
0086   bool fromDDD_;         // whether to build from DDD or DB
0087   bool fromDD4hep_;
0088   const std::string alignmentsLabel_;
0089   const std::string myLabel_;
0090 };
0091 
0092 using namespace edm;
0093 
0094 CSCGeometryESModule::CSCGeometryESModule(const edm::ParameterSet& p)
0095     : fromDDD_(p.getParameter<bool>("fromDDD")),
0096       fromDD4hep_(p.getParameter<bool>("fromDD4hep")),
0097       alignmentsLabel_(p.getParameter<std::string>("alignmentsLabel")),
0098       myLabel_(p.getParameter<std::string>("appendToDataLabel")) {
0099   auto cc = setWhatProduced(this);
0100 
0101   // Choose wire geometry modelling
0102   // We now _require_ some wire geometry specification in the CSCOrcaSpec.xml file
0103   // in the DDD Geometry.
0104   // Default as of transition to CMSSW is to use real values.
0105   // Alternative is to use pseudo-values which match reasonably closely
0106   // the calculated geometry values used up to and including ORCA_8_8_1.
0107   // (This was the default in ORCA.)
0108 
0109   useRealWireGeometry_ = p.getParameter<bool>("useRealWireGeometry");
0110 
0111   // Suppress strips altogether in ME1a region of ME11?
0112 
0113   useOnlyWiresInME1a_ = p.getParameter<bool>("useOnlyWiresInME1a");
0114 
0115   // Allow strips in ME1a region of ME11 but gang them?
0116   // Default is now to treat ME1a with ganged strips (e.g. in clusterizer)
0117 
0118   useGangedStripsInME1a_ = p.getParameter<bool>("useGangedStripsInME1a");
0119 
0120   if (useGangedStripsInME1a_)
0121     useOnlyWiresInME1a_ = false;  // override possible inconsistentcy
0122 
0123   // Use the backed-out offsets that correct the CTI
0124   useCentreTIOffsets_ = p.getParameter<bool>("useCentreTIOffsets");
0125 
0126   // Debug printout etc. in CSCGeometry etc.
0127 
0128   debugV_ = p.getUntrackedParameter<bool>("debugV", false);
0129 
0130   if (fromDDD_) {
0131     cpvToken_ = cc.consumes();
0132     mdcToken_ = cc.consumes();
0133   } else if (fromDD4hep_) {
0134     cpvTokendd4hep_ = cc.consumes();
0135     mdcToken_ = cc.consumes();
0136   } else {
0137     rigToken_ = cc.consumesFrom<RecoIdealGeometry, CSCRecoGeometryRcd>(edm::ESInputTag{});
0138     rdpToken_ = cc.consumesFrom<CSCRecoDigiParameters, CSCRecoDigiParametersRcd>(edm::ESInputTag{});
0139   }
0140 
0141   // Feed these value to where I need them
0142   applyAlignment_ = p.getParameter<bool>("applyAlignment");
0143   if (applyAlignment_) {
0144     globalPositionToken_ = cc.consumesFrom<Alignments, GlobalPositionRcd>(edm::ESInputTag{"", alignmentsLabel_});
0145     alignmentsToken_ = cc.consumesFrom<Alignments, CSCAlignmentRcd>(edm::ESInputTag{"", alignmentsLabel_});
0146     alignmentErrorsToken_ =
0147         cc.consumesFrom<AlignmentErrorsExtended, CSCAlignmentErrorExtendedRcd>(edm::ESInputTag{"", alignmentsLabel_});
0148   }
0149 
0150   edm::LogVerbatim("Geometry") << "@SUB=CSCGeometryESModule Label '" << myLabel_ << "' "
0151                                << (applyAlignment_ ? "looking for" : "IGNORING") << " alignment labels '"
0152                                << alignmentsLabel_ << "'.";
0153 }
0154 
0155 void CSCGeometryESModule::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0156   //
0157   // This cfi should be included to build the CSC geometry model.
0158   //
0159   // modelling flags (for completeness - internal defaults are already sane)
0160   // GF would like to have a shorter name (e.g. CSCGeometry), but since originally
0161   // there was no name, replace statements in other configs would not work anymore...
0162   edm::ParameterSetDescription desc;
0163   desc.add<bool>("fromDDD", true);
0164   desc.add<bool>("fromDD4hep", false);
0165   desc.add<std::string>("alignmentsLabel", "");
0166   desc.add<std::string>("appendToDataLabel", "");
0167   desc.add<bool>("useRealWireGeometry", true);
0168   desc.add<bool>("useOnlyWiresInME1a", false);
0169   desc.add<bool>("useGangedStripsInME1a", true);
0170   desc.add<bool>("useCentreTIOffsets", false);
0171   desc.add<bool>("applyAlignment", true);  //GF: to be abandoned
0172   desc.addUntracked<bool>("debugV", false);
0173   descriptions.add("CSCGeometryESModule", desc);
0174 }
0175 
0176 std::shared_ptr<CSCGeometry> CSCGeometryESModule::produce(const MuonGeometryRecord& record) {
0177   auto host = holder_.makeOrGet([this]() {
0178     return new HostType(
0179         debugV_, useGangedStripsInME1a_, useOnlyWiresInME1a_, useRealWireGeometry_, useCentreTIOffsets_);
0180   });
0181 
0182   initCSCGeometry_(record, host);
0183 
0184   // Called whenever the alignments or alignment errors change
0185 
0186   if (applyAlignment_) {
0187     // applyAlignment_ is scheduled for removal.
0188     // Ideal geometry obtained by using 'fake alignment' (with applyAlignment_ = true)
0189     const auto& globalPosition = record.get(globalPositionToken_);
0190     const auto& alignments = record.get(alignmentsToken_);
0191     const auto& alignmentErrors = record.get(alignmentErrorsToken_);
0192     // Only apply alignment if values exist
0193     if (alignments.empty() && alignmentErrors.empty() && globalPosition.empty()) {
0194       edm::LogVerbatim("Config") << "@SUB=CSCGeometryRecord::produce Alignment(Error)s and global position (label '"
0195                                  << alignmentsLabel_ << "') empty: Geometry producer (label "
0196                                  << "'" << myLabel_ << "') assumes fake and does not apply.";
0197     } else {
0198       GeometryAligner aligner;
0199       aligner.applyAlignments<CSCGeometry>(
0200           &(*host), &alignments, &alignmentErrors, align::DetectorGlobalPosition(globalPosition, DetId(DetId::Muon)));
0201     }
0202   }
0203   return host;  // automatically converts to std::shared_ptr<CSCGeometry>
0204 }
0205 
0206 void CSCGeometryESModule::initCSCGeometry_(const MuonGeometryRecord& record, std::shared_ptr<HostType>& host) {
0207   if (fromDDD_) {
0208     edm::LogVerbatim("CSCGeoemtryESModule") << "(0) CSCGeometryESModule  - DDD ";
0209     host->ifRecordChanges<IdealGeometryRecord>(record, [&host, &record, this](auto const& rec) {
0210       host->clear();
0211       edm::ESTransientHandle<DDCompactView> cpv = record.getTransientHandle(cpvToken_);
0212       const auto& mdc = rec.get(mdcToken_);
0213       CSCGeometryBuilderFromDDD builder;
0214       builder.build(*host, cpv.product(), mdc);
0215     });
0216   } else if (fromDD4hep_) {
0217     edm::LogVerbatim("CSCGeoemtryESModule") << "(0) CSCGeometryESModule  - DD4hep ";
0218     host->ifRecordChanges<IdealGeometryRecord>(record, [&host, &record, this](auto const& rec) {
0219       host->clear();
0220       edm::ESTransientHandle<cms::DDCompactView> cpv = record.getTransientHandle(cpvTokendd4hep_);
0221       const auto& mdc = rec.get(mdcToken_);
0222       CSCGeometryBuilderFromDDD builder;
0223       builder.build(*host, cpv.product(), mdc);
0224     });
0225   } else {
0226     bool recreateGeometry = false;
0227 
0228     host->ifRecordChanges<CSCRecoGeometryRcd>(record,
0229                                               [&recreateGeometry](auto const& rec) { recreateGeometry = true; });
0230 
0231     host->ifRecordChanges<CSCRecoDigiParametersRcd>(record,
0232                                                     [&recreateGeometry](auto const& rec) { recreateGeometry = true; });
0233     edm::LogVerbatim("CSCGeoemtryESModule") << "(0) CSCGeometryESModule  - DB recreateGeometry=false ";
0234     if (recreateGeometry) {
0235       edm::LogVerbatim("CSCGeoemtryESModule") << "(0) CSCGeometryESModule  - DB recreateGeometry=true ";
0236       host->clear();
0237       const auto& rig = record.get(rigToken_);
0238       const auto& rdp = record.get(rdpToken_);
0239       CSCGeometryBuilder cscgb;
0240       cscgb.build(*host, rig, rdp);
0241     }
0242   }
0243 }
0244 
0245 DEFINE_FWK_EVENTSETUP_MODULE(CSCGeometryESModule);