BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
DomainObjectBuilder.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Models/DomainObjectBuilder.cpp
6 //! @brief Implements DomainObjectBuilder namespace
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"
31 
32 std::unique_ptr<MultiLayer> DomainObjectBuilder::buildMultiLayer(const SessionItem& multilayer_item)
33 {
34  auto P_multilayer = TransformToDomain::createMultiLayer(multilayer_item);
35  QVector<SessionItem*> children = multilayer_item.children();
36  for (int i = 0; i < children.size(); ++i) {
37  if (children[i]->modelType() == "Layer") {
38  auto P_layer = buildLayer(*children[i]);
39  auto roughnessItem = children[i]->getGroupItem(LayerItem::P_ROUGHNESS);
40  ASSERT(roughnessItem);
41  auto P_roughness = TransformToDomain::createLayerRoughness(*roughnessItem);
42  if (P_layer) {
43  if (P_roughness) {
44  P_multilayer->addLayerWithTopRoughness(*P_layer, *P_roughness);
45  } else {
46  P_multilayer->addLayer(*P_layer);
47  }
48  }
49  }
50  }
51  return P_multilayer;
52 }
53 
54 std::unique_ptr<Layer> DomainObjectBuilder::buildLayer(const SessionItem& item)
55 {
56  auto P_layer = TransformToDomain::createLayer(item);
57  QVector<SessionItem*> children = item.children();
58  for (int i = 0; i < children.size(); ++i) {
59  if (children[i]->modelType() == "ParticleLayout") {
60  auto P_layout = buildParticleLayout(*children[i]);
61  if (P_layout) {
62  P_layer->addLayout(*P_layout);
63  }
64  }
65  }
66  return P_layer;
67 }
68 
69 std::unique_ptr<ParticleLayout> DomainObjectBuilder::buildParticleLayout(const SessionItem& item)
70 {
71  auto P_layout = TransformToDomain::createParticleLayout(item);
72  QVector<SessionItem*> children = item.getItems();
73  for (int i = 0; i < children.size(); ++i) {
74  auto P_particle = TransformToDomain::createIParticle(*children[i]);
75  if (P_particle) {
76  P_layout->addParticle(*P_particle);
77  continue;
78  }
79  if (children[i]->modelType() == "ParticleDistribution") {
80  auto prop = children[i]
82  .value<ComboProperty>();
83  QString par_name = prop.getValue();
85  auto grandchildren = children[i]->getItems();
86  if (grandchildren.empty()) {
87  continue;
88  }
89  if (grandchildren.size() > 1) {
90  throw GUIHelpers::Error("DomainObjectBuilder::buildParticleLayout()"
91  " -> Error! Too many particles defined"
92  " in ParticleDistribution");
93  }
94  auto P_particle = TransformToDomain::createIParticle(*grandchildren[0]);
95  if (P_particle) {
96  P_layout->addParticle(*P_particle);
97  }
98  } else {
99  auto P_part_distr = TransformToDomain::createParticleDistribution(*children[i]);
100  if (P_part_distr) {
101  P_layout->addParticle(*P_part_distr);
102  }
103  }
104  } else {
105  throw GUIHelpers::Error("DomainObjectBuilder::buildParticleLayout()"
106  " -> Error! Not implemented");
107  }
108  }
109  QVector<SessionItem*> interferences = item.getItems(ParticleLayoutItem::T_INTERFERENCE);
110  for (int i = 0; i < interferences.size(); i++) {
111  auto P_interference = buildInterferenceFunction(*interferences[i]);
112  if (P_interference) {
113  P_layout->setInterferenceFunction(*P_interference);
114  }
115  }
116  return P_layout;
117 }
118 
119 std::unique_ptr<IInterferenceFunction>
121 {
122  auto iffItem = dynamic_cast<const InterferenceFunctionItem*>(&item);
123  ASSERT(iffItem);
124  return iffItem->createInterferenceFunction();
125 }
126 
127 std::unique_ptr<Instrument>
129 {
130  return instrumentItem.createInstrument();
131 }
132 
133 std::unique_ptr<IUnitConverter>
135 {
136  if (auto specular_instrument = dynamic_cast<const SpecularInstrumentItem*>(instrumentItem))
137  return specular_instrument->createUnitConverter();
138  else if (auto depth_instrument = dynamic_cast<const DepthProbeInstrumentItem*>(instrumentItem))
139  return depth_instrument->createUnitConverter();
140 
141  const auto instrument = instrumentItem->createInstrument();
142  instrument->initDetector();
143 
144  if (instrumentItem->is<GISASInstrumentItem>())
146 
147  if (instrumentItem->is<OffSpecularInstrumentItem>()) {
148  auto axis_item =
150  const auto detector2d = dynamic_cast<const IDetector2D*>(instrument->getDetector());
151  return std::make_unique<OffSpecularConverter>(*detector2d, instrument->beam(),
152  *axis_item->createAxis(Units::deg));
153  }
154 
155  throw GUIHelpers::Error(
156  "Error in DomainObjectBuilder::createUnitConverter: unknown instrument type.");
157 }
#define ASSERT(condition)
Definition: Assert.h:31
Defines various axis items.
Defines class ComboProperty.
Defines DepthProbeInstrumentItem class.
Defines DomainObjectBuilder namespace.
Defines class GUIHelpers functions.
Defines interface IDetector2D.
Defines InterferenceFunctionItems's classes.
Defines class LayerItem.
Defines class ParticleDistributionItem.
Defines class ParticleLayoutItem.
Defines interface UnitConverterSimple and its subclasses.
Declares the class SpecularBeamInclinationItem.
Defines class TransformToDomain.
Defines UnitConverter1D class and derived classes.
Declares utilities for unit converters.
Defines some unit conversion factors and other constants in namespace Units.
virtual std::unique_ptr< IAxis > createAxis(double scale) const
Definition: AxesItems.cpp:72
Custom property to define list of string values with multiple selections.
Definition: ComboProperty.h:25
QString getValue() const
Abstract 2D detector interface.
Definition: IDetector2D.h:31
virtual std::unique_ptr< Instrument > createInstrument() const =0
static const QString P_ROUGHNESS
Definition: LayerItem.h:23
static const QString P_ALPHA_AXIS
static const QString NO_SELECTION
static const QString P_DISTRIBUTED_PARAMETER
static const QString T_INTERFERENCE
bool is() const
Definition: SessionItem.h:175
QVector< SessionItem * > getItems(const QString &tag="") const
Returns vector of all items of given tag.
T * item(const QString &tag) const
Definition: SessionItem.h:151
QVector< SessionItem * > children() const
Returns vector of all children.
std::unique_ptr< MultiLayer > buildMultiLayer(const SessionItem &multilayer_item)
std::unique_ptr< Layer > buildLayer(const SessionItem &item)
std::unique_ptr< ParticleLayout > buildParticleLayout(const SessionItem &item)
std::unique_ptr< IUnitConverter > createUnitConverter(const InstrumentItem *instrumentItem)
Creates a unit converter corresponding to the given instrument item.
std::unique_ptr< IInterferenceFunction > buildInterferenceFunction(const SessionItem &item)
std::unique_ptr< Instrument > buildInstrument(const InstrumentItem &instrumentItem)
std::unique_ptr< ParticleLayout > createParticleLayout(const SessionItem &item)
std::unique_ptr< ParticleDistribution > createParticleDistribution(const SessionItem &item)
std::unique_ptr< IParticle > createIParticle(const SessionItem &item)
std::unique_ptr< MultiLayer > createMultiLayer(const SessionItem &item)
std::unique_ptr< Layer > createLayer(const SessionItem &item)
std::unique_ptr< LayerRoughness > createLayerRoughness(const SessionItem &item)
std::unique_ptr< IUnitConverter > createConverterForGISAS(const Instrument &instrument)
Helper factory function to use in GISASSimulation.
static constexpr double deg
Definition: Units.h:46