Skip to content

Commit

Permalink
Change comment syntax in xml file.
Browse files Browse the repository at this point in the history
Attempt to streamline calls to fieldComponents.
  • Loading branch information
dhevang committed Sep 22, 2023
1 parent 1be7ce2 commit 14a2ef4
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 95 deletions.
5 changes: 3 additions & 2 deletions compact/far_backward/lumi/lumi_magnets.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ Construct the sweeper and analyzer dipole magnets for the luminosity subsystem.
<fields>

<comment> Ideal fields </comment>
<!--<field name="LumiSweeperField" type="MultipoleMagnet">
<comment>
<field name="LumiSweeperField" type="MultipoleMagnet">
<position x="LumiSweepMag_X" y="LumiSweepMag_Y" z="LumiSweepMag_Z"/>
<rotation x="0" y="0" z="0"/>
<shape type="Box" dx="LumiMag_DX_InnerBox/2.0" dy="LumiMag_DY_InnerBox/2.0" dz="LumiMag_DZ/2.0"/>
Expand All @@ -94,7 +95,7 @@ Construct the sweeper and analyzer dipole magnets for the luminosity subsystem.
<shape type="Box" dx="LumiMag_DX_InnerBox/2.0" dy="LumiMag_DY_InnerBox/2.0" dz="LumiMag_DZ/2.0"/>
<coefficient coefficient="0" skew="LumiAnalyzerIdealMag_B"/>
</field>
-->
</comment>

<comment> Calculated fields </comment>
<field type="epic_FieldMapB" name="LumiSweeperField" field_type="magnetic" coord_type="BxByBz"
Expand Down
198 changes: 105 additions & 93 deletions src/FieldMapB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ class FieldMapB : public dd4hep::CartesianField::Object {
FieldMapB(const std::string& field_type_str = "magnetic", const std::string& coord_type_str = "BrBz");
void Configure(std::vector<xml_comp_t> dimensions);
void LoadMap(const std::string& map_file, double scale);
void GetIndices(std::vector<double> coord, std::vector<int> *indices, std::vector<double> *deltas);
bool GetIndices(double R, double Z, int *idxR, int *idxZ, double *deltaR, double *deltaZ);
bool GetIndices(double X, double Y, double Z, int *idxX, int *idxY, int *idxZ, double *deltaX, double *deltaY, double *deltaZ);
void SetTransform(const Transform3D& tr)
{
trans = tr;
Expand All @@ -66,11 +67,15 @@ class FieldMapB : public dd4hep::CartesianField::Object {
virtual void fieldComponents(const double* pos, double* field);

private:
std::string coord_type;
Transform3D trans, trans_inv;
std::vector<double> steps, mins, maxs;
std::vector<std::vector<std::vector<double>>> Bvals_RZ; // {R}, {Z}, {Br,Bz}
std::vector<std::vector<std::vector<std::vector<double>>>> Bvals_XYZ; // {X}, {Y}, {Z}, {Bx,By,Bz}
bool case_BrBz; // is it BrBz or not (BxByBz)
Transform3D trans, trans_inv; // transformation matrices
std::vector<double> steps, mins, maxs; // B map cell info
int ir, ix, iy, iz; // lookup indices
double ir_d, ix_d, iy_d, iz_d; // transient indices for std::modf
double dr, dx, dy, dz; // deltas for interpolation
std::vector<std::vector<std::vector<double>>> Bvals_RZ; // B map values: {R}, {Z}, {Br,Bz}
std::vector<std::vector<std::vector<std::vector<double>>>> Bvals_XYZ; // B map values: {X}, {Y}, {Z}, {Bx,By,Bz}
ROOT::Math::XYZPoint B_interpolated; // interpolated B
};

// constructor
Expand All @@ -91,7 +96,12 @@ FieldMapB::FieldMapB(const std::string& field_type_str, const std::string& coord
std::cout << "FieldMapB Warning: Unknown field type " << field_type_str << "!" << std::endl;
}

coord_type = coord_type_str;
if( coord_type_str.compare("BrBz") == 0 ) { // BrBz
case_BrBz = true;
}
else { // BxByBz
case_BrBz = false;
}
}

// fill field vector
Expand All @@ -104,7 +114,7 @@ void FieldMapB::Configure(std::vector<xml_comp_t> dimensions)
maxs.push_back( getAttrOrDefault<double>(el, _Unicode(max), 0) );
}

if( coord_type.compare("BrBz") == 0 ) {
if( case_BrBz ) {
int nr = int((maxs[0] - mins[0]) / steps[0]) + 2;
int nz = int((maxs[1] - mins[1]) / steps[1]) + 2;

Expand All @@ -116,8 +126,7 @@ void FieldMapB::Configure(std::vector<xml_comp_t> dimensions)
}
}
}

if( coord_type.compare("BxByBz") == 0 ) {
else {
int nx = int((maxs[0] - mins[0]) / steps[0]) + 2;
int ny = int((maxs[1] - mins[1]) / steps[1]) + 2;
int nz = int((maxs[2] - mins[2]) / steps[2]) + 2;
Expand All @@ -135,21 +144,42 @@ void FieldMapB::Configure(std::vector<xml_comp_t> dimensions)
}
}

// get cell indices corresponding to point of interest
void FieldMapB::GetIndices(std::vector<double> coord, std::vector<int> *indices, std::vector<double> *deltas)
// get RZ cell indices corresponding to point of interest
bool FieldMapB::GetIndices(double R, double Z, int *idxR, int *idxZ, double *deltaR, double *deltaZ)
{
// boundary check
if( R > maxs[0] || R < mins[0] || Z > maxs[1] || Z < mins[1] ) {
return false;
}

// get indices
*deltaR = std::modf( (R - mins[0]) / steps[0], &ir_d );
*deltaZ = std::modf( (Z - mins[1]) / steps[1], &iz_d );

*idxR = static_cast<int>( ir_d );
*idxZ = static_cast<int>( iz_d );

return true;
}

// get XYZ cell indices corresponding to point of interest
bool FieldMapB::GetIndices(double X, double Y, double Z, int *idxX, int *idxY, int *idxZ, double *deltaX, double *deltaY, double *deltaZ)
{
for( uint i = 0; i < coord.size(); i++ ) {
// Range check
if( coord[i] < mins[i] || coord[i] > maxs[i] ) {
indices->clear();
indices->resize( coord.size(), -1 );
return;
}

double temp_idx;
deltas->push_back( std::modf( (coord[i] - mins[i]) / steps[i], &temp_idx ) );
indices->push_back( static_cast<int>(temp_idx) );
// boundary check
if( X > maxs[0] || X < mins[0] || Y > maxs[1] || Y < mins[1] || Z > maxs[2] || Z < mins[2] ) {
return false;
}

// get indices
*deltaX = std::modf( (X - mins[0]) / steps[0], &ix_d );
*deltaY = std::modf( (Y - mins[1]) / steps[1], &iy_d );
*deltaZ = std::modf( (Z - mins[2]) / steps[2], &iz_d );

*idxX = static_cast<int>( ix_d );
*idxY = static_cast<int>( iy_d );
*idxZ = static_cast<int>( iz_d );

return true;
}

// load data
Expand All @@ -163,42 +193,38 @@ void FieldMapB::LoadMap(const std::string& map_file, double scale)

std::vector<double> coord = {};
std::vector<double> Bcomp = {};
std::vector<int> indices = {};
std::vector<double> deltas = {};

while (std::getline(input, line).good()) {
std::istringstream iss(line);

coord.clear();
Bcomp.clear();
indices.clear();
deltas.clear();

if( coord_type.compare("BrBz") == 0 ) {
if( case_BrBz ) {
coord.resize(2);
Bcomp.resize(2);
iss >> coord[0] >> coord[1] >> Bcomp[0] >> Bcomp[1];

if( ! GetIndices( coord[0], coord[1], &ir, &iz, &dr, &dz) ) {
std::cout << "FieldMapB Warning: coordinates out of range, skipped it."<< std::endl;
}
else {
Bvals_RZ[ ir ][ iz ] = { Bcomp[0] * scale, Bcomp[1] * scale };
//ROOT::Math::XYZPoint p(coord[0], 0, coord[1]);
//std::cout << p << " -> " << trans*p << std::endl;
//std::cout << indices[0] << ", " << indices[1] << ", " << Bcomp[0] << ", " << Bcomp[1] << std::endl;
}
}
if( coord_type.compare("BxByBz") == 0 ) {
else {
coord.resize(3);
Bcomp.resize(3);
iss >> coord[0] >> coord[1] >> coord[2] >> Bcomp[0] >> Bcomp[1] >> Bcomp[2];
}

GetIndices(coord, &indices, &deltas);

if (std::count( indices.begin(), indices.end(), -1)) {
std::cout << "FieldMapB Warning: coordinates out of range, skipped it."
<< std::endl;
} else {
if( coord_type.compare("BrBz") == 0 ) {
Bvals_RZ[ indices[0] ][ indices[1] ] = {Bcomp[0] * scale, Bcomp[1] * scale};
//ROOT::Math::XYZPoint p(coord[0], 0, coord[1]);
//std::cout << p << " -> " << trans*p << std::endl;
//std::cout << indices[0] << ", " << indices[1] << ", " << Bcomp[0] << ", " << Bcomp[1] << std::endl;
if( ! GetIndices(coord[0], coord[1], coord[2], &ix, &iy, &iz, &dx, &dy, &dz) ) {
std::cout << "FieldMapB Warning: coordinates out of range, skipped it."<< std::endl;
}
if( coord_type.compare("BxByBz") == 0 ) {
Bvals_XYZ[ indices[0] ][ indices[1] ][ indices[2] ] = {Bcomp[0] * scale, Bcomp[1] * scale, Bcomp[2] * scale};
else {
Bvals_XYZ[ ix ][ iy ][ iz ] = { Bcomp[0] * scale, Bcomp[1] * scale, Bcomp[2] * scale };
}
}
}
Expand All @@ -210,81 +236,67 @@ void FieldMapB::fieldComponents(const double* pos, double* field)
// coordinate conversion
auto p = trans_inv * ROOT::Math::XYZPoint(pos[0], pos[1], pos[2]);

std::vector<int> indices = {};
std::vector<double> deltas = {};
ROOT::Math::XYZPoint B = ROOT::Math::XYZPoint(0,0,0);

if( coord_type.compare("BrBz") == 0 ) {
if( case_BrBz ) {
// coordinates conversion
const double r = sqrt(p.x() * p.x() + p.y() * p.y());
const double z = p.z();
const double phi = atan2(p.y(), p.x());

GetIndices({r, z}, &indices, &deltas);

// out of the range
if (std::count( indices.begin(), indices.end(), -1)) {
if( ! GetIndices(r, z, &ir, &iz, &dr, &dz) ) {
// out of range
return;
}

// p1 p3
// p
// p0 p2
auto& p0 = Bvals_RZ[indices[0]][indices[1]];
auto& p1 = Bvals_RZ[indices[0]][indices[1] + 1];
auto& p2 = Bvals_RZ[indices[0] + 1][indices[1]];
auto& p3 = Bvals_RZ[indices[0] + 1][indices[1] + 1];
auto& p0 = Bvals_RZ[ ir ][ iz ];
auto& p1 = Bvals_RZ[ ir ][ iz + 1];
auto& p2 = Bvals_RZ[ ir + 1 ][ iz ];
auto& p3 = Bvals_RZ[ ir + 1 ][ iz + 1];

// Bilinear interpolation
double Br = p0[0] * (1 - deltas[0]) * (1 - deltas[1])
+ p1[0] * (1 - deltas[0]) * deltas[1]
+ p2[0] * deltas[0] * (1 - deltas[1])
+ p3[0] * deltas[0] * deltas[1];
double Br = p0[0] * (1 - dr) * (1 - dz) + p1[0] * (1 - dr) * dz
+ p2[0] * dr * (1 - dz) + p3[0] * dr * dz;

double Bz = p0[1] * (1 - deltas[0]) * (1 - deltas[1])
+ p1[1] * (1 - deltas[0]) * deltas[1]
+ p2[1] * deltas[0] * (1 - deltas[1])
+ p3[1] * deltas[0] * deltas[1];
double Bz = p0[1] * (1 - dr) * (1 - dz) + p1[1] * (1 - dr) * dz
+ p2[1] * dr * (1 - dz) + p3[1] * dr * dz;

// convert Br Bz to Bx By Bz
B = ROOT::Math::XYZPoint(Br * sin(phi), Br * cos(phi), Bz);
B = trans * B;
B_interpolated = ROOT::Math::XYZPoint(Br * sin(phi), Br * cos(phi), Bz);
B_interpolated = trans * B_interpolated;
}
else {

if( coord_type.compare("BxByBz") == 0 ) {

GetIndices({p.x(), p.y(), p.z()}, &indices, &deltas);

// out of the range
if (std::count( indices.begin(), indices.end(), -1)) {
return;
if( ! GetIndices(p.x(), p.y(), p.z(), &ix, &iy, &iz, &dx, &dy, &dz) ) {
return; // out of range
}

double b[3] = {0};
for(int comp = 0; comp < 3; comp++) { // field component loop
// Trilinear interpolation
// First along X, along 4 lines
double b00 = Bvals_XYZ[indices[0]][indices[1]][indices[2]][comp] * (1 - deltas[0])
+ Bvals_XYZ[indices[0] + 1][indices[1]][indices[2]][comp] * deltas[0];
double b01 = Bvals_XYZ[indices[0]][indices[1]][indices[2] + 1][comp] * (1 - deltas[0])
+ Bvals_XYZ[indices[0] + 1][indices[1]][indices[2] + 1][comp] * deltas[0];
double b10 = Bvals_XYZ[indices[0]][indices[1] + 1][indices[2]][comp] * (1 - deltas[0])
+ Bvals_XYZ[indices[0] + 1][indices[1] + 1][indices[2]][comp] * deltas[0];
double b11 = Bvals_XYZ[indices[0]][indices[1] + 1][indices[2] + 1][comp] * (1 - deltas[0])
+ Bvals_XYZ[indices[0] + 1][indices[1] + 1][indices[2] + 1][comp] * deltas[0];
//// Next along Y, along 2 lines
double b0 = b00 * (1 - deltas[1]) + b10 * deltas[1];
double b1 = b01 * (1 - deltas[1]) + b11 * deltas[1];
//// Finally along Z
double b = b0 * (1 - deltas[2]) + b1 * deltas[2];
if(comp == 0) { B.SetX( b ); }
if(comp == 1) { B.SetY( b ); }
if(comp == 2) { B.SetZ( b ); }
double b00 = Bvals_XYZ[ ix ][ iy ][ iz ][comp] * (1 - dx)
+ Bvals_XYZ[ ix + 1][ iy ][ iz ][comp] * dx;
double b01 = Bvals_XYZ[ ix ][ iy ][ iz + 1][comp] * (1 - dx)
+ Bvals_XYZ[ ix + 1][ iy ][ iz + 1][comp] * dx;
double b10 = Bvals_XYZ[ ix ][ iy + 1][ iz ][comp] * (1 - dx)
+ Bvals_XYZ[ ix + 1][ iy + 1][ iz ][comp] * dx;
double b11 = Bvals_XYZ[ ix ][ iy + 1][ iz + 1][comp] * (1 - dx)
+ Bvals_XYZ[ ix + 1][ iy + 1][ iz + 1][comp] * dx;
// Next along Y, along 2 lines
double b0 = b00 * (1 - dy) + b10 * dy;
double b1 = b01 * (1 - dy) + b11 * dy;
// Finally along Z
b[comp] = b0 * (1 - dz) + b1 * dz;
}

B_interpolated = ROOT::Math::XYZPoint( b[0], b[1], b[2] );
}

field[0] += B.x() * tesla;
field[1] += B.y() * tesla;
field[2] += B.z() * tesla;
field[0] += B_interpolated.x() * tesla;
field[1] += B_interpolated.y() * tesla;
field[2] += B_interpolated.z() * tesla;

return;
}
Expand Down Expand Up @@ -323,7 +335,7 @@ static Ref_t create_field_map_b(Detector& /*lcdd*/, xml::Handle_t handle)
printout(ERROR, "FieldMapB", "Coordinate type: " + coord_type + ", is not BrBz nor BxByBz");
std::_Exit(EXIT_FAILURE);
}

std::string field_map_file = x_par.attr<std::string>(_Unicode(field_map));
std::string field_map_url = x_par.attr<std::string>(_Unicode(url));
std::string field_map_cache = getAttrOrDefault<std::string>(x_par, _Unicode(cache), "");
Expand Down

0 comments on commit 14a2ef4

Please sign in to comment.