BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
DistributionWidget Class Reference

The DistributionWidget class plots 1d functions corresponding to domain's Distribution1D. More...

Inheritance diagram for DistributionWidget:
[legend]
Collaboration diagram for DistributionWidget:
[legend]

Public Slots

void onMouseMove (QMouseEvent *event)
 Generates label with current mouse position. More...
 
void onMousePress (QMouseEvent *event)
 

Public Member Functions

 DistributionWidget (QWidget *parent=0)
 
 ~DistributionWidget ()
 
void plotItem ()
 
void setItem (DistributionItem *item)
 
void setXAxisName (const QString &xAxisName)
 

Private Slots

void resetView ()
 Reset zoom range to initial state. More...
 

Private Member Functions

void init_plot ()
 Clears all plottables, resets axes to initial state. More...
 
void plot_distributions ()
 
void plot_multiple_values ()
 
void plot_single_value ()
 Plots a single bar corresponding to the value in DistributionNoteItem. More...
 
void plotBars (const QVector< double > &xbars, const QVector< double > &ybars)
 
void plotFunction (const QVector< double > &xFunc, const QVector< double > &ybars)
 
void plotLimits (const RealLimits &limits)
 Plots red line denoting lower and upper limits, if any. More...
 
void plotVerticalLine (double xMin, double yMin, double xMax, double yMax, const QColor &color=Qt::blue)
 
QPoint positionForWarningSign ()
 
void setPlotRange (const QPair< double, double > &xRange, const QPair< double, double > &yRange)
 

Private Attributes

DistributionItemm_item
 
QLabel * m_label
 
QCustomPlot * m_plot
 
QAction * m_resetAction
 
WarningSignm_warningSign
 
QCPRange m_xRange
 
QCPRange m_yRange
 

Detailed Description

The DistributionWidget class plots 1d functions corresponding to domain's Distribution1D.

Definition at line 30 of file DistributionWidget.h.

Constructor & Destructor Documentation

◆ DistributionWidget()

DistributionWidget::DistributionWidget ( QWidget *  parent = 0)

Definition at line 37 of file DistributionWidget.cpp.

38  : QWidget(parent)
39  , m_plot(new QCustomPlot)
40  , m_item(0)
41  , m_label(new QLabel)
42  , m_resetAction(new QAction(this))
43  , m_warningSign(new WarningSign(this))
44 {
45  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
46 
47  m_resetAction->setText("Reset View");
48  connect(m_resetAction, &QAction::triggered, this, &DistributionWidget::resetView);
49 
50  m_label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
51  m_label->setStyleSheet("background-color:white;");
52  m_label->setMargin(3);
53 
54  QVBoxLayout* mainLayout = new QVBoxLayout;
55  mainLayout->setMargin(0);
56  mainLayout->setSpacing(0);
57  mainLayout->addWidget(m_plot, 1);
58  mainLayout->addWidget(m_label);
59  setLayout(mainLayout);
60 
61  setStyleSheet("background-color:white;");
62  connect(m_plot, &QCustomPlot::mousePress, this, &DistributionWidget::onMousePress);
63  connect(m_plot, &QCustomPlot::mouseMove, this, &DistributionWidget::onMouseMove);
64 }
void resetView()
Reset zoom range to initial state.
void onMousePress(QMouseEvent *event)
void onMouseMove(QMouseEvent *event)
Generates label with current mouse position.
WarningSign * m_warningSign
DistributionItem * m_item
The WarningSign controls appearance of WarningSignWidget on top of parent widget.
Definition: WarningSign.h:25

References m_label, m_plot, m_resetAction, onMouseMove(), onMousePress(), and resetView().

Here is the call graph for this function:

◆ ~DistributionWidget()

DistributionWidget::~DistributionWidget ( )

Definition at line 66 of file DistributionWidget.cpp.

67 {
68  if (m_item)
69  m_item->mapper()->unsubscribe(this);
70 }
void unsubscribe(const void *caller)
Cancells all subscribtion of given caller.
Definition: ModelMapper.cpp:98
ModelMapper * mapper()
Returns the current model mapper of this item. Creates new one if necessary.

References m_item, SessionItem::mapper(), and ModelMapper::unsubscribe().

Here is the call graph for this function:

Member Function Documentation

◆ init_plot()

void DistributionWidget::init_plot ( )
private

Clears all plottables, resets axes to initial state.

Definition at line 147 of file DistributionWidget.cpp.

148 {
149  m_warningSign->clear();
150 
151  m_plot->clearGraphs();
152  m_plot->clearItems();
153  m_plot->clearPlottables();
154  m_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes
155  | QCP::iSelectLegend | QCP::iSelectPlottables);
156  m_plot->yAxis->setLabel("probability");
157  m_plot->xAxis2->setVisible(true);
158  m_plot->yAxis2->setVisible(true);
159  m_plot->xAxis2->setTickLabels(false);
160  m_plot->yAxis2->setTickLabels(false);
161  m_plot->xAxis2->setTicks(false);
162  m_plot->yAxis2->setTicks(false);
163 
164  setPlotRange(default_xrange, default_yrange);
165 }
void setPlotRange(const QPair< double, double > &xRange, const QPair< double, double > &yRange)
void clear()
Clears warning message;.
Definition: WarningSign.cpp:40

References WarningSign::clear(), m_plot, m_warningSign, and setPlotRange().

Referenced by plotItem().

Here is the call graph for this function:

◆ onMouseMove

void DistributionWidget::onMouseMove ( QMouseEvent *  event)
slot

Generates label with current mouse position.

Definition at line 114 of file DistributionWidget.cpp.

115 {
116  QPoint point = event->pos();
117  double xPos = m_plot->xAxis->pixelToCoord(point.x());
118  double yPos = m_plot->yAxis->pixelToCoord(point.y());
119 
120  if (m_plot->xAxis->range().contains(xPos) && m_plot->yAxis->range().contains(yPos)) {
121  QString text = QString("[x:%1, y:%2]").arg(xPos).arg(yPos);
122  m_label->setText(text);
123  }
124 }

References m_label, and m_plot.

Referenced by DistributionWidget().

◆ onMousePress

void DistributionWidget::onMousePress ( QMouseEvent *  event)
slot

Definition at line 126 of file DistributionWidget.cpp.

127 {
128  if (event->button() == Qt::RightButton) {
129  QPoint point = event->globalPos();
130  QMenu menu;
131  menu.addAction(m_resetAction);
132  menu.exec(point);
133  }
134 }

References m_resetAction.

Referenced by DistributionWidget().

◆ plot_distributions()

void DistributionWidget::plot_distributions ( )
private

Definition at line 167 of file DistributionWidget.cpp.

168 {
169  if (m_item->modelType() == "DistributionNone")
171 
172  else
174 }
void plot_single_value()
Plots a single bar corresponding to the value in DistributionNoteItem.
QString modelType() const
Get model type.

References m_item, SessionItem::modelType(), plot_multiple_values(), and plot_single_value().

Referenced by plotItem().

Here is the call graph for this function:

◆ plot_multiple_values()

void DistributionWidget::plot_multiple_values ( )
private

Definition at line 191 of file DistributionWidget.cpp.

192 {
193  ASSERT(m_item->displayName() != "DistributionNone");
194 
195  int numberOfSamples = m_item->getItemValue(DistributionItem::P_NUMBER_OF_SAMPLES).toInt();
196  double sigmafactor(0.0);
198  sigmafactor = m_item->getItemValue(DistributionItem::P_SIGMA_FACTOR).toDouble();
199 
200  RealLimits limits;
203  limits = limitsItem.createRealLimits();
204  }
205  plotLimits(limits);
206 
207  auto dist = m_item->createDistribution();
208 
209  // Calculating bars
210  std::vector<double> xp = dist->equidistantPoints(numberOfSamples, sigmafactor, limits);
211  std::vector<double> yp(xp.size());
212  std::transform(xp.begin(), xp.end(), yp.begin(),
213  [&](double value) { return dist->probabilityDensity(value); });
214  double sumOfWeights = std::accumulate(yp.begin(), yp.end(), 0.0);
215  ASSERT(sumOfWeights != 0.0);
216 
217 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
218  QVector<double> xBar(xp.begin(), xp.end());
219 #else
220  QVector<double> xBar = QVector<double>::fromStdVector(xp);
221 #endif
222 
223  QVector<double> yBar(xBar.size());
224  std::transform(yp.begin(), yp.end(), yBar.begin(),
225  [&](double value) { return value / sumOfWeights; });
226 
227  plotBars(xBar, yBar);
228 
229  // calculating function points (for interval, bigger than bars)
230  auto xRange = xRangeForValues(xBar);
231  const int number_of_points = 400;
232  std::vector<double> xf =
233  dist->equidistantPointsInRange(number_of_points, xRange.first, xRange.second);
234  std::vector<double> yf(xf.size());
235  std::transform(xf.begin(), xf.end(), yf.begin(),
236  [&](double value) { return dist->probabilityDensity(value); });
237 
238 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
239  QVector<double> xFunc(xf.begin(), xf.end());
240 #else
241  QVector<double> xFunc = QVector<double>::fromStdVector(xf);
242 #endif
243  QVector<double> yFunc(xFunc.size());
244  std::transform(yf.begin(), yf.end(), yFunc.begin(),
245  [&](double value) { return value / sumOfWeights; });
246 
247  plotFunction(xFunc, yFunc);
248 }
#define ASSERT(condition)
Definition: Assert.h:31
virtual std::unique_ptr< IDistribution1D > createDistribution(double scale=1.0) const =0
static const QString P_LIMITS
static const QString P_NUMBER_OF_SAMPLES
static const QString P_SIGMA_FACTOR
void plotFunction(const QVector< double > &xFunc, const QVector< double > &ybars)
void plotLimits(const RealLimits &limits)
Plots red line denoting lower and upper limits, if any.
void plotBars(const QVector< double > &xbars, const QVector< double > &ybars)
Limits for a real fit parameter.
Definition: RealLimits.h:24
bool isTag(const QString &name) const
Returns true if tag is available.
T & groupItem(const QString &groupName) const
Definition: SessionItem.h:168
QString displayName() const
Get display name of item, append index if ambigue.
QVariant getItemValue(const QString &tag) const
Directly access value of item under given tag.
QVector< double > fromStdVector(const std::vector< double > &data)
Definition: GUIHelpers.cpp:225

References ASSERT, DistributionItem::createDistribution(), SessionItem::displayName(), GUIHelpers::fromStdVector(), SessionItem::getItemValue(), SessionItem::groupItem(), SessionItem::isTag(), m_item, DistributionItem::P_LIMITS, DistributionItem::P_NUMBER_OF_SAMPLES, DistributionItem::P_SIGMA_FACTOR, plotBars(), plotFunction(), and plotLimits().

Referenced by plot_distributions().

Here is the call graph for this function:

◆ plot_single_value()

void DistributionWidget::plot_single_value ( )
private

Plots a single bar corresponding to the value in DistributionNoteItem.

Definition at line 178 of file DistributionWidget.cpp.

179 {
180  ASSERT(m_item->displayName() == "DistributionNone");
181 
182  double value = m_item->getItemValue(DistributionNoneItem::P_MEAN).toDouble();
183 
184  QVector<double> xPos = QVector<double>() << value;
185  QVector<double> yPos = QVector<double>() << 1.0;
186  plotBars(xPos, yPos);
187 
188  plotVerticalLine(value, default_yrange.first, value, default_yrange.second);
189 }
void plotVerticalLine(double xMin, double yMin, double xMax, double yMax, const QColor &color=Qt::blue)
static const QString P_MEAN

References ASSERT, SessionItem::displayName(), SessionItem::getItemValue(), m_item, SymmetricDistributionItem::P_MEAN, plotBars(), and plotVerticalLine().

Referenced by plot_distributions().

Here is the call graph for this function:

◆ plotBars()

void DistributionWidget::plotBars ( const QVector< double > &  xbars,
const QVector< double > &  ybars 
)
private

Definition at line 259 of file DistributionWidget.cpp.

260 {
261  ASSERT(xbars.size() > 0);
262 
263  auto xRange = xRangeForValues(xbars);
264  auto yRange = yRangeForValues(ybars);
265  setPlotRange(xRange, yRange);
266 
267  double barWidth(0.0);
268  if (xbars.size() == 1)
269  barWidth = optimalBarWidth(xRange.first, xRange.second, xbars.size());
270  else
271  barWidth = optimalBarWidth(xbars.front(), xbars.back(), xbars.size());
272 
273  QCPBars* bars = new QCPBars(m_plot->xAxis, m_plot->yAxis);
274 
275  bars->setWidth(barWidth);
276  bars->setData(xbars, ybars);
277 }

References ASSERT, m_plot, and setPlotRange().

Referenced by plot_multiple_values(), and plot_single_value().

Here is the call graph for this function:

◆ plotFunction()

void DistributionWidget::plotFunction ( const QVector< double > &  xFunc,
const QVector< double > &  ybars 
)
private

Definition at line 279 of file DistributionWidget.cpp.

280 {
281  auto xRange = xRangeForValues(xFunc);
282  auto yRange = yRangeForValues(yFunc);
283  setPlotRange(xRange, yRange);
284 
285  m_plot->addGraph();
286  m_plot->graph(0)->setData(xFunc, yFunc);
287 }

References m_plot, and setPlotRange().

Referenced by plot_multiple_values().

Here is the call graph for this function:

◆ plotItem()

void DistributionWidget::plotItem ( )

Definition at line 95 of file DistributionWidget.cpp.

96 {
97  init_plot();
98 
99  try {
101 
102  } catch (const std::exception& ex) {
103  init_plot();
104 
105  QString message = QString("Wrong parameters\n\n").append(QString::fromStdString(ex.what()));
107  }
108 
109  m_plot->replot();
110 }
void init_plot()
Clears all plottables, resets axes to initial state.
void setWarningMessage(const QString &warningMessage)
Shows warning sign on the screen.
Definition: WarningSign.cpp:58

References init_plot(), m_plot, m_warningSign, plot_distributions(), and WarningSign::setWarningMessage().

Referenced by setItem().

Here is the call graph for this function:

◆ plotLimits()

void DistributionWidget::plotLimits ( const RealLimits limits)
private

Plots red line denoting lower and upper limits, if any.

Definition at line 304 of file DistributionWidget.cpp.

305 {
306  if (limits.hasLowerLimit()) {
307  double value = limits.lowerLimit();
308  plotVerticalLine(value, default_yrange.first, value, default_yrange.second, Qt::red);
309  }
310 
311  if (limits.hasUpperLimit()) {
312  double value = limits.upperLimit();
313  plotVerticalLine(value, default_yrange.first, value, default_yrange.second, Qt::red);
314  }
315 }
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

References RealLimits::hasLowerLimit(), RealLimits::hasUpperLimit(), RealLimits::lowerLimit(), plotVerticalLine(), and RealLimits::upperLimit().

Referenced by plot_multiple_values().

Here is the call graph for this function:

◆ plotVerticalLine()

void DistributionWidget::plotVerticalLine ( double  xMin,
double  yMin,
double  xMax,
double  yMax,
const QColor &  color = Qt::blue 
)
private

Definition at line 289 of file DistributionWidget.cpp.

291 {
292  QCPItemLine* line = new QCPItemLine(m_plot);
293 
294  QPen pen(color, 1, Qt::DashLine);
295  line->setPen(pen);
296  line->setSelectable(true);
297 
298  line->start->setCoords(xMin, yMin);
299  line->end->setCoords(xMax, yMax);
300 }

References m_plot.

Referenced by plot_single_value(), and plotLimits().

◆ positionForWarningSign()

QPoint DistributionWidget::positionForWarningSign ( )
private

◆ resetView

void DistributionWidget::resetView ( )
privateslot

Reset zoom range to initial state.

Definition at line 138 of file DistributionWidget.cpp.

139 {
140  m_plot->xAxis->setRange(m_xRange);
141  m_plot->yAxis->setRange(m_yRange);
142  m_plot->replot();
143 }

References m_plot, m_xRange, and m_yRange.

Referenced by DistributionWidget().

◆ setItem()

void DistributionWidget::setItem ( DistributionItem item)

Definition at line 72 of file DistributionWidget.cpp.

73 {
74  if (m_item == item) {
75  return;
76 
77  } else {
78  if (m_item) {
79  disconnect();
80  m_item->mapper()->unsubscribe(this);
81  }
82 
83  m_item = item;
84  if (!m_item)
85  return;
86 
87  plotItem();
88 
89  m_item->mapper()->setOnPropertyChange([this](QString) { plotItem(); }, this);
90 
91  m_item->mapper()->setOnItemDestroy([this](SessionItem*) { m_item = 0; }, this);
92  }
93 }
void setOnItemDestroy(std::function< void(SessionItem *)> f, const void *caller=0)
Definition: ModelMapper.cpp:87
void setOnPropertyChange(std::function< void(QString)> f, const void *caller=0)
Definition: ModelMapper.cpp:35

References m_item, SessionItem::mapper(), plotItem(), ModelMapper::setOnItemDestroy(), ModelMapper::setOnPropertyChange(), and ModelMapper::unsubscribe().

Referenced by DistributionEditor::onPropertyChanged(), and DistributionEditor::subscribeToItem().

Here is the call graph for this function:

◆ setPlotRange()

void DistributionWidget::setPlotRange ( const QPair< double, double > &  xRange,
const QPair< double, double > &  yRange 
)
private

Definition at line 250 of file DistributionWidget.cpp.

252 {
253  m_xRange = QCPRange(xRange.first, xRange.second);
254  m_yRange = QCPRange(yRange.first, yRange.second);
255  m_plot->xAxis->setRange(m_xRange);
256  m_plot->yAxis->setRange(m_yRange);
257 }

References m_plot, m_xRange, and m_yRange.

Referenced by init_plot(), plotBars(), and plotFunction().

◆ setXAxisName()

void DistributionWidget::setXAxisName ( const QString &  xAxisName)

Definition at line 317 of file DistributionWidget.cpp.

318 {
319  m_plot->xAxis->setLabel(xAxisName);
320 }

References m_plot.

Referenced by DistributionEditor::setNameOfEditor().

Member Data Documentation

◆ m_item

DistributionItem* DistributionWidget::m_item
private

◆ m_label

QLabel* DistributionWidget::m_label
private

Definition at line 63 of file DistributionWidget.h.

Referenced by DistributionWidget(), and onMouseMove().

◆ m_plot

QCustomPlot* DistributionWidget::m_plot
private

◆ m_resetAction

QAction* DistributionWidget::m_resetAction
private

Definition at line 64 of file DistributionWidget.h.

Referenced by DistributionWidget(), and onMousePress().

◆ m_warningSign

WarningSign* DistributionWidget::m_warningSign
private

Definition at line 66 of file DistributionWidget.h.

Referenced by init_plot(), and plotItem().

◆ m_xRange

QCPRange DistributionWidget::m_xRange
private

Definition at line 65 of file DistributionWidget.h.

Referenced by resetView(), and setPlotRange().

◆ m_yRange

QCPRange DistributionWidget::m_yRange
private

Definition at line 65 of file DistributionWidget.h.

Referenced by resetView(), and setPlotRange().


The documentation for this class was generated from the following files: