BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
PyFmt2.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Device/Instrument/PyFmt2.cpp
6 //! @brief Implements functions from namespace pyfmt2.
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 
17 #include "Base/Const/Units.h"
18 #include "Base/Utils/Algorithms.h"
19 #include "Base/Utils/PyFmt.h"
20 #include "Device/Mask/Ellipse.h"
22 #include "Device/Mask/Line.h"
23 #include "Device/Mask/Polygon.h"
24 #include "Device/Mask/Rectangle.h"
25 #include "Fit/Tools/StringUtils.h"
31 #include <iomanip>
32 
33 namespace pyfmt2
34 {
35 
36 //! Returns fixed Python code snippet that defines the function "runSimulation".
37 
38 std::string representShape2D(const std::string& indent, const IShape2D* ishape, bool mask_value,
39  std::function<std::string(double)> printValueFunc)
40 {
41  std::ostringstream result;
42  result << std::setprecision(12);
43 
44  if (const Polygon* shape = dynamic_cast<const Polygon*>(ishape)) {
45  std::vector<double> xpos, ypos;
46  shape->getPoints(xpos, ypos);
47  result << indent << "points = [";
48  for (size_t i = 0; i < xpos.size(); ++i) {
49  result << "[" << printValueFunc(xpos[i]) << ", " << printValueFunc(ypos[i]) << "]";
50  if (i != xpos.size() - 1)
51  result << ", ";
52  }
53  result << "]\n";
54  result << indent << "simulation.addMask("
55  << "ba.Polygon(points), " << pyfmt::printBool(mask_value) << ")\n";
56 
57  } else if (dynamic_cast<const InfinitePlane*>(ishape)) {
58  result << indent << "simulation.maskAll()\n";
59 
60  } else if (const Ellipse* shape = dynamic_cast<const Ellipse*>(ishape)) {
61  result << indent << "simulation.addMask(";
62  result << "ba.Ellipse(" << printValueFunc(shape->getCenterX()) << ", "
63  << printValueFunc(shape->getCenterY()) << ", " << printValueFunc(shape->getRadiusX())
64  << ", " << printValueFunc(shape->getRadiusY());
65  if (shape->getTheta() != 0.0)
66  result << ", " << pyfmt::printDegrees(shape->getTheta());
67  result << "), " << pyfmt::printBool(mask_value) << ")\n";
68  }
69 
70  else if (const Rectangle* shape = dynamic_cast<const Rectangle*>(ishape)) {
71  result << indent << "simulation.addMask(";
72  result << "ba.Rectangle(" << printValueFunc(shape->getXlow()) << ", "
73  << printValueFunc(shape->getYlow()) << ", " << printValueFunc(shape->getXup())
74  << ", " << printValueFunc(shape->getYup()) << "), " << pyfmt::printBool(mask_value)
75  << ")\n";
76  }
77 
78  else if (const VerticalLine* shape = dynamic_cast<const VerticalLine*>(ishape)) {
79  result << indent << "simulation.addMask(";
80  result << "ba.VerticalLine(" << printValueFunc(shape->getXpos()) << "), "
81  << pyfmt::printBool(mask_value) << ")\n";
82  }
83 
84  else if (const HorizontalLine* shape = dynamic_cast<const HorizontalLine*>(ishape)) {
85  result << indent << "simulation.addMask(";
86  result << "ba.HorizontalLine(" << printValueFunc(shape->getYpos()) << "), "
87  << pyfmt::printBool(mask_value) << ")\n";
88 
89  } else
90  throw std::runtime_error("representShape2D(const IShape2D*) -> Error. Unknown shape");
91 
92  return result.str();
93 }
94 
95 //! Returns parameter value, followed by its unit multiplicator (like "* nm").
96 
97 std::string valueTimesUnit(const RealParameter* par)
98 {
99  if (par->unit() == "rad")
100  return pyfmt::printDegrees(par->value());
101  return pyfmt::printDouble(par->value()) + (par->unit() == "" ? "" : ("*" + par->unit()));
102 }
103 
104 //! Returns comma-separated list of parameter values, including unit multiplicator (like "* nm").
105 
106 std::string argumentList(const IParameterized* ip)
107 {
108  std::vector<std::string> args;
109  for (const auto* par : ip->parameterPool()->parameters())
110  args.push_back(valueTimesUnit(par));
111  return StringUtils::join(args, ", ");
112 }
113 
114 //! Prints distribution with constructor parameters in given units.
115 //! ba.DistributionGaussian(2.0*deg, 0.02*deg)
116 
117 std::string printDistribution(const IDistribution1D& par_distr, const std::string& units)
118 {
119  std::unique_ptr<IDistribution1D> distr(par_distr.clone());
120  distr->setUnits(units);
121 
122  std::ostringstream result;
123  result << "ba." << distr->getName() << "(" << argumentList(distr.get()) << ")";
124  return result.str();
125 }
126 
128  const std::string& distVarName, const std::string& units)
129 {
130  std::ostringstream result;
131 
132  result << "ba.ParameterDistribution("
133  << "\"" << par_distr.getMainParameterName() << "\""
134  << ", " << distVarName << ", " << par_distr.getNbrSamples() << ", "
135  << pyfmt::printDouble(par_distr.getSigmaFactor())
136  << pyfmt::printRealLimitsArg(par_distr.getLimits(), units) << ")";
137 
138  return result.str();
139 }
140 
141 } // namespace pyfmt2
Defines and implements namespace algo with some algorithms.
Defines classes representing one-dimensional distributions.
Defines class Rectangle.
Defines class InfinitePlane.
Defines class Line.
Defines M_PI and some more mathematical constants.
Defines class ParameterDistribution.
Defines class ParameterPool.
Defines class Polygon.
Defines namespace pyfmt2.
Defines functions in namespace pyfmt.
Defines functions in namespace pyfmt.
Defines class RealParameter.
Defines class Rectangle.
Defines a few helper functions.
Defines some unit conversion factors and other constants in namespace Units.
Ellipse shape.
Definition: Ellipse.h:24
An infinite horizontal line.
Definition: Line.h:58
Interface for one-dimensional distributions.
Definition: Distributions.h:33
virtual IDistribution1D * clone() const =0
Manages a local parameter pool, and a tree of child pools.
ParameterPool * parameterPool() const
Returns pointer to the parameter pool.
Basic class for all shapes in 2D.
Definition: IShape2D.h:27
The infinite plane is used for masking everything once and forever.
Definition: InfinitePlane.h:24
A parametric distribution function, for use with any model parameter.
size_t getNbrSamples() const
get number of samples for this distribution
double getSigmaFactor() const
get the sigma factor
RealLimits getLimits() const
std::string getMainParameterName() const
get the main parameter's name
const std::vector< RealParameter * > parameters() const
Returns full vector of parameters.
Definition: ParameterPool.h:52
A polygon in 2D space.
Definition: Polygon.h:31
Wraps a parameter of type double.
Definition: RealParameter.h:32
double value() const
Returns value of wrapped parameter.
std::string unit() const
The rectangle shape having its axis aligned to the (non-rotated) coordinate system.
Definition: Rectangle.h:24
An infinite vertical line.
Definition: Line.h:40
std::string join(const std::vector< std::string > &joinable, const std::string &joint)
Returns string obtain by joining vector elements.
Definition: StringUtils.cpp:71
Utility functions for writing Python code snippets.
Definition: PyFmt2.cpp:34
std::string printParameterDistribution(const ParameterDistribution &par_distr, const std::string &distVarName, const std::string &units)
Definition: PyFmt2.cpp:127
std::string argumentList(const IParameterized *ip)
Returns comma-separated list of parameter values, including unit multiplicator (like "* nm").
Definition: PyFmt2.cpp:106
std::string printDistribution(const IDistribution1D &par_distr, const std::string &units)
Prints distribution with constructor parameters in given units.
Definition: PyFmt2.cpp:117
std::string valueTimesUnit(const RealParameter *par)
Returns parameter value, followed by its unit multiplicator (like "* nm").
Definition: PyFmt2.cpp:97
std::string representShape2D(const std::string &indent, const IShape2D *ishape, bool mask_value, std::function< std::string(double)> printValueFunc)
Returns fixed Python code snippet that defines the function "runSimulation".
Definition: PyFmt2.cpp:38
std::string printDegrees(double input)
Definition: PyFmt.cpp:94
std::string printDouble(double input)
Definition: PyFmt.cpp:43
std::string printBool(double value)
Definition: PyFmt.cpp:38
std::string indent(size_t width)
Returns a string of blanks with given width.
Definition: PyFmt.cpp:141
std::string printRealLimitsArg(const RealLimits &limits, const std::string &units)
Prints RealLimits in the form of argument (in the context of ParameterDistribution and similar).
Definition: PyFmtLimits.cpp:61