BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
BeamItems.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Models/BeamItems.cpp
6 //! @brief Implements BeamItem hierarchy
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/Axis/IAxis.h"
17 #include "Base/Const/Units.h"
18 #include "Device/Beam/Beam.h"
29 #include <cmath>
30 
31 namespace {
32 const QString polarization_tooltip = "Polarization of the beam, given as the Bloch vector";
33 
34 // defines wavelength limits according to given maximum q value
35 RealLimits getLimits(double max_q);
36 } // namespace
37 
38 const QString BeamItem::P_INTENSITY = QString::fromStdString("Intensity");
39 const QString BeamItem::P_WAVELENGTH = QString::fromStdString("Wavelength");
40 const QString BeamItem::P_INCLINATION_ANGLE = QString::fromStdString("InclinationAngle");
41 const QString BeamItem::P_AZIMUTHAL_ANGLE = QString::fromStdString("AzimuthalAngle");
42 const QString BeamItem::P_POLARIZATION = "Polarization";
43 
44 BeamItem::BeamItem(const QString& beam_model) : SessionItem(beam_model)
45 {
46  addProperty(P_INTENSITY, 1e+08)
47  ->setLimits(RealLimits::limited(0.0, 1e+32))
48  .setToolTip("Beam intensity in neutrons (or gammas) per sec.")
49  .setEditorType("ScientificDouble");
50 
51  addProperty<BeamAzimuthalAngleItem>(P_AZIMUTHAL_ANGLE);
52  addProperty<VectorItem>(P_POLARIZATION)->setToolTip(polarization_tooltip);
53 
55 }
56 
57 BeamItem::~BeamItem() = default;
58 
59 double BeamItem::intensity() const
60 {
61  return getItemValue(P_INTENSITY).toDouble();
62 }
63 
64 void BeamItem::setIntensity(double value)
65 {
67 }
68 
69 double BeamItem::wavelength() const
70 {
71  return item<BeamWavelengthItem>(P_WAVELENGTH)->wavelength();
72 }
73 
74 void BeamItem::setWavelength(double value)
75 {
76  item<BeamWavelengthItem>(P_WAVELENGTH)->resetToValue(value);
77 }
78 
80 {
81  item<BeamDistributionItem>(P_INCLINATION_ANGLE)->resetToValue(value);
82 }
83 
85 {
86  return item<BeamAzimuthalAngleItem>(P_AZIMUTHAL_ANGLE)->azimuthalAngle();
87 }
88 
89 void BeamItem::setAzimuthalAngle(double value)
90 {
91  item<BeamDistributionItem>(P_AZIMUTHAL_ANGLE)->resetToValue(value);
92 }
93 
94 std::unique_ptr<Beam> BeamItem::createBeam() const
95 {
96  double lambda = wavelength();
97  double inclination_angle = Units::deg2rad(getInclinationAngle());
98  double azimuthal_angle = Units::deg2rad(getAzimuthalAngle());
99 
100  auto result =
101  std::make_unique<Beam>(intensity(), lambda, Direction(inclination_angle, azimuthal_angle));
102 
103  result->setPolarization(item<VectorItem>(P_POLARIZATION)->getVector());
104 
105  return result;
106 }
107 
108 // Specular beam item
109 /* ------------------------------------------------------------------------- */
110 
111 const QString SpecularBeamItem::P_FOOPTPRINT = "Footprint";
112 
113 const QString footprint_group_label("Type");
114 
116 {
117  addProperty<SpecularBeamInclinationItem>(P_INCLINATION_ANGLE);
118  addProperty<SpecularBeamWavelengthItem>(P_WAVELENGTH);
119 
122 
123  auto item = addGroupProperty(P_FOOPTPRINT, "Footprint group");
124  item->setDisplayName(footprint_group_label);
125  item->setToolTip("Footprint type");
126 
128  ->mapper()
130  [this](SessionItem*, QString property) {
131  if (property != SymmetricDistributionItem::P_MEAN)
132  return;
133  if (auto axis_item = dynamic_cast<PointwiseAxisItem*>(currentInclinationAxisItem()))
134  axis_item->updateIndicators();
135  },
136  this);
137 
138  inclinationAxisGroup()->mapper()->setOnValueChange([this]() { updateWavelength(); }, this);
139 }
140 
142 
144 {
145  return 0.0;
146 }
147 
149 {
150  ASSERT(value == 0.0);
151  value = 0.0;
153 }
154 
156 {
157  return dynamic_cast<GroupItem*>(
159 }
160 
162 {
163  return dynamic_cast<BasicAxisItem*>(inclinationAxisGroup()->currentItem());
164 }
165 
167 {
168  return &groupItem<FootprintItem>(P_FOOPTPRINT);
169 }
170 
172 {
173  item<SpecularBeamInclinationItem>(BeamItem::P_INCLINATION_ANGLE)->updateFileName(filename);
174 }
175 
176 void SpecularBeamItem::updateToData(const IAxis& axis, QString units)
177 {
178  if (units == "nbins") {
179  inclinationAxisGroup()->setCurrentType("BasicAxis");
180  auto axis_item = currentInclinationAxisItem();
181  axis_item->setBinCount(static_cast<int>(axis.size()));
182  return;
183  }
184 
185  auto axis_group = inclinationAxisGroup();
186  auto axis_item = static_cast<PointwiseAxisItem*>(axis_group->getChildOfType("PointwiseAxis"));
187  axis_item->init(axis, units);
188  axis_group->setCurrentType("PointwiseAxis"); // calls updateWavelength()
189  axis_item->updateIndicators();
190 }
191 
193 {
195  auto wl_item = static_cast<SpecularBeamWavelengthItem*>(getItem(P_WAVELENGTH));
196  if (auto axis_item = dynamic_cast<PointwiseAxisItem*>(item)) {
197  auto axis = axis_item->axis();
198  if (axis && axis_item->getUnitsLabel() == "q-space")
199  wl_item->setToRange(getLimits(axis->upperBound()));
200  } else
201  wl_item->setToRange(RealLimits::positive());
202 }
203 
204 // GISAS beam item
205 /* ------------------------------------------------------------------------- */
206 
208 {
209  addProperty<BeamInclinationAngleItem>(P_INCLINATION_ANGLE);
210  addProperty<BeamWavelengthItem>(P_WAVELENGTH);
211 }
212 
214 
216 {
217  return item<BeamInclinationAngleItem>(P_INCLINATION_ANGLE)->inclinationAngle();
218 }
219 
220 namespace {
221 RealLimits getLimits(double max_q)
222 {
223  double upper_lim = std::nextafter(4.0 * M_PI / max_q, 0.0);
224  RealLimits result = RealLimits::positive();
225  result.setUpperLimit(upper_lim);
226  return result;
227 }
228 } // namespace
#define ASSERT(condition)
Definition: Assert.h:31
Defines class BeamAngleItems.
const QString footprint_group_label("Type")
Defines BeamItem hierarchy.
Defines class BeamWavelengthItem.
Defines class Beam.
#define M_PI
Definition: Constants.h:44
Declares FootprintItem classes.
Defines class GUIHelpers functions.
Defines class GroupItem.
Defines interface IAxis.
Defines interface IParameterTranslator and subclasses.
Defines pointwise axis item.
Defines namespace SessionItemUtils.
Declares the class SpecularBeamInclinationItem.
Defines some unit conversion factors and other constants in namespace Units.
Defines class VectorItem.
static const QString P_AZIMUTHAL_ANGLE
Definition: BeamItems.h:31
~BeamItem() override
std::unique_ptr< Beam > createBeam() const
Definition: BeamItems.cpp:94
double intensity() const
Definition: BeamItems.cpp:59
void setWavelength(double value)
Definition: BeamItems.cpp:74
static const QString P_WAVELENGTH
Definition: BeamItems.h:29
static const QString P_INCLINATION_ANGLE
Definition: BeamItems.h:30
virtual void setInclinationAngle(double value)
Definition: BeamItems.cpp:79
void setIntensity(double value)
Definition: BeamItems.cpp:64
void setAzimuthalAngle(double value)
Definition: BeamItems.cpp:89
BeamItem(const QString &beam_model)
Definition: BeamItems.cpp:44
double wavelength() const
Definition: BeamItems.cpp:69
virtual double getInclinationAngle() const =0
double getAzimuthalAngle() const
Definition: BeamItems.cpp:84
static const QString P_INTENSITY
Definition: BeamItems.h:28
static const QString P_POLARIZATION
Definition: BeamItems.h:32
A direction in three-dimensional space.
Definition: Direction.h:24
double getInclinationAngle() const override
Definition: BeamItems.cpp:215
~GISASBeamItem() override
SessionItem * setCurrentType(const QString &modelType)
Definition: GroupItem.cpp:51
SessionItem * currentItem() const
Definition: GroupItem.cpp:41
Interface for one-dimensional axes.
Definition: IAxis.h:25
virtual size_t size() const =0
retrieve the number of bins
void setOnValueChange(std::function< void(void)> f, const void *caller=0)
Definition: ModelMapper.cpp:30
void setOnChildPropertyChange(std::function< void(SessionItem *, QString)> f, const void *caller=0)
Calls back on child property change, report childItem and property name.
Definition: ModelMapper.cpp:49
Item for non-uniform axis with specified coordinates.
void init(const IAxis &axis, const QString &units_label)
Limits for a real fit parameter.
Definition: RealLimits.h:24
static RealLimits positive()
Creates an object which can have only positive values (>0., zero is not included)
Definition: RealLimits.cpp:110
static RealLimits limited(double left_bound_value, double right_bound_value)
Creates an object bounded from the left and right.
Definition: RealLimits.cpp:125
void setUpperLimit(double value)
Sets upper limit.
Definition: RealLimits.cpp:67
SessionItem * addProperty(const QString &name, const QVariant &variant)
Add new property item and register new tag.
QVariant value() const
Get value.
void setVisible(bool enabled)
Flags accessors.
SessionItem & setEditorType(const QString &editorType)
QVariant getItemValue(const QString &tag) const
Directly access value of item under given tag.
SessionItem * addGroupProperty(const QString &groupTag, const QString &groupType)
Creates new group item and register new tag, returns GroupItem.
ModelMapper * mapper()
Returns the current model mapper of this item. Creates new one if necessary.
void addTranslator(const IPathTranslator &translator)
T * item(const QString &tag) const
Definition: SessionItem.h:151
void setItemValue(const QString &tag, const QVariant &variant)
Directly set value of item under given tag.
SessionItem & setToolTip(const QString &tooltip)
SessionItem * getItem(const QString &tag="", int row=0) const
Returns item in given row of given tag.
SessionItem & setLimits(const RealLimits &value)
static const QString P_FOOPTPRINT
Definition: BeamItems.h:56
void updateWavelength()
Definition: BeamItems.cpp:192
void setInclinationAngle(double value) override
Definition: BeamItems.cpp:148
FootprintItem * currentFootprintItem() const
Definition: BeamItems.cpp:166
GroupItem * inclinationAxisGroup()
Definition: BeamItems.cpp:155
BasicAxisItem * currentInclinationAxisItem()
Definition: BeamItems.cpp:161
void updateFileName(const QString &filename)
Definition: BeamItems.cpp:171
~SpecularBeamItem() override
void updateToData(const IAxis &axis, QString units)
Definition: BeamItems.cpp:176
double getInclinationAngle() const override
Definition: BeamItems.cpp:143
void setToRange(const RealLimits &limits)
static const QString P_MEAN
std::string filename(const std::string &path)
Returns path without directory part ("Foo/Bar/Doz.int.gz" -> "Doz.int.gz")
double deg2rad(double angle)
Definition: Units.h:59