11 #ifdef __USE_BOOST_IOSTREAMS
15 #include <boost/iostreams/filtering_stream.hpp>
16 #include <boost/iostreams/filtering_streambuf.hpp>
17 #include <boost/iostreams/copy.hpp>
18 #include <boost/iostreams/filter/gzip.hpp>
19 #include <boost/iostreams/device/file.hpp>
36 inline std::ostream&
operator<< (std::ostream& stream,
const double v[3])
38 return stream <<
"(" << v[0] <<
"," << v[1] <<
"," << v[2] <<
")";
83 (
"QwMagneticField.mapfile",po::value<std::string>()->default_value(
"peiqing_2011.dat"),
87 (
"QwMagneticField.current",po::value<double>()->default_value(0.0),
88 "Actual current of run to analyze");
90 (
"QwMagneticField.reference",po::value<double>()->default_value(8960.0),
91 "Reference current of field map");
94 (
"QwMagneticField.trans",po::value<double>()->default_value(0),
97 (
"QwMagneticField.rot",po::value<double>()->default_value(0),
100 (
"QwMagneticField.zmin",po::value<double>()->default_value(-250),
101 "Minimum of z [cm]");
103 (
"QwMagneticField.zmax",po::value<double>()->default_value(+250),
104 "Maximum of z [cm]");
106 (
"QwMagneticField.zstep",po::value<double>()->default_value(2),
107 "Step size of z [cm]");
109 (
"QwMagneticField.rmin",po::value<double>()->default_value(2),
110 "Minimum of r [cm]");
112 (
"QwMagneticField.rmax",po::value<double>()->default_value(260),
113 "Maximum of r [cm]");
115 (
"QwMagneticField.rstep",po::value<double>()->default_value(2),
116 "Step size of r [cm]");
118 (
"QwMagneticField.phimin",po::value<double>()->default_value(0),
119 "Minimum of phi [deg]");
121 (
"QwMagneticField.phimax",po::value<double>()->default_value(360),
122 "Maximum of phi [deg]");
124 (
"QwMagneticField.phistep",po::value<double>()->default_value(1),
125 "Step size of phi [deg]");
127 (
"QwMagneticField.phiwrap",po::value<int>()->default_value(1),
128 "Wrap-around of phi (number of equivalent grid points)");
144 double trans =
Qw::cm * options.
GetValue<
double>(
"QwMagneticField.trans");
145 double rot =
Qw::deg * options.
GetValue<
double>(
"QwMagneticField.rot");
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");
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);
167 std::string fieldmap =
168 options.
GetValue<std::string>(
"QwMagneticField.mapfile");
190 if (filename.find(
".dat") != std::string::npos) {
193 if (filename.find(
".dat.gz") != std::string::npos) {
196 if (filename.find(
".bin") != std::string::npos) {
199 if (status ==
false) {
200 filename.replace(filename.find(
"bin"),3,
"dat");
206 if (status ==
false) {
228 QwMessage <<
"Calculating test field value at cartesian position "
229 <<
"(" << point[0]/
Qw::cm <<
"," << point[1]/
Qw::cm <<
"," << point[2]/
Qw::cm <<
") cm "
231 double value[3] = {0.0, 0.0, 0.0};
235 double diff[3] = {0.0, 0.0, 0.0};
237 for (
size_t i = 0; i < 3; i++) {
238 diff[i] = value[i] - exact[i];
239 norm += diff[i] * diff[i];
245 <<
"(" << value[0]/
Qw::kG <<
", " << value[1]/
Qw::kG <<
", " << value[2]/
Qw::kG <<
") kG."
248 <<
"(" << exact[0]/
Qw::kG <<
", " << exact[1]/
Qw::kG <<
", " << exact[2]/
Qw::kG <<
") kG."
251 <<
"(" << diff[0]/
Qw::kG <<
", " << diff[1]/
Qw::kG <<
", " << diff[2]/
Qw::kG <<
") kG."
255 if (norm > 0.1 *
Qw::kG) {
256 QwWarning <<
"Magnetic field is different from expected value by " << norm/
Qw::kG <<
" kG."
262 if (status ==
false) {
299 #ifdef __USE_BOOST_IOSTREAMS
301 boost::iostreams::filtering_istream input;
302 input.push(boost::iostreams::gzip_decompressor());
303 input.push(boost::iostreams::file_source(filename));
322 QwWarning <<
"Trying to read field map without object to put values in."
329 field_t bx, by, bz, bx_new, by_new;
337 QwMessage <<
"Reading magnetic field map ";
341 while (! input.fail()) {
354 input >> r >> z >> phi >> bx >> by >> bz;
355 if (! input.good())
continue;
370 bx = bx_new; by = by_new;
373 double coord[3] = {z, r, phi};
383 double br = bx * cos(phi) + by * sin(phi);
384 double bphi = -bx * sin(phi) + by * cos(phi);
419 const double coord_xyz[3],
420 double field[value_n])
const
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;
432 double coord_zrf[3] = {z, r, phi};
437 for (
unsigned int i = 0; i <
value_n; i++) field[i] = 0.0;
445 for (
unsigned int i = 0; i <
value_n; i++)
459 while (mapstr.ReadNextLine()) {
461 mapstr.TrimWhitespace();
462 if (mapstr.LineIsEmpty())
465 string varname, varvalue;
466 if (mapstr.HasVariablePair(
"=", varname, varvalue)) {
467 if (varname ==
"QTOR") {
static const double pi
Angles: base unit is radian.
#define QwMessage
Predefined log drain for regular messages.
std::string fFilename
File name.
std::ostream & operator<<(std::ostream &out, const QwColor &color)
Output stream operator which uses the enum-to-escape-code mapping.
void PrintCoverage(const unsigned int dim)
Print coverage map for all bins in one dimension.
void SetFilename(const std::string &filename)
Set the filename.
unsigned int GetCurrentEntries() const
Get the current number of entries.
QwMagneticField(QwOptions &options, const bool suppress_read_field_map=false)
Default constructor.
void TrimComment(const char commentchar)
std::vector< double > fStep
double fRotation
Field rotation and translation with respect to the z axis.
static const unsigned int value_n
bool ReadFieldMapStream(std::istream &input)
Read the field map input stream.
void SetActualCurrent(const double current)
Set the actual current.
void ProcessOptions(QwOptions &options)
Process command line and config file options.
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.
QwInterpolator< field_t, value_n > * fField
Field map.
bool Set(const coord_t &coord, const value_t &value)
Set a single value at a coordinate (false if not possible)
T GetValue(const std::string &key)
Get a templated value.
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.
A logfile class, based on an identical class in the Hermes analyzer.
std::vector< double > fMin
Field map grid min, max, step, wrap.
void SetReferenceCurrent(const double current)
Set the reference current.
bool ReadFieldMapZip(const std::string &filename)
Read a field map input gzip file.
std::vector< size_t > fWrap
std::vector< double > fMax
void LoadBeamProperty(const TString &map)
Load beam property.
bool ReadFieldMapFile(const std::string &filename)
Read a field map input file.
void GetFieldValue(const double point[3], double field[value_n]) const
Get the field value.
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.
const std::string getenv_safe_string(const char *name)
static void DefineOptions(QwOptions &options)
Define command line and config file options.
void SetTranslation(const double translation)
Set the field translation along z.
#define QwWarning
Predefined log drain for warnings.
unsigned int GetMaximumEntries() const
Get the maximum number of entries.
void SetRotation(const double rotation)
Set the field rotation around z (with QwUnits)
bool TestFieldMap()
Test the field map.
virtual ~QwMagneticField()
Virtual destructor.
#define QwError
Predefined log drain for errors.
value_t GetValue(const coord_t &coord) const
Get the interpolated value at coordinate (zero if out of bounds)
static std::ostream & flush(std::ostream &)
Flush the streams.
static const double cm
Length units: base unit is mm.
bool ReadFieldMap()
Read a field map.