3#include "Utility/PAssert.h"
38#include <boost/filesystem.hpp>
45namespace fs = boost::filesystem;
47#define REGISTER_PARSE_TYPE(X) \
49 struct Fieldmap::TypeParseTraits<X> { \
50 static const char* name; \
52 const char* Fieldmap::TypeParseTraits<X>::name = #X
55 std::map<std::string, FieldmapDescription>::iterator position =
58 (*position).second.RefCounter++;
59 return (*position).second.Map;
62 std::pair<std::map<std::string, FieldmapDescription>::iterator,
bool> position;
73 return (*position.first).second.Map;
86 return (*position.first).second.Map;
99 return (*position.first).second.Map;
113 return (*position.first).second.Map;
126 return (*position.first).second.Map;
140 return (*position.first).second.Map;
146 return (*position.first).second.Map;
152 return (*position.first).second.Map;
158 return (*position.first).second.Map;
165 return (*position.first).second.Map;
172 return (*position.first).second.Map;
178 return (*position.first).second.Map;
186 return (*position.first).second.Map;
193 return (*position.first).second.Map;
201 return (*position.first).second.Map;
213 return (*position.first).second.Map;
218 "Fieldmap::getFieldmap()",
219 "Couldn't determine type of fieldmap in file \"" + Filename +
"\"");
225 std::vector<std::string> name_list;
226 for (std::map<std::string, FieldmapDescription>::const_iterator it =
FieldmapDictionary.begin();
228 name_list.push_back((*it).first);
240 delete it->second.Map;
241 it->second.Map =
nullptr;
247 char magicnumber[5] =
" ";
252 if (Filename ==
"1DPROFILE1-DEFAULT")
255 if (Filename.empty())
258 if (!fs::exists(Filename))
260 "Fieldmap::readHeader()",
"File '" + Filename +
"' doesn't exist");
262 std::ifstream File(Filename.c_str());
264 std::cerr <<
"could not open file " << Filename << std::endl;
269 std::istringstream interpreter(buffer, std::istringstream::in);
271 interpreter.read(magicnumber, 4);
273 if (std::strcmp(magicnumber,
"3DDy") == 0)
276 if (std::strcmp(magicnumber,
"3DMa") == 0) {
277 char tmpString[21] =
" ";
278 interpreter.read(tmpString, 20);
280 if (std::strcmp(tmpString,
"gnetoStatic_Extended") == 0)
286 if (std::strcmp(magicnumber,
"3DEl") == 0)
289 if (std::strcmp(magicnumber,
"2DDy") == 0) {
295 if (std::strcmp(magicnumber,
"2DMa") == 0) {
301 if (std::strcmp(magicnumber,
"2DEl") == 0) {
307 if (std::strcmp(magicnumber,
"1DDy") == 0)
310 if (std::strcmp(magicnumber,
"1DMa") == 0)
313 if (std::strcmp(magicnumber,
"1DPr") == 0) {
322 if (std::strcmp(magicnumber,
"1DEl") == 0)
325 if (std::strcmp(magicnumber,
"\211HDF") == 0) {
332 h5_size_t len_name =
sizeof(name);
333 h5_prop_t props = H5CreateFileProp();
334 MPI_Comm comm = ippl::Comm->getCommunicator();
335 h5err = H5SetPropFileMPIOCollective(props, &comm);
336 PAssert(h5err != H5_ERR);
337 h5_file_t file = H5OpenFile(Filename.c_str(), H5_O_RDONLY, props);
338 PAssert(file != (h5_file_t)H5_ERR);
341 h5err = H5SetStep(file, 0);
342 PAssert(h5err != H5_ERR);
344 h5_int64_t num_fields = H5BlockGetNumFields(file);
345 PAssert(num_fields != H5_ERR);
348 for (h5_ssize_t i = 0; i < num_fields; ++i) {
349 h5err = H5BlockGetFieldInfo(
350 file, (h5_size_t)i, name, len_name,
nullptr,
nullptr,
nullptr,
nullptr);
351 PAssert(h5err != H5_ERR);
353 if (std::strcmp(name,
"Bfield") == 0) {
356 }
else if (std::strcmp(name,
"Hfield") == 0) {
361 h5err = H5CloseFile(file);
362 PAssert(h5err != H5_ERR);
367 if (std::strcmp(magicnumber,
"Astr") == 0) {
368 char tmpString[3] =
" ";
369 interpreter.read(tmpString, 2);
370 if (std::strcmp(tmpString,
"aE") == 0) {
373 if (std::strcmp(tmpString,
"aM") == 0) {
376 if (std::strcmp(tmpString,
"aD") == 0) {
385 std::map<std::string, FieldmapDescription>::iterator position =
388 if (!(*position).second.read) {
389 (*position).second.Map->readMap();
390 (*position).second.read =
true;
395 std::map<std::string, FieldmapDescription>::iterator position =
401 if ((*position).second.RefCounter > 0) {
402 (*position).second.RefCounter--;
405 if ((*position).second.RefCounter == 0) {
406 delete (*position).second.Map;
407 (*position).second.Map =
nullptr;
414 unsigned int accuracy, std::pair<double, double> fieldDimensions,
double deltaZ,
415 const std::vector<double>& fourierCoefficients, gsl_spline* splineCoefficients,
416 gsl_interp_accel* splineAccelerator) {
417 double length = fieldDimensions.second - fieldDimensions.first;
418 unsigned int sizeSampling = std::round(length / deltaZ);
419 std::vector<double> zSampling(sizeSampling);
420 zSampling[0] = fieldDimensions.first;
421 for (
unsigned int i = 1; i < sizeSampling; ++i) {
422 zSampling[i] = zSampling[i - 1] + deltaZ;
425 accuracy, length, zSampling, fourierCoefficients, splineCoefficients, splineAccelerator);
429 unsigned int accuracy,
double length,
const std::vector<double>& zSampling,
430 const std::vector<double>& fourierCoefficients, gsl_spline* splineCoefficients,
431 gsl_interp_accel* splineAccelerator) {
433 double maxDiff = 0.0;
435 double ezSquare = 0.0;
436 size_t lastDot =
Filename_m.find_last_of(
".");
437 size_t lastSlash =
Filename_m.find_last_of(
"/");
438 lastSlash = (lastSlash == std::string::npos) ? 0 : lastSlash + 1;
442 if (ippl::Comm->rank() == 0 && !opal->isOptimizerRun()) {
444 {opal->getAuxiliaryOutputDirectory(),
445 Filename_m.substr(lastSlash, lastDot) +
".check"});
447 out <<
"# z original reproduced\n";
449 auto it = zSampling.begin();
450 auto end = zSampling.end();
451 for (; it !=
end; ++it) {
453 double onAxisFieldCheck = fourierCoefficients[0];
455 for (
unsigned int l = 1; l < accuracy; ++l, n += 2) {
456 double coskzl = std::cos(kz * l);
457 double sinkzl = std::sin(kz * l);
460 (fourierCoefficients[n] * coskzl - fourierCoefficients[n + 1] * sinkzl);
462 double ez = gsl_spline_eval(splineCoefficients, *it, splineAccelerator);
463 double difference = std::abs(ez - onAxisFieldCheck);
464 maxDiff = difference > maxDiff ? difference : maxDiff;
465 ezMax = std::abs(ez) > ezMax ? std::abs(ez) : ezMax;
466 error += std::pow(difference, 2.0);
467 ezSquare += std::pow(ez, 2.0);
469 if (ippl::Comm->rank() == 0 && !opal->isOptimizerRun()) {
470 out << std::setw(16) << std::setprecision(8) << *it << std::setw(16)
471 << std::setprecision(8) << ez << std::setw(16) << std::setprecision(8)
472 << onAxisFieldCheck << std::endl;
477 if (std::sqrt(error / ezSquare) > 1e-1 || maxDiff > 1e-1 * ezMax) {
481 "Fieldmap::checkMap",
482 "Field map can't be reproduced properly with the given number of fourier components");
484 if (std::sqrt(error / ezSquare) > 1e-2 || maxDiff > 1e-2 * ezMax) {
490 const double& ,
const double& ,
const double& ){};
504 size_t comment = buffer.find(
"#");
505 buffer = buffer.substr(0, comment);
509 }
while (!in.eof() && lastof == std::string::npos);
511 if (firstof != std::string::npos) {
512 buffer = buffer.substr(firstof, lastof - firstof + 1);
521 size_t comment = buffer.find_first_of(
"#");
522 buffer = buffer.substr(0, comment);
524 if (lasto != std::string::npos) {
533 const std::ios_base::iostate& state,
const bool& read_all,
const std::string& expecting,
534 const std::string& found) {
535 std::stringstream errormsg;
536 errormsg <<
"THERE SEEMS TO BE SOMETHING WRONG WITH YOUR FIELD MAP '" <<
Filename_m <<
"'.\n";
538 errormsg <<
"Didn't find enough values!" << std::endl;
539 }
else if (state & std::ios_base::eofbit) {
540 errormsg <<
"Found more values than expected!" << std::endl;
541 }
else if (state & std::ios_base::failbit) {
542 errormsg <<
"Found wrong type of values!"
544 <<
"expecting: '" << expecting <<
"' on line " <<
lines_read_m <<
",\n"
545 <<
"instead found: '" << found <<
"'." << std::endl;
551 std::stringstream errormsg;
552 errormsg <<
"THERE SEEMS TO BE SOMETHING WRONG WITH YOUR FIELD MAP '" <<
Filename_m <<
"'.\n"
553 <<
"There are only " <<
lines_read_m - 1 <<
" lines in the file, expecting more.\n"
554 <<
"Please check the section about field maps in the user manual.";
560 std::stringstream errormsg;
561 errormsg <<
"THERE SEEMS TO BE SOMETHING WRONG WITH YOUR FIELD MAP '" <<
Filename_m <<
"'.\n"
562 <<
"There are too many lines in the file, expecting only " <<
lines_read_m
564 <<
"Please check the section about field maps in the user manual.";
570 std::stringstream errormsg;
571 errormsg <<
"DISABLING FIELD MAP '" +
Filename_m +
"' DUE TO PARSING ERRORS.";
577 std::stringstream errormsg;
578 errormsg <<
"DISABLING FIELD MAP '" <<
Filename_m <<
"' SINCE FILE COULDN'T BE FOUND!";
584 std::stringstream errormsg;
585 errormsg <<
"IT SEEMS THAT YOU USE TOO FEW FOURIER COMPONENTS TO SUFFICIENTLY WELL\n"
586 <<
"RESOLVE THE FIELD MAP '" <<
Filename_m <<
"'.\n"
587 <<
"PLEASE INCREASE THE NUMBER OF FOURIER COMPONENTS!\n"
588 <<
"The ratio (e_i - E_i)^2 / E_i^2 is " << std::to_string(squareError) <<
" and\n"
589 <<
"the ratio (max_i(|e_i - E_i|) / max_i(|E_i|) is " << std::to_string(maxError)
591 <<
"Here E_i is the field as in the field map and e_i is the reconstructed field.\n"
592 <<
"The lower limit for the two ratios is 1e-2\n"
593 <<
"Have a look into the directory "
595 <<
" for a reconstruction of the field map.\n";
596 std::string errormsg_str =
typeset_msg(errormsg.str(),
"warning");
598 *ippl::Error << errormsg_str <<
"\n" << endl;
600 if (ippl::Comm->rank() == 0) {
601 std::ofstream omsg(
"errormsg.txt", std::ios_base::app);
602 omsg << errormsg.str() << std::endl;
608 static std::string frame(
609 "* ******************************************************************************\n");
610 static unsigned int frame_width = frame.length() - 5;
611 static std::string closure(
614 std::string return_string(
"\n" + frame);
616 int remaining_length = msg.length();
617 unsigned int current_position = 0;
620 for (; ii < title.length(); ++ii) {
623 return_string.replace(15 + 2 * ii, 1,
" ");
624 return_string.replace(16 + 2 * ii, 1, &c, 1);
626 return_string.replace(15 + 2 * ii, 1,
" ");
628 while (remaining_length > 0) {
629 size_t eol = msg.find(
"\n", current_position);
630 std::string next_to_process;
631 if (eol != std::string::npos) {
632 next_to_process = msg.substr(current_position, eol - current_position);
634 next_to_process = msg.substr(current_position);
638 if (eol - current_position < frame_width) {
639 return_string +=
"* " + next_to_process + closure.substr(eol - current_position + 2);
641 unsigned int last_space = next_to_process.rfind(
" ", frame_width);
642 if (last_space > 0) {
643 if (last_space < frame_width) {
644 return_string +=
"* " + next_to_process.substr(0, last_space)
645 + closure.substr(last_space + 2);
647 return_string +=
"* " + next_to_process.substr(0, last_space) +
" *\n";
649 if (next_to_process.length() - last_space + 1 < frame_width) {
650 return_string +=
"* " + next_to_process.substr(last_space + 1)
651 + closure.substr(next_to_process.length() - last_space + 1);
653 return_string +=
"* " + next_to_process.substr(last_space + 1) +
" *\n";
656 return_string +=
"* " + next_to_process +
" *\n";
660 current_position = eol + 1;
661 remaining_length = msg.length() - current_position;
663 return_string += frame;
665 return return_string;
672 std::vector<double>& , std::vector<double>& ) {
681 double& ,
double& ,
double& ) {
692 unsigned int nx,
unsigned int ny,
unsigned int nz,
const std::pair<double, double>& xrange,
693 const std::pair<double, double>& yrange,
const std::pair<double, double>& zrange,
695 const size_t numpoints = nx * ny * nz;
696 if (ippl::Comm->rank() != 0 || (ef.size() != numpoints && bf.size() != numpoints))
704 PAssert(of.is_open());
707 const double hx = (xrange.second - xrange.first) / (nx - 1);
708 const double hy = (yrange.second - yrange.first) / (ny - 1);
709 const double hz = (zrange.second - zrange.first) / (nz - 1);
711 of <<
"# vtk DataFile Version 2.0" << std::endl;
712 of <<
"generated by 3D fieldmaps" << std::endl;
713 of <<
"ASCII" << std::endl << std::endl;
714 of <<
"DATASET RECTILINEAR_GRID" << std::endl;
715 of <<
"DIMENSIONS " << nx <<
" " << ny <<
" " << nz << std::endl;
717 of <<
"X_COORDINATES " << nx <<
" float" << std::endl;
719 for (
unsigned int i = 1; i < nx - 1; ++i) {
720 of <<
" " << xrange.first + i * hx;
722 of <<
" " << xrange.second << std::endl;
724 of <<
"Y_COORDINATES " << ny <<
" float" << std::endl;
726 for (
unsigned int i = 1; i < ny - 1; ++i) {
727 of <<
" " << yrange.first + i * hy;
729 of <<
" " << yrange.second << std::endl;
731 of <<
"Z_COORDINATES " << nz <<
" float" << std::endl;
733 for (
unsigned int i = 1; i < nz - 1; ++i) {
734 of <<
" " << zrange.first + i * hz;
736 of <<
" " << zrange.second << std::endl;
738 of <<
"POINT_DATA " << numpoints << std::endl;
740 if (ef.size() == numpoints) {
741 of <<
"VECTORS EField float" << std::endl;
743 for (
size_t i = 0; i < numpoints; ++i) {
744 of << ef[i](0) <<
" " << ef[i](1) <<
" " << ef[i](2) << std::endl;
749 if (bf.size() == numpoints) {
750 of <<
"VECTORS BField float" << std::endl;
752 for (
size_t i = 0; i < numpoints; ++i) {
753 of << bf[i](0) <<
" " << bf[i](1) <<
" " << bf[i](2) << std::endl;
765 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-+\211");
767 std::map<std::string, Fieldmap::FieldmapDescription>();
ippl::Vector< T, Dim > Vector_t
PartBunch< T, Dim >::ConstIterator end(PartBunch< T, Dim > const &bunch)
#define REGISTER_PARSE_TYPE(X)
std::shared_ptr< _Astra1DDynamic_fast > Astra1DDynamic_fast
std::shared_ptr< _FM2DDynamic > FM2DDynamic
std::shared_ptr< _FM3DH5Block > FM3DH5Block
std::shared_ptr< _FM3DMagnetoStaticH5Block > FM3DMagnetoStaticH5Block
std::shared_ptr< _Astra1DDynamic > Astra1DDynamic
std::shared_ptr< _FM1DMagnetoStatic_fast > FM1DMagnetoStatic_fast
std::shared_ptr< _FM2DMagnetoStatic > FM2DMagnetoStatic
std::shared_ptr< _FM3DDynamic > FM3DDynamic
std::shared_ptr< _Astra1DMagnetoStatic > Astra1DMagnetoStatic
std::shared_ptr< _Astra1DElectroStatic_fast > Astra1DElectroStatic_fast
std::shared_ptr< _FM1DElectroStatic_fast > FM1DElectroStatic_fast
std::shared_ptr< _FM1DProfile2 > FM1DProfile2
std::shared_ptr< _FM1DDynamic > FM1DDynamic
std::shared_ptr< _FM1DProfile1 > FM1DProfile1
std::shared_ptr< _FM3DMagnetoStatic > FM3DMagnetoStatic
std::shared_ptr< _FM3DMagnetoStaticExtended > FM3DMagnetoStaticExtended
std::shared_ptr< _FM3DH5Block_nonscale > FM3DH5Block_nonscale
std::shared_ptr< _FM2DElectroStatic > FM2DElectroStatic
std::shared_ptr< _FM1DDynamic_fast > FM1DDynamic_fast
std::shared_ptr< _Astra1DElectroStatic > Astra1DElectroStatic
std::shared_ptr< _FM1DMagnetoStatic > FM1DMagnetoStatic
std::shared_ptr< _Astra1DMagnetoStatic_fast > Astra1DMagnetoStatic_fast
std::shared_ptr< _FM1DElectroStatic > FM1DElectroStatic
#define READ_BUFFER_LENGTH
@ T3DMagnetoStatic_Extended
@ T3DMagnetoStaticH5Block
constexpr double two_pi
The value of.
std::string combineFilePath(std::initializer_list< std::string > ilist)
static OpalData * getInstance()
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
static Fieldmap * getFieldmap(std::string Filename, bool fast=false)
static void deleteFieldmap(std::string Filename)
static std::string alpha_numeric
static std::map< std::string, FieldmapDescription > FieldmapDictionary
static MapType readHeader(std::string Filename)
bool interpreteEOF(std::ifstream &in)
virtual void setFieldLength(const double &)
void missingValuesWarning()
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &onaxis)
virtual void get1DProfile1EntranceParam(double &entranceParameter1, double &entranceParameter2, double &entranceParameter3)
void checkMap(unsigned int accuracy, std::pair< double, double > fieldDimensions, double deltaZ, const std::vector< double > &fourierCoefficients, gsl_spline *splineCoefficients, gsl_interp_accel *splineAccelerator)
void lowResolutionWarning(double squareError, double maxError)
void interpretWarning(const std::ios_base::iostate &state, const bool &read_all, const std::string &error_msg, const std::string &found)
void disableFieldmapWarning()
static char buffer_m[256]
static std::vector< std::string > getListFieldmapNames()
static std::string typeset_msg(const std::string &msg, const std::string &title)
static void clearDictionary()
static void freeMap(std::string Filename)
virtual double getFieldGap()
virtual void setEdgeConstants(const double &bendAngle, const double &entranceAngle, const double &exitAngle)
virtual void setFieldGap(double gap)
void exceedingValuesWarning()
virtual void get1DProfile1EngeCoeffs(std::vector< double > &engeCoeffsEntry, std::vector< double > &engeCoeffsExit)
void getLine(std::ifstream &in, std::string &buffer)
virtual void get1DProfile1ExitParam(double &exitParameter1, double &exitParameter2, double &exitParameter3)
static void readMap(std::string Filename)
void write3DField(unsigned int nx, unsigned int ny, unsigned int nz, const std::pair< double, double > &xrange, const std::pair< double, double > &yrange, const std::pair< double, double > &zrange, const std::vector< Vector_t< double, 3 > > &ef, const std::vector< Vector_t< double, 3 > > &bf)