101 Double_t fmax,
const std::string
path)
103 mMeasuredMap(nullptr),
109 mDefaultIntegration(integ),
111 mMultipicativeFactorSolenoid(1.),
112 mMultipicativeFactorDipole(1.),
114 mDipoleOnOffFlag(factorDip == 0.),
115 mQuadrupoleGradient(0),
117 mCompensatorField2C(0),
118 mCompensatorField1A(0),
119 mCompensatorField2A(0),
120 mParameterNames(
"",
"")
286 double xyz[3] = {xyzExt[0] - gOriginBias->
x, xyzExt[1] - gOriginBias->
y, xyzExt[2] - gOriginBias->
z};
288 if (mFastField && mFastField->Field(xyz,
b)) {
292 if (mMeasuredMap && xyz[2] > mMeasuredMap->getMinZ() && xyz[2] < mMeasuredMap->getMaxZ()) {
293 mMeasuredMap->Field(xyz,
b);
294 if (xyz[2] > sSolenoidToDipoleZ || mDipoleOnOffFlag) {
295 for (
int i = 3;
i--;) {
296 b[
i] *= mMultipicativeFactorSolenoid;
299 for (
int i = 3;
i--;) {
300 b[
i] *= mMultipicativeFactorDipole;
313 double xyz[3] = {xyzExt[0] - gOriginBias->
x, xyzExt[1] - gOriginBias->
y, xyzExt[2] - gOriginBias->
z};
316 if (mFastField->GetBz(xyz, bz)) {
320 if (mMeasuredMap && xyz[2] > mMeasuredMap->getMinZ() && xyz[2] < mMeasuredMap->getMaxZ()) {
321 double bz = mMeasuredMap->getBz(xyz);
322 return (xyz[2] > sSolenoidToDipoleZ || mDipoleOnOffFlag) ? bz * mMultipicativeFactorSolenoid
323 : bz * mMultipicativeFactorDipole;
384 const Double_t kBComp1CZ = 1075., kBComp1hDZ = 260. / 2., kBComp1SqR = 4.0 * 4.0;
385 const Double_t kBComp2CZ = 2049., kBComp2hDZ = 153. / 2., kBComp2SqR = 4.5 * 4.5;
387 const Double_t kTripQ1CZ = 2615., kTripQ1hDZ = 637. / 2., kTripQ1SqR = 3.5 * 3.5;
388 const Double_t kTripQ2CZ = 3480., kTripQ2hDZ = 550. / 2., kTripQ2SqR = 3.5 * 3.5;
389 const Double_t kTripQ3CZ = 4130., kTripQ3hDZ = 550. / 2., kTripQ3SqR = 3.5 * 3.5;
390 const Double_t kTripQ4CZ = 5015., kTripQ4hDZ = 637. / 2., kTripQ4SqR = 3.5 * 3.5;
392 const Double_t kDip1CZ = 6310.8, kDip1hDZ = 945. / 2., kDip1SqRC = 4.5 * 4.5, kDip1SqRA = 3.375 * 3.375;
393 const Double_t kDip2CZ = 12640.3, kDip2hDZ = 945. / 2., kDip2SqRC = 4.5 * 4.5, kDip2SqRA = 3.75 * 3.75;
394 const Double_t kDip2DXC = 9.7, kDip2DXA = 9.4;
396 double rad2 =
x[0] *
x[0] +
x[1] *
x[1];
398 b[0] =
b[1] =
b[2] = 0;
402 if (TMath::Abs(
x[2] + kBComp2CZ) < kBComp2hDZ && rad2 < kBComp2SqR) {
403 b[0] = mCompensatorField2C * mMultipicativeFactorDipole;
404 }
else if (TMath::Abs(
x[2] + kTripQ1CZ) < kTripQ1hDZ && rad2 < kTripQ1SqR) {
405 b[0] = mQuadrupoleGradient *
x[1];
406 b[1] = mQuadrupoleGradient *
x[0];
407 }
else if (TMath::Abs(
x[2] + kTripQ2CZ) < kTripQ2hDZ && rad2 < kTripQ2SqR) {
408 b[0] = -mQuadrupoleGradient *
x[1];
409 b[1] = -mQuadrupoleGradient *
x[0];
410 }
else if (TMath::Abs(
x[2] + kTripQ3CZ) < kTripQ3hDZ && rad2 < kTripQ3SqR) {
411 b[0] = -mQuadrupoleGradient *
x[1];
412 b[1] = -mQuadrupoleGradient *
x[0];
413 }
else if (TMath::Abs(
x[2] + kTripQ4CZ) < kTripQ4hDZ && rad2 < kTripQ4SqR) {
414 b[0] = mQuadrupoleGradient *
x[1];
415 b[1] = mQuadrupoleGradient *
x[0];
416 }
else if (TMath::Abs(
x[2] + kDip1CZ) < kDip1hDZ && rad2 < kDip1SqRC) {
418 }
else if (TMath::Abs(
x[2] + kDip2CZ) < kDip2hDZ && rad2 < kDip2SqRC) {
419 double dxabs = TMath::Abs(
x[0]) - kDip2DXC;
420 if ((dxabs * dxabs +
x[1] *
x[1]) < kDip2SqRC) {
421 b[1] = -mDipoleField;
428 if (TMath::Abs(
x[2] - kBComp1CZ) < kBComp1hDZ && rad2 < kBComp1SqR) {
430 b[0] = mCompensatorField1A * mMultipicativeFactorDipole;
433 if (TMath::Abs(
x[2] - kBComp2CZ) < kBComp2hDZ && rad2 < kBComp2SqR) {
434 b[0] = mCompensatorField2A * mMultipicativeFactorDipole;
435 }
else if (TMath::Abs(
x[2] - kTripQ1CZ) < kTripQ1hDZ && rad2 < kTripQ1SqR) {
436 b[0] = -mQuadrupoleGradient *
x[1];
437 b[1] = -mQuadrupoleGradient *
x[0];
438 }
else if (TMath::Abs(
x[2] - kTripQ2CZ) < kTripQ2hDZ && rad2 < kTripQ2SqR) {
439 b[0] = mQuadrupoleGradient *
x[1];
440 b[1] = mQuadrupoleGradient *
x[0];
441 }
else if (TMath::Abs(
x[2] - kTripQ3CZ) < kTripQ3hDZ && rad2 < kTripQ3SqR) {
442 b[0] = mQuadrupoleGradient *
x[1];
443 b[1] = mQuadrupoleGradient *
x[0];
444 }
else if (TMath::Abs(
x[2] - kTripQ4CZ) < kTripQ4hDZ && rad2 < kTripQ4SqR) {
445 b[0] = -mQuadrupoleGradient *
x[1];
446 b[1] = -mQuadrupoleGradient *
x[0];
447 }
else if (TMath::Abs(
x[2] - kDip1CZ) < kDip1hDZ && rad2 < kDip1SqRA) {
448 b[1] = -mDipoleField;
449 }
else if (TMath::Abs(
x[2] - kDip2CZ) < kDip2hDZ && rad2 < kDip2SqRA) {
450 double dxabs = TMath::Abs(
x[0]) - kDip2DXA;
451 if ((dxabs * dxabs +
x[1] *
x[1]) < kDip2SqRA) {
571 const float l3NominalCurrent1 = 30000.f;
572 const float l3NominalCurrent2 = 12000.f;
573 const float diNominalCurrent = 6000.f;
575 const float tolerance = 0.03;
576 const float zero = 77.f;
580 float l3sav = l3, dipsav = dip;
582 float l3Pol = l3 > 0 ? 1 : -1;
583 float diPol = dip > 0 ? 1 : -1;
586 dip = TMath::Abs(dip);
587 static bool overrideL3 = std::getenv(
"O2_OVERRIDE_L3_CURRENT") !=
nullptr;
588 static bool overrideDIP = std::getenv(
"O2_OVERRIDE_DIPOLE_CURRENT") !=
nullptr;
589 static bool warnL3Done =
false, warnDipDone =
false, warnPolarityDone =
false;
591 if (TMath::Abs((sclDip = dip / diNominalCurrent) - 1.) > tolerance && !uniform) {
596 LOG(fatal) <<
"MagneticField::createFieldMap: Wrong dipole current (" << dipsav <<
" A)!";
599 LOGP(error,
"Dipole current was overridden to unsupported value {}", dipsav);
609 sclL3 = l3 / l3NominalCurrent1;
611 if (TMath::Abs((sclL3 = l3 / l3NominalCurrent1) - 1.) < tolerance) {
613 }
else if (TMath::Abs((sclL3 = l3 / l3NominalCurrent2) - 1.) < tolerance) {
615 }
else if (l3 <= zero && dip <= zero) {
621 LOG(fatal) <<
"MagneticField::createFieldMap: Wrong L3 current (" << l3sav <<
" A)!";
624 LOGP(error,
"L3 current was overridden to unsupported value {}", l3sav);
628 sclL3 = l3 / l3NominalCurrent1;
634 ((convention ==
kConvLHC && l3Pol != diPol) || (convention ==
kConvDCS2008 && l3Pol == diPol))) {
635 if (overrideL3 || overrideDIP) {
636 if (!warnPolarityDone) {
637 LOG(error) <<
"Overriden currents have wrong combination for L3/Dipole polarities ("
638 << (l3Pol > 0 ?
'+' :
'-') <<
"/" << (diPol > 0 ?
'+' :
'-') <<
") for convention "
640 warnPolarityDone =
true;
643 LOG(fatal) <<
"MagneticField::createFieldMap: Wrong combination for L3/Dipole polarities ("
644 << (l3Pol > 0 ?
'+' :
'-') <<
"/" << (diPol > 0 ?
'+' :
'-') <<
") for convention "
649 l3 = (l3Pol < 0) ? -sclL3 : sclL3;
650 dip = (diPol < 0) ? -sclDip : sclDip;
655 float beamenergy,
const Char_t* beamtype,
const std::string
path)
657 float sclL3 = l3Cur, sclDip = diCur;
660 TString btypestr = beamtype;
662 TPRegexp protonBeam(R
"((proton|p)\s*-?\s*\1)");
663 TPRegexp ionBeam(R"((lead|pb|ion|a|A)\s*-?\s*\1)");
664 TPRegexp protonionBeam(R"((proton|p)\s*-?\s*(lead|pb|ion|a|A))");
665 TPRegexp ionprotonBeam(R"((lead|pb|ion|a|A)\s*-?\s*(proton|p))");
666 if (btypestr.Contains(ionBeam)) {
668 }
else if (btypestr.Contains(protonBeam)) {
670 }
else if (btypestr.Contains(protonionBeam)) {
672 }
else if (btypestr.Contains(ionprotonBeam)) {
675 LOG(info) <<
"Assume no LHC magnet field for the beam type " << beamtype;
678 snprintf(ttl, 79,
"L3: %+5d Dip: %+4d kA; %s | Polarities in %s convention", (
int)TMath::Sign(l3Cur,
float(sclL3)),
679 (
int)TMath::Sign(diCur,
float(sclDip)), uniform ?
" Constant" :
"",
680 convention ==
kConvLHC ?
"LHC" :
"DCS2008");
686 return new MagneticField(
"MagneticFieldMap", ttl, sclL3, sclDip, map, btype, beamenergy, 2, 10.,
path);
static MagneticField * createFieldMap(float l3Current=-30000., float diCurrent=-6000., Int_t convention=0, Bool_t uniform=kFALSE, float beamenergy=7000, const Char_t *btype="pp", const std::string path=std::string(gSystem->Getenv("VMCWORKDIR"))+std::string("/Common/maps/mfchebKGI_sym.root"))