17#include "FairLogger.h"
22 const std::string& mapFileName, Float_t xOffset,
23 Float_t yOffset, Float_t zOffset, Float_t phi,
24 Float_t theta, Float_t psi, Float_t scale,
26 : TVirtualMagField(label.c_str()),
28 mapFileName_(mapFileName),
54 isSymmetric_(isSymmetric),
75 Float_t newYOffset, Float_t newZOffset,
76 Float_t newPhi, Float_t newTheta, Float_t newPsi,
78 : TVirtualMagField(newName.c_str()),
79 fieldMap_(rhs.fieldMap_),
80 mapFileName_(rhs.GetMapFileName()),
100 yOffset_(newYOffset),
101 zOffset_(newZOffset),
106 isSymmetric_(rhs.isSymmetric_),
121 Double_t localCoords[3] = {position[0], position[1], position[2]};
124 theTrans_->MasterToLocal(position, localCoords);
128 Float_t x = localCoords[0];
129 Float_t y = localCoords[1];
130 Float_t z = localCoords[2];
167 if (inside == kFALSE) {
176 Int_t iX = xBinInfo.first;
177 Int_t iY = yBinInfo.first;
178 Int_t iZ = zBinInfo.first;
181 if (iX == -1 || iY == -1 || iZ == -1) {
223 if (fabs(
phi_) > 1e-6 || fabs(
theta_) > 1e-6 || fabs(
psi_) > 1e-6) {
240 LOG(info) <<
"ShipBFieldMap::readMapFile() creating field " << this->GetName()
256 LOG(fatal) <<
"ShipBFieldMap: could not find the file " <<
mapFileName_;
260 TTree* rTree =
dynamic_cast<TTree*
>(theFile->Get(
"Range"));
262 LOG(fatal) <<
"ShipBFieldMap: could not find Range tree in "
266 rTree->SetBranchAddress(
"xMin", &
xMin_);
267 rTree->SetBranchAddress(
"xMax", &
xMax_);
268 rTree->SetBranchAddress(
"dx", &
dx_);
269 rTree->SetBranchAddress(
"yMin", &
yMin_);
270 rTree->SetBranchAddress(
"yMax", &
yMax_);
271 rTree->SetBranchAddress(
"dy", &
dy_);
272 rTree->SetBranchAddress(
"zMin", &
zMin_);
273 rTree->SetBranchAddress(
"zMax", &
zMax_);
274 rTree->SetBranchAddress(
"dz", &
dz_);
286 TTree* dTree =
dynamic_cast<TTree*
>(theFile->Get(
"Data"));
288 LOG(fatal) <<
"ShipBFieldMap: could not find Data tree in "
294 dTree->SetBranchStatus(
"*", 0);
295 dTree->SetBranchStatus(
"Bx", 1);
296 dTree->SetBranchStatus(
"By", 1);
297 dTree->SetBranchStatus(
"Bz", 1);
299 dTree->SetBranchAddress(
"Bx", &Bx);
300 dTree->SetBranchAddress(
"By", &By);
301 dTree->SetBranchAddress(
"Bz", &Bz);
303 Int_t nEntries = dTree->GetEntries();
304 if (nEntries !=
N_) {
305 LOG(fatal) <<
"Expected " <<
N_ <<
" field map entries but found "
312 for (Int_t i = 0; i < nEntries; i++) {
332 if (!getData.is_open()) {
333 LOG(fatal) <<
"Error: Cannot open magnetic field map file: "
337 std::string tmpString(
"");
350 getData >> tmpString >> tmpString >> tmpString;
356 Float_t Bx(0.0), By(0.0), Bz(0.0);
358 for (Int_t i = 0; i <
N_; i++) {
359 getData >> Bx >> By >> Bz;
376 Bool_t inside(kFALSE);
378 if (x >=
xMin_ && x <= xMax_ && y >=
yMin_ && y <= yMax_ && z >=
zMin_ &&
409 LOG(info) <<
"x limits: " <<
xMin_ <<
", " <<
xMax_ <<
", dx = " <<
dx_;
410 LOG(info) <<
"y limits: " <<
yMin_ <<
", " <<
yMax_ <<
", dy = " <<
dy_;
411 LOG(info) <<
"z limits: " <<
zMin_ <<
", " <<
zMax_ <<
", dz = " <<
dz_;
415 LOG(info) <<
"Angles : phi = " <<
phi_ <<
", theta = " <<
theta_
416 <<
", psi = " <<
psi_;
418 LOG(info) <<
"Total number of bins = " <<
N_ <<
"; Nx = " <<
Nx_
419 <<
", Ny = " <<
Ny_ <<
", Nz = " <<
Nz_;
424 Float_t du(0.0), uMin(0.0), Nu(0);
446 Float_t dist = (u - uMin) / du;
448 iBin =
static_cast<Int_t
>(dist);
451 fracL = (dist - iBin * 1.0);
455 if (iBin < 0 || iBin >= Nu) {
471 Int_t index = (iX *
Ny_ + iY) *
Nz_ + iZ;
474 }
else if (index >=
N_) {
496 Float_t
A = (*fieldMap_)[
binA_][iAxis];
497 Float_t
B = (*fieldMap_)[
binB_][iAxis];
498 Float_t
C = (*fieldMap_)[
binC_][iAxis];
499 Float_t
D = (*fieldMap_)[
binD_][iAxis];
500 Float_t
E = (*fieldMap_)[
binE_][iAxis];
501 Float_t F = (*fieldMap_)[
binF_][iAxis];
502 Float_t G = (*fieldMap_)[
binG_][iAxis];
503 Float_t H = (*fieldMap_)[
binH_][iAxis];
Class that defines a (3d) magnetic field map (distances in cm, fields in tesla)
Float_t zFrac_
Fractional bin distance along z.
Float_t xMax_
The maximum value of x for the map.
Int_t binD_
Bin D for the trilinear interpolation.
Float_t dy_
The bin width along y.
Float_t psi_
The third Euler rotation angle about the new z axis.
Float_t dz_
The bin width along z.
Float_t zRange_
The coordinate range along z.
std::pair< Int_t, Float_t > binPair
Typedef for an int-double pair.
Float_t zFrac1_
Complimentary fractional bin distance along z.
ShipBFieldMap(const std::string &label, const std::string &mapFileName, Float_t xOffset=0.0, Float_t yOffset=0.0, Float_t zOffset=0.0, Float_t phi=0.0, Float_t theta=0.0, Float_t psi=0.0, Float_t scale=1.0, Bool_t isSymmetric=kFALSE)
Constructor.
Int_t binE_
Bin E for the trilinear interpolation.
Float_t BInterCalc(CoordAxis theAxis)
Int_t Nz_
The number of bins along z.
Float_t Tesla_
Double converting Tesla to kiloGauss (for VMC/FairRoot B field units)
std::vector< std::vector< Float_t > > floatArray
Typedef for a vector containing a vector of floats.
Int_t N_
The total number of bins.
Float_t yFrac1_
Complimentary fractional bin distance along y.
Float_t xFrac_
Fractional bin distance along x.
Float_t yMin_
The minimum value of y for the map.
Float_t zOffset_
The z value of the positional offset for the map.
std::string mapFileName_
The name of the map file.
Bool_t initialised_
Initialisation boolean.
Int_t Ny_
The number of bins along y.
Float_t theta_
The second Euler rotation angle about the new x axis.
Float_t yFrac_
Fractional bin distance along y.
Int_t binC_
Bin C for the trilinear interpolation.
virtual void Field(const Double_t *position, Double_t *B)
Implementation of evaluating the B field.
Int_t binG_
Bin G for the trilinear interpolation.
Int_t binH_
Bin H for the trilinear interpolation.
Float_t xMin_
The minimum value of x for the map.
void initialise()
Initialisation.
Int_t binB_
Bin B for the trilinear interpolation.
Int_t binF_
Bin F for the trilinear interpolation.
CoordAxis
Enumeration to specify the coordinate type.
Int_t Nx_
The number of bins along x.
Float_t xRange_
The coordinate range along x.
Float_t yOffset_
The y value of the positional offset for the map.
void readTextFile()
Process the text file containing the field map data.
Float_t scale_
The B field magnitude scaling factor.
TGeoMatrix * theTrans_
The combined translation and rotation transformation.
binPair getBinInfo(Float_t x, CoordAxis theAxis)
Get the bin number and fractional distance from the leftmost bin edge.
Bool_t insideRange(Float_t x, Float_t y, Float_t z)
Check to see if a point is within the map validity range.
virtual ~ShipBFieldMap()
Destructor.
void readRootFile()
Process the ROOT file containing the field map data.
Float_t xFrac1_
Complimentary fractional bin distance along x.
Int_t binA_
Bin A for the trilinear interpolation.
void readMapFile()
Read the field map data and store the information internally.
Int_t getMapBin(Int_t iX, Int_t iY, Int_t iZ)
Find the vector entry of the field map data given the bins iX, iY and iZ.
Float_t yMax_
The maximum value of y for the map.
Float_t yRange_
The coordinate range along y.
Float_t zMax_
The maximum value of z for the map.
Float_t phi_
The first Euler rotation angle about the z axis.
Float_t zMin_
The minimum value of z for the map.
Float_t dx_
The bin width along x.
Bool_t isSymmetric_
The boolean specifying if we have quadrant symmetry.
Float_t xOffset_
The x value of the positional offset for the map.