BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
OffspecSimulation Class Reference

Description

Off-specular scattering simulation.

Holds an instrument and sample model. Computes reflected and scattered intensity as function of incident and final glancing angle.

Definition at line 30 of file OffspecSimulation.h.

Inheritance diagram for OffspecSimulation:
[legend]
Collaboration diagram for OffspecSimulation:
[legend]

Public Member Functions

 OffspecSimulation (const Beam &beam, const MultiLayer &sample, const IDetector &detector)
 
 OffspecSimulation (const MultiLayer &sample)
 
 ~OffspecSimulation () override=default
 
void addMask (const IShape2D &shape, bool mask_value=true)
 Adds mask of given shape to the stack of detector masks. The mask value 'true' means that the channel will be excluded from the simulation. The mask which is added last has priority. More...
 
void addParameterDistribution (const ParameterDistribution &par_distr)
 
void addParameterDistribution (ParameterDistribution::WhichParameter whichParameter, const IDistribution1D &distribution, size_t nbr_samples, double sigma_factor=0.0, const RealLimits &limits=RealLimits())
 
const IBackgroundbackground () const
 
Beambeam ()
 
const Beambeam () const
 
const IAxisbeamAxis () const
 Returns axis of the beam. More...
 
void checkNodeArgs () const
 Raises exception if a parameter value is invalid. More...
 
std::string className () const final
 Returns the class name, to be hard-coded in each leaf class that inherits from INode. More...
 
ICoordSystemcreateCoordSystem () const override
 
IDetectordetector ()
 
const IDetectordetector () const
 
bool force_polarized () const override
 Force polarized computation even in absence of sample magnetization or external fields. More...
 
const IDetectorgetDetector () const
 
const std::vector< ParameterDistribution > & getDistributions () const
 
size_t intensityMapSize () const override
 Returns the total number of the intensity values in the simulation result. More...
 
void maskAll ()
 Put the mask for all detector channels (i.e. exclude whole detector from the analysis) More...
 
std::vector< const INode * > nodeChildren () const override
 Returns all children. More...
 
std::vector< const INode * > nodeOffspring () const
 Returns all descendants. More...
 
SimulationOptionsoptions ()
 
const SimulationOptionsoptions () const
 
virtual std::vector< ParaMetaparDefs () const
 Returns the parameter definitions, to be hard-coded in each leaf class. More...
 
const MultiLayersample () const
 
void setBackground (const IBackground &bg)
 
void setBeamParameters (double wavelength, const IAxis &alpha_axis, double phi_i)
 Sets beam parameters from here (forwarded to Instrument) More...
 
void setRegionOfInterest (double xlow, double ylow, double xup, double yup)
 Sets rectangular region of interest with lower left and upper right corners defined. More...
 
void setTerminalProgressMonitor ()
 Initializes a progress monitor that prints to stdout. More...
 
SimulationResult simulate ()
 Run a simulation, and return the result. More...
 
void subscribe (const std::function< bool(size_t)> &inform)
 
std::string unitOfParameter (ParameterDistribution::WhichParameter which) const
 

Protected Member Functions

void addBackgroundIntensity (size_t start_ind, size_t n_elements) override
 
void addDataToCache (double weight) override
 
std::unique_ptr< IComputationcreateComputation (const reSample &re_sample, size_t start, size_t n_elements) override
 Generate a single threaded computation for a given range of simulation elements. More...
 
std::vector< std::unique_ptr< DiffuseElement > > generateElements (const Beam &beam)
 Generate simulation elements for given beam. More...
 
virtual void initCoordSystem ()
 
void initDistributionHandler () override
 init callbacks for setting the parameter values More...
 
void moveDataFromCache () override
 
void normalize (size_t start_ind, size_t n_elements) override
 Normalize the detector counts to beam intensity, to solid angle, and to exposure angle. More...
 
ProgressHandlerprogress ()
 

Protected Attributes

std::unique_ptr< Beamm_beam
 
std::vector< double > m_cache
 
std::unique_ptr< IDetectorm_detector
 
DistributionHandler m_distribution_handler
 
std::vector< std::unique_ptr< DiffuseElement > > m_eles
 
std::vector< double > m_P
 

Private Member Functions

void checkInitialization () const
 Check correct number of axes. More...
 
void initElementVector () override
 Initializes the vector of ISimulation elements. More...
 
size_t numberOfElements () const override
 Gets the number of elements this simulation needs to calculate. More...
 
SimulationResult pack_result () override
 Sets m_result. More...
 
void prepareSimulation () override
 Put into a clean state for running a simulation. More...
 
void runSingleSimulation (const reSample &re_sample, size_t batch_start, size_t batch_size, double weight=1.0)
 Runs a single simulation with fixed parameter values. If desired, the simulation is run in several threads. More...
 
void transferDetectorImage (size_t index)
 Normalize, apply detector resolution and transfer detector image corresponding to alpha_i = m_alpha_i_axis->bin(index) More...
 
void updateIntensityMap () override
 Default implementation only adds the detector axes. More...
 
void validateParametrization (const ParameterDistribution &par_distr) const override
 Checks the distribution validity for simulation. More...
 

Private Attributes

std::unique_ptr< IAxism_alpha_i_axis
 
std::shared_ptr< IBackgroundm_background
 
std::unique_ptr< DetectorContextm_detector_context
 
std::unique_ptr< Datafieldm_intensity_map
 
std::shared_ptr< SimulationOptionsm_options
 
std::shared_ptr< ProgressHandlerm_progress
 
std::shared_ptr< MultiLayerm_sample
 

Constructor & Destructor Documentation

◆ OffspecSimulation() [1/2]

OffspecSimulation::OffspecSimulation ( const Beam beam,
const MultiLayer sample,
const IDetector detector 
)

Definition at line 29 of file OffspecSimulation.cpp.

32 {
33 }
IDetector & detector()
Definition: ISimulation2D.h:58
Beam & beam()
Definition: ISimulation2D.h:57
ISimulation2D(const Beam &beam, const MultiLayer &sample, const IDetector &detector)
const MultiLayer * sample() const

◆ OffspecSimulation() [2/2]

OffspecSimulation::OffspecSimulation ( const MultiLayer sample)

Definition at line 35 of file OffspecSimulation.cpp.

37 {
38 }

◆ ~OffspecSimulation()

OffspecSimulation::~OffspecSimulation ( )
overridedefault

Member Function Documentation

◆ addBackgroundIntensity()

void ISimulation2D::addBackgroundIntensity ( size_t  start_ind,
size_t  n_elements 
)
overrideprotectedvirtualinherited

Implements ISimulation.

Definition at line 124 of file ISimulation2D.cpp.

125 {
126  if (!background())
127  return;
128  for (size_t i = start_ind, stop_point = start_ind + n_elements; i < stop_point; ++i) {
129  DiffuseElement& element = *m_eles[i];
130  element.setIntensity(background()->addBackground(element.intensity()));
131  }
132 }
Data stucture containing both input and output of a single detector cell.
double intensity() const
void setIntensity(double intensity)
std::vector< std::unique_ptr< DiffuseElement > > m_eles
const IBackground * background() const
Definition: ISimulation.h:76

References ISimulation::background(), DiffuseElement::intensity(), ISimulation2D::m_eles, and DiffuseElement::setIntensity().

Here is the call graph for this function:

◆ addDataToCache()

void ISimulation2D::addDataToCache ( double  weight)
overrideprotectedvirtualinherited

Implements ISimulation.

Definition at line 134 of file ISimulation2D.cpp.

135 {
136  if (m_eles.size() != m_cache.size())
137  throw std::runtime_error("Error in ISimulation2D::addDataToCache(double): cache size"
138  " not the same as element size");
139  for (unsigned i = 0; i < m_eles.size(); i++)
140  m_cache[i] += m_eles[i]->intensity() * weight;
141 }
std::vector< double > m_cache

References ISimulation2D::m_cache, and ISimulation2D::m_eles.

◆ addMask()

void ISimulation2D::addMask ( const IShape2D shape,
bool  mask_value = true 
)
inherited

Adds mask of given shape to the stack of detector masks. The mask value 'true' means that the channel will be excluded from the simulation. The mask which is added last has priority.

Parameters
shapeThe shape of mask (Rectangle, Polygon, Line, Ellipse)
mask_valueThe value of mask

Definition at line 56 of file ISimulation2D.cpp.

57 {
58  detector().addMask(shape, mask_value);
59 }
void addMask(const IShape2D &shape, bool mask_value=true)
Adds mask of given shape to the stack of detector masks. The mask value 'true' means that the channel...
Definition: IDetector.cpp:360

References IDetector::addMask(), and ISimulation2D::detector().

Here is the call graph for this function:

◆ addParameterDistribution() [1/2]

void ISimulation::addParameterDistribution ( const ParameterDistribution par_distr)
inherited

Definition at line 231 of file ISimulation.cpp.

232 {
233  validateParametrization(par_distr);
235 }
void addParameterDistribution(const std::string &param_name, const IDistribution1D &distribution, size_t nbr_samples, double sigma_factor=0.0, const RealLimits &limits=RealLimits())
add a sampled parameter distribution
virtual void validateParametrization(const ParameterDistribution &) const
Checks the distribution validity for simulation.
Definition: ISimulation.h:120
DistributionHandler m_distribution_handler
Definition: ISimulation.h:104

References DistributionHandler::addParameterDistribution(), ISimulation::m_distribution_handler, and ISimulation::validateParametrization().

Here is the call graph for this function:

◆ addParameterDistribution() [2/2]

void ISimulation::addParameterDistribution ( ParameterDistribution::WhichParameter  whichParameter,
const IDistribution1D distribution,
size_t  nbr_samples,
double  sigma_factor = 0.0,
const RealLimits limits = RealLimits() 
)
inherited

Definition at line 222 of file ISimulation.cpp.

225 {
226  ParameterDistribution par_distr(whichParameter, distribution, nbr_samples, sigma_factor,
227  limits);
228  addParameterDistribution(par_distr);
229 }
void addParameterDistribution(ParameterDistribution::WhichParameter whichParameter, const IDistribution1D &distribution, size_t nbr_samples, double sigma_factor=0.0, const RealLimits &limits=RealLimits())
A parametric distribution function, for use with any model parameter.

◆ background()

const IBackground* ISimulation::background ( ) const
inlineinherited

◆ beam() [1/2]

◆ beam() [2/2]

const Beam& ISimulation2D::beam ( ) const
inlineinherited

Definition at line 62 of file ISimulation2D.h.

62 { return *m_beam; }

References ISimulation2D::m_beam.

◆ beamAxis()

const IAxis * OffspecSimulation::beamAxis ( ) const

Returns axis of the beam.

Definition at line 78 of file OffspecSimulation.cpp.

79 {
80  return m_alpha_i_axis.get();
81 }
std::unique_ptr< IAxis > m_alpha_i_axis

References m_alpha_i_axis.

Referenced by createCoordSystem().

◆ checkInitialization()

void OffspecSimulation::checkInitialization ( ) const
private

Check correct number of axes.

Definition at line 155 of file OffspecSimulation.cpp.

156 {
158  ASSERT(m_alpha_i_axis->size() >= 1);
159  ASSERT(detector().rank() == 2);
160 }
#define ASSERT(condition)
Definition: Assert.h:45

References ASSERT, ISimulation2D::detector(), and m_alpha_i_axis.

Referenced by intensityMapSize(), numberOfElements(), pack_result(), and prepareSimulation().

Here is the call graph for this function:

◆ checkNodeArgs()

void INode::checkNodeArgs ( ) const
inherited

Raises exception if a parameter value is invalid.

Definition at line 27 of file INode.cpp.

28 {
29  size_t nP = m_P.size();
30  if (parDefs().size() != nP) {
31  std::cerr << "BUG in class " << className() << std::endl;
32  std::cerr << "#m_P = " << nP << std::endl;
33  std::cerr << "#PDf = " << parDefs().size() << std::endl;
34  for (const ParaMeta& pm : parDefs())
35  std::cerr << " PDf: " << pm.name << std::endl;
36  ASSERT(0);
37  }
38  ASSERT(parDefs().size() == nP);
39  for (size_t i = 0; i < nP; ++i) {
40  const ParaMeta pm = parDefs()[i];
41 
43  if (pm.vMin == -INF) {
44  ASSERT(pm.vMax == +INF);
45  // nothing to do
46  } else if (pm.vMax == +INF) {
47  ASSERT(pm.vMin == 0);
48  limits = RealLimits::nonnegative();
49  } else {
50  limits = RealLimits::limited(pm.vMin, pm.vMax);
51  }
52  limits.check(pm.name, m_P[i]);
53  }
54 }
const double INF
Definition: INode.h:26
virtual std::vector< ParaMeta > parDefs() const
Returns the parameter definitions, to be hard-coded in each leaf class.
Definition: INode.h:51
std::vector< double > m_P
Definition: INode.h:63
virtual std::string className() const =0
Returns the class name, to be hard-coded in each leaf class that inherits from INode.
Limits for a real fit parameter.
Definition: RealLimits.h:24
static RealLimits limitless()
Creates an object without bounds (default)
Definition: RealLimits.cpp:139
void check(const std::string &name, double value) const
Throws if value is outside limits. Parameter 'name' is for exception message.
Definition: RealLimits.cpp:170
static RealLimits nonnegative()
Creates an object which can have only positive values with 0. included.
Definition: RealLimits.cpp:124
static RealLimits limited(double left_bound_value, double right_bound_value)
Creates an object bounded from the left and right.
Definition: RealLimits.cpp:134
Metadata of one model parameter.
Definition: INode.h:29
double vMin
Definition: INode.h:33
double vMax
Definition: INode.h:34
std::string name
Definition: INode.h:30

References ASSERT, RealLimits::check(), INode::className(), INF, RealLimits::limited(), RealLimits::limitless(), INode::m_P, ParaMeta::name, RealLimits::nonnegative(), INode::parDefs(), ParaMeta::vMax, and ParaMeta::vMin.

Referenced by BarGauss::BarGauss(), BarLorentz::BarLorentz(), Bipyramid4::Bipyramid4(), Box::Box(), CantellatedCube::CantellatedCube(), Cone::Cone(), ConstantBackground::ConstantBackground(), CosineRippleBox::CosineRippleBox(), CosineRippleGauss::CosineRippleGauss(), CosineRippleLorentz::CosineRippleLorentz(), Cylinder::Cylinder(), DistributionCosine::DistributionCosine(), DistributionGate::DistributionGate(), DistributionGaussian::DistributionGaussian(), DistributionLogNormal::DistributionLogNormal(), DistributionLorentz::DistributionLorentz(), DistributionTrapezoid::DistributionTrapezoid(), Dodecahedron::Dodecahedron(), EllipsoidalCylinder::EllipsoidalCylinder(), FootprintGauss::FootprintGauss(), FootprintSquare::FootprintSquare(), FuzzySphere::FuzzySphere(), GaussSphere::GaussSphere(), HemiEllipsoid::HemiEllipsoid(), HollowSphere::HollowSphere(), HorizontalCylinder::HorizontalCylinder(), Icosahedron::Icosahedron(), LongBoxGauss::LongBoxGauss(), LongBoxLorentz::LongBoxLorentz(), PlatonicOctahedron::PlatonicOctahedron(), PlatonicTetrahedron::PlatonicTetrahedron(), Prism3::Prism3(), Prism6::Prism6(), Profile1DCauchy::Profile1DCauchy(), Profile1DCosine::Profile1DCosine(), Profile1DGate::Profile1DGate(), Profile1DGauss::Profile1DGauss(), Profile1DTriangle::Profile1DTriangle(), Profile1DVoigt::Profile1DVoigt(), Profile2DCauchy::Profile2DCauchy(), Profile2DCone::Profile2DCone(), Profile2DGate::Profile2DGate(), Profile2DGauss::Profile2DGauss(), Profile2DVoigt::Profile2DVoigt(), Pyramid2::Pyramid2(), Pyramid3::Pyramid3(), Pyramid4::Pyramid4(), Pyramid6::Pyramid6(), RotationEuler::RotationEuler(), RotationX::RotationX(), RotationY::RotationY(), RotationZ::RotationZ(), SawtoothRippleBox::SawtoothRippleBox(), SawtoothRippleGauss::SawtoothRippleGauss(), SawtoothRippleLorentz::SawtoothRippleLorentz(), Sphere::Sphere(), Spheroid::Spheroid(), TruncatedCube::TruncatedCube(), TruncatedSphere::TruncatedSphere(), and TruncatedSpheroid::TruncatedSpheroid().

Here is the call graph for this function:

◆ className()

std::string OffspecSimulation::className ( ) const
inlinefinalvirtual

Returns the class name, to be hard-coded in each leaf class that inherits from INode.

Implements INode.

Definition at line 36 of file OffspecSimulation.h.

36 { return "OffspecSimulation"; }

◆ createComputation()

std::unique_ptr< IComputation > ISimulation2D::createComputation ( const reSample re_sample,
size_t  start,
size_t  n_elements 
)
overrideprotectedvirtualinherited

Generate a single threaded computation for a given range of simulation elements.

Parameters
re_samplePreprocessed version of our sample
startIndex of the first element to include into computation
n_elementsNumber of elements to process

Implements ISimulation.

Definition at line 78 of file ISimulation2D.cpp.

80 {
81  ASSERT(start < m_eles.size() && start + n_elements <= m_eles.size());
82  const auto& begin = m_eles.begin() + static_cast<long>(start);
83  return std::make_unique<DWBAComputation>(re_sample, options(), progress(), begin,
84  begin + static_cast<long>(n_elements));
85 }
ProgressHandler & progress()
const SimulationOptions & options() const

References ASSERT, ISimulation2D::m_eles, ISimulation::options(), and ISimulation::progress().

Here is the call graph for this function:

◆ createCoordSystem()

ICoordSystem * OffspecSimulation::createCoordSystem ( ) const
overridevirtual

Implements ISimulation.

Definition at line 84 of file OffspecSimulation.cpp.

85 {
86  ASSERT(beamAxis());
87  return detector().offspecCoords(beamAxis()->clone(), beam().direction());
88 }
virtual ICoordSystem * offspecCoords(IAxis *beamAxis, const Direction &beamDirection) const =0
const IAxis * beamAxis() const
Returns axis of the beam.

References ASSERT, ISimulation2D::beam(), beamAxis(), ISimulation2D::detector(), and IDetector::offspecCoords().

Referenced by pack_result().

Here is the call graph for this function:

◆ detector() [1/2]

◆ detector() [2/2]

const IDetector& ISimulation2D::detector ( ) const
inlineinherited

Definition at line 63 of file ISimulation2D.h.

63 { return *m_detector; }

References ISimulation2D::m_detector.

◆ force_polarized()

bool ISimulation2D::force_polarized ( ) const
overridevirtualinherited

Force polarized computation even in absence of sample magnetization or external fields.

Implements ISimulation.

Definition at line 153 of file ISimulation2D.cpp.

154 {
155  return detector().analyzer().analyzerDirection() != R3{};
156 }
const PolFilter & analyzer() const
Returns detection properties.
Definition: IDetector.h:204
R3 analyzerDirection() const
Retrieve the analyzer characteristics.
Definition: PolFilter.cpp:48

References IDetector::analyzer(), PolFilter::analyzerDirection(), and ISimulation2D::detector().

Here is the call graph for this function:

◆ generateElements()

std::vector< std::unique_ptr< DiffuseElement > > ISimulation2D::generateElements ( const Beam beam)
protectedinherited

Generate simulation elements for given beam.

Definition at line 87 of file ISimulation2D.cpp.

88 {
89  const double wavelength = beam.wavelength();
90  const double alpha_i = -beam.direction().alpha(); // Defined to be always positive in Beam
91  const double phi_i = beam.direction().phi();
92  const SpinMatrix beam_polMatrices = beam.polMatrix();
93 
94  const SpinMatrix analyzer_operator = detector().analyzer().matrix();
95  const size_t spec_index = detector().indexOfSpecular(beam);
96 
97  const size_t N = m_detector_context->numberOfElements();
98 
99  std::vector<std::unique_ptr<DiffuseElement>> result;
100  result.reserve(N);
101  for (size_t element_index = 0; element_index < N; ++element_index)
102  result.emplace_back(std::make_unique<DiffuseElement>(
103  wavelength, alpha_i, phi_i, m_detector_context->createPixel(element_index),
104  beam_polMatrices, analyzer_operator,
105  m_detector_context->detectorIndex(element_index) == spec_index));
106  return result;
107 }
Direction direction() const
Definition: Beam.h:46
double wavelength() const
Definition: Beam.h:44
SpinMatrix polMatrix() const
Returns the polarization density matrix (in spin basis along z-axis)
Definition: Beam.cpp:155
double phi() const
Definition: Direction.h:37
double alpha() const
Definition: Direction.h:36
virtual size_t indexOfSpecular(const Beam &beam) const =0
Returns index of pixel that contains the specular wavevector. If no pixel contains this specular wave...
std::unique_ptr< DetectorContext > m_detector_context
SpinMatrix matrix() const
Return the polarization density matrix (in spin basis along z-axis)
Definition: PolFilter.cpp:40
#define N
Definition: mixmax.h:31

References Direction::alpha(), IDetector::analyzer(), ISimulation2D::beam(), ISimulation2D::detector(), Beam::direction(), IDetector::indexOfSpecular(), ISimulation2D::m_detector_context, PolFilter::matrix(), N, Direction::phi(), Beam::polMatrix(), and Beam::wavelength().

Referenced by initElementVector(), and ScatteringSimulation::initElementVector().

Here is the call graph for this function:

◆ getDetector()

const IDetector* ISimulation2D::getDetector ( ) const
inlineinherited

Definition at line 64 of file ISimulation2D.h.

64 { return m_detector.get(); }

References ISimulation2D::m_detector.

Referenced by ScatteringSimulation::createCoordSystem().

◆ getDistributions()

const std::vector< ParameterDistribution > & ISimulation::getDistributions ( ) const
inherited

Definition at line 237 of file ISimulation.cpp.

238 {
240 }
const std::vector< ParameterDistribution > & getDistributions() const

References DistributionHandler::getDistributions(), and ISimulation::m_distribution_handler.

Here is the call graph for this function:

◆ initCoordSystem()

virtual void ISimulation2D::initCoordSystem ( )
inlineprotectedvirtualinherited

Definition at line 70 of file ISimulation2D.h.

70 {}

◆ initDistributionHandler()

void ISimulation2D::initDistributionHandler ( )
overrideprotectedvirtualinherited

init callbacks for setting the parameter values

Reimplemented from ISimulation.

Definition at line 159 of file ISimulation2D.cpp.

160 {
161  for (const auto& distribution : m_distribution_handler.getDistributions()) {
162  const auto* dc = const_cast<ParameterDistribution*>(&distribution);
163 
164  switch (dc->whichParameter()) {
167  dc, [&](double d) { beam().setAzimuthalAngleGuarded(d); });
168  break;
171  dc, [&](double d) { beam().setInclinationAngleGuarded(d); });
172  break;
175  dc, [&](double d) { beam().setWavelengthGuarded(d); });
176  break;
177  default:
178  ASSERT(0);
179  }
180  }
181 }
void setAzimuthalAngleGuarded(double value)
Check for limits, set the value if within limits. Throws if limits are violated.
Definition: Beam.cpp:123
void setInclinationAngleGuarded(double value)
Check for limits, set the value if within limits. Throws if limits are violated.
Definition: Beam.cpp:117
void setWavelengthGuarded(double value)
Check for limits, set the value if within limits. Throws if limits are violated.
Definition: Beam.cpp:129
void defineCallbackForDistribution(const ParameterDistribution *distribution, std::function< void(double)> fn)

References ASSERT, ISimulation2D::beam(), ParameterDistribution::BeamAzimuthalAngle, ParameterDistribution::BeamInclinationAngle, ParameterDistribution::BeamWavelength, DistributionHandler::defineCallbackForDistribution(), DistributionHandler::getDistributions(), ISimulation::m_distribution_handler, Beam::setAzimuthalAngleGuarded(), Beam::setInclinationAngleGuarded(), and Beam::setWavelengthGuarded().

Here is the call graph for this function:

◆ initElementVector()

void OffspecSimulation::initElementVector ( )
overrideprivatevirtual

Initializes the vector of ISimulation elements.

Implements ISimulation.

Definition at line 97 of file OffspecSimulation.cpp.

98 {
99  m_eles.clear();
100  Beam beam2 = beam();
101  for (size_t i = 0; i < m_alpha_i_axis->size(); ++i) {
102  beam2.setInclination(m_alpha_i_axis->bin(i).center());
103  std::vector<std::unique_ptr<DiffuseElement>> eles_i = generateElements(beam2);
104  for (auto&& ele : eles_i)
105  m_eles.emplace_back(std::move(ele));
106  }
107  if (m_cache.empty())
108  m_cache.resize(m_eles.size(), 0.0);
109 }
An incident neutron or x-ray beam.
Definition: Beam.h:28
void setInclination(double alpha)
Definition: Beam.cpp:102
std::vector< std::unique_ptr< DiffuseElement > > generateElements(const Beam &beam)
Generate simulation elements for given beam.

References ISimulation2D::beam(), ISimulation2D::generateElements(), m_alpha_i_axis, ISimulation2D::m_cache, ISimulation2D::m_eles, and Beam::setInclination().

Here is the call graph for this function:

◆ intensityMapSize()

size_t OffspecSimulation::intensityMapSize ( ) const
overridevirtual

Returns the total number of the intensity values in the simulation result.

Implements ISimulation.

Definition at line 91 of file OffspecSimulation.cpp.

92 {
94  return m_alpha_i_axis->size() * detector().axis(1).size();
95 }
virtual size_t size() const =0
Returns the number of bins.
const IAxis & axis(size_t index) const
One axis of the complete detector. Any region of interest is not taken into account.
Definition: IDetector.cpp:74
void checkInitialization() const
Check correct number of axes.

References IDetector::axis(), checkInitialization(), ISimulation2D::detector(), m_alpha_i_axis, and IAxis::size().

Here is the call graph for this function:

◆ maskAll()

void ISimulation2D::maskAll ( )
inherited

Put the mask for all detector channels (i.e. exclude whole detector from the analysis)

Definition at line 61 of file ISimulation2D.cpp.

62 {
63  detector().maskAll();
64 }
void maskAll()
Put the mask for all detector channels (i.e. exclude whole detector from the analysis)
Definition: IDetector.cpp:365

References ISimulation2D::detector(), and IDetector::maskAll().

Here is the call graph for this function:

◆ moveDataFromCache()

void ISimulation2D::moveDataFromCache ( )
overrideprotectedvirtualinherited

Implements ISimulation.

Definition at line 143 of file ISimulation2D.cpp.

144 {
145  ASSERT(!m_cache.empty());
146  if (!m_cache.empty()) {
147  for (unsigned i = 0; i < m_eles.size(); i++)
148  m_eles[i]->setIntensity(m_cache[i]);
149  m_cache.clear();
150  }
151 }

References ASSERT, ISimulation2D::m_cache, and ISimulation2D::m_eles.

◆ nodeChildren()

std::vector< const INode * > ISimulation2D::nodeChildren ( ) const
overridevirtualinherited

Returns all children.

Reimplemented from ISimulation.

Definition at line 42 of file ISimulation2D.cpp.

43 {
44  std::vector<const INode*> result = ISimulation::nodeChildren();
45  result.push_back(m_beam.get());
46  if (m_detector)
47  result.push_back(m_detector.get());
48  return result;
49 }
std::vector< const INode * > nodeChildren() const override
Returns all children.

References ISimulation2D::m_beam, ISimulation2D::m_detector, and ISimulation::nodeChildren().

Here is the call graph for this function:

◆ nodeOffspring()

std::vector< const INode * > INode::nodeOffspring ( ) const
inherited

Returns all descendants.

Definition at line 61 of file INode.cpp.

62 {
63  std::vector<const INode*> result;
64  result.push_back(this);
65  for (const auto* child : nodeChildren()) {
66  for (const auto* p : child->nodeOffspring())
67  result.push_back(p);
68  }
69  return result;
70 }
virtual std::vector< const INode * > nodeChildren() const
Returns all children.
Definition: INode.cpp:56

References INode::nodeChildren().

Here is the call graph for this function:

◆ normalize()

void ISimulation2D::normalize ( size_t  start_ind,
size_t  n_elements 
)
overrideprotectedvirtualinherited

Normalize the detector counts to beam intensity, to solid angle, and to exposure angle.

Parameters
start_indIndex of the first element to operate on
n_elementsNumber of elements to process

Implements ISimulation.

Definition at line 109 of file ISimulation2D.cpp.

110 {
111  const double beam_intensity = beam().intensity();
112  for (size_t i = start_ind, stop_point = start_ind + n_elements; i < stop_point; ++i) {
113  DiffuseElement& element = *m_eles[i];
114  double sin_alpha_i = std::abs(std::sin(element.alphaI()));
115  if (sin_alpha_i == 0.0) {
116  element.setIntensity(0);
117  continue;
118  }
119  const double solid_angle = element.solidAngle();
120  element.setIntensity(element.intensity() * beam_intensity * solid_angle / sin_alpha_i);
121  }
122 }
double intensity() const
Returns the beam intensity in neutrons/sec.
Definition: Beam.h:43
double alphaI() const
double solidAngle() const

References DiffuseElement::alphaI(), ISimulation2D::beam(), Beam::intensity(), DiffuseElement::intensity(), ISimulation2D::m_eles, DiffuseElement::setIntensity(), and DiffuseElement::solidAngle().

Here is the call graph for this function:

◆ numberOfElements()

size_t OffspecSimulation::numberOfElements ( ) const
overrideprivatevirtual

Gets the number of elements this simulation needs to calculate.

Reimplemented from ISimulation2D.

Definition at line 46 of file OffspecSimulation.cpp.

47 {
50 }
size_t numberOfElements() const override
Gets the number of elements this simulation needs to calculate.

References checkInitialization(), m_alpha_i_axis, and ISimulation2D::numberOfElements().

Here is the call graph for this function:

◆ options() [1/2]

SimulationOptions & ISimulation::options ( )
inherited

Definition at line 123 of file ISimulation.cpp.

124 {
125  ASSERT(m_options);
126  return *m_options;
127 }
std::shared_ptr< SimulationOptions > m_options
Definition: ISimulation.h:135

References ASSERT, and ISimulation::m_options.

◆ options() [2/2]

const SimulationOptions & ISimulation::options ( ) const
inherited

◆ pack_result()

SimulationResult OffspecSimulation::pack_result ( )
overrideprivatevirtual

Sets m_result.

Implements ISimulation.

Definition at line 52 of file OffspecSimulation.cpp.

53 {
55  const IAxis& phi_axis = detector().axis(0);
56  size_t phi_f_size = phi_axis.size();
57  ASSERT(phi_f_size * m_intensity_map->size() == m_eles.size());
58  for (size_t i = 0; i < m_alpha_i_axis->size(); ++i)
60 
61  auto data = std::unique_ptr<Datafield>(m_intensity_map->clone());
62  std::unique_ptr<ICoordSystem> coordsSystem(createCoordSystem());
63  return {*data, *coordsSystem};
64 }
Abstract base class for one-dimensional axes.
Definition: IAxis.h:27
std::unique_ptr< Datafield > m_intensity_map
void transferDetectorImage(size_t index)
Normalize, apply detector resolution and transfer detector image corresponding to alpha_i = m_alpha_i...
ICoordSystem * createCoordSystem() const override

References ASSERT, IDetector::axis(), checkInitialization(), createCoordSystem(), ISimulation2D::detector(), m_alpha_i_axis, ISimulation2D::m_eles, m_intensity_map, IAxis::size(), and transferDetectorImage().

Here is the call graph for this function:

◆ parDefs()

virtual std::vector<ParaMeta> INode::parDefs ( ) const
inlinevirtualinherited

Returns the parameter definitions, to be hard-coded in each leaf class.

Reimplemented in ConstantBackground, GaussSphere, FuzzySphere, RotationEuler, RotationZ, RotationY, RotationX, Crystal, Layer, HexagonalLattice2D, SquareLattice2D, BasicLattice2D, LayerRoughness, TruncatedSpheroid, TruncatedSphere, TruncatedCube, Spheroid, Sphere, SawtoothRippleLorentz, SawtoothRippleGauss, SawtoothRippleBox, Pyramid6, Pyramid4, Pyramid3, Pyramid2, Prism6, Prism3, PlatonicTetrahedron, PlatonicOctahedron, LongBoxLorentz, LongBoxGauss, Icosahedron, HorizontalCylinder, HollowSphere, HemiEllipsoid, EllipsoidalCylinder, Dodecahedron, Cylinder, CosineRippleLorentz, CosineRippleGauss, CosineRippleBox, Cone, CantellatedCube, Box, Bipyramid4, BarLorentz, BarGauss, Profile2DVoigt, Profile2DCone, Profile2DGate, Profile2DGauss, Profile2DCauchy, Profile1DVoigt, Profile1DCosine, Profile1DTriangle, Profile1DGate, Profile1DGauss, Profile1DCauchy, MisesGaussPeakShape, MisesFisherGaussPeakShape, LorentzFisherPeakShape, GaussFisherPeakShape, IsotropicLorentzPeakShape, IsotropicGaussPeakShape, ParticleLayout, InterferenceTwin, InterferenceRadialParaCrystal, InterferenceHardDisk, Interference2DSuperLattice, Interference2DParaCrystal, Interference1DLattice, DistributionTrapezoid, DistributionCosine, DistributionLogNormal, DistributionGaussian, DistributionLorentz, DistributionGate, ResolutionFunction2DGaussian, PolFilter, FootprintSquare, and FootprintGauss.

Definition at line 51 of file INode.h.

51 { return {}; }

Referenced by INode::checkNodeArgs(), and IFormFactor::pythonConstructor().

◆ prepareSimulation()

void OffspecSimulation::prepareSimulation ( )
overrideprivatevirtual

Put into a clean state for running a simulation.

Reimplemented from ISimulation2D.

Definition at line 40 of file OffspecSimulation.cpp.

41 {
44 }
void prepareSimulation() override
Put into a clean state for running a simulation.

References checkInitialization(), and ISimulation2D::prepareSimulation().

Here is the call graph for this function:

◆ progress()

ProgressHandler & ISimulation::progress ( )
protectedinherited

Definition at line 129 of file ISimulation.cpp.

130 {
132  return *m_progress;
133 }
std::shared_ptr< ProgressHandler > m_progress
Definition: ISimulation.h:136

References ASSERT, and ISimulation::m_progress.

Referenced by DepthProbeSimulation::createComputation(), ISimulation2D::createComputation(), and SpecularSimulation::createComputation().

◆ runSingleSimulation()

void ISimulation::runSingleSimulation ( const reSample re_sample,
size_t  batch_start,
size_t  batch_size,
double  weight = 1.0 
)
privateinherited

Runs a single simulation with fixed parameter values. If desired, the simulation is run in several threads.

Definition at line 245 of file ISimulation.cpp.

247 {
249 
250  const size_t n_threads = m_options->getNumberOfThreads();
251  ASSERT(n_threads > 0);
252 
253  std::vector<std::unique_ptr<IComputation>> computations;
254 
255  for (size_t i_thread = 0; i_thread < n_threads; ++i_thread) {
256  const size_t thread_start = batch_start + startIndex(n_threads, i_thread, batch_size);
257  const size_t thread_size = batchSize(n_threads, i_thread, batch_size);
258  if (thread_size == 0)
259  break;
260  computations.emplace_back(createComputation(re_sample, thread_start, thread_size));
261  }
262  runComputations(computations);
263 
264  normalize(batch_start, batch_size);
265  addBackgroundIntensity(batch_start, batch_size);
266  addDataToCache(weight);
267 }
virtual void initElementVector()=0
Initializes the vector of ISimulation elements.
virtual void addDataToCache(double weight)=0
virtual void addBackgroundIntensity(size_t start_ind, size_t n_elements)=0
virtual std::unique_ptr< IComputation > createComputation(const reSample &re_sample, size_t start, size_t n_elements)=0
Generate a single threaded computation for a given range of simulation elements.
virtual void normalize(size_t start_ind, size_t n_elements)=0
Normalize the detector counts to beam intensity, to solid angle, and to exposure angle.

References ISimulation::addBackgroundIntensity(), ISimulation::addDataToCache(), ASSERT, ISimulation::createComputation(), ISimulation::initElementVector(), ISimulation::m_options, and ISimulation::normalize().

Referenced by ISimulation::simulate().

Here is the call graph for this function:

◆ sample()

const MultiLayer * ISimulation::sample ( ) const
inherited

Definition at line 191 of file ISimulation.cpp.

192 {
193  return m_sample.get();
194 }
std::shared_ptr< MultiLayer > m_sample
Definition: ISimulation.h:133

References ISimulation::m_sample.

Referenced by ISimulation::simulate(), and DepthProbeSimulation::validityCheck().

◆ setBackground()

void ISimulation::setBackground ( const IBackground bg)
inherited

Definition at line 196 of file ISimulation.cpp.

197 {
198  m_background.reset(bg.clone());
199 }
IBackground * clone() const override=0

References IBackground::clone(), and ISimulation::m_background.

Here is the call graph for this function:

◆ setBeamParameters()

void OffspecSimulation::setBeamParameters ( double  wavelength,
const IAxis alpha_axis,
double  phi_i 
)

Sets beam parameters from here (forwarded to Instrument)

Definition at line 66 of file OffspecSimulation.cpp.

67 {
68  m_alpha_i_axis.reset(alpha_axis.clone());
69  if (alpha_axis.size() < 1)
70  throw std::runtime_error("OffspecSimulation::prepareSimulation() "
71  "-> Error. Incoming alpha range size < 1.");
72  const double alpha_zero = alpha_axis.min();
73  beam().setWavelength(wavelength);
74  beam().setDirection({alpha_zero, phi_i});
76 }
void setDirection(const Direction &direction)
Definition: Beam.cpp:92
void setWavelength(double wavelength)
Definition: Beam.cpp:85
virtual IAxis * clone() const =0
virtual double min() const =0
Returns value of first point of axis.
void updateIntensityMap() override
Default implementation only adds the detector axes.

References ISimulation2D::beam(), IAxis::clone(), m_alpha_i_axis, IAxis::min(), Beam::setDirection(), Beam::setWavelength(), IAxis::size(), and updateIntensityMap().

Here is the call graph for this function:

◆ setRegionOfInterest()

void ISimulation2D::setRegionOfInterest ( double  xlow,
double  ylow,
double  xup,
double  yup 
)
inherited

Sets rectangular region of interest with lower left and upper right corners defined.

Definition at line 66 of file ISimulation2D.cpp.

67 {
68  detector().setRegionOfInterest(xlow, ylow, xup, yup);
69 }
void setRegionOfInterest(double xlow, double ylow, double xup, double yup)
Sets rectangular region of interest with lower left and upper right corners defined.
Definition: IDetector.cpp:337

References ISimulation2D::detector(), and IDetector::setRegionOfInterest().

Here is the call graph for this function:

◆ setTerminalProgressMonitor()

void ISimulation::setTerminalProgressMonitor ( )
inherited

Initializes a progress monitor that prints to stdout.

Definition at line 142 of file ISimulation.cpp.

143 {
144  m_progress->subscribe([](size_t percentage_done) -> bool {
145  if (percentage_done < 100)
146  std::cout << std::setprecision(2) << "\r... " << percentage_done << "%" << std::flush;
147  else // wipe out
148  std::cout << "\r... 100%\n";
149  return true;
150  });
151 }

References ISimulation::m_progress.

◆ simulate()

SimulationResult ISimulation::simulate ( )
inherited

Run a simulation, and return the result.

Runs simulation with possible averaging over parameter distributions; returns result.

Definition at line 154 of file ISimulation.cpp.

155 {
157  throw std::runtime_error("Sample contains incompatible material definitions");
158  gsl_set_error_handler_off();
159 
161 
162  const auto re_sample = reSample::make(*sample(), options(), force_polarized());
163 
164  const size_t total_size = numberOfElements();
165  size_t param_combinations = m_distribution_handler.getTotalNumberOfSamples();
166 
167  m_progress->reset();
168  m_progress->setExpectedNTicks(param_combinations * total_size);
169 
170  // restrict calculation to current batch
171  const size_t n_batches = m_options->getNumberOfBatches();
172  const size_t current_batch = m_options->getCurrentBatch();
173 
174  const size_t batch_start = startIndex(n_batches, current_batch, total_size);
175  const size_t batch_size = batchSize(n_batches, current_batch, total_size);
176  ASSERT(batch_size);
177 
178  if (param_combinations == 1)
179  runSingleSimulation(re_sample, batch_start, batch_size, 1.);
180  else {
182  for (size_t index = 0; index < param_combinations; ++index) {
183  double weight = m_distribution_handler.setParameterValues(index);
184  runSingleSimulation(re_sample, batch_start, batch_size, weight);
185  }
186  }
188  return pack_result();
189 }
double setParameterValues(size_t index)
set the parameter values of the simulation object to a specific combination of values,...
size_t getTotalNumberOfSamples() const
get the total number of parameter value combinations (product of the individual sizes of each paramet...
virtual size_t numberOfElements() const =0
Gets the number of elements this simulation needs to calculate.
virtual void prepareSimulation()=0
Put into a clean state for running a simulation.
virtual SimulationResult pack_result()=0
Sets m_result.
virtual void moveDataFromCache()=0
void runSingleSimulation(const reSample &re_sample, size_t batch_start, size_t batch_size, double weight=1.0)
Runs a single simulation with fixed parameter values. If desired, the simulation is run in several th...
virtual bool force_polarized() const =0
Force polarized computation even in absence of sample magnetization or external fields.
virtual void initDistributionHandler()
Definition: ISimulation.h:106
static reSample make(const MultiLayer &sample, const SimulationOptions &options, bool forcePolarized=false)
Factory method that wraps the private constructor.
Definition: ReSample.cpp:309
bool ContainsCompatibleMaterials(const MultiLayer &sample)
Returns true if the sample contains non-default materials of one type only.

References ASSERT, SampleUtils::Multilayer::ContainsCompatibleMaterials(), ISimulation::force_polarized(), DistributionHandler::getTotalNumberOfSamples(), ISimulation::initDistributionHandler(), ISimulation::m_distribution_handler, ISimulation::m_options, ISimulation::m_progress, ISimulation::m_sample, reSample::make(), ISimulation::moveDataFromCache(), ISimulation::numberOfElements(), ISimulation::options(), ISimulation::pack_result(), ISimulation::prepareSimulation(), ISimulation::runSingleSimulation(), ISimulation::sample(), and DistributionHandler::setParameterValues().

Here is the call graph for this function:

◆ subscribe()

void ISimulation::subscribe ( const std::function< bool(size_t)> &  inform)
inherited

Definition at line 135 of file ISimulation.cpp.

136 {
138  m_progress->subscribe(inform);
139 }

References ASSERT, and ISimulation::m_progress.

◆ transferDetectorImage()

void OffspecSimulation::transferDetectorImage ( size_t  index)
private

Normalize, apply detector resolution and transfer detector image corresponding to alpha_i = m_alpha_i_axis->bin(index)

Definition at line 135 of file OffspecSimulation.cpp.

136 {
137  std::unique_ptr<Datafield> detector_image;
138  if (detector().rank() == 1)
139  detector_image.reset(new Datafield({detector().axis(0).clone()}));
140  else if (detector().rank() == 2)
141  detector_image.reset(new Datafield(
142  {detector().axis(0).clone(), detector().axis(1).clone()}));
143  else
144  ASSERT(0);
145 
146  size_t N = detector_image->size();
147  for (size_t i = 0; i < N; ++i)
148  (*detector_image)[i] = m_eles[index * N + i]->intensity();
149  detector().applyDetectorResolution(detector_image.get());
150  size_t y_axis_size = detector().axis(1).size();
151  for (size_t i = 0; i < N; ++i)
152  (*m_intensity_map)[index * y_axis_size + i % y_axis_size] += (*detector_image)[i];
153 }
Stores radiation power per bin.
Definition: Datafield.h:30
size_t rank() const
Returns number of defined axes.
Definition: IDetector.cpp:64
void applyDetectorResolution(Datafield *p_intensity_map) const
Applies the detector resolution to the given intensity maps.
Definition: IDetector.cpp:169

References IDetector::applyDetectorResolution(), ASSERT, IDetector::axis(), IAxis::clone(), ISimulation2D::detector(), ISimulation2D::m_eles, m_intensity_map, N, IDetector::rank(), and IAxis::size().

Referenced by pack_result().

Here is the call graph for this function:

◆ unitOfParameter()

std::string ISimulation::unitOfParameter ( ParameterDistribution::WhichParameter  which) const
inherited

Definition at line 209 of file ISimulation.cpp.

210 {
211  switch (which) {
213  return "nm";
216  return "rad";
217  default:
218  throw std::runtime_error("ISimulation::unitOfParameter(): missing implementation");
219  }
220 }

References ParameterDistribution::BeamAzimuthalAngle, ParameterDistribution::BeamInclinationAngle, and ParameterDistribution::BeamWavelength.

◆ updateIntensityMap()

void OffspecSimulation::updateIntensityMap ( )
overrideprivatevirtual

Default implementation only adds the detector axes.

Reimplemented from ISimulation.

Definition at line 123 of file OffspecSimulation.cpp.

124 {
126  if (detector().rank() == 1)
127  m_intensity_map.reset(new Datafield({m_alpha_i_axis->clone()}));
128  else if (detector().rank() == 2)
129  m_intensity_map.reset(new Datafield({m_alpha_i_axis->clone(), detector().axis(1).clone()}));
130  else
131  ASSERT(0);
132  m_intensity_map->setAllTo(0.);
133 }

References ASSERT, ISimulation2D::detector(), m_alpha_i_axis, and m_intensity_map.

Referenced by setBeamParameters().

Here is the call graph for this function:

◆ validateParametrization()

void OffspecSimulation::validateParametrization ( const ParameterDistribution par_distr) const
overrideprivatevirtual

Checks the distribution validity for simulation.

Reimplemented from ISimulation.

Definition at line 111 of file OffspecSimulation.cpp.

112 {
113  const bool zero_mean = par_distr.getDistribution()->mean() == 0.0;
114  if (zero_mean)
115  return;
116  /* TODO come back to this after refactoring of distribution handling
117  if (par_distr.whichParameter() == ParameterDistribution::BeamInclinationAngle)
118  throw std::runtime_error("Error in OffspecSimulation: parameter distribution of "
119  "beam inclination angle should have zero mean.");
120  */
121 }
virtual double mean() const =0
Returns the distribution-specific mean.
const IDistribution1D * getDistribution() const

References ParameterDistribution::getDistribution(), and IDistribution1D::mean().

Here is the call graph for this function:

Member Data Documentation

◆ m_alpha_i_axis

std::unique_ptr<IAxis> OffspecSimulation::m_alpha_i_axis
private

◆ m_background

std::shared_ptr<IBackground> ISimulation::m_background
privateinherited

Definition at line 137 of file ISimulation.h.

Referenced by ISimulation::background(), and ISimulation::setBackground().

◆ m_beam

std::unique_ptr<Beam> ISimulation2D::m_beam
protectedinherited

◆ m_cache

std::vector<double> ISimulation2D::m_cache
protectedinherited

◆ m_detector

std::unique_ptr<IDetector> ISimulation2D::m_detector
protectedinherited

◆ m_detector_context

std::unique_ptr<DetectorContext> ISimulation2D::m_detector_context
privateinherited

◆ m_distribution_handler

DistributionHandler ISimulation::m_distribution_handler
protectedinherited

◆ m_eles

◆ m_intensity_map

std::unique_ptr<Datafield> OffspecSimulation::m_intensity_map
private

Definition at line 76 of file OffspecSimulation.h.

Referenced by pack_result(), transferDetectorImage(), and updateIntensityMap().

◆ m_options

std::shared_ptr<SimulationOptions> ISimulation::m_options
privateinherited

◆ m_P

◆ m_progress

std::shared_ptr<ProgressHandler> ISimulation::m_progress
privateinherited

◆ m_sample

std::shared_ptr<MultiLayer> ISimulation::m_sample
privateinherited

The documentation for this class was generated from the following files: