BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
TransformToDomain.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Models/TransformToDomain.cpp
6 //! @brief Implements class TransformToDomain
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/Const/Units.h"
55 
56 namespace {
57 template <class T>
58 void setParameterDistributionToSimulation(const std::string& parameter_name,
59  const SessionItem* item, ISimulation& simulation);
60 
61 std::unique_ptr<ScanResolution> createScanResolution(const SessionItem* item);
62 } // namespace
63 
64 std::unique_ptr<Material> TransformToDomain::createDomainMaterial(const SessionItem& item)
65 {
66  auto parent_job = JobModelFunctions::findJobItem(&item);
67  const MaterialItemContainer* container =
68  parent_job ? parent_job->materialContainerItem() : nullptr;
69  QString tag = MaterialItemUtils::materialTag(item);
70  ExternalProperty property = item.getItemValue(tag).value<ExternalProperty>();
71  return container ? MaterialItemUtils::createDomainMaterial(property, *container)
73 }
74 
75 std::unique_ptr<MultiLayer> TransformToDomain::createMultiLayer(const SessionItem& item)
76 {
77  auto P_multilayer = std::make_unique<MultiLayer>();
78  auto cross_corr_length = item.getItemValue(MultiLayerItem::P_CROSS_CORR_LENGTH).toDouble();
79  if (cross_corr_length > 0)
80  P_multilayer->setCrossCorrLength(cross_corr_length);
81  auto external_field = item.item<VectorItem>(MultiLayerItem::P_EXTERNAL_FIELD)->getVector();
82  P_multilayer->setExternalField(external_field);
83  return P_multilayer;
84 }
85 
86 std::unique_ptr<Layer> TransformToDomain::createLayer(const SessionItem& item)
87 {
88  auto P_layer = std::make_unique<Layer>(*createDomainMaterial(item),
89  item.getItemValue(LayerItem::P_THICKNESS).toDouble());
90  P_layer->setNumberOfSlices(item.getItemValue(LayerItem::P_NSLICES).toUInt());
91  return P_layer;
92 }
93 
94 std::unique_ptr<LayerRoughness>
96 {
97  if (roughnessItem.modelType() == "LayerZeroRoughness") {
98  return nullptr;
99  } else if (roughnessItem.modelType() == "LayerBasicRoughness") {
100  return std::make_unique<LayerRoughness>(
101  roughnessItem.getItemValue(LayerBasicRoughnessItem::P_SIGMA).toDouble(),
102  roughnessItem.getItemValue(LayerBasicRoughnessItem::P_HURST).toDouble(),
104  } else {
105  throw GUIHelpers::Error("TransformToDomain::createLayerRoughness() -> Error.");
106  }
107 }
108 
109 std::unique_ptr<ParticleLayout> TransformToDomain::createParticleLayout(const SessionItem& item)
110 {
111  auto P_layout = std::make_unique<ParticleLayout>();
112  auto total_density = item.getItemValue(ParticleLayoutItem::P_TOTAL_DENSITY).value<double>();
113  auto layout_weight = item.getItemValue(ParticleLayoutItem::P_WEIGHT).value<double>();
114  P_layout->setTotalParticleSurfaceDensity(total_density);
115  P_layout->setWeight(layout_weight);
116  return P_layout;
117 }
118 
119 std::unique_ptr<IParticle> TransformToDomain::createIParticle(const SessionItem& item)
120 {
121  std::unique_ptr<IParticle> P_particle;
122  if (item.modelType() == "Particle") {
123  auto& particle_item = static_cast<const ParticleItem&>(item);
124  P_particle = particle_item.createParticle();
125  } else if (item.modelType() == "ParticleCoreShell") {
126  auto& particle_coreshell_item = static_cast<const ParticleCoreShellItem&>(item);
127  P_particle = particle_coreshell_item.createParticleCoreShell();
128  } else if (item.modelType() == "ParticleComposition") {
129  auto& particle_composition_item = static_cast<const ParticleCompositionItem&>(item);
130  P_particle = particle_composition_item.createParticleComposition();
131  } else if (item.modelType() == "MesoCrystal") {
132  auto& mesocrystal_item = static_cast<const MesoCrystalItem&>(item);
133  P_particle = mesocrystal_item.createMesoCrystal();
134  }
135  return P_particle;
136 }
137 
138 std::unique_ptr<ParticleDistribution>
140 {
141  auto& particle_distribution = static_cast<const ParticleDistributionItem&>(item);
142  auto P_part_distr = particle_distribution.createParticleDistribution();
143  return P_part_distr;
144 }
145 
146 //! adds DistributionParameters to the ISimulation
148  GISASSimulation& simulation)
149 {
150  if (beam_item.modelType() != "GISASBeam") {
151  ASSERT(beam_item.modelType() == "GISASBeam");
152  return;
153  }
154 
155  setParameterDistributionToSimulation<BeamWavelengthItem>(
156  "Wavelength", beam_item.getItem(BeamItem::P_WAVELENGTH), simulation);
157  setParameterDistributionToSimulation<BeamInclinationAngleItem>(
158  "InclinationAngle", beam_item.getItem(BeamItem::P_INCLINATION_ANGLE), simulation);
159  setParameterDistributionToSimulation<BeamAzimuthalAngleItem>(
160  "AzimuthalAngle", beam_item.getItem(BeamItem::P_AZIMUTHAL_ANGLE), simulation);
161 }
162 
164  AngularSpecScan& scan)
165 {
166  if (beam_item.modelType() != "SpecularBeam") {
167  ASSERT(beam_item.modelType() == "SpecularBeam");
168  return;
169  }
170 
171  auto resolution = createScanResolution(beam_item.getItem(SpecularBeamItem::P_WAVELENGTH));
172  if (resolution)
173  scan.setWavelengthResolution(*resolution);
174  resolution = createScanResolution(beam_item.getItem(SpecularBeamItem::P_INCLINATION_ANGLE));
175  if (resolution)
176  scan.setAngleResolution(*resolution);
177 }
178 
179 void TransformToDomain::setBeamDistribution(const std::string& parameter_name,
180  const BeamDistributionItem& item,
181  ISimulation& simulation)
182 {
183  ParameterPattern parameter_pattern;
184  parameter_pattern.beginsWith("*").add("Beam").add(parameter_name);
185 
186  auto P_par_distr = item.getParameterDistributionForName(parameter_pattern.toStdString());
187  if (P_par_distr)
188  simulation.addParameterDistribution(*P_par_distr);
189 }
190 
192 {
193  ASSERT(item.modelType() == "SimulationOptions");
194 
195  if (auto optionItem = dynamic_cast<const SimulationOptionsItem*>(&item)) {
196  simulation->getOptions().setNumberOfThreads(optionItem->getNumberOfThreads());
197  if (optionItem->getComputationMethod() == "Monte-Carlo Integration") {
198  simulation->getOptions().setMonteCarloIntegration(
199  true, optionItem->getNumberOfMonteCarloPoints());
200  }
201  if (optionItem->getFresnelMaterialMethod() == "Average Layer Material")
202  simulation->getOptions().setUseAvgMaterials(true);
203  if (optionItem->getIncludeSpecularPeak() == "Yes")
204  simulation->getOptions().setIncludeSpecular(true);
205  }
206 }
207 
209 {
210  setPositionInfo(result, item);
211  setRotationInfo(result, item);
212 }
213 
215 {
216  kvector_t pos = item.item<VectorItem>(ParticleItem::P_POSITION)->getVector();
217  result->setPosition(pos.x(), pos.y(), pos.z());
218 }
219 
221 {
222  QVector<SessionItem*> children = item.children();
223  for (int i = 0; i < children.size(); ++i) {
224  if (children[i]->modelType() == "Rotation") {
225  auto& rot_item = children[i]->groupItem<RotationItem>(TransformationItem::P_ROT);
226  auto rotation = rot_item.createRotation();
227  if (rotation)
228  result->setRotation(*rotation);
229  break;
230  }
231  }
232 }
233 
234 namespace {
235 template <class T>
236 void setParameterDistributionToSimulation(const std::string& parameter_name,
237  const SessionItem* item, ISimulation& simulation)
238 {
239  const auto parameter_item = dynamic_cast<const T*>(item);
240  if (!parameter_item) {
241  ASSERT(parameter_item);
242  return;
243  }
244 
245  ParameterPattern parameter_pattern;
246  parameter_pattern.beginsWith("*").add("Beam").add(parameter_name);
247 
248  auto P_par_distr =
249  parameter_item->getParameterDistributionForName(parameter_pattern.toStdString());
250  if (P_par_distr)
251  simulation.addParameterDistribution(*P_par_distr);
252 }
253 
254 std::unique_ptr<ScanResolution> createScanResolution(const SessionItem* item)
255 {
256  auto beam_item = dynamic_cast<const BeamDistributionItem*>(item);
257  if (!beam_item)
258  return nullptr;
259 
260  auto distr_item = dynamic_cast<const SymmetricDistributionItem*>(
261  beam_item->getGroupItem(BeamDistributionItem::P_DISTRIBUTION));
262  if (!distr_item)
263  return nullptr;
264 
265  const double scale = beam_item->scaleFactor();
266  auto ranged_distr = distr_item->createIRangedDistribution(scale);
267  if (!ranged_distr)
268  return nullptr;
269 
270  const double deviation = distr_item->deviation(scale);
271  return std::unique_ptr<ScanResolution>(
272  ScanResolution::scanAbsoluteResolution(*ranged_distr, deviation));
273 }
274 } // namespace
Declares AngularSpecScan class.
#define ASSERT(condition)
Definition: Assert.h:31
Defines class BeamAngleItems.
Defines BeamItem hierarchy.
Defines class BeamWavelengthItem.
Defines class ComboProperty.
Defines FTDecayFunction1DItem classes.
Defines FTDistribution1DItem's classes.
Defines class GISASSimulation.
Defines class GUIHelpers functions.
Includes all interference function definitions.
Defines class JobItem.
Defines auxiliary functions in JobModelFunctions namespace.
Defines classes Lattice2DItems.
Defines class LayerItem.
Defines classes LayerRoughnessItems.
Defines MaskItems classes.
Defines class MaterialItemUtils.
Defines class MesoCrystalItem.
Defines class MesoCrystal.
Defines class MultiLayerItem.
Defines class ParameterPattern.
Defines class ParticleCompositionItem.
Defines class ParticleCoreShellItem.
Defines ParticleCoreShell.
Defines class ParticleDistributionItem.
Defines class ParticleItem.
Defines class ParticleLayoutItem.
Defines class Particle.
Defines classes representing ranged one-dimensional distributions.
Defines class RectangularDetectorItem.
Defines class RotationItems.
Defines scan resolution class.
Defines namespace SessionItemUtils.
Defines class SimulationOptionsItem.
Declares the class SpecularBeamInclinationItem.
Defines class SphericalDetectorItem.
Defines class TransformToDomain.
Defines class TransformationItem.
Defines some unit conversion factors and other constants in namespace Units.
Defines class VectorItem.
Scan type with inclination angles as coordinate values and a unique wavelength.
void setAngleResolution(const ScanResolution &resolution)
Sets angle resolution values via ScanResolution object.
void setWavelengthResolution(const ScanResolution &resolution)
Sets wavelength resolution values via ScanResolution object.
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
The BeamDistributionItem handles wavelength, inclination and azimuthal parameter distribution for Bea...
std::unique_ptr< ParameterDistribution > getParameterDistributionForName(const std::string &parameter_name) const
returns parameter distribution to add into the ISimulation
static const QString P_DISTRIBUTION
static const QString P_AZIMUTHAL_ANGLE
Definition: BeamItems.h:31
static const QString P_WAVELENGTH
Definition: BeamItems.h:29
static const QString P_INCLINATION_ANGLE
Definition: BeamItems.h:30
The ExternalProperty class defines custom QVariant property to carry the text, color and an identifie...
Main class to run a Grazing-Incidence Small-Angle Scattering simulation.
Abstract base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal.
Definition: IParticle.h:33
void setPosition(kvector_t position)
Sets relative position of the particle's reference point in the coordinate system of parent.
Definition: IParticle.h:50
void setRotation(const IRotation &rotation)
Sets transformation.
Definition: IParticle.cpp:44
Abstract base class of OffSpecularSimulation, GISASSimulation and SpecularSimulation.
Definition: ISimulation.h:38
void addParameterDistribution(const std::string &param_name, const IDistribution1D &distribution, size_t nbr_samples, double sigma_factor=0.0, const RealLimits &limits=RealLimits())
const SimulationOptions & getOptions() const
Definition: ISimulation.h:91
static const QString P_LATERAL_CORR_LENGTH
static const QString P_SIGMA
static const QString P_HURST
static const QString P_THICKNESS
Definition: LayerItem.h:22
static const QString P_NSLICES
Definition: LayerItem.h:25
std::unique_ptr< MesoCrystal > createMesoCrystal() const
static const QString P_CROSS_CORR_LENGTH
static const QString P_EXTERNAL_FIELD
Helper class for constructing parameter patterns.
ParameterPattern & beginsWith(std::string start_type)
std::string toStdString() const
ParameterPattern & add(std::string object_type)
std::unique_ptr< ParticleComposition > createParticleComposition() const
std::unique_ptr< ParticleCoreShell > createParticleCoreShell() const
std::unique_ptr< ParticleDistribution > createParticleDistribution() const
std::unique_ptr< Particle > createParticle() const
static const QString P_POSITION
Definition: ParticleItem.h:28
static const QString P_TOTAL_DENSITY
static const QString P_WEIGHT
virtual std::unique_ptr< IRotation > createRotation() const =0
static ScanResolution * scanAbsoluteResolution(const IRangedDistribution &distr, double stddev)
QVariant getItemValue(const QString &tag) const
Directly access value of item under given tag.
T * item(const QString &tag) const
Definition: SessionItem.h:151
QVector< SessionItem * > children() const
Returns vector of all children.
QString modelType() const
Get model type.
SessionItem * getItem(const QString &tag="", int row=0) const
Returns item in given row of given tag.
The SimulationOptionsItem class holds simulation status (run policy, number of threads,...
void setUseAvgMaterials(bool use_avg_materials)
void setIncludeSpecular(bool include_specular)
void setNumberOfThreads(int nthreads)
Sets number of threads to use during the simulation (0 - take the default value from the hardware)
void setMonteCarloIntegration(bool flag=true, size_t mc_points=50)
Enables/disables MonetCarlo integration.
virtual std::unique_ptr< IRangedDistribution > createIRangedDistribution(double scale) const =0
static const QString P_ROT
const JobItem * findJobItem(const SessionItem *item)
Determines parenting JobItem of a given SessionItem.
QString materialTag(const SessionItem &item)
Returns material tag for given item. Returns empty string, if item doesn't have materials.
std::unique_ptr< Material > createDomainMaterial(const ExternalProperty &material_property)
void setPositionInfo(IParticle *result, const SessionItem &item)
void setTransformationInfo(IParticle *result, const SessionItem &item)
void setRotationInfo(IParticle *result, const SessionItem &item)
std::unique_ptr< ParticleLayout > createParticleLayout(const SessionItem &item)
void addBeamDivergencesToScan(const SessionItem &beam_item, AngularSpecScan &simulation)
void addDistributionParametersToSimulation(const SessionItem &beam_item, GISASSimulation &simulation)
adds DistributionParameters to the ISimulation
std::unique_ptr< ParticleDistribution > createParticleDistribution(const SessionItem &item)
std::unique_ptr< Material > createDomainMaterial(const SessionItem &item)
std::unique_ptr< IParticle > createIParticle(const SessionItem &item)
void setBeamDistribution(const std::string &parameter_name, const BeamDistributionItem &item, ISimulation &simulation)
std::unique_ptr< MultiLayer > createMultiLayer(const SessionItem &item)
void setSimulationOptions(ISimulation *simulation, const SessionItem &item)
std::unique_ptr< Layer > createLayer(const SessionItem &item)
std::unique_ptr< LayerRoughness > createLayerRoughness(const SessionItem &item)