BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
GUIFitObserver.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/View/Fit/GUIFitObserver.cpp
6 //! @brief Implements class GUIFitObserver
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/Minimizer/MinimizerResult.h"
17 #include "Fit/Tools/MinimizerUtils.h"
18 #include "Sim/Fitting/FitObjective.h"
19 #include "Sim/Fitting/IterationInfo.h"
20 #include "Sim/Fitting/SimDataPair.h"
21 
23  : QObject(parent)
24  , m_block_update_plots(false)
25  , m_update_interval(1)
26 {
27 }
28 
30 
31 void GUIFitObserver::update(const FitObjective* subject)
32 {
33  if (!is_suitable_iteration(subject))
34  return;
35 
36  std::unique_lock<std::mutex> lock(m_update_plot_mutex);
38  return; // plotting still works, will skip iteration
39 
41  m_on_finish_notifier.wait(lock, [this]() { return m_block_update_plots; });
42 
43  FitProgressInfo info;
44  info.m_chi2 = subject->iterationInfo().chi2();
45  info.m_iteration_count = static_cast<int>(subject->iterationInfo().iterationCount());
46  info.m_values = subject->iterationInfo().parameters().values();
47 
48  if (subject->isCompleted())
49  info.m_log_info = subject->minimizerResult().toString();
50 
51  info.m_sim_values = subject->dataPair().simulationResult().flatVector();
52 
53  m_iteration_info = info;
54  emit updateReady();
55 }
56 
57 //! Returns true if data could be plotted, when there are resources for it.
58 
59 bool GUIFitObserver::is_suitable_iteration(const FitObjective* fitSuite) const
60 {
61  if (fitSuite->isInterrupted())
62  return false;
63 
64  int n_iter = static_cast<int>(fitSuite->iterationInfo().iterationCount());
65  return fitSuite->isFirstIteration() || n_iter % m_update_interval == 0
66  || fitSuite->isCompleted();
67 }
68 
69 //! Returns true if given iteration should be obligary plotted.
70 
71 bool GUIFitObserver::is_obligatory_iteration(const FitObjective* fitSuite) const
72 {
73  return fitSuite->isCompleted();
74 }
75 
77 {
78  m_update_interval = val;
79 }
80 
81 //! Informs observer that FitSuiteWidget has finished plotting and is ready for next plot
82 
84 {
85  std::unique_lock<std::mutex> lock(m_update_plot_mutex);
86  m_block_update_plots = false;
87  lock.unlock();
88  m_on_finish_notifier.notify_one();
89 }
90 
92 {
93  std::unique_lock<std::mutex> lock(m_update_plot_mutex);
94  m_block_update_plots = true;
95  return m_iteration_info;
96 }
Implements class GUIFitObserver.
The FitProgressInfo class contains all essential information about fit progress. It is send from GUIF...
std::string m_log_info
std::vector< double > m_values
std::vector< double > m_sim_values
std::condition_variable m_on_finish_notifier
void setInterval(int val)
void finishedPlotting()
Informs observer that FitSuiteWidget has finished plotting and is ready for next plot.
bool is_suitable_iteration(const FitObjective *fitSuite) const
Returns true if data could be plotted, when there are resources for it.
bool is_obligatory_iteration(const FitObjective *fitSuite) const
Returns true if given iteration should be obligary plotted.
void updateReady()
FitProgressInfo m_iteration_info
FitProgressInfo progressInfo()
GUIFitObserver(QObject *parent=nullptr)
bool m_block_update_plots
void update(const FitObjective *subject)
~GUIFitObserver() override
std::mutex m_update_plot_mutex