Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:22:29

0001 /** \class VolumeBasedMagneticFieldESProducerFromDB
0002  *
0003  *  Producer for the VolumeBasedMagneticField, taking all inputs (geometry, etc) from DB
0004  *
0005  */
0006 
0007 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0008 #include "FWCore/Framework/interface/ESProducer.h"
0009 
0010 #include "CondFormats/RunInfo/interface/RunInfo.h"
0011 #include "CondFormats/DataRecord/interface/RunSummaryRcd.h"
0012 
0013 #include "MagneticField/Engine/interface/MagneticField.h"
0014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0015 #include "MagneticField/VolumeBasedEngine/interface/VolumeBasedMagneticField.h"
0016 #include "MagneticField/ParametrizedEngine/interface/ParametrizedMagneticFieldFactory.h"
0017 
0018 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0019 
0020 #include "FWCore/Framework/interface/ESTransientHandle.h"
0021 #include "FWCore/Framework/interface/EventSetup.h"
0022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0023 #include "FWCore/Utilities/interface/ESProductTag.h"
0024 
0025 #include "FWCore/Framework/interface/ModuleFactory.h"
0026 #include "MagneticField/GeomBuilder/src/MagGeoBuilderFromDDD.h"
0027 
0028 #include "DetectorDescription/Core/interface/DDCompactView.h"
0029 #include "DetectorDescription/Core/interface/DDRoot.h"
0030 #include "DetectorDescription/Parser/interface/DDLParser.h"
0031 #include "CondFormats/Common/interface/FileBlob.h"
0032 #include "CondFormats/DataRecord/interface/MFGeometryFileRcd.h"
0033 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0034 #include "CondFormats/MFObjects/interface/MagFieldConfig.h"
0035 #include "CondFormats/DataRecord/interface/MagFieldConfigRcd.h"
0036 
0037 #include "FWCore/Concurrency/interface/SharedResourceNames.h"
0038 
0039 #include <string>
0040 #include <vector>
0041 #include <iostream>
0042 #include <memory>
0043 
0044 using namespace std;
0045 using namespace magneticfield;
0046 using namespace edm;
0047 
0048 namespace magneticfield {
0049   class VolumeBasedMagneticFieldESProducerFromDB : public edm::ESProducer {
0050   public:
0051     VolumeBasedMagneticFieldESProducerFromDB(const edm::ParameterSet& iConfig);
0052     // forbid copy ctor and assignment op.
0053     VolumeBasedMagneticFieldESProducerFromDB(const VolumeBasedMagneticFieldESProducerFromDB&) = delete;
0054     const VolumeBasedMagneticFieldESProducerFromDB& operator=(const VolumeBasedMagneticFieldESProducerFromDB&) = delete;
0055 
0056     std::shared_ptr<MagFieldConfig const> chooseConfigViaParameter(const IdealMagneticFieldRecord& iRecord);
0057     std::shared_ptr<MagFieldConfig const> chooseConfigAtRuntime(const IdealMagneticFieldRecord& iRecord);
0058 
0059     std::unique_ptr<MagneticField> produce(const IdealMagneticFieldRecord& iRecord);
0060 
0061     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0062 
0063   private:
0064     static std::string_view closerNominalLabel(float current);
0065 
0066     edm::ESGetToken<MagFieldConfig, MagFieldConfigRcd> mayGetConfigToken_;
0067     edm::ESGetToken<MagFieldConfig, MagFieldConfigRcd> knownFromParamConfigToken_;
0068 
0069     //NOTE: change of record since this MagFieldConfig was chosen based on data
0070     // from the record RunInfoRcd so therefore has a dependency upon that record
0071     edm::ESGetToken<MagFieldConfig, IdealMagneticFieldRecord> chosenConfigToken_;
0072 
0073     edm::ESGetToken<FileBlob, MFGeometryFileRcd> mayConsumeBlobToken_;
0074     const bool debug_;
0075   };
0076 }  // namespace magneticfield
0077 
0078 VolumeBasedMagneticFieldESProducerFromDB::VolumeBasedMagneticFieldESProducerFromDB(const edm::ParameterSet& iConfig)
0079     : debug_(iConfig.getUntrackedParameter<bool>("debugBuilder")) {
0080   std::string const myConfigLabel = "VBMFESChoice";
0081 
0082   usesResources({{edm::ESSharedResourceNames::kDDGeometry}});
0083   //Based on configuration, pick algorithm to produce the proper MagFieldConfig with a specific label
0084   const int current = iConfig.getParameter<int>("valueOverride");
0085   if (current < 0) {
0086     //We do not know what to get until we first read RunInfo
0087     setWhatProduced(
0088         this, &VolumeBasedMagneticFieldESProducerFromDB::chooseConfigAtRuntime, edm::es::Label(myConfigLabel))
0089         .setMayConsume(
0090             mayGetConfigToken_,
0091             [](auto const& iGet, edm::ESTransientHandle<RunInfo> iHandle) {
0092               auto const label = closerNominalLabel(iHandle->m_avg_current);
0093               edm::LogInfo("MagneticField") << "Current :" << iHandle->m_avg_current
0094                                             << " (from RunInfo DB); using map configuration with label: " << label;
0095               return iGet("", label);
0096             },
0097             edm::ESProductTag<RunInfo, RunInfoRcd>("", ""));
0098 
0099   } else {
0100     //we know exactly what we are going to get
0101     auto const label = closerNominalLabel(current);
0102     edm::LogInfo("MagneticField") << "Current :" << current
0103                                   << " (from valueOverride card); using map configuration with label: " << label;
0104     auto cc = setWhatProduced(
0105         this, &VolumeBasedMagneticFieldESProducerFromDB::chooseConfigViaParameter, edm::es::Label(myConfigLabel));
0106     knownFromParamConfigToken_ = cc.consumes(edm::ESInputTag(""s, std::string(label)));
0107   }
0108 
0109   auto const label = iConfig.getUntrackedParameter<std::string>("label");
0110   auto const myConfigTag = edm::ESInputTag(iConfig.getParameter<std::string>("@module_label"), myConfigLabel);
0111 
0112   //We use the MagFieldConfig created above to decide which FileBlob to use
0113   auto cc = setWhatProduced(this, label);
0114   cc.setMayConsume(
0115       mayConsumeBlobToken_,
0116       [](auto const& iGet, edm::ESTransientHandle<MagFieldConfig> iConfig) {
0117         if (iConfig->version == "parametrizedMagneticField") {
0118           return iGet.nothing();
0119         }
0120         return iGet("", std::to_string(iConfig->geometryVersion));
0121       },
0122       edm::ESProductTag<MagFieldConfig, IdealMagneticFieldRecord>(myConfigTag));
0123   chosenConfigToken_ = cc.consumes(myConfigTag);  //Use same tag as the choice
0124 }
0125 
0126 std::shared_ptr<MagFieldConfig const> VolumeBasedMagneticFieldESProducerFromDB::chooseConfigAtRuntime(
0127     IdealMagneticFieldRecord const& iRcd) {
0128   edm::ESHandle<MagFieldConfig> config = iRcd.getHandle(mayGetConfigToken_);
0129 
0130   //just forward what we just got but do not take ownership
0131   return std::shared_ptr<MagFieldConfig const>(config.product(), [](auto*) {});
0132 }
0133 
0134 std::shared_ptr<MagFieldConfig const> VolumeBasedMagneticFieldESProducerFromDB::chooseConfigViaParameter(
0135     const IdealMagneticFieldRecord& iRecord) {
0136   auto config = iRecord.getHandle(knownFromParamConfigToken_);
0137 
0138   //just forward what we just got but do not take ownership
0139   return std::shared_ptr<MagFieldConfig const>(config.product(), [](auto*) {});
0140 }
0141 
0142 // ------------ method called to produce the data  ------------
0143 std::unique_ptr<MagneticField> VolumeBasedMagneticFieldESProducerFromDB::produce(
0144     const IdealMagneticFieldRecord& iRecord) {
0145   auto const& conf = iRecord.getTransientHandle(chosenConfigToken_);
0146 
0147   std::unique_ptr<MagneticField> paramField =
0148       ParametrizedMagneticFieldFactory::get(conf->slaveFieldVersion, conf->slaveFieldParameters);
0149 
0150   edm::LogInfo("MagneticField") << "Version: " << conf->version << " geometryVersion: " << conf->geometryVersion
0151                                 << " slaveFieldVersion: " << conf->slaveFieldVersion;
0152 
0153   if (conf->version == "parametrizedMagneticField") {
0154     // The map consist of only the parametrization in this case
0155     return paramField;
0156   }
0157 
0158   // Full VolumeBased map + parametrization
0159   MagGeoBuilderFromDDD builder(conf->version, conf->geometryVersion, debug_);
0160 
0161   // Set scaling factors
0162   if (!conf->keys.empty()) {
0163     builder.setScaling(conf->keys, conf->values);
0164   }
0165 
0166   // Set specification for the grid tables to be used.
0167   if (!conf->gridFiles.empty()) {
0168     builder.setGridFiles(conf->gridFiles);
0169   }
0170 
0171   // Build the geometry (DDDCompactView) from the DB blob
0172   // (code taken from GeometryReaders/XMLIdealGeometryESSource/src/XMLIdealMagneticFieldGeometryESProducer.cc)
0173 
0174   auto const& blob = iRecord.getTransientHandle(mayConsumeBlobToken_);
0175 
0176   DDCompactView cpv{DDName("cmsMagneticField:MAGF")};
0177   DDLParser parser(cpv);
0178   parser.getDDLSAX2FileHandler()->setUserNS(true);
0179   parser.clearFiles();
0180   std::unique_ptr<std::vector<unsigned char> > tb = blob->getUncompressedBlob();
0181   parser.parse(*tb, tb->size());
0182   cpv.lockdown();
0183 
0184   builder.build(cpv);
0185 
0186   // Build the VB map. Ownership of the parametrization is transferred to it
0187   return std::make_unique<VolumeBasedMagneticField>(conf->geometryVersion,
0188                                                     builder.barrelLayers(),
0189                                                     builder.endcapSectors(),
0190                                                     builder.barrelVolumes(),
0191                                                     builder.endcapVolumes(),
0192                                                     builder.maxR(),
0193                                                     builder.maxZ(),
0194                                                     paramField.release(),
0195                                                     true);
0196 }
0197 
0198 std::string_view VolumeBasedMagneticFieldESProducerFromDB::closerNominalLabel(float current) {
0199   constexpr std::array<int, 7> nominalCurrents = {{-1, 0, 9558, 14416, 16819, 18268, 19262}};
0200   constexpr std::array<std::string_view, 7> nominalLabels = {{"3.8T", "0T", "2T", "3T", "3.5T", "3.8T", "4T"}};
0201 
0202   int i = 0;
0203   for (; i < (int)nominalLabels.size() - 1; i++) {
0204     if (2 * current < nominalCurrents[i] + nominalCurrents[i + 1])
0205       return nominalLabels[i];
0206   }
0207   return nominalLabels[i];
0208 }
0209 
0210 void VolumeBasedMagneticFieldESProducerFromDB::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0211   edm::ParameterSetDescription desc;
0212   desc.addUntracked<bool>("debugBuilder", false);
0213   desc.add<int>("valueOverride", -1)->setComment("Force value of current (in A); take the value from DB if < 0.");
0214   desc.addUntracked<std::string>("label", "");
0215 
0216   descriptions.addDefault(desc);
0217 }
0218 
0219 DEFINE_FWK_EVENTSETUP_MODULE(VolumeBasedMagneticFieldESProducerFromDB);