101 Double_t fmax,
const std::string
path)
103 mMeasuredMap(nullptr),
109 mDefaultIntegration(integ),
111 mMultipicativeFactorSolenoid(factorSol),
112 mMultipicativeFactorDipole(factorDip),
114 mDipoleOnOffFlag(factorDip == 0.),
115 mQuadrupoleGradient(0),
117 mCompensatorField2C(0),
118 mCompensatorField1A(0),
119 mCompensatorField2A(0),
120 mParameterNames(
"",
"")
279 double xyz[3] = {xyzExt[0] - gOriginBias->
x, xyzExt[1] - gOriginBias->
y, xyzExt[2] - gOriginBias->
z};
281 if (mFastField && mFastField->Field(xyz,
b)) {
285 if (mMeasuredMap && xyz[2] > mMeasuredMap->getMinZ() && xyz[2] < mMeasuredMap->getMaxZ()) {
286 mMeasuredMap->Field(xyz,
b);
287 if (xyz[2] > sSolenoidToDipoleZ || mDipoleOnOffFlag) {
288 for (
int i = 3;
i--;) {
289 b[
i] *= mMultipicativeFactorSolenoid;
292 for (
int i = 3;
i--;) {
293 b[
i] *= mMultipicativeFactorDipole;
306 double xyz[3] = {xyzExt[0] - gOriginBias->
x, xyzExt[1] - gOriginBias->
y, xyzExt[2] - gOriginBias->
z};
309 if (mFastField->GetBz(xyz, bz)) {
313 if (mMeasuredMap && xyz[2] > mMeasuredMap->getMinZ() && xyz[2] < mMeasuredMap->getMaxZ()) {
314 double bz = mMeasuredMap->getBz(xyz);
315 return (xyz[2] > sSolenoidToDipoleZ || mDipoleOnOffFlag) ? bz * mMultipicativeFactorSolenoid
316 : bz * mMultipicativeFactorDipole;
377 const Double_t kBComp1CZ = 1075., kBComp1hDZ = 260. / 2., kBComp1SqR = 4.0 * 4.0;
378 const Double_t kBComp2CZ = 2049., kBComp2hDZ = 153. / 2., kBComp2SqR = 4.5 * 4.5;
380 const Double_t kTripQ1CZ = 2615., kTripQ1hDZ = 637. / 2., kTripQ1SqR = 3.5 * 3.5;
381 const Double_t kTripQ2CZ = 3480., kTripQ2hDZ = 550. / 2., kTripQ2SqR = 3.5 * 3.5;
382 const Double_t kTripQ3CZ = 4130., kTripQ3hDZ = 550. / 2., kTripQ3SqR = 3.5 * 3.5;
383 const Double_t kTripQ4CZ = 5015., kTripQ4hDZ = 637. / 2., kTripQ4SqR = 3.5 * 3.5;
385 const Double_t kDip1CZ = 6310.8, kDip1hDZ = 945. / 2., kDip1SqRC = 4.5 * 4.5, kDip1SqRA = 3.375 * 3.375;
386 const Double_t kDip2CZ = 12640.3, kDip2hDZ = 945. / 2., kDip2SqRC = 4.5 * 4.5, kDip2SqRA = 3.75 * 3.75;
387 const Double_t kDip2DXC = 9.7, kDip2DXA = 9.4;
389 double rad2 =
x[0] *
x[0] +
x[1] *
x[1];
391 b[0] =
b[1] =
b[2] = 0;
395 if (TMath::Abs(
x[2] + kBComp2CZ) < kBComp2hDZ && rad2 < kBComp2SqR) {
396 b[0] = mCompensatorField2C * mMultipicativeFactorDipole;
397 }
else if (TMath::Abs(
x[2] + kTripQ1CZ) < kTripQ1hDZ && rad2 < kTripQ1SqR) {
398 b[0] = mQuadrupoleGradient *
x[1];
399 b[1] = mQuadrupoleGradient *
x[0];
400 }
else if (TMath::Abs(
x[2] + kTripQ2CZ) < kTripQ2hDZ && rad2 < kTripQ2SqR) {
401 b[0] = -mQuadrupoleGradient *
x[1];
402 b[1] = -mQuadrupoleGradient *
x[0];
403 }
else if (TMath::Abs(
x[2] + kTripQ3CZ) < kTripQ3hDZ && rad2 < kTripQ3SqR) {
404 b[0] = -mQuadrupoleGradient *
x[1];
405 b[1] = -mQuadrupoleGradient *
x[0];
406 }
else if (TMath::Abs(
x[2] + kTripQ4CZ) < kTripQ4hDZ && rad2 < kTripQ4SqR) {
407 b[0] = mQuadrupoleGradient *
x[1];
408 b[1] = mQuadrupoleGradient *
x[0];
409 }
else if (TMath::Abs(
x[2] + kDip1CZ) < kDip1hDZ && rad2 < kDip1SqRC) {
411 }
else if (TMath::Abs(
x[2] + kDip2CZ) < kDip2hDZ && rad2 < kDip2SqRC) {
412 double dxabs = TMath::Abs(
x[0]) - kDip2DXC;
413 if ((dxabs * dxabs +
x[1] *
x[1]) < kDip2SqRC) {
414 b[1] = -mDipoleField;
421 if (TMath::Abs(
x[2] - kBComp1CZ) < kBComp1hDZ && rad2 < kBComp1SqR) {
423 b[0] = mCompensatorField1A * mMultipicativeFactorDipole;
426 if (TMath::Abs(
x[2] - kBComp2CZ) < kBComp2hDZ && rad2 < kBComp2SqR) {
427 b[0] = mCompensatorField2A * mMultipicativeFactorDipole;
428 }
else if (TMath::Abs(
x[2] - kTripQ1CZ) < kTripQ1hDZ && rad2 < kTripQ1SqR) {
429 b[0] = -mQuadrupoleGradient *
x[1];
430 b[1] = -mQuadrupoleGradient *
x[0];
431 }
else if (TMath::Abs(
x[2] - kTripQ2CZ) < kTripQ2hDZ && rad2 < kTripQ2SqR) {
432 b[0] = mQuadrupoleGradient *
x[1];
433 b[1] = mQuadrupoleGradient *
x[0];
434 }
else if (TMath::Abs(
x[2] - kTripQ3CZ) < kTripQ3hDZ && rad2 < kTripQ3SqR) {
435 b[0] = mQuadrupoleGradient *
x[1];
436 b[1] = mQuadrupoleGradient *
x[0];
437 }
else if (TMath::Abs(
x[2] - kTripQ4CZ) < kTripQ4hDZ && rad2 < kTripQ4SqR) {
438 b[0] = -mQuadrupoleGradient *
x[1];
439 b[1] = -mQuadrupoleGradient *
x[0];
440 }
else if (TMath::Abs(
x[2] - kDip1CZ) < kDip1hDZ && rad2 < kDip1SqRA) {
441 b[1] = -mDipoleField;
442 }
else if (TMath::Abs(
x[2] - kDip2CZ) < kDip2hDZ && rad2 < kDip2SqRA) {
443 double dxabs = TMath::Abs(
x[0]) - kDip2DXA;
444 if ((dxabs * dxabs +
x[1] *
x[1]) < kDip2SqRA) {
564 const float l3NominalCurrent1 = 30000.f;
565 const float l3NominalCurrent2 = 12000.f;
566 const float diNominalCurrent = 6000.f;
568 const float tolerance = 0.03;
569 const float zero = 77.f;
573 float l3sav = l3, dipsav = dip;
575 float l3Pol = l3 > 0 ? 1 : -1;
576 float diPol = dip > 0 ? 1 : -1;
579 dip = TMath::Abs(dip);
580 static bool overrideL3 = std::getenv(
"O2_OVERRIDE_L3_CURRENT") !=
nullptr;
581 static bool overrideDIP = std::getenv(
"O2_OVERRIDE_DIPOLE_CURRENT") !=
nullptr;
582 static bool warnL3Done =
false, warnDipDone =
false, warnPolarityDone =
false;
584 if (TMath::Abs((sclDip = dip / diNominalCurrent) - 1.) > tolerance && !uniform) {
589 LOG(fatal) <<
"MagneticField::createFieldMap: Wrong dipole current (" << dipsav <<
" A)!";
592 LOGP(error,
"Dipole current was overridden to unsupported value {}", dipsav);
602 sclL3 = l3 / l3NominalCurrent1;
604 if (TMath::Abs((sclL3 = l3 / l3NominalCurrent1) - 1.) < tolerance) {
606 }
else if (TMath::Abs((sclL3 = l3 / l3NominalCurrent2) - 1.) < tolerance) {
608 }
else if (l3 <= zero && dip <= zero) {
614 LOG(fatal) <<
"MagneticField::createFieldMap: Wrong L3 current (" << l3sav <<
" A)!";
617 LOGP(error,
"L3 current was overridden to unsupported value {}", l3sav);
621 sclL3 = l3 / l3NominalCurrent1;
627 ((convention ==
kConvLHC && l3Pol != diPol) || (convention ==
kConvDCS2008 && l3Pol == diPol))) {
628 if (overrideL3 || overrideDIP) {
629 if (!warnPolarityDone) {
630 LOG(error) <<
"Overriden currents have wrong combination for L3/Dipole polarities ("
631 << (l3Pol > 0 ?
'+' :
'-') <<
"/" << (diPol > 0 ?
'+' :
'-') <<
") for convention "
633 warnPolarityDone =
true;
636 LOG(fatal) <<
"MagneticField::createFieldMap: Wrong combination for L3/Dipole polarities ("
637 << (l3Pol > 0 ?
'+' :
'-') <<
"/" << (diPol > 0 ?
'+' :
'-') <<
") for convention "
642 l3 = (l3Pol < 0) ? -sclL3 : sclL3;
643 dip = (diPol < 0) ? -sclDip : sclDip;
648 float beamenergy,
const Char_t* beamtype,
const std::string
path)
650 float sclL3 = l3Cur, sclDip = diCur;
653 TString btypestr = beamtype;
655 TPRegexp protonBeam(R
"((proton|p)\s*-?\s*\1)");
656 TPRegexp ionBeam(R"((lead|pb|ion|a|A)\s*-?\s*\1)");
657 TPRegexp protonionBeam(R"((proton|p)\s*-?\s*(lead|pb|ion|a|A))");
658 TPRegexp ionprotonBeam(R"((lead|pb|ion|a|A)\s*-?\s*(proton|p))");
659 if (btypestr.Contains(ionBeam)) {
661 }
else if (btypestr.Contains(protonBeam)) {
663 }
else if (btypestr.Contains(protonionBeam)) {
665 }
else if (btypestr.Contains(ionprotonBeam)) {
668 LOG(info) <<
"Assume no LHC magnet field for the beam type " << beamtype;
671 snprintf(ttl, 79,
"L3: %+5d Dip: %+4d kA; %s | Polarities in %s convention", (
int)TMath::Sign(l3Cur,
float(sclL3)),
672 (
int)TMath::Sign(diCur,
float(sclDip)), uniform ?
" Constant" :
"",
673 convention ==
kConvLHC ?
"LHC" :
"DCS2008");
679 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"))