BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
FitParameterItem.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/Model/Job/FitParameterItem.cpp
6 //! @brief Implements FitParameterItems family of 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 
16 #include "Base/Util/Assert.h"
19 #include "GUI/Util/ComboProperty.h"
20 
21 namespace {
22 
23 ComboProperty fitParameterTypeCombo()
24 {
25  QStringList tooltips = QStringList() << "Fixed at given value"
26  << "Limited in the range [min, max]"
27  << "Limited at lower bound [min, inf]"
28  << "Limited at upper bound [-inf, max]"
29  << "No limits imposed to parameter value";
30 
31  ComboProperty result;
32  result << "fixed"
33  << "limited"
34  << "lower limited"
35  << "upper limited"
36  << "free";
37  result.setValue("limited");
38  result.setToolTips(tooltips);
39  return result;
40 }
41 
42 const double range_factor = 0.5;
43 
44 } // namespace
45 
46 
48  : SessionItem(M_TYPE)
49 {
50  addProperty(P_TYPE, fitParameterTypeCombo().variant());
52  addProperty(P_MIN, 0.0);
53  addProperty(P_MAX, 0.0)->setEnabled(false);
56 
57  getItem(P_START_VALUE)->setLimits(RealLimits::limitless());
58  getItem(P_MIN)->setLimits(RealLimits::limitless());
59  getItem(P_MAX)->setLimits(RealLimits::limitless());
60 
61  mapper()->setOnPropertyChange([this](const QString& name) {
62  if (name == P_TYPE)
63  onTypeChange();
64  });
65 
66  onTypeChange();
67 }
68 
69 //! Inits P_MIN and P_MAX taking into account current value and external limits
70 
71 void FitParameterItem::initMinMaxValues(const RealLimits& limits)
72 {
73  double value = getItemValue(P_START_VALUE).toDouble();
74 
75  double dr(0);
76  if (value == 0.0)
77  dr = 1.0 * range_factor;
78  else
79  dr = std::abs(value) * range_factor;
80 
81  double min = value - dr;
82  double max = value + dr;
83 
84  if (limits.hasLowerLimit() && min < limits.lowerLimit())
85  min = limits.lowerLimit();
86 
87  if (limits.hasUpperLimit() && max > limits.upperLimit())
88  max = limits.upperLimit();
89 
90  setItemValue(P_MIN, min);
92  setItemValue(P_MAX, max);
94 
96 }
97 
98 //! Constructs Limits correspodning to current GUI settings.
99 
101 {
102  if (isFixed())
103  return AttLimits::fixed();
104  if (isLimited())
105  return AttLimits::limited(getItemValue(P_MIN).toDouble(), getItemValue(P_MAX).toDouble());
106  if (isLowerLimited())
107  return AttLimits::lowerLimited(getItemValue(P_MIN).toDouble());
108  if (isUpperLimited())
109  return AttLimits::upperLimited(getItemValue(P_MAX).toDouble());
110  if (isFree())
111  return AttLimits::limitless();
112  ASSERT(0);
113 }
114 
116 {
117  if (isFixed() || isFree())
118  return true;
119 
120  double value = getItemValue(P_START_VALUE).toDouble();
121  double min = getItemValue(P_MIN).toDouble();
122  double max = getItemValue(P_MAX).toDouble();
123 
124  if (isLowerLimited())
125  return min <= value;
126  if (isUpperLimited())
127  return value <= max;
128  return min <= value && value <= max;
129 }
130 
132 {
133  return getItemValue(P_START_VALUE).toDouble();
134 }
135 
136 void FitParameterItem::setStartValue(const double start_value)
137 {
138  setItemValue(P_START_VALUE, start_value);
139 }
140 
142 {
143  return getItem(P_START_VALUE);
144 }
145 
147 {
148  return getItemValue(P_MIN).toDouble();
149 }
150 
151 void FitParameterItem::setMinimum(const double minimum)
152 {
154 }
155 
157 {
158  return getItem(P_MIN);
159 }
160 
162 {
163  return getItemValue(P_MAX).toDouble();
164 }
165 
166 void FitParameterItem::setMaximum(const double maximum)
167 {
169 }
170 
172 {
173  return getItem(P_MAX);
174 }
175 
176 void FitParameterItem::addLink(const QString& title, const QString& link)
177 {
178  auto* newLink = model()->insertItem<FitParameterLinkItem>(this);
179  newLink->setTitle(title);
180  newLink->setLink(link);
181 }
182 
183 QVector<FitParameterLinkItem*> FitParameterItem::linkItems() const
184 {
185  return items<FitParameterLinkItem>(T_LINK);
186 }
187 
188 QStringList FitParameterItem::links() const
189 {
190  QStringList links;
191  for (FitParameterLinkItem* linkItem : linkItems())
192  links << linkItem->link();
193  return links;
194 }
195 
196 void FitParameterItem::removeLink(const QString& link)
197 {
198  for (FitParameterLinkItem* linkItem : linkItems()) {
199  if (linkItem->link() == link)
200  model()->removeRow(linkItem->index().row(), linkItem->index().parent());
201  }
202 }
203 
205 {
206  return getItem(P_TYPE);
207 }
208 
210 {
211  auto partype = getItemValue(P_TYPE).value<ComboProperty>();
212  return partype.getValue();
213 }
214 
215 //! Enables/disables min, max properties on FitParameterItem's type
216 
218 {
219  if (isFixed()) {
220  setLimitEnabled(P_MIN, false);
221  setLimitEnabled(P_MAX, false);
222  }
223 
224  else if (isLimited()) {
225  setLimitEnabled(P_MIN, true);
226  setLimitEnabled(P_MAX, true);
227  }
228 
229  else if (isLowerLimited()) {
230  setLimitEnabled(P_MIN, true);
231  setLimitEnabled(P_MAX, false);
232  }
233 
234  else if (isUpperLimited()) {
235  setLimitEnabled(P_MIN, false);
236  setLimitEnabled(P_MAX, true);
237  }
238 
239  else if (isFree()) {
240  setLimitEnabled(P_MIN, false);
241  setLimitEnabled(P_MAX, false);
242  }
243 }
244 
245 //! Set limit property with given name to the enabled state
246 
247 void FitParameterItem::setLimitEnabled(const QString& name, bool enabled)
248 {
249  if (isTag(name)) {
250  SessionItem* propertyItem = getItem(name);
251  ASSERT(propertyItem);
252  propertyItem->setEnabled(enabled);
253  propertyItem->setEditable(enabled);
254  }
255 }
256 
258 {
259  return parameterType() == "limited";
260 }
261 
263 {
264  return parameterType() == "free";
265 }
266 
268 {
269  return parameterType() == "lower limited";
270 }
271 
273 {
274  return parameterType() == "upper limited";
275 }
276 
278 {
279  return parameterType() == "fixed";
280 }
Defines class ComboProperty.
Defines class FitParameterItem.
Defines class FitParameterLinkItem.
Defines class SessionModel.
Custom property to define list of string values with multiple selections. Intended for QVariant.
Definition: ComboProperty.h:25
void setValue(const QString &name)
QString getValue() const
void setToolTips(const QStringList &tooltips)
double minimum() const
SessionItem * minimumItem() const
void setMaximum(double maximum)
double maximum() const
SessionItem * maximumItem() const
bool isLimited() const
QVector< FitParameterLinkItem * > linkItems() const
void setLimitEnabled(const QString &name, bool enabled)
Set limit property with given name to the enabled state.
bool isUpperLimited() const
void setStartValue(double start_value)
SessionItem * typeItem() const
void removeLink(const QString &link)
QStringList links() const
static constexpr auto T_LINK
void onTypeChange()
Enables/disables min, max properties on FitParameterItem's type.
static constexpr auto P_MIN
static constexpr auto P_START_VALUE
bool isLowerLimited() const
double startValue() const
void setMinimum(double minimum)
void initMinMaxValues(const RealLimits &limits)
Inits P_MIN and P_MAX taking into account current value and external limits.
QString parameterType() const
SessionItem * startValueItem() const
static constexpr auto P_MAX
void addLink(const QString &title, const QString &link)
AttLimits attLimits() const
Constructs Limits correspodning to current GUI settings.
static constexpr auto P_TYPE
The FitParameterLinkItem class holds a link to ParameterItem in tuning tree.
void setTitle(const QString &title)
static constexpr auto M_TYPE
void setOnPropertyChange(std::function< void(QString)> f, const void *caller=nullptr)
Definition: ModelMapper.cpp:39
Base class for a GUI data item.
Definition: SessionItem.h:204
bool isTag(const QString &name) const
Returns true if tag is available.
SessionItem * addProperty(const QString &name, const QVariant &variant)
Add new property item and register new tag. name is the tag name and the display name....
bool registerTag(const QString &name, int min=0, int max=-1, QStringList modelTypes={})
Add new tag to this item with given name, min, max and types. max = -1 -> unlimited,...
QVariant value() const
Get value.
QVariant getItemValue(const QString &tag) const
Directly access value of item under given tag.
void setItemValue(const QString &tag, const QVariant &variant) const
Directly set value of item under given tag.
ModelMapper * mapper()
Returns the current model mapper of this item. Creates new one if necessary.
void setDefaultTag(const QString &tag)
Set default tag.
SessionModel * model() const
Returns model of this item.
Definition: SessionItem.cpp:60
void setEditable(bool enabled)
RealLimits limits() const
void setEnabled(bool enabled)
Flags accessors.
SessionItem * getItem(const QString &tag="", int row=0) const
Returns item in given row of given tag.
SessionItem & setLimits(const RealLimits &value)
T * insertItem(SessionItem *parent=nullptr, int row=-1, QString tag="")
Definition: SessionModel.h:137
QString const & name(EShape k)
Definition: particles.cpp:20