BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
PyFmt.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Core/Export/PyFmt.cpp
6 //! @brief Implements functions from namespace pyfmt.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #include "Core/Export/PyFmt.h"
16 #include "Base/Const/Units.h" // printDegrees
17 #include "Base/Math/Constants.h"
18 #include "Base/Utils/Algorithms.h"
19 #include "Base/Utils/StringUtils.h"
20 #include <iomanip>
21 
22 namespace pyfmt {
23 
24 std::string printImportedSymbols(const std::string& code)
25 {
26  std::vector<std::string> to_declare;
27  for (const std::string& key : {"angstrom", "deg", "nm", "nm2", "micrometer"})
28  if (code.find("*" + key) != std::string::npos)
29  to_declare.push_back(key);
30  for (const std::string& key : {"kvector_t"})
31  if (code.find(key) != std::string::npos)
32  to_declare.push_back(key);
33  return "from bornagain import " + StringUtils::join(to_declare, ", ") + "\n";
34 }
35 
36 std::string printBool(double value)
37 {
38  return value ? "True" : "False";
39 }
40 
41 std::string printDouble(double input)
42 {
43  std::ostringstream inter;
44  inter << std::setprecision(12);
45  if (std::abs(input) < std::numeric_limits<double>::epsilon()) {
46  inter << "0.0";
47  return inter.str();
48  }
49  inter << input;
50  if (inter.str().find('e') == std::string::npos && inter.str().find('.') == std::string::npos)
51  inter << ".0";
52  return inter.str();
53 }
54 
55 //! prints double as an integer, if possible within standard accuracy
56 std::string printLightDouble(double input)
57 {
58  std::ostringstream inter;
59  int ival = std::lround(input);
60  if (std::abs(input - ival) < 1e-11)
61  inter << ival;
62  else {
63  inter << std::setprecision(12);
64  if (std::abs(input) < std::numeric_limits<double>::epsilon())
65  return "0.0";
66  inter << input;
67  if (inter.str().find('e') == std::string::npos
68  && inter.str().find('.') == std::string::npos)
69  inter << ".0";
70  }
71  return inter.str();
72 }
73 
74 std::string printNm(double input)
75 {
76  std::ostringstream inter;
77  inter << std::setprecision(12);
78  inter << printLightDouble(input) << "*nm";
79  return inter.str();
80 }
81 
82 std::string printNm2(double input)
83 {
84  std::ostringstream inter;
85  inter << std::setprecision(12);
86  inter << printLightDouble(input) << "*nm2";
87  return inter.str();
88 }
89 
90 // 1.000000e+07 -> 1.0e+07
91 std::string printScientificDouble(double input)
92 {
93  std::ostringstream inter;
94  inter << std::scientific;
95  inter << input;
96 
97  std::string::size_type pos = inter.str().find('e');
98  if (pos == std::string::npos)
99  return inter.str();
100 
101  std::string part1 = inter.str().substr(0, pos);
102  std::string part2 = inter.str().substr(pos, std::string::npos);
103 
104  part1.erase(part1.find_last_not_of('0') + 1, std::string::npos);
105  if (part1.back() == '.')
106  part1 += "0";
107 
108  return part1 + part2;
109 }
110 
111 std::string printDegrees(double input)
112 {
113  std::ostringstream inter;
114  inter << printLightDouble(Units::rad2deg(input)) << "*deg";
115  return inter.str();
116 }
117 
118 std::string printValue(double value, const std::string& units)
119 {
120  if (units == "rad")
121  return printDegrees(value);
122  else if (units == "nm")
123  return printNm(value);
124  else if (units == "")
125  return printDouble(value);
126  else
127  throw std::runtime_error("pyfmt::printValue() -> Error. Unknown units '" + units + "'");
128 }
129 
130 std::string printString(const std::string& value)
131 {
132  std::ostringstream result;
133  result << "\"" << value << "\"";
134  return result.str();
135 }
136 
137 bool isSquare(double length1, double length2, double angle)
138 {
139  return length1 == length2 && algo::almostEqual(angle, M_PI_2);
140 }
141 
142 bool isHexagonal(double length1, double length2, double angle)
143 {
144  return length1 == length2 && algo::almostEqual(angle, M_TWOPI / 3.0);
145 }
146 
147 std::string printKvector(const kvector_t value)
148 {
149  std::ostringstream result;
150  result << "kvector_t(" << printDouble(value.x()) << ", " << printDouble(value.y()) << ", "
151  << printDouble(value.z()) << ")";
152  return result.str();
153 }
154 
155 std::string indent(size_t width)
156 {
157  return std::string(width, ' ');
158 }
159 
160 } // namespace pyfmt
Defines and implements namespace algo with some algorithms.
Defines a few helper functions.
Defines M_PI and some more mathematical constants.
#define M_TWOPI
Definition: Constants.h:54
#define M_PI_2
Definition: Constants.h:45
Defines functions in namespace pyfmt.
Defines some unit conversion factors and other constants in namespace Units.
T z() const
Returns z-component in cartesian coordinate system.
Definition: BasicVector3D.h:67
T y() const
Returns y-component in cartesian coordinate system.
Definition: BasicVector3D.h:65
T x() const
Returns x-component in cartesian coordinate system.
Definition: BasicVector3D.h:63
std::string join(const std::vector< std::string > &joinable, const std::string &joint)
Returns string obtain by joining vector elements.
Definition: StringUtils.cpp:71
std::string scientific(const T value, int n=10)
Returns scientific string representing given value of any numeric type.
Definition: StringUtils.h:61
double rad2deg(double angle)
Definition: Units.h:55
bool almostEqual(double a, double b)
Returns true if two doubles agree within machine epsilon.
Definition: Algorithms.h:34
Utility functions for writing Python code snippets.
Definition: PyFmt.cpp:22
std::string printNm(double input)
Definition: PyFmt.cpp:74
std::string printNm2(double input)
Definition: PyFmt.cpp:82
std::string printDegrees(double input)
Definition: PyFmt.cpp:111
bool isSquare(double length1, double length2, double angle)
Definition: PyFmt.cpp:137
std::string printDouble(double input)
Definition: PyFmt.cpp:41
std::string printKvector(const kvector_t value)
Definition: PyFmt.cpp:147
std::string printScientificDouble(double input)
Definition: PyFmt.cpp:91
std::string printBool(double value)
Definition: PyFmt.cpp:36
std::string printImportedSymbols(const std::string &code)
Definition: PyFmt.cpp:24
std::string printLightDouble(double input)
prints double as an integer, if possible within standard accuracy
Definition: PyFmt.cpp:56
std::string printString(const std::string &value)
Definition: PyFmt.cpp:130
std::string indent(size_t width)
Returns a string of blanks with given width.
Definition: PyFmt.cpp:155
bool isHexagonal(double length1, double length2, double angle)
Definition: PyFmt.cpp:142
std::string printValue(double value, const std::string &units)
Definition: PyFmt.cpp:118