QwAnalysis
QwMagneticField Class Reference

Magnetic field map object. More...

#include <QwMagneticField.h>

+ Collaboration diagram for QwMagneticField:

Public Member Functions

 QwMagneticField (QwOptions &options, const bool suppress_read_field_map=false)
 Default constructor. More...
 
virtual ~QwMagneticField ()
 Virtual destructor. More...
 
void ProcessOptions (QwOptions &options)
 Process command line and config file options. More...
 
void LoadBeamProperty (const TString &map)
 Load beam property. More...
 
void SetFilename (const std::string &filename)
 Set the filename. More...
 
const std::string GetFilename () const
 Get the filename. More...
 
void SetActualCurrent (const double current)
 Set the actual current. More...
 
double GetActualCurrent () const
 Get the actual current. More...
 
void SetReferenceCurrent (const double current)
 Set the reference current. More...
 
double GetReferenceCurrent () const
 Get the reference current. More...
 
void SetRotation (const double rotation)
 Set the field rotation around z (with QwUnits) More...
 
double GetRotation () const
 Get the field rotation around z (with QwUnits) More...
 
void SetTranslation (const double translation)
 Set the field translation along z. More...
 
double GetTranslation () const
 Get the field translation along z. More...
 
void GetCartesianFieldValue (const double point_xyz[3], double field_xyz[3]) const
 Get the cartesian components of the field value. More...
 
void GetCylindricalFieldValue (const double point_xyz[3], double field_rfz[3]) const
 Get the cylindrical components of the field value. More...
 
void GetCartesianFieldValue (const TVector3 &point, TVector3 &field) const
 Get the cartesian components of the field value. More...
 
bool ReadFieldMap ()
 Read a field map. More...
 
bool ReadFieldMapFile (const std::string &filename)
 Read a field map input file. More...
 
bool ReadFieldMapZip (const std::string &filename)
 Read a field map input gzip file. More...
 
bool ReadFieldMapStream (std::istream &input)
 Read the field map input stream. More...
 
bool TestFieldMap ()
 Test the field map. More...
 
Expose some functionality of underlying field map
bool WriteBinaryFile (const std::string &fieldmap) const
 Write a binary field map. More...
 
bool WriteTextFile (const std::string &fieldmap) const
 Write a text field map. More...
 
void SetInterpolationMethod (const EQwInterpolationMethod method)
 Set interpolation method. More...
 
EQwInterpolationMethod GetInterpolationMethod () const
 Get interpolation method. More...
 

Static Public Member Functions

static void DefineOptions (QwOptions &options)
 Define command line and config file options. More...
 

Private Types

typedef float field_t
 

Private Member Functions

void GetFieldValue (const double point[3], double field[value_n]) const
 Get the field value. More...
 

Private Attributes

std::string fFilename
 File name. More...
 
QwInterpolator< field_t,
value_n > * 
fField
 Field map. More...
 
std::vector< double > fMin
 Field map grid min, max, step, wrap. More...
 
std::vector< double > fMax
 
std::vector< double > fStep
 
std::vector< size_t > fWrap
 
double fReferenceCurrent
 Field scale factor. More...
 
double fActualCurrent
 
double fScaleFactor
 
double fRotation
 Field rotation and translation with respect to the z axis. More...
 
double fRotationDeg
 
double fRotationRad
 
double fRotationCos
 
double fRotationSin
 
double fTranslation
 

Static Private Attributes

static const unsigned int value_n = 3
 

Detailed Description

Magnetic field map object.

This class implements a magnetic field object using the QwInterpolator class.

Five magnetic field components are stored (larger memory usage, computationally more intensive on creation, but faster access by avoiding trigonometric operations).

Access to the field components is possible using two functions:

* field->GetCartesianFieldValue(double point_xyz[3], double field_xyz[3]);
* field->GetCylindricalFieldValue(double point_xyz[3], double field_rfz[3]);
*

Currently no function exists that takes cylindrical coordinates.

Definition at line 50 of file QwMagneticField.h.

Member Typedef Documentation

typedef float QwMagneticField::field_t
private

Definition at line 58 of file QwMagneticField.h.

Constructor & Destructor Documentation

QwMagneticField::QwMagneticField ( QwOptions options,
const bool  suppress_read_field_map = false 
)

Default constructor.

Default constructor with optional field map

Definition at line 44 of file QwMagneticField.cc.

References QwLog::endl(), fField, ProcessOptions(), QwError, ReadFieldMap(), SetActualCurrent(), SetReferenceCurrent(), SetRotation(), SetTranslation(), and value_n.

45 {
46  // Check number of field components
47  if (value_n < 3) {
48  QwError << "Number of field components should be at least three!" << QwLog::endl;
49  }
50 
51  // No field map yet
52  fField = 0;
53 
54  // Initialize parameters
55  SetReferenceCurrent(8960.0);
56  SetActualCurrent(8921.0);
57  SetTranslation(0.0);
58  SetRotation(0.0);
59 
60  // Process options
61  ProcessOptions(options);
62 
63  // Read field map
64  if (! suppress_read_field_map) ReadFieldMap();
65 }
static const unsigned int value_n
void SetActualCurrent(const double current)
Set the actual current.
void ProcessOptions(QwOptions &options)
Process command line and config file options.
QwInterpolator< field_t, value_n > * fField
Field map.
void SetReferenceCurrent(const double current)
Set the reference current.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
void SetTranslation(const double translation)
Set the field translation along z.
void SetRotation(const double rotation)
Set the field rotation around z (with QwUnits)
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40
bool ReadFieldMap()
Read a field map.

+ Here is the call graph for this function:

QwMagneticField::~QwMagneticField ( )
virtual

Virtual destructor.

Destructor

Definition at line 70 of file QwMagneticField.cc.

References fField.

71 {
72  if (fField) delete fField;
73 }
QwInterpolator< field_t, value_n > * fField
Field map.

Member Function Documentation

void QwMagneticField::DefineOptions ( QwOptions options)
static

Define command line and config file options.

Define the options for this subsystem

Parameters
optionsOptions object

Definition at line 79 of file QwMagneticField.cc.

References QwOptions::AddOptions().

Referenced by DefineOptionsTracking(), and main().

80 {
81  // Options
82  options.AddOptions("Magnetic field map")
83  ("QwMagneticField.mapfile",po::value<std::string>()->default_value("peiqing_2011.dat"),
84  "Field map file");
85 
86  options.AddOptions("Magnetic field map")
87  ("QwMagneticField.current",po::value<double>()->default_value(0.0),
88  "Actual current of run to analyze");
89  options.AddOptions("Magnetic field map")
90  ("QwMagneticField.reference",po::value<double>()->default_value(8960.0),
91  "Reference current of field map");
92 
93  options.AddOptions("Magnetic field map")
94  ("QwMagneticField.trans",po::value<double>()->default_value(0),
95  "Translation [cm]");
96  options.AddOptions("Magnetic field map")
97  ("QwMagneticField.rot",po::value<double>()->default_value(0),
98  "Rotation [deg]");
99  options.AddOptions("Magnetic field map")
100  ("QwMagneticField.zmin",po::value<double>()->default_value(-250),
101  "Minimum of z [cm]");
102  options.AddOptions("Magnetic field map")
103  ("QwMagneticField.zmax",po::value<double>()->default_value(+250),
104  "Maximum of z [cm]");
105  options.AddOptions("Magnetic field map")
106  ("QwMagneticField.zstep",po::value<double>()->default_value(2),
107  "Step size of z [cm]");
108  options.AddOptions("Magnetic field map")
109  ("QwMagneticField.rmin",po::value<double>()->default_value(2),
110  "Minimum of r [cm]");
111  options.AddOptions("Magnetic field map")
112  ("QwMagneticField.rmax",po::value<double>()->default_value(260),
113  "Maximum of r [cm]");
114  options.AddOptions("Magnetic field map")
115  ("QwMagneticField.rstep",po::value<double>()->default_value(2),
116  "Step size of r [cm]");
117  options.AddOptions("Magnetic field map")
118  ("QwMagneticField.phimin",po::value<double>()->default_value(0),
119  "Minimum of phi [deg]");
120  options.AddOptions("Magnetic field map")
121  ("QwMagneticField.phimax",po::value<double>()->default_value(360),
122  "Maximum of phi [deg]");
123  options.AddOptions("Magnetic field map")
124  ("QwMagneticField.phistep",po::value<double>()->default_value(1),
125  "Step size of phi [deg]");
126  options.AddOptions("Magnetic field map")
127  ("QwMagneticField.phiwrap",po::value<int>()->default_value(1),
128  "Wrap-around of phi (number of equivalent grid points)");
129 }
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.
Definition: QwOptions.h:164

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

double QwMagneticField::GetActualCurrent ( ) const
inline

Get the actual current.

Definition at line 90 of file QwMagneticField.h.

References fActualCurrent.

Referenced by QwRayTracer::GetMagneticFieldCurrent().

91  { return fActualCurrent; }

+ Here is the caller graph for this function:

void QwMagneticField::GetCartesianFieldValue ( const double  point_xyz[3],
double  field_xyz[3] 
) const
inline

Get the cartesian components of the field value.

Definition at line 124 of file QwMagneticField.h.

References GetFieldValue(), and value_n.

Referenced by GetCartesianFieldValue(), QwRayTracer::IntegrateRK(), and main().

124  {
125  double field[value_n];
126  GetFieldValue(point_xyz, field);
127  if (value_n >= 3) {
128  field_xyz[0] = field[0]; // x
129  field_xyz[1] = field[1]; // y
130  field_xyz[2] = field[2]; // z
131  }
132  };
static const unsigned int value_n
void GetFieldValue(const double point[3], double field[value_n]) const
Get the field value.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void QwMagneticField::GetCartesianFieldValue ( const TVector3 &  point,
TVector3 &  field 
) const
inline

Get the cartesian components of the field value.

Definition at line 154 of file QwMagneticField.h.

References GetCartesianFieldValue().

154  {
155  double point_xyz[3], field_xyz[3];
156  point.GetXYZ(point_xyz);
157  GetCartesianFieldValue(point_xyz, field_xyz);
158  field = TVector3(field_xyz);
159  }
void GetCartesianFieldValue(const double point_xyz[3], double field_xyz[3]) const
Get the cartesian components of the field value.

+ Here is the call graph for this function:

void QwMagneticField::GetCylindricalFieldValue ( const double  point_xyz[3],
double  field_rfz[3] 
) const
inline

Get the cylindrical components of the field value.

Definition at line 134 of file QwMagneticField.h.

References QwLog::endl(), GetFieldValue(), Qw::pi, QwWarning, and value_n.

134  {
135  double field[value_n];
136  GetFieldValue(point_xyz, field);
137  if (value_n == 3) {
138  double r = sqrt(field[0] * field[0] + field[1] * field[1]) ;
139  double phi = atan2(field[1],field[0]);
140  if (phi < 0) phi += 2.0 * Qw::pi;
141  field_rfz[0] = r; // r
142  field_rfz[1] = phi; // phi
143  field_rfz[2] = field[2]; // z
144  } else if (value_n == 5) {
145  field_rfz[0] = field[3]; // r
146  field_rfz[1] = field[4]; // phi
147  field_rfz[2] = field[2]; // z
148  } else {
149  QwWarning << "Number of field components should be 3 or 5." << QwLog::endl;
150  }
151  };
static const double pi
Angles: base unit is radian.
Definition: QwUnits.h:102
static const unsigned int value_n
void GetFieldValue(const double point[3], double field[value_n]) const
Get the field value.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45

+ Here is the call graph for this function:

void QwMagneticField::GetFieldValue ( const double  coord_xyz[3],
double  field[value_n] 
) const
private

Get the field value.

Get a field value

Parameters
coord_xyz[]Cartesian coordinates (x,y,z)
field[]Field components (x,y,z,r,phi) (return)

Definition at line 418 of file QwMagneticField.cc.

References QwLog::endl(), fField, fScaleFactor, QwInterpolator< value_t, value_n >::GetValue(), QwInterpolator< value_t, value_n >::InBounds(), Qw::pi, QwWarning, and value_n.

Referenced by GetCartesianFieldValue(), GetCylindricalFieldValue(), and TestFieldMap().

421 {
422  // Convert from cartesian to cylindrical coordinates
423  double z = coord_xyz[2];
424  double r = sqrt(coord_xyz[0] * coord_xyz[0] + coord_xyz[1] * coord_xyz[1]);
425  double phi = atan2(coord_xyz[1], coord_xyz[0]); if (phi < 0.0) phi += 2.0*Qw::pi;
426 
427  // The ordering is important! It has to agree with how the ordering is
428  // defined on initialization of the field map. Since tracks are in fairly
429  // constant phi planes, it makes sense to keep phi as the most significant
430  // index. The largest changes happen in z, so that should be the least
431  // significant index. This will allow us to use caching more efficiently.
432  double coord_zrf[3] = {z, r, phi};
433 
434  // The magnetic field object was not defined, return zero field and complain
435  if (!this) {
436  QwWarning << "No field map defined: assuming zero field!" << QwLog::endl;
437  for (unsigned int i = 0; i < value_n; i++) field[i] = 0.0;
438  return;
439  }
440 
441  // Retrieve field value
442  bool status = fField->GetValue(coord_zrf,field);
443 
444  // Apply scale factor
445  for (unsigned int i = 0; i < value_n; i++)
446  field[i] *= fScaleFactor;
447 
448  // Warn if the coordinate was inside the field boundaries,
449  // but we still encountered a problem.
450  if (status == false && fField->InBounds(coord_zrf)) {
451  QwWarning << "Could not get field value at (z,r,phi) = " << coord_zrf << QwLog::endl;
452  QwWarning << "Will use field value (x,y,z) = " << field << QwLog::endl;
453  }
454 }
static const double pi
Angles: base unit is radian.
Definition: QwUnits.h:102
static const unsigned int value_n
QwInterpolator< field_t, value_n > * fField
Field map.
bool InBounds(const coord_t *coord) const
Return true if the coordinate is in bounds.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45
value_t GetValue(const coord_t &coord) const
Get the interpolated value at coordinate (zero if out of bounds)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const std::string QwMagneticField::GetFilename ( ) const
inline

Get the filename.

Definition at line 80 of file QwMagneticField.h.

References fFilename.

81  { return fFilename; };
std::string fFilename
File name.
EQwInterpolationMethod QwMagneticField::GetInterpolationMethod ( ) const
inline

Get interpolation method.

Definition at line 192 of file QwMagneticField.h.

References fField, QwInterpolator< value_t, value_n >::GetInterpolationMethod(), and kInterpolationMethodUnknown.

Referenced by main().

192  {
193  if (fField) return fField->GetInterpolationMethod();
194  else return kInterpolationMethodUnknown;
195  }
QwInterpolator< field_t, value_n > * fField
Field map.
EQwInterpolationMethod GetInterpolationMethod() const
Get the interpolation method.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

double QwMagneticField::GetReferenceCurrent ( ) const
inline

Get the reference current.

Definition at line 100 of file QwMagneticField.h.

References fReferenceCurrent.

101  { return fReferenceCurrent; }
double fReferenceCurrent
Field scale factor.
double QwMagneticField::GetRotation ( ) const
inline

Get the field rotation around z (with QwUnits)

Definition at line 113 of file QwMagneticField.h.

References fRotationRad, and Qw::rad.

114  { return fRotationRad * Qw::rad; };
static const double rad
Definition: QwUnits.h:105
double QwMagneticField::GetTranslation ( ) const
inline

Get the field translation along z.

Definition at line 120 of file QwMagneticField.h.

References fTranslation.

121  { return fTranslation; };
void QwMagneticField::LoadBeamProperty ( const TString &  map)

Load beam property.

Definition at line 457 of file QwMagneticField.cc.

References SetActualCurrent(), and QwParameterFile::TrimComment().

Referenced by ProcessOptions().

457  {
458  QwParameterFile mapstr(map.Data());
459  while (mapstr.ReadNextLine()) {
460  mapstr.TrimComment(); // Remove everything after a comment character.
461  mapstr.TrimWhitespace(); // Get rid of leading and trailing spaces.
462  if (mapstr.LineIsEmpty())
463  continue;
464 
465  string varname, varvalue;
466  if (mapstr.HasVariablePair("=", varname, varvalue)) {
467  if (varname == "QTOR") {
468  SetActualCurrent(atof(varvalue.c_str()));
469  }
470  }
471  }
472 }
void TrimComment(const char commentchar)
void SetActualCurrent(const double current)
Set the actual current.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void QwMagneticField::ProcessOptions ( QwOptions options)

Process command line and config file options.

Process the options for this subsystem

Parameters
optionsOptions object

Definition at line 135 of file QwMagneticField.cc.

References Qw::cm, Qw::deg, fMax, fMin, fStep, fWrap, QwOptions::GetValue(), LoadBeamProperty(), SetActualCurrent(), SetFilename(), SetReferenceCurrent(), SetRotation(), and SetTranslation().

Referenced by QwMagneticField().

136 {
137  // Field currents
138  SetActualCurrent(options.GetValue<double>("QwMagneticField.current"));
139  SetReferenceCurrent(options.GetValue<double>("QwMagneticField.reference"));
140  // Override if necessary
141  LoadBeamProperty("beam_property.map");
142 
143  // Translation and rotation
144  double trans = Qw::cm * options.GetValue<double>("QwMagneticField.trans");
145  double rot = Qw::deg * options.GetValue<double>("QwMagneticField.rot");
146  SetTranslation(trans);
147  SetRotation(rot);
148 
149  // Grid options
150  double zmin = Qw::cm * options.GetValue<double>("QwMagneticField.zmin");
151  double zmax = Qw::cm * options.GetValue<double>("QwMagneticField.zmax");
152  double zstep = Qw::cm * options.GetValue<double>("QwMagneticField.zstep");
153  double rmin = Qw::cm * options.GetValue<double>("QwMagneticField.rmin");
154  double rmax = Qw::cm * options.GetValue<double>("QwMagneticField.rmax");
155  double rstep = Qw::cm * options.GetValue<double>("QwMagneticField.rstep");
156  double phimin = Qw::deg * options.GetValue<double>("QwMagneticField.phimin");
157  double phimax = Qw::deg * options.GetValue<double>("QwMagneticField.phimax");
158  double phistep = Qw::deg * options.GetValue<double>("QwMagneticField.phistep");
159  int phiwrap = options.GetValue<int>("QwMagneticField.phiwrap");
160 
161  // The order is z, r, phi (no wrapping in r or z)
162  fMin.push_back(zmin); fMax.push_back(zmax); fStep.push_back(zstep); fWrap.push_back(0);
163  fMin.push_back(rmin); fMax.push_back(rmax); fStep.push_back(rstep); fWrap.push_back(0);
164  fMin.push_back(phimin); fMax.push_back(phimax); fStep.push_back(phistep); fWrap.push_back(phiwrap);
165 
166  // Determine magnetic field file from environment variables
167  std::string fieldmap =
168  options.GetValue<std::string>("QwMagneticField.mapfile");
169  SetFilename(fieldmap);
170 }
void SetFilename(const std::string &filename)
Set the filename.
static const double deg
Definition: QwUnits.h:106
std::vector< double > fStep
void SetActualCurrent(const double current)
Set the actual current.
T GetValue(const std::string &key)
Get a templated value.
Definition: QwOptions.h:240
std::vector< double > fMin
Field map grid min, max, step, wrap.
void SetReferenceCurrent(const double current)
Set the reference current.
std::vector< size_t > fWrap
std::vector< double > fMax
void LoadBeamProperty(const TString &map)
Load beam property.
void SetTranslation(const double translation)
Set the field translation along z.
void SetRotation(const double rotation)
Set the field rotation around z (with QwUnits)
static const double cm
Length units: base unit is mm.
Definition: QwUnits.h:61

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool QwMagneticField::ReadFieldMap ( )

Read a field map.

Read the magnetic field map

Returns
True if read successfully

Definition at line 176 of file QwMagneticField.cc.

References QwLog::endl(), fField, fFilename, fMax, fMin, fStep, fWrap, getenv_safe_string(), QwError, QwWarning, QwInterpolator< value_t, value_n >::ReadBinaryFile(), ReadFieldMapFile(), ReadFieldMapZip(), and QwInterpolator< value_t, value_n >::SetWrapCoordinate().

Referenced by main(), and QwMagneticField().

177 {
178  // Delete existing magnetic field
179  if (fField) delete fField;
180 
181  // Create new magnetic field
184 
185  // Add path to filename
186  std::string filename = getenv_safe_string("QW_FIELDMAP") + "/" + fFilename;
187 
188  // Depending on form of filename, read zipped/regular/binary field map
189  bool status = false;
190  if (filename.find(".dat") != std::string::npos) {
191  status = ReadFieldMapFile(filename);
192  }
193  if (filename.find(".dat.gz") != std::string::npos) {
194  status = ReadFieldMapZip(filename);
195  }
196  if (filename.find(".bin") != std::string::npos) {
197  status = fField->ReadBinaryFile(filename);
198  // Try the regular map as a fallback option
199  if (status == false) {
200  filename.replace(filename.find("bin"),3,"dat");
201  status = ReadFieldMapFile(filename);
202  }
203  }
204 
205  // Check whether we succeeded
206  if (status == false) {
207  QwError << "Could not load magnetic field map!" << QwLog::endl;
208  QwWarning << "Filename: " << filename << QwLog::endl;
209  }
210 
211  return status;
212 }
std::string fFilename
File name.
std::vector< double > fStep
QwInterpolator< field_t, value_n > * fField
Field map.
void SetWrapCoordinate(const unsigned int dim, const size_t wrap=1)
Set wrapping coordinate.
bool ReadBinaryFile(const std::string &filename)
Read the grid values from binary file.
std::vector< double > fMin
Field map grid min, max, step, wrap.
bool ReadFieldMapZip(const std::string &filename)
Read a field map input gzip file.
std::vector< size_t > fWrap
std::vector< double > fMax
bool ReadFieldMapFile(const std::string &filename)
Read a field map input file.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
const std::string getenv_safe_string(const char *name)
Definition: QwOptions.h:37
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool QwMagneticField::ReadFieldMapFile ( const std::string &  filename)

Read a field map input file.

Read the magnetic field from an ANSYS map file in text format

Parameters
filenameANSYS map file name
Returns
True if read successfully

Definition at line 276 of file QwMagneticField.cc.

References QwLog::endl(), Qw::in, QwError, and ReadFieldMapStream().

Referenced by ReadFieldMap().

277 {
278  // Open the field map file
279  std::ifstream input;
280  input.open(filename.c_str(), std::ios_base::in);
281  // Check for success
282  if (!input.good()) {
283  QwError << "Could not open field map file!" << QwLog::endl;
284  QwError << "File name: " << filename << QwLog::endl;
285  return false;
286  }
287 
288  // Read the input field map stream
289  return ReadFieldMapStream(input);
290 }
static const double in
Definition: QwUnits.h:66
bool ReadFieldMapStream(std::istream &input)
Read the field map input stream.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool QwMagneticField::ReadFieldMapStream ( std::istream &  input)

Read the field map input stream.

Read the magnetic field from an ANSYS map text stream

Parameters
inputInput stream
Returns
True if read successfully

Definition at line 318 of file QwMagneticField.cc.

References Qw::cm, Qw::deg, QwLog::endl(), fField, QwLog::flush(), fRotation, fRotationCos, fRotationSin, fTranslation, QwInterpolator< value_t, value_n >::GetCurrentEntries(), QwInterpolator< value_t, value_n >::GetMaximumEntries(), Qw::kG, Qw::pi, QwInterpolator< value_t, value_n >::PrintCoverage(), QwError, QwMessage, QwWarning, QwInterpolator< value_t, value_n >::Set(), and value_n.

Referenced by ReadFieldMapFile(), and ReadFieldMapZip().

319 {
320  // Check whether field map exists
321  if (fField == 0) {
322  QwWarning << "Trying to read field map without object to put values in."
323  << QwLog::endl;
324  return false;
325  }
326 
327  // Declare variables
328  double r, z, phi;
329  field_t bx, by, bz, bx_new, by_new;
330 
331  // Check for stream
332  if (!input.good()) {
333  QwError << "Error: Could not open field map stream!" << QwLog::endl;
334  return false;
335  }
336 
337  QwMessage << "Reading magnetic field map ";
338 
339  // Loop over stream until end-of-file
340  // Note: input.good() only says whether next operation *might* succeed
341  while (! input.fail()) {
342 
343  // Progress bar
344  if (fField->GetCurrentEntries() % (fField->GetMaximumEntries() / 10) == 0) {
345  int pct = fField->GetCurrentEntries() / (fField->GetMaximumEntries() / 100);
346  QwMessage << pct << "%" << QwLog::flush;
347  }
348  if (fField->GetCurrentEntries() % (fField->GetMaximumEntries() / 10) != 0
349  && fField->GetCurrentEntries() % (fField->GetMaximumEntries() / 40) == 0) {
350  QwMessage << "." << QwLog::flush;
351  }
352 
353  // Read a line with three position coordinates and three field components
354  input >> r >> z >> phi >> bx >> by >> bz;
355  if (! input.good()) continue;
356 
357  // Fix the units
358  r *= Qw::cm; z *= Qw::cm; phi *= Qw::deg;
359  bx *= Qw::kG; by *= Qw::kG; bz *= Qw::kG;
360 
361  // Correct for translation along z
362  z -= fTranslation;
363 
364  // Correct for rotation around z
365  phi -= fRotation;
366  if (phi < 0.0*Qw::pi) phi += 2.0*Qw::pi;
367  if (phi > 2.0*Qw::pi) phi -= 2.0*Qw::pi;
368  bx_new = bx * fRotationCos + by * fRotationSin;
369  by_new = -bx * fRotationSin + by * fRotationCos;
370  bx = bx_new; by = by_new;
371 
372  // Construct the coordinate
373  double coord[3] = {z, r, phi};
374 
375  // Construct the field vector
376  field_t field[value_n];
377  field[0] = bx;
378  field[1] = by;
379  field[2] = bz;
380 
381  if (value_n == 5) {
382  // Calculate the radial and azimuthal field components
383  double br = bx * cos(phi) + by * sin(phi);
384  double bphi = -bx * sin(phi) + by * cos(phi);
385 
386  // Construct the field vector
387  field[3] = br;
388  field[4] = bphi;
389  }
390 
391  bool status = fField->Set(coord, field);
392  if (! status) {
393  QwError << "Problem assigning field to coordinate!" << QwLog::endl;
394  QwError << coord[0] << "," << coord[1] << "," << coord[2] << QwLog::endl;
395  }
396  }
398 
399  if (abs(fField->GetCurrentEntries() / fField->GetMaximumEntries() - 1) > 0.00001) {
400  QwWarning << "Expected " << fField->GetMaximumEntries() << " entries, "
401  << "but only read " << fField->GetCurrentEntries() << "." << QwLog::endl;
402  QwMessage << "Coverage of the z bins:" << QwLog::endl;
403  fField->PrintCoverage(0);
404  QwMessage << "Coverage of the r bins:" << QwLog::endl;
405  fField->PrintCoverage(1);
406  QwMessage << "Coverage of the phi bins:" << QwLog::endl;
407  fField->PrintCoverage(2);
408  }
409 
410  return true;
411 }
static const double pi
Angles: base unit is radian.
Definition: QwUnits.h:102
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
void PrintCoverage(const unsigned int dim)
Print coverage map for all bins in one dimension.
unsigned int GetCurrentEntries() const
Get the current number of entries.
static const double deg
Definition: QwUnits.h:106
double fRotation
Field rotation and translation with respect to the z axis.
static const unsigned int value_n
QwInterpolator< field_t, value_n > * fField
Field map.
static const double kG
Definition: QwUnits.h:113
bool Set(const coord_t &coord, const value_t &value)
Set a single value at a coordinate (false if not possible)
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45
unsigned int GetMaximumEntries() const
Get the maximum number of entries.
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40
static std::ostream & flush(std::ostream &)
Flush the streams.
Definition: QwLog.cc:319
static const double cm
Length units: base unit is mm.
Definition: QwUnits.h:61

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool QwMagneticField::ReadFieldMapZip ( const std::string &  filename)

Read a field map input gzip file.

Read the magnetic field from an ANSYS map file in gzipped text format

Parameters
filenameANSYS map file name
Returns
True if read successfully

Definition at line 297 of file QwMagneticField.cc.

References QwLog::endl(), QwWarning, and ReadFieldMapStream().

Referenced by ReadFieldMap().

298 {
299 #ifdef __USE_BOOST_IOSTREAMS
300  // Create a gzip filter for the field map file
301  boost::iostreams::filtering_istream input;
302  input.push(boost::iostreams::gzip_decompressor());
303  input.push(boost::iostreams::file_source(filename));
304 
305  // Read the input field map stream
306  return ReadFieldMapStream(input);
307 #else
308  QwWarning << "Compressed input files not supported!" << QwLog::endl;
309  return false;
310 #endif
311 }
bool ReadFieldMapStream(std::istream &input)
Read the field map input stream.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void QwMagneticField::SetActualCurrent ( const double  current)
inline

Set the actual current.

Definition at line 84 of file QwMagneticField.h.

References fActualCurrent, fReferenceCurrent, and fScaleFactor.

Referenced by LoadBeamProperty(), ProcessOptions(), QwMagneticField(), and QwRayTracer::SetMagneticFieldCurrent().

84  {
85  fActualCurrent = current;
86  if (fReferenceCurrent > 0.0)
88  }
double fReferenceCurrent
Field scale factor.

+ Here is the caller graph for this function:

void QwMagneticField::SetFilename ( const std::string &  filename)
inline

Set the filename.

Definition at line 77 of file QwMagneticField.h.

References fFilename.

Referenced by main(), and ProcessOptions().

78  { fFilename = filename; };
std::string fFilename
File name.

+ Here is the caller graph for this function:

void QwMagneticField::SetInterpolationMethod ( const EQwInterpolationMethod  method)
inline

Set interpolation method.

Definition at line 188 of file QwMagneticField.h.

References fField, and QwInterpolator< value_t, value_n >::SetInterpolationMethod().

Referenced by main().

188  {
189  if (fField) fField->SetInterpolationMethod(method);
190  }
QwInterpolator< field_t, value_n > * fField
Field map.
void SetInterpolationMethod(const EQwInterpolationMethod method)
Set the interpolation method.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void QwMagneticField::SetReferenceCurrent ( const double  current)
inline

Set the reference current.

Definition at line 94 of file QwMagneticField.h.

References fActualCurrent, fReferenceCurrent, and fScaleFactor.

Referenced by ProcessOptions(), and QwMagneticField().

94  {
95  fReferenceCurrent = current;
96  if (fReferenceCurrent > 0.0)
98  }
double fReferenceCurrent
Field scale factor.

+ Here is the caller graph for this function:

void QwMagneticField::SetRotation ( const double  rotation)
inline

Set the field rotation around z (with QwUnits)

Definition at line 104 of file QwMagneticField.h.

References Qw::deg, fRotation, fRotationCos, fRotationDeg, fRotationRad, fRotationSin, and Qw::rad.

Referenced by ProcessOptions(), and QwMagneticField().

104  {
105  fRotation = rotation;
106  fRotationCos = cos(rotation);
107  fRotationSin = sin(rotation);
108  // Unit conversions
109  fRotationDeg = rotation / Qw::deg;
110  fRotationRad = rotation / Qw::rad;
111  };
static const double deg
Definition: QwUnits.h:106
double fRotation
Field rotation and translation with respect to the z axis.
static const double rad
Definition: QwUnits.h:105

+ Here is the caller graph for this function:

void QwMagneticField::SetTranslation ( const double  translation)
inline

Set the field translation along z.

Definition at line 117 of file QwMagneticField.h.

References fTranslation.

Referenced by ProcessOptions(), and QwMagneticField().

118  { fTranslation = translation; };

+ Here is the caller graph for this function:

bool QwMagneticField::TestFieldMap ( )

Test the field map.

Test the field map value at a specific point to make sure nothing went wrong

Returns
True if read successfully

Definition at line 218 of file QwMagneticField.cc.

References Qw::cm, QwLog::endl(), GetFieldValue(), Qw::kG, QwError, QwMessage, and QwWarning.

Referenced by QwRayTracer::LoadMagneticFieldMap().

219 {
220  bool status = true;
221 
222  // Test field value at exact grid point
223  // (r = 100*cm, z = 100*cm, phi = 22.5*degree)
224  double point[3] = {100.0 * Qw::cm, 0.0 * Qw::cm, 100.0 * Qw::cm};
225  double exact[3] = {-0.0499845 * Qw::kG, 3.28516 * Qw::kG, -0.0112704 * Qw::kG};
226 
227  // Calculate field value
228  QwMessage << "Calculating test field value at cartesian position "
229  << "(" << point[0]/Qw::cm << "," << point[1]/Qw::cm << "," << point[2]/Qw::cm << ") cm "
230  << QwLog::endl;
231  double value[3] = {0.0, 0.0, 0.0};
232  GetFieldValue(point,value);
233 
234  // Calculate difference
235  double diff[3] = {0.0, 0.0, 0.0};
236  double norm = 0.0;
237  for (size_t i = 0; i < 3; i++) {
238  diff[i] = value[i] - exact[i];
239  norm += diff[i] * diff[i];
240  }
241  norm = sqrt(norm);
242 
243  // Output
244  QwMessage << " Value = "
245  << "(" << value[0]/Qw::kG << ", " << value[1]/Qw::kG << ", " << value[2]/Qw::kG << ") kG."
246  << QwLog::endl;
247  QwMessage << " Exact = "
248  << "(" << exact[0]/Qw::kG << ", " << exact[1]/Qw::kG << ", " << exact[2]/Qw::kG << ") kG."
249  << QwLog::endl;
250  QwMessage << " Diff = "
251  << "(" << diff[0]/Qw::kG << ", " << diff[1]/Qw::kG << ", " << diff[2]/Qw::kG << ") kG."
252  << QwLog::endl;
253 
254  // Test difference (0.1 kG is of the order of 2%)
255  if (norm > 0.1 * Qw::kG) {
256  QwWarning << "Magnetic field is different from expected value by " << norm/Qw::kG << " kG."
257  << QwLog::endl;
258  status = false;
259  }
260 
261  // Check validity
262  if (status == false) {
263  QwError << "Fieldmap did not satisfy consistency checks!" << QwLog::endl;
264  }
265 
266  // Nothing is tested, just return true
267  return status;
268 }
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
static const double kG
Definition: QwUnits.h:113
void GetFieldValue(const double point[3], double field[value_n]) const
Get the field value.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40
static const double cm
Length units: base unit is mm.
Definition: QwUnits.h:61

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool QwMagneticField::WriteBinaryFile ( const std::string &  fieldmap) const
inline

Write a binary field map.

Definition at line 176 of file QwMagneticField.h.

References fField, getenv_safe_string(), and QwInterpolator< value_t, value_n >::WriteBinaryFile().

Referenced by main().

176  {
177  std::string filename = getenv_safe_string("QW_FIELDMAP") + "/" + fieldmap;
178  if (fField) return fField->WriteBinaryFile(filename);
179  else return false;
180  }
QwInterpolator< field_t, value_n > * fField
Field map.
bool WriteBinaryFile(const std::string &filename) const
Write the grid values to binary file.
const std::string getenv_safe_string(const char *name)
Definition: QwOptions.h:37

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool QwMagneticField::WriteTextFile ( const std::string &  fieldmap) const
inline

Write a text field map.

Definition at line 182 of file QwMagneticField.h.

References fField, getenv_safe_string(), and QwInterpolator< value_t, value_n >::WriteTextFile().

182  {
183  std::string filename = getenv_safe_string("QW_FIELDMAP") + "/" + fieldmap;
184  if (fField) return fField->WriteTextFile(filename);
185  else return false;
186  }
QwInterpolator< field_t, value_n > * fField
Field map.
const std::string getenv_safe_string(const char *name)
Definition: QwOptions.h:37
bool WriteTextFile(const std::string &filename) const
Write the grid to text file.

+ Here is the call graph for this function:

Field Documentation

double QwMagneticField::fActualCurrent
private

Definition at line 212 of file QwMagneticField.h.

Referenced by GetActualCurrent(), SetActualCurrent(), and SetReferenceCurrent().

std::string QwMagneticField::fFilename
private

File name.

Definition at line 201 of file QwMagneticField.h.

Referenced by GetFilename(), ReadFieldMap(), and SetFilename().

std::vector<double> QwMagneticField::fMax
private

Definition at line 207 of file QwMagneticField.h.

Referenced by ProcessOptions(), and ReadFieldMap().

std::vector<double> QwMagneticField::fMin
private

Field map grid min, max, step, wrap.

Definition at line 207 of file QwMagneticField.h.

Referenced by ProcessOptions(), and ReadFieldMap().

double QwMagneticField::fReferenceCurrent
private

Field scale factor.

Definition at line 211 of file QwMagneticField.h.

Referenced by GetReferenceCurrent(), SetActualCurrent(), and SetReferenceCurrent().

double QwMagneticField::fRotation
private

Field rotation and translation with respect to the z axis.

Definition at line 225 of file QwMagneticField.h.

Referenced by ReadFieldMapStream(), and SetRotation().

double QwMagneticField::fRotationCos
private

Definition at line 225 of file QwMagneticField.h.

Referenced by ReadFieldMapStream(), and SetRotation().

double QwMagneticField::fRotationDeg
private

Definition at line 225 of file QwMagneticField.h.

Referenced by SetRotation().

double QwMagneticField::fRotationRad
private

Definition at line 225 of file QwMagneticField.h.

Referenced by GetRotation(), and SetRotation().

double QwMagneticField::fRotationSin
private

Definition at line 225 of file QwMagneticField.h.

Referenced by ReadFieldMapStream(), and SetRotation().

double QwMagneticField::fScaleFactor
private

Definition at line 213 of file QwMagneticField.h.

Referenced by GetFieldValue(), SetActualCurrent(), and SetReferenceCurrent().

std::vector<double> QwMagneticField::fStep
private

Definition at line 207 of file QwMagneticField.h.

Referenced by ProcessOptions(), and ReadFieldMap().

double QwMagneticField::fTranslation
private

Definition at line 226 of file QwMagneticField.h.

Referenced by GetTranslation(), ReadFieldMapStream(), and SetTranslation().

std::vector<size_t> QwMagneticField::fWrap
private

Definition at line 208 of file QwMagneticField.h.

Referenced by ProcessOptions(), and ReadFieldMap().

const unsigned int QwMagneticField::value_n = 3
staticprivate

The documentation for this class was generated from the following files: