Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Be able to use merged magnetic field interpolation files #38051

Merged
merged 10 commits into from
Jun 4, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

VolumeBasedMagneticFieldESProducer = cms.ESProducer("DD4hep_VolumeBasedMagneticFieldESProducer",
VBFConfig_160812,
DDDetector = cms.ESInputTag('', 'magfield'),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter doesn't actually exist in this module.

appendToDataLabel = cms.string(''),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ namespace magneticfield {

std::unique_ptr<MagneticField> produce(const IdealMagneticFieldRecord& iRecord);

static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);

private:
edm::ParameterSet pset_;
const bool debug_;
const bool useParametrizedTrackerField_;
const bool useMergeFileIfAvailable_;
const MagFieldConfig conf_;
const std::string version_;
edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> paramFieldToken_;
Expand All @@ -53,6 +56,7 @@ DD4hep_VolumeBasedMagneticFieldESProducer::DD4hep_VolumeBasedMagneticFieldESProd
: pset_{iConfig},
debug_{iConfig.getUntrackedParameter<bool>("debugBuilder", false)},
useParametrizedTrackerField_{iConfig.getParameter<bool>("useParametrizedTrackerField")},
useMergeFileIfAvailable_{iConfig.getParameter<bool>("useMergeFileIfAvailable")},
conf_{iConfig, debug_},
version_{iConfig.getParameter<std::string>("version")} {
LogTrace("MagGeoBuilder") << "info:Constructing a DD4hep_VolumeBasedMagneticFieldESProducer";
Expand All @@ -71,7 +75,7 @@ std::unique_ptr<MagneticField> DD4hep_VolumeBasedMagneticFieldESProducer::produc
LogTrace("MagGeoBuilder") << "DD4hep_VolumeBasedMagneticFieldESProducer::produce() " << version_;
}

MagGeoBuilder builder(conf_.version, conf_.geometryVersion, debug_);
MagGeoBuilder builder(conf_.version, conf_.geometryVersion, debug_, useMergeFileIfAvailable_);

// Set scaling factors
if (!conf_.keys.empty()) {
Expand Down Expand Up @@ -106,4 +110,31 @@ std::unique_ptr<MagneticField> DD4hep_VolumeBasedMagneticFieldESProducer::produc
false);
}

void DD4hep_VolumeBasedMagneticFieldESProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.addUntracked<bool>("debugBuilder", false);
desc.add<bool>("useMergeFileIfAvailable", true);
desc.add<bool>("useParametrizedTrackerField");
desc.addUntracked<std::string>("label", "");
desc.add<std::string>("version");
desc.add<std::string>("paramLabel");

//from MagFieldConfig
desc.add<int>("geometryVersion");
{
edm::ParameterSetDescription sub;
sub.add<std::string>("volumes");
sub.add<std::string>("sectors");
sub.add<int>("master");
sub.add<std::string>("path");
desc.addVPSet("gridFiles", sub);
}
desc.add<std::vector<int> >("scalingVolumes");
desc.add<std::vector<double> >("scalingFactors");
//default used to be compatible with older configurations
desc.add<std::vector<double> >("paramData", std::vector<double>());

descriptions.addDefault(desc);
}

DEFINE_FWK_EVENTSETUP_MODULE(DD4hep_VolumeBasedMagneticFieldESProducer);
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,14 @@ namespace magneticfield {

edm::ESGetToken<FileBlob, MFGeometryFileRcd> mayConsumeBlobToken_;
const bool debug_;
const bool useMergeFileIfAvailable_;
};
} // namespace magneticfield

DD4hep_VolumeBasedMagneticFieldESProducerFromDB::DD4hep_VolumeBasedMagneticFieldESProducerFromDB(
const edm::ParameterSet& iConfig)
: debug_(iConfig.getUntrackedParameter<bool>("debugBuilder")) {
: debug_(iConfig.getUntrackedParameter<bool>("debugBuilder")),
useMergeFileIfAvailable_(iConfig.getParameter<bool>("useMergeFileIfAvailable")) {
std::string const myConfigLabel = "VBMFESChoice";
usesResources({edm::ESSharedResourceNames::kDD4hep});

Expand Down Expand Up @@ -162,7 +164,7 @@ std::unique_ptr<MagneticField> DD4hep_VolumeBasedMagneticFieldESProducerFromDB::
}

// Full VolumeBased map + parametrization
MagGeoBuilder builder(conf->version, conf->geometryVersion, debug_);
MagGeoBuilder builder(conf->version, conf->geometryVersion, debug_, useMergeFileIfAvailable_);

// Set scaling factors
if (!conf->keys.empty()) {
Expand Down Expand Up @@ -216,6 +218,7 @@ std::string_view DD4hep_VolumeBasedMagneticFieldESProducerFromDB::closerNominalL
void DD4hep_VolumeBasedMagneticFieldESProducerFromDB::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.addUntracked<bool>("debugBuilder", false);
desc.add<bool>("useMergeFileIfAvailable", true);
desc.add<int>("valueOverride", -1)->setComment("Force value of current (in A); take the value from DB if < 0.");
desc.addUntracked<std::string>("label", "");

Expand Down
72 changes: 20 additions & 52 deletions MagneticField/GeomBuilder/src/DD4hep_MagGeoBuilder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,16 @@
#include "DD4hep_MagGeoBuilder.h"
#include "bLayer.h"
#include "eSector.h"
#include "FakeInterpolator.h"
#include "InterpolatorBuilder.h"

#include "MagneticField/Layers/interface/MagBLayer.h"
#include "MagneticField/Layers/interface/MagESector.h"

#include "FWCore/ParameterSet/interface/FileInPath.h"

#include "DetectorDescription/DDCMS/interface/DDFilteredView.h"

#include "Utilities/BinningTools/interface/ClusterizingHistogram.h"

#include "MagneticField/Interpolation/interface/MagProviderInterpol.h"
#include "MagneticField/Interpolation/interface/MFGridFactory.h"
#include "MagneticField/Interpolation/interface/MFGrid.h"

#include "MagneticField/VolumeGeometry/interface/MagVolume6Faces.h"
Expand All @@ -45,8 +42,12 @@ using namespace magneticfield;
using namespace edm;
using namespace angle_units::operators;

MagGeoBuilder::MagGeoBuilder(string tableSet, int geometryVersion, bool debug)
: tableSet_(tableSet), geometryVersion_(geometryVersion), theGridFiles_(nullptr), debug_(debug) {
MagGeoBuilder::MagGeoBuilder(string tableSet, int geometryVersion, bool debug, bool mergeFile)
: tableSet_(tableSet),
geometryVersion_(geometryVersion),
theGridFiles_(nullptr),
debug_(debug),
useMergeFileIfAvailable_(mergeFile) {
LogTrace("MagGeoBuilder") << "Constructing a MagGeoBuilder";
}

Expand Down Expand Up @@ -147,6 +148,7 @@ void MagGeoBuilder::build(const cms::DDDetector* det) {
LogError("MagGeoBuilder") << "Filtered view has no node. Cannot build.";
return;
}
InterpolatorBuilder interpolatorBuilder(tableSet_, useMergeFileIfAvailable_);
while (doSubDets) {
string name = fv.volume().volume().name();
LogTrace("MagGeoBuilder") << "Name: " << name;
Expand Down Expand Up @@ -205,7 +207,7 @@ void MagGeoBuilder::build(const cms::DDDetector* det) {
// not replicated in phi)
// ASSUMPTION: copyno == sector.
if (v->copyno == v->masterSector) {
auto i = buildInterpolator(v);
auto i = buildInterpolator(v, interpolatorBuilder);
if (i) {
bInterpolators[v->magFile] = i;
}
Expand All @@ -215,7 +217,7 @@ void MagGeoBuilder::build(const cms::DDDetector* det) {
LogTrace("MagGeoBuilder") << " (Endcaps)";
eVolumes_.push_back(v);
if (v->copyno == v->masterSector) {
auto i = buildInterpolator(v);
auto i = buildInterpolator(v, interpolatorBuilder);
if (i) {
eInterpolators[v->magFile] = i;
}
Expand Down Expand Up @@ -436,63 +438,29 @@ void MagGeoBuilder::buildMagVolumes(const handles& volumes,
}
}

MagProviderInterpol* MagGeoBuilder::buildInterpolator(const volumeHandle* vol) const {
MagProviderInterpol* MagGeoBuilder::buildInterpolator(const volumeHandle* vol, InterpolatorBuilder& builder) const {
MagProviderInterpol* retValue = nullptr;
// Phi of the master sector
double masterSectorPhi = (vol->masterSector - 1) * 1._pi / 6.;

LogTrace("MagGeoBuilder") << "Building interpolator from " << vol->volumeno << " copyno " << vol->copyno << " at "
<< vol->center() << " phi: " << static_cast<double>(vol->center().phi()) / 1._pi
<< " pi, file: " << vol->magFile << " master: " << vol->masterSector;
if (debug_) {
// Phi of the master sector
double masterSectorPhi = (vol->masterSector - 1) * 1._pi / 6.;
double delta = std::abs(vol->center().phi() - masterSectorPhi);
if (delta > (1._pi / 9.)) {
LogTrace("MagGeoBuilder") << "***WARNING wrong sector? Vol delta from master sector is " << delta / 1._pi
<< " pi";
}
}

if (tableSet_ == "fake" || vol->magFile == "fake") {
return new magneticfield::FakeInterpolator();
}

string fullPath = edm::FileInPath::findFile("MagneticField/Interpolation/data/" + tableSet_ + "/" + vol->magFile);
if (fullPath.empty()) {
//get the exact error info
try {
edm::FileInPath mydata("MagneticField/Interpolation/data/" + tableSet_ + "/" + vol->magFile);
} catch (edm::Exception& exc) {
cerr << "MagGeoBuilder: exception in reading table; " << exc.what() << endl;
if (!debug_)
throw;
}
return nullptr;
}

try {
if (vol->toExpand()) {
//FIXME: see discussion on mergeCylinders above.
// interpolators[vol->magFile] =
// MFGridFactory::build( fullPath, *(vol->placement()), vol->minPhi(), vol->maxPhi());
} else {
// If the table is in "local" coordinates, must create a reference
// frame that is appropriately rotated along the CMS Z axis.

GloballyPositioned<float> rf = *(vol->placement());

if (vol->masterSector != 1) {
typedef Basic3DVector<float> Vector;

GloballyPositioned<float>::RotationType rot(Vector(0, 0, 1), -masterSectorPhi);
Vector vpos(vol->placement()->position());

rf = GloballyPositioned<float>(GloballyPositioned<float>::PositionType(rot.multiplyInverse(vpos)),
vol->placement()->rotation() * rot);
}

retValue = MFGridFactory::build(fullPath, rf);
}
} catch (MagException& exc) {
retValue = builder.build(vol).release();
} catch (edm::Exception& exc) {
cerr << "MagGeoBuilder: exception in reading table; " << exc.what() << endl;
if (!debug_)
throw;
return nullptr;
} catch (MagException const& exc) {
LogTrace("MagGeoBuilder") << exc.what();
if (!debug_)
throw;
Expand Down
6 changes: 4 additions & 2 deletions MagneticField/GeomBuilder/src/DD4hep_MagGeoBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ class MagESector;
class MagVolume6Faces;

namespace magneticfield {
class InterpolatorBuilder;

class MagGeoBuilder {
public:
MagGeoBuilder(std::string tableSet, int geometryVersion, bool debug = false);
MagGeoBuilder(std::string tableSet, int geometryVersion, bool debug = false, bool useMergeFileIfAvailable = true);

~MagGeoBuilder();

Expand Down Expand Up @@ -63,7 +64,7 @@ namespace magneticfield {

private:
// Build interpolator for the volume with "correct" rotation
MagProviderInterpol* buildInterpolator(const volumeHandle* vol) const;
MagProviderInterpol* buildInterpolator(const volumeHandle* vol, InterpolatorBuilder&) const;

// Build all MagVolumes setting the MagProviderInterpol
void buildMagVolumes(const handles& volumes,
Expand All @@ -88,6 +89,7 @@ namespace magneticfield {
const TableFileMap* theGridFiles_; // Non-owned pointer assumed to be valid until build() is called

const bool debug_;
const bool useMergeFileIfAvailable_;
};
} // namespace magneticfield
#endif
116 changes: 116 additions & 0 deletions MagneticField/GeomBuilder/src/InterpolatorBuilder.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// -*- C++ -*-
//
// Package: MagneticField/GeomBuilder
// Class : InterpolatorBuilder
//
// Implementation:
// [Notes on implementation]
//
// Original Author: Christopher Jones
// Created: Tue, 17 May 2022 20:50:21 GMT
//

// system include files

// user include files
#include "InterpolatorBuilder.h"
#include "FakeInterpolator.h"

#include "FWCore/ParameterSet/interface/FileInPath.h"
#include "FWCore/Utilities/interface/Exception.h"
#include "MagneticField/Interpolation/interface/binary_ifstream.h"
#include "MagneticField/Interpolation/interface/MFGridFactory.h"
#include "MagneticField/Interpolation/interface/MFGrid.h"

#include "DataFormats/Math/interface/angle_units.h"
//
// constants, enums and typedefs
//

namespace magneticfield {
using namespace angle_units::operators;

//
// static data member definitions
//

//
// constructors and destructor
//
InterpolatorBuilder::InterpolatorBuilder(std::string iTableSet, bool useMergeFileIfAvailable)
: tableSet_(std::move(iTableSet)) {
if (not useMergeFileIfAvailable)
return;
auto indexFileName = edm::FileInPath::findFile("MagneticField/Interpolation/data/" + tableSet_ + "/merged.index");
if (not indexFileName.empty()) {
auto binaryFileName = edm::FileInPath::findFile("MagneticField/Interpolation/data/" + tableSet_ + "/merged.bin");
if (not binaryFileName.empty()) {
std::ifstream indexFile(indexFileName);
while (indexFile) {
std::string magFile;
unsigned int offset;
indexFile >> magFile >> offset;
offsets_.emplace(std::move(magFile), offset);
}
stream_ = interpolation::binary_ifstream(binaryFileName);
}
}
}

//
// member functions
//
std::unique_ptr<MagProviderInterpol> InterpolatorBuilder::build(volumeHandle const* vol) {
if (tableSet_ == "fake" || vol->magFile == "fake") {
return std::make_unique<magneticfield::FakeInterpolator>();
}

// If the table is in "local" coordinates, must create a reference
// frame that is appropriately rotated along the CMS Z axis.

GloballyPositioned<float> rf = *(vol->placement());

if (vol->masterSector != 1) {
typedef Basic3DVector<float> Vector;

// Phi of the master sector
double masterSectorPhi = (vol->masterSector - 1) * 1._pi / 6.;

GloballyPositioned<float>::RotationType rot(Vector(0, 0, 1), -masterSectorPhi);
Vector vpos(vol->placement()->position());

rf = GloballyPositioned<float>(GloballyPositioned<float>::PositionType(rot.multiplyInverse(vpos)),
vol->placement()->rotation() * rot);
}

if (not stream_) {
auto fullPath = edm::FileInPath::findFile("MagneticField/Interpolation/data/" + tableSet_ + "/" + vol->magFile);
if (fullPath.empty()) {
//cause the exception to happen
edm::FileInPath mydata("MagneticField/Interpolation/data/" + tableSet_ + "/" + vol->magFile);
return {};
}

magneticfield::interpolation::binary_ifstream strm(fullPath);
return std::unique_ptr<MagProviderInterpol>(MFGridFactory::build(strm, rf));
}

auto find = offsets_.find(vol->magFile);
if (find == offsets_.end()) {
throw cms::Exception("MissingMagFileEntry") << vol->magFile << " was not an entry in the index file";
}
stream_->seekg(find->second);
if (stream_->fail()) {
throw cms::Exception("SeekMagFileEntry") << " failed seekg within merged binary file";
}
return std::unique_ptr<MagProviderInterpol>(MFGridFactory::build(*stream_, rf));
}

//
// const member functions
//

//
// static member functions
//
} // namespace magneticfield