BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
JobItemUtils.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Models/JobItemUtils.cpp
6 //! @brief Implements class JobItemUtils
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 
24 #include <QDebug>
25 #include <QFileInfo>
26 
27 namespace {
28 const std::map<QString, Axes::Units> units_from_names{{"nbins", Axes::Units::NBINS},
29  {"Radians", Axes::Units::RADIANS},
30  {"Degrees", Axes::Units::DEGREES},
31  {"mm", Axes::Units::MM},
32  {"q-space", Axes::Units::QSPACE}};
33 
34 const std::map<Axes::Units, QString> names_from_units{{Axes::Units::NBINS, "nbins"},
35  {Axes::Units::RADIANS, "Radians"},
36  {Axes::Units::MM, "mm"},
37  {Axes::Units::QSPACE, "q-space"},
38  {Axes::Units::DEGREES, "Degrees"}};
39 
40 //! Updates axes' titles
41 void updateAxesTitle(DataItem* intensityItem, const IUnitConverter& converter, Axes::Units units);
42 } // namespace
43 
44 //! Updates axes of OutputData in IntensityData item to correspond with ::P_AXES_UNITS selection.
45 //! InstrumentItem is used to get domain's detector map for given units.
46 
47 void JobItemUtils::updateDataAxes(DataItem* intensityItem, const InstrumentItem* instrumentItem)
48 {
49  ASSERT(intensityItem);
50 
51  if (!instrumentItem) {
52  // special case when reading old project files: project failed on load instrument
53  // but we want to try to recover the rest.
54  qInfo() << "JobItemUtils::updateDataAxes() -> Error. Absent instrument.";
55  return;
56  }
57 
58  if (!intensityItem->getOutputData())
59  return;
60 
61  Axes::Units requested_units = axesUnitsFromName(intensityItem->selectedAxesUnits());
62 
63  const auto converter = DomainObjectBuilder::createUnitConverter(instrumentItem);
64  auto newData = UnitConverterUtils::createOutputData(*converter.get(), requested_units);
65  newData->setRawDataVector(intensityItem->getOutputData()->getRawDataVector());
66 
67  intensityItem->setOutputData(newData.release());
68  intensityItem->setAxesRangeToData();
69  updateAxesTitle(intensityItem, *converter, requested_units);
70 }
71 
72 //! Correspondance of domain detector axes types to their gui counterpart.
73 
75 {
76  return names_from_units.find(units) != names_from_units.end() ? names_from_units.at(units)
77  : QString();
78 }
79 
80 //! Correspondance of GUI axes units names to their domain counterpart.
81 
83 {
84  return units_from_names.at(name);
85 }
86 
87 //! Sets axes units suitable for given instrument.
88 
90  const InstrumentItem* instrumentItem)
91 {
92  const auto converter = DomainObjectBuilder::createUnitConverter(instrumentItem);
93  if (!converter)
94  return;
95  setIntensityItemAxesUnits(intensityItem, *converter);
96 }
97 
99  const IUnitConverter& converter)
100 {
101  ComboProperty combo = availableUnits(converter);
102  intensityItem->setItemValue(DataItem::P_AXES_UNITS, combo.variant());
103 }
104 
106  const InstrumentItem* instrumentItem)
107 {
108  const auto converter = DomainObjectBuilder::createUnitConverter(instrumentItem);
109  auto output_data = UnitConverterUtils::createOutputData(*converter, converter->defaultUnits());
110  intensityItem->setOutputData(output_data.release());
111  setIntensityItemAxesUnits(intensityItem, *converter);
112  updateAxesTitle(intensityItem, *converter, converter->defaultUnits());
113 }
114 
115 void JobItemUtils::setResults(DataItem* intensityItem, const ISimulation* simulation)
116 {
117  const auto sim_result = simulation->result();
118  if (intensityItem->getOutputData() == nullptr) {
119  const auto& converter = sim_result.converter();
120  JobItemUtils::setIntensityItemAxesUnits(intensityItem, converter);
121  updateAxesTitle(intensityItem, converter, converter.defaultUnits());
122  }
123  auto selected_units = JobItemUtils::axesUnitsFromName(intensityItem->selectedAxesUnits());
124  auto data = sim_result.data(selected_units);
125  intensityItem->setOutputData(data.release());
126 }
127 
129 {
130  ComboProperty result;
131  for (auto units : converter.availableUnits()) {
132  auto unit_name = nameFromAxesUnits(units);
133  if (unit_name != "")
134  result << unit_name;
135  }
136 
137  result.setValue(nameFromAxesUnits(converter.defaultUnits()));
138  return result;
139 }
140 
141 namespace {
142 void updateAxesTitle(DataItem* intensityItem, const IUnitConverter& converter, Axes::Units units)
143 {
144  intensityItem->setXaxisTitle(QString::fromStdString(converter.axisName(0, units)));
145  if (converter.dimension() > 1)
146  intensityItem->setYaxisTitle(QString::fromStdString(converter.axisName(1, units)));
147 }
148 } // namespace
#define ASSERT(condition)
Definition: Assert.h:31
Declares class DataItem.
Defines DomainObjectBuilder namespace.
Defines class GUIHelpers functions.
Defines interface ISimulation.
Defines InstrumentItems classes.
Defines class JobItemUtils.
Defines class JobItem.
Defines class RealDataItem.
Declares utilities for unit converters.
Custom property to define list of string values with multiple selections.
Definition: ComboProperty.h:25
QVariant variant() const
Constructs variant enclosing given ComboProperty.
void setValue(const QString &name)
Provides common functionality for IntensityDataItem and SpecularDataItem.
Definition: DataItem.h:29
virtual void setAxesRangeToData()=0
OutputData< double > * getOutputData()
Definition: DataItem.h:36
virtual void setOutputData(OutputData< double > *data)=0
The given pointer becomes owned by this class!!
Definition: DataItem.cpp:24
virtual void setXaxisTitle(const QString &title)=0
QString selectedAxesUnits() const
Definition: DataItem.cpp:87
virtual void setYaxisTitle(const QString &title)=0
static const QString P_AXES_UNITS
Definition: DataItem.h:34
Abstract base class of OffSpecularSimulation, GISASSimulation and SpecularSimulation.
Definition: ISimulation.h:38
virtual SimulationResult result() const =0
Returns the results of the simulation in a format that supports unit conversion and export to numpy a...
Interface to provide axis translations to different units for simulation output.
virtual size_t dimension() const =0
virtual Axes::Units defaultUnits() const =0
virtual std::vector< Axes::Units > availableUnits() const =0
std::string axisName(size_t i_axis, Axes::Units units_type=Axes::Units::DEFAULT) const
std::vector< T > getRawDataVector() const
Returns copy of raw data vector.
Definition: OutputData.h:334
void setItemValue(const QString &tag, const QVariant &variant)
Directly set value of item under given tag.
const IUnitConverter & converter() const
Returns underlying unit converter.
void updateAxesTitle(Data1DViewItem *view_item)
std::unique_ptr< IUnitConverter > createUnitConverter(const InstrumentItem *instrumentItem)
Creates a unit converter corresponding to the given instrument item.
ComboProperty availableUnits(const IUnitConverter &converter)
void setResults(DataItem *intensityItem, const ISimulation *simulation)
Sets simulation results into the DataItem.
void updateDataAxes(DataItem *intensityItem, const InstrumentItem *instrumentItem)
updates axes of OutputData in IntensityData item
Axes::Units axesUnitsFromName(const QString &name)
returns domain axes units type from their GUI name
QString nameFromAxesUnits(Axes::Units units)
returns axes units names from their domain counterpart
void setIntensityItemAxesUnits(DataItem *intensityItem, const InstrumentItem *instrumentItem)
Sets axes units suitable for given instrument.
void createDefaultDetectorMap(DataItem *intensityItem, const InstrumentItem *instrumentItem)
QString const & name(EShape k)
Definition: particles.cpp:21
std::unique_ptr< OutputData< double > > createOutputData(const IUnitConverter &converter, Axes::Units units)
Returns zero-valued output data array in specified units.