File indexing completed on 2023-10-25 09:56:53
0001
0002
0003
0004
0005
0006
0007
0008 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0009 #include "FWCore/Framework/interface/ESProducer.h"
0010 #include "FWCore/Concurrency/interface/SharedResourceNames.h"
0011
0012 #include "CondFormats/RunInfo/interface/RunInfo.h"
0013 #include "CondFormats/DataRecord/interface/RunSummaryRcd.h"
0014
0015 #include "MagneticField/Engine/interface/MagneticField.h"
0016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0017 #include "MagneticField/VolumeBasedEngine/interface/VolumeBasedMagneticField.h"
0018 #include "MagneticField/ParametrizedEngine/interface/ParametrizedMagneticFieldFactory.h"
0019
0020 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0021
0022 #include "FWCore/Framework/interface/ESTransientHandle.h"
0023 #include "FWCore/Framework/interface/EventSetup.h"
0024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0025 #include "FWCore/Utilities/interface/ESProductTag.h"
0026
0027 #include "FWCore/Framework/interface/ModuleFactory.h"
0028 #include "MagneticField/GeomBuilder/src/DD4hep_MagGeoBuilder.h"
0029
0030 #include "DetectorDescription/DDCMS/interface/DDDetector.h"
0031
0032 #include "CondFormats/Common/interface/FileBlob.h"
0033 #include "CondFormats/DataRecord/interface/MFGeometryFileRcd.h"
0034 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0035 #include "CondFormats/MFObjects/interface/MagFieldConfig.h"
0036 #include "CondFormats/DataRecord/interface/MagFieldConfigRcd.h"
0037
0038 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0039
0040 #include <string>
0041 #include <vector>
0042 #include <iostream>
0043 #include <memory>
0044
0045 using namespace std;
0046 using namespace magneticfield;
0047 using namespace edm;
0048
0049 namespace magneticfield {
0050 class DD4hep_VolumeBasedMagneticFieldESProducerFromDB : public edm::ESProducer {
0051 public:
0052 DD4hep_VolumeBasedMagneticFieldESProducerFromDB(const edm::ParameterSet& iConfig);
0053 ~DD4hep_VolumeBasedMagneticFieldESProducerFromDB() override;
0054
0055 DD4hep_VolumeBasedMagneticFieldESProducerFromDB(const DD4hep_VolumeBasedMagneticFieldESProducerFromDB&) = delete;
0056 const DD4hep_VolumeBasedMagneticFieldESProducerFromDB& operator=(
0057 const DD4hep_VolumeBasedMagneticFieldESProducerFromDB&) = delete;
0058
0059 std::shared_ptr<MagFieldConfig const> chooseConfigViaParameter(const IdealMagneticFieldRecord& iRecord);
0060 std::shared_ptr<MagFieldConfig const> chooseConfigAtRuntime(const IdealMagneticFieldRecord& iRecord);
0061
0062 std::unique_ptr<MagneticField> produce(const IdealMagneticFieldRecord& iRecord);
0063
0064 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0065
0066 private:
0067 static std::string_view closerNominalLabel(float current);
0068
0069 edm::ESGetToken<MagFieldConfig, MagFieldConfigRcd> mayGetConfigToken_;
0070 edm::ESGetToken<MagFieldConfig, MagFieldConfigRcd> knownFromParamConfigToken_;
0071
0072
0073
0074 edm::ESGetToken<MagFieldConfig, IdealMagneticFieldRecord> chosenConfigToken_;
0075
0076 edm::ESGetToken<FileBlob, MFGeometryFileRcd> mayConsumeBlobToken_;
0077 cms::DDDetector* detector_{nullptr};
0078 int cachedGeometryVersion_{-1};
0079
0080 const bool debug_;
0081 const bool useMergeFileIfAvailable_;
0082 };
0083 }
0084
0085 DD4hep_VolumeBasedMagneticFieldESProducerFromDB::DD4hep_VolumeBasedMagneticFieldESProducerFromDB(
0086 const edm::ParameterSet& iConfig)
0087 : debug_(iConfig.getUntrackedParameter<bool>("debugBuilder")),
0088 useMergeFileIfAvailable_(iConfig.getParameter<bool>("useMergeFileIfAvailable")) {
0089 std::string const myConfigLabel = "VBMFESChoice";
0090 usesResources({edm::ESSharedResourceNames::kDD4hep});
0091
0092
0093 const int current = iConfig.getParameter<int>("valueOverride");
0094 if (current < 0) {
0095
0096 setWhatProduced(
0097 this, &DD4hep_VolumeBasedMagneticFieldESProducerFromDB::chooseConfigAtRuntime, edm::es::Label(myConfigLabel))
0098 .setMayConsume(
0099 mayGetConfigToken_,
0100 [](auto const& iGet, edm::ESTransientHandle<RunInfo> iHandle) {
0101 auto const label = closerNominalLabel(iHandle->m_avg_current);
0102 edm::LogInfo("MagneticField") << "Current :" << iHandle->m_avg_current
0103 << " (from RunInfo DB); using map configuration with label: " << label;
0104 return iGet("", label);
0105 },
0106 edm::ESProductTag<RunInfo, RunInfoRcd>("", ""));
0107
0108 } else {
0109
0110 auto const label = closerNominalLabel(current);
0111 edm::LogInfo("MagneticField") << "Current :" << current
0112 << " (from valueOverride card); using map configuration with label: " << label;
0113 auto cc = setWhatProduced(this,
0114 &DD4hep_VolumeBasedMagneticFieldESProducerFromDB::chooseConfigViaParameter,
0115 edm::es::Label(myConfigLabel));
0116
0117 knownFromParamConfigToken_ = cc.consumes(edm::ESInputTag(""s, std::string(label)));
0118 }
0119
0120 auto const label = iConfig.getUntrackedParameter<std::string>("label");
0121 auto const myConfigTag = edm::ESInputTag(iConfig.getParameter<std::string>("@module_label"), myConfigLabel);
0122
0123
0124 auto cc = setWhatProduced(this, label);
0125 cc.setMayConsume(
0126 mayConsumeBlobToken_,
0127 [](auto const& iGet, edm::ESTransientHandle<MagFieldConfig> iConfig) {
0128 if (iConfig->version == "parametrizedMagneticField") {
0129 return iGet.nothing();
0130 }
0131 return iGet("", std::to_string(iConfig->geometryVersion));
0132 },
0133 edm::ESProductTag<MagFieldConfig, IdealMagneticFieldRecord>(myConfigTag));
0134 chosenConfigToken_ = cc.consumes(myConfigTag);
0135 }
0136
0137 DD4hep_VolumeBasedMagneticFieldESProducerFromDB::~DD4hep_VolumeBasedMagneticFieldESProducerFromDB() {
0138 delete detector_;
0139 }
0140
0141 std::shared_ptr<MagFieldConfig const> DD4hep_VolumeBasedMagneticFieldESProducerFromDB::chooseConfigAtRuntime(
0142 IdealMagneticFieldRecord const& iRcd) {
0143 edm::ESHandle<MagFieldConfig> config = iRcd.getHandle(mayGetConfigToken_);
0144
0145
0146 return std::shared_ptr<MagFieldConfig const>(config.product(), [](auto*) {});
0147 }
0148
0149 std::shared_ptr<MagFieldConfig const> DD4hep_VolumeBasedMagneticFieldESProducerFromDB::chooseConfigViaParameter(
0150 const IdealMagneticFieldRecord& iRecord) {
0151 auto config = iRecord.getHandle(knownFromParamConfigToken_);
0152
0153
0154 return std::shared_ptr<MagFieldConfig const>(config.product(), [](auto*) {});
0155 }
0156
0157
0158 std::unique_ptr<MagneticField> DD4hep_VolumeBasedMagneticFieldESProducerFromDB::produce(
0159 const IdealMagneticFieldRecord& iRecord) {
0160 auto const& conf = iRecord.getTransientHandle(chosenConfigToken_);
0161
0162 std::unique_ptr<MagneticField> paramField =
0163 ParametrizedMagneticFieldFactory::get(conf->slaveFieldVersion, conf->slaveFieldParameters);
0164
0165 edm::LogInfo("MagneticField") << "(DD4hep) Version: " << conf->version
0166 << " geometryVersion: " << conf->geometryVersion
0167 << " slaveFieldVersion: " << conf->slaveFieldVersion;
0168
0169 if (conf->version == "parametrizedMagneticField") {
0170
0171 return paramField;
0172 }
0173
0174
0175 MagGeoBuilder builder(conf->version, conf->geometryVersion, debug_, useMergeFileIfAvailable_);
0176
0177
0178 if (!conf->keys.empty()) {
0179 builder.setScaling(conf->keys, conf->values);
0180 }
0181
0182
0183 if (!conf->gridFiles.empty()) {
0184 builder.setGridFiles(conf->gridFiles);
0185 }
0186
0187
0188 if (cachedGeometryVersion_ != conf->geometryVersion) {
0189 if (nullptr != detector_) {
0190 edm::LogError("MagneticField") << "MF Geometry needs to be re-created since current changed (cached: "
0191 << cachedGeometryVersion_ << " requested: " << conf->geometryVersion
0192 << "), which is not supported by dd4hep" << endl;
0193 }
0194
0195 auto const& blob = iRecord.getTransientHandle(mayConsumeBlobToken_);
0196 std::unique_ptr<std::vector<unsigned char> > tb = blob->getUncompressedBlob();
0197
0198 string sblob(tb->begin(), tb->end());
0199 sblob.insert(sblob.rfind("</DDDefinition>"),
0200 "<MaterialSection label=\"materials.xml\"><ElementaryMaterial name=\"materials:Vacuum\" "
0201 "density=\"1e-13*mg/cm3\" "
0202 "symbol=\" \" atomicWeight=\"1*g/mole\" atomicNumber=\"1\"/></MaterialSection>");
0203
0204 detector_ = new cms::DDDetector("cmsMagneticField:MAGF", sblob, true);
0205 cachedGeometryVersion_ = conf->geometryVersion;
0206 }
0207
0208 builder.build(detector_);
0209
0210
0211 return std::make_unique<VolumeBasedMagneticField>(conf->geometryVersion,
0212 builder.barrelLayers(),
0213 builder.endcapSectors(),
0214 builder.barrelVolumes(),
0215 builder.endcapVolumes(),
0216 builder.maxR(),
0217 builder.maxZ(),
0218 paramField.release(),
0219 true);
0220 }
0221
0222 std::string_view DD4hep_VolumeBasedMagneticFieldESProducerFromDB::closerNominalLabel(float current) {
0223 constexpr std::array<int, 7> nominalCurrents = {{-1, 0, 9558, 14416, 16819, 18268, 19262}};
0224 constexpr std::array<std::string_view, 7> nominalLabels = {{"3.8T", "0T", "2T", "3T", "3.5T", "3.8T", "4T"}};
0225
0226 int i = 0;
0227 for (; i < (int)nominalLabels.size() - 1; i++) {
0228 if (2 * current < nominalCurrents[i] + nominalCurrents[i + 1])
0229 return nominalLabels[i];
0230 }
0231 return nominalLabels[i];
0232 }
0233
0234 void DD4hep_VolumeBasedMagneticFieldESProducerFromDB::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0235 edm::ParameterSetDescription desc;
0236 desc.addUntracked<bool>("debugBuilder", false);
0237 desc.add<bool>("useMergeFileIfAvailable", true);
0238 desc.add<int>("valueOverride", -1)->setComment("Force value of current (in A); take the value from DB if < 0.");
0239 desc.addUntracked<std::string>("label", "");
0240
0241 descriptions.addDefault(desc);
0242 }
0243
0244 DEFINE_FWK_EVENTSETUP_MODULE(DD4hep_VolumeBasedMagneticFieldESProducerFromDB);