48 std::function<std::string(
double)> printFunc(
const IDetector& detector)
54 throw std::runtime_error(
"SimulationToPython::defineMasks() -> Error. Unknown detector units.");
57 bool isQuadraticDetector(
const IDetector& det)
69 bool isDefaultDirection(
const R3 direction)
78 std::ostringstream result;
79 result <<
indent() <<
"footprint = ba." << foot.
name();
86 std::ostringstream result;
88 <<
indent() <<
"resolution = "
94 std::string defineAlphaScan(
const AlphaScan& scan)
96 std::ostringstream result;
98 <<
indent() <<
"# Define specular scan:\n"
105 result <<
indent() <<
"scan.setFootprintFactor(footprint)\n";
108 result << defineScanResolution(*r) <<
"\n";
109 result <<
indent() <<
"scan.setAngleResolution(resolution)\n";
112 result << defineScanResolution(*r) <<
"\n";
113 result <<
indent() <<
"scan.setWavelengthResolution(resolution)\n";
118 std::string defineQzScan(
const QzScan& scan)
120 std::ostringstream result;
121 const std::string axis_def =
indent() +
"axis = ";
125 result <<
indent() <<
"scan = ba.QzScan(axis)";
128 result << defineScanResolution(*scan.
resolution()) <<
"\n";
129 result <<
indent() <<
"scan.setQResolution(resolution)";
134 std::string definePolarizationAnalyzer(
const PolFilter& analyzer,
const std::string parent)
136 std::ostringstream result;
141 if (analyzer_direction.mag() > 0.0) {
142 std::string direction_name =
"analyzer_direction";
143 result <<
indent() << direction_name <<
" = R3("
147 result <<
indent() << parent <<
".setAnalyzer(" << direction_name <<
", "
156 if (
const auto* s =
dynamic_cast<const AlphaScan*
>(scan); s)
157 return defineAlphaScan(*s);
158 if (
const auto* s =
dynamic_cast<const QzScan*
>(scan); s)
159 return defineQzScan(*s);
166 if (detector.
rank() != 2)
167 throw std::runtime_error(
"defineDetector: "
168 "detector must be two-dimensional for GISAS");
169 std::ostringstream result;
170 result << std::setprecision(12);
174 result <<
indent() <<
"detector = ba.SphericalDetector(";
175 if (isQuadraticDetector(*det)) {
188 result <<
indent() <<
"detector = ba.RectangularDetector(" << det->xSize() <<
", "
192 result <<
indent() <<
"detector.setDetectorPosition("
196 if (!isDefaultDirection(det->getDirectionVector()))
200 result <<
indent() <<
"detector.setPerpendicularToSampleX("
204 }
else if (det->getDetectorArrangment()
206 result <<
indent() <<
"detector.setPerpendicularToDirectBeam("
210 }
else if (det->getDetectorArrangment()
212 result <<
indent() <<
"detector.setPerpendicularToReflectedBeam("
216 }
else if (det->getDetectorArrangment()
218 result <<
indent() <<
"detector.setPerpendicularToReflectedBeam("
220 result <<
indent() <<
"detector.setDirectBeamPosition("
224 throw std::runtime_error(
"defineDetector() -> Error. Unknown alignment.");
226 throw std::runtime_error(
"defineDetector() -> Error. Unknown detector");
230 result <<
indent() <<
"detector.setRegionOfInterest(" << printFunc(detector)(xBounds.first)
231 <<
", " << printFunc(detector)(yBounds.first) <<
", "
232 << printFunc(detector)(xBounds.second) <<
", " << printFunc(detector)(yBounds.second)
235 result << definePolarizationAnalyzer(detector.
analyzer(),
"detector");
239 std::string defineDetectorResolutionFunction(
const IDetector& detector)
241 std::ostringstream result;
246 convfunc->getResolutionFunction2D())) {
247 result <<
indent() <<
"simulation.detector().setResolutionFunction(";
248 result <<
"ba.ResolutionFunction2DGaussian(";
249 result << printFunc(detector)(resfunc->sigmaX()) <<
", ";
250 result << printFunc(detector)(resfunc->sigmaY()) <<
"))\n";
252 throw std::runtime_error(
"defineDetectorResolutionFunction() -> Error. "
253 "Unknown detector resolution function");
255 throw std::runtime_error(
"defineDetectorResolutionFunction() -> Error. "
256 "Not a ConvolutionDetectorResolution function");
261 std::string defineBeamPolarization(
const Beam& beam)
263 std::ostringstream result;
265 if (bloch_vector.mag() > 0.0) {
266 std::string beam_polMatrices =
"beam_polMatrices";
270 result <<
indent() <<
"beam.setPolarization(" << beam_polMatrices <<
")\n";
275 std::string defineBeamIntensity(
const Beam& beam)
277 std::ostringstream result;
278 double beam_intensity = beam.
intensity();
279 if (beam_intensity > 0.0)
280 result <<
indent() <<
"simulation.beam().setIntensity("
287 std::ostringstream result;
288 const Beam& beam = simulation.
beam();
295 result << defineBeamPolarization(beam);
302 std::ostringstream result;
303 const Beam& beam = simulation.
beam();
305 const std::string axidef =
indent() +
"alpha_i_axis = ";
312 result << defineBeamPolarization(beam);
313 result << defineBeamIntensity(beam);
319 std::ostringstream result;
322 throw std::runtime_error(
"Error defineSpecularScan: passed simulation "
323 "does not contain any scan");
324 result << defineScan(scan) <<
"\n";
327 result << definePolarizationAnalyzer(*analyzer,
"scan");
331 std::string defineParameterDistributions(
const ISimulation* simulation)
333 std::ostringstream result;
334 const std::vector<ParameterDistribution>& distributions = simulation->
getDistributions();
335 if (distributions.empty())
337 for (
size_t i = 0; i < distributions.size(); ++i) {
338 const std::string mainParUnits =
341 const std::string distr =
"distr_" + std::to_string(i + 1);
342 result <<
indent() << distr <<
" = "
343 <<
"ba." << distributions[i].getDistribution()->pythonConstructor(mainParUnits)
346 result <<
indent() <<
"simulation.addParameterDistribution(ba."
347 << distributions[i].whichParameterAsPyEnum() <<
", " << distr <<
", "
348 << distributions[i].nDraws() <<
", "
355 std::string defineMasks(
const IDetector& detector)
357 std::ostringstream result;
358 result << std::setprecision(12);
361 if (detectorMask && detectorMask->
hasMasks()) {
363 for (
size_t i_mask = 0; i_mask < detectorMask->
numberOfMasks(); ++i_mask) {
366 bool mask_value = pat->
doMask;
374 std::string defineSimulationOptions(
const ISimulation* simulation)
376 std::ostringstream result;
377 result << std::setprecision(12);
381 result <<
indent() <<
"simulation.options().setNumberOfThreads("
384 result <<
indent() <<
"simulation.options().setMonteCarloIntegration(True, "
387 result <<
indent() <<
"simulation.options().setUseAvgMaterials(True)\n";
389 result <<
indent() <<
"simulation.options().setIncludeSpecular(True)\n";
393 std::string defineBackground(
const ISimulation* simulation)
395 std::ostringstream result;
399 if (constant_bg->backgroundValue() > 0.0) {
400 result <<
indent() <<
"background = ba.ConstantBackground("
402 result <<
indent() <<
"simulation.setBackground(background)\n";
405 result <<
indent() <<
"background = ba.PoissonBackground()\n";
406 result <<
indent() <<
"simulation.setBackground(background)\n";
413 std::ostringstream result;
414 result << defineGISASBeam(*simulation);
415 result << defineDetector(simulation);
416 result <<
indent() <<
"simulation = ba.ScatteringSimulation(beam, sample, detector)\n";
417 result << defineDetectorResolutionFunction(simulation->
detector());
418 result << defineParameterDistributions(simulation);
419 result << defineMasks(simulation->
detector());
420 result << defineSimulationOptions(simulation);
421 result << defineBackground(simulation);
427 std::ostringstream result;
428 result <<
indent() <<
"simulation = ba.OffspecSimulation()\n";
429 result << defineDetector(simulation);
430 result << defineDetectorResolutionFunction(simulation->
detector());
431 result << defineOffspecBeam(*simulation);
432 result << defineParameterDistributions(simulation);
433 result << defineMasks(simulation->
detector());
434 result << defineSimulationOptions(simulation);
435 result << defineBackground(simulation);
441 std::ostringstream result;
442 result << defineSpecularScan(*simulation);
443 result <<
indent() <<
"simulation = ba.SpecularSimulation(scan, sample)\n";
444 result << defineParameterDistributions(simulation);
445 result << defineSimulationOptions(simulation);
446 result << defineBackground(simulation);
452 std::string defineSimulate(
const ISimulation* simulation)
454 std::ostringstream result;
455 result <<
"def get_simulation(sample):\n";
457 result << defineScatteringSimulation(gisas);
458 else if (
const auto* offspec =
dynamic_cast<const OffspecSimulation*
>(simulation))
459 result << defineOffspecSimulation(offspec);
461 result << defineSpecularSimulation(spec);
464 result <<
" return simulation\n\n\n";
469 std::string simulationCode(
const ISimulation& simulation)
471 if (simulation.
sample() ==
nullptr)
472 throw std::runtime_error(
"Cannot export: Simulation has no sample");
486 return simulationCode(simulation)
487 +
"if __name__ == '__main__':\n"
488 " from bornagain import ba_plot as bp\n"
490 " sample = get_sample()\n"
491 " simulation = get_simulation(sample)\n"
492 " result = simulation.simulate()\n"
493 " bp.plot_simulation_result(result)\n";
497 const std::string& fname)
499 return simulationCode(simulation)
500 +
"if __name__ == '__main__':\n"
501 " sample = get_sample()\n"
502 " simulation = get_simulation(sample)\n"
503 " result = simulation.simulate()\n"
504 " ba.IOFactory.writeSimulationResult(result, \""
Defines and implements namespace BaseUtils::algo with some algorithms.
Declares AlphaScan class.
Defines the macro ASSERT.
#define ASSERT(condition)
Defines class ConstantBackground.
Defines class ConvolutionDetectorResolution.
Defines class DetectorMask.
Defines classes representing one-dimensional distributions.
Defines collection of utility functions for INode.
Defines class PoissonBackground.
Defines namespace pyfmt2.
Defines classes representing ranged one-dimensional distributions.
Defines class RectangularDetector.
Defines class ResolutionFunction2DGaussian.
Defines class SampleToPython.
Defines scan resolution class.
Defines class SimulationOptions.
Defines class SimulationToPython.
Defines class SphericalDetector.
Scan type with inclination angles as coordinate values and a unique wavelength. Features footprint co...
const IAxis * coordinateAxis() const override
Returns coordinate axis assigned to the data holder.
const IFootprintFactor * footprintFactor() const override
Returns IFootprintFactor object pointer.
const ScanResolution * angleResolution() const
double wavelength() const override
const ScanResolution * wavelengthResolution() const
An incident neutron or x-ray beam.
Direction direction() const
double intensity() const
Returns the beam intensity in neutrons/sec.
double wavelength() const
R3 polVector() const
Returns polarization density as Bloch vector.
Constant background, to be added to simulated scattering.
Convolutes the intensity in 1 or 2 dimensions with a resolution function.
Collection of detector masks.
const MaskPattern * patternAt(size_t iMask) const
bool hasMasks() const
Returns true if has masks.
size_t numberOfMasks() const
double span() const
Returns distance from first to last point.
virtual double max() const =0
Returns value of last point of axis.
virtual double min() const =0
Returns value of first point of axis.
virtual size_t size() const =0
Returns the number of bins.
double center() const
Returns midpoint of axis.
Interface for detector resolution algorithms.
Abstract detector interface.
virtual Coords defaultCoords() const =0
Return default axes units.
const PolFilter & analyzer() const
Returns detection properties.
std::pair< double, double > regionOfInterestBounds(size_t iAxis) const
The lower and upper bound of the region of interest. If no region of interest is explicitly defined,...
const IAxis & axis(size_t index) const
One axis of the complete detector. Any region of interest is not taken into account.
bool hasExplicitRegionOfInterest() const
True if a region of interest is explicitly set.
const IDetectorResolution * detectorResolution() const
Returns a pointer to detector resolution object.
size_t rank() const
Returns number of defined axes.
const DetectorMask * detectorMask() const
Basic class for all shapes in 2D.
Abstract base class of simulations that generate 2D patterns.
Abstract base class, holds the infrastructure to run a simulation.
const IBackground * background() const
const MultiLayer * sample() const
const SimulationOptions & options() const
const std::vector< ParameterDistribution > & getDistributions() const
std::string unitOfParameter(ParameterDistribution::WhichParameter which) const
Abstract base class for all types of specular scans.
const PolFilter * analyzer() const
Off-specular scattering simulation.
const IAxis * beamAxis() const
Returns axis of the beam.
Poisson distributed noise, to be added to simulated scattering.
Detector properties (efficiency, transmission).
double totalTransmission() const
double analyzerEfficiency() const
will always return positive value
R3 analyzerDirection() const
Retrieve the analyzer characteristics.
Scan type with z-components of scattering vector as coordinate values. Wavelength and incident angles...
const IAxis * coordinateAxis() const override
Returns coordinate axis assigned to the data holder.
const ScanResolution * resolution() const
A flat rectangular detector with axes and resolution function.
@ PERPENDICULAR_TO_DIRECT_BEAM
@ PERPENDICULAR_TO_SAMPLE
@ PERPENDICULAR_TO_REFLECTED_BEAM_DPOS
@ PERPENDICULAR_TO_REFLECTED_BEAM
Simple gaussian two-dimensional resolution function.
Generates Python code snippet from domain (C++) objects representing sample construction.
std::string sampleCode(const MultiLayer &sample)
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.SimulationOptions.
size_t getMcPoints() const
bool includeSpecular() const
unsigned getHardwareConcurrency() const
unsigned getNumberOfThreads() 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.
Specular reflectometry simulation.
const ISpecularScan * scan() const
Returns internal data handler.
A detector with coordinate axes along angles phi and alpha.
Includes all leave classes below ISimulation.
bool almostEqual(double a, double b)
Returns true if two doubles agree within machine epsilon.
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 "simulate".
std::string printRangedDistribution(const IRangedDistribution &distr)
std::string printAxis(const IAxis *axis, const std::string &unit)
Prints an axis.
std::string printDegrees(double input)
std::string printDouble(double input)
std::string printKvector(const R3 value)
std::string printScientificDouble(double input)
std::string printNm(double input)
std::string printRealLimitsArg(const RealLimits &limits, const std::string &units)
Prints RealLimits in the form of argument (in the context of ParameterDistribution and similar)....
std::string indent(size_t width)
Returns a string of blanks with given width. By default the width equals standard offset in python fi...
std::string printImportedSymbols(const std::string &code)