23 #include "art_root_io/TFileService.h" 30 #include "TGeoManager.h" 56 auto fieldDescriptions = pset.
get<std::vector<fhicl::ParameterSet>>(
"FieldDescriptions");
58 MagneticFieldDescription fieldDescription;
59 for(
auto itr : fieldDescriptions)
61 fieldDescription.fMode = (mag::MagFieldMode_t)(itr.get<
int>(
"UseField"));
68 if(fieldDescription.fMode == mag::kNoBFieldMode)
71 fieldDescription.fScaleFactor = itr.get<
float>(
"ScaleFactor", 1.0);
72 fieldDescription.fVolume = itr.get<
std::string>(
"MagnetizedVolume");
73 fieldDescription.fGeoVol = gGeoManager->FindVolumeFast(fieldDescription.fVolume.c_str());
76 if(fieldDescription.fGeoVol ==
nullptr)
79 <<
"cannot locate volume " << fieldDescription.fVolume <<
" in gGeoManager, bail";
84 std::vector<double> defaultField = {0, 0, 0};
85 std::vector<double> field = itr.get<std::vector<double>>(
"ConstantField", defaultField);
89 for(
size_t i = 0; i < 3; ++i)
90 fieldDescription.fField[i] = field[i];
92 if(fieldDescription.fMode == mag::kFieldRZMapMode)
94 fieldDescription.fFieldMapFilename = itr.get<
std::string>(
"FieldMapFilename");
96 std::string fn2 = fieldDescription.fFieldMapFilename;
98 sp.find_file(fn2, fullname);
101 if(fullname.empty() ||
stat(fullname.c_str(), &sb) != 0)
104 <<
"Input magnetic field file " << fn2 <<
" not found in FW_SEARCH_PATH!\n";
108 struct RZFieldMap rzmap;
112 std::vector<double> ZAxis = itr.get<std::vector<double>>(
"ZAxis");
113 rzmap.ZAxis.SetXYZ(ZAxis[0], ZAxis[1], ZAxis[2]);
115 std::vector<double> CoordOffset = itr.get<std::vector<double>>(
"CoordOffset");
116 rzmap.CoordOffset.SetXYZ(CoordOffset[0], CoordOffset[1], CoordOffset[2]);
118 std::chrono::duration<double> elapsed_seconds =
end - start;
119 std::cout <<
"GArMagneticField: Finished reading RZ map in " << elapsed_seconds.count() <<
"s, now setting it: " << rzmap.dr
121 std::cout <<
"Array sizes (R, Z): " << rzmap.br.size() <<
" " << rzmap.br[0].size()
123 fieldDescription.fRZFieldMap = rzmap;
126 if(fieldDescription.fMode == mag::kFieldXYZMapMode)
128 fieldDescription.fFieldMapFilename = itr.get<
std::string>(
"FieldMapFilename");
130 std::string fn2 = fieldDescription.fFieldMapFilename;
132 sp.find_file(fn2, fullname);
135 if(fullname.empty() ||
stat(fullname.c_str(), &sb) != 0)
138 <<
"Input magnetic field file " << fn2 <<
" not found in FW_SEARCH_PATH!\n";
142 struct XYZFieldMap xyzmap;
146 std::vector<double> ZAxis
147 = itr.get<std::vector<double>>(
"ZAxis", std::vector<double>{0.0, 0.0, 1.0});
148 xyzmap.ZAxis.SetXYZ(ZAxis[0], ZAxis[1], ZAxis[2]);
150 xyzmap.CoordOffset.SetXYZ(xyzmap.xo, xyzmap.yo, xyzmap.zo);
151 std::chrono::duration<double> elapsed_seconds =
end - start;
152 std::cout <<
"GArMagneticField: Finished reading XYZ map in " << elapsed_seconds.count()
155 xyzmap.UseSymmetry = itr.get<
bool>(
"UseSymmetry",
false);
156 std::cout <<
"GArMagneticField: Is map symmetric - " << std::boolalpha
158 fieldDescription.fXYZFieldMap = xyzmap;
173 double point[3] = {p.x(), p.y(), p.z()};
174 G4ThreeVector zerofield(0, 0, 0);
175 G4ThreeVector calculatedfield = zerofield;
183 if(fd.fGeoVol->Contains(point))
186 if(fd.fMode == mag::kConstantBFieldMode || fd.fMode == mag::kAutomaticBFieldMode)
188 calculatedfield = fd.fField;
190 else if(fd.fMode == mag::kNoBFieldMode)
192 calculatedfield = zerofield;
194 else if(fd.fMode == mag::kFieldRZMapMode)
198 else if(fd.fMode == mag::kFieldXYZMapMode)
204 throw cet::exception(
"GArMagneticField_service: Ununderstood field mode: ")
208 calculatedfield *= fd.fScaleFactor;
214 return calculatedfield;
225 if(fd.fVolume.compare(volName) == 0)
230 return G4ThreeVector(0);
236 std::cout <<
"GArMagneticField: Opening magnetic field RZ map in: " << filename <<
std::endl;
237 std::ifstream
inFile(filename, std::ios::in);
246 while(std::getline(inFile, line))
255 std::stringstream linestream(line);
256 linestream >> x >> y >> z >> bx >> by >> bz >>
b;
261 float r = TMath::Sqrt(x * x + y * y);
264 std::vector<float> emptyvec;
265 if(TMath::Abs(r - rcur) > 0.001 || rcounter < 0)
267 rzmap.br.push_back(emptyvec);
268 rzmap.bz.push_back(emptyvec);
276 rzmap.br[rcounter].push_back(br);
277 rzmap.bz[rcounter].push_back(bz);
289 std::cout <<
"GArMagneticField: Opening magnetic field XYZ map in: " << filename <<
std::endl;
290 std::fstream fin(filename, std::fstream::in);
293 int xcount{-1}, ycount{-1}, zcount{-1};
294 float xcurr{0}, ycurr{0}, zcurr{0};
296 while(std::getline(fin >>
std::ws, line))
298 std::stringstream ss(line);
300 if(ss.str().front() ==
'#')
303 ss >> xyzmap.xo >> xyzmap.yo >> xyzmap.zo >> xyzmap.dx >> xyzmap.dy >> xyzmap.dz;
306 xyzmap.xo *= unitFactor;
307 xyzmap.yo *= unitFactor;
308 xyzmap.zo *= unitFactor;
309 xyzmap.dx *= unitFactor;
310 xyzmap.dy *= unitFactor;
311 xyzmap.dz *= unitFactor;
316 while(std::getline(fin >>
std::ws, line))
318 float x{0},
y{0},
z{0}, fx{0}, fy{0}, fz{0},
f{0};
319 std::stringstream ss(line);
321 if(ss.str().front() ==
'#')
324 ss >>
x >>
y >>
z >> fx >> fy >> fz >>
f;
331 if(
std::abs(
x - xcurr) > 0.0 || xcount < 0)
336 xyzmap.fx.emplace_back(
std::vector<std::vector<float>>{});
337 xyzmap.fy.emplace_back(
std::vector<std::vector<float>>{});
338 xyzmap.fz.emplace_back(
std::vector<std::vector<float>>{});
341 if(
std::abs(
y - ycurr) > 0.0 || ycount < 0)
346 xyzmap.fx[xcount].emplace_back(std::vector<float>{});
347 xyzmap.fy[xcount].emplace_back(std::vector<float>{});
348 xyzmap.fz[xcount].emplace_back(std::vector<float>{});
351 xyzmap.fx[xcount][ycount].push_back(fx);
352 xyzmap.fy[xcount][ycount].push_back(fy);
353 xyzmap.fz[xcount][ycount].push_back(fz);
355 if(
std::abs(
z - zcurr) > 0.0 || zcount < 0)
369 throw cet::exception(
"GArMagneticField: RZ map bad R spacing:") << rzm.dr;
373 throw cet::exception(
"GArMagneticField: RZ map bad Z spacing:") << rzm.dz;
376 TVector3 pv(p.x(), p.y(), p.z());
377 TVector3 ploc = pv - rzm.CoordOffset;
378 float zloc = ploc.Dot(rzm.ZAxis);
379 float rloc = (ploc.Cross(rzm.ZAxis)).Mag();
380 float azloc = TMath::Abs(zloc);
381 if(azloc > rzm.dz * rzm.nz() || rloc > rzm.dr * rzm.nr())
383 return G4ThreeVector(0, 0, 0);
387 TVector3 fv(0, 0, 0);
388 size_t ibinr = rloc / rzm.dr;
389 size_t ibinz = azloc / rzm.dz;
390 float bzcomponent = rzm.bz.at(ibinr).at(ibinz);
400 = ((rzm.bz.at(ibinr).at(ibinz + 1) - bzcomponent) / rzm.dz) * (azloc - (
int)azloc);
405 float dbz = (bzcomponent - (rzm.bz.at(ibinr).at(ibinz - 1)) / rzm.dz)
406 * (azloc - rzm.dz * ((
int)azloc / rzm.dz));
409 fv = bzcomponent * rzm.ZAxis;
411 float bradial = rzm.br.at(ibinr).at(ibinz);
414 float dbr = ((rzm.br.at(ibinr + 1).at(ibinz) - bradial) / rzm.dr)
415 * (rloc - rzm.dr * ((
int)rloc / rzm.dr));
420 float dbr = (bradial - (rzm.br.at(ibinr - 1).at(ibinz)) / rzm.dr)
421 * (rloc - rzm.dr * ((
int)rloc / rzm.dr));
427 TVector3 rperp = ploc - zloc * rzm.ZAxis;
428 float mrp = rperp.Mag();
433 rperp *= (1.0 / mrp);
436 fv += rperp * bradial;
440 fv -= rperp * bradial;
443 G4ThreeVector fvg(fv.X(), fv.Y(), fv.Z());
451 const float x = fd.UseSymmetry ?
std::abs(p.x() - fd.xo) : p.x() - fd.xo;
452 const float y = fd.UseSymmetry ?
std::abs(p.y() - fd.yo) : p.y() - fd.yo;
453 const float z = fd.UseSymmetry ?
std::abs(p.z() - fd.zo) : p.z() - fd.zo;
456 const float bx = interp.
interpolate(x, y, z, fd.fx, fd.dx, fd.dy, fd.dz, 0.0, 0.0, 0.0);
457 const float by = interp.
interpolate(x, y, z, fd.fy, fd.dx, fd.dy, fd.dz, 0.0, 0.0, 0.0);
458 const float bz = interp.
interpolate(x, y, z, fd.fz, fd.dx, fd.dy, fd.dz, 0.0, 0.0, 0.0);
460 return G4ThreeVector(bx, by, bz);
469 const float* delta,
const float* offset)
const 471 return interpolate(point[0], point[1], point[2],
g, delta[0], delta[1], delta[2], offset[0],
472 offset[1], offset[2]);
478 float hy,
float hz,
float xo,
float yo,
float zo)
const 482 const int xsize =
g.size();
483 const int ysize =
g[0].size();
484 const int zsize =
g[0][0].size();
486 const float xp = (x - xo) / hx;
487 const float yp = (y - yo) / hy;
488 const float zp = (z - zo) / hz;
490 const int x_idx = std::floor(xp);
491 const int y_idx = std::floor(yp);
492 const int z_idx = std::floor(zp);
494 for(
auto i : {x_idx - 1, x_idx, x_idx + 1, x_idx + 2})
496 for(
auto j : {y_idx - 1, y_idx, y_idx + 1, y_idx + 2})
498 for(
auto k : {z_idx - 1, z_idx, z_idx + 1, z_idx + 2})
500 if(i < 0 || j < 0 ||
k < 0)
503 if(i >= xsize || j >= ysize ||
k >= zsize)
506 const float x_c = conv_kernel(xp - i);
507 const float y_c = conv_kernel(yp - j);
508 const float z_c = conv_kernel(zp -
k);
509 v +=
g[i][j][
k] * x_c * y_c * z_c;
524 v = 1 + (0.5) * z * z * (3 * z - 5);
526 else if(1 < z && z < 2)
527 v = 2 - z * (4 + 0.5 * z * (z - 5));
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
static constexpr double g
G4ThreeVector const FieldAtPoint(G4ThreeVector const &p=G4ThreeVector(0)) const override
void reconfigure(fhicl::ParameterSet const &pset)
void ReadXYZFile(const std::string &filename, XYZFieldMap &xyzmap, const float unitFactor)
std::vector< MagneticFieldDescription > fFieldDescriptions
Descriptions of the fields.
GArMagneticField(fhicl::ParameterSet const &pset)
T get(std::string const &key) const
void ReadRZFile(const std::string &filename, RZFieldMap &rzmap)
float interpolate(const float *point, const std::vector< std::vector< std::vector< float >>> &g, const float *delta, const float *offset) const
float conv_kernel(float s) const
G4ThreeVector const UniformFieldInVolume(std::string const &volName) const override
G4ThreeVector CalcRZField(G4ThreeVector const &p, RZFieldMap const &rzmap) const
void line(double t, double *p, double &x, double &y, double &z)
G4ThreeVector CalcXYZField(G4ThreeVector const &p, XYZFieldMap const &xyzmap) const
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)