BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
FitParameterItems.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Models/FitParameterItems.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 "Fit/Param/Parameters.h"
22 #include <cmath>
23 
24 namespace {
25 
26 ComboProperty fitParameterTypeCombo()
27 {
28  QStringList tooltips = QStringList() << "Fixed at given value"
29  << "Limited in the range [min, max]"
30  << "Limited at lower bound [min, inf]"
31  << "Limited at upper bound [-inf, max]"
32  << "No limits imposed to parameter value";
33 
34  ComboProperty result;
35  result << "fixed"
36  << "limited"
37  << "lower limited"
38  << "upper limited"
39  << "free";
40  result.setValue("limited");
41  result.setToolTips(tooltips);
42  return result;
43 }
44 
45 const double range_factor = 0.5;
46 } // namespace
47 
48 // ----------------------------------------------------------------------------
49 
50 const QString FitParameterLinkItem::P_LINK = "Link";
51 const QString FitParameterLinkItem::P_DOMAIN = "Domain";
52 
54 {
55  addProperty(P_LINK, "");
56  addProperty(P_DOMAIN, "");
57 }
58 
59 // ----------------------------------------------------------------------------
60 
61 const QString FitParameterItem::P_TYPE = "Type";
62 const QString FitParameterItem::P_START_VALUE = "Value";
63 const QString FitParameterItem::P_MIN = "Min";
64 const QString FitParameterItem::P_MAX = "Max";
65 const QString FitParameterItem::T_LINK = "Link tag";
66 
68 {
69  addProperty(P_TYPE, fitParameterTypeCombo().variant());
70  addProperty(P_START_VALUE, 0.0)->setEditorType("ScientificSpinBox");
71  addProperty(P_MIN, 0.0)->setEditorType("ScientificSpinBox");
72  addProperty(P_MAX, 0.0)->setEditorType("ScientificSpinBox").setEnabled(false);
73  registerTag(T_LINK, 0, -1, QStringList() << "FitParameterLink");
75 
79 
80  mapper()->setOnPropertyChange([this](const QString& name) {
81  if (name == P_TYPE)
82  onTypeChange();
83  });
84 
85  onTypeChange();
86 }
87 
88 //! Inits P_MIN and P_MAX taking into account current value and external limits
89 
91 {
92  double value = getItemValue(P_START_VALUE).toDouble();
93 
94  double dr(0);
95  if (value == 0.0) {
96  dr = 1.0 * range_factor;
97  } else {
98  dr = std::abs(value) * range_factor;
99  }
100 
101  double min = value - dr;
102  double max = value + dr;
103 
104  if (limits.hasLowerLimit() && min < limits.lowerLimit())
105  min = limits.lowerLimit();
106 
107  if (limits.hasUpperLimit() && max > limits.upperLimit())
108  max = limits.upperLimit();
109 
110  setItemValue(P_MIN, min);
112  setItemValue(P_MAX, max);
114 
116 }
117 
118 //! Constructs Limits correspodning to current GUI settings.
119 
121 {
122  if (isFixed()) {
123  return AttLimits::fixed();
124  }
125 
126  else if (isLimited()) {
127  return AttLimits::limited(getItemValue(P_MIN).toDouble(), getItemValue(P_MAX).toDouble());
128  }
129 
130  else if (isLowerLimited()) {
131  return AttLimits::lowerLimited(getItemValue(P_MIN).toDouble());
132  }
133 
134  else if (isUpperLimited()) {
135  return AttLimits::upperLimited(getItemValue(P_MAX).toDouble());
136  }
137 
138  else if (isFree()) {
139  return AttLimits::limitless();
140  }
141 
142  else {
143  throw GUIHelpers::Error("FitParameterItem::attLimits() -> Error. Unknown limit type");
144  }
145 }
146 
148 {
149  if (isFixed() || isFree())
150  return true;
151 
152  double value = getItemValue(P_START_VALUE).toDouble();
153  double min = getItemValue(P_MIN).toDouble();
154  double max = getItemValue(P_MAX).toDouble();
155 
156  if (isLowerLimited())
157  return min <= value;
158  if (isUpperLimited())
159  return value <= max;
160  return min <= value && value <= max;
161 }
162 
164 {
165  ComboProperty partype = getItemValue(P_TYPE).value<ComboProperty>();
166  return partype.getValue();
167 }
168 
169 //! Enables/disables min, max properties on FitParameterItem's type
170 
172 {
173  if (isFixed()) {
174  setLimitEnabled(P_MIN, false);
175  setLimitEnabled(P_MAX, false);
176  }
177 
178  else if (isLimited()) {
179  setLimitEnabled(P_MIN, true);
180  setLimitEnabled(P_MAX, true);
181  }
182 
183  else if (isLowerLimited()) {
184  setLimitEnabled(P_MIN, true);
185  setLimitEnabled(P_MAX, false);
186  }
187 
188  else if (isUpperLimited()) {
189  setLimitEnabled(P_MIN, false);
190  setLimitEnabled(P_MAX, true);
191  }
192 
193  else if (isFree()) {
194  setLimitEnabled(P_MIN, false);
195  setLimitEnabled(P_MAX, false);
196  }
197 }
198 
199 //! Set limit property with given name to the enabled state
200 
201 void FitParameterItem::setLimitEnabled(const QString& name, bool enabled)
202 {
203  if (isTag(name)) {
204  SessionItem* propertyItem = getItem(name);
205  ASSERT(propertyItem);
206  propertyItem->setEnabled(enabled);
207  propertyItem->setEditable(enabled);
208  }
209 }
210 
212 {
213  return parameterType() == "limited";
214 }
215 
217 {
218  return parameterType() == "free";
219 }
220 
222 {
223  return parameterType() == "lower limited";
224 }
225 
227 {
228  return parameterType() == "upper limited";
229 }
230 
232 {
233  return parameterType() == "fixed";
234 }
235 
236 // ----------------------------------------------------------------------------
237 
238 const QString FitParameterContainerItem::T_FIT_PARAMETERS = "Data tag";
239 
241 {
242  registerTag(T_FIT_PARAMETERS, 0, -1, QStringList() << "FitParameter");
244 }
245 
246 //! returns FitParameterItem for given link (path in model)
247 
249 {
250  for (auto item : getItems(T_FIT_PARAMETERS)) {
251  for (auto linkItem : item->getItems(FitParameterItem::T_LINK)) {
252  if (link == linkItem->getItemValue(FitParameterLinkItem::P_LINK))
253  return dynamic_cast<FitParameterItem*>(item);
254  }
255  }
256  return nullptr;
257 }
258 
260 {
261  QVector<FitParameterItem*> result;
262  for (auto parItem : getItems(T_FIT_PARAMETERS))
263  result.push_back(dynamic_cast<FitParameterItem*>(parItem));
264  return result;
265 }
266 
268 {
269  return getItems(T_FIT_PARAMETERS).isEmpty();
270 }
271 
272 //! Propagate values to the corresponding parameter tree items of parameterContainer.
273 
275  const QVector<double>& values, ParameterContainerItem* parameterContainer)
276 {
277  ASSERT(parameterContainer);
278 
279  QVector<SessionItem*> fitPars = getItems(FitParameterContainerItem::T_FIT_PARAMETERS);
280 
281  int index(0);
282  for (int i = 0; i < fitPars.size(); ++i) {
283  auto link_list = fitPars[i]->getItems(FitParameterItem::T_LINK);
284  if (link_list.empty())
285  continue;
286  for (auto linkItem : link_list) {
287  QString parPath = linkItem->getItemValue(FitParameterLinkItem::P_LINK).toString();
288  auto itemInTuningTree = dynamic_cast<ParameterItem*>(
289  ModelPath::getItemFromPath(parPath, parameterContainer));
290  if (itemInTuningTree)
291  itemInTuningTree->propagateValueToLink(values[index]);
292  }
293  index++;
294  }
295 }
296 
298 {
299  mumufit::Parameters result;
300 
301  int index(0);
303  auto fitPar = dynamic_cast<FitParameterItem*>(item);
304  if (!fitPar->isValid()) {
305  std::stringstream ss;
306  ss << "FitParameterContainerItem::createParameters(): invalid starting value "
307  "or (min, max) range in fitting parameter par"
308  << index;
309  std::string message = ss.str();
310  throw GUIHelpers::Error(QString::fromStdString(ss.str()));
311  }
312  double startValue = fitPar->getItemValue(FitParameterItem::P_START_VALUE).toDouble();
313  AttLimits limits = fitPar->attLimits();
314  QString name = QString("par%1").arg(index);
315  result.add(mumufit::Parameter(name.toStdString(), startValue, limits));
316  ++index;
317  }
318 
319  return result;
320 }
#define ASSERT(condition)
Definition: Assert.h:31
Defines class ComboProperty.
Defines FitParameterItems family of classes.
Defines class GUIHelpers functions.
Defines class JobItem.
Defines ModelPath namespace.
Defines classes for ParameterTreeItems.
Defines class Parameters.
Attributes and limits of a fit parameter, and coupling between these properties.
Definition: AttLimits.h:25
static AttLimits lowerLimited(double bound_value)
Definition: AttLimits.cpp:31
static AttLimits limitless()
Definition: AttLimits.cpp:26
static AttLimits fixed()
Definition: AttLimits.cpp:56
static AttLimits upperLimited(double bound_value)
Definition: AttLimits.cpp:46
static AttLimits limited(double left_bound_value, double right_bound_value)
Definition: AttLimits.cpp:51
Custom property to define list of string values with multiple selections.
Definition: ComboProperty.h:25
void setValue(const QString &name)
QString getValue() const
void setToolTips(const QStringList &tooltips)
FitParameterItem * fitParameterItem(const QString &link)
returns FitParameterItem for given link (path in model)
mumufit::Parameters createParameters() const
static const QString T_FIT_PARAMETERS
QVector< FitParameterItem * > fitParameterItems()
void setValuesInParameterContainer(const QVector< double > &values, class ParameterContainerItem *parameterContainer)
Propagate values to the corresponding parameter tree items of parameterContainer.
The FitParameterItem class represents a fit parameter in GUI.
static const QString P_MAX
static const QString T_LINK
void setLimitEnabled(const QString &name, bool enabled)
Set limit property with given name to the enabled state.
bool isUpperLimited() const
static const QString P_TYPE
void onTypeChange()
Enables/disables min, max properties on FitParameterItem's type.
bool isLowerLimited() const
static const QString P_MIN
void initMinMaxValues(const RealLimits &limits)
Inits P_MIN and P_MAX taking into account current value and external limits.
QString parameterType() const
AttLimits attLimits() const
Constructs Limits correspodning to current GUI settings.
static const QString P_START_VALUE
static const QString P_DOMAIN
static const QString P_LINK
void setOnPropertyChange(std::function< void(QString)> f, const void *caller=0)
Definition: ModelMapper.cpp:35
The ParameterContainerItem is a top item to hold all ParameterItem, represents an entry point to para...
The ParameterItem class represent a tuning value in a parameter tuning tree.
void propagateValueToLink(double newValue)
Sets current value to the original PropertyItem of MultiLayerItem/InstrumentItem.
Limits for a real fit parameter.
Definition: RealLimits.h:24
static RealLimits limitless()
Creates an object withoud bounds (default)
Definition: RealLimits.cpp:130
bool hasUpperLimit() const
if has upper limit
Definition: RealLimits.cpp:57
double upperLimit() const
Returns upper limit.
Definition: RealLimits.cpp:62
double lowerLimit() const
Returns lower limit.
Definition: RealLimits.cpp:40
bool hasLowerLimit() const
if has lower limit
Definition: RealLimits.cpp:35
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.
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.
QVector< SessionItem * > getItems(const QString &tag="") const
Returns vector of all items of given tag.
QVariant value() const
Get value.
SessionItem & setEditorType(const QString &editorType)
QVariant getItemValue(const QString &tag) const
Directly access 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.
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.
void setEditable(bool enabled)
RealLimits limits() const
void setEnabled(bool enabled)
QModelIndex index() const
Returns model index of this item.
Definition: SessionItem.cpp:80
SessionItem * getItem(const QString &tag="", int row=0) const
Returns item in given row of given tag.
SessionItem & setLimits(const RealLimits &value)
A fittable parameter with value, error, step, and limits.
Definition: Parameter.h:26
A collection of fit parameters.
Definition: Parameters.h:26
void add(const Parameter &par)
Definition: Parameters.cpp:22
SessionItem * getItemFromPath(const QString &relPath, const SessionItem *parent)
returns an item from relative path wrt to given parent
Definition: ModelPath.cpp:60
QString const & name(EShape k)
Definition: particles.cpp:21