BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ParameterTreeUtils.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Models/ParameterTreeUtils.cpp
6 //! @brief Implements ParameterTreeUtils namespace
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 <QStack>
25 
26 namespace {
27 
28 QString removeLeadingSlash(const QString& name)
29 {
30  return name.indexOf('/') == 0 ? name.mid(1) : name;
31 }
32 
33 #ifndef NDEBUG
34 
35 //! For every ParameterItem in a container creates a link to the domain.
36 
37 void populateDomainLinks(SessionItem* container)
38 {
39  if (container->modelType() != "Parameter Container")
40  throw GUIHelpers::Error("ParameterTreeUtils::populateParameterContainer() -> Error. "
41  "Not a ParameterContainerType.");
42 
43  ParameterTreeUtils::visitParameterContainer(container, [container](ParameterItem* parItem) {
44  QString translation =
45  "*/" + ModelPath::itemPathTranslation(*parItem->linkedItem(), container->parent());
46  parItem->setItemValue(ParameterItem::P_DOMAIN, translation);
47  });
48 }
49 
50 #endif
51 
52 void handleItem(SessionItem* tree, const SessionItem* source);
53 
54 } // namespace
55 
57 {
58  auto container = jobItem->model()->insertItem<ParameterContainerItem>(
59  jobItem, -1, JobItem::T_PARAMETER_TREE);
60 
62 
64 
66 
67 #ifndef NDEBUG
68  // Provides all items in "JobItem/Parameter Tree Container" with domain links already
69  // at the stage of ParameterTree creation. It is necessary for validation, in Release mode
70  // it will lead for unnecessary large project files.
71  populateDomainLinks(container);
72 #endif
73 }
74 
75 //! Populates ParameterContainer with ParameterItem's corresponding to all properties found
76 //! in a source item.
77 
79  const SessionItem* source)
80 {
81  if (container->modelType() != "Parameter Container")
82  throw GUIHelpers::Error("ParameterTreeUtils::populateParameterContainer() -> Error. "
83  "Not a ParameterContainerType.");
84 
85  auto sourceLabel = container->model()->insertItem<ParameterLabelItem>(container);
86  handleItem(sourceLabel, source);
87 }
88 
89 //! Visit all ParameterItem in container and execute user function.
90 
92  std::function<void(ParameterItem*)> fun)
93 {
94  SessionItem* current(container);
95  QStack<SessionItem*> stack;
96  stack.push(current);
97  while (!stack.empty()) {
98  current = stack.pop();
99  if (current->modelType() == "Parameter Label"
100  || current->modelType() == "Parameter Container") {
101  for (SessionItem* child : current->getItems())
102  stack.push(child);
103  } else {
104  if (ParameterItem* parItem = dynamic_cast<ParameterItem*>(current))
105  fun(parItem);
106  }
107  }
108 }
109 
110 //! Creates list with parameter names of source item.
111 
113 {
114  QStringList result;
115 
116  for (auto pair : parameterDictionary(source))
117  result << pair.first;
118 
119  return result;
120 }
121 
122 //! Creates domain translated list of parameter names for source item.
123 
125 {
126  QStringList result;
127 
128  for (auto pair : parameterDictionary(source))
129  result << pair.second;
130 
131  return result;
132 }
133 
134 //! Correspondance of parameter name to translated name for all properties found in source
135 //! in its children.
136 
137 QVector<QPair<QString, QString>> ParameterTreeUtils::parameterDictionary(const SessionItem* source)
138 {
139  ASSERT(source);
140 
141  QVector<QPair<QString, QString>> result;
142 
143  // Create container with ParameterItem's of given source item
144  SampleModel model;
145  auto container = model.insertItem<ParameterContainerItem>();
146  populateParameterContainer(container, source);
147 
148  // Iterate through all ParameterItems and retrieve necessary data.
149  visitParameterContainer(container, [&](ParameterItem* parItem) {
150  // TODO replace with the method from ModelPath
151  QString parPath = FitParameterHelper::getParameterItemPath(parItem);
152 
153  QString relPath =
154  source->displayName() + "/" + parItem->getItemValue(ParameterItem::P_LINK).toString();
155  SessionItem* linkedItem = ModelPath::getItemFromPath(relPath, source);
156  QString translation = ModelPath::itemPathTranslation(*linkedItem, source->parent());
157 
158  result.push_back(QPair<QString, QString>(parPath, translation));
159  });
160  std::reverse(result.begin(), result.end());
161 
162  return result;
163 }
164 
165 //! Converts domain name to parameterItem name. Parameter name should belong to item or
166 //! one of its children.
167 
168 QString ParameterTreeUtils::domainNameToParameterName(const QString& domainName,
169  const SessionItem* source)
170 {
171  QString domain = removeLeadingSlash(domainName);
172  for (auto pair : parameterDictionary(source)) { // parName, domainName
173  if (pair.second == domain)
174  return pair.first;
175  }
176 
177  return {};
178 }
179 
180 //! Converts parameter name to domain name. Parameter name should belong to item or
181 //! one of its children.
182 
183 QString ParameterTreeUtils::parameterNameToDomainName(const QString& parName,
184  const SessionItem* source)
185 {
186  for (auto pair : parameterDictionary(source)) // parName, domainName
187  if (pair.first == parName)
188  return "/" + pair.second;
189 
190  return {};
191 }
192 
193 //! Converts parameter item name to the corresponding item in the tree below the source.
194 
196  const SessionItem* source)
197 {
198  SampleModel model;
199  auto container = model.insertItem<ParameterContainerItem>();
200  populateParameterContainer(container, source);
201 
202  // Iterate through all ParameterItems and retrieve necessary data.
203  SessionItem* result(nullptr);
204  visitParameterContainer(container, [&](ParameterItem* parItem) {
205  // TODO replace with the method from ModelPath
206  QString parPath = FitParameterHelper::getParameterItemPath(parItem);
207  if (parPath == parName) {
208  QString relPath = source->displayName() + "/"
209  + parItem->getItemValue(ParameterItem::P_LINK).toString();
210  result = ModelPath::getItemFromPath(relPath, source);
211  }
212  });
213 
214  return result;
215 }
216 
217 namespace {
218 
219 void handleItem(SessionItem* tree, const SessionItem* source)
220 {
221  if (tree->modelType() == "Parameter Label") {
222  tree->setDisplayName(source->itemName());
223 
224  }
225 
226  else if (tree->modelType() == "Parameter") {
227  tree->setDisplayName(source->itemName());
228 
229  double sourceValue = source->value().toDouble();
230  tree->setValue(QVariant(sourceValue));
231  QString path = ModelPath::getPathFromIndex(source->index());
232  int firstSlash = path.indexOf('/');
233  path = path.mid(firstSlash + 1);
234  tree->setItemValue(ParameterItem::P_LINK, path);
235  tree->setItemValue(ParameterItem::P_BACKUP, sourceValue);
236  return;
237  }
238 
239  else {
240  return;
241  }
242 
243  for (SessionItem* child : source->children()) {
244  if (child->isVisible() && child->isEnabled()) {
245  if (child->modelType() == "Property") {
246  if (child->value().type() == QVariant::Double) {
247  auto branch = tree->model()->insertItem<ParameterItem>(tree);
248  handleItem(branch, child);
249  }
250 
251  } else if (child->modelType() == "GroupProperty") {
252  SessionItem* currentItem = dynamic_cast<GroupItem*>(child)->currentItem();
253  if (currentItem && currentItem->numberOfChildren() > 0) {
254  auto branch = tree->model()->insertItem<ParameterLabelItem>(tree);
255  handleItem(branch, currentItem);
256  }
257  } else {
258  auto branch = tree->model()->insertItem<ParameterLabelItem>(tree);
259  handleItem(branch, child);
260  }
261  }
262  }
263 }
264 
265 } // namespace
#define ASSERT(condition)
Definition: Assert.h:31
Defines class FitParameterHelper.
Defines class GUIHelpers functions.
Defines class GroupItem.
Defines class JobItem.
Defines ModelPath namespace.
Defines class MultiLayerItem.
Defines classes for ParameterTreeItems.
Defines ParameterTreeUtils namespace.
Defines class SampleModel.
static QString getParameterItemPath(const ParameterItem *parameterItem)
return path to given item in the ParameterTreeContainer
static const QString T_SAMPLE
Definition: JobItem.h:47
static const QString T_PARAMETER_TREE
Definition: JobItem.h:53
static const QString T_INSTRUMENT
Definition: JobItem.h:49
static const QString T_MATERIAL_CONTAINER
Definition: JobItem.h:48
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.
SessionItem * linkedItem()
Returns corresponding linked item in MultiLayerItem/IsntrumentItem.
static const QString P_DOMAIN
static const QString P_LINK
static const QString P_BACKUP
ParameterTreeItems is a collection of items necessary to form a tuning tree for real time widget.
Main model to hold sample items.
Definition: SampleModel.h:24
QString itemName() const
Get item name, return display name if no name is set.
QVector< SessionItem * > getItems(const QString &tag="") const
Returns vector of all items of given tag.
int numberOfChildren() const
Returns total number of children.
Definition: SessionItem.cpp:94
QString displayName() const
Get display name of item, append index if ambigue.
QVariant value() const
Get value.
bool setValue(QVariant value)
Set value, ensure that variant types match.
QVariant getItemValue(const QString &tag) const
Directly access value of item under given tag.
void setDisplayName(const QString &display_name)
Set display name.
SessionItem * parent() const
Returns parent of this item.
Definition: SessionItem.cpp:73
SessionModel * model() const
Returns model of this item.
Definition: SessionItem.cpp:66
void setItemValue(const QString &tag, const QVariant &variant)
Directly set value of item under given tag.
QVector< SessionItem * > children() const
Returns vector of all children.
QString modelType() const
Get model type.
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.
T * insertItem(SessionItem *parent=nullptr, int row=-1, QString tag="")
Definition: SessionModel.h:125
SessionItem * getItemFromPath(const QString &relPath, const SessionItem *parent)
returns an item from relative path wrt to given parent
Definition: ModelPath.cpp:60
QString getPathFromIndex(const QModelIndex &index)
Definition: ModelPath.cpp:19
QString itemPathTranslation(const SessionItem &item, const SessionItem *topItem=0)
Returns translation of item path to domain name.
Definition: ModelPath.cpp:98
void visitParameterContainer(SessionItem *container, std::function< void(ParameterItem *)> fun)
Visit all ParameterItem in container and execute user function.
QStringList translatedParameterTreeNames(const SessionItem *source)
Creates domain translated list of parameter names for source item.
QString domainNameToParameterName(const QString &domainName, const SessionItem *source)
Converts domain name to parameterItem name.
QStringList parameterTreeNames(const SessionItem *source)
Creates list with parameter names of source item.
QVector< QPair< QString, QString > > parameterDictionary(const SessionItem *source)
Correspondance of parameter name to translated name for all properties found in source in its childre...
QString parameterNameToDomainName(const QString &parName, const SessionItem *source)
Converts parameter name to domain name.
void populateParameterContainer(SessionItem *container, const SessionItem *source)
Populates ParameterContainer with ParameterItem's corresponding to all properties found in a source i...
void createParameterTree(JobItem *jobItem)
SessionItem * parameterNameToLinkedItem(const QString &parName, const SessionItem *source)
Converts parameter item name to the corresponding item in the tree below the source.
QString const & name(EShape k)
Definition: particles.cpp:21