BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
InstrumentItems.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Models/InstrumentItems.cpp
6 //! @brief Implements InstrumentItems classes
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 
31 
32 namespace {
33 const QString background_group_label = "Type";
34 const QStringList instrument_names{"GISASInstrument", "OffSpecularInstrument",
35  "SpecularInstrument"};
36 void addAxisGroupProperty(SessionItem* parent, const QString& tag);
37 } // namespace
38 
39 const QString InstrumentItem::P_IDENTIFIER = "Identifier";
40 const QString InstrumentItem::P_BEAM = "Beam";
41 const QString InstrumentItem::P_BACKGROUND = "Background";
42 
43 QStringList InstrumentItem::translateList(const QStringList& list) const
44 {
45  QStringList result;
46  if (list.back().endsWith(P_BACKGROUND) && list.size() == 2) {
47  result << list[0] << list[1];
48  } else {
49  result = SessionItem::translateList(list);
50  if (instrument_names.contains(result.back())) {
51  result.removeLast();
52  result << "Instrument";
53  }
54  }
55  return result;
56 }
57 
58 QString InstrumentItem::id() const
59 {
60  return getItemValue(P_IDENTIFIER).toString();
61 }
62 
63 void InstrumentItem::setId(const QString& id)
64 {
66 }
67 
68 void InstrumentItem::setName(const QString& instrumentName)
69 {
70  setItemName(instrumentName);
71 }
72 
73 QString InstrumentItem::name() const
74 {
75  return itemName();
76 }
77 
79 {
80  return item<BeamItem>(P_BEAM);
81 }
82 
84 {
85  return &groupItem<BackgroundItem>(P_BACKGROUND);
86 }
87 
89 {
90  return item<GroupItem>(P_BACKGROUND);
91 }
92 
94 {
95  return shape() == item->shape();
96 }
97 
98 std::unique_ptr<Instrument> InstrumentItem::createInstrument() const
99 {
100  std::unique_ptr<Instrument> result(new Instrument);
101 
102  auto beam = beamItem()->createBeam();
103  result->setBeam(*beam);
104 
105  return result;
106 }
107 
108 InstrumentItem::InstrumentItem(const QString& modelType) : SessionItem(modelType)
109 {
112 }
113 
115 {
116  auto item = addGroupProperty(P_BACKGROUND, "Background group");
117  item->setDisplayName(background_group_label);
118  item->setToolTip("Background type");
119 }
120 
122 {
123  addProperty<SpecularBeamItem>(P_BEAM);
124 
126  item<SpecularBeamItem>(P_BEAM)->updateFileName(
128 }
129 
131 {
132  return item<SpecularBeamItem>(P_BEAM);
133 }
134 
136 
137 std::unique_ptr<Instrument> SpecularInstrumentItem::createInstrument() const
138 {
140 }
141 
142 std::vector<int> SpecularInstrumentItem::shape() const
143 {
144  const auto axis_item = beamItem()->currentInclinationAxisItem();
145  return {axis_item->binCount()};
146 }
147 
149 {
150  if (shape().size() != item->shape().size())
151  throw GUIHelpers::Error("Error in SpecularInstrumentItem::updateToRealData: The type "
152  "of instrument is incompatible with passed data shape.");
153 
154  const auto& data = item->nativeOutputData()->axis(0);
155  beamItem()->updateToData(data, item->nativeDataUnits());
156 }
157 
159 {
160  const QString native_units = item->nativeDataUnits();
161  if (native_units == "nbins") {
162  return beamItem()->currentInclinationAxisItem()->modelType() == "BasicAxis"
163  && shape() == item->shape();
164  } else {
165  auto axis_item = dynamic_cast<PointwiseAxisItem*>(beamItem()->currentInclinationAxisItem());
166  if (!axis_item)
167  return false;
168  if (axis_item->getUnitsLabel() != native_units)
169  return false;
170 
171  auto instrument_axis = axis_item->axis();
172  if (!instrument_axis)
173  return false;
174 
175  if (!item->hasNativeData())
176  return false;
177 
178  const auto& native_axis = item->nativeOutputData()->axis(0);
179  return *instrument_axis == native_axis;
180  ;
181  }
182 }
183 
184 std::unique_ptr<IUnitConverter> SpecularInstrumentItem::createUnitConverter() const
185 {
186  const auto instrument = createInstrument();
187  auto axis_item = beamItem()->currentInclinationAxisItem();
188  if (auto pointwise_axis = dynamic_cast<PointwiseAxisItem*>(axis_item)) {
189  if (!pointwise_axis->containsNonXMLData()) // workaround for loading project
190  return nullptr;
191  Axes::Units native_units = JobItemUtils::axesUnitsFromName(pointwise_axis->getUnitsLabel());
192  return std::make_unique<UnitConverterConvSpec>(instrument->beam(), *pointwise_axis->axis(),
193  native_units);
194  } else
195  return std::make_unique<UnitConverterConvSpec>(
196  instrument->beam(), *axis_item->createAxis(1.0), Axes::Units::DEGREES);
197 }
198 
200 {
201  return "Specular";
202 }
203 
204 const QString Instrument2DItem::P_DETECTOR = "Detector";
205 
206 Instrument2DItem::Instrument2DItem(const QString& modelType) : InstrumentItem(modelType)
207 {
208  addProperty<GISASBeamItem>(P_BEAM);
209  addGroupProperty(P_DETECTOR, "Detector group");
211 
213 }
214 
216 
218 {
219  return &groupItem<DetectorItem>(P_DETECTOR);
220 }
221 
223 {
224  return item<GroupItem>(P_DETECTOR);
225 }
226 
227 void Instrument2DItem::setDetectorGroup(const QString& modelType)
228 {
230 }
231 
233 {
235 }
236 
238 {
239  detectorItem()->importMasks(maskContainer);
240 }
241 
242 std::unique_ptr<Instrument> Instrument2DItem::createInstrument() const
243 {
244  auto result = InstrumentItem::createInstrument();
245 
246  auto detector = detectorItem()->createDetector();
247  result->setDetector(*detector);
248 
249  return result;
250 }
251 
253 
254 std::vector<int> GISASInstrumentItem::shape() const
255 {
256  auto detector_item = detectorItem();
257  return {detector_item->xSize(), detector_item->ySize()};
258 }
259 
261 {
262  if (!item)
263  return;
264 
265  const auto data_shape = item->shape();
266  if (shape().size() != data_shape.size())
267  throw GUIHelpers::Error("Error in GISASInstrumentItem::updateToRealData: The type of "
268  "instrument is incompatible with passed data shape.");
269  detectorItem()->setXSize(data_shape[0]);
270  detectorItem()->setYSize(data_shape[1]);
271 }
272 
274 {
275  return "GISAS";
276 }
277 
278 const QString OffSpecularInstrumentItem::P_ALPHA_AXIS = "Alpha axis";
279 
281 {
282  addAxisGroupProperty(this, P_ALPHA_AXIS);
283  auto inclination_item = getItem(P_ALPHA_AXIS)->getItem(BasicAxisItem::P_MIN_DEG);
284  auto beam_item = beamItem();
285  beam_item->setInclinationAngle(inclination_item->value().toDouble());
286  beam_item->getItem(BeamItem::P_INCLINATION_ANGLE)->setEnabled(false);
287  inclination_item->mapper()->setOnValueChange([beam_item, inclination_item]() {
288  beam_item->setInclinationAngle(inclination_item->value().toDouble());
289  });
290 }
291 
292 std::vector<int> OffSpecularInstrumentItem::shape() const
293 {
294  const int x_size = item<BasicAxisItem>(P_ALPHA_AXIS)->binCount();
295  auto detector_item = detectorItem();
296  return {x_size, detector_item->ySize()};
297 }
298 
300 {
301  if (!dataItem)
302  return;
303 
304  const auto data_shape = dataItem->shape();
305  if (shape().size() != data_shape.size())
306  throw GUIHelpers::Error("Error in OffSpecularInstrumentItem::updateToRealData: The type of "
307  "instrument is incompatible with passed data shape.");
308 
309  item<BasicAxisItem>(P_ALPHA_AXIS)->setBinCount(data_shape[0]);
310  detectorItem()->setYSize(data_shape[1]);
311 }
312 
314 {
315  return "OffSpecular";
316 }
317 
318 namespace {
319 void addAxisGroupProperty(SessionItem* parent, const QString& tag)
320 {
321  auto axisItem = parent->addProperty<BasicAxisItem>(tag);
322  axisItem->setToolTip("Incoming alpha range [deg]");
323  axisItem->getItem(BasicAxisItem::P_TITLE)->setVisible(false);
324  axisItem->getItem(BasicAxisItem::P_NBINS)->setToolTip("Number of points in scan");
325  axisItem->getItem(BasicAxisItem::P_MIN_DEG)->setToolTip("Starting value [deg]");
326  axisItem->getItem(BasicAxisItem::P_MAX_DEG)->setToolTip("Ending value [deg]");
327 
328  axisItem->setTitle("alpha_i");
329  axisItem->setLowerBound(0.0);
330  axisItem->setUpperBound(10.0);
331 }
332 } // namespace
Defines BackgroundItem classes.
Defines BeamItem hierarchy.
Declares class DataItem.
Defines classes DetectorItems.
Defines class GUIHelpers functions.
Defines class GroupItem.
Defines interface IDetector2D.
Defines InstrumentItems classes.
Defines class Instrument.
Defines auxiliary functions in ItemFileNameUtils namespace.
Defines class JobItemUtils.
Defines MaskItems classes.
Defines pointwise axis item.
Defines class RealDataItem.
Defines class SessionModel.
Defines UnitConverter1D class and derived classes.
static const QString P_NBINS
Definition: AxesItems.h:26
static const QString P_MAX_DEG
Definition: AxesItems.h:28
static const QString P_TITLE
Definition: AxesItems.h:29
int binCount() const
Definition: AxesItems.cpp:32
static const QString P_MIN_DEG
Definition: AxesItems.h:27
std::unique_ptr< Beam > createBeam() const
Definition: BeamItems.cpp:94
static const QString P_INCLINATION_ANGLE
Definition: BeamItems.h:30
virtual void setXSize(int nx)=0
sets the size of x-axis of the detector
void importMasks(const MaskContainerItem *maskContainer)
std::unique_ptr< IDetector2D > createDetector() const
virtual void setYSize(int ny)=0
sets the size of y-axis of the detector
std::vector< int > shape() const override
virtual QString defaultName() const override
The default user visible name when creating an instrument.
void updateToRealData(const RealDataItem *item) override
GroupItem * detectorGroup()
void setDetectorGroup(const QString &modelType)
void clearMasks() override
Instrument2DItem(const QString &modelType)
DetectorItem * detectorItem() const
std::unique_ptr< Instrument > createInstrument() const override
~Instrument2DItem() override
static const QString P_DETECTOR
void importMasks(const MaskContainerItem *maskContainer) override
GroupItem * backgroundGroup()
void setName(const QString &instrumentName)
static const QString P_IDENTIFIER
InstrumentItem(const QString &modelType)
QString id() const
static const QString P_BEAM
void setId(const QString &id)
virtual std::vector< int > shape() const =0
virtual BeamItem * beamItem() const
virtual std::unique_ptr< Instrument > createInstrument() const =0
static const QString P_BACKGROUND
virtual bool alignedWith(const RealDataItem *item) const
BackgroundItem * backgroundItem() const
QStringList translateList(const QStringList &list) const override
QString name() const
Assembles beam, detector and their relative positions with respect to the sample.
Definition: Instrument.h:32
Container holding various masks as children.
Definition: MaskItems.h:24
static const QString P_ALPHA_AXIS
void updateToRealData(const RealDataItem *item) override
std::vector< int > shape() const override
virtual QString defaultName() const override
The default user visible name when creating an instrument.
Item for non-uniform axis with specified coordinates.
const IAxis * axis() const
The RealDataItem class represents intensity data imported from file and intended for fitting.
Definition: RealDataItem.h:35
std::vector< int > shape() const
Returns the shape of underlying data item.
QString itemName() const
Get item name, return display name if no name is set.
void setItemName(const QString &name)
Set item name, add property if necessary.
SessionItem * addProperty(const QString &name, const QVariant &variant)
Add new property item and register new tag.
void setVisible(bool enabled)
Flags accessors.
virtual QStringList translateList(const QStringList &list) const
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.
void setDefaultTag(const QString &tag)
Set default tag.
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 * setGroupProperty(const QString &groupTag, const QString &modelType) const
Set the current type of group item.
SessionItem & setToolTip(const QString &tooltip)
QString modelType() const
Get model type.
SessionItem * getItem(const QString &tag="", int row=0) const
Returns item in given row of given tag.
BasicAxisItem * currentInclinationAxisItem()
Definition: BeamItems.cpp:161
void updateToData(const IAxis &axis, QString units)
Definition: BeamItems.cpp:176
std::unique_ptr< Instrument > createInstrument() const override
~SpecularInstrumentItem() override
SpecularBeamItem * beamItem() const override
std::vector< int > shape() const override
virtual QString defaultName() const override
The default user visible name when creating an instrument.
void updateToRealData(const RealDataItem *item) override
bool alignedWith(const RealDataItem *item) const override
std::unique_ptr< IUnitConverter > createUnitConverter() const
QString createUuid()
Definition: GUIHelpers.cpp:242
QString instrumentDataFileName(const InstrumentItem &instrumentItem)
Axes::Units axesUnitsFromName(const QString &name)
returns domain axes units type from their GUI name