BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
SimulationToPython.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Core/Export/SimulationToPython.cpp
6 //! @brief Implements class SimulationToPython.
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 
16 #include "Base/Utils/Algorithms.h"
20 #include "Core/Export/PyFmt.h"
21 #include "Core/Export/PyFmt2.h"
25 #include "Core/Scan/QSpecScan.h"
40 #include <iomanip>
41 
42 using pyfmt::indent;
43 
44 namespace {
45 //! Returns a function that converts a coordinate to a Python code snippet with appropiate unit
46 std::function<std::string(double)> printFunc(const IDetector* detector)
47 {
48  if (detector->defaultAxesUnits() == Axes::Units::MM)
49  return pyfmt::printDouble;
50  if (detector->defaultAxesUnits() == Axes::Units::RADIANS)
51  return pyfmt::printDegrees;
52  throw std::runtime_error("SimulationToPython::defineMasks() -> Error. Unknown detector units.");
53 }
54 
55 //! returns true if it is (0, -1, 0) vector
56 bool isDefaultDirection(const kvector_t direction)
57 {
58  return algo::almostEqual(direction.x(), 0.0) && algo::almostEqual(direction.y(), -1.0)
59  && algo::almostEqual(direction.z(), 0.0);
60 }
61 
62 std::string defineFootprintFactor(const IFootprintFactor& foot)
63 {
64  std::ostringstream result;
65  result << indent() << "footprint = ba." << foot.name();
66  result << "(" << pyfmt::printDouble(foot.widthRatio()) << ")\n";
67  return result.str();
68 }
69 
70 std::string defineScanResolution(const ScanResolution& scan)
71 {
72  std::ostringstream result;
73  result << pyfmt2::printRangedDistribution(*scan.distribution()) << "\n"
74  << indent() << "resolution = "
75  << "ba." << scan.name() << "(distribution, " << pyfmt::printDouble(scan.delta())
76  << ")\n";
77  return result.str();
78 }
79 
80 std::string defineAngularSpecScan(const AngularSpecScan& scan)
81 {
82  std::ostringstream result;
83  result << "\n"
84  << indent() << "# Define specular scan:\n"
85  << indent() << "axis = " << pyfmt2::printAxis(scan.coordinateAxis(), "rad") << "\n"
86  << indent() << "scan = "
87  << "ba.AngularSpecScan(" << pyfmt::printDouble(scan.wavelength()) << ", axis)\n";
88 
89  if (scan.footprintFactor()) {
90  result << defineFootprintFactor(*scan.footprintFactor());
91  result << indent() << "scan.setFootprintFactor(footprint)\n";
92  }
93  if (const auto* r = scan.angleResolution(); r && r->distribution()) {
94  result << defineScanResolution(*r) << "\n";
95  result << indent() << "scan.setAngleResolution(resolution)\n";
96  }
97  if (const auto* r = scan.wavelengthResolution(); r && r->distribution()) {
98  result << defineScanResolution(*r) << "\n";
99  result << indent() << "scan.setWavelengthResolution(resolution)\n";
100  }
101  return result.str();
102 }
103 
104 std::string defineQSpecScan(const QSpecScan& scan)
105 {
106  std::ostringstream result;
107  const std::string axis_def = indent() + "axis = ";
108  result << axis_def << pyfmt2::printAxis(scan.coordinateAxis(), "") << "\n";
109  // TODO correct unit would be 1/nm
110 
111  result << indent() << "scan = ba.QSpecScan(axis)";
112  if (scan.resolution()) {
113  result << "\n";
114  result << defineScanResolution(*scan.resolution()) << "\n";
115  result << indent() << "scan.setQResolution(resolution)";
116  }
117  return result.str();
118 }
119 
120 std::string defineScan(const ISpecularScan* scan)
121 {
122  if (const auto* s = dynamic_cast<const AngularSpecScan*>(scan); s)
123  return defineAngularSpecScan(*s);
124  if (const auto* s = dynamic_cast<const QSpecScan*>(scan); s)
125  return defineQSpecScan(*s);
126  ASSERT(0);
127 }
128 
129 std::string defineDetector(const ISimulation* simulation)
130 {
131  const IDetector* const detector = simulation->getDetector();
132  if (detector->dimension() != 2)
133  throw std::runtime_error("defineDetector: "
134  "detector must be two-dimensional for GISAS");
135  std::ostringstream result;
136  result << std::setprecision(12);
137 
138  if (const auto* const det = dynamic_cast<const SphericalDetector*>(detector)) {
139  ASSERT(det->dimension() == 2);
140  result << indent() << "detector = ba.SphericalDetector(";
141  if (DetectorUtils::isQuadratic(*det)) {
142  result << det->axis(0).size() << ", " << pyfmt::printDegrees(det->axis(0).span())
143  << ", " << pyfmt::printDegrees(det->axis(0).center()) << ", "
144  << pyfmt::printDegrees(det->axis(1).center());
145  } else {
146  result << det->axis(0).size() << ", " << pyfmt::printDegrees(det->axis(0).lowerBound())
147  << ", " << pyfmt::printDegrees(det->axis(0).upperBound()) << ", "
148  << det->axis(1).size() << ", " << pyfmt::printDegrees(det->axis(1).lowerBound())
149  << ", " << pyfmt::printDegrees(det->axis(1).upperBound());
150  }
151  result << ")\n";
152  } else if (const auto* const det = dynamic_cast<const RectangularDetector*>(detector)) {
153  result << "\n";
154  result << indent() << "detector = ba.RectangularDetector(" << det->getNbinsX() << ", "
155  << pyfmt::printDouble(det->getWidth()) << ", " << det->getNbinsY() << ", "
156  << pyfmt::printDouble(det->getHeight()) << ")\n";
157  if (det->getDetectorArrangment() == RectangularDetector::GENERIC) {
158  result << indent() << "detector.setPosition("
159  << pyfmt::printKvector(det->getNormalVector()) << ", "
160  << pyfmt::printDouble(det->getU0()) << ", " << pyfmt::printDouble(det->getV0());
161  if (!isDefaultDirection(det->getDirectionVector()))
162  result << ", " << pyfmt::printKvector(det->getDirectionVector());
163  result << ")\n";
164  } else if (det->getDetectorArrangment() == RectangularDetector::PERPENDICULAR_TO_SAMPLE) {
165  result << indent() << "detector.setPerpendicularToSampleX("
166  << pyfmt::printDouble(det->getDistance()) << ", "
167  << pyfmt::printDouble(det->getU0()) << ", " << pyfmt::printDouble(det->getV0())
168  << ")\n";
169  } else if (det->getDetectorArrangment()
171  result << indent() << "detector.setPerpendicularToDirectBeam("
172  << pyfmt::printDouble(det->getDistance()) << ", "
173  << pyfmt::printDouble(det->getU0()) << ", " << pyfmt::printDouble(det->getV0())
174  << ")\n";
175  } else if (det->getDetectorArrangment()
177  result << indent() << "detector.setPerpendicularToReflectedBeam("
178  << pyfmt::printDouble(det->getDistance()) << ", "
179  << pyfmt::printDouble(det->getU0()) << ", " << pyfmt::printDouble(det->getV0())
180  << ")\n";
181  } else if (det->getDetectorArrangment()
183  result << indent() << "detector.setPerpendicularToReflectedBeam("
184  << pyfmt::printDouble(det->getDistance()) << ")\n";
185  result << indent() << "detector.setDirectBeamPosition("
186  << pyfmt::printDouble(det->getDirectBeamU0()) << ", "
187  << pyfmt::printDouble(det->getDirectBeamV0()) << ")\n";
188  } else
189  throw std::runtime_error("defineDetector() -> Error. Unknown alignment.");
190  } else
191  throw std::runtime_error("defineDetector() -> Error. Unknown detector");
192  if (detector->regionOfInterest()) {
193  result << indent() << "detector.setRegionOfInterest("
194  << printFunc(detector)(detector->regionOfInterest()->getXlow()) << ", "
195  << printFunc(detector)(detector->regionOfInterest()->getYlow()) << ", "
196  << printFunc(detector)(detector->regionOfInterest()->getXup()) << ", "
197  << printFunc(detector)(detector->regionOfInterest()->getYup()) << ")\n";
198  }
199  return result.str();
200 }
201 
202 std::string defineDetectorResolutionFunction(const ISimulation* simulation)
203 {
204  std::ostringstream result;
205  const IDetector* detector = simulation->getDetector();
206 
207  if (const IDetectorResolution* resfunc = detector->detectorResolution()) {
208  if (auto* convfunc = dynamic_cast<const ConvolutionDetectorResolution*>(resfunc)) {
209  if (auto* resfunc = dynamic_cast<const ResolutionFunction2DGaussian*>(
210  convfunc->getResolutionFunction2D())) {
211  result << indent() << "simulation.setDetectorResolutionFunction(";
212  result << "ba.ResolutionFunction2DGaussian(";
213  result << printFunc(detector)(resfunc->getSigmaX()) << ", ";
214  result << printFunc(detector)(resfunc->getSigmaY()) << "))\n";
215  } else
216  throw std::runtime_error("defineDetectorResolutionFunction() -> Error. "
217  "Unknown detector resolution function");
218  } else
219  throw std::runtime_error("defineDetectorResolutionFunction() -> Error. "
220  "Not a ConvolutionDetectorResolution function");
221  }
222  return result.str();
223 }
224 
225 std::string defineDetectorPolarizationAnalysis(const ISimulation* simulation)
226 {
227  std::ostringstream result;
228  const IDetector* detector = simulation->getDetector();
229  kvector_t analyzer_direction = detector->detectionProperties().analyzerDirection();
230  double analyzer_efficiency = detector->detectionProperties().analyzerEfficiency();
231  double analyzer_total_transmission =
233 
234  if (analyzer_direction.mag() > 0.0) {
235  std::string direction_name = "analyzer_direction";
236  result << indent() << direction_name << " = kvector_t("
237  << pyfmt::printDouble(analyzer_direction.x()) << ", "
238  << pyfmt::printDouble(analyzer_direction.y()) << ", "
239  << pyfmt::printDouble(analyzer_direction.z()) << ")\n";
240  result << indent() << "simulation.detector().setAnalyzerProperties(" << direction_name
241  << ", " << pyfmt::printDouble(analyzer_efficiency) << ", "
242  << pyfmt::printDouble(analyzer_total_transmission) << ")\n";
243  }
244  return result.str();
245 }
246 
247 std::string defineBeamPolarization(const Beam& beam)
248 {
249  std::ostringstream result;
250  auto bloch_vector = beam.getBlochVector();
251  if (bloch_vector.mag() > 0.0) {
252  std::string beam_polarization = "beam_polarization";
253  result << indent() << beam_polarization << " = kvector_t("
254  << pyfmt::printDouble(bloch_vector.x()) << ", "
255  << pyfmt::printDouble(bloch_vector.y()) << ", "
256  << pyfmt::printDouble(bloch_vector.z()) << ")\n";
257  result << indent() << "beam.setPolarization(" << beam_polarization << ")\n";
258  }
259  return result.str();
260 }
261 
262 std::string defineBeamIntensity(const Beam& beam)
263 {
264  std::ostringstream result;
265  double beam_intensity = beam.intensity();
266  if (beam_intensity > 0.0)
267  result << indent() << "simulation.beam().setIntensity("
268  << pyfmt::printScientificDouble(beam_intensity) << ")\n";
269  return result.str();
270 }
271 
272 std::string defineGISASBeam(const GISASSimulation& simulation)
273 {
274  std::ostringstream result;
275  const Beam& beam = simulation.beam();
276 
277  result << indent() << "beam = ba.Beam(" << pyfmt::printDouble(beam.intensity()) << ", "
278  << pyfmt::printNm(beam.wavelength()) << ", ba.Direction("
279  << pyfmt::printDegrees(beam.direction().alpha()) << ", "
280  << pyfmt::printDegrees(beam.direction().phi()) << "))\n";
281 
282  result << defineBeamPolarization(beam);
283 
284  return result.str();
285 }
286 
287 std::string defineOffSpecularBeam(const OffSpecularSimulation& simulation)
288 {
289  std::ostringstream result;
290  const Beam& beam = simulation.beam();
291 
292  const std::string axidef = indent() + "alpha_i_axis = ";
293  result << axidef << pyfmt2::printAxis(simulation.beamAxis(), "rad") << "\n";
294 
295  result << indent() << "simulation.setBeamParameters(" << pyfmt::printNm(beam.wavelength())
296  << ", "
297  << "alpha_i_axis, " << pyfmt::printDegrees(beam.direction().phi()) << ")\n";
298 
299  result << defineBeamPolarization(beam);
300  result << defineBeamIntensity(beam);
301  return result.str();
302 }
303 
304 std::string defineSpecularScan(const SpecularSimulation& simulation)
305 {
306  std::ostringstream result;
307  const ISpecularScan* scan = simulation.dataHandler();
308  if (!scan)
309  throw std::runtime_error("Error defineSpecularScan: passed simulation "
310  "does not contain any scan");
311  result << defineScan(scan) << "\n";
312  result << indent() << "simulation.setScan(scan)\n";
313  result << defineBeamIntensity(simulation.beam()) << "\n";
314  return result.str();
315 }
316 
317 std::string defineParameterDistributions(const ISimulation* simulation)
318 {
319  std::ostringstream result;
320  const std::vector<ParameterDistribution>& distributions =
322  if (distributions.empty())
323  return "";
324  for (size_t i = 0; i < distributions.size(); ++i) {
325  std::string main_par_name = distributions[i].getMainParameterName();
326 
327  std::string mainParUnits = ParameterUtils::poolParameterUnits(*simulation, main_par_name);
328 
329  size_t nbr_samples = distributions[i].getNbrSamples();
330  double sigma_factor = distributions[i].getSigmaFactor();
331 
332  std::string distr = "distr_" + std::to_string(i + 1);
333  result << indent() << distr << " = "
334  << pyfmt2::printDistribution(*distributions[i].getDistribution(), mainParUnits)
335  << "\n";
336 
337  result << indent() << "simulation.addParameterDistribution(\"" << main_par_name << "\", "
338  << distr << ", " << nbr_samples << ", " << pyfmt::printDouble(sigma_factor)
339  << pyfmt::printRealLimitsArg(distributions[i].getLimits(), mainParUnits) << ")\n";
340  }
341  return result.str();
342 }
343 
344 std::string defineMasks(const ISimulation* simulation)
345 {
346  std::ostringstream result;
347  result << std::setprecision(12);
348 
349  const IDetector* detector = simulation->getDetector();
350  const DetectorMask* detectorMask = detector->detectorMask();
351  if (detectorMask && detectorMask->numberOfMasks()) {
352  result << "\n";
353  for (size_t i_mask = 0; i_mask < detectorMask->numberOfMasks(); ++i_mask) {
354  bool mask_value(false);
355  const IShape2D* shape = detectorMask->getMaskShape(i_mask, mask_value);
356  result << pyfmt2::representShape2D(indent(), shape, mask_value, printFunc(detector));
357  }
358  result << "\n";
359  }
360  return result.str();
361 }
362 
363 std::string defineSimulationOptions(const ISimulation* simulation)
364 {
365  std::ostringstream result;
366  result << std::setprecision(12);
367 
368  const SimulationOptions& options = simulation->getOptions();
369  if (options.getHardwareConcurrency() != options.getNumberOfThreads())
370  result << indent() << "simulation.getOptions().setNumberOfThreads("
371  << options.getNumberOfThreads() << ")\n";
372  if (options.isIntegrate())
373  result << indent() << "simulation.getOptions().setMonteCarloIntegration(True, "
374  << options.getMcPoints() << ")\n";
375  if (options.useAvgMaterials())
376  result << indent() << "simulation.getOptions().setUseAvgMaterials(True)\n";
377  if (options.includeSpecular())
378  result << indent() << "simulation.getOptions().setIncludeSpecular(True)\n";
379  return result.str();
380 }
381 
382 std::string defineBackground(const ISimulation* simulation)
383 {
384  std::ostringstream result;
385 
386  auto bg = simulation->background();
387  if (auto constant_bg = dynamic_cast<const ConstantBackground*>(bg)) {
388  if (constant_bg->backgroundValue() > 0.0) {
389  result << indent() << "background = ba.ConstantBackground("
390  << pyfmt::printScientificDouble(constant_bg->backgroundValue()) << ")\n";
391  result << indent() << "simulation.setBackground(background)\n";
392  }
393  } else if (dynamic_cast<const PoissonNoiseBackground*>(bg)) {
394  result << indent() << "background = ba.PoissonNoiseBackground()\n";
395  result << indent() << "simulation.setBackground(background)\n";
396  }
397  return result.str();
398 }
399 
400 std::string defineGISASSimulation(const GISASSimulation* simulation)
401 {
402  std::ostringstream result;
403  result << defineGISASBeam(*simulation);
404  result << defineDetector(simulation);
405  result << indent() << "simulation = ba.GISASSimulation(beam, sample, detector)\n";
406  result << defineDetectorResolutionFunction(simulation);
407  result << defineDetectorPolarizationAnalysis(simulation);
408  result << defineParameterDistributions(simulation);
409  result << defineMasks(simulation);
410  result << defineSimulationOptions(simulation);
411  result << defineBackground(simulation);
412  return result.str();
413 }
414 
415 std::string defineOffSpecularSimulation(const OffSpecularSimulation* simulation)
416 {
417  std::ostringstream result;
418  result << indent() << "simulation = ba.OffSpecularSimulation()\n";
419  result << defineDetector(simulation);
420  result << defineDetectorResolutionFunction(simulation);
421  result << defineDetectorPolarizationAnalysis(simulation);
422  result << defineOffSpecularBeam(*simulation);
423  result << defineParameterDistributions(simulation);
424  result << defineMasks(simulation);
425  result << defineSimulationOptions(simulation);
426  result << defineBackground(simulation);
427  result << " simulation.setSample(sample)\n";
428  return result.str();
429 }
430 
431 std::string defineSpecularSimulation(const SpecularSimulation* simulation)
432 {
433  std::ostringstream result;
434  result << indent() << "simulation = ba.SpecularSimulation()\n";
435  result << defineDetectorPolarizationAnalysis(simulation);
436  result << defineSpecularScan(*simulation);
437  result << defineParameterDistributions(simulation);
438  result << defineSimulationOptions(simulation);
439  result << defineBackground(simulation);
440  result << " simulation.setSample(sample)\n";
441  return result.str();
442 }
443 
444 std::string defineSimulate(const ISimulation* simulation)
445 {
446  std::ostringstream result;
447  result << "def get_simulation(sample):\n";
448  if (auto gisas = dynamic_cast<const GISASSimulation*>(simulation))
449  result << defineGISASSimulation(gisas);
450  else if (auto offspec = dynamic_cast<const OffSpecularSimulation*>(simulation))
451  result << defineOffSpecularSimulation(offspec);
452  else if (auto spec = dynamic_cast<const SpecularSimulation*>(simulation))
453  result << defineSpecularSimulation(spec);
454  else
455  ASSERT(0);
456  result << " return simulation\n\n\n";
457 
458  return result.str();
459 }
460 
461 std::string simulationCode(const ISimulation& simulation)
462 {
463  if (simulation.sample() == nullptr)
464  throw std::runtime_error("Cannot export: Simulation has no sample");
465  std::string code =
466  SampleToPython().sampleCode(*simulation.sample()) + defineSimulate(&simulation);
467  return "import bornagain as ba\n" + pyfmt::printImportedSymbols(code) + "\n\n" + code;
468 }
469 
470 } // namespace
471 
472 // ************************************************************************************************
473 // class SimulationToPython
474 // ************************************************************************************************
475 
477 {
478  return simulationCode(simulation)
479  + "if __name__ == '__main__':\n"
480  " import ba_plot\n"
481  " sample = get_sample()\n"
482  " simulation = get_simulation(sample)\n"
483  " ba_plot.run_and_plot(simulation)\n";
484 }
485 
487  const std::string& fname)
488 {
489  return simulationCode(simulation)
490  + "if __name__ == '__main__':\n"
491  " sample = get_sample()\n"
492  " simulation = get_simulation(sample)\n"
493  " simulation.runSimulation()\n"
494  " ba.IntensityDataIOFactory.writeSimulationResult(simulation.result(), \""
495  + fname + "\")\n";
496 }
Defines and implements namespace algo with some algorithms.
Declares AngularSpecScan class.
#define ASSERT(condition)
Definition: Assert.h:31
Defines class ConstantBackground.
Defines class ConvolutionDetectorResolution.
Defines namespace DetectorUtils.
Defines class FootprintGauss.
Defines class FootprintSquare.
Defines class GISASSimulation.
Defines namespace node_progeny.
Defines class OffSpecularSimulation.
Defines namespace ParameterUtils.
Defines class PoissonNoiseBackground.
Defines namespace pyfmt2.
Defines functions in namespace pyfmt.
Defines functions in namespace pyfmt.
Declares QSpecScan class.
Defines classes representing ranged one-dimensional distributions.
Defines class RectangularDetector.
Defines class RegionOfInterest.
Defines class ResolutionFunction2DGaussian.
Defines class SampleToPython.
Defines scan resolution class.
Defines class SimulationToPython.
Defines class SpecularSimulation.
Defines class SphericalDetector.
Scan type with inclination angles as coordinate values and a unique wavelength.
virtual const IFootprintFactor * footprintFactor() const override
Returns IFootprintFactor object pointer.
const ScanResolution * wavelengthResolution() const
const ScanResolution * angleResolution() const
virtual const IAxis * coordinateAxis() const override
Returns coordinate axis assigned to the data holder.
double wavelength() const
double mag() const
Returns magnitude of the vector.
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
An incident neutron or x-ray beam.
Definition: Beam.h:27
Direction direction() const
Definition: Beam.h:45
double intensity() const
Returns the beam intensity in neutrons/sec.
Definition: Beam.h:42
double wavelength() const
Definition: Beam.h:43
kvector_t getBlochVector() const
Definition: Beam.cpp:122
Class representing a constant background signal.
Convolutes the intensity in 1 or 2 dimensions with a resolution function.
double analyzerEfficiency() const
will always return positive value
double analyzerTotalTransmission() const
kvector_t analyzerDirection() const
Retrieve the analyzer characteristics.
Collection of detector masks.
Definition: DetectorMask.h:28
const IShape2D * getMaskShape(size_t mask_index, bool &mask_value) const
size_t numberOfMasks() const
double phi() const
Definition: Direction.h:30
double alpha() const
Definition: Direction.h:29
const Distributions_t & getDistributions() const
Main class to run a Grazing-Incidence Small-Angle Scattering simulation.
Interface for detector resolution algorithms.
Abstract detector interface.
Definition: IDetector.h:36
virtual const DetectorMask * detectorMask() const =0
Returns detector masks container.
size_t dimension() const
Returns actual dimensionality of the detector (number of defined axes)
Definition: IDetector.cpp:46
const IDetectorResolution * detectorResolution() const
Returns a pointer to detector resolution object.
Definition: IDetector.cpp:138
virtual const RegionOfInterest * regionOfInterest() const =0
Returns region of interest if exists.
virtual Axes::Units defaultAxesUnits() const
Return default axes units.
Definition: IDetector.h:90
const DetectionProperties & detectionProperties() const
Returns detection properties.
Definition: IDetector.h:82
Abstract base for classes that calculate the beam footprint factor.
double widthRatio() const
virtual std::string name() const =0
Basic class for all shapes in 2D.
Definition: IShape2D.h:27
Abstract base class of OffSpecularSimulation, GISASSimulation and SpecularSimulation.
Definition: ISimulation.h:38
const DistributionHandler & getDistributionHandler() const
Definition: ISimulation.h:88
const IBackground * background() const
Definition: ISimulation.h:74
const MultiLayer * sample() const
const SimulationOptions & getOptions() const
Definition: ISimulation.h:91
IDetector * getDetector()
Definition: ISimulation.h:61
Beam & beam()
Definition: ISimulation.h:58
Abstract base class for all types of specular scans.
Definition: ISpecularScan.h:32
Main class to run an off-specular simulation.
const IAxis * beamAxis() const
Returns axis of the beam.
Class representing Poisson noise on top of the scattered intensity.
Scan type with z-components of scattering vector as coordinate values.
Definition: QSpecScan.h:28
virtual const IAxis * coordinateAxis() const override
Returns coordinate axis assigned to the data holder.
Definition: QSpecScan.h:50
const ScanResolution * resolution() const
Definition: QSpecScan.h:42
A flat rectangular detector with axes and resolution function.
double getYlow() const
double getYup() const
double getXlow() const
double getXup() const
Simple gaussian two-dimensional resolution function.
Generates Python code snippet from domain (C++) objects representing sample construction.
std::string sampleCode(const MultiLayer &multilayer)
Container for reflectivity resolution data.
virtual double delta() const =0
virtual std::string name() const =0
const IRangedDistribution * distribution() const
Collect the different options for simulation.
size_t getMcPoints() const
bool includeSpecular() const
unsigned getHardwareConcurrency() const
unsigned getNumberOfThreads() const
bool isIntegrate() const
bool useAvgMaterials() const
std::string simulationSaveCode(const ISimulation &simulation, const std::string &fname)
Returns a Python script that runs a simulation and saves the result to a file.
std::string simulationPlotCode(const ISimulation &simulation)
Returns a Python script that runs a simulation and plots the result.
Main class to run a specular simulation.
const ISpecularScan * dataHandler() const
Returns internal data handler.
A detector with coordinate axes along angles phi and alpha.
bool isQuadratic(const IDetector2D &det)
std::string poolParameterUnits(const IParametricComponent &node, const std::string &parName)
Returns units of main parameter.
bool almostEqual(double a, double b)
Returns true if two doubles agree within machine epsilon.
Definition: Algorithms.h:34
std::string printAxis(const IAxis *axis, const std::string &unit)
Prints an axis.
Definition: PyFmt2.cpp:115
std::string printDistribution(const IDistribution1D &par_distr, const std::string &units)
Prints distribution with constructor parameters in given units.
Definition: PyFmt2.cpp:137
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:40
std::string printRangedDistribution(const IRangedDistribution &distr)
Definition: PyFmt2.cpp:161
std::string printNm(double input)
Definition: PyFmt.cpp:74
std::string printDegrees(double input)
Definition: PyFmt.cpp:111
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 printImportedSymbols(const std::string &code)
Definition: PyFmt.cpp:24
std::string indent(size_t width)
Returns a string of blanks with given width.
Definition: PyFmt.cpp:155
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:60