BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
DomainSimulationBuilder.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Models/DomainSimulationBuilder.cpp
6 //! @brief Implements class DomainSimulationBuilder
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"
35 
36 namespace {
37 void addBackgroundToSimulation(const InstrumentItem& instrument, ISimulation& simulation);
38 
39 std::unique_ptr<GISASSimulation> createGISASSimulation(std::unique_ptr<MultiLayer> P_multilayer,
40  const GISASInstrumentItem* gisasInstrument,
41  const SimulationOptionsItem* optionsItem);
42 
43 std::unique_ptr<OffSpecularSimulation>
44 createOffSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
45  const OffSpecularInstrumentItem* offspecInstrument,
46  const SimulationOptionsItem* optionsItem);
47 
48 std::unique_ptr<SpecularSimulation>
49 createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
50  const SpecularInstrumentItem* specular_instrument,
51  const SimulationOptionsItem* options_item);
52 
53 std::unique_ptr<DepthProbeSimulation>
54 createDepthProbeSimulation(std::unique_ptr<MultiLayer> P_multilayer,
55  const DepthProbeInstrumentItem* instrument,
56  const SimulationOptionsItem* options_item);
57 
58 } // namespace
59 
60 std::unique_ptr<ISimulation>
62  const InstrumentItem* instrumentItem,
63  const SimulationOptionsItem* optionsItem)
64 {
65  if (sampleItem == nullptr || instrumentItem == nullptr) {
66  QString message("DomainSimulationBuilder::getSimulation() -> Error. Either MultiLayerItem "
67  " or InstrumentItem is not defined.");
68  throw GUIHelpers::Error(message);
69  }
70 
71  auto P_multilayer = DomainObjectBuilder::buildMultiLayer(*sampleItem);
72 
73  if (auto gisasInstrument = dynamic_cast<const GISASInstrumentItem*>(instrumentItem))
74  return createGISASSimulation(std::move(P_multilayer), gisasInstrument, optionsItem);
75  else if (auto offspecInstrument =
76  dynamic_cast<const OffSpecularInstrumentItem*>(instrumentItem))
77  return createOffSpecularSimulation(std::move(P_multilayer), offspecInstrument, optionsItem);
78  else if (auto specular_instrument = dynamic_cast<const SpecularInstrumentItem*>(instrumentItem))
79  return createSpecularSimulation(std::move(P_multilayer), specular_instrument, optionsItem);
80  else if (auto penetrator = dynamic_cast<const DepthProbeInstrumentItem*>(instrumentItem))
81  return createDepthProbeSimulation(std::move(P_multilayer), penetrator, optionsItem);
82 
83  throw GUIHelpers::Error(
84  "DomainSimulationBuilder::createSimulation() -> Error. Not yet implemented");
85 }
86 
87 namespace {
88 void addBackgroundToSimulation(const InstrumentItem& instrument, ISimulation& simulation)
89 {
90  auto P_background = instrument.backgroundItem()->createBackground();
91  if (P_background)
92  simulation.setBackground(*P_background);
93 }
94 
95 std::unique_ptr<GISASSimulation> createGISASSimulation(std::unique_ptr<MultiLayer> P_multilayer,
96  const GISASInstrumentItem* instrument,
97  const SimulationOptionsItem* optionsItem)
98 {
99  std::unique_ptr<GISASSimulation> ret(new GISASSimulation);
100  auto P_instrument = DomainObjectBuilder::buildInstrument(*instrument);
101  ret->setSample(*P_multilayer);
102  ret->setInstrument(*P_instrument);
104 
105  // ISimulation options
106  if (optionsItem)
107  TransformToDomain::setSimulationOptions(ret.get(), *optionsItem);
108 
109  addBackgroundToSimulation(*instrument, *ret);
110 
111  return ret;
112 }
113 
114 std::unique_ptr<OffSpecularSimulation>
115 createOffSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
116  const OffSpecularInstrumentItem* instrument,
117  const SimulationOptionsItem* optionsItem)
118 {
119  std::unique_ptr<OffSpecularSimulation> ret(new OffSpecularSimulation);
120  auto P_instrument = DomainObjectBuilder::buildInstrument(*instrument);
121  ret->setSample(*P_multilayer);
122  ret->setInstrument(*P_instrument);
123 
124  auto beamItem = instrument->beamItem();
125  auto axisItem = instrument->item<BasicAxisItem>(OffSpecularInstrumentItem::P_ALPHA_AXIS);
126  ret->setBeamParameters(beamItem->wavelength(), *axisItem->createAxis(Units::deg),
127  beamItem->getAzimuthalAngle());
128 
129  // TODO Take care about distributions
130  // TransformToDomain::addDistributionParametersToSimulation(*gisasInstrument->beamItem(),
131  // gisas.get());
132 
133  // ISimulation options
134  if (optionsItem)
135  TransformToDomain::setSimulationOptions(ret.get(), *optionsItem);
136 
137  addBackgroundToSimulation(*instrument, *ret);
138 
139  return ret;
140 }
141 
142 std::unique_ptr<SpecularSimulation>
143 createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
144  const SpecularInstrumentItem* instrument,
145  const SimulationOptionsItem* options_item)
146 {
147  std::unique_ptr<SpecularSimulation> ret = std::make_unique<SpecularSimulation>();
148  ret->setSample(*P_multilayer);
149 
150  auto beam_item = instrument->beamItem();
151  const auto axis_item = beam_item->currentInclinationAxisItem();
152  const auto footprint = beam_item->currentFootprintItem();
153 
154  AngularSpecScan scan(beam_item->wavelength(), *axis_item->createAxis(Units::deg));
155  scan.setFootprintFactor(footprint->createFootprint().get());
156 
158 
159  ret->beam().setIntensity(beam_item->intensity());
160  ret->setScan(scan);
161 
162  // ISimulation options
163  if (options_item)
164  TransformToDomain::setSimulationOptions(ret.get(), *options_item);
165 
166  addBackgroundToSimulation(*instrument, *ret);
167 
168  return ret;
169 }
170 
171 std::unique_ptr<DepthProbeSimulation>
172 createDepthProbeSimulation(std::unique_ptr<MultiLayer> P_multilayer,
173  const DepthProbeInstrumentItem* instrument,
174  const SimulationOptionsItem* options_item)
175 {
176  std::unique_ptr<DepthProbeSimulation> ret = instrument->createSimulation();
177  ret->setSample(*P_multilayer);
178 
179  if (options_item)
180  TransformToDomain::setSimulationOptions(ret.get(), *options_item);
181 
182  return ret;
183 }
184 
185 } // namespace
Declares AngularSpecScan class.
Defines various axis items.
Defines BackgroundItem classes.
Defines DepthProbeInstrumentItem class.
Defines class DepthProbeSimulation.
Defines classes DetectorItems.
Defines DomainObjectBuilder namespace.
Defines class DomainSimulationBuilder.
Declares FootprintItem classes.
Defines class GISASSimulation.
Defines class GUIHelpers functions.
Defines interface IBackground.
Defines interface IFootprintFactor.
Defines class MultiLayerItem.
Defines class OffSpecularSimulation.
Defines class SimulationOptionsItem.
Declares the class SpecularBeamInclinationItem.
Defines class SpecularSimulation.
Defines class TransformToDomain.
Defines some unit conversion factors and other constants in namespace Units.
Scan type with inclination angles as coordinate values and a unique wavelength.
virtual std::unique_ptr< IBackground > createBackground() const =0
std::unique_ptr< DepthProbeSimulation > createSimulation() const
Main class to run a Grazing-Incidence Small-Angle Scattering simulation.
Abstract base class of OffSpecularSimulation, GISASSimulation and SpecularSimulation.
Definition: ISimulation.h:38
void setBackground(const IBackground &bg)
virtual BeamItem * beamItem() const
BackgroundItem * backgroundItem() const
static const QString P_ALPHA_AXIS
Main class to run an off-specular simulation.
T * item(const QString &tag) const
Definition: SessionItem.h:151
The SimulationOptionsItem class holds simulation status (run policy, number of threads,...
BasicAxisItem * currentInclinationAxisItem()
Definition: BeamItems.cpp:161
SpecularBeamItem * beamItem() const override
std::unique_ptr< MultiLayer > buildMultiLayer(const SessionItem &multilayer_item)
std::unique_ptr< Instrument > buildInstrument(const InstrumentItem &instrumentItem)
std::unique_ptr< ISimulation > createSimulation(const MultiLayerItem *sampleItem, const InstrumentItem *instrumentItem, const SimulationOptionsItem *optionsItem=nullptr)
Creates domain simulation from sample and instrument items.
void addBeamDivergencesToScan(const SessionItem &beam_item, AngularSpecScan &simulation)
void addDistributionParametersToSimulation(const SessionItem &beam_item, GISASSimulation &simulation)
adds DistributionParameters to the ISimulation
void setSimulationOptions(ISimulation *simulation, const SessionItem &item)
static constexpr double deg
Definition: Units.h:46