Skip to content

Commit 1361138

Browse files
committed
Fix in Propagator::initFieldFromGRP
The field normally should not be deleted since this would invalidate the field pointers cached elsewhere (e.g. by the double version of the Propagator if it was requested). Instead, the existing field should be scaled by the newly provided current values. The exception is the marginal case when the scaling is not possible, e.g. when switching from 5kGauss map to 2kGauss (which should be avoided for other reasons). In this case the field will be recreated and the warning will be printed about possible invalidation of cached pointers.
1 parent a78221e commit 1361138

2 files changed

Lines changed: 43 additions & 36 deletions

File tree

Detectors/Base/include/DetectorsBase/Propagator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ class PropagatorImpl
181181
return &instance;
182182
}
183183
static int initFieldFromGRP(const o2::parameters::GRPMagField* grp, bool verbose = false);
184-
185184
static int initFieldFromGRP(const o2::parameters::GRPObject* grp, bool verbose = false);
186185
static int initFieldFromGRP(const std::string grpFileName = "", bool verbose = false);
186+
static int initFieldFromGRP(float currL3, float currDip, bool uniform, bool verbose = false);
187187
#endif
188188

189189
GPUd() MatBudget getMatBudget(MatCorrType corrType, const o2::math_utils::Point3D<value_type>& p0, const o2::math_utils::Point3D<value_type>& p1) const;

Detectors/Base/src/Propagator.cxx

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -84,61 +84,68 @@ int PropagatorImpl<value_T>::initFieldFromGRP(const std::string grpFileName, boo
8484
if (verbose) {
8585
grp->print();
8686
}
87-
8887
return initFieldFromGRP(grp);
8988
}
9089

9190
//____________________________________________________________
9291
template <typename value_T>
9392
int PropagatorImpl<value_T>::initFieldFromGRP(const o2::parameters::GRPObject* grp, bool verbose)
9493
{
95-
/// init mag field from GRP data and attach it to TGeoGlobalMagField
96-
97-
if (TGeoGlobalMagField::Instance()->IsLocked()) {
98-
if (TGeoGlobalMagField::Instance()->GetField()->TestBit(o2::field::MagneticField::kOverrideGRP)) {
99-
LOG(warning) << "ExpertMode!!! GRP information will be ignored";
100-
LOG(warning) << "ExpertMode!!! Running with the externally locked B field";
101-
return 0;
102-
} else {
103-
LOG(info) << "Destroying existing B field instance";
104-
delete TGeoGlobalMagField::Instance();
105-
}
106-
}
107-
auto fld = o2::field::MagneticField::createFieldMap(grp->getL3Current(), grp->getDipoleCurrent(), o2::field::MagneticField::kConvLHC, grp->getFieldUniformity());
108-
TGeoGlobalMagField::Instance()->SetField(fld);
109-
TGeoGlobalMagField::Instance()->Lock();
110-
if (verbose) {
111-
LOG(info) << "Running with the B field constructed out of GRP";
112-
LOG(info) << "Access field via TGeoGlobalMagField::Instance()->Field(xyz,bxyz) or via";
113-
LOG(info) << "auto o2field = static_cast<o2::field::MagneticField*>( TGeoGlobalMagField::Instance()->GetField() )";
114-
}
115-
return 0;
94+
return initFieldFromGRP(grp->getL3Current(), grp->getDipoleCurrent(), grp->getFieldUniformity(), verbose);
11695
}
11796

11897
//____________________________________________________________
11998
template <typename value_T>
12099
int PropagatorImpl<value_T>::initFieldFromGRP(const o2::parameters::GRPMagField* grp, bool verbose)
121100
{
122101
/// init mag field from GRP data and attach it to TGeoGlobalMagField
102+
return initFieldFromGRP(grp->getL3Current(), grp->getDipoleCurrent(), grp->getFieldUniformity(), verbose);
103+
}
123104

124-
if (TGeoGlobalMagField::Instance()->IsLocked()) {
125-
if (TGeoGlobalMagField::Instance()->GetField()->TestBit(o2::field::MagneticField::kOverrideGRP)) {
126-
LOG(warning) << "ExpertMode!!! GRP information will be ignored";
127-
LOG(warning) << "ExpertMode!!! Running with the externally locked B field";
128-
return 0;
105+
//____________________________________________________________
106+
template <typename value_T>
107+
int PropagatorImpl<value_T>::initFieldFromGRP(float currL3, float currDip, bool uniform, bool verbose)
108+
{
109+
/// init mag field from GRP data and attach it to TGeoGlobalMagField or rescale already updated field
110+
auto fldGlo = static_cast<o2::field::MagneticField*>(TGeoGlobalMagField::Instance()->GetField());
111+
if (fldGlo) { // global field object was already initialized, reuse it if it is locked (as it normally should be)
112+
float _currL3(currL3), _currDip(currDip);
113+
auto newFieldType = fldGlo->getFieldMapScale(_currL3, _currDip, uniform);
114+
bool sameFieldType = newFieldType == fldGlo->getMapType();
115+
if (!sameFieldType) {
116+
LOGP(warn, "Existing B-field type {} cannot be rescaled to type {} requested by the GRP", int(fldGlo->getMapType()), int(newFieldType));
117+
}
118+
if (TGeoGlobalMagField::Instance()->IsLocked() && sameFieldType) {
119+
if (Instance()->mField && Instance()->mField != fldGlo) { // just make sure that cached field is the same as the global one
120+
std::string name{"PropagatorF"};
121+
if constexpr (std::is_same_v<value_T, double>) {
122+
std::string name{"PropagatorD"};
123+
}
124+
LOGP(fatal, "Magnetic field pointer cached in the {} instance differs from the gloabal field pointer", name);
125+
}
126+
if (verbose) {
127+
LOGP(info, "Rescaling magnetic field to currents L3: {}, Dipole: {}, UniformityFlag: {}", currL3, currDip, uniform);
128+
}
129+
fldGlo->rescaleField(currL3, currDip, uniform);
129130
} else {
130-
LOG(info) << "Destroying existing B field instance";
131+
LOGP(warn, "Destroying existing B field instance. This may invalidate field pointer cached in other objects");
131132
delete TGeoGlobalMagField::Instance();
133+
Instance()->mField = nullptr;
134+
Instance()->mFieldFast = nullptr;
135+
fldGlo = nullptr;
132136
}
133137
}
134-
auto fld = o2::field::MagneticField::createFieldMap(grp->getL3Current(), grp->getDipoleCurrent(), o2::field::MagneticField::kConvLHC, grp->getFieldUniformity());
135-
TGeoGlobalMagField::Instance()->SetField(fld);
136-
TGeoGlobalMagField::Instance()->Lock();
137-
if (verbose) {
138-
LOG(info) << "Running with the B field constructed out of GRP";
139-
LOG(info) << "Access field via TGeoGlobalMagField::Instance()->Field(xyz,bxyz) or via";
140-
LOG(info) << "auto o2field = static_cast<o2::field::MagneticField*>( TGeoGlobalMagField::Instance()->GetField() )";
138+
if (!fldGlo) {
139+
fldGlo = o2::field::MagneticField::createFieldMap(currL3, currDip, o2::field::MagneticField::kConvLHC, uniform);
140+
TGeoGlobalMagField::Instance()->SetField(fldGlo);
141+
TGeoGlobalMagField::Instance()->Lock();
142+
if (verbose) {
143+
LOG(info) << "Running with the B field constructed out of GRP";
144+
LOG(info) << "Access field via TGeoGlobalMagField::Instance()->Field(xyz,bxyz) or via";
145+
LOG(info) << "auto o2field = static_cast<o2::field::MagneticField*>( TGeoGlobalMagField::Instance()->GetField() )";
146+
}
141147
}
148+
Instance()->updateField();
142149
return 0;
143150
}
144151

0 commit comments

Comments
 (0)