From 3ec6ffb24d638ba601df467a7e8f30bcfd78418f Mon Sep 17 00:00:00 2001 From: Ronald Klasky Date: Wed, 23 Sep 2020 16:30:20 -0400 Subject: [PATCH] updated remora functionality --- MSSPM_GuiForecast/nmfForecastTab01.cpp | 16 +- MSSPM_GuiForecast/nmfForecastTab01.h | 10 + MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.cpp | 812 ------ MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.h | 168 -- MSSPM_GuiManagerMode/REMORA.cpp | 2281 +++++++++++++++++ MSSPM_GuiManagerMode/REMORA.h | 454 ++++ MSSPM_GuiSetup/nmfSetupTab02.cpp | 144 +- MSSPM_Main/MSSPM_Main.pro | 10 +- MSSPM_Main/forms/MMode/mModeWindow.ui | 1003 ++++++-- MSSPM_Main/nmfMainWindow.cpp | 1264 +++++++-- MSSPM_Main/nmfMainWindow.h | 88 +- MSSPM_Main/nmfMainWindow.ui | 52 +- docs/QuickStart_Guide_MSSPM.pdf | Bin 312966 -> 312497 bytes .../_m_s_s_p_m___gui_manager_mode_8h.html | 173 ++ ...s_p_m___gui_manager_mode_8h__dep__incl.map | 3 + ...s_p_m___gui_manager_mode_8h__dep__incl.md5 | 1 + ...s_p_m___gui_manager_mode_8h__dep__incl.png | Bin 0 -> 5939 bytes ..._m_s_s_p_m___gui_manager_mode_8h__incl.map | 2 + ..._m_s_s_p_m___gui_manager_mode_8h__incl.md5 | 1 + ..._m_s_s_p_m___gui_manager_mode_8h__incl.png | Bin 0 -> 41584 bytes ..._s_s_p_m___gui_manager_mode_8h_source.html | 51 +- docs/html/_r_e_m_o_r_a_8h_source.html | 161 ++ docs/html/annotated.html | 44 +- docs/html/annotated_dup.js | 4 +- ..._m_s_s_p_m___gui_manager_mode-members.html | 55 +- .../class_m_s_s_p_m___gui_manager_mode.html | 971 ++++++- .../class_m_s_s_p_m___gui_manager_mode.js | 47 +- docs/html/class_r_e_m_o_r_a-members.html | 165 ++ docs/html/class_r_e_m_o_r_a.html | 1260 +++++++++ docs/html/class_r_e_m_o_r_a.js | 42 + docs/html/class_r_e_m_o_r_a__coll__graph.map | 2 + docs/html/class_r_e_m_o_r_a__coll__graph.md5 | 1 + docs/html/class_r_e_m_o_r_a__coll__graph.png | Bin 0 -> 2615 bytes .../class_r_e_m_o_r_a__inherit__graph.map | 2 + .../class_r_e_m_o_r_a__inherit__graph.md5 | 1 + .../class_r_e_m_o_r_a__inherit__graph.png | Bin 0 -> 2615 bytes docs/html/classes.html | 22 +- .../classnmf_forecast___tab1-members.html | 10 +- docs/html/classnmf_forecast___tab1.html | 48 + docs/html/classnmf_forecast___tab1.js | 4 +- docs/html/classnmf_main_window-members.html | 103 +- docs/html/classnmf_main_window.html | 98 +- docs/html/classnmf_main_window.js | 13 +- docs/html/dir_000005_000014.html | 112 + .../dir_8291466d3bbe86acdba4d4c7465b1826.js | 4 +- docs/html/files.html | 4 +- docs/html/functions.html | 1 + docs/html/functions_b.html | 1 + docs/html/functions_c.html | 88 +- docs/html/functions_d.html | 1 + docs/html/functions_dup.js | 1 + docs/html/functions_e.html | 1 + docs/html/functions_f.html | 1 + docs/html/functions_func.html | 1 + docs/html/functions_func.js | 1 + docs/html/functions_func_b.html | 1 + docs/html/functions_func_c.html | 88 +- docs/html/functions_func_d.html | 1 + docs/html/functions_func_e.html | 1 + docs/html/functions_func_f.html | 1 + docs/html/functions_func_g.html | 7 + docs/html/functions_func_i.html | 5 + docs/html/functions_func_k.html | 156 ++ docs/html/functions_func_l.html | 1 + docs/html/functions_func_m.html | 11 +- docs/html/functions_func_n.html | 1 + docs/html/functions_func_o.html | 1 + docs/html/functions_func_p.html | 1 + docs/html/functions_func_q.html | 1 + docs/html/functions_func_r.html | 4 + docs/html/functions_func_s.html | 25 +- docs/html/functions_func_u.html | 4 + docs/html/functions_func_w.html | 1 + docs/html/functions_g.html | 7 + docs/html/functions_i.html | 5 + docs/html/functions_k.html | 156 ++ docs/html/functions_l.html | 1 + docs/html/functions_m.html | 13 +- docs/html/functions_n.html | 1 + docs/html/functions_o.html | 1 + docs/html/functions_p.html | 1 + docs/html/functions_q.html | 1 + docs/html/functions_r.html | 4 + docs/html/functions_s.html | 25 +- docs/html/functions_u.html | 4 + docs/html/functions_w.html | 1 + docs/html/hierarchy.html | 38 +- docs/html/hierarchy.js | 4 +- docs/html/inherit_graph_0.map | 38 +- docs/html/inherit_graph_0.md5 | 2 +- docs/html/inherit_graph_0.png | Bin 80324 -> 79774 bytes docs/html/inherits.html | 38 +- docs/html/navtreedata.js | 6 +- docs/html/navtreeindex0.js | 336 +-- docs/html/navtreeindex1.js | 500 ++-- docs/html/navtreeindex2.js | 410 +-- docs/html/navtreeindex3.js | 36 + docs/html/nmf_forecast_tab01_8h_source.html | 26 +- docs/html/nmf_main_window_8h.html | 34 +- docs/html/nmf_main_window_8h__incl.map | 32 +- docs/html/nmf_main_window_8h__incl.md5 | 2 +- docs/html/nmf_main_window_8h__incl.png | Bin 196950 -> 201353 bytes docs/html/nmf_main_window_8h_source.html | 10 +- docs/html/nmf_setup_tab02_8h_source.html | 60 +- docs/html/search/all_10.js | 62 +- docs/html/search/all_11.js | 8 +- docs/html/search/all_12.js | 3 +- docs/html/search/all_2.js | 39 +- docs/html/search/all_6.js | 4 +- docs/html/search/all_7.js | 1 + docs/html/search/all_8.js | 11 +- docs/html/search/all_9.js | 49 +- docs/html/search/all_a.js | 78 +- docs/html/search/all_b.js | 38 +- docs/html/search/all_c.js | 5 +- docs/html/search/all_d.js | 5 +- docs/html/search/all_e.js | 21 +- docs/html/search/all_f.js | 73 +- docs/html/search/classes_4.js | 1 - docs/html/search/classes_7.html | 26 + docs/html/search/classes_7.js | 4 + docs/html/search/functions_10.js | 61 +- docs/html/search/functions_11.js | 7 +- docs/html/search/functions_12.js | 3 +- docs/html/search/functions_2.js | 39 +- docs/html/search/functions_6.js | 4 +- docs/html/search/functions_7.js | 1 + docs/html/search/functions_8.js | 7 +- docs/html/search/functions_9.js | 41 +- docs/html/search/functions_a.js | 55 +- docs/html/search/functions_b.js | 19 +- docs/html/search/functions_c.js | 4 +- docs/html/search/functions_d.js | 4 +- docs/html/search/functions_e.js | 20 +- docs/html/search/functions_f.js | 72 +- docs/html/search/searchdata.js | 6 +- 136 files changed, 9803 insertions(+), 2872 deletions(-) delete mode 100644 MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.cpp delete mode 100644 MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.h create mode 100644 MSSPM_GuiManagerMode/REMORA.cpp create mode 100644 MSSPM_GuiManagerMode/REMORA.h create mode 100644 docs/html/_m_s_s_p_m___gui_manager_mode_8h.html create mode 100644 docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.map create mode 100644 docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.md5 create mode 100644 docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.png create mode 100644 docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.map create mode 100644 docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.md5 create mode 100644 docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.png create mode 100644 docs/html/_r_e_m_o_r_a_8h_source.html create mode 100644 docs/html/class_r_e_m_o_r_a-members.html create mode 100644 docs/html/class_r_e_m_o_r_a.html create mode 100644 docs/html/class_r_e_m_o_r_a.js create mode 100644 docs/html/class_r_e_m_o_r_a__coll__graph.map create mode 100644 docs/html/class_r_e_m_o_r_a__coll__graph.md5 create mode 100644 docs/html/class_r_e_m_o_r_a__coll__graph.png create mode 100644 docs/html/class_r_e_m_o_r_a__inherit__graph.map create mode 100644 docs/html/class_r_e_m_o_r_a__inherit__graph.md5 create mode 100644 docs/html/class_r_e_m_o_r_a__inherit__graph.png create mode 100644 docs/html/dir_000005_000014.html create mode 100644 docs/html/functions_func_k.html create mode 100644 docs/html/functions_k.html create mode 100644 docs/html/search/classes_7.html create mode 100644 docs/html/search/classes_7.js diff --git a/MSSPM_GuiForecast/nmfForecastTab01.cpp b/MSSPM_GuiForecast/nmfForecastTab01.cpp index 5f2542df..c9e79032 100644 --- a/MSSPM_GuiForecast/nmfForecastTab01.cpp +++ b/MSSPM_GuiForecast/nmfForecastTab01.cpp @@ -95,6 +95,18 @@ nmfForecast_Tab1::getStartForecastYear() return Forecast_Tab1_StartYearLE->text().toInt(); } +bool +nmfForecast_Tab1::isDeterministic() +{ + return Forecast_Tab1_DeterministicCB->isChecked(); +} + +void +nmfForecast_Tab1::setDeterministic(bool isDeterministic) +{ + Forecast_Tab1_DeterministicCB->setChecked(isDeterministic); +} + void nmfForecast_Tab1::callback_SetNamePB() { @@ -111,7 +123,7 @@ nmfForecast_Tab1::callback_NextPB() int nmfForecast_Tab1::getSeed() { - return (Forecast_Tab1_DeterministicCB->isChecked()) ? Forecast_Tab1_DeterministicSB->value() : -1; + return (isDeterministic()) ? Forecast_Tab1_DeterministicSB->value() : -1; } void @@ -147,7 +159,7 @@ nmfForecast_Tab1::callback_SavePB() std::string StartYear = Forecast_Tab1_StartYearLE->text().toStdString(); std::string EndYear = Forecast_Tab1_EndYearLE->text().toStdString(); std::string NumRuns = std::to_string(Forecast_Tab1_NumRunsSB->value()); - std::string IsDeterministic = std::to_string(Forecast_Tab1_DeterministicCB->isChecked()); + std::string IsDeterministic = std::to_string(isDeterministic()); std::string Seed = std::to_string(Forecast_Tab1_DeterministicSB->value()); std::string Algorithm; std::string Minimizer; diff --git a/MSSPM_GuiForecast/nmfForecastTab01.h b/MSSPM_GuiForecast/nmfForecastTab01.h index 2242f802..825d4f20 100644 --- a/MSSPM_GuiForecast/nmfForecastTab01.h +++ b/MSSPM_GuiForecast/nmfForecastTab01.h @@ -108,6 +108,11 @@ class nmfForecast_Tab1: public QObject * @return The integer start year associated with this Forecast */ int getStartForecastYear(); + /** + * @brief Returns boolean signifying if the deterministic box has been checked + * @return Returns True/False describing if deterministic box has been checked + */ + bool isDeterministic(); /** * @brief Loads all widgets for this GUI from database tables * @return Returns true if all data were loaded successfully @@ -117,6 +122,11 @@ class nmfForecast_Tab1: public QObject * @brief Saves the GUIs settings to a Qt settings file */ void saveSettings(); + /** + * @brief Sets the deterministic state of the appropriate checkbox + * @param isDeterministic : boolean describing deterministic state + */ + void setDeterministic(bool isDeterministic); signals: /** diff --git a/MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.cpp b/MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.cpp deleted file mode 100644 index c0635213..00000000 --- a/MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.cpp +++ /dev/null @@ -1,812 +0,0 @@ -#include "MSSPM_GuiManagerMode.h" - -MSSPM_GuiManagerMode::MSSPM_GuiManagerMode( - nmfDatabase* databasePtr, - nmfLogger* logger, - std::string& projectSettingsConfig, - QWidget* MModeWidget) -{ - int startYear; - int endYear; - int endForecastYear; - std::string MainTitle = "Harvest Scale Factor"; - std::string XTitle = "Year"; - std::string YTitle = "Scale Factor"; - - m_MovableLineChart = new nmfChartMovableLine( - MainTitle,XTitle,YTitle); - - // ---------------------------------------- - // Change these lines..... - m_NumUnusedParameters = 7; - m_ForecastName = "Sample_Schaefer"; - m_HarvestType = "ForecastCatch"; - m_NumYearsPerRun = 20; // remove this later - m_NumRunsPerForecast = 10; // remove this later - // ---------------------------------------- - - m_DatabasePtr = databasePtr; - m_Logger = logger; - m_ProjectSettingsConfig = projectSettingsConfig; - - MModeYearsPerRunSL = MModeWidget->findChild("MModeYearsPerRunSL"); - MModeRunsPerForecastSL = MModeWidget->findChild("MModeRunsPerForecastSL"); -// MModeDetStocSL = MModeWidget->findChild("MModeDetStocSL"); - MModeYearsPerRunLE = MModeWidget->findChild("MModeYearsPerRunLE"); - MModeRunsPerForecastLE = MModeWidget->findChild("MModeRunsPerForecastLE"); - MModePctMSYLE = MModeWidget->findChild("MModePctMSYLE"); - MModeRParamLE = MModeWidget->findChild("MModeRParamLE"); - MModeKParamLE = MModeWidget->findChild("MModeKParamLE"); - MModeCParamLE = MModeWidget->findChild("MModeCParamLE"); - MModePctMSYDL = MModeWidget->findChild("MModePctMSYDL"); - MModeRParamDL = MModeWidget->findChild("MModeRParamDL"); - MModeKParamDL = MModeWidget->findChild("MModeKParamDL"); - MModeCParamDL = MModeWidget->findChild("MModeCParamDL"); - MModeSpeciesCMB = MModeWidget->findChild("MModeSpeciesCMB"); - MModeUpperPlotWidget = MModeWidget->findChild("MModeUpperPlotWidget"); - MModeHarvestChartWidget = MModeWidget->findChild("MModeHarvestChartWidget"); - MModeWindowWidget = MModeWidget->findChild("MModeWindowWidget"); - MModeForecastRunPB = MModeWidget->findChild("MModeForecastRunPB"); - MModeShowMSYCB = MModeWidget->findChild("MModeShowMSYCB"); - MModeEnablePctMSYCB = MModeWidget->findChild("MModeEnablePctMSYCB"); - MModeDeterministicRB = MModeWidget->findChild("MModeDeterministicRB"); - MModeStochasticRB = MModeWidget->findChild("MModeStochasticRB"); - MModePlotTypeSSRB = MModeWidget->findChild("MModePlotTypeSSRB"); - MModePlotTypeMSRB = MModeWidget->findChild("MModePlotTypeMSRB"); - MModeCParamPB = MModeWidget->findChild("MModeCParamPB"); - MModePctMSYLBL = MModeWidget->findChild("MModePctMSYLBL"); - - MModeDeterministicRB->setChecked(false); - MModeStochasticRB->setChecked(true); - MModePlotTypeSSRB->setChecked(true); - MModePlotTypeMSRB->setChecked(false); - - // RSK - remove this later -// MModeDetStocSL->setValue(1); - - // RSK hardcode to 20 years - getYearRange(startYear,endYear); - endForecastYear = endYear + m_NumYearsPerRun; - m_MovableLineChart->populateChart(MModeHarvestChartWidget, - MModeWindowWidget, - endYear, - endForecastYear); - - //Defaulting the dials to their lowest values - MModePctMSYDL->setValue(0); - MModeRParamDL->setValue(0); - MModeKParamDL->setValue(0); - MModeCParamDL->setValue(0); - MModePctMSYLE->setEnabled(false); - MModePctMSYDL->setEnabled(false); - MModePctMSYLBL->setEnabled(false); - - //Defaulting the sliders to their lowest values -// MModeYearsPerRunSL->setValue(1); - MModeYearsPerRunSL->setValue(m_NumYearsPerRun); -// MModeRunsPerForecastSL->setValue(1); - MModeRunsPerForecastSL->setValue(m_NumRunsPerForecast); - - //Setting the paired line edits to the lowest values of their respective widgets -// MModeYearsPerRunLE->setText(QString::number(1)); - MModeYearsPerRunLE->setText(QString::number(m_NumYearsPerRun)); -// MModeRunsPerForecastLE->setText(QString::number(1)); - MModeRunsPerForecastLE->setText(QString::number(m_NumRunsPerForecast)); - MModePctMSYLE->setText(QString::number(0)); - MModeRParamLE->setText(QString::number(0)); - MModeKParamLE->setText(QString::number(0)); - MModeCParamLE->setText(QString::number(0)); - - // Setup chart widgets - m_ChartWidget = new QChart(); - m_ChartView = new QChartView(m_ChartWidget); - QVBoxLayout* vlayt = new QVBoxLayout(); - vlayt->addWidget(m_ChartView); - MModeUpperPlotWidget->setLayout(vlayt); - m_ForecastLineChartMonteCarlo = new nmfChartLine(); - m_ForecastLineChart = new nmfChartLine(); - m_MSYLineChart = new nmfChartLine(); - - setupConnections(); - -} - -MSSPM_GuiManagerMode::~MSSPM_GuiManagerMode() -{ - -} - -void -MSSPM_GuiManagerMode::getYearRange(int& firstYear, int& lastYear) -{ - int StartYear; - int NumYears; - std::vector fields; - std::map > dataMap; - std::string queryStr; - - fields = {"StartYear","RunLength"}; - queryStr = "SELECT StartYear,RunLength from Systems where SystemName = '" + - QString::fromStdString(m_ProjectSettingsConfig).split("__")[0].toStdString() + "'"; - dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); - if (dataMap["RunLength"].size() != 0) { - StartYear = std::stoi(dataMap["StartYear"][0]); - NumYears = std::stoi(dataMap["RunLength"][0]); - } - firstYear = StartYear; - lastYear = firstYear + NumYears; -} - -void -MSSPM_GuiManagerMode::setupConnections() -{ - std::cout << "Setup Connections begins." << std::endl; - - connect(this, SIGNAL(KeyPressed(QKeyEvent*)), - m_MovableLineChart, SLOT(callback_keyPressed(QKeyEvent*))); - connect(this, SIGNAL(MouseMoved(QMouseEvent*)), - m_MovableLineChart, SLOT(callback_mouseMoved(QMouseEvent*))); - connect(this, SIGNAL(MouseReleased(QMouseEvent*)), - m_MovableLineChart, SLOT(callback_mouseReleased(QMouseEvent*))); - - connect(MModeYearsPerRunSL, SIGNAL(sliderMoved(int)), - this, SLOT(callback_YearsPerRunSL(int))); - connect(MModeRunsPerForecastSL, SIGNAL(sliderMoved(int)), - this, SLOT(callback_RunsPerForecastSL(int))); - connect(MModePctMSYDL, SIGNAL(sliderMoved(int)), - this, SLOT(callback_PctMSY(int))); - connect(MModeRParamDL, SIGNAL(sliderMoved(int)), - this, SLOT(callback_RParam(int))); - connect(MModeKParamDL, SIGNAL(sliderMoved(int)), - this, SLOT(callback_KParam(int))); - connect(MModeCParamDL, SIGNAL(sliderMoved(int)), - this, SLOT(callback_CParam(int))); - connect(MModeForecastRunPB, SIGNAL(clicked()), - this, SLOT(callback_RunPB())); - connect(MModeShowMSYCB, SIGNAL(toggled(bool)), - this, SLOT(callback_MSYCB(bool))); - connect(MModeEnablePctMSYCB, SIGNAL(toggled(bool)), - this, SLOT(callback_EnablePctMSYCB(bool))); - connect(MModePctMSYDL, SIGNAL(sliderReleased()), - this, SLOT(callback_PctMSYDL())); - connect(MModeDeterministicRB, SIGNAL(clicked(bool)), - this, SLOT(callback_DeterministicPB(bool))); - connect(MModeStochasticRB, SIGNAL(clicked(bool)), - this, SLOT(callback_StochasticPB(bool))); - connect(MModePlotTypeSSRB, SIGNAL(clicked(bool)), - this, SLOT(callback_PlotTypeSSRB(bool))); - connect(MModePlotTypeMSRB, SIGNAL(clicked(bool)), - this, SLOT(callback_PlotTypeMSRB(bool))); - connect(MModeCParamPB, SIGNAL(clicked()), - this, SLOT(callback_MModeCParamPB())); - -} - -void -MSSPM_GuiManagerMode::setData(const QStringList& speciesList) -{ - std::cout << "Set Data works" << std::endl; - - MModeSpeciesCMB->clear(); - MModeSpeciesCMB->addItems(speciesList); -} - -void -MSSPM_GuiManagerMode::callback_YearsPerRunSL(int value) -{ - MModeYearsPerRunLE->setText(QString::number(value)); -} - -void -MSSPM_GuiManagerMode::callback_RunsPerForecastSL(int value) -{ - MModeRunsPerForecastLE->setText(QString::number(value)); - m_NumRunsPerForecast = value; -} - -void -MSSPM_GuiManagerMode::callback_PctMSY(int value) -{ - MModePctMSYLE->setText(QString::number(value)); -} - -void -MSSPM_GuiManagerMode::callback_RParam(int value) -{ - MModeRParamLE->setText(QString::number(value)); -} - -void -MSSPM_GuiManagerMode::callback_KParam(int value) -{ - MModeKParamLE->setText(QString::number(value)); -} - -void -MSSPM_GuiManagerMode::callback_CParam(int value) -{ - MModeCParamLE->setText(QString::number(value)); -} - -void -MSSPM_GuiManagerMode::callback_RunPB() -{ - callback_RunPB(false); -} - -void -MSSPM_GuiManagerMode::callback_RunPB(bool MSYOnly) -{ - QApplication::setOverrideCursor(Qt::WaitCursor); - - m_MovableLineChart->calculateYearlyPoints(); - - saveUncertaintyParameters(); - saveHarvestData(); - saveOutputBiomassData(); - drawChart(MSYOnly); - - QApplication::restoreOverrideCursor(); - -} - -void -MSSPM_GuiManagerMode::callback_EnablePctMSYCB(bool isChecked) -{ - MModePctMSYLE->setEnabled(isChecked); - MModePctMSYDL->setEnabled(isChecked); - MModePctMSYLBL->setEnabled(isChecked); - callback_RunPB(true); -} - - - -void -MSSPM_GuiManagerMode::callback_StochasticPB(bool pressed) -{ - MModeDeterministicRB->setChecked(! pressed); -} - -void -MSSPM_GuiManagerMode::callback_DeterministicPB(bool pressed) -{ - MModeStochasticRB->setChecked(! pressed); -} - -void -MSSPM_GuiManagerMode::callback_PlotTypeSSRB(bool pressed) -{ - MModePlotTypeMSRB->setChecked(! pressed); -} - -void -MSSPM_GuiManagerMode::callback_PlotTypeMSRB(bool pressed) -{ - MModePlotTypeSSRB->setChecked(! pressed); -} - -void -MSSPM_GuiManagerMode::callback_MModeCParamPB() -{ - if (MModeCParamPB->text() == "Catch") { - MModeCParamPB->setText("Effort (E)"); - } else if (MModeCParamPB->text() == "Effort (E)") { - MModeCParamPB->setText("Exploitation (F)"); - } else if (MModeCParamPB->text() == "Exploitation (F)") { - MModeCParamPB->setText("Catch"); - } -} - - -bool -MSSPM_GuiManagerMode::isMSYBoxChecked() -{ - return MModeShowMSYCB->isChecked(); -} - -bool -MSSPM_GuiManagerMode::isEnablePctMSYBoxChecked() -{ - return MModeEnablePctMSYCB->isChecked(); -} - - -int -MSSPM_GuiManagerMode::getNumYearsPerRun() -{ - return MModeYearsPerRunLE->text().toInt(); -} - -int -MSSPM_GuiManagerMode::getNumRunsPerForecast() -{ - return MModeRunsPerForecastLE->text().toInt(); -} - -void -MSSPM_GuiManagerMode::callback_keyPressed(QKeyEvent* event) -{ - emit KeyPressed(event); -} - -void -MSSPM_GuiManagerMode::callback_mouseMoved(QMouseEvent* event) -{ - emit MouseMoved(event); -} - -void -MSSPM_GuiManagerMode::callback_mouseReleased(QMouseEvent* event) -{ - emit MouseReleased(event); -} - -void -MSSPM_GuiManagerMode::callback_MSYCB(bool isChecked) -{ - callback_RunPB(true); -} - - -void -MSSPM_GuiManagerMode::callback_PctMSYDL() -{ - callback_RunPB(true); -} - - - -void -MSSPM_GuiManagerMode::saveUncertaintyParameters() -{ - std::string cmd; - std::string errorMsg; - std::vector SpeNames; - - for (int i = 0; i < MModeSpeciesCMB->count(); i++) - { - SpeNames.push_back(MModeSpeciesCMB->itemText(i).toStdString()); - } - - std::string ForecastName = "Sample_Schaefer"; - std::vector fields = {"ForecastName","Algorithm","Minimizer","ObjectiveCriterion","Scaling"}; - std::string queryStr = "SELECT ForecastName,Algorithm,Minimizer,ObjectiveCriterion,Scaling FROM Forecasts where "; - queryStr += "ForecastName = '" + ForecastName + "'"; - std::map > dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); - - int NumRecords = dataMap["ForecastName"].size(); - if (NumRecords == 0) { - std::cout << "Error: No records found." << std::endl; - std::cout << queryStr << std::endl; - return; - } - - std::string Algorithm = dataMap["Algorithm"][0]; - std::string Minimizer = dataMap["Minimizer"][0]; - std::string ObjectiveCriterion = dataMap["ObjectiveCriterion"][0]; - std::string Scaling = dataMap["Scaling"][0]; - std::string GrowthRate = std::to_string(MModeRParamLE->text().toDouble()/100.0); - std::string CarryingCapacity = std::to_string(MModeKParamLE->text().toDouble()/100.0); - std::string Harvest = std::to_string(MModeCParamLE->text().toDouble()/100.0); - - // Clear previous entry in ForecastUncertainty table - cmd = "DELETE FROM ForecastUncertainty WHERE ForecastName = '" + ForecastName + "'"; - errorMsg = m_DatabasePtr->nmfUpdateDatabase(cmd); - if (errorMsg != " ") { - m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::callback_SavePB: DELETE error: " + errorMsg); - m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); - QMessageBox::warning(MModeWindowWidget, "Error", - "\nError in Save command. Couldn't delete all records from ForecastUncertainty table.\n", - QMessageBox::Ok); - return; - } - - cmd = "INSERT INTO ForecastUncertainty (" ; - cmd += "SpeName,ForecastName,Algorithm,Minimizer,ObjectiveCriterion,Scaling,"; - cmd += "GrowthRate,CarryingCapacity,Predation,Competition,BetaSpecies,"; - cmd += "BetaGuilds,Handling,Exponent,Catchability,Harvest) VALUES "; - for (int i = 0; i < SpeNames.size(); ++i) { // Species - cmd += "('" + SpeNames[i] + "','" + ForecastName + "','" + Algorithm + - "','" + Minimizer + "','" + ObjectiveCriterion + "','" + Scaling + "'"; - cmd += "," + GrowthRate; - cmd += "," + CarryingCapacity; - for (int i=0;inmfUpdateDatabase(cmd); - if (errorMsg != " ") { - m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::callback_SavePB: Write table error: " + errorMsg); - m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); - QMessageBox::warning(MModeWindowWidget, "Error", - "\nError in Save command. Check that all cells are populated.\n", - QMessageBox::Ok); - return; - } -} - -void -MSSPM_GuiManagerMode::getLastYearsCatchValues( - int& lastYear, - std::vector& lastYearsCatchValues) -{ - std::vector fields; - std::map > dataMap; - std::string queryStr; - - lastYearsCatchValues.clear(); - - // Get last year's catch data - fields = {"Value"}; - queryStr = "SELECT Value from Catch where SystemName = '" + - QString::fromStdString(m_ProjectSettingsConfig).split("__")[0].toStdString() + "'"; - queryStr += " AND Year = " + std::to_string(lastYear-1); - dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); - for (unsigned i=0; i SpeNames; - std::string Algorithm; - std::string Minimizer; - std::string ObjectiveCriterion; - std::string Scaling; - std::string CompetitionForm; - std::vector lastYearsCatchValues; - - bool systemFound = m_DatabasePtr->getAlgorithmIdentifiers( - 0,m_Logger,m_ProjectSettingsConfig, - Algorithm,Minimizer,ObjectiveCriterion,Scaling, - CompetitionForm,nmfConstantsMSSPM::DontShowPopupError); - if (! systemFound) { - m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::saveHarvestData: No systems found"); - return; - } - - getYearRange(startYear,endYear); - NumYears = endYear-startYear+1; - - m_DatabasePtr->getAllSpecies(m_Logger,SpeNames); - - cmd = "DELETE FROM " + m_HarvestType + " WHERE ForecastName = '" + - m_ForecastName + "'"; - errorMsg = m_DatabasePtr->nmfUpdateDatabase(cmd); - if (errorMsg != " ") { - m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::saveHarvestData: DELETE error: " + errorMsg); - m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); - QMessageBox::warning(0, "Error", - "\nError in Save command. Couldn't delete all records from" + - QString::fromStdString(m_HarvestType) + " table.\n", - QMessageBox::Ok); - QApplication::restoreOverrideCursor(); - return; - } - - - getLastYearsCatchValues(NumYears,lastYearsCatchValues); - - - cmd = "INSERT INTO " + m_HarvestType + " (ForecastName,Algorithm,Minimizer,ObjectiveCriterion,Scaling,SpeName,Year,Value) VALUES "; - for (int speciesNum=0; speciesNumnmfUpdateDatabase(cmd); - if (errorMsg != " ") { - m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::saveHarvestData: Write table error: " + errorMsg); - m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); - QApplication::restoreOverrideCursor(); - return; - } - - QApplication::restoreOverrideCursor(); -} - - -double -MSSPM_GuiManagerMode::getScaleValueFromPlot(int speciesNum, - int yearNum) -{ - double scaleValue = m_MovableLineChart->getYValue(yearNum); - if (scaleValue < 0) { - m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::getScaleValueFromPlot: Error reading from Scale plot"); - return 0; - } - return scaleValue; -} - -void -MSSPM_GuiManagerMode::saveOutputBiomassData() -{ - - emit SaveOutputBiomassData(m_ForecastName); -} - -void -MSSPM_GuiManagerMode::drawChart(bool MSYOnly) -{ - int StartYear; - int EndYear; - int StartForecastYear; - int YMinSliderVal = 0; - int NoUncertaintyRun = 0; - int NumYearsPerRun = getNumYearsPerRun(); - int NumRunsPerForecast = getNumRunsPerForecast(); - std::string TableName = "Forecasts"; - std::string ChartType = "Line"; - std::string LineStyle = "SolidLine"; - QStringList RowLabelsForBars; - QStringList ColumnLabelsForLegend; - std::string MainTitle = "Forecast Run"; - std::string XLabel = "Year"; - std::string YLabel = "Biomass (metric tons)"; - std::vector GridLines(true,true); // Replace with checkbox values - int Theme = 0; // Replace with checkbox values - QList LineColors; - std::string lineColorName = "MonteCarloSimulation"; - boost::numeric::ublas::matrix ChartLine; - boost::numeric::ublas::matrix ChartLinesMonteCarlo; - std::string Algorithm; - std::string Minimizer; - std::string ObjectiveCriterion; - std::string Scaling; - std::vector > ForecastBiomass; - std::vector > ForecastBiomassMonteCarlo; - std::vector SpeNames; - int NumSpecies; - boost::numeric::ublas::matrix ChartBMSYData; - int line = 0; // RSK change this later - std::vector fields; - std::map > dataMap; - std::string queryStr; - QList BMSYValues; - QList MSYValues; - QList FMSYValues; - std::string isAggProdStr = "0"; // RSK fix this later - int SpeciesNum = 0; // RSK - remove this later - double ScaleVal = 1.0; // RSK - remove this later - double pct = 1.0; - double brightnessFactor = 0.2; - QColor dimmedColor = QColor(255-brightnessFactor*255, - 255-brightnessFactor*255, - 255-brightnessFactor*255); - - LineColors.append(QColor(nmfConstants::LineColors[0].c_str())); - - m_DatabasePtr->getAllSpecies(m_Logger,SpeNames); - NumSpecies = SpeNames.size(); - - getYearRange(StartYear,EndYear); - StartForecastYear = EndYear; - - - - if (! m_DatabasePtr->getForecastInfo( - TableName,m_ForecastName,NumYearsPerRun,StartForecastYear, - Algorithm,Minimizer,ObjectiveCriterion,Scaling,NumRunsPerForecast)) { - return; - } - - if (! m_DatabasePtr->getForecastBiomassMonteCarlo( - 0,m_Logger,m_ForecastName, - NumSpecies,NumYearsPerRun,NumRunsPerForecast, - Algorithm,Minimizer,ObjectiveCriterion,Scaling, - ForecastBiomassMonteCarlo)) { - return; - } - - // Plot ForecastBiomass data - if (! m_DatabasePtr->getForecastBiomass( - 0,m_Logger,m_ForecastName, - NumSpecies,NumYearsPerRun, - Algorithm,Minimizer,ObjectiveCriterion,Scaling, - ForecastBiomass)) { - return; - } - - - ChartLinesMonteCarlo.resize(NumYearsPerRun+1,ForecastBiomassMonteCarlo.size()); - ChartLinesMonteCarlo.clear(); - ChartLine.resize(NumYearsPerRun+1,ForecastBiomass.size()); - ChartLine.clear(); - NoUncertaintyRun = ForecastBiomass.size(); - - - // Get ChartLinesMonteCarlo Data - for (int line=0; linesetMargins(chartMargins); - - // Draw forecast line(s) - m_ChartWidget->removeAllSeries(); - - // Draw stochastic forecast lines - m_ForecastLineChartMonteCarlo->populateChart( - m_ChartWidget, - ChartType, - LineStyle, - nmfConstantsMSSPM::ShowFirstPoint, - nmfConstants::DontShowLegend, - StartForecastYear, - nmfConstantsMSSPM::LabelXAxisAsInts, - YMinSliderVal, - ChartLinesMonteCarlo, - RowLabelsForBars, - ColumnLabelsForLegend, - MainTitle, - XLabel, - YLabel, - GridLines, - Theme, - dimmedColor, - "MonteCarloSimulation", - 1.0); - - // Draw single line without any uncertainty variation - m_ForecastLineChart->populateChart( - m_ChartWidget, - ChartType, - LineStyle, - nmfConstantsMSSPM::ShowFirstPoint, - nmfConstants::DontShowLegend, - StartForecastYear, - nmfConstantsMSSPM::LabelXAxisAsInts, - YMinSliderVal, - ChartLine, - RowLabelsForBars, - ColumnLabelsForLegend, - MainTitle, - XLabel, - YLabel, - GridLines, - Theme, - LineColors[0], - "No Uncertainty Variations", - 1.0); - } - - if (1) { - - // Remove any existing MSY series - QList allSeries = m_ChartWidget->series(); - int NumSeries = allSeries.size(); - if (NumSeries > NumRunsPerForecast+NoUncertaintyRun) { - for (int i=NumRunsPerForecast+NoUncertaintyRun; iremoveSeries(allSeries[i]); - } - } - - TableName = "OutputMSYBiomass"; - ChartBMSYData.resize(NumYearsPerRun+1,1); - ChartBMSYData.clear(); - - fields = {"Algorithm","Minimizer","ObjectiveCriterion","Scaling","isAggProd","SpeName","Value"}; - queryStr = "SELECT Algorithm,Minimizer,ObjectiveCriterion,Scaling,isAggProd,SpeName,Value FROM " + TableName; - queryStr += " WHERE Algorithm = '" + Algorithm + - "' AND Minimizer = '" + Minimizer + - "' AND ObjectiveCriterion = '" + ObjectiveCriterion + - "' AND Scaling = '" + Scaling + - "' AND isAggProd = " + isAggProdStr + - " ORDER by SpeName"; - - dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); - int NumRecords = dataMap["SpeName"].size(); - if (NumRecords == 0) { - m_Logger->logMsg(nmfConstants::Error, queryStr); - return; - } - - - for (int ii=0; ii<2; ++ii) { - - BMSYValues.clear(); - MSYValues.clear(); - FMSYValues.clear(); - ChartBMSYData.clear(); - - if ((ii == 0) && isMSYBoxChecked()) { - LineStyle = "DashedLine"; - pct = 1.0; - } else if ((ii == 1) && isEnablePctMSYBoxChecked()) { - LineStyle = "DottedLine"; - pct = MModePctMSYDL->value()/100.0; - } else { - continue; - } - - for (int j=0; jpopulateChart( - m_ChartWidget, - ChartType, - LineStyle, - nmfConstantsMSSPM::ShowFirstPoint, - nmfConstants::DontShowLegend, - StartForecastYear, - nmfConstantsMSSPM::LabelXAxisAsInts, - YMinSliderVal, - ChartBMSYData, - RowLabelsForBars, - ColumnLabelsForLegend, - MainTitle, - XLabel, - YLabel, - GridLines, - Theme, - LineColors[0], - lineColorName, - 1.0); - - - } - - } - -} diff --git a/MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.h b/MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.h deleted file mode 100644 index 389e8cf6..00000000 --- a/MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef MSSPM_GUIMANAGERMODE_H -#define MSSPM_GUIMANAGERMODE_H - -#include -#include -#include -#include -#include -#include -#include "nmfChartMovableLine.h" -#include "nmfChartLine.h" -#include - - -//QT_CHARTS_USE_NAMESPACE - -/** - * @brief The MSSPM_GuiManagerMode class - */ -class MSSPM_GuiManagerMode : public QObject -{ - Q_OBJECT - -private: - QSlider* MModeYearsPerRunSL; - QSlider* MModeRunsPerForecastSL; - QLineEdit* MModeYearsPerRunLE; - QLineEdit* MModeRunsPerForecastLE; - QLineEdit* MModeRParamLE; - QLineEdit* MModeKParamLE; - QLineEdit* MModeCParamLE; - QDial* MModeRParamDL; - QDial* MModeKParamDL; - QDial* MModeCParamDL; - QComboBox* MModeSpeciesCMB; - QWidget* MModeHarvestChartWidget; - QWidget* MModeUpperPlotWidget; - QWidget* MModeWindowWidget; - QPushButton* MModeForecastRunPB; - QCheckBox* MModeShowMSYCB; -// QSlider* MModeDetStocSL; - QDial* MModePctMSYDL; - QLineEdit* MModePctMSYLE; - QCheckBox* MModeEnablePctMSYCB; - QRadioButton* MModeDeterministicRB; - QRadioButton* MModeStochasticRB; - QRadioButton* MModePlotTypeSSRB; - QRadioButton* MModePlotTypeMSRB; - QPushButton* MModeCParamPB; - QLabel* MModePctMSYLBL; - - QChart* m_MModeHarvestChartWidget; - QChart* m_MModeOutputChartWidget; - nmfDatabase* m_DatabasePtr; - nmfLogger* m_Logger; - std::string m_ProjectSettingsConfig; - nmfChartMovableLine* m_MovableLineChart; - QChart* m_ChartWidget; - QChartView* m_ChartView; - nmfChartLine* m_ForecastLineChartMonteCarlo; - nmfChartLine* m_ForecastLineChart; - nmfChartLine* m_MSYLineChart; - - int m_NumUnusedParameters; - std::string m_ForecastName; - std::string m_HarvestType; - int m_NumYearsPerRun; - int m_NumRunsPerForecast; - - void drawChart(bool MSYOnly); - void saveHarvestData(); - void saveUncertaintyParameters(); - void saveOutputBiomassData(); - double getScaleValueFromPlot(int speciesNum, - int yearNum); - void getYearRange(int& firstYear, int& lastYear); - int getNumYearsPerRun(); - int getNumRunsPerForecast(); - bool isMSYBoxChecked(); - bool isEnablePctMSYBoxChecked(); - -signals: - void KeyPressed(QKeyEvent* event); - void MouseMoved(QMouseEvent* event); - void MouseReleased(QMouseEvent* event); - void SaveOutputBiomassData(std::string forecastName); - -public: - /** - * @brief MSSPM_GuiManagerMode - * @param MModeWidget - */ - MSSPM_GuiManagerMode( - nmfDatabase* databasePtr, - nmfLogger* logger, - std::string& projectSettingsConfig, - QWidget* MModeWidget); - ~MSSPM_GuiManagerMode(); - - - - void getLastYearsCatchValues( - int& lastYear, - std::vector& lastYearsCatchValues); - - /** - * @brief setupConnections - */ - void setupConnections(); - - /** - * @brief setupConnections - */ - void setData(const QStringList& speciesList); - -public Q_SLOTS: - - void callback_MModeCParamPB(); - void callback_PctMSYDL(); - void callback_EnablePctMSYCB(bool isChecked); - /** - * @brief callback_MSYCB - * @param isChecked - */ - void callback_MSYCB(bool isChecked); - /** - * @brief callback_YearsPerRun - * @param value - */ - void callback_YearsPerRunSL(int value); - /** - * @brief callback_RunsPerFore - * @param value - */ - void callback_RunsPerForecastSL(int value); - /** - * @brief callback_PctMSY - * @param value - */ - void callback_PctMSY(int value); - /** - * @brief callback_RParam - * @param value - */ - void callback_RParam(int value); - /** - * @brief callback_KParam - * @param value - */ - void callback_KParam(int value); - /** - * @brief callback_CParam - * @param value - */ - void callback_CParam(int value); - void callback_RunPB(); - void callback_RunPB(bool MSYOnly); - void callback_keyPressed(QKeyEvent* event); - void callback_mouseMoved(QMouseEvent* event); - void callback_mouseReleased(QMouseEvent* event); - void callback_StochasticPB(bool pressed); - void callback_DeterministicPB(bool pressed); - void callback_PlotTypeSSRB(bool pressed); - void callback_PlotTypeMSRB(bool pressed); - -}; - -#endif // MSSPM_GUIMANAGERMODE_H diff --git a/MSSPM_GuiManagerMode/REMORA.cpp b/MSSPM_GuiManagerMode/REMORA.cpp new file mode 100644 index 00000000..52f9004c --- /dev/null +++ b/MSSPM_GuiManagerMode/REMORA.cpp @@ -0,0 +1,2281 @@ +#include "REMORA.h" + +REMORA::REMORA( + nmfDatabase* databasePtr, + nmfLogger* logger, + std::string& projectDir, + std::string& projectSettingsConfig, + QStringList& SpeciesList, + QWidget* MModeWidget) +{ + m_DatabasePtr = databasePtr; + m_Logger = logger; + m_ProjectDir = projectDir; + m_ProjectSettingsConfig = projectSettingsConfig; + m_Widget = MModeWidget; + m_ScenarioChanged = false; + m_MaxYAxis = -1.0; + m_HarvestType = "ForecastCatch"; + m_NumYearsPerRun = 20; + m_NumRunsPerForecast = 10; + m_IndexMaxYScaleFactor = 0; + m_IndexScaleFactorChart1 = 0; + m_IndexScaleFactorChart2 = -1; + m_IndexScaleFactorPoint = 0; + + MModeYearsPerRunSL = MModeWidget->findChild("MModeYearsPerRunSL"); + MModeRunsPerForecastSL = MModeWidget->findChild("MModeRunsPerForecastSL"); + MModeScenarioNameLE = MModeWidget->findChild("MModeScenarioNameLE"); + MModeYearsPerRunLE = MModeWidget->findChild("MModeYearsPerRunLE"); + MModeRunsPerForecastLE = MModeWidget->findChild("MModeRunsPerForecastLE"); + MModePctMSYLE = MModeWidget->findChild("MModePctMSYLE"); + MModeRParamLE = MModeWidget->findChild("MModeRParamLE"); + MModeKParamLE = MModeWidget->findChild("MModeKParamLE"); + MModeHParamLE = MModeWidget->findChild("MModeHParamLE"); + MModePctMSYDL = MModeWidget->findChild("MModePctMSYDL"); + MModeRParamDL = MModeWidget->findChild("MModeRParamDL"); + MModeKParamDL = MModeWidget->findChild("MModeKParamDL"); + MModeHParamDL = MModeWidget->findChild("MModeHParamDL"); + MModeSpeciesCMB = MModeWidget->findChild("MModeSpeciesCMB"); + MModeSpeciesLB = MModeWidget->findChild("MModeSpeciesLB"); + MModeUpperPlotWidget = MModeWidget->findChild("MModeUpperPlotWidget"); + MModeHarvestChartWidget = MModeWidget->findChild("MModeHarvestChartWidget"); + MModeWindowWidget = MModeWidget->findChild("MModeWindowWidget"); + MModeParentChartW = MModeWidget->findChild("MModeParentChartW"); + MModeForecastRunPB = MModeWidget->findChild("MModeForecastRunPB"); + MModeForecastLoadPB = MModeWidget->findChild("MModeForecastLoadPB"); + MModeForecastSavePB = MModeWidget->findChild("MModeForecastSavePB"); + MModeForecastDelPB = MModeWidget->findChild("MModeForecastDelPB"); + MModeMultiPlotTypePB = MModeWidget->findChild("MModeMultiPlotTypePB"); + MModeMaxScaleFactorPB = MModeWidget->findChild("MModeMaxScaleFactorPB"); + MModeShowMSYCB = MModeWidget->findChild("MModeShowMSYCB"); + MModePctMSYCB = MModeWidget->findChild("MModePctMSYCB"); + MModeDeterministicRB = MModeWidget->findChild("MModeDeterministicRB"); + MModeStochasticRB = MModeWidget->findChild("MModeStochasticRB"); + MModePlotTypeSSRB = MModeWidget->findChild("MModePlotTypeSSRB"); + MModePlotTypeMSRB = MModeWidget->findChild("MModePlotTypeMSRB"); + MModeHarvestTypePB = MModeWidget->findChild("MModeHarvestTypePB"); + MModePctMSYLBL = MModeWidget->findChild("MModePctMSYLBL"); + MModeForecastPlotTypeCMB = MModeWidget->findChild("MModeForecastPlotTypeCMB"); + MModeForecastPlotTypeLB = MModeWidget->findChild("MModeForecastPlotTypeLB"); + MModeYAxisLockCB = MModeWidget->findChild("MModeYAxisLockCB"); + MModeForecastTypeLB = MModeWidget->findChild("MModeForecastTypeLB"); + MModePlotTypeLB = MModeWidget->findChild("MModePlotTypeLB"); + + MModeDeterministicRB->setChecked(false); + MModeStochasticRB->setChecked(true); + MModePlotTypeSSRB->setChecked(true); + MModePlotTypeMSRB->setChecked(false); + MModeMultiPlotTypePB->setEnabled(false); + MModeYearsPerRunSL->setPageStep(1); + MModeRunsPerForecastSL->setPageStep(1); + MModeHParamDL->setPageStep(1); + MModeRParamDL->setPageStep(1); + MModeKParamDL->setPageStep(1); + MModePctMSYDL->setPageStep(1); + MModeHarvestTypePB->setEnabled(false); // RSK - disable this temporarily until implemented + + // Setting the dials to their default values + MModePctMSYDL->setValue(110); + MModePctMSYLE->setText("110"); + MModeRParamDL->setValue(0); + MModeKParamDL->setValue(0); + MModeHParamDL->setValue(0); + MModePctMSYLE->setEnabled(false); + MModePctMSYDL->setEnabled(false); + MModePctMSYLBL->setEnabled(false); + + //Defaulting the sliders to their lowest values + MModeYearsPerRunSL->setValue(m_NumYearsPerRun); + MModeRunsPerForecastSL->setValue(m_NumRunsPerForecast); + + //Setting the paired line edits to the lowest values of their respective widgets + MModeYearsPerRunLE->setText(QString::number(m_NumYearsPerRun)); + MModeRunsPerForecastLE->setText(QString::number(m_NumRunsPerForecast)); + MModeRParamLE->setText(QString::number(0)); + MModeKParamLE->setText(QString::number(0)); + MModeHParamLE->setText(QString::number(0)); + + // Setup chart widgets + m_ChartWidget = new QChart(); + m_ChartView = new QChartView(m_ChartWidget); + m_VLayt = new QVBoxLayout(); + m_GridVLayt = new QVBoxLayout(); + m_GridLayt = new QGridLayout(); + m_GridParent = new QWidget(); + QLabel* gridTitle = new QLabel("Forecast Runs for All Species"); + m_ForecastLineChartMonteCarlo = new nmfChartLine(); + m_ForecastBiomassLineChart = new nmfChartLine(); + m_ForecastHarvestLineChart = new nmfChartLine(); + m_MSYLineChart = new nmfChartLine(); + QFont font = gridTitle->font(); + font.setPixelSize(font.pixelSize()+20); + font.setWeight(QFont::Bold); + gridTitle->setFont(font); + gridTitle->setAlignment(Qt::AlignHCenter); + m_GridVLayt->addWidget(gridTitle); + m_GridVLayt->addLayout(m_GridLayt); + m_GridParent->setLayout(m_GridVLayt); + m_VLayt->addWidget(m_ChartView); + MModeUpperPlotWidget->setLayout(m_VLayt); + + // Setup Remora's forecast directory + m_RemoraScenarioDir = QDir(QString::fromStdString(m_ProjectDir)).filePath( + QString::fromStdString(nmfConstantsMSSPM::OutputScenariosDirMMode)); + QDir().mkdir(m_RemoraScenarioDir); // Makes the directory if it doesn't already exist + + // Setup function map for setters + m_FunctionMap["Forecast"] = &REMORA::setScenarioName; + m_FunctionMap["NumYearsPerRun"] = &REMORA::setNumYearsPerRun; + m_FunctionMap["NumRunsPerForecast"] = &REMORA::setNumRunsPerForecast; + m_FunctionMap["isDeterministic"] = &REMORA::setDeterministic; + m_FunctionMap["isSingleSpecies"] = &REMORA::setSingleSpecies; + m_FunctionMap["isMultiPlot"] = &REMORA::setMultiPlot; + m_FunctionMap["ForecastDataType"] = &REMORA::setForecastPlotType; + m_FunctionMap["isMSYLineVisible"] = &REMORA::setMSYLineVisible; + m_FunctionMap["r_Uncertainty"] = &REMORA::setUncertaintyGrowth; + m_FunctionMap["K_Uncertainty"] = &REMORA::setUncertaintyCarryingCapacity; + m_FunctionMap["HarvestType"] = &REMORA::setHarvestType; + m_FunctionMap["H_Uncertainty"] = &REMORA::setUncertaintyHarvest; + m_FunctionMap["MaxYScaleFactor"] = &REMORA::setMaxYScaleFactor; + m_FunctionMap["NumScaleFactorPoints"] = &REMORA::setNumScaleFactorPoints; + m_FunctionMap["point"] = &REMORA::setAScaleFactorPoint; + + setupMovableLineCharts(SpeciesList); + setupConnections(); + enableWidgets(false); + +} + +REMORA::~REMORA() +{ + +} + +bool +REMORA::couldShowMSYCB() +{ + return (isSingleSpecies() || (isMultiSpecies() && isMultiPlot())); +} + +void +REMORA::drawMultiSpeciesChart() +{ + bool isFishingMortality = isFishingMortalityPlotType(); + bool isAbsoluteBiomass = isAbsoluteBiomassPlotType(); + bool isRelativeBiomass = isRelativeBiomassPlotType(); + int StartForecastYear; + int StartYear; + int EndYear; + int NumSpecies; + int NumObservedYears; + int LastCatchYear; + int YMinSliderVal = 0; + int NumYearsPerRun = getNumYearsPerRun(); + int NumRunsPerForecast = getNumRunsPerForecast(); + int NoUncertaintyRun = 0; + int SpeciesNum = -1; + int Theme = 0; + double ScaleVal = 1.0; + double CatchValue; + double remTime0Value; + std::string ChartType = "Line"; + std::string LineStyle = "SolidLine"; + std::string msg; + std::string Algorithm; + std::string Minimizer; + std::string ObjectiveCriterion; + std::string Scaling; + std::string TableName = "Forecasts"; + std::string MainTitle = "Forecast Runs for All Species"; + std::string XLabel = "Year"; + std::string YLabel; + QStringList RowLabelsForBars; + QStringList ColumnLabelsForLegend; + QStringList ColumnLabelsForLegendMSY; + QStringList HoverLabels; + boost::numeric::ublas::matrix ChartLine; + boost::numeric::ublas::matrix Catch; + std::vector SpeNames; + std::vector GridLines(true,true); + std::vector > ForecastBiomass; + QList LineColors; + + LineColors.append(QColor(nmfConstants::LineColors[0].c_str())); + + getYearRange(StartYear,EndYear); + NumObservedYears = EndYear - StartYear; + StartForecastYear = EndYear; + + m_DatabasePtr->getAllSpecies(m_Logger,SpeNames); + for (std::string species : SpeNames) { + ColumnLabelsForLegend << QString::fromStdString(species); + HoverLabels << QString::fromStdString(species); + ColumnLabelsForLegendMSY << "MSY"; + } + HoverLabels = ColumnLabelsForLegend; + NumSpecies = SpeNames.size(); + + if (isFishingMortality) { + YLabel = "Fishing Mortality (C/Bc)"; + if (! m_DatabasePtr->getTimeSeriesData(m_Widget,m_Logger,m_ProjectSettingsConfig, + "","","Catch",NumSpecies,NumObservedYears,Catch)) { + return; + } + LastCatchYear = Catch.size1()-1; + } else if (isAbsoluteBiomass) { + YLabel = "Biomass (metric tons)"; + } else if (isRelativeBiomass) { + YLabel = "Relative Biomass"; + } + + ChartLine.resize(NumYearsPerRun+1,NumSpecies); + ChartLine.clear(); + + if (! m_DatabasePtr->getForecastInfo( + TableName,m_ForecastName,NumYearsPerRun,StartForecastYear, + Algorithm,Minimizer,ObjectiveCriterion,Scaling,NumRunsPerForecast)) { + return; + } + + // Plot ForecastBiomass data + if (! m_DatabasePtr->getForecastBiomass( + m_Widget,m_Logger,m_ForecastName, + NumSpecies,NumYearsPerRun, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + ForecastBiomass)) { + return; + } + + // Get ChartLine Data (Forecast Biomass data without any stochasticity) + for (int species=0; speciesgetYValue(time) * Catch(LastCatchYear,species); + if (ForecastBiomass[0](time,species) == 0) { + ChartLine(time,species) = nmfConstantsMSSPM::NoFishingMortality; +// msg = "Found MS Biomass = 0, setting F to 0 for Species: " + +// SpeNames[species] + " at Year = " + std::to_string(time+StartForecastYear); +// m_Logger->logMsg(nmfConstants::Warning,msg); + } else { + ChartLine(time,species) = CatchValue/ForecastBiomass[0](time,species); + } + } else { + ChartLine(time,species) = ForecastBiomass[0](time,species)/ScaleVal; + if (isRelativeBiomass) { + if (time == 0) { + remTime0Value = ChartLine(0,species); + } + if (remTime0Value == 0) { + msg = "Found first year Biomass = 0, setting relative Biomass to 0 for Species: " + + SpeNames[species] + " at Year = " + std::to_string(time+StartForecastYear); + m_Logger->logMsg(nmfConstants::Warning,msg); + ChartLine(time,species) = 0; + } else { + ChartLine(time,species) /= remTime0Value; + } + } + } + } + } + + m_GridParent->hide(); + m_ChartView->show(); + + m_ForecastHarvestLineChart->populateChart( + m_ChartWidget, + ChartType, + LineStyle, + nmfConstantsMSSPM::ShowFirstPoint, + nmfConstants::ShowLegend, + StartForecastYear, + nmfConstantsMSSPM::LabelXAxisAsInts, + YMinSliderVal, + nmfConstantsMSSPM::LeaveGapsWhereNegative, + ChartLine, + RowLabelsForBars, + ColumnLabelsForLegend, + HoverLabels, + MainTitle, + XLabel, + YLabel, + GridLines, + Theme, + LineColors[0], + "MultiSpecies", + 1.0); + + removeMSYLines(m_ChartWidget,{"MSY = r/2","MSY = K/2"}); + removeMSYLines(m_ChartWidget,{"MSY = % of r/2","MSY = % of K/2"}); + if (isMSYBoxChecked()) { + drawMSYLines(m_ChartWidget,SpeciesNum,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegendMSY,HoverLabels, + MainTitle,XLabel,YLabel,nmfConstants::ShowLegend,1.0); + } + if (isPctMSYBoxChecked()) { + drawMSYLines(m_ChartWidget,SpeciesNum,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegendMSY,HoverLabels, + MainTitle,XLabel,YLabel,nmfConstants::ShowLegend,getPctMSYValue()); + } + +} + +void +REMORA::drawMSYLines() +{ + int StartYear; + int EndYear; + int NumSpecies; + int StartForecastYear; + int YMinSliderVal = 0; + int NoUncertaintyRun = 0; + int NumYearsPerRun = getNumYearsPerRun(); + int NumRunsPerForecast = getNumRunsPerForecast(); + int SpeciesNum = getSpeciesNum(); + std::string XLabel = "Year"; + std::string YLabel = "Biomass (metric tons)"; + std::string MainTitle = "Forecast Run for Species: "; + std::string Algorithm; + std::string Minimizer; + std::string ObjectiveCriterion; + std::string Scaling; + std::string TableName = "Forecasts"; + std::vector SpeNames; + QStringList RowLabelsForBars; + QStringList HoverLabels; + QStringList HoverLabelsPct; + QStringList ColumnLabelsForLegendMSY; + QStringList ColumnLabelsForLegendPctMSY; + + getYearRange(StartYear,EndYear); + StartForecastYear = EndYear; + + m_DatabasePtr->getAllSpecies(m_Logger,SpeNames); + NumSpecies = SpeNames.size(); + MainTitle += SpeNames[SpeciesNum]; + + if (! m_DatabasePtr->getForecastInfo( + TableName,m_ForecastName,NumYearsPerRun,StartForecastYear, + Algorithm,Minimizer,ObjectiveCriterion,Scaling,NumRunsPerForecast)) { + return; + } + + if (isSingleSpecies()) { + + if (isMSYBoxChecked()) { + HoverLabels.clear(); + ColumnLabelsForLegendMSY.clear(); + if (isAbsoluteBiomassPlotType()) { + HoverLabels << "MSY = K/2"; + ColumnLabelsForLegendMSY << "MSY = K/2"; + } else if (isFishingMortalityPlotType()) { + HoverLabels << "MSY = r/2"; + ColumnLabelsForLegendMSY << "MSY = r/2"; + } + drawMSYLines(m_ChartWidget,SpeciesNum,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegendMSY,HoverLabels, + MainTitle,XLabel,YLabel,nmfConstants::DontShowLegend,1.0); + } + if (isPctMSYBoxChecked()) { + HoverLabelsPct.clear(); + ColumnLabelsForLegendPctMSY.clear(); + if (isAbsoluteBiomassPlotType()) { + HoverLabelsPct << "MSY = % of K/2"; + ColumnLabelsForLegendPctMSY << "MSY = % of K/2"; + } else if (isFishingMortalityPlotType()) { + HoverLabelsPct << "MSY = % of r/2"; + ColumnLabelsForLegendPctMSY << "MSY = % of r/2"; + } + drawMSYLines(m_ChartWidget,SpeciesNum,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegendPctMSY,HoverLabelsPct, + MainTitle,XLabel,YLabel,nmfConstants::DontShowLegend,getPctMSYValue()); + } + qobject_cast(m_ChartWidget->axisY())->setTickCount(5); + + } else if (isMultiPlot()) { + SpeciesNum = 0; + if (isAbsoluteBiomassPlotType()) { + YLabel = "Biomass (mt)"; + } else if (isRelativeBiomassPlotType()) { + YLabel = "Rel Biomass"; + } else if (isFishingMortalityPlotType()) { + YLabel = "F Mortality (C/Bc)"; + } + for (QChart* chart : m_Charts) { + MainTitle = SpeNames[SpeciesNum]; + if (isMSYBoxChecked()) { + HoverLabels.clear(); + ColumnLabelsForLegendMSY.clear(); + if (isAbsoluteBiomassPlotType()) { + HoverLabels << "MSY = K/2"; + ColumnLabelsForLegendMSY << "MSY = K/2"; + } else if (isFishingMortalityPlotType()) { + HoverLabels << "MSY = r/2"; + ColumnLabelsForLegendMSY << "MSY = r/2"; + } + drawMSYLines(chart,SpeciesNum,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegendMSY,HoverLabels, + MainTitle,XLabel,YLabel,nmfConstants::DontShowLegend,1.0); + } + if (isPctMSYBoxChecked()) { + HoverLabelsPct.clear(); + ColumnLabelsForLegendPctMSY.clear(); + if (isAbsoluteBiomassPlotType()) { + HoverLabelsPct << "MSY = % of K/2"; + ColumnLabelsForLegendPctMSY << "MSY = % of K/2"; + } else if (isFishingMortalityPlotType()) { + HoverLabelsPct << "MSY = % of r/2"; + ColumnLabelsForLegendPctMSY << "MSY = % of r/2"; + } + drawMSYLines(chart,SpeciesNum,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegendPctMSY,HoverLabelsPct, + MainTitle,XLabel,YLabel,nmfConstants::DontShowLegend,getPctMSYValue()); + } + qobject_cast(chart->axisY())->setTickCount(5); + ++SpeciesNum; + } + + } + + resetXAxis(); +} + +void +REMORA::drawMSYLines( + QChart* chart, + int& SpeciesNum, + int& NumSpecies, + int& NumYearsPerRun, + int& NumRunsPerForecast, + int& NoUncertaintyRun, + int& StartForecastYear, + int& YMinSliderVal, + std::string& Algorithm, + std::string& Minimizer, + std::string& ObjectiveCriterion, + std::string& Scaling, + QStringList& RowLabelsForBars, + QStringList& ColumnLabelsForLegend, + QStringList& HoverData, + std::string& MainTitle, + std::string& XLabel, + std::string& YLabel, + const bool& ShowLegend, + const double& Pct) +{ + bool isFishingMortality = (getForecastPlotType() == "Fishing Mortality"); + int Theme = 0; + double MSYValue; + double ScaleVal = 1.0; + std::string queryStr; + std::string LineStyle = "DashedLine"; + std::string ChartType = "Line"; + std::string isAggProdStr = "0"; + boost::numeric::ublas::matrix ChartMSYData; + std::map > dataMap; + std::vector fields; + std::vector GridLines(true,true); + QColor LineColor = QColor(nmfConstants::LineColors[0].c_str()); + + if (Pct != 1.0) { + LineStyle = "DottedLine"; + } + + std::string TableName = (isFishingMortality) ? "OutputMSYFishing" : "OutputMSYBiomass"; + if (SpeciesNum == -1) { + ChartMSYData.resize(NumYearsPerRun+1,NumSpecies); + } else { + ChartMSYData.resize(NumYearsPerRun+1,1); + } + ChartMSYData.clear(); + + fields = {"Algorithm","Minimizer","ObjectiveCriterion","Scaling","isAggProd","SpeName","Value"}; + queryStr = "SELECT Algorithm,Minimizer,ObjectiveCriterion,Scaling,isAggProd,SpeName,Value FROM " + TableName; + queryStr += " WHERE Algorithm = '" + Algorithm + + "' AND Minimizer = '" + Minimizer + + "' AND ObjectiveCriterion = '" + ObjectiveCriterion + + "' AND Scaling = '" + Scaling + + "' AND isAggProd = " + isAggProdStr + + " ORDER by SpeName"; + + dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); + int NumRecords = dataMap["SpeName"].size(); + if (NumRecords == 0) { + m_Logger->logMsg(nmfConstants::Error, queryStr); + return; + } + // Draw the MSY line + for (int i=0; ipopulateChart( + chart, + ChartType, + LineStyle, + nmfConstantsMSSPM::ShowFirstPoint, + ShowLegend, + StartForecastYear, + nmfConstantsMSSPM::LabelXAxisAsInts, + YMinSliderVal, + nmfConstantsMSSPM::LeaveGapsWhereNegative, + ChartMSYData, + RowLabelsForBars, + ColumnLabelsForLegend, + HoverData, + MainTitle, + XLabel, + YLabel, + GridLines, + Theme, + LineColor, + "MultiSpecies", + 1.0); +} + +void +REMORA::drawPlot() +{ + m_ForecastBiomassLineChart->clear(m_ChartWidget); + m_ForecastHarvestLineChart->clear(m_ChartWidget); + m_ForecastLineChartMonteCarlo->clear(m_ChartWidget); + + if (couldShowMSYCB()) { + drawSingleSpeciesChart(); + } else { + drawMultiSpeciesChart(); + } + + // Rescale axes of plot(s) + resetXAxis(); + resetYAxis(); +} + +void +REMORA::drawSingleSpeciesChart() +{ + bool isFishingMortality = isFishingMortalityPlotType(); + bool isAbsoluteBiomass = isAbsoluteBiomassPlotType(); + bool isRelativeBiomass = isRelativeBiomassPlotType(); + int StartYear; + int EndYear; + int NumSpecies; + int StartForecastYear; + int YMinSliderVal = 0; + int NoUncertaintyRun = 0; + int NumYearsPerRun = getNumYearsPerRun(); + int NumRunsPerForecast = getNumRunsPerForecast(); + int SpeciesNum = getSpeciesNum(); + int Theme = 0; + int LastCatchYear; + int NumObservedYears; + double ScaleVal = 1.0; + double brightnessFactor = 0.2; + double CatchValue; + double remTime0Value; + std::string TableName = "Forecasts"; + std::string ChartType = "Line"; + std::string LineStyle = "SolidLine"; + std::string MainTitle = "Forecast Run"; + std::string XLabel = "Year"; + std::string YLabel = "Biomass (metric tons)"; + std::string Algorithm; + std::string Minimizer; + std::string ObjectiveCriterion; + std::string Scaling; + std::string CurrentSpecies; + std::string msg; + std::string MainTitleMultiPlot; + std::string YLabelMultiPlot; + QStringList RowLabelsForBars; + QStringList ColumnLabelsForLegend; + QStringList HoverData; + QStringList HoverLabels; + QStringList HoverLabelsPct; + boost::numeric::ublas::matrix ChartLine; + boost::numeric::ublas::matrix ChartLineSinglePlot; + boost::numeric::ublas::matrix ChartLinesMonteCarlo; + boost::numeric::ublas::matrix ChartLinesMonteCarloSinglePlot; + std::vector > ChartLineMultiPlot; + std::vector > ChartLinesMonteCarloMultiPlot; + std::vector > ChartLineSpans; + boost::numeric::ublas::matrix Catch; + std::vector GridLines(true,true); + std::vector > ForecastBiomass; + std::vector > ForecastBiomassMonteCarlo; + std::vector SpeNames; + QList LineColors; + QColor dimmedColor = QColor(255-brightnessFactor*255, + 255-brightnessFactor*255, + 255-brightnessFactor*255); + LineColors.append(QColor(nmfConstants::LineColors[0].c_str())); + + m_DatabasePtr->getAllSpecies(m_Logger,SpeNames); + NumSpecies = SpeNames.size(); + CurrentSpecies = SpeNames[SpeciesNum]; + MainTitle += " for Species: " + CurrentSpecies; + + getYearRange(StartYear,EndYear); + StartForecastYear = EndYear; + NumObservedYears = EndYear-StartYear; + + if (isFishingMortality) { + YLabel = "Fishing Mortality (C/Bc)"; + if (! m_DatabasePtr->getTimeSeriesData(m_Widget,m_Logger,m_ProjectSettingsConfig, + "","","Catch",NumSpecies,NumObservedYears,Catch)) { + return; + } + LastCatchYear = Catch.size1()-1; + } else if (isRelativeBiomass) { + YLabel = "Relative Biomass"; + } + + if (! m_DatabasePtr->getForecastInfo( + TableName,m_ForecastName,NumYearsPerRun,StartForecastYear, + Algorithm,Minimizer,ObjectiveCriterion,Scaling,NumRunsPerForecast)) { + return; + } + + if (! m_DatabasePtr->getForecastBiomassMonteCarlo( + m_Widget,m_Logger,m_ForecastName, + NumSpecies,NumYearsPerRun,NumRunsPerForecast, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + ForecastBiomassMonteCarlo)) { + return; + } + + // Plot ForecastBiomass data + if (! m_DatabasePtr->getForecastBiomass( + m_Widget,m_Logger,m_ForecastName, + NumSpecies,NumYearsPerRun, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + ForecastBiomass)) { + return; + } + + if (! m_DatabasePtr->getForecastMonteCarloParameters( + m_Widget,m_Logger,m_ForecastName, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + HoverData)) { + return; + } + + ChartLinesMonteCarlo.resize(NumYearsPerRun+1,ForecastBiomassMonteCarlo.size()); + ChartLinesMonteCarlo.clear(); + ChartLine.resize(NumYearsPerRun+1,ForecastBiomass.size()); + ChartLine.clear(); + NoUncertaintyRun = ForecastBiomass.size(); + + // Get ChartLinesMonteCarlo Data + for (int species=0; speciesgetYValue(time) * Catch(LastCatchYear,species); + if (ForecastBiomassMonteCarlo[line](time,species) == 0) { + ChartLinesMonteCarlo(time,line) = nmfConstantsMSSPM::NoFishingMortality; +// msg = "Found Monte Carlo Biomass = 0, setting F to 0 for Species: " + +// SpeNames[species] + " at Year = " + std::to_string(time+StartForecastYear); +// m_Logger->logMsg(nmfConstants::Warning,msg); + } else { + ChartLinesMonteCarlo(time,line) = CatchValue/ForecastBiomassMonteCarlo[line](time,species); + } + } else { + ChartLinesMonteCarlo(time,line) = ForecastBiomassMonteCarlo[line](time,species)/ScaleVal; + if (time == 0) { + remTime0Value = ChartLinesMonteCarlo(0,line); + } + if (isRelativeBiomass) { + if (remTime0Value == 0) { + ChartLinesMonteCarlo(time,line) = 0; + } else { + ChartLinesMonteCarlo(time,line) /= remTime0Value; + } + } + } + } + } + + if (species == SpeciesNum) { + ChartLinesMonteCarloSinglePlot = ChartLinesMonteCarlo; + } + ChartLinesMonteCarloMultiPlot.push_back(ChartLinesMonteCarlo); + } + + // Get ChartLineMultiPlot Data + for (int species=0; speciesgetYValue(time) * Catch(LastCatchYear,species); + if (ForecastBiomass[0](time,species) == 0) { + ChartLine(time,0) = nmfConstantsMSSPM::NoFishingMortality; +// msg = "Found Biomass = 0, setting F to 0 for Species: " + +// SpeNames[species] + " at Year = " + std::to_string(time+StartForecastYear); +// m_Logger->logMsg(nmfConstants::Warning,msg); + } else { + ChartLine(time,0) = CatchValue/ForecastBiomass[0](time,species); + } + } else { + ChartLine(time,0) = ForecastBiomass[0](time,species)/ScaleVal; + if (time == 0) { + remTime0Value = ChartLine(0,0); + } + if (isRelativeBiomass) { + if (remTime0Value == 0) { + ChartLine(time,0) = 0; + } else { + ChartLine(time,0) /= remTime0Value; + } + } + } + } + if (species == SpeciesNum) { + ChartLineSinglePlot = ChartLine; + } + ChartLineMultiPlot.push_back(ChartLine); + } + + if (isMultiSpecies() && isMultiPlot()) { + + m_ChartView->hide(); + m_GridParent->show(); + + m_Charts.clear(); + m_Views.clear(); + for (int i=0; isetRowStretch(row,1); + for (int col=0; colsetColumnStretch(col,1); + } + m_GridLayt->addWidget(m_Views[m++],row,col); + } else { + done = true; + } + } + } + m_VLayt->addWidget(m_GridParent); + int species = 0; + if (isFishingMortality) { + YLabelMultiPlot = "F Mortality (C/Bc)"; + } else if (isAbsoluteBiomass) { + YLabelMultiPlot = "Biomass (mt)"; + } else if (isRelativeBiomass) { + YLabelMultiPlot = "Rel Biomass"; + } + //YLabelMultiPlot = (isFishingMortality) ? "F Mortality (C/Bc)" : "Biomass (mt)"; + for (QChart* chart : m_Charts) { + + QMargins chartMargins(8, 10, 20, 10); + m_ChartWidget->setMargins(chartMargins); + + // Draw forecast line(s) + m_ChartWidget->removeAllSeries(); + + // Draw stochastic forecast lines + MainTitleMultiPlot = SpeNames[species]; + m_ForecastLineChartMonteCarlo->clear(chart); + + // Split curve up into spans. Gaps are where yvalue = -1. + // Then iterate and call populateChart for each span. + m_ForecastLineChartMonteCarlo->populateChart( + chart, + ChartType, + LineStyle, + nmfConstantsMSSPM::ShowFirstPoint, + nmfConstants::DontShowLegend, + StartForecastYear, + nmfConstantsMSSPM::LabelXAxisAsInts, + YMinSliderVal, + nmfConstantsMSSPM::LeaveGapsWhereNegative, + ChartLinesMonteCarloMultiPlot[species], + RowLabelsForBars, + ColumnLabelsForLegend, + HoverData, + MainTitleMultiPlot, + XLabel, + YLabelMultiPlot, + GridLines, + Theme, + dimmedColor, + "MonteCarloSimulation", + 1.0); + + // Draw single line without any uncertainty variation + m_ForecastBiomassLineChart->populateChart( + chart, + ChartType, + LineStyle, + nmfConstantsMSSPM::ShowFirstPoint, + nmfConstants::DontShowLegend, + StartForecastYear, + nmfConstantsMSSPM::LabelXAxisAsInts, + YMinSliderVal, + nmfConstantsMSSPM::LeaveGapsWhereNegative, + ChartLineMultiPlot[species], + RowLabelsForBars, + ColumnLabelsForLegend, + {HoverData[NumRunsPerForecast]}, + MainTitleMultiPlot, + XLabel, + YLabelMultiPlot, + GridLines, + Theme, + LineColors[0], + "No Uncertainty Variations", + 1.0); + + removeMSYLines(chart,{"MSY = r/2","MSY = K/2"}); + removeMSYLines(chart,{"MSY = % of r/2","MSY = % of K/2"}); + + if (isMSYBoxChecked()) { + HoverLabels.clear(); + if (isFishingMortality) { + HoverLabels << "MSY = r/2"; + } else if (isAbsoluteBiomass) { + HoverLabels << "MSY = K/2"; + } else if (isRelativeBiomass) { + HoverLabels << ""; + } + drawMSYLines(chart,species,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegend,HoverLabels, + MainTitleMultiPlot,XLabel,YLabelMultiPlot, + nmfConstants::DontShowLegend,1.0); + } + if (isPctMSYBoxChecked()) { + HoverLabelsPct.clear(); + if (isFishingMortality) { + HoverLabelsPct << "MSY = % of r/2"; + } else if (isAbsoluteBiomass) { + HoverLabelsPct << "MSY = % of K/2"; + } else if (isRelativeBiomass) { + HoverLabelsPct << ""; + } + drawMSYLines(chart,species,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegend,HoverLabelsPct, + MainTitleMultiPlot,XLabel,YLabelMultiPlot, + nmfConstants::DontShowLegend,getPctMSYValue()); + } + + qobject_cast(chart->axisY())->setTickCount(5); + ++species; + } + + } + + if (isSingleSpecies()) { + + m_GridParent->hide(); + m_ChartView->show(); + + QMargins chartMargins(8, 10, 20, 10); + m_ChartWidget->setMargins(chartMargins); + + // Draw forecast line(s) + m_ChartWidget->removeAllSeries(); + + // Draw stochastic forecast lines + m_ForecastLineChartMonteCarlo->populateChart( + m_ChartWidget, + ChartType, + LineStyle, + nmfConstantsMSSPM::ShowFirstPoint, + nmfConstants::DontShowLegend, + StartForecastYear, + nmfConstantsMSSPM::LabelXAxisAsInts, + YMinSliderVal, + nmfConstantsMSSPM::LeaveGapsWhereNegative, + ChartLinesMonteCarloSinglePlot, + RowLabelsForBars, + ColumnLabelsForLegend, + HoverData, + MainTitle, + XLabel, + YLabel, + GridLines, + Theme, + dimmedColor, + "MonteCarloSimulation", + 1.0); + + // Draw single line without any uncertainty variation + m_ForecastBiomassLineChart->populateChart( + m_ChartWidget, + ChartType, + LineStyle, + nmfConstantsMSSPM::ShowFirstPoint, + nmfConstants::DontShowLegend, + StartForecastYear, + nmfConstantsMSSPM::LabelXAxisAsInts, + YMinSliderVal, + nmfConstantsMSSPM::LeaveGapsWhereNegative, + ChartLineSinglePlot, + RowLabelsForBars, + ColumnLabelsForLegend, + {HoverData[NumRunsPerForecast]}, + MainTitle, + XLabel, + YLabel, + GridLines, + Theme, + LineColors[0], + "No Uncertainty Variations", + 1.0); + + // Remove any existing MSY series + removeMSYLines(m_ChartWidget,{"MSY = r/2","MSY = K/2"}); + removeMSYLines(m_ChartWidget,{"MSY = % of r/2","MSY = % of K/2"}); + + if (isMSYBoxChecked()) { + HoverLabels.clear(); + if (isFishingMortality) { + HoverLabels << "MSY = r/2"; + } else if (isAbsoluteBiomass) { + HoverLabels << "MSY = K/2"; + } else if (isRelativeBiomass) { + HoverLabels << ""; + } + drawMSYLines(m_ChartWidget,SpeciesNum,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegend,HoverLabels, + MainTitle,XLabel,YLabel,nmfConstants::DontShowLegend,1.0); + } + if (isPctMSYBoxChecked()) { + HoverLabelsPct.clear(); + if (isFishingMortality) { + HoverLabelsPct << "MSY = % of r/2"; + } else if (isAbsoluteBiomass) { + HoverLabelsPct << "MSY = % of K/2"; + } else if (isRelativeBiomass) { + HoverLabelsPct << ""; + } + drawMSYLines(m_ChartWidget,SpeciesNum,NumSpecies,NumYearsPerRun,NumRunsPerForecast, + NoUncertaintyRun,StartForecastYear,YMinSliderVal, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + RowLabelsForBars,ColumnLabelsForLegend,HoverLabelsPct, + MainTitle,XLabel,YLabel,nmfConstants::DontShowLegend,getPctMSYValue()); + } + + qobject_cast(m_ChartWidget->axisY())->setTickCount(5); + } +} + + +void +REMORA::enableWidgets(bool enable) +{ + MModePctMSYLE->setEnabled(enable); + MModePctMSYDL->setEnabled(enable); + MModeSpeciesCMB->setEnabled(enable); + MModeSpeciesLB->setEnabled(enable); + MModeMaxScaleFactorPB->setEnabled(enable); + MModeShowMSYCB->setEnabled(enable); + MModePctMSYCB->setEnabled(enable); + MModePlotTypeSSRB->setEnabled(enable); + MModePlotTypeMSRB->setEnabled(enable); + MModePctMSYLBL->setEnabled(enable); + MModeForecastPlotTypeCMB->setEnabled(enable); + MModeForecastPlotTypeLB->setEnabled(enable); + MModeYAxisLockCB->setEnabled(enable); + MModeForecastTypeLB->setEnabled(enable); + MModePlotTypeLB->setEnabled(enable); + MModeMultiPlotTypePB->setEnabled(enable); + if (isSingleSpecies()) { + MModeMultiPlotTypePB->setEnabled(false); + } +} + +QString +REMORA::getCarryingCapacityUncertainty() +{ + return MModeKParamLE->text(); +} + +QString +REMORA::getForecastPlotType() +{ + return MModeForecastPlotTypeCMB->currentText(); +} + +QString +REMORA::getGrowthUncertainty() +{ + return MModeRParamLE->text(); +} + +QString +REMORA::getHarvestType() +{ + return MModeHarvestTypePB->text(); +} + +QString +REMORA::getHarvestUncertainty() +{ + return MModeHParamLE->text(); +} + +void +REMORA::getLastYearsCatchValues( + int& lastYear, + std::vector& lastYearsCatchValues) +{ + std::vector fields; + std::map > dataMap; + std::string queryStr; + + lastYearsCatchValues.clear(); + + // Get last year's catch data + fields = {"Value"}; + queryStr = "SELECT Value from Catch where SystemName = '" + + QString::fromStdString(m_ProjectSettingsConfig).split("__")[0].toStdString() + "'"; + queryStr += " AND Year = " + std::to_string(lastYear-1); + dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); + for (unsigned i=0; i= 0) { + return m_MovableLineCharts[speciesNum]->getMaxYScaleFactor(); + } else { + return MAX_SCALE_VALUE; + } +} + +int +REMORA::getNumRunsPerForecast() +{ + return MModeRunsPerForecastLE->text().toInt(); +} + +int +REMORA::getNumScaleFactorPoints(const int& speciesNum) +{ + if (speciesNum >= 0) { + return m_MovableLineCharts[speciesNum]->getNumPoints(); + } else { + return 2; + } +} + +int +REMORA::getNumSpecies() +{ + return MModeSpeciesCMB->count(); +} + +int +REMORA::getNumYearsPerRun() +{ + return MModeYearsPerRunLE->text().toInt(); +} + + +double +REMORA::getPctMSYValue() +{ + return MModePctMSYDL->value()/100.0; +} + +QList +REMORA::getScaleFactorPoints(const int& speciesNum) +{ + if (speciesNum >= 0) { + return m_MovableLineCharts[speciesNum]->getPoints(); + } else { + return {}; + } +} + +double +REMORA::getScaleValueFromPlot(int speciesNum, + int year) +{ + double scaleValue; + + if (speciesNum >= 0) { + scaleValue = m_MovableLineCharts[speciesNum]->getYValue(year); + } else { + scaleValue = 1.0; + } + if (scaleValue < 0) { + m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::getScaleValueFromPlot: Error reading from Scale plot"); + return 0; + } + return scaleValue; +} + +QString +REMORA::getScenarioName() +{ + return MModeScenarioNameLE->text(); +} + +int +REMORA::getSpeciesNum() +{ + return MModeSpeciesCMB->currentIndex(); +} + +void +REMORA::getYearRange(int& firstYear, int& lastYear) +{ + int StartYear; + int NumYears; + std::vector fields; + std::map > dataMap; + std::string queryStr; + + fields = {"StartYear","RunLength"}; + queryStr = "SELECT StartYear,RunLength from Systems where SystemName = '" + + QString::fromStdString(m_ProjectSettingsConfig).split("__")[0].toStdString() + "'"; + dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); + if (dataMap["RunLength"].size() != 0) { + StartYear = std::stoi(dataMap["StartYear"][0]); + NumYears = std::stoi(dataMap["RunLength"][0]); + } + firstYear = StartYear; + lastYear = firstYear + NumYears; +} + +void +REMORA::grabImage(QPixmap& pm) +{ + if (isSingleSpecies()) { + // This will grab the Harvest Scale Factor plot as well as the Model plot(s) + pm = MModeParentChartW->grab(); + } else { + // This will only grab only the Model plot(s) + if (isMultiPlot()) { + pm = m_GridParent->grab(); + } else { + pm = m_ChartView->grab(); + } + } +} + +bool +REMORA::isAbsoluteBiomassPlotType() +{ + return (MModeForecastPlotTypeCMB->currentText() == "Biomass (absolute)"); +} + +bool +REMORA::isDeterministic() +{ + return MModeDeterministicRB->isChecked(); +} + +bool +REMORA::isFishingMortalityPlotType() +{ + return (MModeForecastPlotTypeCMB->currentText() == "Fishing Mortality"); +} + +bool +REMORA::isMultiPlot() +{ + return (MModeMultiPlotTypePB->text() == "1+"); +} + +bool +REMORA::isMultiSpecies() +{ + return MModePlotTypeMSRB->isChecked(); +} + +bool +REMORA::isMSYBoxChecked() +{ + return MModeShowMSYCB->isChecked(); +} + +bool +REMORA::isPctMSYBoxChecked() +{ + return MModePctMSYCB->isChecked(); +} + +bool +REMORA::isRelativeBiomassPlotType() +{ + return (MModeForecastPlotTypeCMB->currentText() == "Biomass (relative)"); +} + +bool +REMORA::isSingleSpecies() +{ + return MModePlotTypeSSRB->isChecked(); +} + +bool +REMORA::isYAxisLocked() +{ + return MModeYAxisLockCB->isChecked(); +} + +void +REMORA::loadForecastScenario(QString filename) +{ + QString line; + QString controlName; + QString controlData; + QStringList parts; + QFile file(filename); + + m_IndexMaxYScaleFactor = 0; + m_IndexScaleFactorChart1 = 0; + m_IndexScaleFactorChart2 = -1; + + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QTextStream in(&file); + while (!in.atEnd()) { + line = in.readLine().trimmed(); + if (line[0] != '#') { + parts = line.split(":"); + controlName = parts[0].trimmed(); + controlData = parts[1].trimmed(); + // Call the setter that corresponds to the control name found in config file. + // Using a function map so don't have to use series of if...else if... statements. + (this->*m_FunctionMap[controlName])(controlData); + } + } + } + + MModeMaxScaleFactorPB->setText(QString::number(m_MaxYAxisValues[0])); +} + +void +REMORA::removeMSYLines( + QChart* chart, + const QStringList& MSYTypes) +{ + QList allSeries = chart->series(); + int NumSeries = allSeries.size(); + + for (int i=NumSeries-1; i >= 0; --i) { + for (QString type : MSYTypes) { + if (allSeries[i]->name().contains(type)) { + chart->removeSeries(allSeries[i]); + break; + } + } + } +} + +void +REMORA::removeAllMSYLines(QString type) +{ + QStringList types; + if (type == "%") { + types << "MSY = % of r/2" << "MSY = % of K/2"; + } else { + types << "MSY = r/2" << "MSY = K/2"; + } + if (isMultiSpecies() && isMultiPlot()) { + for (QChart* chart : m_Charts) { + removeMSYLines(chart,types); + } + } else { + removeMSYLines(m_ChartWidget,types); + } +} + +void +REMORA::resetControls() +{ + setScenarioName(""); + setUncertaintyGrowth("0"); + setUncertaintyCarryingCapacity("0"); + setUncertaintyHarvest("0"); +} + +void +REMORA::resetNumYearsOnScaleFactorCharts() +{ + for (int i=0; isetRange(m_NumYearsPerRun); + } +} + +void +REMORA::resetScenarioName() +{ + QString scenarioName = getScenarioName(); + scenarioName.remove('*'); + setScenarioName(scenarioName); +} + +void +REMORA::saveForecastParameters() +{ + int startYear; + int endYear; + std::string errorMsg; + + getYearRange(startYear,endYear); + int endForecastYear = endYear + m_NumYearsPerRun; + + // Update forecast parameters in Forecasts file + std::string cmd = + "UPDATE Forecasts SET NumRuns = " + std::to_string(getNumRunsPerForecast()) + + ", RunLength = " + std::to_string(getNumYearsPerRun()) + + ", EndYear = " + std::to_string(endForecastYear) + + ", IsDeterministic = " + std::to_string(isDeterministic()) + + " WHERE ForecastName = '" + m_ProjectSettingsConfig + "'"; + errorMsg = m_DatabasePtr->nmfUpdateDatabase(cmd); + if (errorMsg != " ") { + m_Logger->logMsg(nmfConstants::Error,"[Error 1] MSSPM_GuiManagerMode: DELETE error: " + errorMsg); + m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); + } + + // Update seed value in main + emit UpdateSeedValue(isDeterministic()); +} + +bool +REMORA::saveForecastScenario(QString filename) +{ + bool retv = false; + int numScaleFactorPoints; + int numSpecies = getNumSpecies(); + QList scaleFactorPoints; + QFile file(filename); + + if (file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QTextStream stream(&file); + stream << "# " << '\n'; + stream << "# This is a REMORA Forecast configuration file" << '\n'; + stream << "# " << '\n'; + stream << "Forecast: " << getScenarioName() << '\n'; + stream << "NumYearsPerRun: " << getNumYearsPerRun() << '\n'; + stream << "NumRunsPerForecast: " << getNumRunsPerForecast() << '\n'; + stream << "isDeterministic: " << isDeterministic() << '\n'; + stream << "isSingleSpecies: " << isSingleSpecies() << '\n'; + stream << "isMultiPlot: " << isMultiPlot() << '\n'; + stream << "ForecastDataType: " << getForecastPlotType() << '\n'; + stream << "isMSYLineVisible: " << isMSYBoxChecked() << '\n'; + stream << "r_Uncertainty: " << getGrowthUncertainty() << '\n'; + stream << "K_Uncertainty: " << getCarryingCapacityUncertainty() << '\n'; + stream << "HarvestType: " << getHarvestType() << '\n'; + stream << "H_Uncertainty: " << getHarvestUncertainty() << '\n'; + + for (int speciesNum=0; speciesNum SpeNames; + std::string Algorithm; + std::string Minimizer; + std::string ObjectiveCriterion; + std::string Scaling; + std::string CompetitionForm; + std::vector lastYearsCatchValues; + + bool systemFound = m_DatabasePtr->getAlgorithmIdentifiers( + m_Widget,m_Logger,m_ProjectSettingsConfig, + Algorithm,Minimizer,ObjectiveCriterion,Scaling, + CompetitionForm,nmfConstantsMSSPM::DontShowPopupError); + if (! systemFound) { + m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::saveHarvestData: No systems found"); + return; + } + + getYearRange(startYear,endYear); + NumYears = endYear-startYear+1; + + m_DatabasePtr->getAllSpecies(m_Logger,SpeNames); + + cmd = "DELETE FROM " + m_HarvestType + " WHERE ForecastName = '" + + m_ForecastName + "'"; + errorMsg = m_DatabasePtr->nmfUpdateDatabase(cmd); + if (errorMsg != " ") { + m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::saveHarvestData: DELETE error: " + errorMsg); + m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); + QMessageBox::warning(m_Widget, "Error", + "\nError in Save command. Couldn't delete all records from" + + QString::fromStdString(m_HarvestType) + " table.\n", + QMessageBox::Ok); + QApplication::restoreOverrideCursor(); + return; + } + + getLastYearsCatchValues(NumYears,lastYearsCatchValues); + + cmd = "INSERT INTO " + m_HarvestType + " (ForecastName,Algorithm,Minimizer,ObjectiveCriterion,Scaling,SpeName,Year,Value) VALUES "; + for (int speciesNum=0; speciesNumnmfUpdateDatabase(cmd); + if (errorMsg != " ") { + m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::saveHarvestData: Write table error: " + errorMsg); + m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); + QApplication::restoreOverrideCursor(); + return; + } +} + +void +REMORA::saveOutputBiomassData() +{ + emit SaveOutputBiomassData(m_ForecastName); +} + +void +REMORA::saveUncertaintyParameters() +{ + std::string cmd; + std::string errorMsg; + std::vector SpeNames; + + for (int i = 0; i < MModeSpeciesCMB->count(); i++) + { + SpeNames.push_back(MModeSpeciesCMB->itemText(i).toStdString()); + } + + std::string ForecastName = "Sample_Schaefer"; + std::vector fields = {"ForecastName","Algorithm","Minimizer","ObjectiveCriterion","Scaling"}; + std::string queryStr = "SELECT ForecastName,Algorithm,Minimizer,ObjectiveCriterion,Scaling FROM Forecasts where "; + queryStr += "ForecastName = '" + ForecastName + "'"; + std::map > dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); + + int NumRecords = dataMap["ForecastName"].size(); + if (NumRecords == 0) { + std::cout << "Error: No records found." << std::endl; + std::cout << queryStr << std::endl; + return; + } + + std::string Algorithm = dataMap["Algorithm"][0]; + std::string Minimizer = dataMap["Minimizer"][0]; + std::string ObjectiveCriterion = dataMap["ObjectiveCriterion"][0]; + std::string Scaling = dataMap["Scaling"][0]; + std::string GrowthRate = std::to_string(MModeRParamLE->text().toDouble()/100.0); + std::string CarryingCapacity = std::to_string(MModeKParamLE->text().toDouble()/100.0); + std::string Harvest = std::to_string(MModeHParamLE->text().toDouble()/100.0); + + // Clear previous entry in ForecastUncertainty table + cmd = "DELETE FROM ForecastUncertainty WHERE ForecastName = '" + ForecastName + "'"; + errorMsg = m_DatabasePtr->nmfUpdateDatabase(cmd); + if (errorMsg != " ") { + m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::callback_SavePB: DELETE error: " + errorMsg); + m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); + QMessageBox::warning(MModeWindowWidget, "Error", + "\nError in Save command. Couldn't delete all records from ForecastUncertainty table.\n", + QMessageBox::Ok); + return; + } + + m_NumUnusedParameters = 7; // RSK adjust this later + cmd = "INSERT INTO ForecastUncertainty (" ; + cmd += "SpeName,ForecastName,Algorithm,Minimizer,ObjectiveCriterion,Scaling,"; + cmd += "GrowthRate,CarryingCapacity,Predation,Competition,BetaSpecies,"; + cmd += "BetaGuilds,Handling,Exponent,Catchability,Harvest) VALUES "; + for (int i = 0; i < SpeNames.size(); ++i) { // Species + cmd += "('" + SpeNames[i] + "','" + ForecastName + "','" + Algorithm + + "','" + Minimizer + "','" + ObjectiveCriterion + "','" + Scaling + "'"; + cmd += "," + GrowthRate; + cmd += "," + CarryingCapacity; + for (int i=0;inmfUpdateDatabase(cmd); + if (errorMsg != " ") { + m_Logger->logMsg(nmfConstants::Error,"MSSPM_GuiManagerMode::callback_SavePB: Write table error: " + errorMsg); + m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); + QMessageBox::warning(MModeWindowWidget, "Error", + "\nError in Save command. Check that all cells are populated.\n", + QMessageBox::Ok); + return; + } +} + +void +REMORA::setAScaleFactorPoint(QString arg1) +{ + QStringList parts = arg1.split(" "); + double xValue = parts[0].toDouble(); + double yValue = parts[1].toDouble(); + int startYear; + int endYear; + + // Rescale x axis of plot(s) + getYearRange(startYear,endYear); + + if ((xValue == endYear) || (xValue == endYear+m_NumYearsPerRun)) { + m_MovableLineCharts[m_IndexScaleFactorChart2]->setPointYValue(m_IndexScaleFactorPoint,QPointF(xValue,yValue)); + } else { + m_MovableLineCharts[m_IndexScaleFactorChart2]->addPoint(QPointF(xValue,yValue)); + } + ++m_IndexScaleFactorPoint; +} + +void +REMORA::setDeterministic(QString isChecked) +{ + MModeDeterministicRB->setChecked(isChecked == "1"); + MModeStochasticRB->setChecked( isChecked == "0"); +} + +void +REMORA::setForecastName(QString forecastName) +{ + m_ForecastName = forecastName.toStdString(); +} + +void +REMORA::setForecastNumRunsPerForecast(int numRunsPerForecast) +{ + m_NumRunsPerForecast = numRunsPerForecast; + MModeRunsPerForecastSL->blockSignals(true); + MModeRunsPerForecastLE->blockSignals(true); + MModeRunsPerForecastSL->setValue(m_NumRunsPerForecast); + MModeRunsPerForecastLE->setText(QString::number(numRunsPerForecast)); + MModeRunsPerForecastLE->blockSignals(false); + MModeRunsPerForecastSL->blockSignals(false); +} + +void +REMORA::setForecastNumYearsPerRun(int numYearsPerRun) +{ + m_NumYearsPerRun = numYearsPerRun; + MModeYearsPerRunLE->blockSignals(true); + MModeYearsPerRunSL->blockSignals(true); + MModeYearsPerRunSL->setValue(m_NumYearsPerRun); + MModeYearsPerRunLE->setText(QString::number(numYearsPerRun)); + MModeYearsPerRunLE->blockSignals(false); + MModeYearsPerRunSL->blockSignals(false); + + resetNumYearsOnScaleFactorCharts(); +} + +void +REMORA::setForecastPlotType(QString arg1) +{ + MModeForecastPlotTypeCMB->setCurrentText(arg1); +} + +void +REMORA::setHarvestType(QString arg1) +{ + MModeHarvestTypePB->setText(arg1); + if (arg1 == "Catch") { + m_HarvestType = "ForecastCatch"; + } else if (arg1 == "Effort (E)") { + m_HarvestType = "ForecastEffort"; + } else if (arg1 == "Exploitation (F)") { + m_HarvestType = "ForecastExploitation"; + } +} + +void +REMORA::setMaxYScaleFactor(QString maxY) +{ + int value = (maxY.toInt()-1 == 0) ? MAX_SCALE_VALUE : maxY.toInt()-1; + + m_MaxYAxisValues[m_IndexMaxYScaleFactor] = maxY.toInt(); + m_MovableLineCharts[m_IndexMaxYScaleFactor]->setMaxYValue(maxY.toInt()); + + ++m_IndexMaxYScaleFactor; + + MModeMaxScaleFactorPB->setText(QString::number(value)); + callback_MaxScaleFactorPB(); +} + +void +REMORA::setMSYLineVisible(QString arg1) +{ + MModeShowMSYCB->blockSignals(true); + MModeShowMSYCB->setChecked(arg1 == "1"); + MModeShowMSYCB->blockSignals(false); +} + +void +REMORA::setMultiPlot(QString isChecked) +{ + bool isMultiPlot = (isChecked == "1"); + + if (isMultiPlot) { + MModeMultiPlotTypePB->setText("1+"); + } else { + MModeMultiPlotTypePB->setText("1"); + } +} + +void +REMORA::setNumRunsPerForecast(QString numRuns) +{ + MModeRunsPerForecastSL->setValue(numRuns.toInt()); + MModeRunsPerForecastLE->setText(numRuns); +} + + +void +REMORA::setNumScaleFactorPoints(QString arg1) +{ + m_MovableLineCharts[m_IndexScaleFactorChart1++]->resetPoints(); + ++m_IndexScaleFactorChart2; + m_IndexScaleFactorPoint = 0; +} + +void +REMORA::setNumYearsPerRun(QString numYearsStr) +{ + int numYears = numYearsStr.toInt(); + + MModeYearsPerRunSL->setValue(numYears); + MModeYearsPerRunLE->setText(numYearsStr); + for (int i=0; isetRange(numYears); + } +} + +void +REMORA::setScenarioChanged(bool state) +{ + m_ScenarioChanged = state; + QString scenarioName = getScenarioName(); + int last = scenarioName.size()-1; + if (! scenarioName.isEmpty() && scenarioName[last] != "*") { + scenarioName += "*"; + setScenarioName(scenarioName); + } +} + +void +REMORA::setScenarioName(QString scenarioName) +{ + MModeScenarioNameLE->setText(scenarioName); +} + +void +REMORA::setSingleSpecies(QString isChecked) +{ + bool isSingleSpecies = (isChecked == "1"); + MModePlotTypeSSRB->setChecked( isSingleSpecies); + MModePlotTypeMSRB->setChecked( ! isSingleSpecies); + MModeMultiPlotTypePB->setEnabled(! isSingleSpecies); + MModeShowMSYCB->setEnabled(isSingleSpecies || (! isSingleSpecies && isMultiPlot())); +} + +void +REMORA::setSpeciesList(const QStringList& speciesList) +{ + MModeSpeciesCMB->blockSignals(true); + MModeSpeciesCMB->clear(); + MModeSpeciesCMB->addItems(speciesList); + MModeSpeciesCMB->blockSignals(false); +} + +void +REMORA::setUncertaintyCarryingCapacity(QString arg1) +{ + MModeKParamDL->setValue(arg1.toInt()); + MModeKParamLE->setText(arg1); +} + +void +REMORA::setUncertaintyGrowth(QString arg1) +{ + MModeRParamDL->setValue(arg1.toInt()); + MModeRParamLE->setText(arg1); +} + +void +REMORA::setUncertaintyHarvest(QString arg1) +{ + MModeHParamDL->setValue(arg1.toInt()); + MModeHParamLE->setText(arg1); +} + +void +REMORA::setupConnections() +{ + connect(MModeYearsPerRunSL, SIGNAL(valueChanged(int)), + this, SLOT(callback_YearsPerRunSL(int))); + connect(MModeRunsPerForecastSL, SIGNAL(valueChanged(int)), + this, SLOT(callback_RunsPerForecastSL(int))); + connect(MModeRParamDL, SIGNAL(valueChanged(int)), + this, SLOT(callback_UncertaintyRParameterDL(int))); + connect(MModeKParamDL, SIGNAL(valueChanged(int)), + this, SLOT(callback_UncertaintyKParameterDL(int))); + connect(MModeHParamDL, SIGNAL(valueChanged(int)), + this, SLOT(callback_UncertaintyHarvestParameterDL(int))); + connect(MModeForecastRunPB, SIGNAL(clicked()), + this, SLOT(callback_RunPB())); + connect(MModeForecastLoadPB, SIGNAL(clicked()), + this, SLOT(callback_LoadPB())); + connect(MModeForecastSavePB, SIGNAL(clicked()), + this, SLOT(callback_SavePB())); + connect(MModeForecastDelPB, SIGNAL(clicked()), + this, SLOT(callback_DelPB())); + connect(MModeShowMSYCB, SIGNAL(toggled(bool)), + this, SLOT(callback_MSYCB(bool))); + connect(MModePctMSYDL, SIGNAL(valueChanged(int)), + this, SLOT(callback_PctMSYDL(int))); + connect(MModePctMSYCB, SIGNAL(toggled(bool)), + this, SLOT(callback_PctMSYCB(bool))); + connect(MModeDeterministicRB, SIGNAL(clicked(bool)), + this, SLOT(callback_DeterministicRB(bool))); + connect(MModeStochasticRB, SIGNAL(clicked(bool)), + this, SLOT(callback_StochasticRB(bool))); + connect(MModePlotTypeSSRB, SIGNAL(clicked(bool)), + this, SLOT(callback_SingleSpeciesRB(bool))); + connect(MModePlotTypeMSRB, SIGNAL(clicked(bool)), + this, SLOT(callback_MultiSpeciesRB(bool))); + connect(MModeHarvestTypePB, SIGNAL(clicked()), + this, SLOT(callback_UncertaintyHarvestParameterPB())); + connect(MModeSpeciesCMB, SIGNAL(currentIndexChanged(QString)), + this, SLOT(callback_SpeciesCMB(QString))); + connect(MModeMultiPlotTypePB, SIGNAL(clicked()), + this, SLOT(callback_MultiPlotTypePB())); + connect(MModeMaxScaleFactorPB, SIGNAL(clicked()), + this, SLOT(callback_MaxScaleFactorPB())); + connect(MModeForecastPlotTypeCMB, SIGNAL(activated(QString)), + this, SLOT(callback_ForecastPlotTypeCMB(QString))); + connect(MModeYAxisLockCB, SIGNAL(toggled(bool)), + this, SLOT(callback_YAxisLockedCB(bool))); +} + +void +REMORA::setupMovableLineCharts(const QStringList& SpeciesList) +{ + int i=0; + int startYear; + int endYear; + int endForecastYear; + std::string MainTitle = "Harvest Scale Factor"; + std::string XTitle = "Year"; + std::string YTitle = "Scale Factor"; + std::string mainTitle; + nmfChartMovableLine* movableLineChart; + + getYearRange(startYear,endYear); + endForecastYear = endYear + m_NumYearsPerRun; + + MModeHarvestChartWidget->setLayout(new QVBoxLayout()); + m_MovableLineCharts.clear(); + if (SpeciesList.size() > 0) { + for (QString Species : SpeciesList) { + m_SpeciesMap[Species] = i++; + mainTitle = MainTitle + ": " + Species.toStdString(); + movableLineChart = new nmfChartMovableLine(MModeHarvestChartWidget,mainTitle,XTitle,YTitle); + movableLineChart->hide(); + movableLineChart->populateChart(endYear,endForecastYear); + + connect(this, SIGNAL(KeyPressed(QKeyEvent*)), + movableLineChart, SLOT(callback_KeyPressed(QKeyEvent*))); + connect(this, SIGNAL(MouseMoved(QMouseEvent*)), + movableLineChart, SLOT(callback_MouseMoved(QMouseEvent*))); + connect(this, SIGNAL(MouseReleased(QMouseEvent*)), + movableLineChart, SLOT(callback_MouseReleased(QMouseEvent*))); + + m_MovableLineCharts.push_back(movableLineChart); + + m_MaxYAxisValues.push_back(MAX_SCALE_VALUE); + } + m_MovableLineCharts[0]->show(); + + } +} + +void +REMORA::resetXAxis() +{ + int startYear; + int endYear; + int endForecastYear; + + // Rescale x axis of plot(s) + getYearRange(startYear,endYear); + endForecastYear = endYear + m_NumYearsPerRun; + if (isMultiSpecies() && isMultiPlot()) { + for (QChart* chart : m_Charts) { + chart->axisX()->setRange(endYear,endForecastYear); + } + } else { + if (m_ChartWidget->axes().size() != 0) { + m_ChartWidget->axisX()->setRange(endYear,endForecastYear); + } + } +} + +void +REMORA::resetYAxis() +{ + if (m_MaxYAxis > 0) { + QValueAxis* axisY = qobject_cast(m_ChartWidget->axisY()); + axisY->setMax(m_MaxYAxis); + axisY->setTickCount(5); + } +} + +void +REMORA::updateYearlyScaleFactorPoints() +{ + for (int i=0; icalculateYearlyPoints(); + } +} + + + + +void +REMORA::callback_DelPB() +{ + QString msg; + QString fullFilename; + QString scenarioName = getScenarioName().remove("*"); + + if (scenarioName.isEmpty()) { + msg = "\nA scenario file must be loaded in order to delete it.\n"; + QMessageBox::information(m_Widget, tr("Delete Scenario"), msg, QMessageBox::Ok); + return; + + } + + msg = "\nOK to delete scenario: " + scenarioName + " ?\n\nThis cannot be undone.\n"; + + QMessageBox::StandardButton reply = QMessageBox::question( + m_Widget,"Delete Scenario",msg, + QMessageBox::Yes|QMessageBox::No); + if (reply == QMessageBox::Yes) { + fullFilename = QDir(m_RemoraScenarioDir).filePath(scenarioName); + bool ok = QFile::remove(fullFilename); + if (ok) { + msg = "\nScenario file successfully deleted: " + scenarioName + "\n"; + QMessageBox::information(m_Widget, tr("Delete Scenario"), msg, QMessageBox::Ok); + resetControls(); + } else { + msg = "Error: Couldn't delete scenario file: " + fullFilename; + m_Logger->logMsg(nmfConstants::Error,msg.toStdString()); + } + } +} + +void +REMORA::callback_DeterministicRB(bool pressed) +{ + MModeStochasticRB->setChecked(! pressed); + setScenarioChanged(true); +} + +void +REMORA::callback_ForecastPlotTypeCMB(QString type) +{ + bool showMSYCheckboxes = couldShowMSYCB(); + + if (type == "Biomass (absolute)") { + MModeShowMSYCB->setEnabled(showMSYCheckboxes); + MModePctMSYCB->setEnabled(showMSYCheckboxes); + } else if (type == "Biomass (relative)") { + MModeShowMSYCB->setEnabled(false); + MModeShowMSYCB->setChecked(false); + MModePctMSYCB->setEnabled(false); + MModePctMSYCB->setChecked(false); + } else if (type == "Fishing Mortality") { + MModeShowMSYCB->setEnabled(showMSYCheckboxes); + MModePctMSYCB->setEnabled(showMSYCheckboxes); + } + drawPlot(); + setScenarioChanged(true); +} + +void +REMORA::callback_KeyPressed(QKeyEvent* event) +{ + emit KeyPressed(event); +} + +void +REMORA::callback_LoadPB() +{ + QString filename = QFileDialog::getOpenFileName( + m_Widget, + tr("Load Forecast Scenario"), + m_RemoraScenarioDir.toLatin1(), + tr("*.scn")); + if (! filename.isEmpty()) { + loadForecastScenario(filename); + callback_RunPB(); + setScenarioChanged(false); + resetScenarioName(); + } +} + +void +REMORA::callback_MaxScaleFactorPB() +{ + int newValue; + int speciesNum = getSpeciesNum(); + + // Allow only values of 1, 2, 3, or 4 for the button text + QString maxSF = MModeMaxScaleFactorPB->text(); + newValue = (maxSF.toInt()%MAX_SCALE_VALUE)+1; + MModeMaxScaleFactorPB->setText(QString::number(newValue)); + m_MaxYAxisValues[speciesNum] = newValue; + m_MovableLineCharts[speciesNum]->setMaxYValue(MModeMaxScaleFactorPB->text().toInt()); + setScenarioChanged(true); +} + +void +REMORA::callback_MouseMoved(QMouseEvent* event) +{ + emit MouseMoved(event); +} + +void +REMORA::callback_MouseReleased(QMouseEvent* event) +{ + emit MouseReleased(event); +} + +void +REMORA::callback_MSYCB(bool isChecked) +{ + if (isChecked) { + drawMSYLines(); + } else { + removeAllMSYLines(""); + } + setScenarioChanged(true); +} + +void +REMORA::callback_MultiPlotTypePB() +{ + if (MModeMultiPlotTypePB->text() == "1") { + MModeMultiPlotTypePB->setText("1+"); + MModeShowMSYCB->setEnabled(true); + MModePctMSYCB->setEnabled(true); + MModeYAxisLockCB->setEnabled(false); + } else { + MModeMultiPlotTypePB->setText("1"); + MModeShowMSYCB->setEnabled(false); + MModeShowMSYCB->setChecked(false); + MModePctMSYCB->setEnabled(false); + MModePctMSYCB->setChecked(false); + MModeYAxisLockCB->setEnabled(true); + } + drawPlot(); + setScenarioChanged(true); +} + +void +REMORA::callback_MultiSpeciesRB(bool pressed) +{ + MModePlotTypeSSRB->setChecked( ! pressed); + MModeMultiPlotTypePB->setEnabled( pressed); + MModeShowMSYCB->setEnabled( pressed && isMultiPlot()); + MModePctMSYCB->setEnabled( pressed && isMultiPlot()); + MModeYAxisLockCB->setEnabled( pressed && ! isMultiPlot()); + if (pressed and ! isMultiPlot()) { + MModeShowMSYCB->setChecked(false); + MModePctMSYCB->setChecked(false); + } + drawPlot(); + setScenarioChanged(true); +} + +void +REMORA::callback_PctMSYCB(bool isChecked) +{ + MModePctMSYDL->setEnabled(isChecked); + MModePctMSYLE->setEnabled(isChecked); + MModePctMSYLBL->setEnabled(isChecked); + if (isChecked) { + drawMSYLines(); + } else { + removeAllMSYLines("%"); + } + setScenarioChanged(true); +} + +void +REMORA::callback_PctMSYDL(int value) +{ + MModePctMSYLE->setText(QString::number(value)); + removeAllMSYLines("%"); + drawMSYLines(); + setScenarioChanged(true); +} + +void +REMORA::callback_RunPB() +{ + QApplication::setOverrideCursor(Qt::WaitCursor); + + updateYearlyScaleFactorPoints(); + saveForecastParameters(); + saveUncertaintyParameters(); + saveHarvestData(); + saveOutputBiomassData(); + drawPlot(); + enableWidgets(true); + + QApplication::restoreOverrideCursor(); +} + +void +REMORA::callback_RunsPerForecastSL(int value) +{ + MModeRunsPerForecastLE->setText(QString::number(value)); + m_NumRunsPerForecast = value; + setScenarioChanged(true); +} + +void +REMORA::callback_SavePB() +{ + QString filename = ""; + QString fullFilename = ""; + + filename = QFileDialog::getSaveFileName( + m_Widget, + tr("Save Forecast Scenario"), + m_RemoraScenarioDir.toLatin1(), + tr("*.scn")); + + if (! filename.isEmpty()) { + // Guarantee no spaces in filenames + filename.simplified(); + filename.replace(" ","_"); + + // Make sure file has a valid extension + if (! filename.contains(".scn")) { + fullFilename = QDir(m_RemoraScenarioDir).filePath(filename); + } else { + fullFilename = filename; + } + QFileInfo fi(fullFilename); + QString ext = fi.suffix(); + if (ext != "scn") { + fullFilename += ".scn"; + } + + // Update forecast qlineedit + setScenarioName(QFileInfo(fullFilename).fileName()); + + // The file fullFilename is good to save now + bool saved = saveForecastScenario(fullFilename); + if (saved) { + setScenarioChanged(false); + resetScenarioName(); + } + } +} + +void +REMORA::callback_SingleSpeciesRB(bool pressed) +{ + MModePlotTypeMSRB->setChecked( ! pressed); + MModeYAxisLockCB->setEnabled( pressed); + MModeMultiPlotTypePB->setEnabled(! pressed); + MModeShowMSYCB->setEnabled( pressed && ! isRelativeBiomassPlotType()); + MModePctMSYCB->setEnabled( pressed && ! isRelativeBiomassPlotType()); + drawPlot(); + setScenarioChanged(true); +} + +void +REMORA::callback_SpeciesCMB(QString species) +{ + int speciesNum = getSpeciesNum(); + int numMovableLines = m_MovableLineCharts.size(); + + if (numMovableLines > 0) { + for (int i=0; ihide(); + } + m_MovableLineCharts[speciesNum]->show(); + MModeMaxScaleFactorPB->setText(QString::number(m_MaxYAxisValues[speciesNum])); + } + drawPlot(); + setScenarioChanged(true); +} + +void +REMORA::callback_StochasticRB(bool pressed) +{ + MModeDeterministicRB->setChecked(! pressed); + setScenarioChanged(true); +} + +void +REMORA::callback_UncertaintyHarvestParameterDL(int value) +{ + MModeHParamLE->setText(QString::number(value)); + setScenarioChanged(true); +} + +void +REMORA::callback_UncertaintyHarvestParameterPB() +{ + QString harvestType = getHarvestType(); + + if (harvestType == "Catch") { + MModeHarvestTypePB->setText("Effort (E)"); + m_HarvestType = "ForecastCatch"; + } else if (harvestType == "Effort (E)") { + MModeHarvestTypePB->setText("Exploitation (F)"); + m_HarvestType = "ForecastEffort"; + } else if (harvestType == "Exploitation (F)") { + MModeHarvestTypePB->setText("Catch"); + m_HarvestType = "ForecastExploitation"; + } + setScenarioChanged(true); +} + +void +REMORA::callback_UncertaintyKParameterDL(int value) +{ + MModeKParamLE->setText(QString::number(value)); + setScenarioChanged(true); +} + +void +REMORA::callback_UncertaintyRParameterDL(int value) +{ + MModeRParamLE->setText(QString::number(value)); + setScenarioChanged(true); +} + +void +REMORA::callback_YAxisLockedCB(bool checked) +{ + if (m_ChartWidget->axisY()) { + QValueAxis* axisY = qobject_cast(m_ChartWidget->axisY()); + if (checked) { + m_MaxYAxis = axisY->max(); + axisY->setTickCount(3); + } else { + m_MaxYAxis = -1; + axisY->setTickCount(5); + } + } +} + +void +REMORA::resetYearsPerRunOnScaleFactorPlot() +{ + int startYear; + int endYear; + int endForecastYear; + int speciesNum = getSpeciesNum(); + + // Reset year range on movable line plot + getYearRange(startYear,endYear); + endForecastYear = endYear + m_NumYearsPerRun; + if (speciesNum >= 0) { + m_MovableLineCharts[speciesNum]->updateChart(endYear,endForecastYear); + m_MovableLineCharts[speciesNum]->resetEndPoints(); + } + resetXAxis(); + setScenarioChanged(true); +} + +void +REMORA::callback_YearsPerRunSL(int value) +{ + MModeYearsPerRunLE->setText(QString::number(value)); + m_NumYearsPerRun = value; + + resetYearsPerRunOnScaleFactorPlot(); + setScenarioChanged(true); +} + diff --git a/MSSPM_GuiManagerMode/REMORA.h b/MSSPM_GuiManagerMode/REMORA.h new file mode 100644 index 00000000..d96908e4 --- /dev/null +++ b/MSSPM_GuiManagerMode/REMORA.h @@ -0,0 +1,454 @@ +/** + * @file MSSPM_GuiManagerMode.h + * @brief GUI definition for the Control widgets class MSSPM_GuiManagerMode in the REMORA embedded tiik + * + * This file contains the GUI definitions for the controls and charts found in the MSSPM_GuiManagerMode + * class. This class represents the MSSPM REMORA Management tool and allows managers to quickly and + * intuitively create, view, and save forecast scenarios. + * + * @copyright + * Public Domain Notice\n + * + * National Oceanic And Atmospheric Administration\n\n + * + * This software is a "United States Government Work" under the terms of the + * United States Copyright Act. It was written as part of the author's official + * duties as a United States Government employee/contractor and thus cannot be copyrighted. + * This software is freely available to the public for use. The National Oceanic + * And Atmospheric Administration and the U.S. Government have not placed any + * restriction on its use or reproduction. Although all reasonable efforts have + * been taken to ensure the accuracy and reliability of the software and data, + * the National Oceanic And Atmospheric Administration and the U.S. Government + * do not and cannot warrant the performance or results that may be obtained + * by using this software or data. The National Oceanic And Atmospheric + * Administration and the U.S. Government disclaim all warranties, express + * or implied, including warranties of performance, merchantability or fitness + * for any particular purpose.\n\n + * + * Please cite the author(s) in any work or product based on this material. + * + */ + +#ifndef MSSPM_GUIMANAGERMODE_H +#define MSSPM_GUIMANAGERMODE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nmfChartMovableLine.h" +#include "nmfChartLine.h" +#include "nmfConstantsMSSPM.h" +#include "nmfUtils.h" + +#include + + +/** + * @brief The main GUI class that contains all of the widget + * definitions for the REMORA Management tool. + */ +class REMORA : public QObject +{ + Q_OBJECT + +private: + const int MAX_SCALE_VALUE = 4; + + QCheckBox* MModeShowMSYCB; + QCheckBox* MModePctMSYCB; + QCheckBox* MModeYAxisLockCB; + QComboBox* MModeSpeciesCMB; + QComboBox* MModeForecastPlotTypeCMB; + QDial* MModeRParamDL; + QDial* MModeKParamDL; + QDial* MModeHParamDL; + QDial* MModePctMSYDL; + QLabel* MModeForecastPlotTypeLB; + QLabel* MModeForecastTypeLB; + QLabel* MModePlotTypeLB; + QLabel* MModePctMSYLBL; + QLabel* MModeSpeciesLB; + QLineEdit* MModeScenarioNameLE; + QLineEdit* MModeYearsPerRunLE; + QLineEdit* MModeRunsPerForecastLE; + QLineEdit* MModeRParamLE; + QLineEdit* MModeKParamLE; + QLineEdit* MModeHParamLE; + QLineEdit* MModePctMSYLE; + QPushButton* MModeForecastRunPB; + QPushButton* MModeForecastDelPB; + QPushButton* MModeForecastLoadPB; + QPushButton* MModeForecastSavePB; + QPushButton* MModeHarvestTypePB; + QPushButton* MModeMultiPlotTypePB; + QPushButton* MModeMaxScaleFactorPB; + QRadioButton* MModeDeterministicRB; + QRadioButton* MModeStochasticRB; + QRadioButton* MModePlotTypeSSRB; + QRadioButton* MModePlotTypeMSRB; + QSlider* MModeYearsPerRunSL; + QSlider* MModeRunsPerForecastSL; + QWidget* MModeHarvestChartWidget; + QWidget* MModeUpperPlotWidget; + QWidget* MModeWindowWidget; + QWidget* MModeParentChartW; + + bool m_ScenarioChanged; + int m_IndexMaxYScaleFactor; + int m_IndexScaleFactorChart1; + int m_IndexScaleFactorChart2; + int m_IndexScaleFactorPoint; + int m_NumRunsPerForecast; + int m_NumUnusedParameters; + int m_NumYearsPerRun; + double m_MaxYAxis; + nmfChartLine* m_ForecastBiomassLineChart; + nmfChartLine* m_ForecastHarvestLineChart; + nmfChartLine* m_ForecastLineChartMonteCarlo; + nmfChartLine* m_MSYLineChart; + nmfDatabase* m_DatabasePtr; + nmfLogger* m_Logger; + std::map m_SpeciesMap; + std::map m_FunctionMap; + std::string m_ForecastName; + std::string m_HarvestType; + std::string m_ProjectDir; + std::string m_ProjectSettingsConfig; + std::vector m_MaxYAxisValues; + std::vector m_MovableLineCharts; + QChart* m_ChartWidget; + QChart* m_MModeHarvestChartWidget; + QChart* m_MModeOutputChartWidget; + QChartView* m_ChartView; + QGridLayout* m_GridLayt; + QVBoxLayout* m_GridVLayt; + QVBoxLayout* m_VLayt; + QList m_Charts; + QList m_Views; + QString m_RemoraScenarioDir; + QWidget* m_GridParent; + QWidget* m_Widget; + + bool couldShowMSYCB(); + void drawMultiSpeciesChart(); + void drawMSYLines(); + void drawMSYLines( + QChart* chart, + int& SpeciesNum, + int& NumSpecies, + int& NumYearsPerRun, + int& NumRunsPerForecast, + int& NoUncertaintyRun, + int& StartForecastYear, + int& YMinSliderVal, + std::string& Algorithm, + std::string& Minimizer, + std::string& ObjectiveCriterion, + std::string& Scaling, + QStringList& RowLabelsForBars, + QStringList& ColumnLabelsForLegend, + QStringList& HoverData, + std::string& MainTitle, + std::string& XLabel, + std::string& YLabel, + const bool& ShowLegend, + const double& Pct); + void drawPlot(); + void drawSingleSpeciesChart(); + void enableWidgets(bool enable); + QString getCarryingCapacityUncertainty(); + QString getForecastPlotType(); + QString getGrowthUncertainty(); + QString getHarvestType(); + QString getHarvestUncertainty(); + void getLastYearsCatchValues( + int& lastYear, + std::vector& lastYearsCatchValues); + int getMaxYScaleFactor(const int& speciesNum); + int getNumRunsPerForecast(); + int getNumScaleFactorPoints(const int& speciesNum); + int getNumSpecies(); + int getNumYearsPerRun(); + double getPctMSYValue(); + QList getScaleFactorPoints(const int& speciesNum); + QString getScenarioName(); + int getSpeciesNum(); + void getYearRange(int& firstYear, int& lastYear); + bool isAbsoluteBiomassPlotType(); + bool isFishingMortalityPlotType(); + bool isMultiPlot(); + bool isMultiSpecies(); + bool isMSYBoxChecked(); + bool isPctMSYBoxChecked(); + bool isRelativeBiomassPlotType(); + bool isSingleSpecies(); + bool isYAxisLocked(); + void loadForecastScenario(QString filename); + void removeAllMSYLines(QString type); + void removeMSYLines( + QChart* chart, + const QStringList& MSYTypes); + void resetControls(); + void resetNumYearsOnScaleFactorCharts(); + void resetScenarioName(); + void resetYearsPerRunOnScaleFactorPlot(); + void saveForecastParameters(); + bool saveForecastScenario(QString filename); + void saveHarvestData(); + void saveOutputBiomassData(); + void saveUncertaintyParameters(); + void setAScaleFactorPoint(QString arg1); + void setDeterministic(QString arg1); + void setForecastPlotType(QString arg1); + void setHarvestType(QString arg1); + void setMaxYScaleFactor(QString maxY); + void setNumRunsPerForecast(QString numRuns); + void setNumYearsPerRun(QString numYears); + void setScenarioChanged(bool state); + void setScenarioName(QString scenarioName); + void setSingleSpecies(QString arg1); + void setupConnections(); + void setupMovableLineCharts(const QStringList& SpeciesList); + void setMultiPlot(QString isChecked); + void setMSYLineVisible(QString arg1); + void setNumScaleFactorPoints(QString arg1); + void setUncertaintyCarryingCapacity(QString arg1); + void setUncertaintyGrowth(QString arg1); + void setUncertaintyHarvest(QString arg1); + void resetXAxis(); + /** + * @brief Resets the maximum y-axis value of the model plot if the user has + * checked the lock button in the controls + */ + void resetYAxis(); + void updateYearlyScaleFactorPoints(); + +signals: + /** + * @brief Signal emitted when the user presses a key over the movable line chart + * @param event : key event data + */ + void KeyPressed(QKeyEvent* event); + /** + * @brief Signal emitted when the user moves the mouse over the movable line chart + * @param event : mouse event data + */ + void MouseMoved(QMouseEvent* event); + /** + * @brief Signal emitted when the user releases the mouse over the movable line chart + * @param event : mouse event data + */ + void MouseReleased(QMouseEvent* event); + /** + * @brief Signal emitted when the user wants to save the output biomass data for the current forecast + * @param forecastName : the forecast name + */ + void SaveOutputBiomassData(std::string forecastName); + /** + * @brief Signal emitted when the user needs to update the seed value in the main routine when saving the + * current forecast parameters + * @param seedValue : 1 or 0 (0 signifies that a random seed value will be used) + */ + void UpdateSeedValue(int seedValue); + +public: + + /** + * @brief Class definition for REMORA Management Tool + * @param DatabasePtr : pointer to database + * @param Logger : pointer to logger + * @param ProjectDir : project directory + * @param ProjectSettingsConfig : project settings configuration name + * @param SpeciesList : list of species + * @param MModeWidget : parent widget in which to place this class + */ + REMORA( + nmfDatabase* DatabasePtr, + nmfLogger* Logger, + std::string& ProjectDir, + std::string& ProjectSettingsConfig, + QStringList& SpeciesList, + QWidget* MModeWidget); + ~REMORA(); + + /** + * @brief getScaleValueFromPlot : returns harvest scale value for the passed in species and year + * @param species : species number from the list of species + * @param year : year along x-axis of scale factor plot + * @return Returns scale factor (y-value) corresponding to the passed in values + */ + double getScaleValueFromPlot(int species, int year); + /** + * @brief grabImage : Performs a "smart" screen grab based upon the state of the controls + * @param pixmap : Returns the pixmap of the captured widget + */ + void grabImage(QPixmap& pixmap); + /** + * @brief Returns true if the Deterministic radio button is pressed + * @return true if state is deterministic, else false if stochastic + */ + bool isDeterministic(); + /** + * @brief Sets REMORA's internal forecast name variable to the passed in forecast name + * @param forecastName : the name of the current forecast + */ + void setForecastName(QString forecastName); + /** + * @brief Sets REMORA's internal number years per run variable to the passed value and updates the GUI + * @param numYearsPerRun : number of years per forecast run + */ + void setForecastNumYearsPerRun(int numYearsPerRun); + /** + * @brief Sets REMORA's internal number of runs per forecast to the passed value and updates the GUI + * @param numRunsPerForecast : number of runs to generate per forecast scenario run + */ + void setForecastNumRunsPerForecast(int numRunsPerForecast); + /** + * @brief Sets REMORA's species pulldown list to the passed list of QStrings + * @param speciesList : current list of species in model + */ + void setSpeciesList(const QStringList& speciesList); + + +public Q_SLOTS: + /** + * @brief Callback invoked when the user presses the delete scenario button + */ + void callback_DelPB(); + /** + * @brief Callback invoked when the user presses the Deterministic radio button + * @param pressed : state of the radio button (true/false) + */ + void callback_DeterministicRB(bool pressed); + /** + * @brief Callback invoked when the user selects a new forecast plot type + * @param type : name of the forecast plot type chosen + */ + void callback_ForecastPlotTypeCMB(QString type); + /** + * @brief Callback invoked when the user presses a keyboard key + * @param event : key event data structure + */ + void callback_KeyPressed(QKeyEvent* event); + /** + * @brief Callback invoked when the user presses the Load Scenario button + */ + void callback_LoadPB(); + /** + * @brief Callback invoked when the user toggles the maximum scale factor button + */ + void callback_MaxScaleFactorPB(); + /** + * @brief Callback invoked when the user moves the mouse + * @param event : mouse event data + */ + void callback_MouseMoved(QMouseEvent* event); + /** + * @brief Callback invoked when the user releases the mouse + * @param event : mouse event data + */ + void callback_MouseReleased(QMouseEvent* event); + /** + * @brief Callback invoked when the user checks the MSY checkbox + * @param isChecked : boolean signifying if the checkbox has been checked + */ + void callback_MSYCB(bool isChecked); + /** + * @brief Callback invoked when the user presses the multi-species plot type + * toggle button. There are states: 1 and 1+. The former signifies the user wishes + * to see all plots on the same chart (with no Monte Carlo plots). The latter signifies + * the user wishes to see all plots on separate smaller charts (with the Monte Carlo plots) + * and composited into one image. + */ + void callback_MultiPlotTypePB(); + /** + * @brief Callback invoked when the user presses the Multi-Species radio button + * @param pressed : state of the Multi-Species button + */ + void callback_MultiSpeciesRB(bool pressed); + /** + * @brief Callback invoked when the user checks the Percent MSY checkbox. This will enable the + * Percent MSY dial to the right of this checkbox. + * @param isChecked : state of checkbox + */ + void callback_PctMSYCB(bool isChecked); + /** + * @brief Callback invoked when the user modifies the Percent MSY dial + * @param value : Integer value from the Percent MSY dial + */ + void callback_PctMSYDL(int value); + /** + * @brief Callback invoked when the user presses the Run button. Run causes the appropriate + * forecast scenario biomass data to be generated and saved in the database for each species. + * A default plot is then displayed using these data. Additional plots can be viewed by selecting + * another species or by changing the plot type. + */ + void callback_RunPB(); + /** + * @brief Callback invoked when the user interacts with the Runs per Forecast slider + * @param value : current value on the Runs per Forecast slider + */ + void callback_RunsPerForecastSL(int value); + /** + * @brief Callback invoked when the user presses the Save Scenario button + */ + void callback_SavePB(); + /** + * @brief Callback invoked when the user presses the single species radio button + * @param pressed : state of the single species radio button + */ + void callback_SingleSpeciesRB(bool pressed); + /** + * @brief Callback invoked when the user changes the species combo box + * @param species : current species shown in the species combo box + */ + void callback_SpeciesCMB(QString species); + /** + * @brief Callback invoked when the user presses the stochastic radio button + * @param pressed : state of the stochastic radio button + */ + void callback_StochasticRB(bool pressed); + /** + * @brief Callback invoked when the user modifies the Harvest Uncertainty dial + * @param value : current value of the Harvest Uncertainty dial + */ + void callback_UncertaintyHarvestParameterDL(int value); + /** + * @brief Callback invoked when the user presses the Harvest Uncertainty parameter toggle + * button + */ + void callback_UncertaintyHarvestParameterPB(); + /** + * @brief Callback invoked when the user modifies the Carrying Capacity Uncertainty dial + * @param value : current value of the Carrying Capacity Uncertainty dial + */ + void callback_UncertaintyKParameterDL(int value); + /** + * @brief Callback invoked when the user modifies the Growth Uncertainty dial + * @param value : current value of the Growth Uncertainty dial + */ + void callback_UncertaintyRParameterDL(int value); + /** + * @brief Callback invoked when the user checks the Lock Y Axis checkbox. Checking this box + * forces all subsequent plots to have the same maximum y range value. This is useful if + * multiple plots will be captured and then flipped through to view differences. + * @param checked : boolean determining if the box has just been checked (true) or unchecked (false) + */ + void callback_YAxisLockedCB(bool checked); + /** + * @brief Callback invoked when the user releases the Years per Run slider + * @param value : current value of the Years per Run slider + */ + void callback_YearsPerRunSL(int value); +}; + +#endif // MSSPM_GUIMANAGERMODE_H diff --git a/MSSPM_GuiSetup/nmfSetupTab02.cpp b/MSSPM_GuiSetup/nmfSetupTab02.cpp index 196c17cd..c6d137c0 100644 --- a/MSSPM_GuiSetup/nmfSetupTab02.cpp +++ b/MSSPM_GuiSetup/nmfSetupTab02.cpp @@ -247,12 +247,12 @@ nmfSetup_Tab2::createTables(QString databaseName) "Cancel", 0, 35, Setup_Tabs); m_ProgressDlg->setWindowModality(Qt::WindowModal); m_ProgressDlg->setValue(pInc); - m_ProgressDlg->setRange(0,51); + m_ProgressDlg->setRange(0,52); m_ProgressDlg->show(); connect(m_ProgressDlg, SIGNAL(canceled()), this, SLOT(callback_progressDlgCancel())); - // 1 of 51: BetweenGuildsInteractionCoeff + // 1 of 52: BetweenGuildsInteractionCoeff fullTableName = db + ".BetweenGuildsInteractionCoeff "; ExistingTableNames.push_back("BetweenGuildsInteractionCoeff"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -272,8 +272,8 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 2 of 51: CompetitionAlpha - // 3 of 51: HandlingTime + // 2 of 52: CompetitionAlpha + // 3 of 52: HandlingTime for (std::string tableName : {"CompetitionAlpha", "HandlingTime"}) { @@ -297,8 +297,8 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 4 of 51: CompetitionAlphaMax - // 5 of 51: CompetitionAlphaMin + // 4 of 52: CompetitionAlphaMax + // 5 of 52: CompetitionAlphaMin for (std::string tableName : {"CompetitionAlphaMax", "CompetitionAlphaMin"}) { @@ -324,8 +324,8 @@ nmfSetup_Tab2::createTables(QString databaseName) } - // 6 of 51: CompetitionBetaSpeciesMax - // 7 of 51: CompetitionBetaSpeciesMin + // 6 of 52: CompetitionBetaSpeciesMax + // 7 of 52: CompetitionBetaSpeciesMin for (std::string tableName : {"CompetitionBetaSpeciesMax", "CompetitionBetaSpeciesMin"}) { @@ -350,8 +350,8 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 8 of 51: CompetitionBetaGuildsMax - // 9 of 51: CompetitionBetaGuildsMin + // 8 of 52: CompetitionBetaGuildsMax + // 9 of 52: CompetitionBetaGuildsMin for (std::string tableName : {"CompetitionBetaGuildsMax", "CompetitionBetaGuildsMin"}) { @@ -376,8 +376,8 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 10 of 51: PredationExponentMin - // 11 of 51: PredationExponentMax + // 10 of 52: PredationExponentMin + // 11 of 52: PredationExponentMax for (std::string tableName : {"PredationExponentMin", "PredationExponentMax"}) { @@ -401,10 +401,10 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 12 of 51: Catch - // 13 of 51: Effort - // 14 of 51: Exploitation - // 15 of 51: ObservedBiomass + // 12 of 52: Catch + // 13 of 52: Effort + // 14 of 52: Exploitation + // 15 of 52: ObservedBiomass for (std::string tableName : {"Catch", "Effort", "Exploitation", @@ -433,7 +433,7 @@ nmfSetup_Tab2::createTables(QString databaseName) } - // 16 of 51: Covariate + // 16 of 52: Covariate fullTableName = db + ".Covariate"; ExistingTableNames.push_back("Covariate"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -452,7 +452,7 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 17 of 51: CovariateTS + // 17 of 52: CovariateTS fullTableName = db + ".CovariateTS"; ExistingTableNames.push_back("CovariateTS"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -471,7 +471,7 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 18 of 51: Guilds + // 18 of 52: Guilds fullTableName = db + ".Guilds"; ExistingTableNames.push_back("Guilds"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -498,7 +498,7 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 19 of 51: OutputBiomass + // 19 of 52: OutputBiomass fullTableName = db + ".OutputBiomass"; ExistingTableNames.push_back("OutputBiomass"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -524,10 +524,10 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 20 of 51: OutputCompetitionAlpha - // 21 of 51: OutputCompetitionBetaSpecies - // 22 of 51: OutputPredation - // 23 of 51: OutputHandling + // 20 of 52: OutputCompetitionAlpha + // 21 of 52: OutputCompetitionBetaSpecies + // 22 of 52: OutputPredation + // 23 of 52: OutputHandling for (std::string tableName : {"OutputCompetitionAlpha", "OutputCompetitionBetaSpecies", "OutputPredation", @@ -559,7 +559,7 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 24 of 51: OutputCompetitionBetaGuilds + // 24 of 52: OutputCompetitionBetaGuilds for (std::string tableName : {"OutputCompetitionBetaGuilds"}) { ExistingTableNames.push_back(tableName); @@ -588,13 +588,13 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 25 of 51: OutputCatchability - // 26 of 51: OutputGrowthRate - // 27 of 51: OutputCarryingCapacity - // 28 of 51: OutputExponent - // 29 of 51: OutputMSY - // 30 of 51: OutputMSYBiomass - // 31 of 51: OutputMSYFishing + // 25 of 52: OutputCatchability + // 26 of 52: OutputGrowthRate + // 27 of 52: OutputCarryingCapacity + // 28 of 52: OutputExponent + // 29 of 52: OutputMSY + // 30 of 52: OutputMSYBiomass + // 31 of 52: OutputMSYFishing for (std::string tableName : {"OutputCatchability", "OutputGrowthRate", "OutputCarryingCapacity", @@ -628,8 +628,8 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 32 of 51: PredationLossRates - // 33 of 51: SpatialOverlap + // 32 of 52: PredationLossRates + // 33 of 52: SpatialOverlap for (std::string tableName : {"PredationLossRates", "SpatialOverlap"}) { @@ -653,11 +653,11 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 34 of 51: PredationLossRatesMax - // 35 of 51: PredationLossRatesMin - // 36 of 51: HandlingTimeMin - // 37 of 51: HandlingTimeMin - // xx of 51: TestCompetition + // 34 of 52: PredationLossRatesMax + // 35 of 52: PredationLossRatesMin + // 36 of 52: HandlingTimeMin + // 37 of 52: HandlingTimeMin + // xx of 52: TestCompetition for (std::string tableName : {"HandlingTimeMin", "HandlingTimeMax", "PredationLossRatesMax", @@ -685,7 +685,7 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } -// // 39 of 51: TestData +// // 39 of 52: TestData // fullTableName = db + ".TestData"; // cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; // cmd += "(GrowthRate float NOT NULL,"; @@ -702,7 +702,7 @@ nmfSetup_Tab2::createTables(QString databaseName) // if (! okToCreateMoreTables) // return; - // 38 of 51: Species + // 38 of 52: Species fullTableName = db + ".Species"; ExistingTableNames.push_back("Species"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -741,7 +741,7 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 39 of 51: Forecasts + // 39 of 52: Forecasts fullTableName = db + ".Forecasts"; ExistingTableNames.push_back("Forecasts"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -774,9 +774,9 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 40 of 51: ForecastExploitation - // 41 of 51: ForecastEffort - // 42 of 51: ForecastCatch + // 40 of 52: ForecastExploitation + // 41 of 52: ForecastEffort + // 42 of 52: ForecastCatch for (std::string tableName : {"ForecastExploitation", "ForecastEffort", "ForecastCatch"}) @@ -806,7 +806,7 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 43 of 51: ForecastBiomass + // 43 of 52: ForecastBiomass fullTableName = db + ".ForecastBiomass"; ExistingTableNames.push_back("ForecastBiomass"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -832,7 +832,7 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 44 of 51: ForecastBiomassMonteCarlo + // 44 of 52: ForecastBiomassMonteCarlo fullTableName = db + ".ForecastBiomassMonteCarlo"; ExistingTableNames.push_back("ForecastBiomassMonteCarlo"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -859,7 +859,41 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 45 of 51: ForecastBiomassMultiScenario + // 45 of 52: ForecastMonteCarloParameters + fullTableName = db + ".ForecastMonteCarloParameters"; + ExistingTableNames.push_back("ForecastMonteCarloParameters"); + cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; + cmd += "(ForecastName varchar(50) NOT NULL,"; + cmd += " RunNum int(11) NOT NULL,"; + cmd += " Algorithm varchar(50) NOT NULL,"; + cmd += " Minimizer varchar(50) NOT NULL,"; + cmd += " ObjectiveCriterion varchar(50) NOT NULL,"; + cmd += " Scaling varchar(50) NOT NULL,"; + cmd += " SpeName varchar(50) NOT NULL,"; + cmd += " GrowthRate float NULL,"; + cmd += " CarryingCapacity float NULL,"; + cmd += " Catchability float NULL,"; + cmd += " Exponent float NULL,"; + cmd += " CompetitionAlpha float NULL,"; + cmd += " CompetitionBetaSpecies float NULL,"; + cmd += " CompetitionBetaGuilds float NULL,"; + cmd += " Predation float NULL,"; + cmd += " Handling float NULL,"; + cmd += " Harvest float NULL,"; + cmd += " PRIMARY KEY (ForecastName,RunNum,Algorithm,Minimizer,ObjectiveCriterion,Scaling,SpeName))"; + errorMsg = m_DatabasePtr->nmfUpdateDatabase(cmd); + if (errorMsg != " ") { + nmfUtils::printError("[Error 20.1] CreateTables: Create table " + fullTableName + " error: ", errorMsg); + okToCreateMoreTables = false; + } else { + m_Logger->logMsg(nmfConstants::Normal,"Created table: "+fullTableName); + m_ProgressDlg->setValue(++pInc); + m_ProgressDlg->update(); + } + if (! okToCreateMoreTables) + return; + + // 46 of 52: ForecastBiomassMultiScenario fullTableName = db + ".ForecastBiomassMultiScenario"; ExistingTableNames.push_back("ForecastBiomassMultiScenario"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -882,7 +916,7 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 46 of 51: ForecastUncertainty + // 47 of 52: ForecastUncertainty fullTableName = db + ".ForecastUncertainty"; ExistingTableNames.push_back("ForecastUncertainty"); cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; @@ -915,8 +949,8 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; - // 47 of 51: DiagnosticGrowthRate - // 48 of 51: DiagnosticCarryingCapacity + // 48 of 52: DiagnosticGrowthRate + // 49 of 52: DiagnosticCarryingCapacity for (std::string tableName : {"DiagnosticGrowthRate", "DiagnosticCarryingCapacity"}) { @@ -946,7 +980,7 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 49 of 51: DiagnosticGRandCC (Growth Rate and CarryingCapacity + // 50 of 52: DiagnosticGRandCC (Growth Rate and CarryingCapacity for (std::string tableName : {"DiagnosticGRandCC"}) { ExistingTableNames.push_back(tableName); @@ -975,7 +1009,7 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } /* - // 52 of 51: OutputBiomassMohnsRho + // 52 of 52: OutputBiomassMohnsRho fullTableName = db + ".OutputBiomassMohnsRho"; cmd = "CREATE TABLE IF NOT EXISTS " + fullTableName; cmd += "(Label varchar(50) NOT NULL,"; @@ -1000,7 +1034,7 @@ nmfSetup_Tab2::createTables(QString databaseName) if (! okToCreateMoreTables) return; */ - // 50 of 51: Systems + // 51 of 52: Systems for (std::string tableName : {"Systems"}) { ExistingTableNames.push_back(tableName); @@ -1067,7 +1101,7 @@ nmfSetup_Tab2::createTables(QString databaseName) return; } - // 51 of 51: Application (contains name of application - used to assure app is using correct database) + // 52 of 52: Application (contains name of application - used to assure app is using correct database) for (std::string tableName : {"Application"}) { ExistingTableNames.push_back(tableName); diff --git a/MSSPM_Main/MSSPM_Main.pro b/MSSPM_Main/MSSPM_Main.pro index fb6f4e5c..77c2db1d 100644 --- a/MSSPM_Main/MSSPM_Main.pro +++ b/MSSPM_Main/MSSPM_Main.pro @@ -162,9 +162,9 @@ else:unix: LIBS += -L$$PWD/../../build-MSSPM_GuiOutput-Qt_5_12_3_gcc64-Release/ INCLUDEPATH += $$PWD/../MSSPM_GuiOutput DEPENDPATH += $$PWD/../MSSPM_GuiOutput -win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../build-MSSPM_GuiManagerMode-Qt_5_12_3_gcc64-Release/release/ -lMSSPM_GuiManagerMode -else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../build-MSSPM_GuiManagerMode-Qt_5_12_3_gcc64-Release/debug/ -lMSSPM_GuiManagerMode -else:unix: LIBS += -L$$PWD/../../build-MSSPM_GuiManagerMode-Qt_5_12_3_gcc64-Release/ -lMSSPM_GuiManagerMode +win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../build-REMORA-Qt_5_12_3_gcc64-Release/release/ -lREMORA +else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../build-REMORA-Qt_5_12_3_gcc64-Release/debug/ -lREMORA +else:unix: LIBS += -L$$PWD/../../build-REMORA-Qt_5_12_3_gcc64-Release/ -lREMORA -INCLUDEPATH += $$PWD/../MSSPM_GuiManagerMode -DEPENDPATH += $$PWD/../MSSPM_GuiManagerMode +INCLUDEPATH += $$PWD/../../REMORA/REMORA +DEPENDPATH += $$PWD/../../REMORA/REMORA diff --git a/MSSPM_Main/forms/MMode/mModeWindow.ui b/MSSPM_Main/forms/MMode/mModeWindow.ui index a1a383be..0a9f346a 100644 --- a/MSSPM_Main/forms/MMode/mModeWindow.ui +++ b/MSSPM_Main/forms/MMode/mModeWindow.ui @@ -6,19 +6,28 @@ 0 0 - 1293 - 863 + 1073 + 866 + + + 0 + 0 + + Form - - - 0 - + + + + 0 + 0 + + false @@ -49,51 +58,72 @@ + + + 0 + 0 + + - - - 0 - - - QLayout::SetFixedSize - - - - - - - - - 0 - 0 - - - - - 0 - 250 - - - - - 16777215 - 250 - - - - - 8 - - - - Qt::WheelFocus - - - - + + + + + + + 0 + 0 + + + + false + + + 5000 + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Output Chart Area</span></p><p>After a forecast has successfully run, its output will be drawn here. The input controls can be found in the Controls section to the right and in the Harvest interactive line chart section below. </p><p>Chart output may be captured and saved by using the camera icon in the main toolbar.</p></body></html> + + + + + + + + 0 + 0 + + + + + 0 + 250 + + + + + 16777215 + 250 + + + + + 8 + + + + Qt::WheelFocus + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Harvest Interactive Chart</span></p><p>This chart allows the user to interactively enter the future harvest data needed for the forecast model to run. The values on the chart correspond to scale values as they will apply to the last year's observed harvest values. For example, if we assume there are observed data from 1980-2000 and the harvest type is Catch, then the values on the plot refer to the scale factor for the year 2000's given Catch values.</p><p>A constant line at y-value = 1, depicted by 2 movable points, is initially presented to the user. This flat line signifies a constant future harvest rate. The user may move either end point or add (and then move) additional points by clicking on, and interacting with, the line.</p><p><span style=" font-weight:600; font-style:italic;">Allowable Actions:</span></p><p><span style=" font-weight:600;">Select point:</span> Click on point and hold mouse button down<br/><span style=" font-weight:600;">Add point</span>: Click on line<br/><span style=" font-weight:600;">Move point:</span> Click point and drag<br/><span style=" font-weight:600;">Delete point:</span> Select point and press delete button<br/><span style=" font-weight:600;">Reset line: </span>Select any point and press the &quot;r&quot; key</p></body></html> + + + + + @@ -116,7 +146,7 @@ - + 0 0 @@ -124,13 +154,13 @@ 320 - 700 + 0 320 - 700 + 32000 @@ -143,24 +173,6 @@ Controls - - 7 - - - QLayout::SetFixedSize - - - 0 - - - 0 - - - 0 - - - 0 - @@ -190,14 +202,154 @@ Qt::Vertical + + QSizePolicy::Fixed + 270 - 15 + 10 + + + + + + + 1 + 0 + + + + + 90 + 0 + + + + + 90 + 16777215 + + + + + 50 + false + + + + The name of the current forecast management scenario + + + The name of the current forecast management scenario + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Forecast Scenario</span></p><p>This is the name of the current forecast scenario file which contains the values of the control settings on this page. This field is not editable. It may only be changed by either loading a new forecast scenario or deleting the current forecast scenario.</p></body></html> + + + Scenario: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + true + + + + 2 + 0 + + + + + 50 + false + + + + false + + + The name of the current forecast management scenario + + + The name of the current forecast management scenario + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Forecast Scenario</span></p><p>This is the name of the current forecast scenario file which contains the values of the control settings on this page. This field is not editable. It may only be changed by either loading a new forecast scenario or deleting the current forecast scenario.</p><p>An &quot;*&quot; next to the scenario name signifies that the scenario has been modified since its loading.</p></body></html> + + + true + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + 50 + false + + + + Delete the current forecast scenario + + + Delete the current forecast scenario + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Delete</span></p><p>This button allows the user to delete the current forecast scenario file. After deletion, the controls on this page will be set to default values. Once deleted, the file can't be recovered.</p></body></html> + + + Del + + + + + @@ -206,6 +358,22 @@ QLayout::SetFixedSize + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 3 + + + + @@ -262,6 +430,9 @@ The duration of the Forecast in years. + + <html><head/><body><p align="center"><span style=" font-weight:600;">Years per Run</span></p><p>This sets the length of a forecast in years. Keep in mind that as the number of years in a forecast increases so does the processing time.</p></body></html> + Years / Run: @@ -343,6 +514,9 @@ The duration of the Forecast in years. + + <html><head/><body><p align="center"><span style=" font-weight:600;">Years per Run</span></p><p>This sets the length of a forecast in years. Keep in mind that as the number of years in a forecast increases so does the processing time.</p><p>Drag with the mouse or for fine control use the thumbwheel.</p></body></html> + 1 @@ -430,6 +604,9 @@ The duration of the Forecast in years. + + <html><head/><body><p align="center"><span style=" font-weight:600;">Years per Run</span></p><p>This sets the length of a forecast in years. Keep in mind that as the number of years in a forecast increases so does the processing time.</p></body></html> + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -496,6 +673,9 @@ The number of times the Forecast will be run. + + <html><head/><body><p align="center"><span style=" font-weight:600;">Runs per Forecast</span></p><p>This value sets the number of times a forecast will be run. Processing time increases as this value increases.</p></body></html> + Runs / Forecast: @@ -577,6 +757,9 @@ The number of times the Forecast will be run. + + <html><head/><body><p align="center"><span style=" font-weight:600;">Runs per Forecast</span></p><p>This value sets the number of times a forecast will be run. Processing time increases as this value increases.</p><p>Drag with the mouse or for fine control use the thumbwheel.</p></body></html> + 1 @@ -670,6 +853,9 @@ The number of times the Forecast will be run. + + <html><head/><body><p align="center"><span style=" font-weight:600;">Runs per Forecast</span></p><p>This value sets the number of times a forecast will be run. Processing time increases as this value increases.</p></body></html> + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -737,6 +923,15 @@ false + + <html><head/><body><p>Sets individual forecast uncertainty to be deterministic (i.e., reproducible)</p></body></html> + + + <html><head/><body><p>Sets individual forecast uncertainty to be deterministic (i.e., reproducible)</p></body></html> + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Deterministic Option</span></p><p>A forecast may be run deterministically or stochastically, by using a fixed seed value or a random seed value for the uncertainty parameters. Set this option if you want the same forecast uncertainty values used with each consecutive group of runs (the seed will be set to 1).</p></body></html> + Qt::RightToLeft @@ -753,6 +948,15 @@ false + + Sets individual forecast uncertainty to be randomized + + + Sets individual forecast uncertainty to be randomized + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Stochastic Option</span></p><p>A forecast may be run deterministically or stochastically, by using a fixed seed value or a random seed value for the uncertainty parameters. Set this option if you want randomized forecast uncertainty values used with each consecutive group of runs.</p></body></html> + Qt::RightToLeft @@ -870,6 +1074,15 @@ false + + View single species plot + + + View single species plot + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Single Species Plot</span></p><p>This option will show a forecast plot of a single species at a time. The pulldown below will set the species whose plot will be generated and drawn.</p></body></html> + Qt::RightToLeft @@ -886,6 +1099,15 @@ false + + View multiple species plot + + + View multiple species plot + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Multiple Species Plot</span></p><p>This option will show a forecast plot of all of the species at a time. The plot will consist of either multiple single-species plots laid out in a grid (with uncertainty variations) or a single plot with multiple species forecasts superimposed on each other (without any uncertaintly variations).</p></body></html> + Qt::RightToLeft @@ -894,6 +1116,46 @@ + + + + + 0 + 0 + + + + + 25 + 20 + + + + + 25 + 20 + + + + + 50 + false + + + + Selects Multi Species Single Plot or Mult Species Multi Plot + + + Selects Multi Species Single Plot or Mult Species Multi Plot + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Multi Species Plot Selector</span></p><p>If set to [ 1 ], the Multi Species data will appear on a single plot without Monte Carlo run data. If set to [ 1+ ], the Multi Species data will appear on separate plots composited within a single plot with Monte Carlo run data. </p></body></html> + + + 1 + + + @@ -959,6 +1221,15 @@ false + + Species on which to run a forecast + + + Species on which to run a forecast + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Species</span></p><p>This sets the species whose forecast will be generated to the left. For multi-species plots, this pulldown will be disabled.</p></body></html> + Species: @@ -987,6 +1258,62 @@ false + + Species on which to run a forecast + + + Species on which to run a forecast + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Species</span></p><p>This sets the species whose forecast will be generated to the left. For multi-species plots, this pulldown will be disabled.</p></body></html> + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + + 25 + 25 + + + + + 25 + 25 + + + + + 50 + false + + + + Sets the max y-value on the Harvest Scale Factor plot + + + Sets the max y-value on the Harvest Scale Factor plot + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Maximum Scale Factor Plot Y Value</span></p><p>This button allows the user to change the maximum value on the y-axis of the Harvest Scale Factor plot. The possible choices are 1, 2, 3, or 4.</p></body></html> + + + 4 + @@ -1024,7 +1351,13 @@ - + + + + 0 + 0 + + 75 @@ -1077,7 +1410,7 @@ - + 0 @@ -1102,6 +1435,15 @@ false + + Type of forecast chart to be displayed + + + Type of forecast chart to be displayed + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Forecast Type</span></p><p>There are 3 types of forecast charts available to the user:<br/><br/>(1) Biomass vs Time<br/>(2) Harvest vs Time<br/>(3) Fishing Mortality vs Time</p></body></html> + Data: @@ -1111,7 +1453,7 @@ - + 200 @@ -1130,14 +1472,23 @@ false + + Type of forecast chart to be displayed + + + Type of forecast chart to be displayed + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Forecast Type</span></p><p>There are 3 types of forecast charts available to the user:<br/><br/>(1) Absolute Biomass vs Time<br/>(2) Relative Biomass vs Time<br/>(3) Fishing Mortality vs Time</p></body></html> + - Biomass + Biomass (absolute) - Harvest + Biomass (relative) @@ -1148,25 +1499,66 @@ - + Qt::Horizontal + + QSizePolicy::Fixed + - 10 + 5 20 - - - - - - 0 - + + + + + 50 + false + + + + Locks the Y Axis to the current value + + + Locks the Y Axis to the current value + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Y Axis Lock</span></p><p>When this box is checked, all model runs' maximum y-axis values are set to the y-axis maximum value of the run at the time the box was checked.</p><p>The purpose of this is to be able to save and compare screenshot images using the same maximum y-axis value.</p></body></html> + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + + 0 + QLayout::SetFixedSize @@ -1196,6 +1588,9 @@ Qt::Vertical + + QSizePolicy::Fixed + 20 @@ -1218,6 +1613,15 @@ false + + Toggles on/off the maximum sustained yield line + + + Toggles on/off the maximum sustained yield line + + + <html><head/><body><p align="center"><span style=" font-weight:600;">MSY Line</span></p><p>Toggles on/off the MSY (Maximum Sustained Yield) line. The MSY line appears as a dotted line superimposed over the forecast plots.</p><p>For Biomass, the MSY is the carrying capacity / 2, i.e., MSY = K/2. For Fishing Mortality, the MSY is the growth rate / 2, i.e., MSY = r/2.</p></body></html> + Qt::RightToLeft @@ -1231,16 +1635,19 @@ Qt::Vertical + + QSizePolicy::Fixed + 20 - 10 + 5 - + 0 @@ -1253,6 +1660,15 @@ false + + Enable the % MSY line + + + Enable the % MSY line + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Enable % MSY Line</span></p><p>This checkbox enables the % MSY line functionality. The dial to the right will be enabled and will allow the user to set the value for the % MSY line.</p></body></html> + Qt::RightToLeft @@ -1266,10 +1682,13 @@ Qt::Vertical + + QSizePolicy::Fixed + 20 - 30 + 20 @@ -1320,6 +1739,30 @@ 80 + + Value of line representing % of MSY + + + Value of line representing % of MSY + + + <html><head/><body><p align="center"><span style=" font-weight:600;">% MSY</span></p><p>The value generated by this dial represents the % MSY line drawn on the plot to the left. For example, a 50% MSY line would appear halfway between 0 and the MSY line.</p><p>Turn the dial using the mouse. For fine control either use the thumbwheel or turn the dial by clicking on the dial handle and dragging the mouse away from the dial then turning the dial.</p></body></html> + + + 200 + + + false + + + false + + + false + + + false + @@ -1372,6 +1815,15 @@ false + + Value of line representing % of MSY + + + Value of line representing % of MSY + + + <html><head/><body><p align="center"><span style=" font-weight:600;">% MSY</span></p><p>This value is generated by the above dial and represents the % MSY line drawn on the plot to the left. For example, a value of 50% means that the % MSY line would appear halfway between 0 and the MSY line.</p></body></html> + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1382,6 +1834,12 @@ + + + 0 + 0 + + 50 @@ -1411,6 +1869,22 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 15 + + + + @@ -1455,6 +1929,12 @@ + + + 0 + 0 + + 75 @@ -1540,6 +2020,15 @@ 80 + + Uncertainty (or error) range for Growth term + + + Uncertainty (or error) range for Growth term + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Uncertainty Growth Parameter</span></p><p>This value represents the range of error (with respect to the growth parameter) that each forecast will receive. For example, if the user sets this to 10% each forecast run's growth parameter will vary by a random number with the range of <span style=" font-family:'Arial,Helvetica Neue,Helvetica,sans-serif'; font-size:13px;">±</span>10%.</p><p>Turn the dial using the mouse. For fine control either use the thumbwheel or turn the dial by clicking on the dial handle and dragging the mouse away from the dial then turning the dial.</p></body></html> + 200 @@ -1593,10 +2082,13 @@ - Growth Rate Percentage Error + Uncertainty (or error) range for Growth term - Growth Rate Percentage Error + Uncertainty (or error) range for Growth term + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Uncertainty Growth Parameter</span></p><p>This value represents the range of error (with respect to the growth parameter) that each forecast will receive. For example, if the user sets this to 10% each forecast run's growth parameter will vary by a random number with the range of <span style=" font-family:'Arial,sans-serif'; font-size:16px;">±</span>10%.</p></body></html> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1689,6 +2181,15 @@ 80 + + Uncertainty (or error) range for Carrying Capacity term + + + Uncertainty (or error) range for Carrying Capacity term + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Uncertainty Carrying Capacity Parameter</span></p><p>This value represents the range of error (with respect to the carrying capacity parameter) that each forecast will receive. For example, if the user sets this to 10% each forecast run's carrying capacity parameter will vary by a random number with the range of <span style=" font-family:'Arial,Helvetica Neue,Helvetica,sans-serif'; font-size:13px;">±1</span>0%.</p><p>Turn the dial using the mouse. For fine control either use the thumbwheel or turn the dial by clicking on the dial handle and dragging the mouse away from the dial then turning the dial.</p></body></html> + 200 @@ -1742,10 +2243,13 @@ - Carrying Capacity Percentage Error + Uncertainty (or error) range for Carrying Capacity term - Carrying Capacity Percentage Error + Uncertainty (or error) range for Carrying Capacity term + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Uncertainty Carrying Capacity Parameter</span></p><p>This value represents the range of error (with respect to the carrying capacity parameter) that each forecast will receive. For example, if the user sets this to 10% each forecast run's carrying capacity parameter will vary by a random number with the range of <span style=" font-family:'Arial,sans-serif'; font-size:16px;">±</span>10%.</p></body></html> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1797,7 +2301,7 @@ QLayout::SetFixedSize - + 0 @@ -1816,6 +2320,15 @@ false + + Sets the type of Harvest uncertainty parameter + + + Sets the type of Harvest uncertainty parameter + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Harvest Uncertainty Selector</span></p><p>This button allows the user to set the harvest parameter type to either Catch, Effort, or Exploitation. The line graph to the left and bottom will then reflect this type of harvest selection in the plot that allows for harvest data input in the form of a curve defined by multiple line segments.</p></body></html> + Catch @@ -1825,7 +2338,7 @@ - + 0 @@ -1844,6 +2357,15 @@ 80 + + Uncertainty (or error) range for Harvest term + + + Uncertainty (or error) range for Harvest term + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Uncertainty Harvest Parameter</span></p><p>This value represents the range of error (with respect to the harvest parameter) that each forecast will receive. For example, if the user sets this to 10% each forecast run's harvest parameter will vary by a random number with the range of <span style=" font-family:'Arial,Helvetica Neue,Helvetica,sans-serif'; font-size:13px;">±</span>10%. </p><p>The harvest parameter type is set by the button directly above this dial. The allowable harvest parameter types are: Catch, Effort, and Exploitation.</p><p>Turn the dial using the mouse. For fine control either use the thumbwheel or turn the dial by clicking on the dial handle and dragging the mouse away from the dial then turning the dial.</p></body></html> + 200 @@ -1874,7 +2396,7 @@ - + 0 @@ -1901,10 +2423,13 @@ - Catch Percentage Error + Uncertainty (or error) range for Harvest term - Catch Percentage Error + Uncertainty (or error) range for Harvest term + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Uncertainty Harvest Parameter</span></p><p>This value represents the range of error (with respect to the harvest parameter) that each forecast will receive. For example, if the user sets this to 10% each forecast run's harvest parameter will vary by a random number with the range of <span style=" font-family:'Arial,sans-serif'; font-size:16px;">±</span>10%. </p><p>The harvest parameter type is set by the button directly above this dial. The allowable harvest parameter types are: Catch, Effort, and Exploitation.</p></body></html> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1949,6 +2474,29 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 5 + + + + + + + + Qt::Horizontal + + + @@ -1957,7 +2505,197 @@ 20 - 10 + 40 + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + 50 + false + + + + Load a forecast + + + Load a forecast + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Load</span></p><p>This button allows the user to load a previously saved Remora forecast configuration. The forecast name will appear in the Forecast Name box at the top of the controls. </p></body></html> + + + Load... + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + 100 + 75 + + + + + 100 + 75 + + + + + 11 + 50 + false + + + + Run the forecast using above settings + + + Run the forecast using above settings + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Run</span></p><p>This button will run the forecast scenario based upon the settings of the input controls. The output will be shown in the chart at the top left. On the bottom left is an interactive plot that the user may interact with to define the future harvest input data.</p></body></html> + + + Run + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + + 50 + false + + + + Save current forecast configuration + + + Save current forecast configuration + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Save</span></p><p>This buttons allows the user to save a forecast configuration based upon all of the controls on this page.</p></body></html> + + + Save... + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 20 @@ -1978,79 +2716,6 @@ - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - - 100 - 75 - - - - - 100 - 75 - - - - - 11 - - - - Run - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/MSSPM_Main/nmfMainWindow.cpp b/MSSPM_Main/nmfMainWindow.cpp index 4c0e3c9b..c382007d 100644 --- a/MSSPM_Main/nmfMainWindow.cpp +++ b/MSSPM_Main/nmfMainWindow.cpp @@ -63,7 +63,7 @@ nmfMainWindow::nmfMainWindow(QWidget *parent) : m_Graph3D = nullptr; OutputChartMainLayt = nullptr; Output_Controls_ptr = nullptr; - MMode_Controls_ptr = nullptr; + Remora_ptr = nullptr; m_PreferencesDlg = new QDialog(this); m_TableNamesDlg = new QDialog(this); m_PreferencesWidget = nullptr; @@ -75,6 +75,7 @@ nmfMainWindow::nmfMainWindow(QWidget *parent) : m_ChartView2d = nullptr; m_EstimatedParametersTW = nullptr; m_EstimatedParametersMap.clear(); + m_UI->actionToggleManagerModeViewer->setEnabled(false); m_UI->actionShowAllSavedRunsTB->setEnabled(false); @@ -103,7 +104,7 @@ nmfMainWindow::nmfMainWindow(QWidget *parent) : m_DatabasePtr = new nmfDatabase(); m_DatabasePtr->nmfSetConnectionByName(db.connectionName()); - readSettingsGuiPositionOrientationOnly(); + readSettingsGuiOrientation(nmfConstantsMSSPM::ResetPositionAlso); readSettings(); initializePreferencesDlg(); @@ -353,8 +354,14 @@ nmfMainWindow::menu_layoutOutput() void nmfMainWindow::menu_layoutDefault() { - this->addDockWidget(Qt::LeftDockWidgetArea, m_UI->NavigatorDockWidget); - this->addDockWidget(Qt::RightDockWidgetArea, m_UI->OutputDockWidget); + MModeDockWidget->hide(); + MModeViewerDockWidget->hide(); + setVisibilityToolbarButtons(true); + +// this->addDockWidget(Qt::LeftDockWidgetArea, m_UI->NavigatorDockWidget); +// this->addDockWidget(Qt::RightDockWidgetArea, m_UI->OutputDockWidget); + this->restoreDockWidget(m_UI->NavigatorDockWidget); + this->restoreDockWidget(m_UI->OutputDockWidget); m_UI->NavigatorDockWidget->show(); m_UI->OutputDockWidget->setFloating(false); m_UI->OutputDockWidget->show(); @@ -362,10 +369,11 @@ nmfMainWindow::menu_layoutDefault() m_UI->ProgressDockWidget->show(); m_UI->LogDockWidget->setFloating(false); m_UI->LogDockWidget->show(); - this->addDockWidget(Qt::BottomDockWidgetArea, m_UI->ProgressDockWidget); - this->addDockWidget(Qt::BottomDockWidgetArea, m_UI->LogDockWidget); + centralWidget()->show(); this->tabifyDockWidget(m_UI->LogDockWidget, m_UI->ProgressDockWidget); + readSettingsGuiOrientation(nmfConstantsMSSPM::DontResetPosition); + } @@ -542,9 +550,9 @@ nmfMainWindow::getTimeSeriesDataByGuild( // Load data if (ForecastName == "") { ModifiedTableName = TableName;; - fields = {"SystemName","SpeName","Year","Value"}; - queryStr = "SELECT SystemName,SpeName,Year,Value FROM " + ModifiedTableName + - " WHERE SystemName = '" + m_ProjectSettingsConfig + "' ORDER BY SpeName,Year"; + fields = {"MohnsRhoLabel","SystemName","SpeName","Year","Value"}; + queryStr = "SELECT MohnsRhoLabel,SystemName,SpeName,Year,Value FROM " + ModifiedTableName + + " WHERE MohnsRhoLabel = '' AND SystemName = '" + m_ProjectSettingsConfig + "' ORDER BY SpeName,Year"; } else { ModifiedTableName = "Forecast" + TableName; fields = {"ForecastName","SpeName","Year","Value"}; @@ -585,75 +593,6 @@ nmfMainWindow::getTimeSeriesDataByGuild( } -bool -nmfMainWindow::getTimeSeriesData( - const std::string MohnsRhoLabel, - const std::string ForecastName, - const std::string& TableName, - const int& NumSpecies, - const int& RunLength, - boost::numeric::ublas::matrix& TableData) -{ - int m=0; - int NumRecords; - std::vector fields; - std::map > dataMap; - std::string queryStr; - std::string errorMsg; - std::string ModifiedTableName = ""; - QString msg; - QString SystemName = QString::fromStdString(m_ProjectSettingsConfig); - - auto parts = SystemName.split("__"); - SystemName = parts[0]; - - nmfUtils::initialize(TableData,RunLength+1,NumSpecies); // +1 because there's a 0 year - - // Load data - if (ForecastName == "") { - ModifiedTableName = TableName;; - fields = {"MohnsRhoLabel","SystemName","SpeName","Year","Value"}; - queryStr = "SELECT MohnsRhoLabel,SystemName,SpeName,Year,Value FROM " + ModifiedTableName + - " WHERE SystemName = '" + SystemName.toStdString() + - "' AND MohnsRhoLabel = '" + MohnsRhoLabel + "' ORDER BY SpeName,Year"; - } else { - ModifiedTableName = "Forecast" + TableName;; - fields = {"ForecastName","SpeName","Year","Value"}; - queryStr = "SELECT ForecastName,SpeName,Year,Value FROM " + ModifiedTableName + - " WHERE ForecastName = '" + ForecastName + - "' ORDER BY SpeName,Year"; - } - dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); - NumRecords = dataMap["SpeName"].size(); - if (NumRecords == 0) { - m_Logger->logMsg(nmfConstants::Error,"[Error 1] getTimeSeriesData: No records found in table "+TableName); - m_Logger->logMsg(nmfConstants::Error,queryStr); - msg = "\nMissing or unsaved data. Please populate and resave table: " + QString::fromStdString(TableName); - QMessageBox::critical(this, "Error", msg, QMessageBox::Ok); - return false; - } - if (NumRecords != NumSpecies*(RunLength+1)) { - errorMsg = "[Error 2] getTimeSeriesData: Number of records found (" + std::to_string(NumRecords) + ") in "; - errorMsg += "table " + ModifiedTableName + " does not equal number of Species*(RunLength+1) ("; - errorMsg += std::to_string(NumSpecies) + "*" + std::to_string((RunLength+1)) + "="; - errorMsg += std::to_string(NumSpecies*(RunLength+1)) + ") records"; - errorMsg += "\n" + queryStr; - m_Logger->logMsg(nmfConstants::Error,errorMsg); - msg = "\nMissing or unsaved data.\n\nPlease populate and resave table: " + QString::fromStdString(ModifiedTableName) + "\n"; - QMessageBox::critical(this, "Error", msg, QMessageBox::Ok); - return false; - } - - // Figure out what to do here with the hardcoded 0 for time=0.....RSK - for (int species=0; species &FinalBiomass) return false; // Get final observed biomass values - if (! getTimeSeriesData("","","ObservedBiomass",NumSpecies,RunLength,ObservedBiomass)) { + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + "","","ObservedBiomass", + NumSpecies,RunLength,ObservedBiomass)) { return false; } for (int species=0; speciesgetTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,"","Catch",NumSpecies,RunLength,Catch)) return; getOutputGrowthRate(EstGrowthRate,false); getOutputCarryingCapacity(EstCarryingCapacity,false); @@ -1515,67 +1457,80 @@ nmfMainWindow::menu_screenShot() QPixmap pm; QString outputFile; - QString currentTabName = nmfUtilsQt::getCurrentTabName(m_UI->MSSPMOutputTabWidget); + if (runningREMORA()) { - if ((currentTabName != "Chart") && (currentTabName != "Screen Shot Viewer")) { - // Save numeric table - if (currentTabName == "Estimated Parameters") - { - QString currentSubTabName = nmfUtilsQt::getCurrentTabName(m_EstimatedParametersTW); - nmfUtilsQt::saveModelToCSVFile(m_ProjectDir, - currentSubTabName.toStdString(), - m_EstimatedParametersMap[currentSubTabName]); - } else if ((currentTabName == "Data") || - (currentTabName == "Model Fit Summary")) - { - nmfUtilsQt::saveModelToCSVFile(m_ProjectDir, - currentTabName.toStdString(), - m_EstimatedParametersMap[currentTabName]); + Remora_ptr->grabImage(pm); + + nmfStructsQt::ChartSaveDlg *dlg = new nmfStructsQt::ChartSaveDlg(this); + if (dlg->exec()) { + outputFile = dlg->getFilename(); } - return; + delete dlg; + if (outputFile.isEmpty()) + return; + saveScreenshot(outputFile,pm); } + else { + QString currentTabName = nmfUtilsQt::getCurrentTabName(m_UI->MSSPMOutputTabWidget); + if ((currentTabName != "Chart") && (currentTabName != "Screen Shot Viewer")) { + // Save numeric table + if (currentTabName == "Estimated Parameters") + { + QString currentSubTabName = nmfUtilsQt::getCurrentTabName(m_EstimatedParametersTW); + nmfUtilsQt::saveModelToCSVFile(m_ProjectDir, + currentSubTabName.toStdString(), + m_EstimatedParametersMap[currentSubTabName]); + } else if ((currentTabName == "Data") || + (currentTabName == "Model Fit Summary")) + { + nmfUtilsQt::saveModelToCSVFile(m_ProjectDir, + currentTabName.toStdString(), + m_EstimatedParametersMap[currentTabName]); + } + return; + } - // Need this so as to ensure each screen shot finishes - // before the next one starts. - QApplication::sync(); + // Need this so as to ensure each screen shot finishes + // before the next one starts. + QApplication::sync(); - setCurrentOutputTab("Chart"); + setCurrentOutputTab("Chart"); - if (m_ChartView2d->isVisible() || m_ChartView3d->isVisible()) - { - if (! m_ScreenshotOn) { - nmfStructsQt::ChartSaveDlg *dlg = new nmfStructsQt::ChartSaveDlg(this); - if (dlg->exec()) { - outputFile = dlg->getFilename(); + if (m_ChartView2d->isVisible() || m_ChartView3d->isVisible()) + { + if (! m_ScreenshotOn) { + nmfStructsQt::ChartSaveDlg *dlg = new nmfStructsQt::ChartSaveDlg(this); + if (dlg->exec()) { + outputFile = dlg->getFilename(); + } + delete dlg; + if (outputFile.isEmpty()) + return; } - delete dlg; - if (outputFile.isEmpty()) - return; - } - // Grab the image and store in a pixmap - if (m_ChartView2d->isVisible()) { - m_ChartView2d->update(); - m_ChartView2d->repaint(); - pm = m_ChartView2d->grab(); + // Grab the image and store in a pixmap + if (m_ChartView2d->isVisible()) { + m_ChartView2d->update(); + m_ChartView2d->repaint(); + pm = m_ChartView2d->grab(); - } else if (m_ChartView3d->isVisible()) { - m_ChartView3d->update(); - m_ChartView3d->repaint(); - pm.convertFromImage(m_Graph3D->renderToImage()); - } + } else if (m_ChartView3d->isVisible()) { + m_ChartView3d->update(); + m_ChartView3d->repaint(); + pm.convertFromImage(m_Graph3D->renderToImage()); + } - // Either load pixmap into vector of pixmaps for a composite image - // or save the pixmap to disk - if (m_ScreenshotOn) { - m_Pixmaps.push_back(pm); - } else { - saveScreenshot(outputFile,pm); - } + // Either load pixmap into vector of pixmaps for a composite image + // or save the pixmap to disk + if (m_ScreenshotOn) { + m_Pixmaps.push_back(pm); + } else { + saveScreenshot(outputFile,pm); + } + } } - // RSK add... // else check for visible table @@ -1685,40 +1640,219 @@ nmfMainWindow::menu_exportAllDatabases() } } +bool +nmfMainWindow::runningREMORA() +{ + return MModeDockWidget->isVisible(); +} + + + void -nmfMainWindow::menu_toggleManagerMode() +nmfMainWindow::menu_toggleManagerModeViewer() { - bool isVisible = MModeDockWidget->isVisible(); + if (runningREMORA()) { + if (MModeViewerDockWidget->isVisible()) { + MModeViewerDockWidget->hide(); + m_UI->actionToggleManagerModeViewer->setChecked(false); + m_UI->actionOpenCSVFile->setEnabled(false); + } else { + showMModeViewerDockWidget(); + } + } +} - MModeDockWidget->setVisible(! isVisible); - m_UI->LogDockWidget->setVisible(isVisible); - m_UI->OutputDockWidget->setVisible(isVisible); - m_UI->NavigatorDockWidget->setVisible(isVisible); - m_UI->ProgressDockWidget->setVisible(isVisible); - m_UI->centralWidget->setVisible(isVisible); +void +nmfMainWindow::menu_openCSVFile() +{ + QString fileName; + QString pathData = QDir(QString::fromStdString(m_ProjectDir)).filePath(QString::fromStdString(nmfConstantsMSSPM::OutputDataDirMMode)); + QString filenameWithPath = QDir(pathData).filePath(m_MModeViewerWidget->getCurrentFilename()); + nmfUtilsQt::switchFileExtensions(filenameWithPath,".csv",{".jpg",".png"}); + + fileName = QFileDialog::getOpenFileName( + this, tr("Open CSV File"), + filenameWithPath, tr("*.csv")); + if (! fileName.isEmpty()) { + if (nmfUtils::isOSWindows()) { + std::string cmd = "start " + fileName.toStdString(); + std::system(cmd.c_str()); + } else { + std::string cmd = "/usr/bin/libreoffice " + fileName.toStdString(); + QProcess::execute(cmd.c_str()); + } + } +} + +bool +nmfMainWindow::getForecastInitialData( + QString& forecastName, + int& numYearsPerRun, + int& numRunsPerForecast) +{ + int NumRecords; + std::vector fields; + std::map > dataMap; + std::string queryStr; + bool ok; + QStringList items; + + forecastName.clear(); + numYearsPerRun = 0; + numRunsPerForecast = 0; + + fields = {"ForecastName","RunLength","NumRuns"}; + queryStr = "SELECT ForecastName,RunLength,NumRuns FROM Forecasts"; + dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); + NumRecords = dataMap["ForecastName"].size(); + if (NumRecords == 0) { + return false; + } else if (NumRecords == 1) { + forecastName = QString::fromStdString(dataMap["ForecastName"][0]); + numYearsPerRun = std::stod(dataMap["RunLength"][0]); + numRunsPerForecast = std::stod(dataMap["NumRuns"][0]); + } else { + for (int i=0; inmfQueryDatabase(queryStr, fields); + NumRecords = dataMap["ForecastName"].size(); + if (NumRecords == 0) { + return false; + } + } + + return true; +} + +void +nmfMainWindow::menu_toggleManagerMode() +{ + bool ok; int numSpecies; QStringList speciesList; + bool showManagerMode = ! runningREMORA(); + + // Set state of relevant menu items + m_UI->actionToggleManagerModeViewer->setEnabled(showManagerMode); + if (! showManagerMode) { + m_UI->actionToggleManagerModeViewer->setChecked(false); + } + + if (showManagerMode) { + + saveSettings(); + + // Get desired forecast data and initialize Remora with them + int numYearsPerRun; + int numRunsPerForecast; + QString forecastName; + ok = getForecastInitialData(forecastName,numYearsPerRun,numRunsPerForecast); + if (! ok and forecastName.isEmpty()) { + return; + } + if (! ok and ! forecastName.isEmpty()) { + QString msg = "\nPlease make sure a forecast has been run for: "+forecastName+"\n"; + QMessageBox::warning(this, "Warning", msg, QMessageBox::Ok); + return; + } + if (forecastName.isEmpty()) { + QString msg = "\nAt least one forecast must be created prior to using REMORA.\n"; + QMessageBox::warning(this, "Warning", msg, QMessageBox::Ok); + return; + } - getSpecies(numSpecies, speciesList); - MMode_Controls_ptr->setData(speciesList); + Remora_ptr->setForecastName(forecastName); + Remora_ptr->setForecastNumYearsPerRun(numYearsPerRun); + Remora_ptr->setForecastNumRunsPerForecast(numRunsPerForecast); + + // Set visibility on dock widgets + m_UI->OutputDockWidget->setVisible(false); + m_UI->NavigatorDockWidget->setVisible(false); + m_UI->ProgressDockWidget->setVisible(false); + m_UI->LogDockWidget->setVisible(false); + m_UI->centralWidget->setVisible(false); + this->tabifyDockWidget(m_UI->LogDockWidget, m_UI->ProgressDockWidget); + + // Load species into manager mode + getSpecies(numSpecies, speciesList); + Remora_ptr->setSpeciesList(speciesList); + + // Show Manager Mode UI + MModeDockWidget->setVisible(true); + + } else { + menu_layoutDefault(); + } + + // Set visibility on toolbar buttons + setVisibilityToolbarButtons(! showManagerMode); + +} + +void +nmfMainWindow::setVisibilityToolbarButtons(bool isVisible) +{ + m_UI->actionSaveCurrentRunTB->setEnabled(isVisible); + m_UI->actionShowCurrentRunTB->setEnabled(isVisible); + m_UI->actionSaveViewTB->setEnabled(isVisible); + m_UI->actionBeesTB->setEnabled(isVisible); + m_UI->actionNLoptTB->setEnabled(isVisible); + m_UI->actionScreenShotAll->setEnabled(isVisible); + m_UI->actionMultiShot->setEnabled(isVisible); } bool -nmfMainWindow::saveScreenshot(QString &outputFile, QPixmap &pm) +nmfMainWindow::saveScreenshot(QString &outputImageFile, QPixmap &pm) { QString msg; - QString path = QDir(QString::fromStdString(m_ProjectDir)).filePath(QString::fromStdString(nmfConstantsMSSPM::OutputImagesDir)); + QString pathImage; + QString pathData; QMessageBox::StandardButton reply; - QString outputFileWithPath; + QString outputImageFileWithPath; + QString outputDataFileWithPath; + QString outputDataFile = outputImageFile; + + nmfUtilsQt::switchFileExtensions(outputDataFile,".csv",{".jpg",".png"}); + + if (runningREMORA()) { + pathImage = QDir(QString::fromStdString(m_ProjectDir)).filePath(QString::fromStdString(nmfConstantsMSSPM::OutputImagesDirMMode)); + pathData = QDir(QString::fromStdString(m_ProjectDir)).filePath(QString::fromStdString(nmfConstantsMSSPM::OutputDataDirMMode)); + } else { + pathImage = QDir(QString::fromStdString(m_ProjectDir)).filePath(QString::fromStdString(nmfConstantsMSSPM::OutputImagesDir)); + pathData = QDir(QString::fromStdString(m_ProjectDir)).filePath(QString::fromStdString(nmfConstantsMSSPM::OutputDataDir)); + } // If path doesn't exist make it - QDir pathDir(path); - if (! pathDir.exists()) { - pathDir.mkpath(path); + for (QString path : {pathImage,pathData}) { + QDir pathDir(path); + if (! pathDir.exists()) { + pathDir.mkpath(path); + } } - outputFileWithPath = QDir(path).filePath(outputFile); - if (QFileInfo(outputFileWithPath).exists()) { + outputDataFileWithPath = QDir(pathData).filePath(outputDataFile); + outputImageFileWithPath = QDir(pathImage).filePath(outputImageFile); + if (QFileInfo(outputImageFileWithPath).exists()) { msg = "\nFile exists. OK to overwrite?\n"; reply = QMessageBox::question(this, tr("File Exists"), tr(msg.toLatin1()), QMessageBox::No|QMessageBox::Yes, @@ -1728,11 +1862,20 @@ nmfMainWindow::saveScreenshot(QString &outputFile, QPixmap &pm) } // Save the image - pm.save(outputFileWithPath); + pm.save(outputImageFileWithPath); + + // Save the data file + if (runningREMORA()) { + saveRemoraDataFile(outputDataFileWithPath); + } // Notify user image has been saved - msg = "\nCapture image saved to file:\n\n" + outputFileWithPath; - msg += "\n\nView captured image in \"Screen Shot Viewer\" tab?\n"; + msg = "\nCapture image saved to file:\n\n" + outputImageFileWithPath; + if (runningREMORA()) { + msg += "\n\nView captured image in \"REMORA Viewer\" window?\n"; + } else { + msg += "\n\nView captured image in \"Screen Shot Viewer\" tab?\n"; + } reply = QMessageBox::question(this, tr("Image Saved"), tr(msg.toLatin1()), @@ -1740,16 +1883,198 @@ nmfMainWindow::saveScreenshot(QString &outputFile, QPixmap &pm) QMessageBox::Yes); if (reply == QMessageBox::Yes) { - // Enable the viewer tab - m_ViewerWidget->updateScreenShotViewer(outputFile); - setCurrentOutputTab("Screen Shot Viewer"); + if (runningREMORA()) { + // Enable the viewer tab + m_MModeViewerWidget->updateScreenShotViewer(outputImageFile); + showMModeViewerDockWidget(); + } else { + // Enable the viewer tab + m_ViewerWidget->updateScreenShotViewer(outputImageFile); + setCurrentOutputTab("Screen Shot Viewer"); + } + } else { + // Refresh the viewer image list so that if the user just toggles on the viewer, + // it will show the most recent images in its combobox and won't need to be refreshed. + m_MModeViewerWidget->refreshList(); } - m_Logger->logMsg(nmfConstants::Normal,"menu_screenshot: Image saved: "+ outputFile.toStdString()); + m_Logger->logMsg(nmfConstants::Normal,"menu_screenshot: Image saved: "+ outputImageFile.toStdString()); return true; } +void +nmfMainWindow::saveRemoraDataFile(QString filename) +{ + int NumSpecies=0; + int RunLength; + int NumRuns; + int StartForecastYear; + int NumYearsPerRun; + int NumRunsPerForecast; + int Year; + double val,val0; + double numerator,denominator; + QString ForecastName; + std::string Algorithm; + std::string Minimizer; + std::string ObjectiveCriterion; + std::string Scaling; + std::string TableName = "Forecasts"; + QStringList SpeciesList; + QString Header = "Year"; + QStringList HeaderList; + std::vector > ForecastCatch; + std::vector > ForecastBiomass; + QStandardItem* item; + + // Get number of years in forecast and number of species + if (! getSpecies(NumSpecies,SpeciesList)) + return; + HeaderList << "Year"; + for (QString Species : SpeciesList) { + Header += ", " + Species; + HeaderList << Species; + } + + getForecastInitialData(ForecastName,NumYearsPerRun,NumRunsPerForecast); + + // Find Forecast info + if (! m_DatabasePtr->getForecastInfo( + TableName,ForecastName.toStdString(),RunLength,StartForecastYear, + Algorithm,Minimizer,ObjectiveCriterion,Scaling,NumRuns)) { + return; + } + + // Get ForecastBiomass data + if (! m_DatabasePtr->getForecastBiomass( + this,m_Logger,ForecastName.toStdString(),NumSpecies,RunLength, + Algorithm,Minimizer,ObjectiveCriterion,Scaling,ForecastBiomass)) { + return; + } + + // Get ForecastCatch data + if (! m_DatabasePtr->getForecastCatch( + this,m_Logger,ForecastName.toStdString(),NumSpecies,RunLength, + Algorithm,Minimizer,ObjectiveCriterion,Scaling,ForecastCatch)) { + return; + } + + QFile file(filename); + if (file.open(QIODevice::ReadWrite)) { + QTextStream stream(&file); + + stream << "Number of Species: " << NumSpecies << endl; + stream << "Number of Years: " << RunLength << endl; + + QStandardItemModel* smodel1 = new QStandardItemModel(RunLength,1+NumSpecies); + QStandardItemModel* smodel2 = new QStandardItemModel(RunLength,1+NumSpecies); + QStandardItemModel* smodel3 = new QStandardItemModel(RunLength,1+NumSpecies); + QStandardItemModel* smodel4 = new QStandardItemModel(RunLength,1+NumSpecies); + + // Write out Absolute Biomass data + stream << endl << "# Biomass (absolute)" << endl; + stream << Header << endl; + for (int i=0; i<=RunLength; ++i) { + stream << StartForecastYear+i; + item = new QStandardItem(QString::number(StartForecastYear+i,'d',0)); + item->setTextAlignment(Qt::AlignCenter); + smodel1->setItem(i, 0, item); + for (int j=0; jsetTextAlignment(Qt::AlignCenter); + smodel1->setItem(i, j+1, item); + } + stream << endl; + } + smodel1->setHorizontalHeaderLabels(HeaderList); + + // Write out Relative Biomass data + stream << endl << "# Biomass (relative)" << endl; + stream << Header << endl; + for (int i=0; i<=RunLength; ++i) { + stream << StartForecastYear+i; + item = new QStandardItem(QString::number(StartForecastYear+i,'d',0)); + item->setTextAlignment(Qt::AlignCenter); + smodel2->setItem(i, 0, item); + for (int j=0; jsetTextAlignment(Qt::AlignCenter); + smodel2->setItem(i, j+1, item); + } + stream << endl; + } + smodel2->setHorizontalHeaderLabels(HeaderList); + + // Write out Fishing Mortality data (C/Bc) + stream << endl << "# Fishing Mortality" << endl; + stream << Header << endl; + for (int i=0; i<=RunLength; ++i) { + stream << StartForecastYear+i; + item = new QStandardItem(QString::number(StartForecastYear+i,'d',0)); + item->setTextAlignment(Qt::AlignCenter); + smodel3->setItem(i, 0, item); + for (int j=0; jsetTextAlignment(Qt::AlignCenter); + smodel3->setItem(i, j+1, item); + } + stream << endl; + } + smodel3->setHorizontalHeaderLabels(HeaderList); + + // Write out harvest scale factor data + stream << endl << "# Harvest Scale Factor" << endl; + stream << Header << endl; + for (int i=0; i<=RunLength; ++i) { + stream << StartForecastYear+i; + Year = StartForecastYear+i; + item = new QStandardItem(QString::number(Year,'d',0)); + item->setTextAlignment(Qt::AlignCenter); + smodel4->setItem(i, 0, item); + for (int j=0; jgetScaleValueFromPlot(j,i); + stream << ", " << val; + item = new QStandardItem(QString::number(val,'f',3)); + item->setTextAlignment(Qt::AlignCenter); + smodel4->setItem(i, j+1, item); + } + stream << endl; + } + smodel4->setHorizontalHeaderLabels(HeaderList); + + stream << endl; + file.close(); + + // Attach the models to their table views + m_BiomassAbsTV->setModel(smodel1); + m_BiomassRelTV->setModel(smodel2); + m_FishingMortalityTV->setModel(smodel3); + m_HarvestScaleFactorTV->setModel(smodel4); + } +} + +void +nmfMainWindow::showMModeViewerDockWidget() +{ + MModeViewerDockWidget->show(); + m_UI->actionToggleManagerModeViewer->setChecked(true); + m_UI->actionOpenCSVFile->setEnabled(true); + + QList tabifiedWithViewer = this->tabifiedDockWidgets(MModeViewerDockWidget); + if (tabifiedWithViewer.size() > 0) { + MModeViewerDockWidget->raise(); + } +} void nmfMainWindow::menu_about() @@ -1966,16 +2291,21 @@ nmfMainWindow::callback_ReadProgressChartDataFile(bool validPointsOnly, } } - void nmfMainWindow::setupOutputViewerWidget() { // Setup viewer widget into tab QString imagePath = QDir(QString::fromStdString(m_ProjectDir)).filePath("outputImages"); m_ViewerWidget = new nmfViewerWidget(this,imagePath,m_Logger); - m_UI->MSSPMOutputScreenShotViewerTab->setLayout(m_ViewerWidget->mainLayt); -} + m_ViewerWidget->hideFrame(); + m_ViewerWidget->hideDataTab(); + QVBoxLayout* vlayt = new QVBoxLayout(); + vlayt->setContentsMargins(0,0,0,0); + vlayt->addWidget(m_ViewerWidget->getMainWidget()); + m_UI->MSSPMOutputScreenShotViewerTab->setLayout(vlayt); + m_UI->MSSPMOutputScreenShotViewerTab->setContentsMargins(0,0,0,0); +} void nmfMainWindow::setupProgressChart() @@ -2403,7 +2733,11 @@ nmfMainWindow::initConnections() this, SLOT(menu_exportAllDatabases())); connect(m_UI->actionToggleManagerMode, SIGNAL(triggered()), this, SLOT(menu_toggleManagerMode())); - + connect(m_UI->actionToggleManagerModeViewer, SIGNAL(triggered()), + this, SLOT(menu_toggleManagerModeViewer())); + connect(m_UI->actionOpenCSVFile, SIGNAL(triggered()), + this, SLOT(menu_openCSVFile())); + // Widget connections connect(NavigatorTree, SIGNAL(itemSelectionChanged()), this, SLOT(callback_NavigatorSelectionChanged())); @@ -2545,10 +2879,10 @@ nmfMainWindow::initConnections() this, SLOT(callback_EnableFilterButtons(bool))); connect(Output_Controls_ptr, SIGNAL(ShowChart(QString,QString)), this, SLOT(callback_ShowChart(QString,QString))); + connect(Output_Controls_ptr, SIGNAL(ShowChartBy(QString)), this, SLOT(callback_ShowChartBy(QString))); - connect(Output_Controls_ptr, SIGNAL(ShowChartBy(QString)), - this, SLOT(callback_ShowChartBy(QString))); + connect(Output_Controls_ptr, SIGNAL(ShowChartMultiScenario(QStringList)), this, SLOT(callback_ShowChartMultiScenario(QStringList))); connect(Output_Controls_ptr, SIGNAL(ShowDiagnosticsChart3d()), @@ -2562,13 +2896,15 @@ nmfMainWindow::initConnections() connect(Output_Controls_ptr, SIGNAL(ShowChartMohnsRho()), this, SLOT(callback_ShowChartMohnsRho())); connect(this, SIGNAL(KeyPressed(QKeyEvent*)), - MMode_Controls_ptr, SLOT(callback_keyPressed(QKeyEvent*))); + Remora_ptr, SLOT(callback_KeyPressed(QKeyEvent*))); connect(this, SIGNAL(MouseMoved(QMouseEvent*)), - MMode_Controls_ptr, SLOT(callback_mouseMoved(QMouseEvent*))); + Remora_ptr, SLOT(callback_MouseMoved(QMouseEvent*))); connect(this, SIGNAL(MouseReleased(QMouseEvent*)), - MMode_Controls_ptr, SLOT(callback_mouseReleased(QMouseEvent*))); - connect(MMode_Controls_ptr, SIGNAL(SaveOutputBiomassData(std::string)), + Remora_ptr, SLOT(callback_MouseReleased(QMouseEvent*))); + connect(Remora_ptr, SIGNAL(SaveOutputBiomassData(std::string)), this, SLOT(callback_SaveOutputBiomassData(std::string))); + connect(Remora_ptr, SIGNAL(UpdateSeedValue(int)), + this, SLOT(callback_UpdateSeedValue(int))); callback_Setup_Tab4_GrowthFormCMB("Null"); callback_Setup_Tab4_HarvestFormCMB("Null"); @@ -2637,7 +2973,6 @@ nmfMainWindow::keyPressEvent(QKeyEvent *event) void nmfMainWindow::mouseMoveEvent(QMouseEvent *event) { - std::cout << "nmfMainWindow mouse moved" << std::endl; emit MouseMoved(event); } @@ -2727,6 +3062,15 @@ nmfMainWindow::findTableInFocus() return MSYTV; } else if (FMSYTV->hasFocus()) { return FMSYTV; + + } else if (m_BiomassAbsTV->hasFocus()) { + return m_BiomassAbsTV; + } else if (m_BiomassRelTV->hasFocus()) { + return m_BiomassRelTV; + } else if (m_FishingMortalityTV->hasFocus()) { + return m_FishingMortalityTV; + } else if (m_HarvestScaleFactorTV->hasFocus()) { + return m_HarvestScaleFactorTV; } else { @@ -3447,19 +3791,45 @@ nmfMainWindow::loadUncertaintyData(const bool& isMonteCarlo, bool nmfMainWindow::scaleTimeSeries(const std::vector& Uncertainty, - boost::numeric::ublas::matrix& HarvestMatrix) + boost::numeric::ublas::matrix& HarvestMatrix, + std::vector& RandomValues) { int NumYears = HarvestMatrix.size1(); int NumSpecies = HarvestMatrix.size2(); + double RandomValue = 0; + RandomValues.clear(); for (int i=0; i 0) ? ++m_SeedValue : m_SeedValue; + randomValue = nmfUtils::getRandomNumber(m_SeedValue,-uncertainty,uncertainty); + retv = (1.0 + randomValue) * dataValue; +// retv = nmfUtils::getRandomNumber(m_SeedValue,dataValue*(1.0-uncertainty),dataValue*(1.0+uncertainty)); + } + + return retv; +} + + void nmfMainWindow::getMohnsRhoLabelsToDelete(const int& NumMohnsRhos, std::string &mohnsRhoLabelsToDelete) @@ -3483,6 +3853,44 @@ nmfMainWindow::getMohnsRhoLabelsToDelete(const int& NumMohnsRhos, } } + +bool +nmfMainWindow::clearMonteCarloParametersTable( + std::string& ForecastName, + std::string& Algorithm, + std::string& Minimizer, + std::string& ObjectiveCriterion, + std::string& Scaling, + std::string& MonteCarloParametersTable) +{ + std::string cmd=""; + std::string errorMsg; + + if (! isMohnsRho() && ! ForecastName.empty()) { + cmd = "DELETE FROM " + MonteCarloParametersTable + + " WHERE ForecastName = '" + ForecastName + + "' AND Algorithm = '" + Algorithm + + "' AND Minimizer = '" + Minimizer + + "' AND ObjectiveCriterion = '" + ObjectiveCriterion + + "' AND Scaling = '" + Scaling + + "'"; + errorMsg = m_DatabasePtr->nmfUpdateDatabase(cmd); + if (errorMsg != " ") { + m_Logger->logMsg(nmfConstants::Error,"[Error 1] clearMonteCarloParametersTable: DELETE error: " + errorMsg); + m_Logger->logMsg(nmfConstants::Error,"cmd: " + cmd); + QMessageBox::warning(this, "Error", + "\nError in clearMonteCarloParametersTable command:\n\n" + QString::fromStdString(errorMsg) + "\n", + QMessageBox::Ok); + return false; + } + } + + return true; +} + + + + // // Clear OutputBiomass table with passed Algorithm, Minimizer, ObjectiveCriterion, Scaling // @@ -3539,21 +3947,6 @@ nmfMainWindow::clearOutputBiomassTable(std::string& ForecastName, } -double -nmfMainWindow::calculateMonteCarloValue(const double& uncertainty, - const double& value) -{ - double randomVal = value; - - if (uncertainty != 0) { - m_SeedValue = (m_SeedValue > 0) ? ++m_SeedValue : m_SeedValue; - randomVal = nmfUtils::getRandomNumber(m_SeedValue,value*(1.0-uncertainty),value*(1.0+uncertainty)); - } - - return randomVal; -} - - bool nmfMainWindow::updateOutputBiomassTable(std::string& ForecastName, int& StartYear, @@ -3600,10 +3993,21 @@ nmfMainWindow::updateOutputBiomassTable(std::string& ForecastName, std::string queryStr; QStringList SpeciesList; QStringList GuildList; - std::vector EstGrowthRates; - std::vector EstCarryingCapacities; - std::vector EstExponent; - std::vector EstCatchabilityRates; + std::vector EstGrowthRates = {}; + std::vector EstCarryingCapacities = {}; + std::vector EstExponent = {}; + std::vector EstCatchabilityRates = {}; + std::vector HarvestRandomValues = {}; + std::vector GrowthRandomValues = {}; + std::vector CarryingCapacityRandomValues = {}; + std::vector CatchabilityRandomValues = {}; + std::vector ExponentRandomValues = {}; + std::vector CompetitionAlphaRandomValues = {}; + std::vector CompetitionBetaSpeciesRandomValues = {}; + std::vector CompetitionBetaGuildsRandomValues = {}; + std::vector PredationRandomValues = {}; + std::vector HandlingRandomValues = {}; + boost::numeric::ublas::matrix EstCompetitionAlpha; boost::numeric::ublas::matrix EstCompetitionBetaSpecies; boost::numeric::ublas::matrix EstCompetitionBetaGuilds; @@ -3623,6 +4027,7 @@ nmfMainWindow::updateOutputBiomassTable(std::string& ForecastName, double harvestTerm; double competitionTerm; double predationTerm; + double randomValue = 0.0; std::vector GrowthRateUncertainty; std::vector CarryingCapacityUncertainty; std::vector PredationUncertainty; @@ -3648,6 +4053,7 @@ nmfMainWindow::updateOutputBiomassTable(std::string& ForecastName, GuildList.clear(); exploitationRate.clear(); catchabilityRate.clear(); + HarvestRandomValues.clear(); // Find Guilds and Species if (! getGuilds(NumGuilds,GuildList)) { @@ -3676,6 +4082,7 @@ nmfMainWindow::updateOutputBiomassTable(std::string& ForecastName, CatchabilityUncertainty, HarvestUncertainty); if (! loadOK) { + m_Logger->logMsg(nmfConstants::Error, "[Error] nmfMainWindow::updateOutputBiomassTable: " + errorMsg); return false; } @@ -3711,26 +4118,34 @@ nmfMainWindow::updateOutputBiomassTable(std::string& ForecastName, if (TableNames[j] == GrowthRateTable) { for (int i=0; iHarvest Parameters tab.", + "\nError: No data found in Catch table for current Forecast.\nCheck Forecast->Harvest Parameters tab.", QMessageBox::Ok); return false; } } else { - if (! getTimeSeriesData(m_MohnsRhoLabel,ForecastName,"Catch", NumSpeciesOrGuilds,RunLength,Catch)) { + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,ForecastName,"Catch", + NumSpeciesOrGuilds,RunLength,Catch)) { QMessageBox::warning(this, "Error", - "\nError: No data found in ForecastCatch table for current Forecast.\nCheck Forecast->Harvest Parameters tab.", + "\nError: No data found in Catch table for current Forecast.\nCheck Forecast->Harvest Parameters tab.", QMessageBox::Ok); return false; } } if (isMonteCarlo) { - scaleTimeSeries(HarvestUncertainty,Catch); + scaleTimeSeries(HarvestUncertainty,Catch,HarvestRandomValues); + } else { + nmfUtils::initialize(HarvestRandomValues,NumSpeciesOrGuilds); } } else if (HarvestForm == "Effort (qE)") { if (isAggProd) { if (! getTimeSeriesDataByGuild(ForecastName,"Effort",NumSpeciesOrGuilds,RunLength,Effort)) return false; } else { - if (! getTimeSeriesData(m_MohnsRhoLabel,ForecastName,"Effort",NumSpeciesOrGuilds,RunLength,Effort)) + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,ForecastName,"Effort", + NumSpeciesOrGuilds,RunLength,Effort)) return false; } if (isMonteCarlo) { - scaleTimeSeries(HarvestUncertainty,Effort); + scaleTimeSeries(HarvestUncertainty,Effort,HarvestRandomValues); + } else { + nmfUtils::initialize(HarvestRandomValues,NumSpeciesOrGuilds); } } else if (HarvestForm == "Exploitation (F)") { if (isAggProd) { if (! getTimeSeriesDataByGuild(ForecastName,"Exploitation",NumSpeciesOrGuilds,RunLength,Exploitation)) return false; } else { - if (! getTimeSeriesData(m_MohnsRhoLabel,ForecastName,"Exploitation",NumSpeciesOrGuilds,RunLength,Exploitation)) + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,ForecastName,"Exploitation", + NumSpeciesOrGuilds,RunLength,Exploitation)) return false; } if (isMonteCarlo) { - scaleTimeSeries(HarvestUncertainty,Exploitation); + scaleTimeSeries(HarvestUncertainty,Exploitation,HarvestRandomValues); + } else { + nmfUtils::initialize(HarvestRandomValues,NumSpeciesOrGuilds); } } + // Update the Forecast Monte Carlo Parameters table + if (! m_DatabasePtr->updateForecastMonteCarloParameters( + 0,m_Logger, + ForecastName,Algorithm,Minimizer,ObjectiveCriterion,Scaling, + SpeciesList,RunNum, + GrowthRandomValues,CarryingCapacityRandomValues,CatchabilityRandomValues, + ExponentRandomValues,CompetitionAlphaRandomValues, + CompetitionBetaSpeciesRandomValues,CompetitionBetaGuildsRandomValues, + PredationRandomValues,HandlingRandomValues,HarvestRandomValues)) { + return false; + } + // If not running a forecast initial biomass is the first observed biomass. // else if running a forecast initial biomass is the last observed biomass. if (ForecastName == "") { @@ -3993,7 +4447,9 @@ nmfMainWindow::updateOutputBiomassTable(std::string& ForecastName, cmd = "INSERT INTO " + BiomassTable + " (ForecastName,RunNum,Algorithm,Minimizer,ObjectiveCriterion,Scaling,isAggProd,SpeName,Year,Value) VALUES "; for (int species=0; species nmfConstants::MaxBiomass) { EstimatedBiomassBySpecies(time,species) = -1; } cmd += "('" + ForecastName + "'," + std::to_string(RunNum) + @@ -4011,7 +4467,9 @@ nmfMainWindow::updateOutputBiomassTable(std::string& ForecastName, cmd = "INSERT INTO " + BiomassTable + " (ForecastName,Algorithm,Minimizer,ObjectiveCriterion,Scaling,isAggProd,SpeName,Year,Value) VALUES "; for (int species=0; species nmfConstants::MaxBiomass) { EstimatedBiomassBySpecies(time,species) = -1; } cmd += "('" + ForecastName + @@ -4416,7 +4874,9 @@ nmfMainWindow::callback_ShowChart(QString OutputType, return false; } } else { - if (! getTimeSeriesData(m_MohnsRhoLabel,"","ObservedBiomass",NumSpeciesOrGuilds,RunLength,ObservedBiomass)) { + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,"","ObservedBiomass", + NumSpeciesOrGuilds,RunLength,ObservedBiomass)) { return false; } } @@ -4465,7 +4925,9 @@ nmfMainWindow::callback_ShowChart(QString OutputType, } else if (OutputType == "Harvest vs Time") { // Load Catch - if (! getTimeSeriesData(m_MohnsRhoLabel,"","Catch",NumSpeciesOrGuilds,RunLength,Catch)) { + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,"","Catch", + NumSpeciesOrGuilds,RunLength,Catch)) { return false; } std::vector > CatchVec; @@ -4487,7 +4949,9 @@ nmfMainWindow::callback_ShowChart(QString OutputType, else if (OutputType == "Fishing Mortality vs Time") { // Load Catch - if (! getTimeSeriesData(m_MohnsRhoLabel,"","Catch",NumSpeciesOrGuilds,RunLength,Catch)) { + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,"","Catch", + NumSpeciesOrGuilds,RunLength,Catch)) { return false; } showChartTableVsTime("Fishing Mortality (C/Bc)", @@ -4531,16 +4995,16 @@ nmfMainWindow::callback_ShowChart(QString OutputType, boost::numeric::ublas::matrix -nmfMainWindow::getObservedBiomass(const int& NumGuilds, +nmfMainWindow::getObservedBiomassByGroup(const int& NumGuilds, const int& RunLength, - const std::string& type) + const std::string& group) { boost::numeric::ublas::matrix tmpObservedBiomass; boost::numeric::ublas::matrix ObservedBiomass; - if (type == "Guild") { + if (group == "Guild") { getTimeSeriesDataByGuild("","ObservedBiomass",NumGuilds,RunLength,ObservedBiomass); - } else if (type == "System") { + } else if (group == "System") { // Find total system observed biomass if (! getTimeSeriesDataByGuild("","ObservedBiomass",NumGuilds,RunLength,tmpObservedBiomass)) { return ObservedBiomass; @@ -4557,11 +5021,11 @@ nmfMainWindow::getObservedBiomass(const int& NumGuilds, } std::vector > -nmfMainWindow::getOutputBiomass2( +nmfMainWindow::getOutputBiomassByGroup( const int& NumLines, const int& RunLength, const std::vector >& OutputBiomassSpecies, - const std::string& type) + const std::string& group) { QStringList SpeciesList; QStringList GuildList; @@ -4579,7 +5043,7 @@ nmfMainWindow::getOutputBiomass2( if (! getSpeciesWithGuilds(NumSpecies,SpeciesList,GuildList)) return OutputBiomassGuilds; - if (type == "Guild") { + if (group == "Guild") { NumSpecies = SpeciesList.size(); for (unsigned i=0; i fields; - std::map > dataMap; - std::string queryStr; std::vector > ForecastBiomass; std::vector > ForecastBiomassMonteCarlo; QStringList SpeciesOrGuildList; @@ -5440,20 +5901,6 @@ nmfMainWindow::showForecastChart(const bool& isAggProd, } // Find Forecast info -// fields = {"ForecastName","Algorithm","Minimizer","ObjectiveCriterion","Scaling","GrowthForm","HarvestForm","WithinGuildCompetitionForm","PredationForm","RunLength","StartYear","EndYear","NumRuns"}; -// queryStr = "SELECT ForecastName,Algorithm,Minimizer,ObjectiveCriterion,Scaling,GrowthForm,HarvestForm,WithinGuildCompetitionForm,PredationForm,RunLength,StartYear,EndYear,NumRuns FROM Forecasts where "; -// queryStr += "ForecastName = '" + ForecastName + "'"; -// dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); -// if (dataMap["ForecastName"].size() != 0) { -// RunLength = std::stoi(dataMap["RunLength"][0]); -// StartForecastYear = std::stoi(dataMap["StartYear"][0]); -// // EndYear = std::stoi(dataMap["EndYear"][0]); -// Algorithm = dataMap["Algorithm"][0]; -// Minimizer = dataMap["Minimizer"][0]; -// ObjectiveCriterion = dataMap["ObjectiveCriterion"][0]; -// Scaling = dataMap["Scaling"][0]; -// NumRuns = std::stoi(dataMap["NumRuns"][0]); - // } if (! m_DatabasePtr->getForecastInfo( TableName,ForecastName,RunLength,StartForecastYear, Algorithm,Minimizer,ObjectiveCriterion,Scaling,NumRuns)) { @@ -5629,7 +6076,9 @@ nmfMainWindow::calculateSummaryStatistics(QStandardItemModel* smodel, return; } } else { - if (! getTimeSeriesData(m_MohnsRhoLabel,"","ObservedBiomass",NumSpeciesOrGuilds,RunLength,ObservedBiomass)) { + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,"","ObservedBiomass", + NumSpeciesOrGuilds,RunLength,ObservedBiomass)) { return; } } @@ -5834,6 +6283,7 @@ nmfMainWindow::showChartTableVsTime( QColor lineColor; bool xAxisIsInteger = true; QString colorName; + QStringList HoverLabels; ChartMSYData.resize(RunLength+1,1); // NumSpecies); ChartMSYData.clear(); @@ -5975,9 +6425,11 @@ nmfMainWindow::showChartTableVsTime( StartYear, xAxisIsInteger, YMinSliderVal, + nmfConstantsMSSPM::DontLeaveGapsWhereNegative, ChartMSYData, RowLabelsForBars, ColumnLabelsForLegend, + HoverLabels, MainTitle, XLabel, YLabel, @@ -6031,6 +6483,7 @@ nmfMainWindow::showDiagnosticsFitnessVsParameter( std::vector GridLines(true,true); // Replace with checkbox values double StartXValue = -Diagnostic_Tab1_ptr->getLastRunsPctVariation(); double XInc = -StartXValue/NumPoints; + QStringList HoverLabels; ChartType = "Line"; XLabel += " Percent Deviation"; @@ -6076,9 +6529,11 @@ nmfMainWindow::showDiagnosticsFitnessVsParameter( StartXValue, nmfConstantsMSSPM::LabelXAxisAsReals, YMinSliderVal, + nmfConstantsMSSPM::DontLeaveGapsWhereNegative, ChartLineData, RowLabelsForBars, ColumnLabelsForLegend, + HoverLabels, MainTitle, XLabel, YLabel, @@ -6137,6 +6592,7 @@ nmfMainWindow::showMohnsRhoBiomassVsTime( int NumColors; std::vector GridLines(true,true); // Replace with checkbox values std::vector StartYears; + QStringList HoverLabels; for (int i=0; i& formattedUncertaintyData) +{ + int RunLength; + int NumRuns; + int NumRecords; + int StartForecastYear; + std::vector fields; + std::map > dataMap; + std::string Algorithm; + std::string Minimizer; + std::string ObjectiveCriterion; + std::string Scaling; + std::string queryStr; + std::string TableName = "Forecasts"; + std::string ForecastName = Forecast_Tab1_ptr->getForecastName(); + std::string str; + + if (! m_DatabasePtr->getForecastInfo( + TableName,ForecastName,RunLength,StartForecastYear, + Algorithm,Minimizer,ObjectiveCriterion,Scaling,NumRuns)) { + return; + } + + fields = {"ForecastName","RunNum","SpeName","Algorithm","Minimzer", + "ObjectiveCriterion","Scaling","GrowthRate", + "CarryingCapacity","Harvest"}; + queryStr = "SELECT ForecastName,RunNum,SpeName,Algorithm,Minimizer,ObjectiveCriterion,Scaling,GrowthRate,CarryingCapacity,Harvest "; + queryStr += "FROM ForecastMonteCarloParameters WHERE ForecastName = '" + ForecastName + + "' AND SpeName = '" + Species.toStdString() + + "' AND Algorithm = '" + Algorithm + + "' AND Minimizer = '" + Minimizer + + "' AND ObjectiveCriterion = '" + ObjectiveCriterion + + "' AND Scaling = '" + Scaling + + "' ORDER BY RunNum,SpeName"; + dataMap = m_DatabasePtr->nmfQueryDatabase(queryStr, fields); + NumRecords = dataMap["SpeName"].size(); + if (NumRecords < NumRuns) { + m_Logger->logMsg(nmfConstants::Error,"Couldn't find sufficient uncertainty records in ForecastMonteCarloParameters"); + for (int i=0; i GridLines(true,true); // Replace with checkbox values - + QStringList HoverLabels; + QList formattedUncertaintyData; ChartType = "Line"; MainTitle = ChartTitle + " for: " + OutputSpecies.toStdString(); @@ -6281,12 +6801,19 @@ nmfMainWindow::showForecastBiomassVsTime( m_ChartWidget->removeAllSeries(); } + formattedUncertaintyData << "(0%, 0%, 0%)"; + if (isMonteCarloSimulation) { + getMonteCarloUncertaintyData(OutputSpecies,formattedUncertaintyData); + } + ChartLineData.clear(); for (int line=0; linesetHorizontalHeaderLabels(SpeciesNames); @@ -6467,6 +6997,7 @@ nmfMainWindow::showChartBiomassVsTime( std::vector GridLines(true,true); // Replace with checkbox values bool xAxisIsInteger = true; int NumLineColors = nmfConstants::LineColors.size(); + QStringList HoverLabels; ChartType = "Line"; MainTitle = "Calculated Biomass Overlayed with Observed Biomass Points for: " + OutputSpecies.toStdString(); @@ -6584,9 +7115,11 @@ nmfMainWindow::showChartBiomassVsTime( StartYear, xAxisIsInteger, YMinSliderVal, + nmfConstantsMSSPM::DontLeaveGapsWhereNegative, ChartBMSYData, RowLabelsForBars, ColumnLabelsForLegend, + HoverLabels, MainTitle, XLabel, YLabel, @@ -6656,6 +7189,7 @@ nmfMainWindow::showChartBcVsTimeSelectedSpecies(QList &RowNumList, QStandardItem *item; QList LineColors; double YMinSliderVal = -1; + QStringList HoverLabels; if (NumSpecies == 0) { m_ChartWidget->removeAllSeries(); @@ -6697,9 +7231,11 @@ nmfMainWindow::showChartBcVsTimeSelectedSpecies(QList &RowNumList, 0, false, YMinSliderVal, + nmfConstantsMSSPM::DontLeaveGapsWhereNegative, SelectedSpeciesCalculatedBiomassData, RowLabelsForBars, ColumnLabelsForLegend, + HoverLabels, MainTitle, XLabel, YLabel, @@ -6743,6 +7279,7 @@ nmfMainWindow::showChartBcVsTimeAllSpecies( std::string LineStyle = "SolidLine"; double biomassData; double YMinSliderVal = -1; + QStringList HoverLabels; m = 0; double val; @@ -6787,9 +7324,11 @@ nmfMainWindow::showChartBcVsTimeAllSpecies( 0, false, YMinSliderVal, + nmfConstantsMSSPM::DontLeaveGapsWhereNegative, m_SpeciesCalculatedBiomassData, RowLabelsForBars, ColumnLabelsForLegend, + HoverLabels, MainTitle, XLabel, YLabel, @@ -6900,8 +7439,122 @@ nmfMainWindow::showChartCatchVsBc( void nmfMainWindow::initializeMMode() +{ + initializeMModeMain(); + initializeMModeViewer(); +} + +void +nmfMainWindow::initializeMModeViewer() +{ + int NumSpecies; + int RunLength; + int StartYear; + QStringList SpeciesList; + QString imagePath = QDir(QString::fromStdString(m_ProjectDir)).filePath(QString::fromStdString(nmfConstantsMSSPM::OutputImagesDirMMode)); + m_MModeViewerWidget = new nmfViewerWidget(this,imagePath,m_Logger); + + MModeViewerDockWidget = new QDockWidget(this); + MModeViewerDockWidget->setWidget(m_MModeViewerWidget->getMainWidget()); + MModeViewerDockWidget->setObjectName("VIEWMORA"); + MModeViewerDockWidget->setAccessibleName("Viewmora"); + addDockWidget(Qt::RightDockWidgetArea, MModeViewerDockWidget); + + // Setup viewer's initial position and size + MModeViewerDockWidget->setFloating(true); + int x = this->x() + (9.0/16.0)*this->width(); + int y = this->y() - (1.0/16.0)*this->height(); + MModeViewerDockWidget->setGeometry(x,y,this->width()/2,this->height()); + // MModeViewerDockWidget->setStyleSheet("QDockWidget#Viewmora {border: 10px solid red}"); + + MModeViewerDockWidget->hide(); + MModeViewerDockWidget->setWindowTitle("Viewmora"); + MModeViewerDockWidget->setContextMenuPolicy(Qt::CustomContextMenu); + + connect(MModeViewerDockWidget, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(callback_openCSVFile(QPoint))); + + + // Set a custom title for the Remora Viewer dock widget + QWidget* customTitleBar = new QWidget(); + QHBoxLayout* hlayt = new QHBoxLayout; + QPushButton* quitPB = new QPushButton("X"); + quitPB->setFlat(true); + quitPB->setFixedWidth(25); + quitPB->setToolTip("Close REMORA Viewer"); + hlayt->addSpacerItem(new QSpacerItem(25,1,QSizePolicy::Fixed,QSizePolicy::Fixed)); + hlayt->addSpacerItem(new QSpacerItem(2,1,QSizePolicy::Expanding,QSizePolicy::Fixed)); + QLabel* title = new QLabel("VIEWMORA (REMORA Image and Data Viewer)"); + QFont titleFont = title->font(); + titleFont.setPointSize(titleFont.pointSize()+4); + title->setFont(titleFont); + hlayt->addWidget(title); + hlayt->addSpacerItem(new QSpacerItem(2,1,QSizePolicy::Expanding,QSizePolicy::Fixed)); + hlayt->addWidget(quitPB); + customTitleBar->setLayout(hlayt); + MModeViewerDockWidget->setTitleBarWidget(customTitleBar); + + connect(quitPB, SIGNAL(clicked(bool)), + this, SLOT(callback_ManagerModeViewerClose(bool))); + + m_BiomassAbsTV = new QTableView(); + m_BiomassRelTV = new QTableView(); + m_FishingMortalityTV = new QTableView(); + m_HarvestScaleFactorTV = new QTableView(); + + if (! getSpecies(NumSpecies,SpeciesList)) + return; + if (! m_DatabasePtr->getRunLengthAndStartYear(m_Logger,m_ProjectSettingsConfig,RunLength,StartYear)) { + return; + } + + QStandardItemModel* smodel1 = new QStandardItemModel(RunLength,NumSpecies+1 ); // +1 for Year (1st column) + QStandardItemModel* smodel2 = new QStandardItemModel(RunLength,NumSpecies+1 ); + QStandardItemModel* smodel3 = new QStandardItemModel(RunLength,NumSpecies+1 ); + QStandardItemModel* smodel4 = new QStandardItemModel(RunLength,NumSpecies+1 ); + m_BiomassAbsTV->setModel(smodel1); + m_BiomassRelTV->setModel(smodel2); + m_FishingMortalityTV->setModel(smodel3); + m_HarvestScaleFactorTV->setModel(smodel4); + + m_MModeViewerWidget->addDataTab("Biomass (absolute)", m_BiomassAbsTV); + m_MModeViewerWidget->addDataTab("Biomass (relative)", m_BiomassRelTV); + m_MModeViewerWidget->addDataTab("Fishing Mortality", m_FishingMortalityTV); + m_MModeViewerWidget->addDataTab("Harvest Scale Factor",m_HarvestScaleFactorTV); + +} + +void +nmfMainWindow::callback_openCSVFile(QPoint pos) +{ + QMenu contextMenu("", MModeViewerDockWidget); + QAction actionOpenCSVFile("Open CSV File...", this); + actionOpenCSVFile.setToolTip("Open CSV File associated with current image"); + actionOpenCSVFile.setStatusTip("Open CSV File associated with current image"); + + connect(&actionOpenCSVFile, SIGNAL(triggered()), + this, SLOT(menu_openCSVFile())); + + contextMenu.addAction(&actionOpenCSVFile); + contextMenu.exec(MModeViewerDockWidget->mapToGlobal(pos)); +} + +void +nmfMainWindow::callback_ManagerModeViewerClose(bool state) +{ + m_MModeViewerWidget->stopPlayback(); + MModeDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + menu_toggleManagerModeViewer(); +} + +void +nmfMainWindow::initializeMModeMain() { QUiLoader loader; + int NumSpecies; + QStringList SpeciesList; + + getSpecies(NumSpecies,SpeciesList); // Initialize MModeDockWidget QFile file(":/forms/MMode/mModeWindow.ui"); @@ -6909,6 +7562,7 @@ nmfMainWindow::initializeMMode() QWidget* MModeWidget = loader.load(&file,this); file.close(); + // Set up main REMORA dock widget MModeDockWidget = new QDockWidget(this); MModeDockWidget->setWidget(MModeWidget); //MModeDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); @@ -6919,8 +7573,8 @@ nmfMainWindow::initializeMMode() mmodeFont.setPointSize(12); mmodeFont.setBold(true); - MModeDockWidget->hide(); + MModeDockWidget->setWindowTitle("REMORA"); // Set a custom title for the Remora dock widget QWidget* customTitleBar = new QWidget(); @@ -6935,9 +7589,61 @@ nmfMainWindow::initializeMMode() customTitleBar->setLayout(hlayt); MModeDockWidget->setTitleBarWidget(customTitleBar); + Remora_ptr = new REMORA(m_DatabasePtr,m_Logger,m_ProjectDir, + m_ProjectSettingsConfig,SpeciesList,MModeWidget); +} + +QMenu* +nmfMainWindow::createPopupMenu() +{ + QStringList actionNames = {"Navigator","Progress","Log","Output"}; + QMenu* popupMenu = new QMenu(); + + for (QString actionName : actionNames) { + QAction* action = new QAction(actionName); + action->setCheckable(true); + setDefaultDockWidgetsVisibility(actionName,action); + popupMenu->addAction(action); + connect(action, SIGNAL(triggered(bool)), + this, SLOT(context_Action(bool))); + } + + return popupMenu; +} - MMode_Controls_ptr = new MSSPM_GuiManagerMode( - m_DatabasePtr, m_Logger, m_ProjectSettingsConfig, MModeWidget); +void +nmfMainWindow::setDefaultDockWidgetsVisibility( + const QString& actionName, + QAction* action) +{ + if (actionName == "Navigator") { + action->setChecked(m_UI->NavigatorDockWidget->isVisible()); + } else if (actionName == "Progress") { + action->setChecked(m_UI->ProgressDockWidget->isVisible()); + } else if (actionName == "Log") { + action->setChecked(m_UI->LogDockWidget->isVisible()); + } else if (actionName == "Output") { + action->setChecked(m_UI->OutputDockWidget->isVisible()); + } + this->tabifyDockWidget(m_UI->LogDockWidget, m_UI->ProgressDockWidget); +} + +void +nmfMainWindow::context_Action(bool triggered) +{ + QString actionName = qobject_cast(QObject::sender())->text(); + QAction* action = qobject_cast(QObject::sender()); + if (actionName == "Navigator") { + m_UI->NavigatorDockWidget->setVisible(triggered); + } else if (actionName == "Progress") { + m_UI->ProgressDockWidget->setVisible(triggered); + } else if (actionName == "Log") { + m_UI->LogDockWidget->setVisible(triggered); + } else if (actionName == "Output") { + m_UI->OutputDockWidget->setVisible(triggered); + } + action->setChecked(triggered); + this->tabifyDockWidget(m_UI->LogDockWidget, m_UI->ProgressDockWidget); } void @@ -7263,6 +7969,9 @@ nmfMainWindow::readSettings(QString Name) } else if (Name == "LogDockWidgetIsVisible") { //ui->LogDockWidget->setVisible(settings->value("LogDockWidgetIsVisible",false).toBool()); } +//std::cout << "resizing (h,w): " << settings->value("CentralWidgetSize", QSize(400, 400)).toSize().height() << ", " +// << settings->value("CentralWidgetSize", QSize(400, 400)).toSize().width() << std::endl; +// centralWidget()->resize(settings->value("CentralWidgetSize", QSize(400, 400)).toSize()); settings->endGroup(); if (Name == "Preferences") { @@ -7276,13 +7985,15 @@ nmfMainWindow::readSettings(QString Name) } void -nmfMainWindow::readSettingsGuiPositionOrientationOnly() +nmfMainWindow::readSettingsGuiOrientation(bool alsoResetPosition) { QSettings* settings = nmfUtilsQt::createSettings(nmfConstantsMSSPM::SettingsDirWindows,"MSSPM"); settings->beginGroup("MainWindow"); resize(settings->value("size", QSize(400, 400)).toSize()); - move(settings->value("pos", QPoint(200, 200)).toPoint()); + if (alsoResetPosition) { + move(settings->value("pos", QPoint(200, 200)).toPoint()); + } // Resize the dock widgets int NavDockWidth = settings->value("NavigatorDockWidgetWidth",200).toInt(); @@ -7361,6 +8072,7 @@ nmfMainWindow::saveSettings() { settings->setValue("OutputDockWidgetIsFloating", m_UI->OutputDockWidget->isFloating()); settings->setValue("OutputDockWidgetPos", m_UI->OutputDockWidget->pos()); settings->setValue("OutputDockWidgetSize", m_UI->OutputDockWidget->size()); +// settings->setValue("CentralWidgetSize", centralWidget()->size()); settings->endGroup(); settings->beginGroup("SetupTabIsVisible"); @@ -7602,6 +8314,7 @@ nmfMainWindow::callback_SaveOutputBiomassData(std::string ForecastName) std::string CatchabilityTable = "OutputCatchability"; std::string BiomassTable = "ForecastBiomass"; std::string BiomassMonteCarloTable = "ForecastBiomassMonteCarlo"; + std::string MonteCarloParametersTable = "ForecastMonteCarloParameters"; // Find Forecast info fields = {"ForecastName","Algorithm","Minimizer","ObjectiveCriterion","Scaling","GrowthForm","HarvestForm","WithinGuildCompetitionForm","PredationForm","RunLength","StartYear","EndYear","NumRuns"}; @@ -7630,6 +8343,9 @@ nmfMainWindow::callback_SaveOutputBiomassData(std::string ForecastName) clearOutputBiomassTable(ForecastName,Algorithm,Minimizer, ObjectiveCriterion,Scaling, isAggProdStr,BiomassMonteCarloTable); + clearMonteCarloParametersTable(ForecastName,Algorithm,Minimizer, + ObjectiveCriterion,Scaling, + MonteCarloParametersTable); for (RunNum=0; RunNumsetDeterministic(isDeterministic); +} + + void nmfMainWindow::callback_RunForecast(std::string ForecastName, bool GenerateBiomass) @@ -7689,7 +8413,11 @@ nmfMainWindow::callback_RunForecast(std::string ForecastName, QString ScaleStr = ""; double YMinSliderValue = Output_Controls_ptr->getYMinSliderVal(); - m_SeedValue = Forecast_Tab1_ptr->getSeed(); + if (runningREMORA()) { + m_SeedValue = (Remora_ptr->isDeterministic()) ? 1 : -1; + } else { + m_SeedValue = Forecast_Tab1_ptr->getSeed(); + } // Turn on wait cursor QApplication::setOverrideCursor(Qt::WaitCursor); @@ -9167,25 +9895,33 @@ nmfMainWindow::loadParameters(Data_Struct &dataStruct, const bool& verbose) } if (harvestForm == "Catch") { - if (! getTimeSeriesData(m_MohnsRhoLabel,"","Catch",NumSpecies,RunLength,dataStruct.Catch)) + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,"","Catch", + NumSpecies,RunLength,dataStruct.Catch)) return false; if (verbose) { m_Logger->logMsg(nmfConstants::Normal,"LoadParameters Read: Catch"); } } else if (harvestForm == "Effort (qE)") { - if (! getTimeSeriesData(m_MohnsRhoLabel,"","Effort",NumSpecies,RunLength,dataStruct.Effort)) + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,"","Effort", + NumSpecies,RunLength,dataStruct.Effort)) return false; if (verbose) { m_Logger->logMsg(nmfConstants::Normal,"LoadParameters Read: Effort"); } } else if (harvestForm == "Exploitation (F)") { - if (! getTimeSeriesData(m_MohnsRhoLabel,"","Exploitation",NumSpecies,RunLength,dataStruct.Exploitation)) + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,"","Exploitation", + NumSpecies,RunLength,dataStruct.Exploitation)) return false; if (verbose) { m_Logger->logMsg(nmfConstants::Normal,"LoadParameters Read: Exploitation"); } } - if (! getTimeSeriesData(m_MohnsRhoLabel,"","ObservedBiomass",NumSpecies,RunLength,dataStruct.ObservedBiomassBySpecies)) { + if (! m_DatabasePtr->getTimeSeriesData(this,m_Logger,m_ProjectSettingsConfig, + m_MohnsRhoLabel,"","ObservedBiomass", + NumSpecies,RunLength,dataStruct.ObservedBiomassBySpecies)) { return false; } diff --git a/MSSPM_Main/nmfMainWindow.h b/MSSPM_Main/nmfMainWindow.h index 4189826a..dbfff3dd 100644 --- a/MSSPM_Main/nmfMainWindow.h +++ b/MSSPM_Main/nmfMainWindow.h @@ -94,7 +94,8 @@ #include #include -#include "MSSPM_GuiManagerMode.h" + +#include "REMORA.h" //class Gradient_Estimator; @@ -212,6 +213,10 @@ class nmfMainWindow : public QMainWindow nmfViewerWidget* m_ViewerWidget; // QString m_outputFile; bool m_isStartUpOK; + QTableView* m_BiomassAbsTV; + QTableView* m_BiomassRelTV; + QTableView* m_FishingMortalityTV; + QTableView* m_HarvestScaleFactorTV; QBarSeries* ProgressBarSeries; QBarSet* ProgressBarSet; @@ -237,7 +242,8 @@ class nmfMainWindow : public QMainWindow // QSurface3DSeries* SurfaceSeries; QWidget* NavigatorTreeWidget; QTreeWidget* NavigatorTree; - QDockWidget* MModeDockWidget; + QDockWidget* MModeDockWidget; + QDockWidget* MModeViewerDockWidget; nmfDiagnostic_Tab1* Diagnostic_Tab1_ptr; nmfDiagnostic_Tab2* Diagnostic_Tab2_ptr; @@ -252,7 +258,7 @@ class nmfMainWindow : public QMainWindow nmfForecast_Tab3* Forecast_Tab3_ptr; nmfForecast_Tab4* Forecast_Tab4_ptr; MSSPM_GuiOutputControls* Output_Controls_ptr; - MSSPM_GuiManagerMode* MMode_Controls_ptr; + REMORA* Remora_ptr; nmfSetup_Tab1* Setup_Tab1_ptr; nmfSetup_Tab2* Setup_Tab2_ptr; nmfSetup_Tab3* Setup_Tab3_ptr; @@ -263,6 +269,12 @@ class nmfMainWindow : public QMainWindow QWidget* m_TableNamesWidget; QTabWidget* m_EstimatedParametersTW; std::map m_EstimatedParametersMap; + nmfViewerWidget* m_MModeViewerWidget; + QTabWidget* MModeViewerTBW; + QTabWidget* MModeViewerDataSubTab; + QWidget* MModeViewerImageTB; + QWidget* MModeViewerDataTB; + QWidget* MModeViewerTab1; // Gradient_Struct gradientStruct; // int RunNumGenetic; @@ -282,6 +294,13 @@ class nmfMainWindow : public QMainWindow std::string minimizer, std::string objectiveCriterion, std::string scaling); + bool clearMonteCarloParametersTable( + std::string& ForecastName, + std::string& Algorithm, + std::string& Minimizer, + std::string& ObjectiveCriterion, + std::string& Scaling, + std::string& MonteCarloParametersTable); double convertUnitsStringToValue(QString& ScaleStr); int getNumDistinctRecords(const std::string& field, const std::string& table); @@ -291,9 +310,11 @@ class nmfMainWindow : public QMainWindow void initPostGuiConnections(); void initializePreferencesDlg(); void initializeTableNamesDlg(); - void initializeMMode(); + void initializeMMode(); + void initializeMModeMain(); + void initializeMModeViewer(); + bool runningREMORA(); void showDockWidgets(bool show); -// void screenShot(); QList getTableNames(bool isExponent); void adjustProgressWidget(); @@ -303,7 +324,8 @@ class nmfMainWindow : public QMainWindow std::string system, std::vector fields); double calculateMonteCarloValue(const double& uncertainty, - const double& value); + const double& value, + double& randomValue); bool calculateMSYValues( const bool& isAggProdStr, const int& NumLines, @@ -356,7 +378,10 @@ class nmfMainWindow : public QMainWindow std::string& scaling, std::string& competitionForm); QString getCurrentStyle(); - + bool getForecastInitialData( + QString& forecastName, + int& numYearsPerRun, + int& numRunsPerForecast); bool getSystemDataForChart( int& StartYear, int& RunLength, @@ -430,13 +455,13 @@ class nmfMainWindow : public QMainWindow QStringList& ForecastLabels, std::vector >& MultiScenarioBiomass); int getNumLines(); - boost::numeric::ublas::matrix getObservedBiomass( + boost::numeric::ublas::matrix getObservedBiomassByGroup( const int& NumGuilds, const int& RunLength, const std::string& type); std::vector > - getOutputBiomass2( + getOutputBiomassByGroup( const int& NumLines, const int& RunLength, const std::vector >& OutputBiomassSpecies, @@ -476,6 +501,15 @@ class nmfMainWindow : public QMainWindow const int& NumSpecies, const int& RunLength, boost::numeric::ublas::matrix &Catch); + /** + * @brief Gets the formatted string describing what uncertainty + * values were used for each Monte Carlo curve for the given species. + * @param Species : current species whose curve is displayed + * @param formattedUncertaintyData : list of qstrings describing the uncertainty values used to create each Monte Carlo curve + */ + void getMonteCarloUncertaintyData( + const QString& Species, + QList& formattedUncertaintyData); void initConnections(); void initGUIs(); bool isAggProd(); @@ -555,15 +589,18 @@ class nmfMainWindow : public QMainWindow void queryUserPreviousDatabase(); void readSettings(QString name); void readSettings(); - void readSettingsGuiPositionOrientationOnly(); + void readSettingsGuiOrientation(bool alsoResetPosition); void runBeesAlgorithm(bool showDiagnosticsChart); void runNextMohnsRhoEstimation(); void runNLoptAlgorithm(bool showDiagnosticChart); + void saveRemoraDataFile(QString filename); bool saveScreenshot(QString &outputfile, QPixmap &pm); void saveSettings(); bool scaleTimeSeries(const std::vector& Uncertainty, - boost::numeric::ublas::matrix& HarvestMatrix); + boost::numeric::ublas::matrix& HarvestMatrix, + std::vector& RandomValues); void setCurrentOutputTab(QString outputTab); + void setVisibilityToolbarButtons(bool isVisible); void setDefaultDockWidgetsVisibility(); void setNumLines(int numLines); void setup2dChart(); @@ -676,6 +713,7 @@ class nmfMainWindow : public QMainWindow bool useDimColor, bool clearChart, QStringList ColumnLabelsForLegend); + void showMModeViewerDockWidget(); void updateDiagnosticSummaryStatistics(); bool updateOutputBiomassTable(std::string& ForecastName, int& StartYear, @@ -742,6 +780,10 @@ class nmfMainWindow : public QMainWindow */ void updateWindowTitle(); + void setDefaultDockWidgetsVisibility( + const QString& actionName, + QAction* action); + // bool isThereMohnsRhoData(); // bool loadGradientParameters(Gradient_Struct &gradientStruct); // void simulateBiomass(double &growthRate, @@ -797,8 +839,17 @@ class nmfMainWindow : public QMainWindow bool eventFilter(QObject *object, QEvent *event); void keyPressEvent(QKeyEvent *event); void mouseMoveEvent(QMouseEvent *event); + /** + * @brief Need to prevent Remora's window from appearing in main window's so have + * to create custom popupMenu. + * @return Custom context menu + * + */ + QMenu* createPopupMenu(); public slots: + + void callback_UpdateSeedValue(int isDeterministic); /** * @brief Callback invoked when user Runs an Estimation */ @@ -1036,9 +1087,9 @@ public slots: void callback_PreferencesSetStyleSheet(QString style); /** * @brief Callback invoked when user changes the chart group type - * @param type : type of chart grouping desired: species, guild, system + * @param groupType : type of chart grouping desired: species, guild, system */ - void callback_ShowChartBy(QString type); + void callback_ShowChartBy(QString groupType); /** * @brief Callback invoked when user is modifying the Population Parameters and needs to * store the current value of the Output widget's species @@ -1064,6 +1115,11 @@ public slots: * @brief Callback invoked to update the Model Equation in the Setup page 4 summary text box */ void callback_UpdateModelEquationSummary(); + + void callback_openCSVFile(QPoint pos); + void context_Action(bool triggered); + + /** * @brief Raises an About MSSPM Dialog * @@ -1119,6 +1175,10 @@ public slots: * @brief Change the Application layout to one with the Output window torn off and placed to the side */ void menu_layoutOutput(); + /** + * @brief Open the CSV file that's associated with the current image file displayed in the REMORA viewer + */ + void menu_openCSVFile(); /** * @brief Pastes the previously copied or cleared table cells */ @@ -1208,10 +1268,12 @@ public slots: */ void menu_whatsThis(); void menu_toggleManagerMode(); + void menu_toggleManagerModeViewer(); void callback_TableNamesOkPB(); void callback_PreferencesMShotOkPB(); void callback_ErrorFound(std::string errorMsg); + void callback_ManagerModeViewerClose(bool state); // /** // * @brief Copy TestData into OutputGrowthRate diff --git a/MSSPM_Main/nmfMainWindow.ui b/MSSPM_Main/nmfMainWindow.ui index 105e173a..9e1c59c7 100644 --- a/MSSPM_Main/nmfMainWindow.ui +++ b/MSSPM_Main/nmfMainWindow.ui @@ -110,6 +110,7 @@ &File + @@ -121,7 +122,6 @@ - @@ -174,6 +174,7 @@ + @@ -710,8 +711,14 @@ p, li { white-space: pre-wrap; } &What's This? + + Point and Click Help Feature (called "What's This?") + - What's This? + Point and Click Help Feature (called "What's This?") + + + Point and Click Help Feature (called "What's This?") @@ -728,7 +735,10 @@ p, li { white-space: pre-wrap; } - What's This? + Point and Click Help Feature (called "What's This?") + + + Point and Click Help Feature (called "What's This?") <html><head/><body><p align="center"><span style=" font-weight:600;">WhatsThis? Help</span></p><p>This is the WhatsThis? help functionality available in this application. Selecting this feature will transform the cursor into a WhatsThis? cursor. As the user hovers this transformed cursor over an object that has additional &quot;WhatsThis?&quot; help implemented, the cursor shape will change to a question mark with an arrow which signifies additional popup help will appear once the user clicks over the object.</p></body></html> @@ -869,13 +879,47 @@ p, li { white-space: pre-wrap; } + + true + - Toggle REMORA Management Tool + &REMORA Management Tool + + + Toggles On/Off the REMORA Management Tool Ctrl+R + + + true + + + REMORA Vie&wer + + + Toggles On/Off the REMORA Viewer + + + Ctrl+W + + + + + false + + + Open CSV File... + + + Open VIEWMORA CSV File + + + Open REMORA CSV File + + diff --git a/docs/QuickStart_Guide_MSSPM.pdf b/docs/QuickStart_Guide_MSSPM.pdf index 94d84d74e03c7a41b7b58ebe97bb4adf445fd677..78de08e136a899f4bd6e20f169df2234402edf25 100644 GIT binary patch delta 98598 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
  • +~JB>_rsJ8svjL zb+o)5u>!$^CWH{CUF%@QI!n-IE|ez}4-0M>Y?a3R3blR=Yo}skBCdz5IELXHaHNPz z^A9aS0+ld50ZAFH;K;_Qu;gdw4cf++(HGyNUwDVz3o#vh6pY{}B{B2A>-`fqcb0HZ z0Gcj@E0y-!e;muoEEf8PTtLw}0v2b#h#n;F7FQ~5{v!4NH{_crXdy8jWKJmhxth}L3q8}02aBHpit^4(n-g+Kn+ zoo=6E#LhEUT_N(1D19ihH^#y9@9)*VaKM#l{G)2z8o#n4;ByFm+Z08(^W{5N|7WAu zx4WFo7U~Evb9>2plF;_ls5n`{yUlBbNkH`Qd+WU|1E7{dgU8+Wda*EIH zD}kRV2su|Z5FM1N_6Q`e+^NZ(BEo)%I1RX*{GnxC|`!oC8!OSW432-G7?srCx|D1#q(?r zN}*7QrRDMKh13J2 zD}*LTHHeIyK}qMgm16&DUGKDw?&)_GZQ5=E<4EYeMucKK&B7dL)C4*=B&%hOrjUxWn`Tuvb% zUPn0wXuQISv8mHr2XY#zu!gSUBtw->wo11NpkxY>Zkgr%V=kDTEU8oo5HKzEFSgGd zYcuN*(x|WaZfl>Xc=wix0A2qxwyE(`&6QFUcC7ZzL*M+(eY>*0m#m$GflZ&Qg8km#=7^h|&niw9c zNh_ZayImk9OQux`hC^RI_uxnV;^&OJQawZd))9qb@eThA#6P%y^TKiMg;s49)ahBj zer)X`YdAzAb!guyXw|B}NSxQIHIs7y$&CJ<-+CQsw$BE*ezZLs#l;iHy@`hryy8g9 zH;O6dm*FN_uX4;O?5WvRs)b7qQ4_4&r|1b&2^n;fR9zU+{aJ6QV6t4UUa$O<5ld|C z#X%E|vR!`mV%mCk7oXR-1ck8pZaMzgxc_qFxqjd9 zbiLmEM|2IilDST>8|7cUGq1Cy8ov4=h?(8E?W}G*H83<0I!(PVVAWVyn0{5=?7vv> zUBEt4J3qoRJ=u+l7G+Q*OK?3hCkM*1U@29_{)y>94HRvD)BG51QYZ~&QYZkIOd0`h zWH|9#z*|1CwQ|#|a~z!w<^Nw`d3rg8tT^4s4S@U<9t4QTmhP9REg8ZCC~)`EFX8ae z5H1}mW*yp@@>;Y#k*R>H|6;T15N6-XB5OFe;&1*1D=L5m@Sj@ls|vmKi)2_qOZ4#9 z5$qAyz(TfX=rsP$F>~){~7;PyD$f&6c#rZ533^atbPdPHM0Z)FwKGS zIoAmK#58Bj3aSbA2y+G%D1rGbn?VW_AG_E1EC-i8TuYwC*$%p|;PM~mYb&M>p%McP zS?yGQnuAy|{0!-E!kUE%twjO>PO{>@K>SqBeYxYwzIvW=t3W$e{u|80)BELi>aKL<#~hbbPAEJOnvcS%^J;nc=8j z;D{{2tt^>x^;)7w>Bq<2|BlX(Ek?A5%?-)sVkP-7=!tYY2`PaVM;F9d%jE2|upD#_ z&Vi?M(BHKy4Nv6)=YFv3L$Rq;$JETkA|ly8-MB*EhUXj z6CS=$@zhUg`qw2bLDs@*)X?%K>_S5erUBk^(rF}b?F#$BG{7d6w2gBwNypYz{AF%c zlqvO}k;~Kdzur24F2H1ZiaRZ<4Cb3JE#BtrYJ}kZy^DHt3-|*qj^!ZUv!jLQe>qCB zv3A9;qF?-ZbOGWozMC>kou<>-o1D0tz$00Po;aJIWDcGu{|M$}KRN3_T(2IQp594Z z1PDeSqn@6BGANH?Tm`v$-;rIq%+~-u{~2EGc5DIP%e?-~b=F-rJpTU9bPFif*F|2p z`7E|dhZE=lzYM+#XcmO$=T%*xH^Z3NuCXn-crVJ!hXs^8WXufA@UGg$cFRBUe44+q zaP%LZoX1FRyg#5F+Rjvveg8QlT~Sp(f}hh_u;qVaesaz%k^S7~TYadCflB@vnHQ~% z8Hh&Pw^jk1KA)ZsSsz++4VZ`In8<%oJp6jVdWgMJ^#aNi`r?|yL{tT}LTx;n-+KYH z@%nq;XL2-dFM(pl=HR1Z+{~F>EBi%Txcj zRleREXp~UFqRxMG=Lykw`K8yP%pIQD7MMSL!C(W5Y2`B+oHDm-Mc&Oa;pXTUqzbOs zxFaImkP;kvJhn%y0ft$;?^q@1Zw%6Y>prqIm*1utVAdj-(|YSUf|E=S5oQ$yLR;q6 zoht)qahy<=GuwP4r{+mtmuxU=Q5%k8_iuD#w$EHa&C&U;zy*VcA%KzOc8NH2rsDjm zBria*{1b##UQbmctRzsu&qu$qIR;3~;%~a1kiRA<&c80DE9gCO&Pz%kTz51PeQ4h| z9i+b*9n3#;A1L2i?yiCh+X?}k*X6S5<}F{a7(r0=58jPHs7_jdBpCtF4bh92r2_`i zyCi0D){p79-`t>!<~Wwphtg#4IpfQ$_V)mQS%(GcbAHwdInmwK(Scbz|2Od5gW+3) zn?=GKmDR5&vP#^i&@Ys$3w9aCYX?%A&b@@TWRlNwu0&)#MKe z4XmOGrxM;RTa{W`9?Xxu9L^zGiNmOyLWRX&65R%bBhTTNHc~qCvgdG_U<$mTv@rlD z?Rm;F=rK)(?3z-UsiKMpd#fY1U||B0D4O!7GG5C9{0G*`_ZvNm$L*2ARfzW=Z7j^g zG1O1y!zX7O(9g^ItWB%CMdp7=PC--K%}o!`e{Z47TiU!ld8hJSycvmefdV{`$iJ#< zG+<2NlC43gbrZs_j`-*yPk6w$X{F_I2mvnn|F1PeYQ)=C3J&iVbcZG4&xBooXrjexco~KJV zW?DlHhJ*S<7<&V|aqwhoTP|sTn41AVYrn{b7&^4b8a0hxdJmahe>lKVtz;B|%_En@ zNhY&yTtVfHb%kV$hQFjXTeVEQvP3Do)+NOPP^1vB$8;G2)kqJ`4ap7a4T+Y@ehc&< ze4?7Gt4z!|gY^JX97B$vh*!)fMQ#8!h!Xk(!c!Hxj&r4?{8K^bAq^A|6Yxm*e}EFm z2xcc%svubZvlfC4i|>P6sY*XJ;5sk^ zX+%rBCB7e^IEWDnU`DXq8_e%c|ALHF#;f2{L9K@}LLH@uRSv2IQU|Tq*myu^{tFZ` zN%cVVfReb1T1%;?+FMQLB8;uWPS)@T0y+@1U*X4r^!;j4ew@uQIowBbX8tJ zCn`LFG*L!8C1&BDE?A{G6lKtXUWD*Ka>I2&bb)liIhQVY&HzHTkh+eF8Bz>;_Vf4S z_uCBzh)2=|TgRSLbg6oje7d{_itd^m^b0kGo6<$;n`V|5-iVfP1?>_0JmiYNgyG*V z`?%Ht5k;a8sZF@(xS~zZ`D>4*F68Cj)a6B#g993A>8CIfkRa8@ljTp^cO*=UIIBTv zr~QZU+;cY936g7z{-<;9FxZKRn!Ln1?dmQ78fJNR!SG5-wj3p(Wik{G0E=-o2ZbqB2PsA5gbo=1`=pVSH|WdaJymxQGW8R0=wVh2ojt>k+l6=) zOA+iIhY5B#c7|x|=vc!9!krsVj7(>lmWE;Vp>Nj%D%WK8poC1=5B&7M-}Wismgl%)F@PA0D_Rxm`w!=Y$4ER0UCLl%nPbq57ZCYG&dUUKfy-f@B2%b!S2* zhU~gGLqf@DP4G%3t3iiIoG}`UwIIkujlCq|sNn|5pX-8SbL?7AbK&ISb;)?HF?s%& zl%%xn^tJD(uU)%o9S5U*#G<}c=UI_y@;t%kJcH0s{T%i?FzH~B`g<_+5veE7TD?{1 z@n)vJRG%?UnqJZ%CKiBWB6t!U!N?8ZdUrxkx}a0%WlvYTf@p$RR>>iygnrv7M-FN zZZS5|E==+;f45tPnTUBYZP9szSj*{@y6vI7+vzeohU$gMs{3-j7M%xBw=ExSY@p#| zY4Zfu^I*fkrGFQFXMmJF}Y?_OZjq^4asop?F5gX%{mL)>=pP%$(XS>YQEy z-d4l(oOIL;Hp#!Ze8ULv+K4eh%Szmp)g{kB!=$u_k!=PeWstrq)Ar({y@p_!Ztm6; zSvzl}XVF&Z%s2hvgTazn(XcILc{rWQ$ zii+h)FdhU@>^S zb>+Z@PHjaNZevIvpi)wPG z1Gsx(*6NcLxWyusShu+8>rGMUu;edETY0$j<8v_ahvKF5{pz-S|0v&gml-rbt}}lW z=Xkr!qw#KKb}`i}iKvpPI5M@ljum)iLd}Fus@t$8Qx#G&mcbYMf)9o-J8eOm0nYyo z#K4>qcLa$+{=#l?(t)v=;(+=> z`xU^oCbC`lQ5yF#>|i8m!fotCp+X$9v00#)$Q757;nWbQix3)lgh#mAb3IpZY? zapMH4z|H*9pD|Iwr#f>43UqX%<#$^+M!CDenGpzs>O+rJfZ#(cBl;4_*4TA~pEHBY z_G=WI0XW9OMLhu(iWYQ&49TIFD{T;}!oF~9Vah?>b_v7Jdcq~jBYFGv*vB$D)$EN% z$KB5$XXd>(=Hox)5$~OtRS1q(p`fFu0-;mIsRdcOz*rkY@sG}-VuL`(PL=9+c63<<-t`wasq z`qrG3r~3_q>cI%pi}$lbU$;{REkW_-ZuMp_XBQBCUGK(zEwVH%ocu-P;7FnN%C#wF z2lxu^?eCGNgShMnTN*d-lu7YyODigcMuG8>9Yzl~nEG2x=vP;$71%aJy%}kd{OQ`= zPCe18RW*0vdDEx_nyXSt+UmyBHF@=VwEiX2bYd=LIHeq@%x5^91sk4<_-FR)cPQ!k zWk4-FXJi!%>18OqYa1bTK}W-HFcWqIJis#i#w3&X-*wNVO%iJ#1w$$ck~_A#S@hk; z#NWhx7N?#8i5X?J%L!ELtuAxsGz!pe48cAP(|G+PrrE*s^%IF1p3CWHRhp z2gzy#eJ$<^OqxS{*`q`s;C%gbXze%w_ep?7n>Hu9S zU0yrJx;KpN5({_6HXC8mX57E&K*uur^Uf@Ve32T$29KY7%RHLV$O$j(y3OR`aiT=b z>g6H7*rWcK9oqS+)7t59RhDR;+AQnhtR1Arglek6CGKqhRDS@}F3 z#7jz$nf<^L`$0N88$b;fE;r;b7k5Vc?2099wAh5vreP2}R*&5Ue(0PC zWfDh!cH{9^qi&(em$hq$%%FD$vPX=942H%8^EE!S%s!|AyWY+cv{pM^M2L0qevvt= zempWQ4LNF|-F6OG$t+OYFSORj-z+*lo777Nu2qZ0!qP7YVOXsH7;KlOg8{`slsiBz zIy=c0w%5mX$hR#SEbJVtc6pdcD>XT=6m)`A>76*f@rxD>AN47>9?LS!c><&YCDa7h z3)8{>6<}3yC)(vgRlPGcM)q>`($RJ5LtGRr26H#ZdhlOB0P89C7TezsQyzSTBwWM; zQleLW;V&ZBU(>j^A8BNOX=I*3%*Ft?Fbg)^J@tBPpfV(}gM0?pm9(R_VQWhaK?(7{}lYbz`V0cXa-N94Q$KA{1rE72#5VGDoC)?n#k9#{l zKJEKNNK~uLqllfbYA}={bdy2tN@`%5+*>!V4n&NLdt?DR3&&b@Xyb|9{ou#~ie*oy zRc*IN&dY=ID|iypM4x8FUGdbGRJ}5cMm=W9$^)kLU;7Di?}eq*Fxz&z&M0v0r$jgC zZ2GeXWpe1>bmTfHh#M2+uj(WuiI;=u`>COXV}|brnsSR~6}hm{<;kl-(El0|T$2-* zQ&NIp7}fz=RaBYTr{riYfHVn|98k+moG(#}DgQ0ljkQ>)IGJ5H<{K_hqO%)EnbTRx z%!Trtr?wj>ngpZ=@7N5#~)Pr3)3TtJ&k7e+cf1i`>EzF>HB2-K&` zh+zzg+)o)O`q-XUvX$m&UfKD%OAL`af0fn~W-GghtTgL8Du6=&iQT;)6XupmKLp~3 z@kS{ZkVX8OrvxgiGMZKeSEK$GeV|`nSj8~V>{7uzaZ_sVi!@GKRsP0arJfP(*QZq+w=q;RN}Q`t-i%g+U&>n5N+WoLcgQ^I zGYhC2C1&}vTOYSHhh5_QirtWdldtrDTzvy@AYrp@Y$qGr8{4+c4L90oV{77MV{L5P zwr$(i#>UHk@4Hp+zN)F3ue)ZZ=c}6PI@8sC&SPGjHa~X?`eS6~$%KY$pXQqI($Tqpqxo~WJ+MRO8d_C^u`6>OoyvdvrlMQr z62^Ht9{Q1Os5Q1W4FoEdnktOtB{WdJ{gGM_jR`KbSzLNGGagypAmVj&vmmmNWn4&f zBXsF+4soo{G1Nk+=3(m#7pxupbd0cwjo()^I0wAaTYe3u97XE?V=DWEzW7lRVQORY zUoa!db`@MQNiiNmsR?Qg92pdl&doV7<}S3)rt+y!dJ;h!o|iT81C+4eH>}&v==lg*V>RCTfmyUk82YIi}xE1HgrH>{;fZFHf?IC6rvy{yl%o!wUYUU1ak8`2C#C@ zK>nCcgYYd$ADApjM?ld$pwnEe`TgriA5xp&RC$H_g22w+mq_0pAvy$5#C55RiZ&=1 zr)Umj`GdtQE}DX8TsRx!r%Ud8BLFIDHg6S&!Sczx4I*)a+APQDG}SA}HXS30AP_@( zp*O&VovRtfeI=$B!60XbRZr()h*u`7dyn~$0z;9RhqlCCD@iIqo>@>$$%#hm;Akwh zjLLKPcm3#FnM(T)gh**|pa|AROUGkem4x}YXJ#v*VSv;yl-h+aC0 zQab#*zbJ@Xh*4(01R?p#0xdBB&yBg+MVomh5-(5U9kP`TgHcYPpmzud*Pc7ms;sc8 zlqrg!*xOdO5k8!EwaH^`!w#_lzbb-_Bv;K82 z=`d@0mFHxO_s!ez`tZ%gW-@xqAa!Tpk+BUJ!rJh9=9E|Hopj9;$HpDK`PhygaGTnJ`i-TMj`kOpFH@ zidNXHf6(eZT{~i$n@+Y?besy@waTCIYmG3DKcl&HN(*+>-c zVs&1dUG)4gW}Tdf4~;F3nEQgXRSQ9Vwmf-zp%lYC4s<^)E9hC43KJkniNwdQrpm4c zL|J1HNJ=Bsm;Lo0A9{xT#)c>24Gj%Ys|q1f(dNWn?meut{FK9~g|CG>MYy~awwO&j zM(}Zx`1NawhTS&rCS=lBiT*M-75xWO%Q0^DX`?UAgh!s`9d89p$m$@<}?N7}@Gy zRX~za^&+@J>moNSZ%pcjr42Yrf38}33B1Ct+6FvT9^`_((GzYXvjdoI_a7)O_W;&4 zvUFl)sFv$9i7K7hbFly|(%U^k#C?ziAxc9c_>?Qar4zRDQmoWm*jokmAYhB5(6^Zo zd>NLISczD8DF8KyCuY{}IC&OOf)4Ymp2C%woDWvloFpFtky64Q7q0WMsU0qT_8TY2 zr-XNwBDY8zXW+ph`L+t0mQ605Vc@YSK1jMST2My5K_}+0U?;HsU29qlhY60Ub<9ca zrZt^6v$VDC*!f@qP2;XL^R@>I))Y!{WIgrDK39kOHDZ0);~~#)TW=TeUB`}+i|M!* zy&geZjK+P#ObIPuqb$41ietV8Q$=-ZANaWm6-o!1a#5P(fp7c5kC`1GtfrB}*Yn5_+ zs522NwjW&3@Pqz$G~qAyu&@YBwP-OhYk?=yqb~k1v3f}0wHKj0+a!)8 zd&nPIzGOd?hzfn=V*Z8qV7#axKqtQj_|=y~eIK>jP6y9LQrM?A*)rn^TRgVy z_0+xb+}YTwpfqxqyUX)_?`*k@hH*HHALXRb*aUw6s@-3>CZsP0qFq@Jw`U07gP9-_ z#o#bwe@b|AA2MptX~*(T*2QTTcW&yt-7&hYfGk3)92TZ*w8r8bZC8w}lmEq`FP_pB zM8nXRnK_`2+<^}uHo>f15@8Y{Omw8S%ks)fm`qMn;i)j27qq4*?p!iEKhaMR@NA%v z!D{zitT4lCSFGUyp865A4V}d4D94oVSdK2VA~5HNj9}Ihi8ZelvCGT*v{Z^*9WwHY z377VKvIo^9HPg2}bFAvK1zOjQaLV@eSaq}YylYMyo1biOWLex?;;o={ZxaZJi+Ikw z&9t3|pPATYV`yE`;frLp2SY|d*liU5%1u`($9L?zh+I5J94-E{NX>f^YX@eO({+Pqv>{SnntQkUrmytPzH~ zDv^f-1%XdD?2n_WEyB*%8A6{|gHOydQ66#vq#w_AUUOB)lI(9rB5Zw%g7?57!A!>W z!pm+`+)sbrkzwHqROZgBllz@EELWx+_?@elvw+M*83O%Jx8a?ufrmYw_K%}0#e(|R zkE@s002e(L2A!;Ez{-54C~=wl;I;C^F`zcP2jB~Us)|J+nj!m`k7>matzS_@gz6X* zr>5xn)jMs(YZb@w;W4z%B(-H~>}01sU1R?w*lyES+d+7rG5h@+JYS^-#m@V&|J1u6 z?3sojmFFKM+uYyy3sj!y5t)k%{E>*ORux96xM=3sk~=)#oTCIX@yc;A*PSE^uovz^ zC4qkqj73mu$b!fE(wk*#D#OJ#V^sCHSyIxFM^rd2N+;_B#{mvzaX(jbqT9$ixA3b~ zujC2aVHFwhAu)D(0=Mn^7Lv!967j^h)+{hEBf(r2bulk?@7hLh18Dr9>fM4$4+eTT z#)F+TJ=roX!?&(Yw%?7Wu}PB=tAz%_pa85&R~i1C-w>Yg>gb%r?A;>stjC(nanCp0 z4l;(|x>rLvb)~l>DG7ZSuesAb?xOa5@R<0r#7#_SO4e!@6BHv76Z8o9c&VCPP>6~3 z(}>Dh$KDAuFMMPLphch^c2d#TGFYC&-yNNM&oXEjFF+KA-$4{T+s{I*)ZoMe=mXb884&Hc+C-d4 ztSBbfW<%nC!nZ+KEkMb+N_{aHi$POt$U%E@cZX$Vrg*G+$dG!(tiyJcrv!UMq-GFg z%Awd~yCDo|jr~CK&Fp$}?uA8{eSp@Ta#Cy%if;Lk8bKZc3xa7vgy>*dlsjRykx6TC zkcg>JiRw@-p7S5w&qAXBBxrq)<#(4!34`r|L#2rlFAGSD=|E)39Yp5RgT0K4<%U^E#-+{>5+XQcETQX+khLOfI~K=h zG(59^-B7%5!Tj^0HLP7Ws|8~7sBDhEd5CBpzBy!{%QVTeoUSn=sKLXmOuU87kVeUIHketSegT&7SW^&Nd-N!b z2fqz9x)b_Nq1Nz$a@-BHag7_+WPE%gt8x`H4xVyZ@LacKidy7sIeNhXLOy%8R zB0#48@kRf~hX}?(s14!)j$(D57Pec>hJ!X3Zny0TxmD|h>TO+j%`t3_(xZ-|O+TnK z*B`S}ckvTB8qp6TH5GvM`)0KsNXM&8jweq`L^pKut(jnm3od7@x@TYc<(k0{vHJpj zpyFr`hP6w|sAuuXlJ5svhNE~Exqwg3o768nD7yefbp6#Y3Hu^B{$6yhQ<4SLQzT#}G`Zjsxs4)c#KxjBgB?JW$TXWgOb-Z{99zsP zpNKN@l+;r{OKB*vZ+{!s^mYY=h z<@9q2%FmM}B=RSZW3{i2!A@J@U2o2dcucUZ=KgzPXoT$%kg&?s;UUNKlv@-$>eQpw zqaX=^WyX-6M2^Zajs!%z; zSsCKk5hQ8!HNJ@5?jN-5;qT3cfGtTzZ&%cq-Gaprn9vm}D@@WAxon3oDoysu z!}uH;&^deRmS^lb3sJ}_2SkyLaEFc)Ae8}n9$m}>1vN361)Uy!EEF0!TwbyeWg87lgeIc1x5p(dk z*e_*kI)EB3`K#aRr`x7zh08?QY9v;IV@^E3wLBakP0xkH4Wd!AoX(cr)mWD)(0@yC zI1<{}v}J}o)0(t8=8|Wfp(naBIbjMU&_Z~^rj1;uL9|Mi%Fwc}aLiS2mrfSS3aqIi z)ODBzy^9r{g}1T7lwuNZ!_RZhKjL0TgdOAFibw^Y(3tIUL}0u~#M9+9hGpq6?{=-R zKm7o9ob~^niZ3-)P535)3UiC`7uVNkavLJhVv3Fy+|Fy_< zU@TQ5Bs1JRi=^GWfEn!R#44^fz@gGw_7S$Ptb=)<^VF*IN|c% zKig%;QS~a8)beb7ck|$iq_qC+yyuA_50eDwuUHuMm|NMAg^YJ-*plzKuVh@675nv0 zxhl{}?^gS8m(%Jx_9&e0D!e4ZS9v?rYVIc1Jv$`}g?T?j^K!X#Cq=!FNb)2drmQfWzXJuCmxw^qigd(MPSB5R9Z0kyxe8R&vn7%Angb! zgbBvEJ=k*R45>r}g>~gKm2{fYcaR40z#|t8>+C0K4I+N=g3yCat@M#Ih*-<43$pAM zp$eoxyfKwNCYKyQP-tL`zW%D>wOTE@T0$hp*R1w<4AtFBG_|@^ZyqVEKvZy+i_)wp z<&K56p;h7{fY&{dpqB04k3Yv=&YJ?1iR0b3-5s1+oqFMsJotJCAYMYo%=O~}0A?nyasom6tF)*4`T?V#9cSn%_ zu6fE<|9yuLacm=#Y-5c^jA6t=n`a9rz66Ed!{(m zds$X;`B#1B^JI!VI`c^sAT>yxbbS5a82kULi145@O0csKbF=+d<>YJ4O3clk1iA(; zlLUSH1;bhYw;JRZ43FAxMD@<9Iz9p!JIKH=gjgp0ckbv9`UV>HyITmX{}~`YPm~~) zT6Ty6*0HUz8uZ%!!;n z=LBc7yhvrtHGebMR53?fV$Hg@n1<%`-QM;cQF*FpxGfcY4$R&DL$>5$boWr0lNR-< z9bBHf?NShwE?M7FoB{;Ia?({;`p33T@#Y(L&K$#~wRPl1`_GnT-~g-&q{WCj2RON< zAgh3HEX54XOdML_opya#%rdqc^Tde9aMAWq#>+6cHrRQaJk}w&gjI-?1l5|2X^k5K zIZzK^6r3WdtWsut&Zbt9rY%>4a(S zZrO3d)DE6z?{(hbMPEf+AHTwcf58qOmTtP4s*UFK4WpE6IUCzmU>E3aI!~$IBittE zFnH>GLq<492ht^3Ya}350aC7W{b0}tW45f|d4X^=gq#7OkN|g^lcA?D?v;=pG$DgO z(wv0eQtAGxkuge1KtJXUg{=Broc;xUhfqu?r^3UOG(5dAOq}nw9I|Et8i%}&3|RZ@ z#9JtMUo|2lj31J2w))#vXQ?SsRr%)F?RNtfBQ8;*J}uMS-diI(B5Xk9i18E9%O z3#Ymn@fxYCH30sMj878*lnCtfgx1gglD02aI@3j_*$GkCzOYJqQ$E8y%>ZFZevBPw zgjt}R6Fa0eYz1rfm#?L+AKyJt*%~pmHSaX1$vHGkjmC42YK?TX;@e4FJaOX8Pz175 zRlx=Z>N%r?;5RIw*-jn_QqXc8+@X*E)Um7quH^E;3y{K^tCBzmhHA4$LuZ1e((pi* z!wZX$w8x+01@yn+f%f}@aNMiG{m@z+VKh~6?^d@Q$;((G{e##;kD8W9or5+_f;b;OhDVeq zTAv>64QOtk5Q>HSZWsZL)xRt^A2%Z(a7@K8bYSUQ7ArcuIsGqmwvIh66j{`nM8$*5 zMQWBu$wZkA%wR3-@9c596z|nl#l_OSU_$l0RWi1kF2L zkrb8hsN2GU5at-3RL);bD@HC%Nvb|=k=5$v_l5aNLp_yFq!~G{;IdF?Y*-F!1#Z98 zF#yh`URekohA<2_#UUkXKDHpO6cqwx*o^Xk*r%k*KIhHFS-s`d(G+gTzRnl;dnF+n z`S%h5LUDB}J#x?3kP~0B+u27m%dk^UyC-6CDw&S|4#8?@_D>vV=i+#h%*q`Owf>iL z{(cpZd1}&Y5ZiC~0U|e2`bkO?e`cV?zXMcDGc|#bRKr{Qm;jGtRo<2)da#?C$rj9`9tmjJ`jlDxN}%+ zW_eiz5532I?^>4bJuS>nhOH~KsmOx502NQgocwUBih0ZqC|!N`0>+5p+99JlBXC64VGuWmIcxsyW4-pQ>e=xQEvF|K$ zv}oYXNfkGbFU)f`npV4g@(8-y30R>(C;4@QY~EVx$g+B<#>j&6>hO=9`$4fc`oPi} z`Gq0$t>WQ-T4~eR6GO}fGO@2OsF~1v1Xd$Fwpx+D-etoCs(5bGvl=c?y?XhL1 z*bdZ{R}XxqhGJMRz(N(lI6Cu?rdYlLEj(}&Z8v-o79Qe|p@#nc4}dn%|_>31}`vV z8oZ07(vBxZw``q6zy-g;rZeZCQ4!0_q6vyDc}V#j7rh;5hmX9h`NV5v6oe69#8Ld~ zlN;$og$*o!-Qbn>H}Dk9%dl!PSgLX7Dj}7dDv;#OiVz$U=%#}uhgs5rX}bo6x2)hK zTE5Yrh1?C5r;I#kzh%hjH|Uj|7&6vk@jVwVYd^S@s)C`aba@ke-ac;zqtKH_h~Nmo zcE*Ryn0B(M_UnL4$ZXU{BMRjr87w`x+~7+7lQ@us*j@7^4}_xj!r-UQa-8s9Wj56V zTJ&@MQ2HL(MWI=I;)V(d4-k(b*BB%%*E3%9XYLBK4~gW0G2^7>79Tlzp?e$rZsGUyxbM+IRtbMDqo( zLW>p;De8Dz;D;OZO45@}NMwp!=V@UK^C>fhBiA6?oMVdeeO{||8`2@mOTd_yfo`zX zgs`-qZ45=qy;^mbBz@K1@Akk81SuIKDb2``fU=DY-`R)E#guAaS*=@*-X3e zcbi<%(G&OkP>-*^e&U)8xTW66+;#uoGbMIZyI`#c`M!cF4`rN9O@~gFv8hK_?4i(k?7_Wp*W7bTS0$)%~gWzG@K3!+`WKK1GGW zm}bvQLtH~_V3k*C8@xe(MEbx(4qUSfxdtMW7Z&63W2tQhYO%}9B9{jQTTKXX<4D?j z-ugxtcCXfC-C!(A%Z7tw?%d;bGJ>(>t1WHYf(}hla!9(P>)_UR=!28HO={(*olUr= zu_Fdc#%tQsbCvrI^L5uUy`~MUX^?=Zm<{o=T0h@Hk9A?9v1|e%{esLf8mIFY+|cva z@avV1In?VW+SGyx-2EwehhrUJMKY47lFF8(VM8G95-BA|yVAlRvn(3+t>k#mn~|`Y zNf?QbZ@;CVy|Je5eoNXNLS<$fV@>WS{DkaY!V;G-$>c1*X0> zC`=)&VOPrtTg~^Lnb;iwzS_i={)pA37|~07p{XQRu@lRsIE~pDlV13wI4n@%tT~eu zFX2XAvE>|2qannQi@q~!pVOz;8=nb~-JdFQ)?e%3}zO6*NzyOH3cUo%?wt6QRq+MX;fUOAyDtH^1Xj)iHzq)L)do`Oq*5a)HNi$s1}P8g3#m9%nP zE8~|(Rw6pM>|mx1Ew;#WJR%t?n;7V`NueX+y1^b}FRzpU7|Cc|Mf72isp|I^`((fS z=NRO6PwWLG6*hm)epst~8&IVaUXZB9AhsS4Y|76*;$~V4{$)PCZ~yFy9}ZhH zLK&8c*b$kH^`nIzBctBi{o!^uK%_}X`crOp&05yDUVf`1h`XA1RZTt&Qy_ZVqT`1O zM$(g>7Hv5R0GpxHj3clDn;}J^0{;i<`Di=&A53R)Q9!^6Afp!>t6|VT6LS+65wzbgHhI3XOzm#0I6@FIyULVHhm?wLlH^zb``7;{M;6BtMlgQN{1vfKmlhZ3R}2^0*R3oMGqT<8za zUPKf;8B8;R6IwTAadyC-|Mnmk55v=7GeTId|CqVMR>`RX4D2l-t1Zy^@3CWx)42r5 zDCKEbS9ShS=Y$mk5t2XwrBs+0?d)^-1qt$}e-?*ThK7dfx0V~`ts@9sSFw)D8ZjpP z6sT5L-wVBS8J-?lrvnjq^#)9KiqaO7t+eh{m?_9)d@>Pxm5V7jmoS)AeVy_ly}nM@ z8R4fT$N;P%$3#}0$pj#q_yh}*VgVB8^Rd3lEqSz_ll}2poW)55Pdc%S2l5=il*I=~ z@1^EIrdp0G_Hnb*>1$~6=2)()%qtGQJWw=P;RcFz5E>pUkGCZ*GNhb2CccB+5`eHZ z{9GB8U`M?K!|vIfTBtU%>FaQvdS^fM23fW8gW-(-QleV_Hv{Yok^b2`k=s!(F4E`- z#;qqUP|G!^MakAI)@pRZL9y%Mm^jnZjKklco;`(jc$#ne2?+|(>o0)iMv8)HC=?MWB}RsgDvv*5D3Ty7QBV8QYT2VIKk2 z_QGi=#FiUxi~w+<829|ahGq`E#z!Yscqc?7AyoE*5X0Ja-3}J(Cs#t@-xiUB;xvLI zFWC~IaYKO?Vll!U@{7s!0Y8ZeI}TzKBN{@$F3t>*lad?@n>38kWF^;|}fPLJHCCM`aRwhl3+Vwg z!S3lW`lJ$M4Ka+q53x}9-_UkPb3uin43YYP?isQfabu80g{btyQH!Q`+mq`0alsA} zD+Je^9x(;&sbLpo`dKJ_(ee+HP5Q#!vo@nq5^MB|_0uE=a>ehdGvU}{%88c;TZC#l zwnG(`6#+R=m15;VGW{#~XW26EwBvp$p^iH={T|6dT+w@8#S*$8nq&-txc%bzSfcd1 zXvvYy7^m}!hB!k|$$35qV?P;o;ff`7M`} zE;+n?rxR^Q!ktI{$xkP_4njMRwEV@iQ57Q5p9S>L^y3+_??&R=`ezjrbx-|7+@;hC zcVivW+5XW_`Bd_PwT!StVzc8$TQ1p-$Wi4aXWEu(($fyg793)2!}|Oz2w?x|WS|-4yz-H^7c} z*9B+>w})OY=>$i%Ux)1yT8DHcxePWS5g5NlePZ9uvuk?c;DdT3{)pNmd_vsSZ$@SY zc_eGJvkrouZ^}k&B)JTLMt$sa=?BLr3Lyv;c9Zf(N9tARcZmuy#M(u##=Dkw!@mCR z264^ASNZ`P)omQA*!K@5Yv;*xIj<8`@+VOBBI$++77F-c_8(<`yLLAh^#Xk$>4bSj zjqU;MPujM>C&v#V-i74~ePS8X%qF;2=gRLys_H=xt#agpRV=OQA=+Wu#j}IBR>a>5 zEJEG#|240x;d?{7 zng+pNe{ddP0>MeBf;&%|Zjje(?WKeviaXBzQ(T#T@u69LM5tZ9oG4QcZ)hKZPv6>u zp4i{CyJuEOAw$ayI~Mmnr!|&_V6moTnHIad_PARsI1Y-`>XKJqnTql_Jv7?bg?B!MPVzc^ zf&r+^S4n{2p$rt-!d+>Q<0)T!UyCKMdq<6>2Dx|mcX*nA$U{nQV6JnR>nXg~7N9Ai z!-7^btekt3Jdr+OnZgewj^(0VZYW5xR2Ja1YZ82pxOQELq+pc`#&!hE{+Nm-Saw7c zLI$fc)^4o>#AH>z0ll}qS@ToUIND*D;i5j7V9-F|)Q&vqY%Fe(SwSi&E+5t>$k2&f zdK2VSqu2fk>~K2o%;UqJzE4`dMc53mG5n%xzuz#7v9=>#`}b?K`WR`)eZuLU@S9{$ z=AE16-yC^7yG21^N;lk2V$^<#OiCg+h3n1As@6_T*X=aq?)YMusXyvZ9Fj9wo4x#x z1Sx>RX-Sd-I<8nGmtv&G<4!vI)f;YzB4n)(;>`|J{j&G8NE5tHYm|$3I4#+BykFhq zP`nk?>M!WkovD5iBPlo>p~09E6VMe2pKKnU2z^D@XY ztN!SED0X>z&7(4_dFc7RVJ{87in*(Z)IY#tGp?&Fc<0>xa6RXqmXbDyL2ySi2IaPFg(uh@k>f$W)iG2^*cz=y+C~;zFeE;8F zE4^veBA0972w2_BTM_{B zC+!b~UP(%qUE&cF;t^tP@@P5I_z^jlXtub9{a^bWvvQY|k8vOteJgz8nG^tJR!rSK zZ9PJ23T|-<4cng=bEt`Y^kcr(KOA#I$38C*0#(!Tck(YB?=e2oU08Jf1X<)H>eyrv z=w`5Ef$Y6Mes)|@uihqKbyDxXqznLTGgO<@0_2z93@`=1buD4DHCbHFzx}w)ITWQg zH@%R$AiwasU~CY+(BTp0)Yh!hsanf^O}PZoU*vlkifKa5%XoZvVCR9KidY&^y&_!s zzI>8rg0>-kNlMuR8y>h7qse|?2Tz|3sv?{hR5fB*i<=u5GQz!|0j`#Bi&h0Rhg%0w zO~*G*i#tV{Q)-4GhiBv~d&y&%L!ako)!Em(*keUC;`-8&LUw>QhTpPLjkNX4Qkoy`eSlwk z|14Kh{C%e+NV*zcl;-ORv|sU!le%U<5*6uV%O>@B_kM{uR!6_7rBjU$X;6k0(^~Sr zquKg1!p*fE#(EB5-;HJEK2{3B<7_Ki1B@(#3e$NB{vU35mrK<99Izej2q{*4y7HYO z(Ji1A36ishVDkRr^-@Q(tDsKcAa6dvPH`+GSuiqQsvtQhmFHD<`8Yxrr?=s%?|g!Z zV%%B*Ic5LQz#tdFj56Sowm_ODKPV*{n7?Gf-W&?yRghVWt4Z8INnGeL7%^h#u1JqL z|3Fg=+gx3IZj|9$7F^cCuy~he=1n9INX>2KNtE2m_>rF)=OUOr9N?{_?{=Ta+lrDGPJo+IlLcea*|TdzME38!|Q>Lu&%OpS^Pv~kg`?>BGgWNf+1mzeaqPn4^)~6(1t!{|K(C6=~raMQD{Oh3HTPU8?Q&;{7 zG-<=}ur6HIvX5dFuw4((u2KX=sbGYL-Tf^h1QMT}l@ z_Oqc11xFb!kQv0`+O|?^gY@!~!wd|MN;CL|A(>za?t{)&-FLA%m287uc}{y`@G>>? zkezV7^Y!V1nkHNE;`vu%-tU6j5NN48K$)LY%|Kv5Rlwb>psc=x(t7R20_#BJUexon zSEXA+_j~_Lwb&knemJkaMl{Qqngmoo##_+=ue*X0P&8CAEE`%zN4yjP`%^t|%{wL1 z|5ST1j0!6?s0au9vV%)-H}_3^F5DW;uGff$K8vHSSW?{e`$%~SzsD=Dv7}UbUguP!az4{Z{?Z{Qc)j!&Mw|pJn?cYfou_2#LQ}e(T z_v|AHK#_Fqh3;|uTLc5}nIg20qg1>dn$FYnpK8mIY=ZqY*@)zQU+1|tW#AmyvfVBq zF=b%)8ukmR&gpY_(bdPT$uZL>NdS6F>$IgvmC}5fF#vM9rx{ZQDORqX;>_HK*1Vs1 zWIcokmWT433MFsJQi~tb52Hz1lmFmubPK}?z?6%b`ljZDDMT`Q6Acpp-9m383kTLS z6-lJm8%y+#`=)09M{-$r#rx;?%xe~9RpTa4ULdk+%H;knW~=!)VQS!_hqTyhGqp1oLecAF0UB5+|R zph#JyfNlEB-$XsFoMM&O{m@r}EWDQ$L%d5B!}MfTLL}5Wn9i%A7KT)Gg|vusOh@Qy zqO=2YAwL(L^`-?Wg@Ry#Kg*yA?5w&RtffwJofEDlWY4Yfk(vB!Wo3jOka26*EP6V$DmQWV#9r8~_puDhHX*dMYE!RT zG-f#B%oO^|5We(Z6VCp+nB4mxt?UNr>zT%8H|EF)dwmOZG!_UFnm+1*LaTt&*v9>w z7QRT?-I6WTi{XvXD#4ZC(nJvC@R6x!qZ#LSwVJy6_GbQX@(oL86^4ty9)?al0qx>o z%QOTVEUj~%3XP(Ba*8=GPbVh@7yV3UDTaIU9q6UH{A4ZZg}>r}me10q&{BzkK*#ZZ z=>g+=PfU9shK}*k4tdSHO|L>tW8UcCNBb8Z8eTlo7CaKzJCKU30 z@gJXXb}Y1me$zi9yXa1cKKKQsEM;D57Zp#1FA))m+?q3g&{*YmQYKHM0Qo|>D%d65 zWjU2z|h~oswQguDECc(#XWv*p%$#6kZ%J@j`t50^;!4*ofH@b4GS#EiYdQ z2V2P>iIo;^$mdgjXV=TLx7*cNlb7b=@!ken8&^SryR(3)%JK*tRHFB0cazh<_m7{} zcmAs>yjC{px*u)w>P>PDfJ7?VAR>d@WTp=NR@dukZSV=A-d06cvbQtC^Dvz(<-di# z!KuzeRI|Mx^F7jfdj#^H*nsW94Dyjg-GLyKi3jz9kvLk5xi}79&Y{rBWLl#Vq=z9s zyZ{3xfj&he&VjIQClUrs2-=!tbYks6@FXxFHF*(Xa@B!mt*n9-pmjo~LSv>t>=ZxD zyc+6+;Df78HtST{F6A9blOfsEG2l5tn=M*KfneY~a;=Kg0zMBk|ALO=+C<)(^YR?t;A{Ctcq5;ZPz7H$|)Q9xNq^)G6>upt~CW|Nm5H} zMFjtPyXE7FlYqhvK2cavSYcO)vz(}dBlXb;SN3P8;aT-(F(*Zg^%rK*&duY`7N(g^ z)yhFOrY-jU!7}iTau1rR9IZ3o(%+OZ zIJ2W{CG?^u$s=xTi zK;@Q-suLw7)A8D_NAd3hP~>xbdqU=5z7G+syQN3|o!0$(?I24(j|80^kG;wqf?t_U zI~AG@@MI5RFO`tIzJnpK8}|USp8Wg);1PV%z})U<1PgEDD+CQU`eXRSQp zz^hvgi<#;ESC1*uG~39^P!iMIA2b&!0_8k|tchT%*PrQ8A zxMSIYzwpeM+g5n_t8Pf^Acf>}Y4-0QPmaYWpo87Xm76vr;y#+L4kgPVY}mWo zb=YzFv33t~YDmqqY0qXV^O#@S(>nxzRb>w0-D&RcqQ@LmmIkTxS4$g;cT|a7)qTw$ zMYhqF-fkzExw#aIKeB|unITZ}QgV0H3~k}xnnQD&$2H1^%$nA;{W6xVA27u6^28)| z0SyJRRVRv>;KN7A5i6g(4LWVw3zlUQyavb-(k^A`7<5`axBM|Ub*(>OY6?~4ES+p} zfmT;4U!$tkS~}w^Psl z#zN-6>%X{g2U3p$U`bJtft?d(fF@N#310zm%=Eow_#@FH273eaXYs`kqo)`D7gEp&x)%^18 zgzdpNx+*e5N}cIKC}PIa%+};2F3ZbvRa-g98LVc`{kYvEP(l8t+o}q*ky}R23}(C> z^>>8<==CLR^7t}0$Jn)r>mp8+tltpkt&!q`)k>Cd6Q-d!LWcXSD#2dM#^Aqzj#oNM+X)ySBRQ4q^BLCLx^pT{iKSd*2OdsGiL>{#;#7#JH2JIeYJh$&1!C=QBQ^VL+Xu+ zV?7Q+P?kd*Q0$>^#^kfyyaFM@AGnQ+!SYjV1@4RxW| z;k2UiPz_3kGc&qbtEe3?%>f_x86%hNaId)Z4qxm|{AoQHs#}3UpJQNt?fjkamDqB+ zjzXFUl_XnGJXH=b3-FUs2^_IrOe3d9op`z+hf%}($&@^SLK3+oF^`iBNEcrB>q5Wq z=<&*f(X-dr#HXi(p}hLwB<{4#DdXiw;Lq}wufyvSSKpg1bMA6^5?PrBZL@nb&UM`O#vt9cx5 z`=BF3V({PAd*TD#pz@K3!MJDcFK$`u=A<6l^zx+lZ{g$H^&~Cu+4)+k6W79zvbxgP^cpJsVG4zK@GT=pqK7DHY+Ya@am{o|~|+Sflk z3pcs|j(YN&!d&UojjjO`la@{4xhnUpkI1A;gSj$*{vRYo+JIBb`=i|2devxmZZPM9 z76SkKUPLaPgSn?3%&O1CtDH{f{&eiB-6vh%-aD`-rO?)}G`T0d^z|HzH3sf_<)Na& zhPsH%M}M*b@iosc{+YY?)DZsyozT|(X*2KQPxHiBH%2ZMf7Ta=*CrSEC?EB4quR`_ z*2xhT)OIZVk#9%mXEE;^tQhATBI6VxjWRhOds>6to;|Va_RODlpEW=eV3wu-o+qw~ z2JF4^cma>dL4?fQ$pPn)J{HPN z_^5=G)06)WvD+53FN;KAwO>UTJIZ4Ab=McrR^#~b&+v4K4d`k+I|D`nV zzupuyZDHut!)Q?VMBlznQTT;6;MG@@rO8=dGw|g0B|mzC89~S4Tpak8-jrnW&jU!$ zK35qr*NwQk%_C%B-okL0Aape7h}EK28`b~)#}1{bu9_M=!mhq&BkBr=M#phKz*?7aD19fk8S+Aml(jNTh+c zI%a&b<3K&+!EYA;x+$Ok+&T(q_(h>JYvyguaLp|#{RJxHl|CSbh-5K*La zW_Ym#VO}eQ%<2ZtiLTwoZjwr!2}!lC2Wx09QVa2`!>El2;mw4Trq+~f*wdQrI)4dE zG#!(mjljtzt$oKJYF?i=^=)bzVkk|^pJ_nz*A+n*=v(;!POJT-<%{@NLw3EV>0v;b zdIR>wOjSd|x}k-8XCDK64p5*KmzXLu71JOx4go6{;pkgB-5|1h-&HG`9qQRdizn0p z8o8OB@yT<9b@o#% zOcBbkJT(GRQJ`bmR!s98%degSS}%9X9A5S$IoYu-dD40OR*Rk;bD-$oe)TX1a8VSf z?ODuZWJ~f@jfM-GI)~N60cS2t>k-%W7xb35pS5e83S0_eJ(S}VIfiyf_8Yx7xG}*$ z8rU-ino3rWe;_$+OfW_o5s!rbNOjnM-G}GR*}bFUEg7@u!SDv4le~phBKO2TV>rf% z56)y%Y!Hw_0)49!PJq;^^^AwD)$-nH)YvsLgayX>&LydoFMv0QaQRMsj+H*crsEHR z+m$_?%&4r)C?W_61FKi}B5{&|JRReK1A|Vef|ZPJK@V814tLC0hgb88TOrZ7zve2R z#ej!Gl^0zY#eXeS+f?}DE#t%oolLSG#2*R=M3$TL<$&beFreo8T;RPzkH%`Hbl;c@ zrB%|DE}$&9TJJ zupFIagdS%=od7c$oF{d4oFb|@1k9GT9_qIWV;97ZA3Upc7nFF8FV4SxcGuR`CMKyy z5~27BCX-S1q*}emGpeXSKN-rB10}J<+unFi%A5;W@864Pq$r7Ikj&Y$r24d>w-yCi z{&`!sxw2WPqfaSN&WY9K*2MeG)V~mBG6Mm{Dv%QJG{APMn2(QX0qw=KOxtLqGSB%c z6&2*J_8ARxd=ng1RY#ao7^51(A};#RG0&I6CMbtwnsw)KaeUJf!{&68OpT><hBt+Skd-D#?3u_B`Lz zle8^@6ku-lCjzChr+g_e@GP9P@Mzbw^+M2dmhRe~N3QXVq)Yggt2lKEb-}3@St+UA~%9`+0-@h@dYj*sm~A;`(9o!rx`47EOl9}dM1}mZ z#B!JV=oRI%)wP~Wo6M*VV&s@*dU#j`yH}$f zwKmKb3~uqJMvEsUpd1v)!py|*e=|r}*%cEP~Bl0wrcEvX-WU03a2T zEk8e+tBQm!j_u1$52eq->@_pp`)(4*)|q<8<;LOW@wDl6SyhhwlZ1i@O@?}Ubgl8^ zF*95pplJ4&GF_hWn|iZNqAP^%^wvqX_`sZ_OB(Tk_#$*vWvxv9r+QTwJyq1W+spSO zfb6&0`gl0%BT70ZZK-W(iF!RsTj*)kFZE8-?z>$naug~KVeg~<46+KOY)>yBi^3P0 zFzZ?W+G$4DnO$%dm=kU@G7O563>I3^=>>v%YoS9^SG+EnK%qD?%%DCl`v zdEya(0zd&3tg|9BHhA{%%CMgUdc}u04<+I`)k>tN-^~J=vjY7Elw>Z@J;*B&Zddpe z;SuFrDtzr}L2gFIhd=l=fWR^Eqwi`|3YOiETOaiSDzQ&#|0jK#pu`TpB;?0VOOhln zL$qSAGcGhD316Ckg+6&vU|?Tjl1N}LaZ;X-kPt)z71|Hcz`k8(z~8*QwdEul_JI1n zcxL#&1-mF=vqn{5D5rPb9a> zQ3%$LEB0$Jr*>zQ0XLg>wvX8%V-|W#qP8Gc7r|JgP^M*1HTC}{VHwtjmvitbcWi3 zUlr*EYMG<8s$BE7>v)CwiuDLQ`@UiY5$1CBLO}rK+ycIUl9_#>$8;C8ui($DHU(b2 z7tZw0VryW$(pvFv6n*&4gr##=y_lZ-UWu9z>&F7uD6c%vlpi#$i3D>oGe!Z#Ymk@u z7dy7E1+HlXSl$5ykU52X{&KU3_DD^B7dv_<7M2iS(l$H4@1a|Yc$TvwSl^j+XZU9PbWmr zp!i_1Fuvk7mQcq(JrUmVx~jXRM@|r~jb3SGL!9K5V z{UtqLa?kfqL2|&WA30mZ-kzb?C-_+2z}N4O{aPvk0{cqbUhYwM=cR(>=s%ErUfFl& zC+ME<;dnm+UQ?eOHvs7&{cmjwr#i0plGHC)p6nPF#`uSY=J}E+qmRLX zGudL(rGdsd=QJHDa`GFzM)(Nfv9oLI7j=o6dK#Np!)*8xii4Z$8aD>4C!^)^kxWki z&!W2@ykc5lHO(p6rlw^pjS^D8Ks8R1ImH;UFcm#L2&m~-S)j7T9ypt5- zLvz#;$$ZJc^NmP+AIw*0h^4nXbqc#$^`%gXyJ^x`=RoJ4`vhlHIaCTgsC7hc5%O1d z0ymEA9?&Zfp3WVgYg#VgE=2Y)HFucHJ+Wuj0A?M{YS+2LBkh~Nmpd?fB=u(7KKbhK zN~)`nYL5AY>7-@O^hD!Cg+r7sVPfBFKkGL0(D}|m%H=39i_jdc3HAc_VtH+EEvHGX zE_K!Z@;KIq58-Xx@EoJ!dW*F;k|)@UaOnZ1a=)bxQ_k?5M4bdUVY;WzkvWCgaB!~L z9KShrsSh-ucjAiO<#{3HO{d>Ed*=1!A5RvQB<2vAN{~9xxFu;*&@~(H=jm(gyN|QT zwCFeqI%(us>O>gHPn~+6?p$xHbuu~P%Fv0Nd$mZ{#GisA|D)!}kcz19$Pj`gvhU>-j6YOvd^b-~sNO+VZ zC0o{$M0~I_l?YozQYNuR*G2M_w8yxXxQ}srfPJ$)ad8WrzZG}^M@#=x%svmIlu`EA zxuIAPC#aH%hl3=p$ zT6SNlztk%YjY7E70oFX3!z3DLaEeITl22o)Hx9R(-anu2F4~JY)KrI-hk?0TWWxmq zrYEefTs-4IY+04%25-$F-)OdvUlk+gk_D4<1Z9b_rtLqy{0?SX=0Kkdml-vMR`p#` zqW9kRQ)Q+nb*G`OrB+a0P#a`?Q&?|C4yZY_OtIHl?CsekTXuw>f)|MJ2g=n+*o;JU z$Bc1@#OBy$?DP>iG*AhJA*?Htdda2kH0-!bbRS)S?%|wU{cz^=9a;1ViYpku;B?y) z*QBRsvWm-Y&(?%r6l4U(4-6Ta^9Z z<-H48Fj(zGpNlOGD>4M??x497pG^|>Zt#U~?%B9M_b63#O0L%H6|q3`(A<{?L2^=sN@7RlwC;(zmJw%eQYaxCBCcA;&Ho1t94}xU}N{KONcLht95XN8-O&AM2aGm0HZ0SH0Oh zeZfis67Rtq{z=CN^ZbOhI!Sx1@`g5gg5D%$^c+Stn@U}tO)Ta~dFMCCB?2mMjiR)1 z41}5>;U}=L|2C5M)GP<;N6>Rv__g$iIXs=MQ`ETy&~&SP2kGk=r;bZUp+h%Ko6=-} z^+B%ll3fKA=qzoL$%$P?!-Z!Kb}Xpn(-NhM7^Km>+oCGvLFta&CLk$yKvNusU*I|^ zf6Mk2bUiZ^PgNE^$aKjDO=ZgXpHoontz zj|a;XsgRY{3>nZrVlJ=E&zBBe^3V7K<8ZI4>eWjij@CFvTThmG0SY)skBzESxH7@^$8-ELatovr&pAe2ANsjfG8Y zHqaavwknpw(JjTEuEEqQP!FtzinF%ixWE_2WjO_90xj*j&y5Y?va$u0lH*xmaq&aM z8gJ3R4ei(|ePoy1UvjuQi_Ew(b~9qL$^J3No6Cel?xmV`W!Z`@W%+BJB3r>Ssj9od z_qK`_r?_%fS6lu%?5y{6DjCHp?mU(P`E2Ssb0tMkEHXOtDai7uQ_~W1Ru0411*@nS z_=v*7*?6TF<7mVN)uH3Xt_T#sd9Qu^NQ+$RJM{a){z#~?S%pj?nL9`Q5SmeW$*Ml9 zQYD)q6`3g%&vsp17BY@5$$5!>t0&*j)fcM8U38~}JJJ&YA4g{yhW#9bin6lu?V4#g zDMnq=*EITnt0xvTLf#=QTV?zP&*qL05fEa=`hR%{KB~5Uz|Lq3FMMZED`PtZACfmK z68&T;y`|(qYRPi$(e->bp_^OI#M5{J!2H8|UkPifBF&O&DqyOQBv zA)2N-4%K4@`bJnnIoN^=*im81qll8XOh%DD)L5fH_Py@xO`0ulu#D=<-Q0T_Vj_-w z_#;Ss5u__wniCOBD1jgE>Fd4kadYR1HA|Y;)mF>AK6HzM-tA>GF6H+PKL^QC`3XxIudn%s3Go*_pGRCurdMFAAlwzTman$7k<#u7 zC&QFv`Q+?994&zTzuPxfW0rhb?y zkWh%JifCRWjP2VSi$ao^&HqxhsH&Z`U%4w}oWs8J)+Az?#rzS+nr;JL|WR0UQ z(?SzJ@XTP5=8{JHyFO~Tp3ysBnLIU}JZ(gsd@aDa4!w~Un9s?IRg#E%$2|h;(RAVX zMm-YkjQY>xW4Tn|BFBM(# zUIX!6XIWlQX7wD*p*q7U^Cs%^{@9_vS=9nYL3KtBfEhw-G+g*?h3t+O>Qh`sj$~HS z)l`Kpjl=tj;$A&0s%m<~rU(|H58kOt({@NJ1y1eTc&gZ9UR(3kpvW#y;E*u1L~XIH%sY)>_7>;K%! zozE7$oyL-%u2-nFEY-AXZ>sTyY$e9cR6S5UoZRKCf2h@D3;T+kbieL}Lwa=mr<<3C zqwVcy-({i*ja4o!q zbsjUYAD~Rpm=V|0Z>92#h7%}DK#l18hL6(auNF)ng;L={wJ$cS@#E8U!GnJ|s?Mv- zVI>;4wss5$|E31Hm;^OQnvluv9sWcx!Oet&&k`|-gx<9=cSk?Csqs)H6YGX(;KdC$V_=z8ZT^fdqKzv+mMAohkd3yP zm|}Gv))#v74!O(;3i+w83!(wXflOzMI%MOZffGz%@uPk?FDrV7U=(yzVKfyP?Uf~l zi71gsC5~37OiZNAkGa}r2MFEO<**AyuzYB5DnsWiX(WGxjgB37d1_3_1i2W4GBn({ z`bVR#qtW%#)hd@^0($>2ytl)~BUqybgZ$b}fikg226WU|9Ah6t9BLl`@WrtXu?{XR z6(HEsUdibRbDZ=h#75rrgEot>FNUTesSL9D-n`ccXF|#?h6=lb0)j~-;~yfzZ5wSF z?Q;F)`sE$z5g9DUBv*fJ?&Qo)+ioAD90W?;4}!5v6**Y(t3M1&fy@}H5I?i zbv7dWvh7XOYv9kyYYB{xRljD41rZpPQ}Q73sORNzLT>RabMqA84;Ym@^E`3NOY%Ii zsi)-YLL!)zgYtf~Ti%6o?fvHb9|!P%n*KKnTx^`!vO64j{U&iIc%Cl9!d=K3mOVc` zPTbL_dTc`^xa~0wF%7XwoB%T4Ak@tSVzCV(xg}z;EfBHz0@EJK7)khad{6OFcA=w=2GHEd)AKO(vg zlHlmoOcSrCtcecsfp0CN9z?E}AP+q~KC`J#GEb!(&6Ddz9f*3*dWAXmjap}FzFk`ns9Z0 z)M|HU!~`$M^shqRxd_axrnGGq@Wvu<7|WOyV5uX{A-lulr8$dgZNGnguW7zkpi?=SpBInDSaesA!cJF>a@ z8GqRq7}M7Esp$5_seGU2*UCk+pb|y3W6_dD%Y>#Sp-D{q47%{7?^haubNW8FdAfCVcP{|X{j zK5{qbF+P5kG(I1J%u`N^Kbou_lXTLtp=-Y`4S<-!6DT%I1(Ti&i)tS>8Xm#zRd(`| zbKsiW`stoZZA=}8SZ+7EMPwcBoz(#t9s8`8)LG>v6E~baFgj zrW-u+x#kA)Io7noPbBRoks_A^kxFYvk;vqTfT0G2%?XVhdQ(wj!Oy_(j+3~1Dh|cK z@=dKm&d!x*IPJ12?i5BS2+d_CRtic%J>V&^Q;=myIz;|5!`xmwwL^>aIkAEeAmQhL z#!2u=uqWnWXEsLB*C@f1qYlelVrwQ3`jjIH2jsqNNlp2P_W@eRH0@Z?+70=m40$5Az zUBp^#E-dsKOBM*u&H}JEhTiE!?lmCxOB4hd2?Alg264RtX}$z`yZ~Xn0C7F93U+nK zUZfQaMSNpD+K^^s*2qAW4CI6Y~U>K@ooX(o!lx4S>t*oy=@Jv^tBIOiJs2vp!)9J z+58B7vy!TN>TS+S*XL_t@k7Gq*_GUw8{r>`mu)^b;5R3#$ED`WQ&Cc#Dmf{SE0ujQ z^}m20Suhf z7tkykGtE*HEPeF7yt^g=DjbgycgwLPKbi74q%B_sL2`h&q?)i;RjwA)Gk-Cy!Dw?M z{^0c>7u+vlR8WWVTI89)3k(kpm7WO>fae$UKIME}uknXspEw6cqq9K>I0ToUkpdg z7sgA4Z!xd8B=ySUp?mh4&v0x_7D!bAXjP0uh!zb2YuE-(6Al){c#^hTGZ&evONY%3 z#h<32P%=2@(v8?7Xq?cwl0g)J%f+0Nuw@WcoDS~OTPNjM@El-)XT(WyRw|-*Ul;OW zb>%URN+FEU^^zO}=t2;AQ$V>1TuusKO~{Ukf&vHxM!+I}I~A=uQ9Pn@&@4=OShN$7 zD)^bGB1IB0zXX^UsBHPC@`?~sd)eTiBK;6EOu8><@@^6M-hg8ic_AQ0q1?n_9C@eM zPsl?hf{T;8%^a9dT_{s=ic>XASC7dp;;Nssa;Af?O={xT2)hEZmu(lo^8B+X!Lqx8O z(r=7h@pE=37F3oHOKMNUQ(${1+py`Xno~dl&mFC<1Q|zMzGO!>??ChvUXF9fx!h6^ zidP-(p5q5tIibv47~wh*!haBS!>5gWAQr7YYu%UW_qQA6j%GBbUEp)@UW!tA(!Bn# zo!3#gb-Z~o>~$nf7u=*-!f%=RTvT;mLjqCB&? zzmL0@h%;#}QEpqxw{yOs?gg<{>nEDc4b~z?uM_(sUgd%tGgYCz3}D=c@F9uwx)mm* z!X0NqGUoduK5$#hb2MTO-HMlxeHNOJN&Do&-9R?hY@sQ&>Iw8rNbBdnZ1%Z{7=318 zq*QeFZqNZOqe`9Q#s}ND^W>N@U@ovxwn9KQT<{JPYi9dQQ6u+9^H<7< zaKQAkHtg(q9?P;I`krYAt#jvcOS~R4R_xMvkOX3{P~FLio(^SF2_GaGeJ+S$wdH`X z8PHN8U6a%fdi^J;xia#3UL=;g986aFMuk%4U2eMw%LfQA#Rk{1U$D=O_eS^>FE(X& zAuLKC7_)g8LXzl!XqF%%qjQ3NQ4^@>z!Q{q4MD7J1&)JY?8#>r&e=ajmy4h{NXXhZIIxG()QjIqt=HRPQE52&Utt z8LQiux-6zYZR?>bjK5O%EJDo(C6JdUYJpmjZ+-u0ng&2LLy-HdSk#8F++qw-?{*#X z8_qWE##R8!iJ!SGrtX5h*gF*YT*(^BUJ&z#iHV#?hW->N^28Q^9GSUt5K;wihOIx= zC%3iLA`c0fwod1#@Dczf0i|=pj$frtiDst|P(f#UTD~KFGa}ahWrcSK3KTMkzYVE| zV67n>2OebQJ!jYY?B=DlbP14Uv0S}CJ|I9O@D|T?x<#+KhjwC2y=D_L_l1JzM)tI6 zy?9%=W8A@DSRXg%4NfHzfsK9Y9)0=aM62TN96m}&w9QmavmN*Hv(!}yl$Jfez&^iX z;<(wbKwIX*kea*^4Q13B0d0DIXDw%8mqKWxMT`mQn2adp&u8n*uKNqi&k~6se3ypn z;7xi-!j|cdnIDnYt;7xD=zGuqW^QNrp{x+ z?b(#IbHGUMN>@5tB_ho);!?cp9$VY&5#lrO=r1)==w$V#X2{68Hqct^(9rMikdGI# zNVD010}nR3J9nHVid%c&jIKLUBKTlsw`e$CL!ha~f(9Sv<3431F%vCnx<( z>OM%HIu6|7yg0MC2a)2mJLDho?%d1ldHBCl!`K)my^q?jl0jsdU_V+V*Q5-xPSW}3 z4V%!Xb!F#>VcJ8A>47+0@WNE4GaV8^JN1UkL12Nf`ajo2VhwtQ96~D#5$YW9au|X^ zDgTKWq>W{vBoG?Opn|fp8XaYkq#e=FpQjm_{?2WiC zV!v~Qtwm;6*^?q$_)EPQ6}+rmb3-Q?TZOuSVVbvv0R@H@Y@FU9K3yZCI#Z*U2<22+ zWvHOl_(%Na^*pc#@NiR+@wj>sjwsrS+ysd>x!RapefGn%U0j$fV2QdCHGD|Y*-vb5 zQq9%WD=>?lV5mYzc6+tYL|#BRKfsfVZi*9!i4NLIhCeg;L2$-V$BSr)?04|5XmSbS zss!`xxI%}vgj18IQ!;-`pNinn@d2XnR)s~*@LF=%lRIGd8b1lYPGK&Zut#3!xL0DIkEFbG-n9}gID^osV@sIOXIog6 z%O~5=#!Gj5)6%RhVSH0Va<&yj7GQC^q_G0qKy(21(F$?Rqa0ixq!M{mv$mJHLc&&Z zmSi)DkP6iM4Y5!N707~4XJ163pf>-kT?vignnI&!doDBOUuhmZ{@(0gMz%JkdIxjUBz6@{ z|BNvPzr{a6kGX1Rm;7a_ZLv1jXNh7@IWWTA_bn$^RC5V5YS{fv6MO6nT$bl>k2g`` z1mQ7Xv8zjn*QnR$-sT^S?tIdO7cRpQw><9X;Z}ab58(lUFOY%BDXKqR3kboX6eFNA z$2m&ZLc^9ENIb5CgeGgvE4gh;D;}4sUtMpHjem7d?bX@a+5OvHascjYT8#SwrkUG& z`5k~w7&+8XOMSME7%?>%%j_zA+_7+8R>KK>0@X~r z4O@BoOF^T#Lg)T!)8;wjM4RN-I6g=D)DENop;Ml9=+t+e6DJ>f??q_mb37VHafii2 z+Vzy=cLbM7Z)So)%FW5xJYKAvfQH{{W9=EXQA@SLCzPU+S zA&I+tAOEIjTIL+mpV2~y_9vjgWMxY)X`o<2Ao@Z;Ic2jb!t2^nMR~gCy#V7K z`@-Q=Ov06ZD^6TGikvxX>2;p-6mjUGnk(5A{m#o9=7h zHHtXLhWJE)i)v&D8Y1eBZoqjm)On->V|4BKr3xGO#xN)xUiBhjoc>Zp6#Df0_|%mg z@~uqBmf=SA>bUO=kT6nY>2JtLA_v6W;(cRpU6p8ejrXG-`pbNrkvMsU`a}+X3Td11 z=i-;)=j+CiiMbQkj_l-<_CDBVBb4e5SY0DF`42{LNA2pkl!-tPBLpdhtg9%_VcSUF#^;m)m9!r z0mk(IbzP7s8HgBJ{|hp$&dNl@$o}7LW}@#Ly#J_o(W|qv5-~9)o+f-;3IO=vEDX%4)Xsn`AR}?cNdX@spNELEnRiqBbJw{2Qj|$yZZkS#&-Kg0$sU&5 zTs0go0`Q?^IVb17sb}HDr8EZTlb#(*wg$-cp-Xk~Y47{S=yr~%5sH#c7vI6E={Zqf&?O=~BA zg1gA(FSs%B+>0oRxK>nok|U49v+ivD%NR|aMq^^~0qb5)14W?Cq~QqZ-1u?fTb#vZ zVp4wW*=jY>!N^RereRtK$ydNL$0j7z*jK zHcS+OQE#p4VGA)_dq zmEj^f2<~XixyIrq>o^;KA_Ow&=X3a@`iu$g?t+NdJo=4R)G`kkhic$r_HOrj$aQ^KdLZs6L8S~VtFs`LS*N!(2r(TQ0 zd%(E|(^Fe8Z$vwcra}2xO49|i3@)Js`SiJjcF{Nu3hW9W=0;xkQ!S{%u?;ltQP~)m z5@ib=KxQKG3z^0-Zn!xP32JsO-Z(>VOBuDGXgqu^iOAh z6?;`s+4>&U>{YZM%0iTZB;XW&l}SA*rjX4o45&8~LVAONIe`C%Tv#j5+UqfZ4MPMj zML!)j(8V!VAXj%LkOvzxUge3;OmGUm83Ejd6gzKv?|X~W=BfMxMblyDsEo##PkgD@ zbl|6mYO8{%o&Db%ZAs*N1p$#+Y07_88VsU|r%x4W`$9O(w$)ZYE0Z|SC|HvCctQmETxZ! zMf$%MM+gz@SA&m>;~ECOg9Y{$v^k?Vzt+fB3cOij;BRH2FV6ve$c-jCHB8smWJ@di zJR2d6x9t(K#hK3>nnA)7&cbNjCntyeh`==Rx)?D>Brjh}+Uvk9pFaiIpj@ST_A;|= zCm{x$<9q%7vK#gW3dCiT1+MqS(@plmBKNLh?(mg##xxe%YIOP>)ijt4D}peIFfNph zgP7Ig)}w(z_`jaAW$t&#;fF??&a3~>fXzqP58KoQ){iz`nZ5Jm8)`w0-pWp5l>$i= z@7XfDwTE+GnK zqumLOgX!lLNRrWDnpo)-LgHf8d5 zsx&?)Apt%T+3u$aoM@mmFoD}OE`2+^&J}*jj^LvoOAw(D-`> zsm8=fm2MbR-lKlCeTCaU`K+@DdW-RuWCp=`TyC%(J*CYFLgTr#2&#Twpk?UMJZzFN zj}!^@t2OFcN7V&`7LCGa8RO~IN@T)VDjm(EBm3Z^Z7=attiQ}NM2G(7a{+$7X~Jwy z*Zknk={9}1K58N${6bwgDFIH`FbVkpYBG9U->4J2#yw}h$#urTVEPTD5%LasuHFmr$806BoJT-2?(d3Fq7dCxt4tP;7;wyWfw;bR;lDoExIOY zPgA(KE#51O2R^4(TYVnQf1l;F-dvt9$)K3Ogi*?ExsgO_LFgChw31f^%$6MoL6FUn z)+g__RDii!836I}BQq(YDO4=D`!L-S!Hclzp`uR~#9Bz=eA5iH6Npti)vo{j>Z5kB z{xqf71&(1o*2MzYZUPi-JlHB$NN5UR3w4lsl>O2H;0F=4OSuzzLK{`n-kjt8ev+up zr%AzASOKoTk5?vC5rp;wsq2m_G)~|~&D+65dFP;$y7tc*N#pb7A1&jP7xNd@W4%Po z@9_GXIt_^etnv!*K&!jYj%aLZ*bhKbsM;5!3F{@iBf26I7JY{T?kO2epYzO58K37d8|0u+R zpYWO-NjF*DCR_Qg`Ic(z_JIPLsgHG3%d18wvuMn7V#8sGb&{&4l+MCuOMzhapM~@) z5oUNOYuNj)5cZXyKRX0*qxW**I&H)b!wm z9*qVQSm~f6vq*Z{O*m9WZD9`2s&w-*gUS4oAV2cG2F4|z!g+!~JY56sj0y4nGVS$> z-coJ9oXDob)Bf;NJ}0AbfRm22$b@uDRh2HfW)~x2Mzd#**U7O8(ZP(6#s;fFtbso& zXjz2_NhRm^T+f3-pm(XAbz6$Ic43{cs%EeXPf%pXx`DpjkF&5b5HTg5LExo+1$;Xq zb2b3>7P&w`8d$2Q8N>n4>@r9=V=VY&+-l5&6HN+=z_;)%CKu7248Yo zUz9?u2(ABRSk4u6^^c|9ay3zm7&4^`zMe|1Z6oJEH(p@fAJ@f_TZt7x^`a&2;;o{0 zxgZs<4^dX7Y=xs_{B2mX?3~h0mmBs~xplBatwWdWixx#ZsEbBbV%^V$>TOqfff8;4 zyCKtJkVSvKVCrp&9cd>PEx%A8p!+8HBDBeQda-eE*g%;PfI%Odk5CGNkm3WWGlEYA zHL>zihuargA4cF-P!Ci%*`w+3v7}j`OJmU5iRN)F(1v`#t3_R@mUN#0dt=`ou(T)R zaod47a_hLr%py=B(n^z%5-u+lEK;2CW9?H2=xRQevM&*|DPL0LAg~7>uHXo==o=J2 z?OLLw&fPbu>utS8X8G+!h#H0Zg_Q+D?4hALxU#7O7yEP|=;#+nTYV8|O!az0CG%!& zJ1LnjH17e0HS0mH0t&oC0w>?1SPYAVBk6(mvI7;1JNfv5v>_0nP^o^+{N|7WnA#B0 zd$p3DkU9SZjLG;(k^+Heeng7-5m*7n?Xc{4J5p-SnOpRzUGeKzFC#=nS*eeNrR~_~Ky_SMxV)rKs`tEa0y|tm|)=_A9-mjfxH))`(9Yaf?tnrQqa4O!qzf}yXYU2Wjcc`sRs6!eg<}0?#fc{ae zf-HX3b&t~GXE!5|Vc647lRn7$&TV}Tf_^75dKrzq68h@w?de0eg-RI|NOSOE5jY<) zAn@LM5u9`@53+ELU@lQ_7n^NKUyk0FyK&O_2f6~Cgash-x~#o)6gSk(o(sL1#g@rJ zcD*>A4Cg=%=S9=kRZjr$vpAL{J@}$iI))CBwMag)n6pyKG}zxR{P8@2T);m5sW*TV z`#K#tu&*2f-VxzY82%R3Sjpz7=mCuzt4@VX##CTgQeO#+A7cJ*D>?ri6K@g*$c9Cs z4TR~ki!f5c+kw+juYM9YQaO%_-#d=GZ~*KE8V!&Ul|fq&n;E+za5ocIjksaFdWHtu zL>G1~>+w5jZ?m#!OeX3eob^HsFC;K8h2kHB7o-55;j}&Idr}Zh0>`94K1wvS9Nxda zmftk)eALl5Q?j27Suhc$11e0mr_6z22E8s-!i;Tzq#%YUxmQS(A5e?cN>)sM24(la%6m^K zua=Q<*aKmKgtRp)j$FjofQ+tE_93^p5rp++J-ZB`S`3%sQ8 z(M*z2B)e$dm{*o?MlIMhbD1SMtF`=W(N7IED=O(hz z4H3!b$8ge}83vU4u~eKcAnGIwF?>axI$!Np>0f1GR?ONh#`spQvnI`AP&DkERsu61 ze;uSgl@b&!R>Us}>r?<~M+i*tAaGU$|G-Cn+}vd!bz(a(nGM|+ioa&l>}~eOTh^k% zn!rH3l~Usqz^uWDq`EazFPy;${^Npx24Ug;uj?6@GgT=OtR?lu|NmUNfFEt{|BZ!? z+2la+$*tjOO%=@fdUxqYX~bsycs-w={!#BNTi3(|zpfsRLyhdYzS{+| z0lsg5UAE7|>FwO^_r4t8@1K&013eyce1#tF_S)H_|4y;ic|} zfw{-=5X;+-Wcb^2cR01=TA(A*P5PUDjbGNC@jRDJ8qAxyH>s2=Dt)i-@aCs1 z0s$;WyR~o?L%3`IK{%^FbwQw`tj=v7--h6~Gg~dMA5Q;ccPaJk_aJp!BD3$zbL|5q zSOVcw(sLi1Y7RZSCsCR$4e~*I@_JH@1c`uXarpB3wfj|UDSQskYU;~2Y?RtFY76)! z`X{GGU)jyz9ICqvi%nt%u{Mb9n`A}svKtZ}w!2iT0SrGh6y-z3>1@wINW73|hcmtqMSpk``Uu_bvTV8W%*To1 zQCJD`1*#HUXKV+)n-&8jNs$pgP6lw}+ln8ueB^hil1gF7Wc=5Ieoc3ctq>hj(0^GN zs^$!s1xKb*h_=gUDgr3$o((4uzTouVZp9si8h>wN`XMdG23#E)DKWLZ<$5!lW+_xy z3Q21|d#KzFj49uWVOV8L5dsNp=vs$R04))ey?Fem#8da%oP3f|UnGzjGCjb}{5~9m z*Eq64su7EG3sfx!^S7Ddh5vXHr!zUOd81)92o5+Mo*H3;;@Gn)+l$CP`fh2CogINk zpZFE_0ye4gOI<1Z43rS8l3i#;!Be)IO{qIV%^GQkz@+?6_DiuzFy?Quw9tSN$b5#J zP%l$^Uy1EVB{W|VGbi)QNL>Idb9(4pZ2e@A*=Y!(U1K%LP4Ebl*EEALF1Z_enn0Ab zxEp@qnl;{p-I}KbP=?K@gtSK&0w;9T!8Suq*HKM$u9oiGz7aBmy&`Gaca-Hmm zQxB-_cTTwI*0L05_`ufqk)Yl{J$N3Q^hwD30KIqIhKPaeNfa>neKav~xmk7pr!-O{ z5~(PnE@GVhjV$m#KMc^Rt=Ir$3Toh2?BDD8n8c)RWIEOZu51M&uU#3c7Ilx!$ob$e zK#_~)Jqr*?XI#Sb<=&Obo?{CCz7^=-S?I9Jm^}^?07ATln%P5&q){+(!FG%f!ucd6kG<^o-xb# zoH}X7OCBZHpB;b%^x)?_-Z5v+Ra#onj@|JBnmqwxzCT0S005Sg@yC%bC)ahrrJOg^ zoW;7OIDJRIj-u()W0%WpEPqGigM&%5Uzds?zEa2-kPm^Fb|wZ1IGhX({cXHqgI)I= zf!!>8Ws~L~BU{q%Yt^&zC198at}6Fzq``R}p^g*N9Rm1}mpYT^7!tKwhBas_8J-0T z)quj1O1r7T)>GO6;?b~ri;o>PKra2H`aR7yT&LJbAkj$RLz`PEPPs!220|Kx#OArK z*<*wY7Vh%|0%o6D$?kaoVk=~=YgkoyPK?JhvS%xcoOnoad1)Nni5sL*>fqz++eDu( z;jm}ZCk04o9m;;tB?@o)xeZ0|@0t?!`%F&C#}$qotWceR@P zD~`kgujrXgwh~n9OUB+;67HzYBP%7MDi#+DT%Z8ienw>CCxxgz8a;aTD8eURE{mIR z8*#okBLF)X3#Rw5V1iB33N!P7saW4lDTo&CqY3a(HP@lTh83UQEbgv0npQl9D&%jM ze##0*j6>M4D9J?r(N~U&@7AL>Gk%e! z*8y0zQgiBIa|B6*LB(4j|8iTib zx=3Ax;(d73GB-w95iQWORS>*!9KoEgO^^<*?|>=bn-6F?dab*+Vrvhf4cxnHZ!TxW z0qeHO1sNR3p%BKE;&bqaMR0*?^t;DH>bl6tAMH!!C=x2%rc+(lp8l zm^9@$7}9YZe(dh3RzdAlc7nC{B?guKV^*mg@vviV#0v4SpZ;Wy0MZ{WlP?@J8Q_aU zS>XgmtBGU=1QR442Hxu_f-gBe2i_Lftr%1H*{g&@I-poAK0O&lZ+8}!Wjlq;Jv8-~ zX}@yp0bx1$z(|3(7=<6W3{r=`@RHO0g*q1J^d|!XFXODssr#K&+Dx#Y%w;md@=?y4 z{mYzL$X}LB9mkE?)Vf`WK=g$QeZb&3u0_2qj|)ZmObCgdX(?vLU+`uv_SFhcp&b1&1YC`Qd;TNWapu6PKzR)0|mrlouN1mFOsry;w*s zWhk=kmn4!cbMbx|RBNp^c^8FZ)i;k}xVfP;S0!OH$onXwNKM+%ViN2JO#nC8DWeP5 z=@r|03R@f_m{wjVkiG<{Hfpm~hKPygvb}Xc0qzlY^5$IMat8wh0KstVM#Z_bSUnAw zq&`gjP3|^gxU5EL+CDyA-gZuX;;`7X$m$f^M*{rvS2A))CW~ndT3!Da$5VxtW-ggb zIUQE`Tx}b_PrEezEw@fnBtYUI6OJ~cs9vE-n!EUxiq?J#@4Mjh^ zG^?KW(qVr*^WP2%*rq+hxUbo3Ym2~{=DLYfbgaf0q8Bk6tPd3_16VN=JOF_O)`A5= zSj!`3-Z9W1potfkVVsg%7t8mZqbDZdnpTo37D-k{o0a2X?FN%xYFVG#U()cd=LmG4 z1DofT6SKPs8<+6vDa}~>l#%bv>z@ttjlj7zN%~w#kjc2cPv%R464K;$wu+?0YkY7o zx#}}hDU&qaOa(dQ0jjYQkj8`&c;Xu9mD?wI!_mj{6Y+IUZK&OSkXh`V(yg|66Oi9< zv}Q5Bh6sc-m08hYF-NrcDwAzWaF9$Df4LA7dZ^rhI~ER0sI1<4HA;rmt_5}=rNxuZ zd!&ewjFTmo3lpv>kD*4992qgnJ8l^pDoeqb((*iGya7uO0T2i*#H$Th28fV0@>Lm_ zTKXNT$%A$zE`RI5fc&Ao)6(SSzG%fma?9;&o-JfbVj&N)>7WJndkrx1*1{7=`J-Fqe8i8(LuPjvPaf-F33pPa{NyO~aVZVhj}{E=U9w zbiOpce%~c*0i3(h7|Y?_%z~IwQNM9m8#bwknsG)AF_hk7ZTfhy4X3p146|F8xVZg; z=}Tz-7txEpE5D)5TNteD;O&{aDz}G2iS)(sb`<_qHAK{k!jTvi!N8xqd zu$_wm=iF?_5ZqB!JDe9f4H%YuQM&?M1Z85fO zo^Y?0GAI@2O)W&l-!VYD4I74C;wjK}x$(Cf0T7fF_)fBKG5C&1_G%>h2+o~cSM9W! zyEnqKCiW%^{>7(Tpmk@9HX{;sUzBebje9zwY!B9`aaRG4kq{~x?}#w8`mObv5vQI* zDv}_Ii@2!5Pqf1U?q6RfUXL`Xmn5H{GjPogo_vIe@Ji5xLaQVy***3qEbU>E`vvUS+BYHb^P|Fl3$>|;fneyVc!^*z zsfYn!)c<=0yclt4DU-8XD)lZU%pHF*!Rbm zHvw0N(}uol_+NMLHHf)@yAH!|-X8O_GdIq5-{Z4tfag5pgYlo2qSMf$o7voBL1S^f zMVHaDIeT>pLqZ&uZ*zI%VN3x5L7%U+D?Q!EO}1~=s~mvmuhiRe_vs#fxzDTlg$}pp zkNc}w*G+*>>*tSYNWoNA0M~0O<0YYs1K``JQtw!gKPnZn|4UeRF)%a4p_LD77gGH9HJfwWwrIcS>*k@Wu-TTb1$*Ndu8>zF+2c-Qr zfIc?Sp`s|iJE(pxbZjC<+-3#OohCOVyroEM7Oq)V<=R6aXzYLF6jz6dj9FW1`CKHC zbBtJWR~y*>`RF{R2BHx7OMU1wzS>i-)jY{ctABbEQHeuiES7E5ldV*;pox&bS72e> zFC|k$MJu2p7ICQVO5a_(f3j>E(BV)nskN?*c_)DEAlVJik!?lO=vu2>wHfozq;<^r z)%5aX(G}^DaYF3P_g!4K9{&mID`08JSmE;}3m6}MO0y}GmmfrW*kM{F5LDp4q~PZt z=d>3)>eVI^k>x>pBoHEA&`o9nR9yRg#X~12w)^$l3PPXOwsy{VgaU#9-MS!dK|@$} zdtfAJ5#~nru1u4f0g_D`dJxT`mmAfvQ(4WdNzwbEsZjr1!Kmq@!+?=8m3B3LE=E#%tehbM93fq8&Y9A8L1RW?RE3Rj7t|?} zlS-=x;2zVpn=Cl@EsCyNo&i?2-$@A z!Z1x0cKQod0uDV&V@o@J9;seXiyZ}Uf+%5#e3XDwwvUlKo$4eEynID6oTiraPFkyE zo>-Y34!%*`5Sh5KCo~$NE?YOLyFHb;fj5^S0-Y&={P+cMNa=4~YB)oRB zD8cainEISk%F8W_jD(PK z9D6p+k%$&foNe4I6V8)3FuNNOFm}S&V$|yMl5)oqiwHyj4=kttGscm_V)CpSNM
    TxNXhyBgD&u8Eh_M(kP-nTiF+3Ytz)^HFkx=@zb|K`A+*jY{%x8Y*%iN zOIiPMkL%}ED8RBGVDD_tQX>j&_mXr82!lnIcKGeF0yltd#Tv=Y<}2i-K(`mEqg$=! z2W_g>FsKjM62mOt2`#&y=?lfFqyplqK$>y*|bO4wHZV<1uf$+f#izQ{ERe)^w167L}&i4Yh1c$kWrJ>E^y!rx&-N^BUP27W2A?GnHFqMWHxV&rP z)5~>LEsfOcW)yFMi~tow>MM}xcJWa41+>$X-{YmkV>RTLYsA|9A;&im+bysjZ^~xn zba6?ylXhKv+6T6X8LZvX;*{yhgrhMhpDkx&1ci(A*|*bZVP~=s3QWLhoPuRVB5j52$cx&r!na3${*u=Zdh1B1vvrB8{~krwj7&_y z-%A%>cLWbX!dC1`{19a3sw4pPb*l=X`G`LlCSOJ*Q&QXqjr(-LckVE4#&UapqU)+6 zTJtAfNC!!VCVg`WIFNa?S4hsZ%80*1x@xvZuSRhdT*BF-o=RKT&cAh zN%R@npDMCc++UeVn>?v-5kCB5(8&EK&_xAmvRZhVb#-L656Hb?R|p{)f~#_X`}ph~ zfq}|dV177jG%~?}>|HI%+QbuKvgxE(l@*6;nBM<7NpKCXlT1hNxVtv%+L zweCf5Du-LJ|GLL>x_As^(X;OWq;RJa#z`C?Wj4PQNk+_F1zUvO2^RS^$9ad3cF~5* zc%b@5&A?@b&Gm3+J*2x6h6Iar{{1gps2@2PhTJL|E z@J3u)$@QLYn5(YQd|Nc$(n~?5kBQkiJu)2%&|&{0GF~mO#*UmS|9kfc;B)W1pFNHL z-k~Y^n^7-OUvICW>{E>F+lOO)?tp%@<4sCiXWdax-k36PcOEr8CIs^c7F^@B!6dAs zx+B_kQueMq+(QAJ<(^ z8zmso(%%rux!@e%G*F79fw+&RY+Rxv=IVXVvP06lQ$17;Z?xJQz5Qp&=Fm9#^&wZ@aKir;N=dX6#Jaeb zHCnr;IbkW<|Ix1iRM_hKp|3xMn!L9J_EwyFhoBN5&Z++HwNj^qRvLJ$c{B{CiNYa@c%VLZ zPG-LwwZrD=5I#1fx%lU+@0Cyt?saR1?e1EAJ5_LAkw47}a6wjhuQE)E+fJy-;a0tR z3alu0sNsiY76;~Y*2q2GBi^KzLm&vYbP=;zVL>{AVpE>0P~_x1D|3-w^@C%kHuoNs zNLY7h4;Nr5iWYW2QdGn+Ed7YW(T!?(n{-|}UAEgaqj@JB;~=R{O!EM!qJ#{)>U^=hryKGTJvS2Ilt8W+shQd^&l=4MYp@nB!OHrZlUgBcQ za1JIeXpwos97yF0{tBaAg-L#19v*jjnvXi<;q8-v4)!g5c_TjU;!88px2j>T*17Hj zRhq`CK$hr%-BqSocj6z-Uo(7QC+$lUUfzwaK`Y8m@04S zVXF~V`^c%H&~3RiQl4~X3|>Cbt#qoy6lwaRIk#e}{tA&2lMjga2Q_>Jl#uwp0tv@y zazFq8s%Pli8{QRb5F~issKi=Lan0LTw8^k@4dIY?_4&$#q`r}m6TiUk;kNlHsiGRg zc)S`yJlCI&B>3*CVNKnSWRV!utH+KQ+nqH)!%p;r^t z_S=$rWkWz}S$E_X{M;d8>v;Dc(kS@9+|dMp*3&tpYeqyaI#)Bexyc(FBZ*Hmy}x9v zf71p~lynqIN%6OU+ui&nV&jx(WLsn0uM=_-;>nB+*o!|yiPW?aD~~zWeSU8`gYo5K zkM>WS$%;MJ%ZmY(0==AlG=bYjpp}Or>Bl*$J{u^_raI6tW~c~Dq|&(%-S!5|_Ldm| z#`d}1Z72k4#u%SMfE@?Mm6G8)~j?=u!ZWy%6fnsnS_PHXv z1|XINWU??~!YBA}bPkaz#%uNjwBy;=XgvcE~o`n7^zNdr#8X z1|)iPS&#w0LVmr=CX@SCP;Y=31Rc<-htT>{b;!HZ4~&P=(AOyoH=o3f?(vQS+D|6s zqw4X>ifsL{#@U*<$rCyCbziTrHb*g&OkNtu1LE}|T4?zR=}9!zj>h8u&h*6@{?*0X z!W7z+0^UE@ba3``Na?B>nxCA*WE*=85KAC**rMyPL{sb=_X&&IgKC@q9qmD$*aab% zo<{EgL4hiBvRF>@wrZ-`OlzVKC^;AG#VnI?5_1@35MLjDpA(HLx|38$)f9@}Flo0W z3PqbLg4@km#C_GN6N+<`RXi4B7%i(#;+msj4EPg2l}(mzD{n$AQXI5v>Kf)L`kF^V6P_v2-`EqVy`K<%ol>Q4Y4)i7-lW1S&7W34-Pbbm_O;G zxBW`uRqmbc%I^+CGqYI(@~l&Oz`PBT!wieI5HHwa zF4#o)wrO6ecHUmjeW=r}Mt_z14QvW~F_-$40H*x2{r4(?{m`LViP*XS6B0@Nl?Vn% zMQZ@VNrg%RqXy+;Ecp<7AA(4(E$!klYE`Nz z;*&A^z)KyI*0&^gwOS=p`2uBM$B>)fvl7m4!;XsIo;(1Q#x|du;hvnYuhjYL&l34_ z#vbp_Z^S?OJpcRo_sgyQ>oC?ZSKv=WiQ)IUpg1kzLfQQ8UCVtTz}G()AvbL%<6IJO z4wx%G8G3Q5y6sR$c@xN{4gX{Ay^x>HYhAT|W#(!)XJ2OKaqtt&FTr$Y$%o#3cpFb7 zI1b|J`g%eW{YG3Yzj}C^o;OUMyBeN9?|DyQ%l+W;r#M{3< zuQ%kpVXfG{knktPU+YF#L*86hJU;x&055uj>Tdic zmuNB#?@4lzUk+)`uGwgF`1s84ssr4P(Wr4({u?rD?KXhv?!Mx!s&tlD%LkZnbc8Tq zly_ab-_(8Acr!I*3shhIs#y2!md~A9i^T8ji9OyGx2|~yI7Tu4Nn37q)Sda9z=1VT z5{4vTf7oCzU#xrFr^8NJmpiOQPy;%@p)bdK%DR?}BnajS(+%$KL)@!{cpqFX+xbXA zcwo*k-&)(W&4f!M7H)fWN2bi|lT-clfnPm< zW1w@#i9SyO2t-04KD}bQRFOh1mRAfiM=R@lH}^U=*GuPy@^e4wIw2NsSQT8?MR5^+X%L*TOl zUn?}E+6x~=OHh`tbjP{x@--95$+!^Lr&ry_@Q?@ zh8`=F8WlTxsQhYD?6yvZpPFJCL1Z>sv!DNm?*gse#lOl(QZXtUP|C{(G5A@jTyj1Q z7{q=(%_NBa+>3Ila(I(ImOPGYG()>z6oFL}vy+-N-pyDrc?P{}#vI$V_J5sH_a50=Yb+PY!#5;H4 z(fW7p0x^PuGoOyMALN(;BUcoVCKtDFJUR~4vsLbm=d;4pWSJx~eX7}+lh?zI56@to z$ZY!=#L~*KN^a-KASH87I1;oe&aDw!o%Wk%k#nUE;Pu(wq?|fdHM%?##ZNy17^TB+ znab#?RHrCvEpP>5olHP+RD2DDyy=71yLkQutnMImSgT%Z6n^iSw;%uRIKx@*TVz@C zh!c5gOoFPtBDUW`RbN^!cCl*n)+Z9BT7O1^zZ57~fA^%peK75@NdW(R2P$C! z&$%LO6-=kw+fdosCX}9>KSSLD(0EZ}+=X|l*i{1&B^#p~vqDmsS1CYUik5v>$zMXa zuP$m2!&J+cPE_8{{0M49%}OyM7J;xaiOcLtN`ZwZ$nr{~^AC~(a|N(zYvGb5)}+b! zbKs2AUctXM-?1+^H5^gxK|!HTZX8SlLA#jG5olPEj(NIUdu|xOSXH3_Fo@PIiIt?? zYrtR+GZz9vEqF*yoT(P_;AtG|pEY7<>pKXeL!T$u|GD;=Agc;c|8(t6ErT zADz3OXqcxN>GE4A$#1|%S!fCBcw zZ?PVk!_6n~R|rhU_qUW$i!xW7zVPU2P$2c7-#U zNxyM|F#e^)x%ed6JT{rBDF7|%NQyM*8 zNOpfVSCvNCh>w2KN#p&fIC7A$FJ(9Xj!X8wm(z*n?U09*npCJJ5 zzvWQsLrq7a`8A@#L-rI<=Qn4T|cKr%f2rHf+!vN&njX^~di7I7T$@HNoVJ{-)Bh%W zb7<`Ec^sFt_$-FjrP4(V`HVFIn9qS8j?xWC7aGZ+dIqCZT80LN=c;~@x(|+;h>8Uu zX)A-Y3-{@2^F=V2G?Z?T?1|PP$gj=ib>*k^eVlO6VfVeH#gAae=^%OHN}Ay+sI5mgfqEEJz-X*lMBcTlIPDHw ze|DbhpMygc+G=y54v)48VWJyTdPfR?U{&}B$T~@$XA4mJ=g9~w>Uhu{itp2xpup~a z$hcv%_-%q?{>s@Zz<@~InE9c3&yMDn+`?-p!>UrfyRJo#>q#ouzp9*R1q#;eCS*EV zpS-}yHc%Yc%;yc<3_&@F17Q;*Y)NZAn~)Q{HfDRMc>|==T1`-duhR@PSjG~-<@KcV zD3=BNKw&=?RG$jD^A0w*-iyd1EgTL?4N47#{Pb*cV^5Q6=nHN}lQLp)nx&MR(;^9j ze?jH4lW0J?1xZ@$M90Sn>IW5xsV&3^s$#e!Is42QnE(_9qDo%9*ml6|1Ox3@NS&99 zex&(Z_&AfwYzpC?pRW}Zj~E}IF+yGV9e1Q826N%7d;VqlVK0I_8zR2_@rl5!XU!w& z6WaRRT}SN3vpqk;JJ6?EsR$n^m6af&IH_k%7aQ&GS(NL@ulh4dM0i&RM##HN@vzyT z6$2v{#?xh@#asHWindL}(zoHhXGcoB?Fs+k_4H>KF6(&r`<^J;a3=yZZ0a{s>~6hW z{1k#-bHzyy>lnMKp^1^mEQhQpaFC*mQ~5yUwFovjV=-06fm|~Mtqv789Cr}c!$*jx z-77L98ShcqVx>ki-h22^j!Mv3%g;A!NU{l_p#USkLuonTPwLa#Zs><`Vn3Bb-7pNG z_J!Kpu)W=NqqoLM{$&R^nO=(u=p={*c(u3}Om9M?*%fMp4sfx07WXdB9#-=wA0&?P zLh6kZ;vC=hZC}t6{7s;4*fpZdmjzYl*~r#Js#P{;<9*MT2oHCOpap4?84Dm#T;@^J zj@_>*%=AwtjhoZY5A82~nP^oq5>YOtjF99< z>Z|rvOt-uO3*w=O9d)>gX$U6PNJnqR;~2RYaSaV-_=e$>@t#zu*0O}Az*cdc{d4BX zCDN}b>e8UE;ryC%%Zkw|ki`)Hb6JqH(JV@|Nt<~OuTXk1Y0etm2?k-2M}i32X@f=R z(tvh?eLEgPIlB*NCqLg-xV3n|EqFFsEb{~3BwZ6mKZFkd5I zDkft)84{+NS_2SC8CM_C@lBT2 z%U1*A1NaOd3MS{9@WRE-t+++?=@QRx&8x;m9g1(^?U z-QD@Sr+z__+B@``H&Uy)@H}@~m-EBJ_l#qGC+EwIHZ0U&h3N9oD$c#!M=;O!Mx^b2-qYwumZ#nUMCLS4l-eVyNpD;v92|4EYmyI<2Jf)6f`PzosCRHyr4;JC zVhJogu^SV)`2KM`JW9zcT^e*5fdFaoaghgqIO!B-tB}nV#ya3$LJP^t%0viyQYZx{ zDb_HWkf6vA8gPYim`gLb(4YfoItebC4$~-&uME#a2?M}2?j35crs@ZZ2pnZYYfNDurB%XUF8NtB>g7R zrBo+Rd#82n$AN~hV`D%Xlhh~{Bzbw43@qM#QqV1kmE+zu|n6JG`O zfJxL~Z4I!k6k{)c5ghNhFW!8#V-cxpppdA?77KTvRbolw3GorZz#<9{fEeQ zI>(_O4SHw@q1 z?nge?o+;i_&QtnRoVK0Vk9%rynCk4Z)Xpl(L}N4Ah4oI+$06Z8%n1ymA4?TawfjD)*Vr{k7Ny zR0o583#`0`VqqX_oK{qz==O(Q-qOkL|4AO4gml>$a>9(Mkz5SQ2v1$=9nV)QeJVfO zD}N34{xUZ2n7q{EOk3WDxEoHq?EE$F$-pLmY`A3{i?%euq z(uIY8g}6_ZKSd9C$i;PD*lN|!|5^Z5ZZ#sgq6}cT`$#(lAwiZ0{F~sLUc$0qGdaaW zq>sTK=YxgKm>~=k<;xaEWh>mCRWs$wn73vV1^Em)vXbs80KZ2=nTb#+AlG5l?USH1 zGXDz5B$}PJiso>^;}o@6OB?1I65|=WPZtx+hj;i(NNfw}1iw6iB-`WQ2_Peze{N0o z#Ilc<+0MsbV|5gTUY{^L=-5c1S_{odm z4R}bW6VnI4u+UmC99%*6$im5h(Hj&4Tt5DY2*IB);EBr-34uR;cyOi&1HaZn^rG^f znW0FnX(9SWb(z3|C-NsINBXI}5MNsZw+5M_^4*p4esc}Ytz!Wbb_K^%709<{w;?-3 z6-sz0P0)!!+xJo>&1GUmJ9&Y+?Nax}+U+RvvGL!CCA6#?D|_so<##70+8 z!h|0QIF+90MLFu4pnRG12_qPm+SLy8IfX6$g9^9`55-&GF~+jPY}_I5-?0JG(;HQS6FUB6fPuv6!hPlzX@#*Tc3 zzh#|&u_-yn92;NBt!JnB^A32Yyy`8yJ5Eu8ZfTiposo`KB- zfVdeRy)wQL#8`^w$UJ_-(Osm{8CX*ac5Nbf&u_uZu@CfG2fjVSWj82H^Y0y}Wf$r7 z2DqD&v3VaVdN6c?dBvab1i>dLH;wmql7uOyGn&8A@YmfKIThy$i8e=K8Q~+pn(m}koCR}@t7L%{g(0`h+#&_rynoC@fH() zNcclO@E6oKQ%^tn*q|{I{J=9vQXr{_5{EAm&rz(1BIr#blM+S@3~Adhxu8VU;oxwV z+lDZsFA@@JP|Be6xBa3p5=ez`tFur;akzUOO;vkQ`xf55dL^{fxdT1I)h6U`dgWD4fFOnN_*}tV%N>LeLc@xv{n;5$d z-p?d&y=a8>)#1zO(!&Eju6(T2xvB+0Z`?h>zuj&U*`j5$i_?FK6A_ZIn{h4m5b`ce z_&?g`+xy=bQe%k}@w$IszJ3!70qjf(B)ej_Gm<}Y2#=Ymh~!xbz5m5Bd4ezGw(>#y z_G>+94PI~3YywNxe01iELLiRerzP?ejUP@-oLrwQwIfe4#srG`2Op19}KpQ2O9s99yut)s!;atY#HjgdJnmY?@YA2RPEzquA ze}x%MRys;T+fCM!(XiLz=d>jTNaH>ln;nkO^pNKw0=vebtiVDZjhRFhjWX$F9 z>>9$H3nJH<60Ry2?c|ZS>rsIm9zwo*xo~4o0gpyNtIJzB?g*?80+5{ZaLpy~M@&`d za2VFH;pXd{)o4{4TqR$gRXKTzey`Po{q2^Lk>6ci{tExF>?k@(>=fT0TWF}^BI3>N z^TfTzN)8q|z)Q-mWSdRhQ|^LUu6wJFr zq)0hb=>PWcc;l<@SSj2hUoB|lo!DG$B511cu;cVF{H-BLkYkmw!BeqSxJ9oar47eT znhlT9t)Ef4H5=tJN?+N!H`Eoxx3K1VS(~RgF`*&v^*A?S2dLOIMI`tpC9|cXFfA}? zFQ$j3tsX+VIPM9-c+dc~p=^uDUIz2fFC0?x%U}9(&f;-p5W&Akr+9R;Fl0VOeVsJV zj>()=JJXkoLpzXmXw!Nc`GDiT+c;ZUXj{5+bnws0G(1_layy~M_RU6Xd~UUYU9A2n z@{^vThbk3t0*ruB#})b!3PAQ)@MpL{+cdoJqC=UDs%Z4$-mt6uiKo*(5E6B8$QwIU z4|KT?;+!i6*C4mem#p&`7h`Pt!#zwG2fJ~~2Vd5w*qn2ZfNzNquuR6DILkt1ug*e1 z--cz-;cRF3#;qlv;oP6H2Y=?d9EW<;Aj+^Lc^#(Y45)x|Aoe&}@R2jD5uCCQE==yX zTad&;V({3V&)>fC?GRsc7|-9t=XHr`7$#razj*Z0D_`DaVf6ndTR4xgt!msc31h-R z9v#HP2%%z_-Q5k_MX_b+`$x_|0wUka79AzVmug|bn&E7Xj2;Zeu#|??7!w_AR@X~_ z89Gob5BROyU}3dg5X{kS8U7p-uh;O)f;nnY zdq_HKu#6P(_>-^Z0bjcSN;4ay^Hs^B0kr7LTiiD6n}YJ4-P|?b1g%n?czp@454iRbF-x^ zz@aW+da;uBu+ogg@UKi(oz;Gs`P(XM5~rcg-=m#xUoIOGxZ7r}K(j~=vXy`EZtI)o z^Z>j0l2!XdbGP*fY?DE@x&pZ%>_j^W(FA&l<%QzqReNh5W%fRYNET<;04Y{jg*f{} z+skGQ=xlpySCXn^DO>6}8*!ZgrNu$t4tc-q&#XIG0|VBjrZCidvcK}aLe;8x{bx8N ze?2>$VoGgi!r{aLiJJ^b6m28;Ir(hpK4uIfN-pUR2Q)w9ZgN}_ zj6vNII}DsA+&zw~k4=I$*VrbNPWce`QZy2XOtt$INo>Nh&h0TqYx3I?!QVt3?YXtU zjEsYW1Dwa1DZPZih=Uz}0C2Di!AFZ+KbQ_MFjs2)5h!MA_W+nAfSuKxjfK@KT&|>?G>)Z(yxiF?x!BZRxlhuH(;8`+_!eT5#CdwNj z*BXSV8pX33b!hmlP7)V;&=L>Id=6st`?4wS;EO_wub b_2lZSKZ64zjX)nw-5vx>Nc}YghVj1u;mRd% delta 99263 zcmafZV{9%?^k!}M*0yciytQrH?OWS6Z_QiVwr#s_?cV+Uv&kmAUv_dPlaptX=gi4` zm^tV98-*Sohn~p9$-~J>%p^^$OU%N|!$Qo;!bYr5%%nuj&Oyv1LCng*%E9&@u1L(n zLd>K_%*MjX&cQ+~D3~Gw=907)0LI0fq6ta?_zzTeG57f2I4kl0Gniz=iFNtSO}I@h zjLl6sjaf`t*qAxYc(~bFSUEYF%{h(DOu1MD|NlGm|6_)8b#pN{wuke|H8n9a+P5?^ zF*4%kh9%W*?zfXdnef7pZv>U0tQ8YZzW)m)9ZG{OPB|HDjwfRFM=&#Qs(<)R69Bpn z0X6zNS%)0NRRiWL19li9rO6143pC{e90Qq~n3-7RzvCENn!6J7aHSAJhyhr6h?(Tg z9W33fh*{X!{_h}+jQ%GAXA2`^Bcp(E;$aX-BThEy)S%KplFFo@1Gz6yD5zb+c$>dz z@p|Yg^jTe37(;dTdSP&PH%_#l#Y1!LhF zcah{w6eCKtAab}cdP*}A=)|3?UiI3s2G%K1iG^{4^GBkWZh|>cImLr2`%Glnb2+PW3|`3Jr=Qwb9|QKyN_}mClb_pWPK6T^QLF z#in|f!7BI|gVCpMm(T2~hp|{<0HYlc z_Q->NI)~^`;bSQ%x{46`wmqS)YO$Nyfmr8>EEZ{-$y!$i*O3^i99Zg^BaLvVw4Guuu==YU@>ghF)%1zzo8oLFy&-LF9frKM+Yv=!15Z zI0UX0qV*F70;B{M)C0}WZTbx=*u62I!wLCf>Hrcupr3`dAfGnt$j>0x2|i%yB?c2j z3m}Nl#k+wa^DTiPzYC6$ts=w4ejD~1R~R-zB1)YElCk4QL4m}Jf~V}2z_G(Pu^Yj6 zA|ZxXjt>Vls6WtR=YJ=t5+?&0D@qDH0_~GPSBBgdXUBCy>qK&5#ZCEwQdn@J zjRt@#img%gNiO}SShlqC0>_2sMvsd)YMO`W-@w%@Kty+D?K4_;%!FazQcl z{7oQoF-IV>^&7Jed^>C{_;&0iXd6gCFrkPim|*lOxM27#m>>R5-WQ$^*iOn9Hb5YX z6U0H{70h7?NaIGdzjPkZZ#fShxW(azDFD+BE&#C}NC>qJ>jlP9tPt2WZ_!WrB>h0v zj3th16HbVmyp78fkml57D zH{re1hD@!9_P4Br_W91kj=RqF`#tA<&zS=6O27lh76y*D&cP9d#3Mk2M43SIg(E

    5RQ21a2FF68H>nAksk-u#%vVKw&;X5$KE@tiOwx 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℞vs z2N*|7U)Ff73$FB1B@JtLWC{@nB2pC*#qM|aJAlQ#urMO0yDq4TYY2`JYAEUE8fi3l zL6`4S717E+xdrl0e{q~~!}0z;-7p6C#iSAVrb`k;aTbkT8sF@2WkF|*Va5+M17@R; zhoW+Glw8hx?g(64f7Rv4a*8h*WdcYt zC8UGd$NuUi{;Opro{uSxkZ=AJHnYr#%luX^22Adjv09?F@kmg5lLw2K-OaL%O+6bl z0!%?ciy6(S{rB)@vmoUcTpkjYskWPLkQ$kRn@D`@nJ!BPq-Kk1vPVv_)|NYLfRr<- z64MT(BevI&iFa-NaN8*nnV`Bv%FGA#`W`9zx_$r7&`ShqSy-4ZqKsikg6Qcf(z`wx zUFT$DDsKy_oK14`e&;?O6V*0#B=KUmKYj!JeC;8>^8aQr&bK%$L0j)i1qv{cbOh$5 zOZjlQ(NcTn$c8fChzyS~Qb@)~r(?c=BLn7t#`ZB}(psC;V~_V0&Jj6_F|JgC6gT@p z5ffzMWZ)-@2l?_9IT^#iKXDpwfV7oQ&!^uk_zG`G(F)0oLC+IX|6(TmQ2(h7)* zr!7lgB42C6PYxb*P;bR@z&OOZh*7*${%R5%UJcKLTs_I4SK*|e@V#s5toi0QV-k!L zRYx_V@qtI$Vp>C}#FZHgPv-CQkY7E|C74$X&weJh(@<&!Y39~@RoN|=@~M-QE(&I+ zpTmRqMXLN0_+SsixcfrJyePA$Hwl0PljE+^vQeCdV^@`?7R_smckm6GB@XSOeCGd= z{D(x3EnA(DZ@!MpATL}enJ!Sb^k=tG4Cz2+%U#ANwcEV+0c+?Lvxwn7H z|LU6|YQiRz*);s^f9D-$uI{y~HweuzB29&N8kf*S{5>6N-omCeZ&7d95k&>0qU9@? zMvgYSR!`cA=~nc9&P7YqJ%Q0@3Tbxnb@|t^S795<7;M^_=?hHN=+IHermyYam9*Na zIY}!2;S+rp&jXFcRmsku^L%a~zy5;^IxBOGOOX=B_N5V` zCY!9Cm?>OQbf3`V^Jo%H*$veEIhmd>?~a&}cK?shSvmQP35|&|g3Ipen3RsG5iRGtN)+yqFOzAwi!lA*y-*N|Vfs*Mvc>}J- zJ*`FW5V0-FzLN0EtCmvDN{jk5H`{<-hA3^mxUI?MoTkxM+*EgL`Z8#cNVQs8jQH9Y z*c%4xva?G%Ls{Dpms|6tI8L584<%|+E!Lf_`L;ZHj3B#7L+Lou2+NdFk?O-gy-7`k zBb;q1@bs~$APwjyPT<1|}v_FUCLh5pRypBQ|ZKYjB z7*26RxmOwKd)TG3hBD*b$_1%oH-sEHm=bzOw@G`OL>sfHrCA)e!Vp>DF}|+|hd)he z_>Y-YsZ;OroQl^H&4!!;G+1Q4qp3w*JPv}7v6FXJyo$%`lKoT zoVHPf*2uzr<_IS~ye89#pYe~bJDxP9RLq&3rd@%hwg9{7Fvajq`b#@8$@iEiJ~|b4 zrD$Sd#C%Yr?jgW3VL(vRv)v0KHJ%B5TZ3{`Hx8y40(@}1vFmC@%9DC*Ae_4H5qUKv zlN?mmWn1zhK`Ko;`S}_l73^Pny}LA8aQ>`4%hbBmBbRP+EuQ!{juR7STe8G6!>jh8 z1VXte?xIlVkX?Sl3^m?OGsV*;a?mm8ui`r;i0Wfa3t%_gKP+C6|O1l4i1h%O$xSlJ{0+6;a? zLDbVUGS}f1M?oQWLbxGZT&TmzM{O?<4S`KnzIxmy3GP|L{qge2nMq3V%xLP#P!|JY z$SGeYzw0LvWD3FHv+puioOr`dKJMb;v3u)&5sm;%MeQ163bDnm$xqTW9groc?Ts=& zI$sOs8I|XSQtp4e&Es4ycwU5*9`f$$H0cRp)U?po=Y|Xe6bM3&4>8zWRL|8nx!ua+6oS+}y@J_4IKZt}+t&no zMUMk&-V4g66^2NL=iP_SkU^&Z7!7VNlG0K=faVAV-a$KcGdk5itflcWjs_v$6<;-U zV5kkr_x`SMfvF2kN^_}6l^1YP<~glVOmGlF)KEB`gKhdzJZGAc?YoRzP;W);_@xXSTKjF#o#VheF>@I zGZv)LK=1*$Ias(!nB^@Te!5wGXE?aH{-Z79(ht^8UE=R&MSDy7dhS(s7saMdM~b4T zG&MwWVm-t>X^b!oUk1rsXri#Wj5HWneDHp-r1~PR6d|@GiWBY$MId5%LCAja4sU$? z`FB7JSGe~hYs0hBf!YHt$K+`03-IN8{Zz{IRHdd-rl^ry`C93K1_=hj77W8;uc`Ss zRp#K06DV$cwb4e2nYOTO;D@&W4_e(*uBW+{Jc z+i9g^chgA)qJ>{N!dz)@4}~oa0_@PCkNH(=y%JCcz!Vlm=`}U%bXq+-2GlsKfwJX; zCf>)K+hP+Ldd1*REEffAnNCL5N7ns*CM!+BX13K6s1#Ox3^nhoQN(p}Ot2O!&}Z z=0h9!s7lh`Y>sYKf9+}G0w4(*y!FbvLE}))HWZ7~O;V*(x!3qoo@?rajSLpKlbv~? zkmAa7dkrG+d&*7>1_3h>A%_V?17n&h8y35%F$5JjNprYQ3bg_OFGP)vL`4a*0z)s% zEP|YjWE+jt93<|A(meF74?&y*^%#_nSJ_eigi?$Yb#sn|qBccn1)!Lb;<3h?@ek5% zi+~N1wv!Ugg*-D-h=Q4-wW4#a-fb$6(gb|*^QH3;4EEoAXCy(Sn$VDk9#o&+mwI% z!5t5%56WhQYeO!e9y@n}SdvUf=tM5D-~&bDvHJ)PAr^aI0FlkgQLTYygzB__urLBMid)j^Ad5&_6P~>i0sxdkWV*1V+UtP_C)_>Bc&^^VNUna~ z!x<;^YN?Gupye~q9-~vqEzt&?7WrrJKJzZ#;JPvRULDGI*gDS^=rZXR>}6z6_&Mrz za9pIPYbUgW@>Y=VF4f>vJuHwb(s97wiG2^N71Eg=uu<6w`Q*9*)g!!t)Ixd{XhbU5 z3lwQ31d_Ijd7~4B^PvJJoT=aOoUu3JZ~}c%__#g#yThUhZNZpRYVBId`A&eimBmGQY%MH?= z=MB@|_Kv{d_3lihkkdu@6RPhHb0i$W&)2Ui?#%%nfh1QSv|~3%A;qt7*H^C5Q-Bx> zJGZ5ar4WAEPbbBhgB-zFSD#-lP&~ONL~L)k2luFvu?sWrYB_>X4Uy#g_cMUt1)<}d zPoCrZ8J@EIqnv;&*H`Q5)3TY&1tn)ip&_0RjN|*1oCPHpMWHdC4~qYFcp?{sc5^;q zkMEVZ%K-g69}vg)=sAD|B_~CpzW?_A%KeiNyc8BOx|e?MH3vyh$(Ue@BI=y;g3 z=r05eh|Ug>RLOJ zDHQYuqs6ou$LGsfyZ*KV;vM^g{H=O~{WtFNfD>5(GjaGtBy5vcG=Iz;Klbvg!eD%v z5(k?l`~`X*>SuWlnT0veBOlg_E7b+2V&A!V@jeHWLRB&>9)C*!veYTYMGNLkp5MV- z#i-r7ljB8S^CJ~NW&vaWQ&wCvFO0FSFSipikDP1Hr#;yLGjDEE;Ra?oi)&^x!ubNWXu%9D^Hll z%94m{m5x&NFw5Tu`enu{K{mP|-Y)UpuWZhWw7}r|B0T~8LfA=mQlh%1M^Y@9UVqZR z?kWw+7Rtckic%%(6ernHZL1LyD%2I|opJ?BN)J#gt&m-yZeeX<3Sv`7R}CRIOHwM( zYGKh=rTM0XjLQGuS6H|~$c)%(MOp2{9dUzX+xk7NF=rkv&Ryz=Q@MF<8kS8B;q@Ixus|@(ao{iCL3o zTvSN0f|@EGI8kqpbSTI^8E`}P$H>P%t@@VRp!x_5Q0zgk4hGMsAl1mAk;giMSLnAf ziF0bZL3zE4yvd{4d)FD{U={0>?KIk;>?R2y3n*i?aai1_Y%{nEIs#|3vbf~Fbh|XY zWNrqCT;lVJaEUD!bm+GzKDllhcFKD{Ad}Y-i3?rBeaX<}CVa05Z-On-bqHwxNcpn$ zG5bM=R^zA}+uP()g4!ZT4q-a0)Ei122~CmW8xWq5&ieG|d-px`mXxU*nycbCH&_Ek z-O-mla8oX8bR#TCAA-MgYSn}_VjJ-_HDCaeiBYdqtX*6`WcOawcFdn9kS@0Zx={}O z-aW9Yr{Xv=R1Iyv^GO{yVKh}E%bxL0sPs7O@43utZdl_2zcCKoa>F)j1tRnVn8h)Q znDL4Gt#?F252}h-3v=e6E^`qFg14l(;F$NaD`ZUbow8e0f@~UpaF&T9uVGU{p=6nH%z*HY7Dxf}(1`j^gHZs^x^RLj+|>xabC)Dpi%jdpL}FWMZ`c9+2CG(K z`mHpce2GkbDAp;zE_9#+OyKr4Gl5X8@kPd5(XG_ck$D169w!6)K)N7@y|j&NBNy%5 zzG7rTOk9))PZ1fRN4Cb_3`7MC%WI5tQ zIjk2;RdtVIuiC&8{|Dzs`6`R>LY>X)8%NXyZD8;uf>OmYI=AlL1H@P-ZW_(D@?Om? zgrZAZ@PsLyQU*&>MkFVHN$n729!Lc+6>40Q(Sf;!R>YT3Qmmn+bt^Fwln{zMS~3+( z(a{y!Ii6a-V0xaF5aXWeLIXfDtfz_>`S|O*Iun{YzZMpB%1$RIXNrzq#l{X++&bMs z0#hxemtv0Z=kmOwMZ>Ag$$=MwlwiVWVM-MJ)k7+w_HsB!# zHr+g8AVf9STGQ$x=4D+yYj|dJUvKXF2Bl>SO-$J>3h5I z$5Uz8f<9u*;?Q7{0jdkNa=>;iy5u_~X;0Ox&tqj+u1^Ul!4)zI)kf zO-?F!|GbP*%ZJwjVk~2_`T)t2tjFHq6~&vMFO^_T;b{bCj8TA`0oi{~zwR~afP1%_ zQ`b^Sp#C=7LNNpu%m(~a!iArT&Rx2Of)jdzW`-qYO$j^Psx~j>-HnMD_1Ic) z4IC76+Ck}ivN_vjlW1wEpsbKz)-SS#IE$yww6_F%wD6;x=o-~*6jXU;B?T^7OM7z( zOQM?yvA_qVgiApB)pA#)2Phvy>HO{L-P$_h$M|@n=i2&2XI|rD*5g`1V?fX{x$pYZ z+}r8LqV1uV2*2 zjb1aY(=FYA4&S7J4nb%s250{O731LWk48-pLiwwL0}$Ns7IVU>Ylt`;iUALJ<5^Y{ zEAPV4|zJr-z1YJAuq^lSMp(zz&ER)H3GQ#R+Qig_~$J9$PAl@PE+G=>Ns9KWq z(SL6*9k znW&(vzU3V7Y+w1rY~aCNEXdwXGibx0V3lRkGt)0a+rCKZ9Bvl8xScnG;tUP)Q8UHP zB)?@{n;vG1xV>)qVtXs4t;-knho|t1G@tw(+^APf*Ay{(XesU~-kS!}*)2{@n$zf$o#jOt3VsOzTl5ROib#saU-oazizlA|0BRfcS4v=`QM4e6VNKL zvZb@8tzz@6>&WQwvFV9Fag!xm6z@Ae(HH=9{0iQllP7wIb<`8@r*tI-Z}-FKV}RPn z(iO7rj|C_f#+QQQWr4cx$5D5sV}%V7HZCLJ>l!6=lTdUGBuXfoNdnXRO)<2Nk5h5$g&uJsJcl##W*Mx!ZAy!J{w_`)fymZ z6yA5hf+Mdo=0NQ{-PB>`RuOL3V(g}=TPUrb_&%MVcsN&jq{9!ZOzWH7wOB>*T=Q37 zIuSh!Ei_c>)aIRAR>IuyrG8Bd=>8ysE8tpMh);Qx(Vw!pG{Th;@iNK1+C51$&!qd^M+x>GS%wozl%eTABPxmpb?LaJsA=4i_J`d2iQwW`z zz${6O{X3zE6c*_+L|k7c*>1|+7o~8ey^=%EmC{~!{-O4~NJ8u0n^hg!w=h3?m^lMs zpOO{dRNS~71s^;(PMZ;!$gm$I2P#xqT11kpV`?WK?w(@*CvMHIaD?!;Yr8}dqqHM% zgqQzS-LZ3I&(p`Hk4!I%@fx5jKJk382%Ow*eWz15B0iQwdD7tAPq{k79C@h~y%sz- z`?S~T`$gq!BXQ5lyZS39Wy&wBT!T;sZEkmRyZ>I;X69!?jgQToBh33PuqOlXEZSLH z>*J}!ma9-}Fz=Dbu~z%;wi=^#O>w;Wc6z7wv%Lu5{iNIYgK2Lqn+s4?O^&g@6&pw4A1DG+-3fBo-w$c@+=y5E4-}Y4{>3 zGQ<+b!!3fws%XB~*wGcnp6xcdhLKG*I=T`PNd@ck?Z_*Ob^N zsm=&1kcX-@N5h}LDjg7H{^*8{k+)Is;;gbJIWcp_;UW^GsF`U6SvyA1!6ifu;2(l4 z-;YsAFS>(UQrf@<v>+z1lko(hFMGl(qK%ZS;7&*oiXB)RfemnOf0s1>J4DuwnB&TP=8k`- z8*|2S(_t4jd(L63xKHbfd z)%Q~UL=LFz8t{(r{JA(?Y=8@$v!;5d|3Pr~@)zo^9ic`%`CjHI>6O4W(=fY_S8$5r z7*1?~Rzc}!9tDv%#}&Vum7i$v@};wvc6dbVCQ;1PQ8OO_(yv_-j}G#onm7+B@f}q~ z@-;WlV8YFOR0`%d1*91BDz{PN^vgve3b}VG&rU#&@@XHrfrlE`gfn>B0)13$NVv5V zs$uletCJ~z<2vd3YT*$PY}Z*y(bII_pwlUfp>W1J%e@N-k*e2+u&OykU~*MYWb*W6 zdSM-22yz99)QDms4Yia9f%hfp^x|WB%=T)ED!|cwb18|v{j9co&3hqF?*bjp@}m5a zX%pa@t)Hp~>>ZMcGd-)tbj4@Z*Y@iPb^ARETlPk~bzH$u_5zCOVBRPi4K$ zhEov#p}=lnZo?K;3VzSV4^6weeOf)ZejLyvVCSH}!x7dRt{^!CyxPC`6`GWQ%5=O5 zW@G{?J~3jD<10oaMSI{pJb*tLfn0?hEST_g*Q`k6{qsDL^3ArcmD6${51))W%@FV< zIZejuzTFsxuN7~w?2r2~6O5UIhfv_2evVyp`8Z>3K9B`c_ZQ8s`BCc85q!ubgLM^PxDQDg)Vn@kE zfkTIx%ghLrjxWe25P+Y`>ed%_tc@x(Ur#xHNS&CC)iQbnQ8wLyrbiQnZ0CmUC6ngj zjy(AU;P#(YhxjBYu-KIYJf_gthj){{f5eh!f@7q!DNn&$zXrINs+YVuZMP&?QXh4C z>b>QilgOcaH9H;IRl~~-2+ev2$+UUZeoPcv+5+Pp3nS?PszJ`BxZDM_X>)d^rKuz zuVh}!YJbfS8j+Sj@VnZR6zURI3IiYo{62p@O7~p1BzeEgfhIXfk4p664YQ@e913+%v)m_FU?S9j)#uxrxiWOX?mI#V$xruq8+cjai=@mtU4f@*PLVf5C+`o7l_Inat?in`WQGfT{j^VIgd;`S!qDWh` zp(U9(54CSxpFbJAS6NE_Qx$DQwcE8~t5@-ugR9`{>p8u6Vl{kf-hz>Gt9;eDe0JSr zDjOTqgRiZq$9}&sjwPyY=;-o;+YnrabkXLsUPRuA^G%s^d|ykLG=$am(py zDXsq_Zb9#7J^v_d^5|_JXh*>j!K)3$&ulZZt6m zBI@2X1gC5Fr-T-JLH-PFD#JT=3*BjE#xUOI<0xqk3{>wejLXTJR);{|=bc$OJi`dj zY`A2lZ?cy(1}AIx7bm7Ny6lDGcYQ9;9j819ib7vB-@xO<_y1zE0~co^qc;BU!M#f~ zCP*~THEQS83_yd%z)ba?MC5%Vq}@yZraru|cgU8YDCI@-eZKacCQ+oeBnSmQztw+F zWvEieWG)N$q~T4V_c-@R2|rSEurg1M!Ef7#vx&xAjU(yk^#>lpb=VUR(Hx zTnNB%x_MF=EYmYQ(9E2P*w@}t?EhtF2d=Hf(FowNF}+7(FYCY_d4y4(-FPVD=-DeY zYY-u74OE`=Ln_AEWk!p94Ew=@ojSd^lW(~|_szb&B0zbCfPzN=Qr%7kp!%pC{FeU0 z+ylUGAwIa*i~OR#VHM&Dx`6TbD*l39ox>gupWl^KHIhVF?lh66t z2M{b|BOZidi`6^jptz8~A$b6RFz+frpx>?KW+lUNNniDN8DqjgqmQ8o;j1qHW1^5 zKR4iLNS`#DT20&(ZU}d+J!qJ^NK_@nx=ei4X}SL>|GDk4(>n4Iig=nl5un}AO2X_7 zStrKmbq*zg5kJP6Gh;nqRha30vqxAb=I||>F#WXBHwMv~ov%uly|s~%gqhn`NAAcC zTZpNVIb`yb2jC-N_F9oGV>gPHu-wZkqKSV5@J;)EH2k{|7EMhg!~dUVqetX*Tnwd^ zhiqj?i5F44cHK-tKgtf!L0Hv9h%#U-k#i^qQ0drnvBYbYi6iL5BE@$9n6r(}^G>YetnnFl@U(X1({YY;W*?g*NTZl|2 zn@_`565F67Kq12F4)Em@>wHOe?mM;3B-DM70@O?0(NjN`vO+zRk{_henpsxprn8pR zI-BZijGngMQdUMv4s$LH3mZHm$W<1ay2@>3oj);Ioy|TAlBKP+g+h!6tUVW~u+OzJ zv@)?bLMw*5CTsvzTMF9h*PeaM-j3a+t2w1@<;Csg#VygQ_Ig_EQ_4!4YVU|i4QY(C zRVBsLnsSxq3r?R&Bw-f zNpV$Aj;8^73XLfL!&#G)J`G|sJBZj{=HKSR$qk-%$SVrIYh#@C(W^#ywugS&A#HKn z+)2zY2!?>~*ns~0F^KaMwzZIJK_C7>_2B*R#hY#@ec%rl?PFQaF9I=)+cN93KNpWQ zIZE-#}I{P*^cgfI8t9-5DQ47wMd392n3OVEV< z)*Puf^Md#nquWu3J;JX-e*RV7Ddmfq5%y8%9Bxo!_MX%dc^C78%rw1&8FC8@lE7y) zhXzCdex~X*VnP`H>AJz$jsXaz1Pu3LXSn^Tvth2gTU{!KC-p+)l9ZTb?Ze$4Q zsi4qP$LH1g7H4{w6h-jH#mI@rS|pA|4AJPsAeLs*`GT652! zAqHbTfxp=TAT3T5xxD>on1|GeXG!S+KKh;l?4N-X2tsyM16x4dY!U`;rawk+Rh7o; zyQNoyn$bOPp&IDa>bnZ6;EI(nx*;t;hUW98q~-w`NTHtvP5`e54e8WMSQv>IYRQbbjg--F>A z8ePaHF_@$(DkdDQ+VJS!vt{hbqZH)7u~C_LDVBOi9z_byJlpZ;xK-&VK=o<>$I*8W zi_!$Wre3EsLcGV`aea@!vaUl;T`!(fQd~T`yIY=|vp*}U1%TBZI~7Uir&S#)+u9>D z6>5~83Z={>Of_;R7~;T#iPh#tZfi3rG|g8ma1T|_pr~I*T7amC{G_`X!JLQ5y~|p($66YL7m6( zE;Ws_v`dK9ExT(rQm@N*Kx}Cq000LA=7L+bh`=g<0qh)%Z2v=4VrOOlKSdQUy`epR zh)Un(9nVh*GYgvj!9c#koGKR#D7D>5!#rjYU1AgTJ0clATfKtyL?*QYRzp8IUtsBifir` z@>Nz=DpB(4_9QT|q)gkqwSHd*>C{!q5d~ZkNg?;tIA@f9szhQ$KI!f;sPHHD(uQqi{nfcL z_`F_ZQ}mO|M``P`Z#Vm8!z9L@KEt7+)fbeazGvA91?;{80C+AbZjmR?RDnaL=24b5 zr;+QGs!nTBj1h~@M5V6snu0T%^*z$&{Z1<%cmzp_ek2Lw45lbm?grN>ca#`5Hz$lb>X(B-ZOi$1 zc!j%jN_)#oKsvIM{;LWoH(CL!^G=tb9XV=1fYmvvONwm*2U=Zd9dUJF`=VVS`-0_- z_a&Mevkr*1oEq>Qp;b%q6SWS!wty8N?GuPSdrR6I_a=lkuT^xMA+ zkbDKiM{pDCLVm+6`jUzTfaDgB`p+tcJ#q2Mcly&q`NX?{>KBX#&@ZC& z`96@`pm|AoM?Wp%?E#;G;T4rOtDna8sh?u)SvO(4aDAeMzgvXGndgG{NX`NyF5dU` zE=KjW`a_=DdO^P+bi?_iK3PJZ@CJyVpzXc80C^-Kfbi!D_Zfrm7pXUYJ|K4kAU+_w zYr2I-PvQ5V-*9e>y-;4DaUuMq0FZtVTjIHk+I{pVxOrkXy*yaCHMl^*RylS=W5p1 zH*2Xp5@+`d2&Zr4*r~FJ96d6C)AtPA=}jhnQCd`v9)+{}0)+FEDSq)kq0SHP)0gAF zZOqc6b@GZHJG~c?%O!Vu`v8oerbcD;AhpSu+>@C&^On-zPM$szmFg2Zy(z^nrbcG% z5IA`i>dWcVIlVc>FRF)U^(g&&P$ep@y_-DkMdtjp`dOFC>1|#g5VyFC!TIUio8>3+ z?}3=86#tdA^gCnmd-mwz8Zdoo?(7vXb{axdilN6+8jHc%ee$ypYq_7D{3HQV79-kT zy5R_krH8;$<3k?3x+7T;uZeCbC$jqFg?4VO~pfZc);H8^M0SY};A zu(qMHD%QyFPagRp^jM{Poy66MooXz(%daoeTR1*(ZNML!mW&)TGD`jRGEyR(?35L& z=Rp)^r(>6Y-Ieuf{D$jQiPs7h^~{F^)Uo1rI)9R%7;;OqM4C9%%l1cQC_0`HlSAe!=4&_F6RR^XaoD-Q zW?-!fwJ7JnKxZk4qXnO#e{@48)Mlf(ae(V5B6VDmFHX4K9YH!zL_9yyQcbY)X`E;LOBol$ZwlS7I-FFMqPU?W3Rp?!<6an>A~sM zbbF><)1KLn4AOyvCYySm7{#GRij~#x*1@VIUTN+k=&C=}#)}$A)@G)t{U|4VuP}Ui zJ(>1lw~m#9T;M8=>bC;XJkb&@S@1>mgL(rvP0Ss6(w){gC?jQ4jsW#Nn58?< zt|k#$I}^?p^qtZ4NeAo6H1O-~Q5(tTCvwFie!7_y{1xS8nxujC@NNuZEqWDkkk-td zJ*MYH5?@U$;jw1=6UkjI=d(7ya7Or(LhB%Q#{5h!Y4Dg&MD?beHT8SYoWD`sqFdwF zza?$@yKbuGPDQNO^3sQ``jtJx-G83XQ(wRL}O3riWOX~xb}(CA>;{w@B#xi+X)_^q8aZ?d?3^Fbm9T6zL$)~`tf?=8l#vcPzW^NM8j47E+d=r!`& zZX#uMA#noFxrKZ+F_D+cdTDIx5Axt*7`!Y_LPkPXQraHg?`v#SjPu`^g0sc>(}!|79aK%7)-~GIXv{m9iZ{G(FEa=ZiIx?u#lB(PDkk5OvYz zG-uZ?s}Kd{+2scT=bc#=-q4ccDze5(&7|a{GITE0>mHEOjeav($`BvvfJT`|KeB&D zgp)xcgis-Am=6lD#2Bb$dTROTUZX6u7Iak<{@rTY0zJ&VWCQ@pcr8#HB-^+y->k># zDtR^(kZWa*hU7$2C_T@2E?Agu#Tk%o@LE)L4b97Jp5mrD0xq%=8p`>}yUHx*?tfGF zp(Idf6Bw8^vns@rLo(yTo!VcvPonWxq&FWcLXFfar9Lt40n@)e zk|A#kEE_X2L1!#+f_^V=@r;zmSk_q7T+G#^pQ~KX9O-hv9kH)ssJZZeBG^7p&+jmv zPci_)!EHnSYnT)r<<@Ki=xTS4Jak$lpxZLX(fTJ<{bERu>%t1_X<&ChXx-8Z!Y`4WDSCPqjn z*bInS9g!ujN6NAa#FH=z+B7U<1J&BDjaQRNnxQvpDw-(!Pmf?C*5NT%LmL2hzS8`; z`6cfUvuwP8J)!}b`v|3PY={n((+2~%M{iu+vg9*TLo!{JTZFcZ9!MgelRx?^X+-Y{ z!NmdF&)JqGjZhP~yg$|$aJ}d40Ol79=(pv71K%@PsC3208%gI>r{R5iGuRr&>*_ZUy6+qCmQrVdyIq=J)vzN$ zE3XQsI2}2p+Mk_WKcTTj9UcSpcV2Qk>nK2~S8^KdiC|!$PB`Dq3Xn3Zk1vQHp8EQ7 z8e`|eAiy8XK5zE+{&Vr%u<1R+CxnlMzT*6Z{B{x^p3{ggwAAZmubG}q3oAFb*>!oc3|);i=clk=su*aGS-!jv9B}E4on%Tqtox(Q=2lhh zsD;<>eycW%>w{ml>hk(dpgS%P4zm#d=47%6IoByeoaUe8_87WMPXW;#A{nA1`jz1w zQz3lm`?l6e@_?hI&ELm~q#5QLe-llyEjmWYsZlLE`pGjXR#ZHn1Z&k|-b}Fkj>CXct-hL|git=d(HEL-p94!p$ft}~55a2U>*|xPkx#Nn z@X?u|oDu(9^=bH%+9w`tvocD$d!ERM{z^r7Zolt)*bd;+Y)vFJsifx%wHX?Xi+;gu zK*kqlJ1`y-^MP9rkEMe=F^-3PG5I69fxhuHTTsn7moiGS13lnm)|e>r#nX;#fg3!Kj$oQACa8! zdF9hw9N^3JVg8e{a6M`FJl;mHP4LfRTb^y6d{Ewur}OKL*$9~rYc~832ZsW_r2V@| zy3u$Ye&xHQ`@6}DWVDbQ?B_b4=IShxQv#nJ_DLe69^-l1F#Q*L?~C@wi0LhkdS0&I zf7-4y^o1W?`&#){r+0^8H7z^wc zoB>|R73-)=EP6$UK3|x#eQD9^eeZybsHUt=KI{4%su2CRMV+U{wA1EZkz*m}(z`5+ zv&N@`YCpFkoMQ6g?gcypYANla(PDnd%LTgf#{t@7&9Gzr2#idex2^K0%z);e*N1zq zZ@%arRj&hmwbKyo8H`43eU*wCoW}c>Bf9Epounl7)-o?0ub-8VqwVrSM`(vUJ7ev)w#XcZncwE7)hKiCGC5@Iu1! zmT1&c!p18sHqKH)MrcN{EGuByFF?A0N2XWQgN0xAj*3cbVJWo%nTR*P>}{2{o-`-( zU&ng||G6%COOV)S6rhgj4&wnU0@Cs8y?m`8Dr82fiRDCJM5MPLqwan&yX5tX53!ia zAsO%2<`4+s_txkYsxrMouFJOH()o82n7#@X(qrRZFVefLBy8M>%@^p5Z{;D9<^J_pjJ?%PLhV@FHf~EywmBo_Dk(5-JQhnC8h8p z53Z7<_LD+(Ge!(^WTI%jZA!mYs9qtvn0VC4Qyo;$X5fO5legq>6ZQkRM8WSpk~xSt zhy==^)tO@GOPjpH14%$R)FDxp7tcc5)5k~CvUibV6V?Ns#INS^fpW*o(^Cj}EF*{1 z$vx1&4u1v8j{Vhwp58mC3p!bOXi3?{uwzSZ+h!s5@aFvHyz}S zv`>O%LV8%5kPpC>u-&%1 zY;2!72j3|VuA*N%tyvn>v-I{r)b;@E_P~9|T)t}y{S_dS^d+L_)C;t;2|iHIF*%m~ z)gvU99H(oV*QU%s7(T_Uju1kcRU@*03j)Wc&Le0TvnsaV3#Tfzp9l`!u8tuH9E)bo zfGxYZ(|4u~&Ri#ynQjm(b^p(#!-y%zU#2WatpCq$z<;IF3o&wyDu>IuyX;{>Jr(rp zF|6I=;k+EI(TqZOPtiSc^wol}22cr%6R?kgN6xzzWwmHS2AQ^2%87f{sA9{y<}K&J z6KGD@s2l%A_*V!gvk51&1Shlo6HNEv=J6(ciLGvr6hCCwbrO=pKF4lAtM{PQG{GXS z1Kfh98P;5aM7_xZzk%K`U7(tNH-WLBumC3^V#7;8MjN2I1!tS^RORRnYNZWfYGRH4 zI$4B#Wv5v>@XR^~u-DyXZdeT(e$ThOykY`-2OpSlBY>hMcFw(YfCfx zN?Y6Qh3;8`WNn>~gE-+}K{pQAxtwgP_?Pc4=c36{_Z0sfZEpVNZ{spqIeOVy?r*(z z@j1`=_p-KaXvmFAzD12&JL>Lm1nt}VIQy8+p%DlF=c ze$313{U9Y%cT_VxNAT1I1(u%idVa=`g_gx>hhAYg1&`OBmqa54c5S2^qmvVN((c6K z&txkKV%?ceM9u>Z!px(nS&&pdFN^s7C`6zCf(yo}-3`5X*6iHi*b6z(hS9s%3NVP@ zz3u5Uw9d9ydZ#i=V70y*hyd5J%FFA;ogO6Dx*By+&-0p^r*!Sv;^-+Sk51l#nwrRX z^>c$)=+L~8%UBPAv_)rLMG)G-c)NBdoF4eP^m^uVQ9k~^g=Udo{pS+XYgV-?(b1bK zD&`!2EyHAMk-wf^7#*U*RUlgTDhRe*lS_6&`hl&W2TfSHs6T#I@YOUB8wdNbGQSRpKU(FVt32(UnM}Ish7}uz7cUyPX_@p@ zO(Kcns#SBKI(ic8OHJ^IX>?osS4a{eUKTbF2a|_`-pyX!9-v>cKgc)`5~mHavlUXi z74p3WGP4De`zd7$$T4S=XvR4+qzh~FSmCI@d?1K81QMqMva=m>6b#YL9B~E%&*mKO zHv`Yr7l&Xc*bp2qxx@ftZ{?p~3`X7g$Ws3?makt0f;8D{$(cW-wd;BLh48|6L1aWc?`&^YOv_uPGi`mzvr(sH&J>GkRX> zdaW21o!v6)N>ZJha;Mz_>v}Csb4ph6P5r?&-5}k?)$m>Wps^lNijp!cB@txUSX3jC zVhke~#swoHo3RMBp%I)So!cfF&(H75!|5CH=03hjLJXNc<5%?(9Oq`~@leVY zraeA$0zS@`E+m?s9yU{T*oMb(oDOqv&eY@NA#LTd>AG@fpt@m?0$O_T@rnk=zGYn zJ)x*gq)_TgI!0ZSnR^F%+p%XW0dB#@U^T-v08L`40lF@izt(5qU6kAY<~z1_6g9n2Zjw~yLKp3G^8kD>Ofwh;x)?AOGd7PyIH3zuXP34-%3MKGNd z18yn|e!FJDjVP0p8-Tbrz>z80s0l`Mi9;k(G^jA7b7?~;Q{1UAByZ3MS)!IxrO9QJ z1@Xb;!k8(Tj~STFp=SEH5;9X$EYt>1T@d`UR8~0Y@z0sZI`Q$S8`tMSWnzb{=SxCa z;yz4C^Gb3)s#zvmvGNq$o+@W>J-Sgo0;pAu*eM-Dy0S!+#AzbYAf$)%!xHf?IQFXw zIAJ94h?3OGMN*Ru+Y^$4Nkov6*iuuLCna@7CnE9V@odI;3ciu&GGqtZ6tH}zt1l9jdw?C zg4}(pj%v0iHG4IN>pR;bo?kN20I@`kbwa_csjHWdb!WFJ#8v%&pN1kle)JmP*I8XR ztr|dGXM6o#@2rn!O!Y!1Y`3Lh7)GDNt9zMUR$NMN~E#__E z)B9(rdCD=8Ti@j4?gvFH1v_I*ad~i(w_ry_aasTPYA(0i&B>Z6KYgU!__}1n_x~DR z=FIB-9)vn#i~`5|t0Ce{gIXD2r^B+t$j3BOh{esZBd~b8m43X^oScul3HY`U zViuX_(ez`froUE+a@_QoY@19G%^LVUl14b;V{BnIN&C0vwz%HL$G8gnINDv2O><`5 zi_stHX#-OFTUy)&9fF4%K-q^STZ~MpO;2znE)7LYAhevFMzDo5CdGuGhax` z;_#kK=#@}jw$fMuKg%WXZ|!kR>~)G6qSo4rP)ZepppPB$oMQTIWpTa$zheV$83r$> zKhhfOL~tCQN~PFYKU{qQM;xrMoO_96AN{W1(a! zvZTvG_cY5?B+v4@<%Uh_g9m)M*TcH%%f^n^*Xfhrogod>jsGa6DFmIscn7&%e}H$f@>A0Au(hhVh}7%M9QW8w`sPHLI}7*;BaJXmt8ygJw~ zuv7s>u!z(%ZLqggdnGXV)Qc=I+|&&Luxx;$UNrt^8ek%ZB7fV=*U`J#Fz|Yl7(KbOz1KD%L{GwFNi>T#8vwL0}e4*-zrdEb+n`2K2tuS^pAuJ-<1O;j3?DldZD zZXYV|A^9(*Xg!#V)SkY7HJ+x4=`eZ%z%^8XAeL_+)Fuj)ZRP4u>Dp))HOvnmr)XuvE$k$2c-aYh=l zXHO5xSzYbn57k02p~rb?Adr<%qL$!tLx}ujuDb9|Lm7pCAWXj%!FCclO`HTI)xZgu z>d*)$Qe}WEaXHEaQXWY_HxRihfa-z}Yg@(0s65puBUq-_|K}h4fLlXOF%%_`Ns8qL z4pS%x<-Ytbs$pE*932*bBHBWU>f;|ZV+>8$93t*I`HROI1iAz!0WEMFf5%z&eq26N z0xD(14zdSFpgYFnmil5?LI^O9u~tXOA%8WZAx59ck4VaiA9on$3PK`J@lnQcu-X{) zrpZa&%B-GskcLJ=i2XsLhY;5dK9kDxC-$}tJwHM4V3d@jR$vQ25d0fM4zRQrq?+*J z8ypf!1(YFE_;S3(%_vZ5Y*g_rO?RHXgM9slyLxtB8GKj7nsPWCNtv=k>6{a>YbbfP z5tk}!J}7<__}gy;;N@5{%b{4?xKKqQa5Q7r4Sau=Ek0ZQXBjU~JJt3^w8kA^%TV6( zVg<5X0dPGJv1kpz$@g#9v99D>6%7Z?jD6|}sPaO%5K8A_P;+79BeURXixXMhb0B!8 z>86D_W=peo2X{z|DXtN2dn!-MUg56!(dJ7R+D*-t0>+K7bQ@X%yOR}R1598%XNbXZ z%i3k8Uj^Hb`D842e|x~MtxuB+IrJ&rgZ5Zxy``K`h<0%RIJ1Pu)T^eEvY>1}M>rgF zL85-=2i z7}c8%dzqU7Wiqr0?7^4uKrB>HPjkbtU8TV@GFQu#E1nA51sQ%oxhPlJ)_ns#9(-3K z=J;@^`br_;2Ef=XLl9DhhJ|v3VVGQ!Z3`Pfh5PTIHR_1t?(;1v$%>QPg6=U~xtUFa z>Q?ay@sGf3K!d;As->t~i@*plZrnB;FuY9zR_4F}tl(%O*W5aBS<;YIj-_NSF4v~o3#je_ucK+pluODko759QNh5@{SyJvfbf3@>|ak`!^e2TgT0XyPi3gAq4^O!nmYe>9!9tx|1vLg zZtXxO&A%l;eLWwlmb;Tm|ayJN?!gFZ+|yOzxw9` z>LfgcS3xpY5f6LsW)ytn*LrRgrZ#u-5@s@yX=r8E0p|zSNzbY?ew?MnKfPNY4wdhWQ=jyWiO?Ic(5u)sA-XuPt2*fY_N) z;OL--H=Jm*alZ`@4u%I$qB)#SCcYWjsk(d&YZG-p-#u-;Bd!*L-)#mX)( z?6}z&C(=&-233E+?=4BNi+GUA&3QoOQ1lhtXDuO)NR9tQG8uT&`H~JK$O0qikX{zo z%{<8DS=MVsn$we?#)0VyFQ)zh;6fCjGM{Xd2svohTMGpUg4e}g7K}3N<+ll|ErhPM zMa!oR0HNL%FiicMff|pkCyM~W$*jMZL!P=%#&DZrY{Z(|I>F^*h054R#MBRgm@c8w z-`8ru`WhYfb#B+#+JdwBaSC5hVBzE6DB5w>9LcixV<7cOG8pvmXK_0NXjAbbV36s? zr7Fg`BjvV5>}YvS20jQy?=-kbur&d%=qBXbj(HFCfxd<8H51+4^B|ZiAx=mrzl#A05^t7ajpOtcJE|Y|w+!sb-iIc!Wr>@jprPfWNP;K9Qqu_~2g3Ml_MUK28Lg>2#P{)w~D~m#P38bJ; za_5G^e1@T4o@PqY8*K~TBdQV%4Ki?0!GZ%~!ZLwp-0S zDZI`cvnricuCkpy@6^7eQCDi`mZrqU=!+nb-Qj}OHbgJd$-{32>Ith*NU5{B{Z#e# zLDBwqcrd679RROUAvv?c&W%FL@1JoJorvxp=Zr(Ep2M;a(SYCU z2?A0TGv-ggME{_{PpgL3?kyd>80xX2KIXx!2 z0D3q^3{Lx($JrW0*wW({?+Q>p82f_?AI74JrzD%V_A{f>k13c6_2(v^zS$`i zVtoNv)V1yefbQKI&-vMpMD*<%4UK1G>JlDL^cB|xiVnxo+YK$2pVM$k{N^|m>kIax z;>ol$Yfy)Y2k_~y>rqAV4KwQdhX#D?o}k+S#H|A*+t>Ob?S3@u*;1t(sO5b~Gs-Sq zx?m;&SY9`h6I0pkM0aX)H^RU94w3q58wdy&wKV;cI zx--mtIlr{QoO1LvpM=CO7e7q9i~A%rn27Qh6UVuz2MYT7YxfLh8pR^}ArsB0%=pq2 z5$Rd@e@NyWj`%4RD`U#lst|N7W{v2jP$~VI|!)#Yy)jOuI8)^!9rW z^vo}u8tgtY@wkP3y@mnt=%IC(L#>W%fAy*+cSH$B>{5rNfSvF|(Q7M;@1eeZ&^wS(L$f6a-~$;*7|qtf$NeH2MS+>55cRtW%#ypuwQUv}i( z%&^C5^?>n?+}r>RH!GQcdDq`eo6=P_fM&GZned%X){Xv_h<4H|zkf#&MLe7T#wYlU z1U63HQwGCJ)mZ_B0sj9%HI`Q)iXH z*i$=H!B|pvtia$>eU!k+QVG<+GJx6sR|@-oQrP|js!+gEr|o`nWEH`D{)4REe;$87 z3ycDkm4Pi4S@#E8%?r-re>%R5Qx|amty~_yRt;@5qag-wE)IVUnXQ$_?`=zT)4j2L zspRke`Y5XXES9SkcAdHb^tU^BeQusUOIbdLEuQn|yvcc2t6t3RX5gLN_8+gJCp*=Y zB|#gnYq|EglW}>MCwoIIyO!bZ#3JgfK2vez@`m4oqPa!_`1J57VDa{>JcFcG%X*+u z5A;SL-58wa=uBn5gC|bbON@;PGyAm0wd`to^8gc(P!qJ7yZ{68#?l`T%PMWVP^l69 z$(%np+}2*%zE@s1uxHY0ZVQvH6MU_wTBP{2b;_6!4@&dxoFAn=GOt6b&>51P%A+!# zy35C}&ew?mrpXlw>6vOnT+2UvA*R-2VzNO}vcl``jto65Zo;T9u8rmELP#K z3wG7dZXQ($mr-bd8kfm!vfmnR-)b$Y%DHJXWqe}E)wvdiuE@Ls@BZ(B=+|{!Kz+D# zgJ%b{haohBo-Mv@9S+yxIKUgtdqo44pj$AJvTOi=IsVc0#l2&Szci+Jw`|8h z**Zc%jn?msQ{P55U=mQ5%YmDP-$_l7B6=akSY+H&|5st}6dYLicKOCh$F^w{{w%xI9+w7kH&(utP-<)&mTbFE`-h_0gH{KQ=bdl zET1XBdhIBZ{F%$_pcjcPqJO5)Mku|`+V;|#XIbWlcnT=69|x{NHR0O*cElt9sM*&v zVC~?+4@*D+W%r#X&W@EL!pA?2P*4;9i1)o3|Iz1&5p;(^zXq`qVmfkN581&3@;$S) zF`C07`vT%G)NwfRaS$W)dX31!_coZ27tg;DF)V1mfp0S4YxFp$s0}Qapsm%(r^-JP zxoe-zy58*-8&$mz|C`Xp&Hp0WgC&a_NqY{h9Rrg`!FK!p$k1hH;N zXGX>_i;RD!b1!hA3QDsDp`fT+jHUG#xsrFci+ut?oaB*p_1M?D>?G^3W*fh-x+LDi8v8$885x|~;2rv8VBdR<8@}N1J*V|#2ll8;+5$@!_+H`7N#m`283n}T7e26qc zapDouG!DeFdIy`tou~#C#KY1?nTw(*jR&!0srUXECMTLGaB|VdGb&m9E>uzY8E8!n zsE7d~4ak_Kr2W$bpC}Nlh8gS{G%pQuh53$Gf#)nh!B0-Ta`}fO1!WZ3VOEB*N|9zR zCP5WbPXev zH+!7LsVf?;tXo4fbEM=trDR#R3QAni&V2xTq#J*d&+3DkO(4wXwqG^~srVe?NezuHhT+M-sz0TV+v5?z^t4rkCwC;f(ieoWa6`Es#B ziWWx+V=+SVOT+dT+ahQ#BWl4s6OSW3lnl)fHv4FT6p2zlp@SO~j15-dG!N?@VGJO# zXmlLUYx9X97ME~F)EvuQoPi0$k3KuxhU^k8%v+%lbWfPczRlZ-4hm{s)Dzn;o=8|) zbB1iH(||4uqL=o?k{7a%8m61E)uC&!|4p9mR{;!EUJ1!eW2DmfTv&+W-j^mRFC8$KCLm( zkNgXMgn75`y6XfgI57}R!*96YO(58bglXBA_CP68wjX4JzQ=xvE)1d((jk6Au2R}+ zd_Mbjd+JI3?S)B~8Q1h9`LH2)>Qk|67)iL~-pg0~pw1G!l1{E9iL!&u0} zNPyZ?^ki%j!vIe$p}0!A@fxJCF0Y);n_n7mdXe$k0>!&FogZe!|H)SI@vyTZd+P6h zbo=(mQ57y!_w@RTm9HrD<>Q}D^x2%P1)1AD;XPMXTDR3RVbHo@3gHC`Am)CA zF=&Qs!c;DdghGU2QgG||ufUxirRllDRH&)pD{KCG{?y^GzjVzs=r!wJ%X@+v)Ov^N z{o*zSWh%3hMx(nskyQ?mY>x(c#bOfBX5DcsO@Py(+H3Y^!%vA z7Sv5xt0ykh`h}5zM~rGZA2MXWlg*Zz%5v10lyWyn+IUJ= zfeI}nvQ9^RfbW^PkI+!&`x$J-;;C0@~-aeK`L+hWsLuh z#@loEFZCN?NL^_zJ&P2`bTMi~QIIV=%ql89^6?Qp_@3>!KAkC7?A zq^i>>Gb!}v9nN0XD$}Y_ps-$+{@q&h9gH=rHXt#c9n6f0#|K`fm^!6f$JDIZl4JS6 z0A>AC(vhJKJ7QPo^i(pS>gN4Tc7sllC%`Pq-t8dV7B%0vuE;bdU78^6x_#RXm6h*G zfI$N1;&z%Tih8S2a<525zcu8IX^;49e1>ud$3lY#!)(nPlK%$@0L_Tlw8YBn@a+Lv zqU$wDBVS;FG%%J-FrkR_8`LQv}Ck+8jC=3mQ!+}C@EOfS})coml)j8iz+ zwUeiscjDwKPr~nVZ^n5eq%o$)_LBpQhUSaxTEfNIXEsGgPjj}fwsBqGdATsk8 ztC~Wli)PZ4z8!QKfNi7GX7*c@P^C!Jkl=E;_E%Uo$!Romeu0(`9p?2E=LJ92NIh*g zBAkWp8V}Z@(9EV<>Z=b%MP+% z7&o!1tFT-pv2i&Cb5&VR<3eMl+sX7tIx!vOl#e7hS4-_t(DlN5c0Cd#$cuMvl4c$f znDb9zYl^!* z(Raebze9~u3=WzY!)IJ}6KuhFy|jO;1VfF6e>xH7Hw3B>o#QF%|%UpJmhkCKOnC(p8qh(bM0eAZY(T7cr2WJj86w$#;;r>4!ED z*kEkT|IrVet?afC8DL;+EdNU>u<~%EzuEs&3hNhJKYI`J8%eye^?$XrHJ{hB*k4E+ zFjN@7^pB>8&&;^9z4w3oo@7FL=hm=(xZe=F&sOSR`#b^c|5T^=e_B1<-$2`ibFZ7~ zt>eo+wvfYXwr{fgQ7c2CXH*D>lY|_`&E#$f#*4uV#+UP9#*{mMxasbPvB#}%6cG<- z0iWu|P;8O{n9UF!Wd1#5ZO+=^RR%a3+-dU7e?J?qedFg4w%y(DwB+G#yaCHI`qjJcGB)Kz+E2r zB31RLK5hnL^kf%SjQzYWnB2kQ=x}2Rz(`9GF=LdZht{?XzcipdFxtA5lXu@asx$mR ziD*M5JMW5Sn{4LL5_;^>)*&U{(4k9yAy)LM1Nat*13U5O*QHh@Wg&d$46`cV=LqewiyB-!Lz zL4BNeeS3;54fkW#^AZQ6eiynT;CyjTV`YbDqFiFI0EfbfK<~R_3i*bZ7HGMmS%2ju z2($($^bHQYs@Sc~vz@H{;|MsUn+No83@-%7pbOhZDIH?e_2sQwpoK^{&`*J;7drnA zF7DyvX(j9oDQhit(y#Du(2D)Li0Ml{h@{QrVJw^IyV%V3*Fx)nU-7HvZ*G}s4zPU` zf?6-ffD~0W$f!{;!ymZRbMhn*vIRDd3xd6wTp-B{>^F+jEN@c$GwX!rUCB%YEdv)L2B zz__p!iC8U5hLJqevpJhGpJj6i%b#TA5|$s-aOcwF2Um5dx=vQuKyX!kY6bQ*r9z#5 z*&j&Ob(kfPj*)dXlA2K>JYr-18IBi`fVm^6(QlxoTz*#bU{rxdd#C1@lgWx!dHm9B z#I)v*d|=GCv2^EchAVswv#^US*R38Ws(&W$+QY?IBh!2!@BCxHguT{4I&+4qR?k(y z9kMDl5W7JwZU^cufH{rqGm8t9&o^Dc?Mn$(xDBsNe0_Xd*+NVOH|_K(SnwUxt2GLR zpk30NKu9;{T{aS^U=29zL)@uI>_dvN()DS%3o1`W<0{##si4}_zEZ{j*wRcVg@9u- zUurs#wgu@8*s0o!2tx9g$&=~8erhj5b+$^7H@4dd2#hu=K+~Aquq}kyl35dakc*>M z)I3$cP>Xq@3%!Z&Du0Kt30 zC^J__Nkh%{qNMJeE{-95&HfFr2-%SeXWD7xmUKlc<^jT@IQ*0m84+HGhqz@t3XiBT`&2e~%8r-M5!;d=1A_Tfx@r-{s z3L4 zNA~sK6*RK_!W+1tf6q3#0E8Z4Y`GE&RvJJA!ZT4&0tlV-Sj-%XvISyQwUe-`V%m2V z&z~^4y;1J2{fp4QO{=e(qCUdPY1ZKa71KflL*C&bHJx`AsbFg*+EBnUXHx>FxGqM^ z?@p{`lG;P#t}oD}`U>^QO;edTyg^l|e@F1v~L1X!n1x~mU_6@<=3&yV!+YzUQfW_h&yUQ@y)N}o&nW7&P7LtxK(uj$}tS^6*k6$*#&X>LlhC`%6J%Oy-1<5 zn0aR&xGMM$nRRdI=%`S#etnQZ`ite`@_yo=^w*E~FKQDG@cMO927I19=I^aAzTe#_ z{{2L+MmXuMRXPy@fWK$#Uz0bzf?v1E0$=aFdvxRNuCly2P4|1BB|m24t=}b}{oc+T z2J^c}JJ@=3^gj*EJWobg-wRsMo!)j&(#wc?I{q^>{JQOR^?o~&*%_6~HSqU2A3RgL z_xF6RTgXpky=MAX+%5E^A0tR@F%4Mx?!MmzUZ^knJ>ES7eNwl5C3hm{O)EOXuE5}r zZD|?ElN+RzlF3*2iGa{S)@ocL%LSZNWA*QT2(;vlC7pE#;C%2Vv$d_0O9Kq9qKGp>vSHn+llxeod&?%U@u=j!sfWZ2N!qFH~D@rfQ^B;*8{uxm$rx6`*etPbyG zBPAIf2M zAbosrIcj+Gb7cIGn?QTObOT#hUjvAuLJ^K8<-m&p)Gi{z@V#F=hV4xyG6YAFkrQA0$lPWP3pzi^|?RQw?iwTGdO?w4u@rvq#09^ zmt5KIq#eUzfX=BxAT=E)eA_gNfj)std`fE)G2K%Ju%sO!Aqs1#8+XRGwRSopQR!ci z1L%u@-?f*5bLLc+PMDFH4GtblogslL`$l{>#3jXi0Z>49Xw_0 zgs@9l)i8W#F2z`Li?J^AVs^1S$pp2mq=2SCIifVeG26x1!{=W|u&X!mAHU7!yB;;r%AU+T~wxA>14+ND|6ezFi6i$^rdDWT#IH zXyA~9)~t-t7ft&hSbcwy$G`89?2sdWHfZ^?N10{^QX(UYw25WE5qyYwuOn&!Pn~fC z|4oI$h2UB#s2~;_$9vT$z&4lz5(ZoczRg<*&OD|T|jdhG562Wt0{BVz1w)AUdFI{ghQguI1z=^#H7xEtfN)MVP zv!T1z$jabCEDQfR=KDRCmDrWJL!h!st@t6X^e0-PGonYaX3gihBQ4r#2YBtgj zsvwe#kn$J3K1Wd`mO%dzIFc+N{i5WOv*Xoa!Yx!BFRo&`jC`DZ?=jQejk-y{Vxz2Ce1pMe8@##13|=EwW+v41!xqSAiV31g^I@*)bQ@+wu=pYNhmss{`>B6G(sTh? zw>fxV86-vr0Z%Ufx(vgZu?xbhY5AVGVp4}}EfjT~dCdK+a$zKXA)^0g$iNGNM1ow- zEjoK>_v0(b4jJNp4Gy_Uzj66+0&+QEzNKefctwo6X>9*zXvDa2^7C`O=r)2V-6E%; zVDEaOJQ_WYgNpM19{9di=7Uq7I<*E8u!;H^;luyY`rc5)a!Upeg1Th zV_yH6UEIspp;HMK%aW^jP+tblp>>A6b6&n6&z0B29YavH(4{r;j&Fn!nDB^yG_37g zOqk869u@?*smJggd&(s`Su>(dx6{_d3aqpQwkf_e#pry`>Mg+YJKyWt(7I8g%u_pR=Xjf zQ~~5E)ZuU#zi=@{5;y|{JkTsdyi``53|Eu{Y6fMS@@%Fz-Vj-`yZ-p=4*A%t#aqjJ8>e zSFh6tx3#cz9A4L~rD@xaXpo1Ed+Aqy-U#njw+fk%MUG| zn<=_6n01=)3KFcR@y_4o ziB19M`7Ns!1|#Afa>Kwg$WvC_Vh*F|QW|o1k1b3}YH!0ll{E$e-|h?Jf6X2E(%#Wd)@yu8L6JCI06iC+-D|=c{itt%_k+>w~gr z$Hzv)kM6817TtOrPwRobAwxG9510@6`|a&fJb4Yb2}lmLln0n3jm8^ds_D)GoOjXKecCbd$8XkBFjEr#^iur6o2Yp}|>0#fDp494x|7-lljXOYV1dn$+2WCP|^WI|l<4IM_lxu2)vHT8q%h#KIG>z-- zAgf-Dm)A&QAStWRMs8A}(@1soG&;@-hto8tlM@d*%Ih@*k>uBcC-#!Wh5AG_Bs_E{ zebvfNM|EDiR+?ao5C7_{FxCiu>36JFM7c|a7^xbUg&)x)-x!Ek-voilwiR`um1KG$ z(;Xd8$|*ZL7O5y`UO1v=Ol=D|qZ7fPrGX3CAI^FVWyJ6iWlJC*a3OQ!j>9qjv|GD^cIZwj0MkdI^bN)P6EEZ75i8 z^8K+w?5>V;nRLs3M(+fk=?wfp;yvh}_s^b|J(TSS(=r~y1MfdA`zk<6U_NxU)}AO` zeIH5-UhTePQ{XXPYab?+G2s`7_KlHE+L(E??i@>*_BLeUNFpotWtOM)tH%L)bwAJq=MyPr-HJD%@g?&xSG z2F|e6a6w3~{PheFuNcXp?5kO{w7cRc&W+K?vkmD=vC;Ftqvma;Yx~!*GpD1@ysVWk zh%GtKsiF;DR~LcZKPMGBTBcV3oZs&Ska@-;6Q5=@lHBQp{84T{2;45G zzw#$Ijkc;*=a zc?%%tMDByy{}e)YliN~=Q?F4&mG~WZ0P4O{V|C}RU9EPaoUi`(LFNS*`d4;&x3K`^ zP3J?{F%o^=)s^-BJ$m%{YlZf8oSwnqefzCXTY|I>;)e;9JL zt{2Z8=O@A+vi$)OqRKrqg2&gno%j4E(him$?f-~H2oCn*zoU#2mM8D;7t1--*ZEDl zusA>7{_~a+pvorb=Kb&b!UdDkyCBWt*;8v7V~(JkNasJwL-}NRd|G-Ax_5w^4Kjw* zI3jW|)!3C;>=g4ZUO&RceSul$fHFBVjT^pPSUx}O4*335V72KfKwXtQ=x~4d5x~?~ zP+4vVteML8B*a=M$7PS6VKp|VV$_^Ok2ruGfb@cBG3l1L7E5epF%YY4kcUw+;5qUftj)?BpoMRb#aHe|o6}P(z$gO6BD1&Lk@rD@d8_W?R zoEkq-$@x+thUb~U($K!^SR$MbCuJdZ`U8gwLhD>})xsugfq5VpOC5Q39xUv&ZY{q7 zdEd3I;SfrQwuZ-@_7U^a-ie}3%{P?*Fk+oa z_x(%I*kWR@;7MU5M2V2Kw1Ho0MT~oViQ&0zXmgZ^lZr3AWye%9h%2O?Ab~J_;Ox=h znW7Mx#QO;eOdEaa1;1JSk(x94r3Mw7X>gE#%9cVA3-5{y$MH2@dr*|<08B$bSG_V~ zpq99Shy$i^%Y^vX5k_*L@{JMRLwCM^Qr@;8aGo8i9+VZujDRpp2t)abLn7yI{(gFyjQq5Iba$W&Fs*L-=^ge35a-n?T)2 z%Vm)Cmr|#LDsmV8zdXday23oIY#XMhD4($INbLOqI}V}IT)$-O(hY@|M<;n(vBr?XMk2$M<_umE{6J1`vcGvV$Gz z3g&DybI=?!oo(1u(CQf!3oOBgNY}Y+cU?J=POF4Lyed8EeKmGf)7N08r7acy$k2~j zgH_}8iT?3~xHLyodR41E==lwK-q&VObp%=L4_qA}(L-JoUF7rE0NvQc zAFp`wp@ec5VI^= z*<#oX`M`s{g*s1xem|E1oKJE}Kg_QXYV68O)Hp6J;*z6y z^nq(y{3?g*^bdKU(!QFH0FhefpV;3B^9B8#F(1S}HBWMZUznje5rVE{Dq`t~)IQME zO7$^!@Upwe@a)#JmCB8btuCB+NOsxLlzq#OG*|IisXxFK-npJ1$Vcq#~{Kb*cr^;CZB)Wy$Lvy z1(=rU!3Ztx%;w>orei@Y5Mo)b)!8~Qk!E!6Rogc`@nqab49vu22yXP+?3DeB=aZ$c z!I&~~)3{od{7%rF`<+|)iq$KD_f<`ZusEg(bSViKM=_5d=hMWxPH!g!Rf&5*d2#?f zc1~H=H5v{=bonUcJHRv3L0asP5IKBgNAw!D1!-2meZ^qMKeK6sGB=JdQVfN>u7`{5 z^bA}`^$DR6h~wu6A2K5(3bulov|^%#5<bMEcneb3Jw62y>`o6Hj z{rYQ@S)UlXTG0<)hy&B#A_y}hbzFWAy!^8KC0q3mU8BIhxKfux7-Gi&DXKv{DV!@8 z8s@&Fk4ToT;sItYM+D^t2WJ7QkoU3!0BTGD} z6|?YXv}&JD5U=fbYs?yRQC(rDo&idrkL@t_8vIrYY{wLXZ)U}AoI8-8H8DRja9 zhNhhkod#{cacqspQblitc;b)(|3o;PDI>9ua5BWk{*RaTzyExbRu0HAT2VM<&19~I z8J8hc6A@FCPYfB?scobT>x{Sq^7TDAaSCH&zsl5j4WTGi z=qU2F_k3t5zJd=V3HMqdYwesZ%4dgn7+w%T8Xm5}$62cGmpsa6mi58S;-;OAN&r5y4w`CMzrQ0@o zpF*l|^?VI5Al5Kqd2HFYrM;st_a4czq^I3kwPD2fDIVz4)WEh4fn@a@q#CJ3RcUV? zC<0*>`~qVQrxwKvw}%tAsXm*I&j!;TbuiJj|J+)vA|fF)XbcoBVY?LILl;1^0O^*= zW-Yut0(}(>eB=afgB4Yk_k|~fVMRl}y0Lw8Cn(Z?fM!NfG=Ar$S}Z%cN)(0m!Q#E; zsYAI5Mp5Iz%u5Fq4jGQ7FGvTiV7je3-AI#=0TBlxF>#|C;8=hrc)mF-y!cQ1>$DV*fEm9J3CgBwVa zednYho%w7Gcg`fzb;f(3mwLJ~1+fWI^>_gNn<>+NBW&K;X{j*KeYdvdIlkjW zoE+CYa9IveM~J7?A~fXMN|L9kydn!b0M;kWhT0^M+eR>K?g}=k9B)v=q*HIL*b&T5 zDI77ABk5lJJ;|nIX-%b(bLWUpNTK3=lY(GrdQvW0leive`wAW1v|wG|?!<46vT?wh82Oo)AGwAkO=W4lUJz2t4^AlTkKYr`)f{K|i4KR>QNNSBHrT*=KD}`Y z?S_kr1&#Tx#EqR>+$Suq5)^^9Y#rU+EHMaCtRA=x%ko^|ErhoGu1b5E{0joPD%AV` zz?j%L|0l)-#>Vv@OS$}iwx$1X(sv{W0vD9)Ke!SVz|G0_-_loxwKuFcnUVcov|ihh z%_Qef!Ak07lKETdAHmltl`RX;{)(B^5y-_VY09>2V>fo<+Sq6Du#sKU2w>&>c`N^@ z6YAXAs^8a+hl}6oWV(6(VWr`Pvm@YZKu(HK=OV~KmCXVpke`(PK(g) z2d#li0(!Zct9MP0Gy?6k)lE5ycyA7(dW}}dsLAzQV;S5ASDll(8^1IZjo;zE{`4Fi zO_lFZ`Bf|Qj=eoz=>E-%m73YaRe5(`lmgIHZ6N)ydJ-b4oBtU2JcrX2RFIT$JlW>Z4r zsf00~$?AtNu9A+fBVq6aGwdr?t4=(<$YCf~YbSG?iL+k)F`K9_RAw7|`|izHkf0|$ z_FK|^ek_EaJ63;7*)j^OlDnOBo>pCy6YHYz%Fo;p=GK*1gh<{{6}1{boFm{O^{Dza z$|c;ZX#@)MNejx{;e_6rrz{>*o0zUF$UY+ML%QtQX&7Q_6BqNGu-0D=p?N!c73Cu8 zU{);yABEa&2JFUYq~!?yguNUf-h3d>`MIU+XocdBh(%exbArcEI>gKbs z+R@hm>TznbSjeo}!XX2&;2xwwkwi(2f%YRUop1IuMu4v&s}koJ*@50qEJgdRQ99X^ zf9IBED*D3rvR6z!8Jy=nCFr3KHc&gxUa{yY!1Rj>F3uNjpkQ@ayJz= z!bPQK#oRn0IrQQxY{Jb{zr8GP&({Q5hA*nRc(Eui`dc`-G_ew>09V3t@&k95TpH6Z zBE5&crvsZL&=w-~MDuMJlH+=!U*!tr=D`@c%X#5H`LZEa%xl!h`nB{fNqvwoJGiDT z>(7@0+Cvr6_$@sKcEs}J7nrh}+hL<=xW058+nWX$?y>s@WF4a7nxTUB({1V7LF+hC z#T3!s=g)7nQSMm)U56h+DF0Fd;H5w?G12{#X(28R?u!+g>1IA~#-Atea9?%Y@Ivl| zUS=EJBLJrokTCbrniD();pO8W6b8fRHytz=)ac+wx|-o{iG-btZJcp7GTc{&(9X#t z18bt|+LH(}Q{nAEmR*wV{e;{P?}7WTziqmAGXyih#mfDEx^dW8{#l^@YaY_Dwuf)> zFy3DS$rtHDVG85z+jUs?kZyY9_2Q;9QD{Rj7@6#*iWc_L5=@9{@KEL<0g+9ZxYp?) zILE>Wa22P32w3Vi5s|=?mo5h|qFt^(Ut8H9+rO@_+dE&jJE@RC!SwKNYaY%}y> z5ZVd1?JPr|_RYP*CV(7X=Ne+Mb6{IoDK1m>C-EE115507OTj9-Shdzyy16&r*N*+) zH|z(V%N?Qq(&MxPn?2C^_wskcF(N&7vyGi8tY6zu-A0+(h-CZqsYJUg(pIa1I$Nm1 z>6VK)uXATknzY%>{$Q6wG|L`M`ts3F!}aOPCz$W?u@u%0n?S8H5yu@pVI(;sG#}0LEa4gJ7KpI zs2}wA!H2o@9zcSUu~?w%eeDr}(Qq?XaIBlQd zI}q$02CFbZP+TzQ5md4$VtbStoh{CM6P8c*R3N5*7-)io#Fn}#QWk@rI3?g_$>aP9 zbM(kL!rBvRtUjAfEkbcHoFVN{fS!En7BgtN9>UsYMK)prdjK(lKs~DNjeyaXVjw|L zx^qq@Z?5eI1MM0@Lvd*ZBHA~25H zdgCLsMQQ#-aXDj|8sZlGw;gwIA(Cgs_n0FrK%mi za)qv4xb@x?X*B`8F5Ykizb@5vB0FHvj_^4(ryuZ(F{&;&(w_1}OEaWk7*ypKmTQ1V zV%;8UgP6QSW*GVHnKIA@89zt5S-EGYtpMl5w>%r$25xf(wK?7f;;|>wLFjQnGvag0 z4(Nyb;M5KKofg>CgUzV&Y3}okeBjiL&~^zw+<_PrdwC*XSTYjM-x_s^Ywe+Q$-CTA z8x*d2!q=(dX&!KNpvIekAK=;+YgP|aW`$DS@;2|vbcy`-gmqvMjBTZXfXqIFb=@U^ z-N)&YQ}D#p#m*np%!)j@6Xe*3^p!^N1QPF@UH8d4;4kW9odjCc1PqMfcg=i7-8>=l zRT&J1Ph#p=-Wx!FBp~74Q7jpvxvO#*tlT18k}_=%aUJ&Su8OhUavr$aj@i9cZAnms#i1QS$FhUEawu4OU--vA52zuwl0pFmV z3fTO8WQ~2c5!lPVeD%1QJFEjNZc(&biUUvI(B2AozB{DYK}LL&Pu$T8^iC01mL8M> z)Jv40sJoh37JsTocFY|(a15h5<|MQaaeAKmA44i6{>XPRLjQ>FKF~yI6Gvt8L;|5m zQ{32m3D^TB(p1Sktwc$(yX;d@;O$kvctPS-Y*4HSFSgHUE;sBzDN$tb7VAJ6A4R|l zCJvVEV5bNRVMHh<*ik-53fxIg+Y&?(hK`Kod8Oyo`>HB`=)?*to!6fm#VV8I{oiCi zQ*i8Noi^|9Qdhd>gPuI}%yG?>jh^dA~(QKW3FzZ_Tow5s`|Dppoxd+kCWK z)F>toK`5ljDsb0&WTO+Y>_?DxiWy$cwHmpG&?mOGZpKU0Gc{S9s={KrJ8Z& z^5&8ublL_TUDfV$HcUAJ9=riLUWM{!Q>r)9e2*--IiGe_?Hl-T2le^J)SgDMGrp5f zc*4dXan|N3z%#5?NV>9}Ka{&}i|(A4`tPvhEc;}2g%6qE73YL&m5iwiXkX1x ztSQgdG+f~pKR(RvX71HjAQtB@kR}nOOt&dJ&^v>_b#n1)T1W}uZTJZAM|iv8 z(&|MiAkv;Wiwp%oCUrnPX)xBvHf1Fll=rEj)s(E}ATBYD131szq==Pv;~2GWzBub! zEYhq(d6DGOSG8rYoj+7HHWOa7@gT=GYp-d_HL=B$@3mu9u`a9 zi`I9m(~W{w)p7isY>LijQ{Jr|I`j!q*oQ&Bni-z$?3(&>LB8V@Q`}Y~-Qo=D=P~XX za~7DGRkYnYKy&@7t(z{{8PI0>F9v-|eP7XLawtemP~!cqu2!O2Bm7-fvG;%-dd6}Q z+l_gB9e7qNo0e!YsYNMcw78Q=6-@SEoOIocp;Xmk5mQxWY&Y$_OnW0}Oz&K5sBo#N zaj;6&(_tAdsd0Z~$n=E5nnU6%iB_c|qQR$1*9_GF@OUbN&>2!4U7{+@(@lcpWK1UO3+gqv;a zRh0-DHdkjcY5vBj0wW#CFk``Oq^Ieq#q6H8Za5RKAGel~HEonxMTLZZNu$%PNh8Do zXK3Lxx}dQ=fzhq1H-pi*eEH4*W_yXo3DZN0&c8sWK%bJbjbYTT(4f`gMlKEa_L#r8 zT!;o4^+&HtgIZr!g||WY%#60JnpW90lre?&Ewx0}_f1_Z9C>o{cwVvL(-kzo1C9@p zk~S&M?ZuPC@4>Q|L=bc_1OS~6kuk|ZDMX@X2NO2V#314%wfvI z&CbHg$;oWSX=G}`#UjZ6|9e9JziAZ{V-QeE$zxp%czJmEm^u;i2QK7sR|N6K;##M@-le$4mW8I*W*1^)8SoPc)zp0TpEg&$f*Ih5WGOi8#E1h%RRX V0il7#C`kV{1d)`UGX#P0KLDR^SSkPj diff --git a/docs/html/_m_s_s_p_m___gui_manager_mode_8h.html b/docs/html/_m_s_s_p_m___gui_manager_mode_8h.html new file mode 100644 index 00000000..961a741a --- /dev/null +++ b/docs/html/_m_s_s_p_m___gui_manager_mode_8h.html @@ -0,0 +1,173 @@ + + + + + + +MSSPM: MSSPM_GuiManagerMode/MSSPM_GuiManagerMode.h File Reference + + + + + + + + + + + + + + + +

    +
    + + + + + + +
    +
    MSSPM +
    +
    +
    + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    + +
    + +
    + +
    +
    MSSPM_GuiManagerMode.h File Reference
    +
    +
    + +

    GUI definition for the Control widgets class MSSPM_GuiManagerMode in the REMORA embedded tiik. +More...

    +
    #include <QCheckBox>
    +#include <QComboBox>
    +#include <QDial>
    +#include <QFileDialog>
    +#include <QLineEdit>
    +#include <QLineSeries>
    +#include <QPushButton>
    +#include <QRadioButton>
    +#include <QSlider>
    +#include <QVBoxLayout>
    +#include "nmfChartMovableLine.h"
    +#include "nmfChartLine.h"
    +#include "nmfConstantsMSSPM.h"
    +#include "nmfUtils.h"
    +#include <string.h>
    +
    +Include dependency graph for MSSPM_GuiManagerMode.h:
    +
    +
    +
    +
    +This graph shows which files directly or indirectly include this file:
    +
    +
    + + + +
    +
    +

    Go to the source code of this file.

    + + + + + +

    +Classes

    class  MSSPM_GuiManagerMode
     The main GUI class that contains all of the widget definitions for the REMORA Management tool. More...
     
    +

    Detailed Description

    +

    GUI definition for the Control widgets class MSSPM_GuiManagerMode in the REMORA embedded tiik.

    +

    This file contains the GUI definitions for the controls and charts found in the MSSPM_GuiManagerMode class. This class represents the MSSPM REMORA Management tool and allows managers to quickly and intuitively create, view, and save forecast scenarios.

    + +
    +
    + + + + diff --git a/docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.map b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.map new file mode 100644 index 00000000..d8462410 --- /dev/null +++ b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.map @@ -0,0 +1,3 @@ + + + diff --git a/docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.md5 b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.md5 new file mode 100644 index 00000000..9ec9860e --- /dev/null +++ b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.md5 @@ -0,0 +1 @@ +d43496156fdd4fb51184e4dbefbec50f \ No newline at end of file diff --git a/docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.png b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__dep__incl.png new file mode 100644 index 0000000000000000000000000000000000000000..4e71e379611a6853790975c7f7cf0fb027978047 GIT binary patch literal 5939 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 K!ph{$1OEq!`mH1Y literal 0 HcmV?d00001 diff --git a/docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.map b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.map new file mode 100644 index 00000000..e7e2206b --- /dev/null +++ b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.map @@ -0,0 +1,2 @@ + + diff --git a/docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.md5 b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.md5 new file mode 100644 index 00000000..3141e1fe --- /dev/null +++ b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.md5 @@ -0,0 +1 @@ +d012adfa75a88992036092c6127d209f \ No newline at end of file diff --git a/docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.png b/docs/html/_m_s_s_p_m___gui_manager_mode_8h__incl.png new file mode 100644 index 0000000000000000000000000000000000000000..fcbb17f051ec461b0cbe4a9dcd8446686c5efb4b GIT binary patch literal 41584 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 HPWS!+_ymRm literal 0 HcmV?d00001 diff --git a/docs/html/_m_s_s_p_m___gui_manager_mode_8h_source.html b/docs/html/_m_s_s_p_m___gui_manager_mode_8h_source.html index 1e6523ef..2a263d20 100644 --- a/docs/html/_m_s_s_p_m___gui_manager_mode_8h_source.html +++ b/docs/html/_m_s_s_p_m___gui_manager_mode_8h_source.html @@ -107,22 +107,51 @@
    MSSPM_GuiManagerMode.h
    -
    1 #ifndef MSSPM_GUIMANAGERMODE_H
    2 #define MSSPM_GUIMANAGERMODE_H
    3 
    4 #include <QDial>
    5 #include <QVBoxLayout>
    6 #include "nmfChartMovableLine.h"
    7 #include "nmfChartLine.h"
    8 #include <string.h>
    9 
    10 
    11 //QT_CHARTS_USE_NAMESPACE
    12 
    16 class MSSPM_GuiManagerMode : public QObject
    17 {
    18  Q_OBJECT
    19 
    20 private:
    21  QSlider* MModeYearsPerRunSL;
    22  QSlider* MModeRunsPerForecastSL;
    23  QLineEdit* MModeYearsPerRunLE;
    24  QLineEdit* MModeRunsPerForecastLE;
    25  QLineEdit* MModePercMSYLE;
    26  QLineEdit* MModeRParamLE;
    27  QLineEdit* MModeKParamLE;
    28  QLineEdit* MModeCParamLE;
    29  QDial* MModePercMSYDL;
    30  QDial* MModeRParamDL;
    31  QDial* MModeKParamDL;
    32  QDial* MModeCParamDL;
    33  QComboBox* MModeSpeciesCMB;
    34  QWidget* MModeHarvestChartWidget;
    35  QWidget* MModeUpperPlotWidget;
    36  QWidget* MModeWindowWidget;
    37  QPushButton* MModeForecastRunPB;
    38 
    39  QChart* m_MModeHarvestChartWidget;
    40  QChart* m_MModeOutputChartWidget;
    41  nmfDatabase* m_DatabasePtr;
    42  nmfLogger* m_Logger;
    43  std::string m_ProjectSettingsConfig;
    44  nmfChartMovableLine* m_MovableLineChart;
    45 
    46  int m_NumUnusedParameters;
    47  std::string m_ForecastName;
    48  std::string m_HarvestType;
    49  int m_NumYearsInForecast;
    50 
    51  void drawChart();
    52  void saveHarvestData();
    53  void saveUncertaintyParameters();
    54  double getScaleValueFromPlot(int speciesNum,
    55  int yearNum);
    56  void getYearRange(int& firstYear, int& lastYear);
    57  int getNumYearsPerRun();
    58  int getNumRunsPerForecast();
    59 
    60 
    61 signals:
    62  void KeyPressed(QKeyEvent* event);
    63  void MouseMoved(QMouseEvent* event);
    64 
    65 public:
    71  nmfDatabase* databasePtr,
    72  nmfLogger* logger,
    73  std::string& projectSettingsConfig,
    74  QWidget* MModeWidget);
    76 
    77  void getLastYearsCatchValues(
    78  int& lastYear,
    79  std::vector<double>& lastYearsCatchValues);
    80 
    84  void setupConnections();
    85 
    89  void setData(const QStringList& speciesList);
    90 
    91 public Q_SLOTS:
    96  void callback_YearsPerRun(int value);
    101  void callback_RunsPerFore(int value);
    106  void callback_PercMSY(int value);
    111  void callback_RParam(int value);
    116  void callback_KParam(int value);
    121  void callback_CParam(int value);
    122  void callback_RunPB();
    123  void callback_keyPressed(QKeyEvent* event);
    124  void callback_mouseMoved(QMouseEvent* event);
    125 
    126 };
    127 
    128 #endif // MSSPM_GUIMANAGERMODE_H
    void callback_PercMSY(int value)
    callback_PercMSY
    Definition: MSSPM_GuiManagerMode.cpp:153
    -
    The MSSPM_GuiManagerMode class.
    Definition: MSSPM_GuiManagerMode.h:16
    -
    void callback_RParam(int value)
    callback_RParam
    Definition: MSSPM_GuiManagerMode.cpp:159
    -
    void setData(const QStringList &speciesList)
    setupConnections
    Definition: MSSPM_GuiManagerMode.cpp:132
    -
    void callback_CParam(int value)
    callback_CParam
    Definition: MSSPM_GuiManagerMode.cpp:171
    -
    void callback_YearsPerRun(int value)
    callback_YearsPerRun
    Definition: MSSPM_GuiManagerMode.cpp:141
    -
    void setupConnections()
    setupConnections
    Definition: MSSPM_GuiManagerMode.cpp:111
    -
    MSSPM_GuiManagerMode(nmfDatabase *databasePtr, nmfLogger *logger, std::string &projectSettingsConfig, QWidget *MModeWidget)
    MSSPM_GuiManagerMode.
    Definition: MSSPM_GuiManagerMode.cpp:3
    -
    void callback_RunsPerFore(int value)
    callback_RunsPerFore
    Definition: MSSPM_GuiManagerMode.cpp:147
    -
    void callback_KParam(int value)
    callback_KParam
    Definition: MSSPM_GuiManagerMode.cpp:165
    +Go to the documentation of this file.
    1 
    32 #ifndef MSSPM_GUIMANAGERMODE_H
    33 #define MSSPM_GUIMANAGERMODE_H
    34 
    35 #include <QCheckBox>
    36 #include <QComboBox>
    37 #include <QDial>
    38 #include <QFileDialog>
    39 #include <QLineEdit>
    40 #include <QLineSeries>
    41 #include <QPushButton>
    42 #include <QRadioButton>
    43 #include <QSlider>
    44 #include <QVBoxLayout>
    45 
    46 #include "nmfChartMovableLine.h"
    47 #include "nmfChartLine.h"
    48 #include "nmfConstantsMSSPM.h"
    49 #include "nmfUtils.h"
    50 
    51 #include <string.h>
    52 
    53 
    58 class MSSPM_GuiManagerMode : public QObject
    59 {
    60  Q_OBJECT
    61 
    62 private:
    63  const int MAX_SCALE_VALUE = 4;
    64 
    65  QCheckBox* MModeShowMSYCB;
    66  QCheckBox* MModePctMSYCB;
    67  QCheckBox* MModeYAxisLockCB;
    68  QComboBox* MModeSpeciesCMB;
    69  QComboBox* MModeForecastPlotTypeCMB;
    70  QDial* MModeRParamDL;
    71  QDial* MModeKParamDL;
    72  QDial* MModeHParamDL;
    73  QDial* MModePctMSYDL;
    74  QLabel* MModeForecastPlotTypeLB;
    75  QLabel* MModeForecastTypeLB;
    76  QLabel* MModePlotTypeLB;
    77  QLabel* MModePctMSYLBL;
    78  QLabel* MModeSpeciesLB;
    79  QLineEdit* MModeScenarioNameLE;
    80  QLineEdit* MModeYearsPerRunLE;
    81  QLineEdit* MModeRunsPerForecastLE;
    82  QLineEdit* MModeRParamLE;
    83  QLineEdit* MModeKParamLE;
    84  QLineEdit* MModeHParamLE;
    85  QLineEdit* MModePctMSYLE;
    86  QPushButton* MModeForecastRunPB;
    87  QPushButton* MModeForecastDelPB;
    88  QPushButton* MModeForecastLoadPB;
    89  QPushButton* MModeForecastSavePB;
    90  QPushButton* MModeHarvestTypePB;
    91  QPushButton* MModeMultiPlotTypePB;
    92  QPushButton* MModeMaxScaleFactorPB;
    93  QRadioButton* MModeDeterministicRB;
    94  QRadioButton* MModeStochasticRB;
    95  QRadioButton* MModePlotTypeSSRB;
    96  QRadioButton* MModePlotTypeMSRB;
    97  QSlider* MModeYearsPerRunSL;
    98  QSlider* MModeRunsPerForecastSL;
    99  QWidget* MModeHarvestChartWidget;
    100  QWidget* MModeUpperPlotWidget;
    101  QWidget* MModeWindowWidget;
    102  QWidget* MModeParentChartW;
    103 
    104  bool m_ScenarioChanged;
    105  int m_IndexMaxYScaleFactor;
    106  int m_IndexScaleFactorChart1;
    107  int m_IndexScaleFactorChart2;
    108  int m_IndexScaleFactorPoint;
    109  int m_NumRunsPerForecast;
    110  int m_NumUnusedParameters;
    111  int m_NumYearsPerRun;
    112  double m_MaxYAxis;
    113  nmfChartLine* m_ForecastBiomassLineChart;
    114  nmfChartLine* m_ForecastHarvestLineChart;
    115  nmfChartLine* m_ForecastLineChartMonteCarlo;
    116  nmfChartLine* m_MSYLineChart;
    117  nmfDatabase* m_DatabasePtr;
    118  nmfLogger* m_Logger;
    119  std::map<QString,int> m_SpeciesMap;
    120  std::map<QString, void(MSSPM_GuiManagerMode::*)(
    121  QString arg)> m_FunctionMap;
    122  std::string m_ForecastName;
    123  std::string m_HarvestType;
    124  std::string m_ProjectDir;
    125  std::string m_ProjectSettingsConfig;
    126  std::vector<int> m_MaxYAxisValues;
    127  std::vector<nmfChartMovableLine *> m_MovableLineCharts;
    128  QChart* m_ChartWidget;
    129  QChart* m_MModeHarvestChartWidget;
    130  QChart* m_MModeOutputChartWidget;
    131  QChartView* m_ChartView;
    132  QGridLayout* m_GridLayt;
    133  QVBoxLayout* m_GridVLayt;
    134  QVBoxLayout* m_VLayt;
    135  QList<QChart*> m_Charts;
    136  QList<QChartView*> m_Views;
    137  QString m_RemoraScenarioDir;
    138  QWidget* m_GridParent;
    139  QWidget* m_Widget;
    140 
    141  bool couldShowMSYCB();
    142  void drawMultiSpeciesChart();
    143  void drawMSYLines();
    144  void drawMSYLines(
    145  QChart* chart,
    146  int& SpeciesNum,
    147  int& NumSpecies,
    148  int& NumYearsPerRun,
    149  int& NumRunsPerForecast,
    150  int& NoUncertaintyRun,
    151  int& StartForecastYear,
    152  int& YMinSliderVal,
    153  std::string& Algorithm,
    154  std::string& Minimizer,
    155  std::string& ObjectiveCriterion,
    156  std::string& Scaling,
    157  QStringList& RowLabelsForBars,
    158  QStringList& ColumnLabelsForLegend,
    159  QStringList& HoverData,
    160  std::string& MainTitle,
    161  std::string& XLabel,
    162  std::string& YLabel,
    163  const bool& ShowLegend,
    164  const double& Pct);
    165  void drawPlot();
    166  void drawSingleSpeciesChart();
    167  void enableWidgets(bool enable);
    168  QString getCarryingCapacityUncertainty();
    169  QString getForecastPlotType();
    170  QString getGrowthUncertainty();
    171  QString getHarvestType();
    172  QString getHarvestUncertainty();
    173  void getLastYearsCatchValues(
    174  int& lastYear,
    175  std::vector<double>& lastYearsCatchValues);
    176  int getMaxYScaleFactor(const int& speciesNum);
    177  int getNumRunsPerForecast();
    178  int getNumScaleFactorPoints(const int& speciesNum);
    179  int getNumSpecies();
    180  int getNumYearsPerRun();
    181  double getPctMSYValue();
    182  QList<QPointF> getScaleFactorPoints(const int& speciesNum);
    183  QString getScenarioName();
    184  int getSpeciesNum();
    185  void getYearRange(int& firstYear, int& lastYear);
    186  bool isAbsoluteBiomassPlotType();
    187  bool isFishingMortalityPlotType();
    188  bool isMultiPlot();
    189  bool isMultiSpecies();
    190  bool isMSYBoxChecked();
    191  bool isPctMSYBoxChecked();
    192  bool isRelativeBiomassPlotType();
    193  bool isSingleSpecies();
    194  bool isYAxisLocked();
    195  void loadForecastScenario(QString filename);
    196  void removeAllMSYLines(QString type);
    197  void removeMSYLines(
    198  QChart* chart,
    199  const QStringList& MSYTypes);
    200  void resetControls();
    201  void resetNumYearsOnScaleFactorCharts();
    202  void resetScenarioName();
    203  void resetYearsPerRunOnScaleFactorPlot();
    204  void saveForecastParameters();
    205  bool saveForecastScenario(QString filename);
    206  void saveHarvestData();
    207  void saveOutputBiomassData();
    208  void saveUncertaintyParameters();
    209  void setAScaleFactorPoint(QString arg1);
    210  void setDeterministic(QString arg1);
    211  void setForecastPlotType(QString arg1);
    212  void setHarvestType(QString arg1);
    213  void setMaxYScaleFactor(QString maxY);
    214  void setNumRunsPerForecast(QString numRuns);
    215  void setNumYearsPerRun(QString numYears);
    216  void setScenarioChanged(bool state);
    217  void setScenarioName(QString scenarioName);
    218  void setSingleSpecies(QString arg1);
    219  void setupConnections();
    220  void setupMovableLineCharts(const QStringList& SpeciesList);
    221  void setMultiPlot(QString isChecked);
    222  void setMSYLineVisible(QString arg1);
    223  void setNumScaleFactorPoints(QString arg1);
    224  void setUncertaintyCarryingCapacity(QString arg1);
    225  void setUncertaintyGrowth(QString arg1);
    226  void setUncertaintyHarvest(QString arg1);
    227  void resetXAxis();
    232  void resetYAxis();
    233  void updateYearlyScaleFactorPoints();
    234 
    235 signals:
    240  void KeyPressed(QKeyEvent* event);
    245  void MouseMoved(QMouseEvent* event);
    250  void MouseReleased(QMouseEvent* event);
    255  void SaveOutputBiomassData(std::string forecastName);
    261  void UpdateSeedValue(int seedValue);
    262 
    263 public:
    264 
    275  nmfDatabase* DatabasePtr,
    276  nmfLogger* Logger,
    277  std::string& ProjectDir,
    278  std::string& ProjectSettingsConfig,
    279  QStringList& SpeciesList,
    280  QWidget* MModeWidget);
    282 
    289  double getScaleValueFromPlot(int species, int year);
    294  void grabImage(QPixmap& pixmap);
    299  bool isDeterministic();
    304  void setForecastName(QString forecastName);
    309  void setForecastNumYearsPerRun(int numYearsPerRun);
    314  void setForecastNumRunsPerForecast(int numRunsPerForecast);
    319  void setSpeciesList(const QStringList& speciesList);
    320 
    321 
    322 public Q_SLOTS:
    326  void callback_DelPB();
    331  void callback_DeterministicRB(bool pressed);
    336  void callback_ForecastPlotTypeCMB(QString type);
    341  void callback_KeyPressed(QKeyEvent* event);
    345  void callback_LoadPB();
    354  void callback_MouseMoved(QMouseEvent* event);
    359  void callback_MouseReleased(QMouseEvent* event);
    364  void callback_MSYCB(bool isChecked);
    377  void callback_MultiSpeciesRB(bool pressed);
    383  void callback_PctMSYCB(bool isChecked);
    388  void callback_PctMSYDL(int value);
    395  void callback_RunPB();
    400  void callback_RunsPerForecastSL(int value);
    404  void callback_SavePB();
    409  void callback_SingleSpeciesRB(bool pressed);
    414  void callback_SpeciesCMB(QString species);
    419  void callback_StochasticRB(bool pressed);
    434  void callback_UncertaintyKParameterDL(int value);
    439  void callback_UncertaintyRParameterDL(int value);
    446  void callback_YAxisLockedCB(bool checked);
    451  void callback_YearsPerRunSL(int value);
    452 };
    453 
    454 #endif // MSSPM_GUIMANAGERMODE_H
    double getScaleValueFromPlot(int species, int year)
    getScaleValueFromPlot : returns harvest scale value for the passed in species and year ...
    Definition: MSSPM_GuiManagerMode.cpp:1139
    +
    void callback_MultiPlotTypePB()
    Callback invoked when the user presses the multi-species plot type toggle button. There are states: 1...
    Definition: MSSPM_GuiManagerMode.cpp:2040
    +
    void callback_YAxisLockedCB(bool checked)
    Callback invoked when the user checks the Lock Y Axis checkbox. Checking this box forces all subseque...
    Definition: MSSPM_GuiManagerMode.cpp:2239
    +
    void callback_DelPB()
    Callback invoked when the user presses the delete scenario button.
    Definition: MSSPM_GuiManagerMode.cpp:1919
    +
    void callback_UncertaintyHarvestParameterDL(int value)
    Callback invoked when the user modifies the Harvest Uncertainty dial.
    Definition: MSSPM_GuiManagerMode.cpp:2200
    +
    The main GUI class that contains all of the widget definitions for the REMORA Management tool...
    Definition: MSSPM_GuiManagerMode.h:58
    +
    void callback_ForecastPlotTypeCMB(QString type)
    Callback invoked when the user selects a new forecast plot type.
    Definition: MSSPM_GuiManagerMode.cpp:1959
    +
    void callback_PctMSYCB(bool isChecked)
    Callback invoked when the user checks the Percent MSY checkbox. This will enable the Percent MSY dial...
    Definition: MSSPM_GuiManagerMode.cpp:2076
    +
    void callback_MouseMoved(QMouseEvent *event)
    Callback invoked when the user moves the mouse.
    Definition: MSSPM_GuiManagerMode.cpp:2017
    +
    MSSPM_GuiManagerMode(nmfDatabase *DatabasePtr, nmfLogger *Logger, std::string &ProjectDir, std::string &ProjectSettingsConfig, QStringList &SpeciesList, QWidget *MModeWidget)
    Class definition for REMORA Management Tool.
    Definition: MSSPM_GuiManagerMode.cpp:3
    +
    void callback_MaxScaleFactorPB()
    Callback invoked when the user toggles the maximum scale factor button.
    Definition: MSSPM_GuiManagerMode.cpp:2002
    +
    void MouseMoved(QMouseEvent *event)
    Signal emitted when the user moves the mouse over the movable line chart.
    +
    void KeyPressed(QKeyEvent *event)
    Signal emitted when the user presses a key over the movable line chart.
    +
    void callback_SingleSpeciesRB(bool pressed)
    Callback invoked when the user presses the single species radio button.
    Definition: MSSPM_GuiManagerMode.cpp:2164
    +
    void callback_MSYCB(bool isChecked)
    Callback invoked when the user checks the MSY checkbox.
    Definition: MSSPM_GuiManagerMode.cpp:2029
    +
    void callback_DeterministicRB(bool pressed)
    Callback invoked when the user presses the Deterministic radio button.
    Definition: MSSPM_GuiManagerMode.cpp:1952
    +
    void callback_UncertaintyRParameterDL(int value)
    Callback invoked when the user modifies the Growth Uncertainty dial.
    Definition: MSSPM_GuiManagerMode.cpp:2232
    +
    void callback_RunsPerForecastSL(int value)
    Callback invoked when the user interacts with the Runs per Forecast slider.
    Definition: MSSPM_GuiManagerMode.cpp:2115
    +
    void setForecastNumYearsPerRun(int numYearsPerRun)
    Sets REMORA&#39;s internal number years per run variable to the passed value and updates the GUI...
    Definition: MSSPM_GuiManagerMode.cpp:1633
    +
    void MouseReleased(QMouseEvent *event)
    Signal emitted when the user releases the mouse over the movable line chart.
    +
    void grabImage(QPixmap &pixmap)
    grabImage : Performs a "smart" screen grab based upon the state of the controls
    Definition: MSSPM_GuiManagerMode.cpp:1190
    +
    void callback_StochasticRB(bool pressed)
    Callback invoked when the user presses the stochastic radio button.
    Definition: MSSPM_GuiManagerMode.cpp:2193
    +
    void callback_MultiSpeciesRB(bool pressed)
    Callback invoked when the user presses the Multi-Species radio button.
    Definition: MSSPM_GuiManagerMode.cpp:2060
    +
    void callback_MouseReleased(QMouseEvent *event)
    Callback invoked when the user releases the mouse.
    Definition: MSSPM_GuiManagerMode.cpp:2023
    +
    void callback_RunPB()
    Callback invoked when the user presses the Run button. Run causes the appropriate forecast scenario b...
    Definition: MSSPM_GuiManagerMode.cpp:2099
    +
    void callback_UncertaintyHarvestParameterPB()
    Callback invoked when the user presses the Harvest Uncertainty parameter toggle button.
    Definition: MSSPM_GuiManagerMode.cpp:2207
    +
    void SaveOutputBiomassData(std::string forecastName)
    Signal emitted when the user wants to save the output biomass data for the current forecast...
    +
    bool isDeterministic()
    Returns true if the Deterministic radio button is pressed.
    Definition: MSSPM_GuiManagerMode.cpp:1212
    +
    void callback_KeyPressed(QKeyEvent *event)
    Callback invoked when the user presses a keyboard key.
    Definition: MSSPM_GuiManagerMode.cpp:1980
    +
    void callback_SpeciesCMB(QString species)
    Callback invoked when the user changes the species combo box.
    Definition: MSSPM_GuiManagerMode.cpp:2176
    +
    void callback_LoadPB()
    Callback invoked when the user presses the Load Scenario button.
    Definition: MSSPM_GuiManagerMode.cpp:1986
    +
    void UpdateSeedValue(int seedValue)
    Signal emitted when the user needs to update the seed value in the main routine when saving the curre...
    +
    void setSpeciesList(const QStringList &speciesList)
    Sets REMORA&#39;s species pulldown list to the passed list of QStrings.
    Definition: MSSPM_GuiManagerMode.cpp:1756
    +
    void callback_YearsPerRunSL(int value)
    Callback invoked when the user releases the Years per Run slider.
    Definition: MSSPM_GuiManagerMode.cpp:2273
    +
    void callback_UncertaintyKParameterDL(int value)
    Callback invoked when the user modifies the Carrying Capacity Uncertainty dial.
    Definition: MSSPM_GuiManagerMode.cpp:2225
    +
    void setForecastNumRunsPerForecast(int numRunsPerForecast)
    Sets REMORA&#39;s internal number of runs per forecast to the passed value and updates the GUI...
    Definition: MSSPM_GuiManagerMode.cpp:1621
    +
    void callback_PctMSYDL(int value)
    Callback invoked when the user modifies the Percent MSY dial.
    Definition: MSSPM_GuiManagerMode.cpp:2090
    +
    void setForecastName(QString forecastName)
    Sets REMORA&#39;s internal forecast name variable to the passed in forecast name.
    Definition: MSSPM_GuiManagerMode.cpp:1615
    +
    void callback_SavePB()
    Callback invoked when the user presses the Save Scenario button.
    Definition: MSSPM_GuiManagerMode.cpp:2123
    diff --git a/docs/html/annotated_dup.js b/docs/html/annotated_dup.js index ee48a2fc..0d272ddf 100644 --- a/docs/html/annotated_dup.js +++ b/docs/html/annotated_dup.js @@ -6,7 +6,6 @@ var annotated_dup = [ "InitSpeciesDataStruct", "struct_init_species_data_struct.html", "struct_init_species_data_struct" ], [ "LoadDlg", "class_load_dlg.html", "class_load_dlg" ], [ "LoadForecastDlg", "class_load_forecast_dlg.html", "class_load_forecast_dlg" ], - [ "MSSPM_GuiManagerMode", "class_m_s_s_p_m___gui_manager_mode.html", "class_m_s_s_p_m___gui_manager_mode" ], [ "MSSPM_GuiOutputControls", "class_m_s_s_p_m___gui_output_controls.html", "class_m_s_s_p_m___gui_output_controls" ], [ "MultiScenarioSaveDlg", "class_multi_scenario_save_dlg.html", "class_multi_scenario_save_dlg" ], [ "NLopt_Estimator", "class_n_lopt___estimator.html", "class_n_lopt___estimator" ], @@ -27,5 +26,6 @@ var annotated_dup = [ "nmfSetup_Tab2", "classnmf_setup___tab2.html", "classnmf_setup___tab2" ], [ "nmfSetup_Tab3", "classnmf_setup___tab3.html", "classnmf_setup___tab3" ], [ "nmfSetup_Tab4", "classnmf_setup___tab4.html", "classnmf_setup___tab4" ], - [ "PreferencesDialog", "class_preferences_dialog.html", "class_preferences_dialog" ] + [ "PreferencesDialog", "class_preferences_dialog.html", "class_preferences_dialog" ], + [ "REMORA", "class_r_e_m_o_r_a.html", "class_r_e_m_o_r_a" ] ]; \ No newline at end of file diff --git a/docs/html/class_m_s_s_p_m___gui_manager_mode-members.html b/docs/html/class_m_s_s_p_m___gui_manager_mode-members.html index fd94a207..2e2d35f0 100644 --- a/docs/html/class_m_s_s_p_m___gui_manager_mode-members.html +++ b/docs/html/class_m_s_s_p_m___gui_manager_mode-members.html @@ -112,22 +112,45 @@

    This is the complete list of members for MSSPM_GuiManagerMode, including all inherited members.

    - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    callback_CParam(int value)MSSPM_GuiManagerModeslot
    callback_keyPressed(QKeyEvent *event) (defined in MSSPM_GuiManagerMode)MSSPM_GuiManagerModeslot
    callback_KParam(int value)MSSPM_GuiManagerModeslot
    callback_mouseMoved(QMouseEvent *event) (defined in MSSPM_GuiManagerMode)MSSPM_GuiManagerModeslot
    callback_PercMSY(int value)MSSPM_GuiManagerModeslot
    callback_RParam(int value)MSSPM_GuiManagerModeslot
    callback_RunPB() (defined in MSSPM_GuiManagerMode)MSSPM_GuiManagerModeslot
    callback_RunsPerFore(int value)MSSPM_GuiManagerModeslot
    callback_YearsPerRun(int value)MSSPM_GuiManagerModeslot
    getLastYearsCatchValues(int &lastYear, std::vector< double > &lastYearsCatchValues) (defined in MSSPM_GuiManagerMode)MSSPM_GuiManagerMode
    KeyPressed(QKeyEvent *event) (defined in MSSPM_GuiManagerMode)MSSPM_GuiManagerModesignal
    MouseMoved(QMouseEvent *event) (defined in MSSPM_GuiManagerMode)MSSPM_GuiManagerModesignal
    MSSPM_GuiManagerMode(nmfDatabase *databasePtr, nmfLogger *logger, std::string &projectSettingsConfig, QWidget *MModeWidget)MSSPM_GuiManagerMode
    setData(const QStringList &speciesList)MSSPM_GuiManagerMode
    setupConnections()MSSPM_GuiManagerMode
    ~MSSPM_GuiManagerMode() (defined in MSSPM_GuiManagerMode)MSSPM_GuiManagerMode
    callback_DelPB()MSSPM_GuiManagerModeslot
    callback_DeterministicRB(bool pressed)MSSPM_GuiManagerModeslot
    callback_ForecastPlotTypeCMB(QString type)MSSPM_GuiManagerModeslot
    callback_KeyPressed(QKeyEvent *event)MSSPM_GuiManagerModeslot
    callback_LoadPB()MSSPM_GuiManagerModeslot
    callback_MaxScaleFactorPB()MSSPM_GuiManagerModeslot
    callback_MouseMoved(QMouseEvent *event)MSSPM_GuiManagerModeslot
    callback_MouseReleased(QMouseEvent *event)MSSPM_GuiManagerModeslot
    callback_MSYCB(bool isChecked)MSSPM_GuiManagerModeslot
    callback_MultiPlotTypePB()MSSPM_GuiManagerModeslot
    callback_MultiSpeciesRB(bool pressed)MSSPM_GuiManagerModeslot
    callback_PctMSYCB(bool isChecked)MSSPM_GuiManagerModeslot
    callback_PctMSYDL(int value)MSSPM_GuiManagerModeslot
    callback_RunPB()MSSPM_GuiManagerModeslot
    callback_RunsPerForecastSL(int value)MSSPM_GuiManagerModeslot
    callback_SavePB()MSSPM_GuiManagerModeslot
    callback_SingleSpeciesRB(bool pressed)MSSPM_GuiManagerModeslot
    callback_SpeciesCMB(QString species)MSSPM_GuiManagerModeslot
    callback_StochasticRB(bool pressed)MSSPM_GuiManagerModeslot
    callback_UncertaintyHarvestParameterDL(int value)MSSPM_GuiManagerModeslot
    callback_UncertaintyHarvestParameterPB()MSSPM_GuiManagerModeslot
    callback_UncertaintyKParameterDL(int value)MSSPM_GuiManagerModeslot
    callback_UncertaintyRParameterDL(int value)MSSPM_GuiManagerModeslot
    callback_YAxisLockedCB(bool checked)MSSPM_GuiManagerModeslot
    callback_YearsPerRunSL(int value)MSSPM_GuiManagerModeslot
    getScaleValueFromPlot(int species, int year)MSSPM_GuiManagerMode
    grabImage(QPixmap &pixmap)MSSPM_GuiManagerMode
    isDeterministic()MSSPM_GuiManagerMode
    KeyPressed(QKeyEvent *event)MSSPM_GuiManagerModesignal
    MouseMoved(QMouseEvent *event)MSSPM_GuiManagerModesignal
    MouseReleased(QMouseEvent *event)MSSPM_GuiManagerModesignal
    MSSPM_GuiManagerMode(nmfDatabase *DatabasePtr, nmfLogger *Logger, std::string &ProjectDir, std::string &ProjectSettingsConfig, QStringList &SpeciesList, QWidget *MModeWidget)MSSPM_GuiManagerMode
    SaveOutputBiomassData(std::string forecastName)MSSPM_GuiManagerModesignal
    setForecastName(QString forecastName)MSSPM_GuiManagerMode
    setForecastNumRunsPerForecast(int numRunsPerForecast)MSSPM_GuiManagerMode
    setForecastNumYearsPerRun(int numYearsPerRun)MSSPM_GuiManagerMode
    setSpeciesList(const QStringList &speciesList)MSSPM_GuiManagerMode
    UpdateSeedValue(int seedValue)MSSPM_GuiManagerModesignal
    ~MSSPM_GuiManagerMode() (defined in MSSPM_GuiManagerMode)MSSPM_GuiManagerMode
    diff --git a/docs/html/class_m_s_s_p_m___gui_manager_mode.html b/docs/html/class_m_s_s_p_m___gui_manager_mode.html index 886d2763..84ded2fb 100644 --- a/docs/html/class_m_s_s_p_m___gui_manager_mode.html +++ b/docs/html/class_m_s_s_p_m___gui_manager_mode.html @@ -115,7 +115,7 @@
    -

    The MSSPM_GuiManagerMode class. +

    The main GUI class that contains all of the widget definitions for the REMORA Management tool. More...

    #include <MSSPM_GuiManagerMode.h>

    @@ -123,77 +123,147 @@ Inheritance diagram for MSSPM_GuiManagerMode:
    Inheritance graph
    - -
    [legend]
    Collaboration diagram for MSSPM_GuiManagerMode:
    Collaboration graph
    - -
    [legend]
    - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +void  + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Public Slots

    void callback_YearsPerRun (int value)
     callback_YearsPerRun More...
     
    void callback_RunsPerFore (int value)
     callback_RunsPerFore More...
     
    void callback_PercMSY (int value)
     callback_PercMSY More...
     
    void callback_RParam (int value)
     callback_RParam More...
     
    void callback_KParam (int value)
     callback_KParam More...
     
    void callback_CParam (int value)
     callback_CParam More...
     
    +void callback_DelPB ()
     Callback invoked when the user presses the delete scenario button.
     
    void callback_DeterministicRB (bool pressed)
     Callback invoked when the user presses the Deterministic radio button. More...
     
    void callback_ForecastPlotTypeCMB (QString type)
     Callback invoked when the user selects a new forecast plot type. More...
     
    void callback_KeyPressed (QKeyEvent *event)
     Callback invoked when the user presses a keyboard key. More...
     
    +void callback_LoadPB ()
     Callback invoked when the user presses the Load Scenario button.
     
    +void callback_MaxScaleFactorPB ()
     Callback invoked when the user toggles the maximum scale factor button.
     
    void callback_MouseMoved (QMouseEvent *event)
     Callback invoked when the user moves the mouse. More...
     
    void callback_MouseReleased (QMouseEvent *event)
     Callback invoked when the user releases the mouse. More...
     
    void callback_MSYCB (bool isChecked)
     Callback invoked when the user checks the MSY checkbox. More...
     
    +void callback_MultiPlotTypePB ()
     Callback invoked when the user presses the multi-species plot type toggle button. There are states: 1 and 1+. The former signifies the user wishes to see all plots on the same chart (with no Monte Carlo plots). The latter signifies the user wishes to see all plots on separate smaller charts (with the Monte Carlo plots) and composited into one image.
     
    void callback_MultiSpeciesRB (bool pressed)
     Callback invoked when the user presses the Multi-Species radio button. More...
     
    void callback_PctMSYCB (bool isChecked)
     Callback invoked when the user checks the Percent MSY checkbox. This will enable the Percent MSY dial to the right of this checkbox. More...
     
    void callback_PctMSYDL (int value)
     Callback invoked when the user modifies the Percent MSY dial. More...
     
    -void callback_RunPB ()
    callback_RunPB ()
     Callback invoked when the user presses the Run button. Run causes the appropriate forecast scenario biomass data to be generated and saved in the database for each species. A default plot is then displayed using these data. Additional plots can be viewed by selecting another species or by changing the plot type.
     
    -void callback_keyPressed (QKeyEvent *event)
     
    -void callback_mouseMoved (QMouseEvent *event)
     
    void callback_RunsPerForecastSL (int value)
     Callback invoked when the user interacts with the Runs per Forecast slider. More...
     
    +void callback_SavePB ()
     Callback invoked when the user presses the Save Scenario button.
     
    void callback_SingleSpeciesRB (bool pressed)
     Callback invoked when the user presses the single species radio button. More...
     
    void callback_SpeciesCMB (QString species)
     Callback invoked when the user changes the species combo box. More...
     
    void callback_StochasticRB (bool pressed)
     Callback invoked when the user presses the stochastic radio button. More...
     
    void callback_UncertaintyHarvestParameterDL (int value)
     Callback invoked when the user modifies the Harvest Uncertainty dial. More...
     
    +void callback_UncertaintyHarvestParameterPB ()
     Callback invoked when the user presses the Harvest Uncertainty parameter toggle button.
     
    void callback_UncertaintyKParameterDL (int value)
     Callback invoked when the user modifies the Carrying Capacity Uncertainty dial. More...
     
    void callback_UncertaintyRParameterDL (int value)
     Callback invoked when the user modifies the Growth Uncertainty dial. More...
     
    void callback_YAxisLockedCB (bool checked)
     Callback invoked when the user checks the Lock Y Axis checkbox. Checking this box forces all subsequent plots to have the same maximum y range value. This is useful if multiple plots will be captured and then flipped through to view differences. More...
     
    void callback_YearsPerRunSL (int value)
     Callback invoked when the user releases the Years per Run slider. More...
     
    - + + - + + + + + + + + + + +

    Signals

    -void KeyPressed (QKeyEvent *event)
    void KeyPressed (QKeyEvent *event)
     Signal emitted when the user presses a key over the movable line chart. More...
     
    -void MouseMoved (QMouseEvent *event)
    void MouseMoved (QMouseEvent *event)
     Signal emitted when the user moves the mouse over the movable line chart. More...
     
    void MouseReleased (QMouseEvent *event)
     Signal emitted when the user releases the mouse over the movable line chart. More...
     
    void SaveOutputBiomassData (std::string forecastName)
     Signal emitted when the user wants to save the output biomass data for the current forecast. More...
     
    void UpdateSeedValue (int seedValue)
     Signal emitted when the user needs to update the seed value in the main routine when saving the current forecast parameters. More...
     
    - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + +

    Public Member Functions

     MSSPM_GuiManagerMode (nmfDatabase *databasePtr, nmfLogger *logger, std::string &projectSettingsConfig, QWidget *MModeWidget)
     MSSPM_GuiManagerMode. More...
     
    -void getLastYearsCatchValues (int &lastYear, std::vector< double > &lastYearsCatchValues)
     
    -void setupConnections ()
     setupConnections
     
    -void setData (const QStringList &speciesList)
     setupConnections
     
     MSSPM_GuiManagerMode (nmfDatabase *DatabasePtr, nmfLogger *Logger, std::string &ProjectDir, std::string &ProjectSettingsConfig, QStringList &SpeciesList, QWidget *MModeWidget)
     Class definition for REMORA Management Tool. More...
     
    double getScaleValueFromPlot (int species, int year)
     getScaleValueFromPlot : returns harvest scale value for the passed in species and year More...
     
    void grabImage (QPixmap &pixmap)
     grabImage : Performs a "smart" screen grab based upon the state of the controls More...
     
    bool isDeterministic ()
     Returns true if the Deterministic radio button is pressed. More...
     
    void setForecastName (QString forecastName)
     Sets REMORA's internal forecast name variable to the passed in forecast name. More...
     
    void setForecastNumYearsPerRun (int numYearsPerRun)
     Sets REMORA's internal number years per run variable to the passed value and updates the GUI. More...
     
    void setForecastNumRunsPerForecast (int numRunsPerForecast)
     Sets REMORA's internal number of runs per forecast to the passed value and updates the GUI. More...
     
    void setSpeciesList (const QStringList &speciesList)
     Sets REMORA's species pulldown list to the passed list of QStrings. More...
     

    Detailed Description

    -

    The MSSPM_GuiManagerMode class.

    +

    The main GUI class that contains all of the widget definitions for the REMORA Management tool.

    Constructor & Destructor Documentation

    - +
    @@ -201,19 +271,31 @@ - + - + - + + + + + + + + + + + + + @@ -229,10 +311,15 @@
    MSSPM_GuiManagerMode::MSSPM_GuiManagerMode ( nmfDatabase * databasePtr, DatabasePtr,
    nmfLogger * logger, Logger,
    std::string & projectSettingsConfig, ProjectDir,
    std::string & ProjectSettingsConfig,
    QStringList & SpeciesList,
    -

    MSSPM_GuiManagerMode.

    +

    Class definition for REMORA Management Tool.

    Parameters
    - + + + + + +
    MModeWidget
    DatabasePtr: pointer to database
    Logger: pointer to logger
    ProjectDir: project directory
    ProjectSettingsConfig: project settings configuration name
    SpeciesList: list of species
    MModeWidget: parent widget in which to place this class
    @@ -240,7 +327,7 @@

    Member Function Documentation

    - +
    @@ -248,10 +335,10 @@

    Member Function Documentation

    - + - - + +
    void MSSPM_GuiManagerMode::callback_CParam void MSSPM_GuiManagerMode::callback_DeterministicRB (int value)bool pressed)
    @@ -262,17 +349,17 @@

    Member Function Documentation

    -

    callback_CParam

    +

    Callback invoked when the user presses the Deterministic radio button.

    Parameters
    - +
    value
    pressed: state of the radio button (true/false)
    - +
    @@ -280,10 +367,202 @@

    Member Function Documentation

    + + +
    - + - - + + + + +
    void MSSPM_GuiManagerMode::callback_KParam void MSSPM_GuiManagerMode::callback_ForecastPlotTypeCMB (int value)QString type)
    +
    +slot
    +
    + +

    Callback invoked when the user selects a new forecast plot type.

    +
    Parameters
    + + +
    type: name of the forecast plot type chosen
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_KeyPressed (QKeyEvent * event)
    +
    +slot
    +
    + +

    Callback invoked when the user presses a keyboard key.

    +
    Parameters
    + + +
    event: key event data structure
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_MouseMoved (QMouseEvent * event)
    +
    +slot
    +
    + +

    Callback invoked when the user moves the mouse.

    +
    Parameters
    + + +
    event: mouse event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_MouseReleased (QMouseEvent * event)
    +
    +slot
    +
    + +

    Callback invoked when the user releases the mouse.

    +
    Parameters
    + + +
    event: mouse event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_MSYCB (bool isChecked)
    +
    +slot
    +
    + +

    Callback invoked when the user checks the MSY checkbox.

    +
    Parameters
    + + +
    isChecked: boolean signifying if the checkbox has been checked
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_MultiSpeciesRB (bool pressed)
    +
    +slot
    +
    + +

    Callback invoked when the user presses the Multi-Species radio button.

    +
    Parameters
    + + +
    pressed: state of the Multi-Species button
    +
    +
    + +
    +
    + +
    +
    + + +
    + + + + + +
    void MSSPM_GuiManagerMode::callback_PctMSYCB (bool isChecked)
    @@ -294,17 +573,17 @@

    Member Function Documentation

    -

    callback_KParam

    +

    Callback invoked when the user checks the Percent MSY checkbox. This will enable the Percent MSY dial to the right of this checkbox.

    Parameters
    - +
    value
    isChecked: state of checkbox
    - +
    @@ -312,7 +591,7 @@

    Member Function Documentation

    - - + + diff --git a/docs/html/functions.html b/docs/html/functions.html index c976034f..7739abe9 100644 --- a/docs/html/functions.html +++ b/docs/html/functions.html @@ -92,6 +92,7 @@
  • f
  • g
  • i
  • +
  • k
  • l
  • m
  • n
  • diff --git a/docs/html/functions_b.html b/docs/html/functions_b.html index 0716646c..f8552423 100644 --- a/docs/html/functions_b.html +++ b/docs/html/functions_b.html @@ -92,6 +92,7 @@
  • f
  • g
  • i
  • +
  • k
  • l
  • m
  • n
  • diff --git a/docs/html/functions_c.html b/docs/html/functions_c.html index 3edc62d4..649ca276 100644 --- a/docs/html/functions_c.html +++ b/docs/html/functions_c.html @@ -92,6 +92,7 @@
  • f
  • g
  • i
  • +
  • k
  • l
  • m
  • n
  • @@ -167,9 +168,6 @@

    - c -

    - + @@ -326,17 +605,17 @@

    Member Function Documentation

    void MSSPM_GuiManagerMode::callback_PercMSY void MSSPM_GuiManagerMode::callback_PctMSYDL ( int  value)
    -

    callback_PercMSY

    +

    Callback invoked when the user modifies the Percent MSY dial.

    Parameters
    - +
    value
    value: Integer value from the Percent MSY dial
    - +
    @@ -344,7 +623,7 @@

    Member Function Documentation

    - + + + @@ -142,31 +144,35 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -184,31 +190,34 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - + + +
    - + @@ -358,17 +637,113 @@

    Member Function Documentation

    void MSSPM_GuiManagerMode::callback_RParam void MSSPM_GuiManagerMode::callback_RunsPerForecastSL ( int  value)
    -

    callback_RParam

    +

    Callback invoked when the user interacts with the Runs per Forecast slider.

    +
    Parameters
    + + +
    value: current value on the Runs per Forecast slider
    +
    +
    + +
    + + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_SingleSpeciesRB (bool pressed)
    +
    +slot
    +
    + +

    Callback invoked when the user presses the single species radio button.

    +
    Parameters
    + + +
    pressed: state of the single species radio button
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_SpeciesCMB (QString species)
    +
    +slot
    +
    + +

    Callback invoked when the user changes the species combo box.

    +
    Parameters
    + + +
    species: current species shown in the species combo box
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_StochasticRB (bool pressed)
    +
    +slot
    +
    + +

    Callback invoked when the user presses the stochastic radio button.

    Parameters
    - +
    value
    pressed: state of the stochastic radio button
    - +
    @@ -376,7 +751,7 @@

    Member Function Documentation

    + + + @@ -194,6 +197,9 @@ void  + + +
    - + @@ -390,17 +765,17 @@

    Member Function Documentation

    void MSSPM_GuiManagerMode::callback_RunsPerFore void MSSPM_GuiManagerMode::callback_UncertaintyHarvestParameterDL ( int  value)
    -

    callback_RunsPerFore

    +

    Callback invoked when the user modifies the Harvest Uncertainty dial.

    Parameters
    - +
    value
    value: current value of the Harvest Uncertainty dial
    - +
    @@ -408,7 +783,7 @@

    Member Function Documentation

    - - - - + + + + + +
    - + @@ -422,10 +797,440 @@

    Member Function Documentation

    void MSSPM_GuiManagerMode::callback_YearsPerRun void MSSPM_GuiManagerMode::callback_UncertaintyKParameterDL ( int  value)
    -

    callback_YearsPerRun

    +

    Callback invoked when the user modifies the Carrying Capacity Uncertainty dial.

    +
    Parameters
    + + +
    value: current value of the Carrying Capacity Uncertainty dial
    +
    +
    + +
    + + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_UncertaintyRParameterDL (int value)
    +
    +slot
    +
    + +

    Callback invoked when the user modifies the Growth Uncertainty dial.

    +
    Parameters
    + + +
    value: current value of the Growth Uncertainty dial
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_YAxisLockedCB (bool checked)
    +
    +slot
    +
    + +

    Callback invoked when the user checks the Lock Y Axis checkbox. Checking this box forces all subsequent plots to have the same maximum y range value. This is useful if multiple plots will be captured and then flipped through to view differences.

    +
    Parameters
    + + +
    checked: boolean determining if the box has just been checked (true) or unchecked (false)
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::callback_YearsPerRunSL (int value)
    +
    +slot
    +
    + +

    Callback invoked when the user releases the Years per Run slider.

    +
    Parameters
    + + +
    value: current value of the Years per Run slider
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + +
    double MSSPM_GuiManagerMode::getScaleValueFromPlot (int species,
    int year 
    )
    +
    + +

    getScaleValueFromPlot : returns harvest scale value for the passed in species and year

    +
    Parameters
    + + + +
    species: species number from the list of species
    year: year along x-axis of scale factor plot
    +
    +
    +
    Returns
    Returns scale factor (y-value) corresponding to the passed in values
    + +
    +
    + +
    +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::grabImage (QPixmap & pixmap)
    +
    + +

    grabImage : Performs a "smart" screen grab based upon the state of the controls

    +
    Parameters
    + + +
    pixmap: Returns the pixmap of the captured widget
    +
    +
    + +
    +
    + +
    +
    + + + + + + + +
    bool MSSPM_GuiManagerMode::isDeterministic ()
    +
    + +

    Returns true if the Deterministic radio button is pressed.

    +
    Returns
    true if state is deterministic, else false if stochastic
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::KeyPressed (QKeyEvent * event)
    +
    +signal
    +
    + +

    Signal emitted when the user presses a key over the movable line chart.

    +
    Parameters
    + + +
    event: key event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::MouseMoved (QMouseEvent * event)
    +
    +signal
    +
    + +

    Signal emitted when the user moves the mouse over the movable line chart.

    +
    Parameters
    + + +
    event: mouse event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::MouseReleased (QMouseEvent * event)
    +
    +signal
    +
    + +

    Signal emitted when the user releases the mouse over the movable line chart.

    +
    Parameters
    + + +
    event: mouse event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::SaveOutputBiomassData (std::string forecastName)
    +
    +signal
    +
    + +

    Signal emitted when the user wants to save the output biomass data for the current forecast.

    +
    Parameters
    + + +
    forecastName: the forecast name
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::setForecastName (QString forecastName)
    +
    + +

    Sets REMORA's internal forecast name variable to the passed in forecast name.

    +
    Parameters
    + + +
    forecastName: the name of the current forecast
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::setForecastNumRunsPerForecast (int numRunsPerForecast)
    +
    + +

    Sets REMORA's internal number of runs per forecast to the passed value and updates the GUI.

    +
    Parameters
    + + +
    numRunsPerForecast: number of runs to generate per forecast scenario run
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::setForecastNumYearsPerRun (int numYearsPerRun)
    +
    + +

    Sets REMORA's internal number years per run variable to the passed value and updates the GUI.

    +
    Parameters
    + + +
    numYearsPerRun: number of years per forecast run
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::setSpeciesList (const QStringList & speciesList)
    +
    + +

    Sets REMORA's species pulldown list to the passed list of QStrings.

    +
    Parameters
    + + +
    speciesList: current list of species in model
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void MSSPM_GuiManagerMode::UpdateSeedValue (int seedValue)
    +
    +signal
    +
    + +

    Signal emitted when the user needs to update the seed value in the main routine when saving the current forecast parameters.

    Parameters
    - +
    value
    seedValue: 1 or 0 (0 signifies that a random seed value will be used)
    diff --git a/docs/html/class_m_s_s_p_m___gui_manager_mode.js b/docs/html/class_m_s_s_p_m___gui_manager_mode.js index 02ed05a0..c5f19c79 100644 --- a/docs/html/class_m_s_s_p_m___gui_manager_mode.js +++ b/docs/html/class_m_s_s_p_m___gui_manager_mode.js @@ -1,19 +1,42 @@ var class_m_s_s_p_m___gui_manager_mode = [ - [ "MSSPM_GuiManagerMode", "class_m_s_s_p_m___gui_manager_mode.html#a2bcd62bfb5e89e0cfd41d80899b5dd92", null ], + [ "MSSPM_GuiManagerMode", "class_m_s_s_p_m___gui_manager_mode.html#abaa6f0bd5d796bbb69057f4f4d9b617c", null ], [ "~MSSPM_GuiManagerMode", "class_m_s_s_p_m___gui_manager_mode.html#a08e7399d712e599b72e900a548e86c3c", null ], - [ "callback_CParam", "class_m_s_s_p_m___gui_manager_mode.html#a17c42f0841b89d4fb5afd315529659d3", null ], - [ "callback_keyPressed", "class_m_s_s_p_m___gui_manager_mode.html#afcb9563de6c18d62e9df3b574e240bd2", null ], - [ "callback_KParam", "class_m_s_s_p_m___gui_manager_mode.html#aa249ff02418ee6f18037fa3d323f236c", null ], - [ "callback_mouseMoved", "class_m_s_s_p_m___gui_manager_mode.html#a5d4d13f8e1ae9b9d53a1047a50286ee1", null ], - [ "callback_PercMSY", "class_m_s_s_p_m___gui_manager_mode.html#a74f3091230eaea5cdc219301e39a28d3", null ], - [ "callback_RParam", "class_m_s_s_p_m___gui_manager_mode.html#a23fdcc5784e0b3593a6822e57cabfe22", null ], + [ "callback_DelPB", "class_m_s_s_p_m___gui_manager_mode.html#acf1c7c12a25f5e65affcbdba47f65947", null ], + [ "callback_DeterministicRB", "class_m_s_s_p_m___gui_manager_mode.html#abd28c621a4e0a470542da111dd489fae", null ], + [ "callback_ForecastPlotTypeCMB", "class_m_s_s_p_m___gui_manager_mode.html#a64451aee868eb3e5ce504e63fa60f210", null ], + [ "callback_KeyPressed", "class_m_s_s_p_m___gui_manager_mode.html#a76bd8df95115add564b1a5c730f3c74a", null ], + [ "callback_LoadPB", "class_m_s_s_p_m___gui_manager_mode.html#aaab464abdd85e0931c05122581ea8aeb", null ], + [ "callback_MaxScaleFactorPB", "class_m_s_s_p_m___gui_manager_mode.html#ab066eb9fd3fd321d246b565da3642dd5", null ], + [ "callback_MouseMoved", "class_m_s_s_p_m___gui_manager_mode.html#affcdba97b83c24c927bff0998777d84e", null ], + [ "callback_MouseReleased", "class_m_s_s_p_m___gui_manager_mode.html#a452dd4f6c1bc8da61920232a6f07551c", null ], + [ "callback_MSYCB", "class_m_s_s_p_m___gui_manager_mode.html#a530d60ec1e4301b70931bf6ff893a8d4", null ], + [ "callback_MultiPlotTypePB", "class_m_s_s_p_m___gui_manager_mode.html#a4a5368914d685ab8ec5b705955214879", null ], + [ "callback_MultiSpeciesRB", "class_m_s_s_p_m___gui_manager_mode.html#a5d5a2ad01140362d7c7ae5a80826c706", null ], + [ "callback_PctMSYCB", "class_m_s_s_p_m___gui_manager_mode.html#ab30c192a05f6f6b4d033d3f400a50fd8", null ], + [ "callback_PctMSYDL", "class_m_s_s_p_m___gui_manager_mode.html#ad4fe1f05441b792b6f5d0258c660e8ec", null ], [ "callback_RunPB", "class_m_s_s_p_m___gui_manager_mode.html#af73f0a4f09e9f5fb090e3f08c6b2f305", null ], - [ "callback_RunsPerFore", "class_m_s_s_p_m___gui_manager_mode.html#ac152e3c77045e71c52db0368b03ea07b", null ], - [ "callback_YearsPerRun", "class_m_s_s_p_m___gui_manager_mode.html#a895653d93dc34a709d2305e960024919", null ], - [ "getLastYearsCatchValues", "class_m_s_s_p_m___gui_manager_mode.html#a1a919afdbc6e5d0bcf7f41c68bdcfaa7", null ], + [ "callback_RunsPerForecastSL", "class_m_s_s_p_m___gui_manager_mode.html#af8a22b1bd911bcde1231429500338d29", null ], + [ "callback_SavePB", "class_m_s_s_p_m___gui_manager_mode.html#acd5e15b4165552a36ea383b26c27288b", null ], + [ "callback_SingleSpeciesRB", "class_m_s_s_p_m___gui_manager_mode.html#a61d64673124f4edfa97b39484d070b6e", null ], + [ "callback_SpeciesCMB", "class_m_s_s_p_m___gui_manager_mode.html#ae3d78ccec6bf9afad5cf6a7be1ce0a6e", null ], + [ "callback_StochasticRB", "class_m_s_s_p_m___gui_manager_mode.html#aa94bfff0dc53865e31b30571dd1ce6ed", null ], + [ "callback_UncertaintyHarvestParameterDL", "class_m_s_s_p_m___gui_manager_mode.html#aa38c146ea845fb8aeb85266514fca881", null ], + [ "callback_UncertaintyHarvestParameterPB", "class_m_s_s_p_m___gui_manager_mode.html#a434487d176e0a6fb9eaa442f116ecb51", null ], + [ "callback_UncertaintyKParameterDL", "class_m_s_s_p_m___gui_manager_mode.html#aea70fff16fd8e66874ecdef2f4accf09", null ], + [ "callback_UncertaintyRParameterDL", "class_m_s_s_p_m___gui_manager_mode.html#aec774b7d939656ae95a5c5f657a31a3d", null ], + [ "callback_YAxisLockedCB", "class_m_s_s_p_m___gui_manager_mode.html#ae21ed19d7ab64d1173626f1ebf64d2b5", null ], + [ "callback_YearsPerRunSL", "class_m_s_s_p_m___gui_manager_mode.html#a762b85a273118c5cd08b21d7408efc89", null ], + [ "getScaleValueFromPlot", "class_m_s_s_p_m___gui_manager_mode.html#a0506a62e14ee2a294fb79593d2b0c324", null ], + [ "grabImage", "class_m_s_s_p_m___gui_manager_mode.html#aaeaa9777c932109868a1c5f0ade72140", null ], + [ "isDeterministic", "class_m_s_s_p_m___gui_manager_mode.html#a3952efd9e616273fdb136babbfedf501", null ], [ "KeyPressed", "class_m_s_s_p_m___gui_manager_mode.html#a7c55247fb2533814fc75cfb2fae65c8f", null ], [ "MouseMoved", "class_m_s_s_p_m___gui_manager_mode.html#add16e2448fab9da654fdadd348f0e836", null ], - [ "setData", "class_m_s_s_p_m___gui_manager_mode.html#a9e37f31f8453b713147087c4344182d1", null ], - [ "setupConnections", "class_m_s_s_p_m___gui_manager_mode.html#a5bcdbe89226d1a590ab756c088715dbc", null ] + [ "MouseReleased", "class_m_s_s_p_m___gui_manager_mode.html#a271c8c25059d89c06a27bbff4cdb2374", null ], + [ "SaveOutputBiomassData", "class_m_s_s_p_m___gui_manager_mode.html#ada6111f6f8538b61c9975c6f130e27ab", null ], + [ "setForecastName", "class_m_s_s_p_m___gui_manager_mode.html#ab407a5a55f6f285a7e757437c3718212", null ], + [ "setForecastNumRunsPerForecast", "class_m_s_s_p_m___gui_manager_mode.html#a04d73a42e5722a053c5d9210850f02b7", null ], + [ "setForecastNumYearsPerRun", "class_m_s_s_p_m___gui_manager_mode.html#af8520069a715725ad81aed7f115cc983", null ], + [ "setSpeciesList", "class_m_s_s_p_m___gui_manager_mode.html#ab1c8520e415eb9ec6b5411a3e26b4af1", null ], + [ "UpdateSeedValue", "class_m_s_s_p_m___gui_manager_mode.html#a9ac1b683eafb3abdc2b96c9d9c8cca09", null ] ]; \ No newline at end of file diff --git a/docs/html/class_r_e_m_o_r_a-members.html b/docs/html/class_r_e_m_o_r_a-members.html new file mode 100644 index 00000000..2ed459d1 --- /dev/null +++ b/docs/html/class_r_e_m_o_r_a-members.html @@ -0,0 +1,165 @@ + + + + + + +MSSPM: Member List + + + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    MSSPM +
    +
    +
    + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    + +
    + +
    +
    +
    REMORA Member List
    +
    +
    + +

    This is the complete list of members for REMORA, including all inherited members.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    callback_DelPB()REMORAslot
    callback_DeterministicRB(bool pressed)REMORAslot
    callback_ForecastPlotTypeCMB(QString type)REMORAslot
    callback_KeyPressed(QKeyEvent *event)REMORAslot
    callback_LoadPB()REMORAslot
    callback_MaxScaleFactorPB()REMORAslot
    callback_MouseMoved(QMouseEvent *event)REMORAslot
    callback_MouseReleased(QMouseEvent *event)REMORAslot
    callback_MSYCB(bool isChecked)REMORAslot
    callback_MultiPlotTypePB()REMORAslot
    callback_MultiSpeciesRB(bool pressed)REMORAslot
    callback_PctMSYCB(bool isChecked)REMORAslot
    callback_PctMSYDL(int value)REMORAslot
    callback_RunPB()REMORAslot
    callback_RunsPerForecastSL(int value)REMORAslot
    callback_SavePB()REMORAslot
    callback_SingleSpeciesRB(bool pressed)REMORAslot
    callback_SpeciesCMB(QString species)REMORAslot
    callback_StochasticRB(bool pressed)REMORAslot
    callback_UncertaintyHarvestParameterDL(int value)REMORAslot
    callback_UncertaintyHarvestParameterPB()REMORAslot
    callback_UncertaintyKParameterDL(int value)REMORAslot
    callback_UncertaintyRParameterDL(int value)REMORAslot
    callback_YAxisLockedCB(bool checked)REMORAslot
    callback_YearsPerRunSL(int value)REMORAslot
    getScaleValueFromPlot(int species, int year)REMORA
    grabImage(QPixmap &pixmap)REMORA
    isDeterministic()REMORA
    KeyPressed(QKeyEvent *event)REMORAsignal
    MouseMoved(QMouseEvent *event)REMORAsignal
    MouseReleased(QMouseEvent *event)REMORAsignal
    REMORA(nmfDatabase *DatabasePtr, nmfLogger *Logger, std::string &ProjectDir, std::string &ProjectSettingsConfig, QStringList &SpeciesList, QWidget *MModeWidget)REMORA
    SaveOutputBiomassData(std::string forecastName)REMORAsignal
    setForecastName(QString forecastName)REMORA
    setForecastNumRunsPerForecast(int numRunsPerForecast)REMORA
    setForecastNumYearsPerRun(int numYearsPerRun)REMORA
    setSpeciesList(const QStringList &speciesList)REMORA
    UpdateSeedValue(int seedValue)REMORAsignal
    ~REMORA() (defined in REMORA)REMORA
    +
    + + + + diff --git a/docs/html/class_r_e_m_o_r_a.html b/docs/html/class_r_e_m_o_r_a.html new file mode 100644 index 00000000..79a3a876 --- /dev/null +++ b/docs/html/class_r_e_m_o_r_a.html @@ -0,0 +1,1260 @@ + + + + + + +MSSPM: REMORA Class Reference + + + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    MSSPM +
    +
    +
    + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    + +
    + +
    + +
    +
    REMORA Class Reference
    +
    +
    + +

    The main GUI class that contains all of the widget definitions for the REMORA Management tool. + More...

    + +

    #include <REMORA.h>

    +
    +Inheritance diagram for REMORA:
    +
    +
    Inheritance graph
    + + +
    [legend]
    +
    +Collaboration diagram for REMORA:
    +
    +
    Collaboration graph
    + + +
    [legend]
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Public Slots

    +void callback_DelPB ()
     Callback invoked when the user presses the delete scenario button.
     
    void callback_DeterministicRB (bool pressed)
     Callback invoked when the user presses the Deterministic radio button. More...
     
    void callback_ForecastPlotTypeCMB (QString type)
     Callback invoked when the user selects a new forecast plot type. More...
     
    void callback_KeyPressed (QKeyEvent *event)
     Callback invoked when the user presses a keyboard key. More...
     
    +void callback_LoadPB ()
     Callback invoked when the user presses the Load Scenario button.
     
    +void callback_MaxScaleFactorPB ()
     Callback invoked when the user toggles the maximum scale factor button.
     
    void callback_MouseMoved (QMouseEvent *event)
     Callback invoked when the user moves the mouse. More...
     
    void callback_MouseReleased (QMouseEvent *event)
     Callback invoked when the user releases the mouse. More...
     
    void callback_MSYCB (bool isChecked)
     Callback invoked when the user checks the MSY checkbox. More...
     
    +void callback_MultiPlotTypePB ()
     Callback invoked when the user presses the multi-species plot type toggle button. There are states: 1 and 1+. The former signifies the user wishes to see all plots on the same chart (with no Monte Carlo plots). The latter signifies the user wishes to see all plots on separate smaller charts (with the Monte Carlo plots) and composited into one image.
     
    void callback_MultiSpeciesRB (bool pressed)
     Callback invoked when the user presses the Multi-Species radio button. More...
     
    void callback_PctMSYCB (bool isChecked)
     Callback invoked when the user checks the Percent MSY checkbox. This will enable the Percent MSY dial to the right of this checkbox. More...
     
    void callback_PctMSYDL (int value)
     Callback invoked when the user modifies the Percent MSY dial. More...
     
    +void callback_RunPB ()
     Callback invoked when the user presses the Run button. Run causes the appropriate forecast scenario biomass data to be generated and saved in the database for each species. A default plot is then displayed using these data. Additional plots can be viewed by selecting another species or by changing the plot type.
     
    void callback_RunsPerForecastSL (int value)
     Callback invoked when the user interacts with the Runs per Forecast slider. More...
     
    +void callback_SavePB ()
     Callback invoked when the user presses the Save Scenario button.
     
    void callback_SingleSpeciesRB (bool pressed)
     Callback invoked when the user presses the single species radio button. More...
     
    void callback_SpeciesCMB (QString species)
     Callback invoked when the user changes the species combo box. More...
     
    void callback_StochasticRB (bool pressed)
     Callback invoked when the user presses the stochastic radio button. More...
     
    void callback_UncertaintyHarvestParameterDL (int value)
     Callback invoked when the user modifies the Harvest Uncertainty dial. More...
     
    +void callback_UncertaintyHarvestParameterPB ()
     Callback invoked when the user presses the Harvest Uncertainty parameter toggle button.
     
    void callback_UncertaintyKParameterDL (int value)
     Callback invoked when the user modifies the Carrying Capacity Uncertainty dial. More...
     
    void callback_UncertaintyRParameterDL (int value)
     Callback invoked when the user modifies the Growth Uncertainty dial. More...
     
    void callback_YAxisLockedCB (bool checked)
     Callback invoked when the user checks the Lock Y Axis checkbox. Checking this box forces all subsequent plots to have the same maximum y range value. This is useful if multiple plots will be captured and then flipped through to view differences. More...
     
    void callback_YearsPerRunSL (int value)
     Callback invoked when the user releases the Years per Run slider. More...
     
    + + + + + + + + + + + + + + + + +

    +Signals

    void KeyPressed (QKeyEvent *event)
     Signal emitted when the user presses a key over the movable line chart. More...
     
    void MouseMoved (QMouseEvent *event)
     Signal emitted when the user moves the mouse over the movable line chart. More...
     
    void MouseReleased (QMouseEvent *event)
     Signal emitted when the user releases the mouse over the movable line chart. More...
     
    void SaveOutputBiomassData (std::string forecastName)
     Signal emitted when the user wants to save the output biomass data for the current forecast. More...
     
    void UpdateSeedValue (int seedValue)
     Signal emitted when the user needs to update the seed value in the main routine when saving the current forecast parameters. More...
     
    + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Public Member Functions

     REMORA (nmfDatabase *DatabasePtr, nmfLogger *Logger, std::string &ProjectDir, std::string &ProjectSettingsConfig, QStringList &SpeciesList, QWidget *MModeWidget)
     Class definition for REMORA Management Tool. More...
     
    double getScaleValueFromPlot (int species, int year)
     getScaleValueFromPlot : returns harvest scale value for the passed in species and year More...
     
    void grabImage (QPixmap &pixmap)
     grabImage : Performs a "smart" screen grab based upon the state of the controls More...
     
    bool isDeterministic ()
     Returns true if the Deterministic radio button is pressed. More...
     
    void setForecastName (QString forecastName)
     Sets REMORA's internal forecast name variable to the passed in forecast name. More...
     
    void setForecastNumYearsPerRun (int numYearsPerRun)
     Sets REMORA's internal number years per run variable to the passed value and updates the GUI. More...
     
    void setForecastNumRunsPerForecast (int numRunsPerForecast)
     Sets REMORA's internal number of runs per forecast to the passed value and updates the GUI. More...
     
    void setSpeciesList (const QStringList &speciesList)
     Sets REMORA's species pulldown list to the passed list of QStrings. More...
     
    +

    Detailed Description

    +

    The main GUI class that contains all of the widget definitions for the REMORA Management tool.

    +

    Constructor & Destructor Documentation

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    REMORA::REMORA (nmfDatabase * DatabasePtr,
    nmfLogger * Logger,
    std::string & ProjectDir,
    std::string & ProjectSettingsConfig,
    QStringList & SpeciesList,
    QWidget * MModeWidget 
    )
    +
    + +

    Class definition for REMORA Management Tool.

    +
    Parameters
    + + + + + + + +
    DatabasePtr: pointer to database
    Logger: pointer to logger
    ProjectDir: project directory
    ProjectSettingsConfig: project settings configuration name
    SpeciesList: list of species
    MModeWidget: parent widget in which to place this class
    +
    +
    + +
    +
    +

    Member Function Documentation

    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_DeterministicRB (bool pressed)
    +
    +slot
    +
    + +

    Callback invoked when the user presses the Deterministic radio button.

    +
    Parameters
    + + +
    pressed: state of the radio button (true/false)
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_ForecastPlotTypeCMB (QString type)
    +
    +slot
    +
    + +

    Callback invoked when the user selects a new forecast plot type.

    +
    Parameters
    + + +
    type: name of the forecast plot type chosen
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_KeyPressed (QKeyEvent * event)
    +
    +slot
    +
    + +

    Callback invoked when the user presses a keyboard key.

    +
    Parameters
    + + +
    event: key event data structure
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_MouseMoved (QMouseEvent * event)
    +
    +slot
    +
    + +

    Callback invoked when the user moves the mouse.

    +
    Parameters
    + + +
    event: mouse event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_MouseReleased (QMouseEvent * event)
    +
    +slot
    +
    + +

    Callback invoked when the user releases the mouse.

    +
    Parameters
    + + +
    event: mouse event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_MSYCB (bool isChecked)
    +
    +slot
    +
    + +

    Callback invoked when the user checks the MSY checkbox.

    +
    Parameters
    + + +
    isChecked: boolean signifying if the checkbox has been checked
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_MultiSpeciesRB (bool pressed)
    +
    +slot
    +
    + +

    Callback invoked when the user presses the Multi-Species radio button.

    +
    Parameters
    + + +
    pressed: state of the Multi-Species button
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_PctMSYCB (bool isChecked)
    +
    +slot
    +
    + +

    Callback invoked when the user checks the Percent MSY checkbox. This will enable the Percent MSY dial to the right of this checkbox.

    +
    Parameters
    + + +
    isChecked: state of checkbox
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_PctMSYDL (int value)
    +
    +slot
    +
    + +

    Callback invoked when the user modifies the Percent MSY dial.

    +
    Parameters
    + + +
    value: Integer value from the Percent MSY dial
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_RunsPerForecastSL (int value)
    +
    +slot
    +
    + +

    Callback invoked when the user interacts with the Runs per Forecast slider.

    +
    Parameters
    + + +
    value: current value on the Runs per Forecast slider
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_SingleSpeciesRB (bool pressed)
    +
    +slot
    +
    + +

    Callback invoked when the user presses the single species radio button.

    +
    Parameters
    + + +
    pressed: state of the single species radio button
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_SpeciesCMB (QString species)
    +
    +slot
    +
    + +

    Callback invoked when the user changes the species combo box.

    +
    Parameters
    + + +
    species: current species shown in the species combo box
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_StochasticRB (bool pressed)
    +
    +slot
    +
    + +

    Callback invoked when the user presses the stochastic radio button.

    +
    Parameters
    + + +
    pressed: state of the stochastic radio button
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_UncertaintyHarvestParameterDL (int value)
    +
    +slot
    +
    + +

    Callback invoked when the user modifies the Harvest Uncertainty dial.

    +
    Parameters
    + + +
    value: current value of the Harvest Uncertainty dial
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_UncertaintyKParameterDL (int value)
    +
    +slot
    +
    + +

    Callback invoked when the user modifies the Carrying Capacity Uncertainty dial.

    +
    Parameters
    + + +
    value: current value of the Carrying Capacity Uncertainty dial
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_UncertaintyRParameterDL (int value)
    +
    +slot
    +
    + +

    Callback invoked when the user modifies the Growth Uncertainty dial.

    +
    Parameters
    + + +
    value: current value of the Growth Uncertainty dial
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_YAxisLockedCB (bool checked)
    +
    +slot
    +
    + +

    Callback invoked when the user checks the Lock Y Axis checkbox. Checking this box forces all subsequent plots to have the same maximum y range value. This is useful if multiple plots will be captured and then flipped through to view differences.

    +
    Parameters
    + + +
    checked: boolean determining if the box has just been checked (true) or unchecked (false)
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::callback_YearsPerRunSL (int value)
    +
    +slot
    +
    + +

    Callback invoked when the user releases the Years per Run slider.

    +
    Parameters
    + + +
    value: current value of the Years per Run slider
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + +
    double REMORA::getScaleValueFromPlot (int species,
    int year 
    )
    +
    + +

    getScaleValueFromPlot : returns harvest scale value for the passed in species and year

    +
    Parameters
    + + + +
    species: species number from the list of species
    year: year along x-axis of scale factor plot
    +
    +
    +
    Returns
    Returns scale factor (y-value) corresponding to the passed in values
    + +
    +
    + +
    +
    + + + + + + + + +
    void REMORA::grabImage (QPixmap & pixmap)
    +
    + +

    grabImage : Performs a "smart" screen grab based upon the state of the controls

    +
    Parameters
    + + +
    pixmap: Returns the pixmap of the captured widget
    +
    +
    + +
    +
    + +
    +
    + + + + + + + +
    bool REMORA::isDeterministic ()
    +
    + +

    Returns true if the Deterministic radio button is pressed.

    +
    Returns
    true if state is deterministic, else false if stochastic
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::KeyPressed (QKeyEvent * event)
    +
    +signal
    +
    + +

    Signal emitted when the user presses a key over the movable line chart.

    +
    Parameters
    + + +
    event: key event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::MouseMoved (QMouseEvent * event)
    +
    +signal
    +
    + +

    Signal emitted when the user moves the mouse over the movable line chart.

    +
    Parameters
    + + +
    event: mouse event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::MouseReleased (QMouseEvent * event)
    +
    +signal
    +
    + +

    Signal emitted when the user releases the mouse over the movable line chart.

    +
    Parameters
    + + +
    event: mouse event data
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::SaveOutputBiomassData (std::string forecastName)
    +
    +signal
    +
    + +

    Signal emitted when the user wants to save the output biomass data for the current forecast.

    +
    Parameters
    + + +
    forecastName: the forecast name
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + +
    void REMORA::setForecastName (QString forecastName)
    +
    + +

    Sets REMORA's internal forecast name variable to the passed in forecast name.

    +
    Parameters
    + + +
    forecastName: the name of the current forecast
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + +
    void REMORA::setForecastNumRunsPerForecast (int numRunsPerForecast)
    +
    + +

    Sets REMORA's internal number of runs per forecast to the passed value and updates the GUI.

    +
    Parameters
    + + +
    numRunsPerForecast: number of runs to generate per forecast scenario run
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + +
    void REMORA::setForecastNumYearsPerRun (int numYearsPerRun)
    +
    + +

    Sets REMORA's internal number years per run variable to the passed value and updates the GUI.

    +
    Parameters
    + + +
    numYearsPerRun: number of years per forecast run
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + +
    void REMORA::setSpeciesList (const QStringList & speciesList)
    +
    + +

    Sets REMORA's species pulldown list to the passed list of QStrings.

    +
    Parameters
    + + +
    speciesList: current list of species in model
    +
    +
    + +
    +
    + +
    +
    + + + + + +
    + + + + + + + + +
    void REMORA::UpdateSeedValue (int seedValue)
    +
    +signal
    +
    + +

    Signal emitted when the user needs to update the seed value in the main routine when saving the current forecast parameters.

    +
    Parameters
    + + +
    seedValue: 1 or 0 (0 signifies that a random seed value will be used)
    +
    +
    + +
    +
    +
    The documentation for this class was generated from the following files:
      +
    • MSSPM_GuiManagerMode/REMORA.h
    • +
    • MSSPM_GuiManagerMode/REMORA.cpp
    • +
    +
    +
    + + + + diff --git a/docs/html/class_r_e_m_o_r_a.js b/docs/html/class_r_e_m_o_r_a.js new file mode 100644 index 00000000..95b58701 --- /dev/null +++ b/docs/html/class_r_e_m_o_r_a.js @@ -0,0 +1,42 @@ +var class_r_e_m_o_r_a = +[ + [ "REMORA", "class_r_e_m_o_r_a.html#a06fcea88037286a126da443fc474ba44", null ], + [ "~REMORA", "class_r_e_m_o_r_a.html#af5750f77cb36737ece9e118a321a52da", null ], + [ "callback_DelPB", "class_r_e_m_o_r_a.html#a31f1ce14e8573b4b4566e9609bde996d", null ], + [ "callback_DeterministicRB", "class_r_e_m_o_r_a.html#a343b1746203ef20e1ed0f04500696534", null ], + [ "callback_ForecastPlotTypeCMB", "class_r_e_m_o_r_a.html#aeb7d14caba3191c6ce63c4901d50f860", null ], + [ "callback_KeyPressed", "class_r_e_m_o_r_a.html#a761bd29d3687027e6e419d31f89a6462", null ], + [ "callback_LoadPB", "class_r_e_m_o_r_a.html#a463dc1abdc93afd1b1cbcb940c92d854", null ], + [ "callback_MaxScaleFactorPB", "class_r_e_m_o_r_a.html#a6a694a9da3b951d26e0c83381b257f15", null ], + [ "callback_MouseMoved", "class_r_e_m_o_r_a.html#a2f6cfe9a561706fd501887c8f5d6f835", null ], + [ "callback_MouseReleased", "class_r_e_m_o_r_a.html#af7e6b5c8df5fa243afc68c162e65d3e1", null ], + [ "callback_MSYCB", "class_r_e_m_o_r_a.html#af9c2d8b7a428f44838978e64ad52881e", null ], + [ "callback_MultiPlotTypePB", "class_r_e_m_o_r_a.html#af22b104c5984d6c801246eead330f235", null ], + [ "callback_MultiSpeciesRB", "class_r_e_m_o_r_a.html#a5d64c508a6d033f4321061313b8cfce9", null ], + [ "callback_PctMSYCB", "class_r_e_m_o_r_a.html#a4007d7ee1509de0960a60738ad151ed8", null ], + [ "callback_PctMSYDL", "class_r_e_m_o_r_a.html#a1dfc0c430d686f97f9b957d894a44e60", null ], + [ "callback_RunPB", "class_r_e_m_o_r_a.html#a5b95d0081911cb759d30934afafcbee9", null ], + [ "callback_RunsPerForecastSL", "class_r_e_m_o_r_a.html#ab991abdc9e19ee13bceb88df5bd53efc", null ], + [ "callback_SavePB", "class_r_e_m_o_r_a.html#aca7a4967dfe1fd9081eac9095327c0bb", null ], + [ "callback_SingleSpeciesRB", "class_r_e_m_o_r_a.html#a22cdf525d586c6a2d252fe41e613a1fd", null ], + [ "callback_SpeciesCMB", "class_r_e_m_o_r_a.html#ad8dac877d4c931236a612c8c755b2c75", null ], + [ "callback_StochasticRB", "class_r_e_m_o_r_a.html#a9add6ffe145eab12eff5feec84264c6d", null ], + [ "callback_UncertaintyHarvestParameterDL", "class_r_e_m_o_r_a.html#a62b868c132dba853391ccf31cc258d93", null ], + [ "callback_UncertaintyHarvestParameterPB", "class_r_e_m_o_r_a.html#a8ceae4e1150f87b7a5e58ab1da3f2ee7", null ], + [ "callback_UncertaintyKParameterDL", "class_r_e_m_o_r_a.html#a1a310e108bb71feb1ce8403ce869f6d0", null ], + [ "callback_UncertaintyRParameterDL", "class_r_e_m_o_r_a.html#a51bc56058228300ec5a4c21a0663be1e", null ], + [ "callback_YAxisLockedCB", "class_r_e_m_o_r_a.html#a95f5befc5249a88e644f004ade71bf4e", null ], + [ "callback_YearsPerRunSL", "class_r_e_m_o_r_a.html#a31e311ed427814ca6ebd87a962477684", null ], + [ "getScaleValueFromPlot", "class_r_e_m_o_r_a.html#a4e55e652d872ceb14fe569c53bf2cd58", null ], + [ "grabImage", "class_r_e_m_o_r_a.html#a74d4b822bddcd452acb97a971ad82065", null ], + [ "isDeterministic", "class_r_e_m_o_r_a.html#a2a95b7dde949813654b9e7a26aa04214", null ], + [ "KeyPressed", "class_r_e_m_o_r_a.html#ad81a8074bd3d52faf7e58216faf2ce6b", null ], + [ "MouseMoved", "class_r_e_m_o_r_a.html#a525ff2f7c495f62ef146823dee6ac8b8", null ], + [ "MouseReleased", "class_r_e_m_o_r_a.html#a26771442e3a10d6ee4ce702cf7671542", null ], + [ "SaveOutputBiomassData", "class_r_e_m_o_r_a.html#a3cefd41fc226c15e416ff4ab0943cc30", null ], + [ "setForecastName", "class_r_e_m_o_r_a.html#a0b1c570e2747dc5e9f7845e0a1fe0723", null ], + [ "setForecastNumRunsPerForecast", "class_r_e_m_o_r_a.html#a40b697d627dd2281f5b1c25ab84f67df", null ], + [ "setForecastNumYearsPerRun", "class_r_e_m_o_r_a.html#a8f7176d9cfe38d29070f11bf4d732a46", null ], + [ "setSpeciesList", "class_r_e_m_o_r_a.html#a3c3547123015a24142f257f56132065d", null ], + [ "UpdateSeedValue", "class_r_e_m_o_r_a.html#acfb792d3e300504a8808583db6203132", null ] +]; \ No newline at end of file diff --git a/docs/html/class_r_e_m_o_r_a__coll__graph.map b/docs/html/class_r_e_m_o_r_a__coll__graph.map new file mode 100644 index 00000000..da36bc28 --- /dev/null +++ b/docs/html/class_r_e_m_o_r_a__coll__graph.map @@ -0,0 +1,2 @@ + + diff --git a/docs/html/class_r_e_m_o_r_a__coll__graph.md5 b/docs/html/class_r_e_m_o_r_a__coll__graph.md5 new file mode 100644 index 00000000..a52723a2 --- /dev/null +++ b/docs/html/class_r_e_m_o_r_a__coll__graph.md5 @@ -0,0 +1 @@ +adbfeefe683a54dfc98edde9512793f3 \ No newline at end of file diff --git a/docs/html/class_r_e_m_o_r_a__coll__graph.png b/docs/html/class_r_e_m_o_r_a__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..b8387e5a7e7406c52f23da6c1fcc923e326a0270 GIT binary patch literal 2615 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 + diff --git a/docs/html/class_r_e_m_o_r_a__inherit__graph.md5 b/docs/html/class_r_e_m_o_r_a__inherit__graph.md5 new file mode 100644 index 00000000..a52723a2 --- /dev/null +++ b/docs/html/class_r_e_m_o_r_a__inherit__graph.md5 @@ -0,0 +1 @@ +adbfeefe683a54dfc98edde9512793f3 \ No newline at end of file diff --git a/docs/html/class_r_e_m_o_r_a__inherit__graph.png b/docs/html/class_r_e_m_o_r_a__inherit__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..b8387e5a7e7406c52f23da6c1fcc923e326a0270 GIT binary patch literal 2615 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 Index
    -
    B | C | I | L | M | N | P
    +
    B | C | I | L | M | N | P | R
    - - + - - + - - + + + +
      B  
      L  
    -
      N  
    +
      P  
    nmfDiagnostic_Tab2   nmfForecast_Tab3   
    nmfEstimation_Tab1   nmfForecast_Tab4   
    Bees_Estimator   LoadDlg   NLopt_Estimator   nmfEstimation_Tab2   nmfMainWindow   
    BeesStats   LoadForecastDlg   
      P  
    +
    Bees_Estimator   LoadDlg   PreferencesDialog   nmfEstimation_Tab2   nmfMainWindow   
    BeesStats   LoadForecastDlg   
      R  
    nmfEstimation_Tab3   nmfSetup_Tab1   
      C  
      M  
    nmfEstimation_Tab4   nmfSetup_Tab2   
    PreferencesDialog   nmfEstimation_Tab5   nmfSetup_Tab3   
    ClearOutputDialog   MSSPM_GuiManagerMode   
      n  
    +
    REMORA   nmfEstimation_Tab5   nmfSetup_Tab3   
    ClearOutputDialog   MSSPM_GuiOutputControls   
      n  
    nmfEstimation_Tab6   nmfSetup_Tab4   
      I  
    -
    MSSPM_GuiOutputControls   nmfForecast_Tab1   
    MultiScenarioSaveDlg   nmfDiagnostic_Tab1   nmfForecast_Tab2   
    InitSpeciesDataStruct   
    MultiScenarioSaveDlg   nmfForecast_Tab1   
      N  
    +
    nmfDiagnostic_Tab1   nmfForecast_Tab2   
    InitSpeciesDataStruct   
    NLopt_Estimator   
    -
    B | C | I | L | M | N | P
    +
    B | C | I | L | M | N | P | R
    diff --git a/docs/html/classnmf_forecast___tab1-members.html b/docs/html/classnmf_forecast___tab1-members.html index 02472741..cb52c1a5 100644 --- a/docs/html/classnmf_forecast___tab1-members.html +++ b/docs/html/classnmf_forecast___tab1-members.html @@ -124,10 +124,12 @@
    getForecastName()nmfForecast_Tab1
    getSeed()nmfForecast_Tab1
    getStartForecastYear()nmfForecast_Tab1
    loadWidgets()nmfForecast_Tab1
    nmfForecast_Tab1(QTabWidget *tabs, nmfLogger *logger, nmfDatabase *databasePtr, std::string &projectDir)nmfForecast_Tab1
    ResetOutputWidgetsForAggProd()nmfForecast_Tab1signal
    saveSettings()nmfForecast_Tab1
    isDeterministic()nmfForecast_Tab1
    loadWidgets()nmfForecast_Tab1
    nmfForecast_Tab1(QTabWidget *tabs, nmfLogger *logger, nmfDatabase *databasePtr, std::string &projectDir)nmfForecast_Tab1
    ResetOutputWidgetsForAggProd()nmfForecast_Tab1signal
    saveSettings()nmfForecast_Tab1
    setDeterministic(bool isDeterministic)nmfForecast_Tab1
    ~nmfForecast_Tab1() (defined in nmfForecast_Tab1)nmfForecast_Tab1virtual
    diff --git a/docs/html/classnmf_forecast___tab1.html b/docs/html/classnmf_forecast___tab1.html index 51498e04..48b51dc1 100644 --- a/docs/html/classnmf_forecast___tab1.html +++ b/docs/html/classnmf_forecast___tab1.html @@ -187,6 +187,9 @@
    int getStartForecastYear ()
     Returns the start year associated with this Forecast. More...
     
    bool isDeterministic ()
     Returns boolean signifying if the deterministic box has been checked. More...
     
    bool loadWidgets ()
     Loads all widgets for this GUI from database tables. More...
     
    saveSettings ()
     Saves the GUIs settings to a Qt settings file.
     
    void setDeterministic (bool isDeterministic)
     Sets the deterministic state of the appropriate checkbox. More...
     

    Detailed Description

    Forecast Setup.

    @@ -397,6 +403,24 @@

    Member Function Documentation

    Returns the start year associated with this Forecast.

    Returns
    The integer start year associated with this Forecast
    +
    +
    + +
    +
    + + + + + + + +
    bool nmfForecast_Tab1::isDeterministic ()
    +
    + +

    Returns boolean signifying if the deterministic box has been checked.

    +
    Returns
    Returns True/False describing if deterministic box has been checked
    +
    @@ -415,6 +439,30 @@

    Member Function Documentation

    Loads all widgets for this GUI from database tables.

    Returns
    Returns true if all data were loaded successfully
    +
    + + +
    +
    + + + + + + + + +
    void nmfForecast_Tab1::setDeterministic (bool isDeterministic)
    +
    + +

    Sets the deterministic state of the appropriate checkbox.

    +
    Parameters
    + + +
    isDeterministic: boolean describing deterministic state
    +
    +
    +

    The documentation for this class was generated from the following files:
      diff --git a/docs/html/classnmf_forecast___tab1.js b/docs/html/classnmf_forecast___tab1.js index f7b61bd0..708d5247 100644 --- a/docs/html/classnmf_forecast___tab1.js +++ b/docs/html/classnmf_forecast___tab1.js @@ -14,7 +14,9 @@ var classnmf_forecast___tab1 = [ "getForecastName", "classnmf_forecast___tab1.html#a9f6d098e92df14994f9c74691b201989", null ], [ "getSeed", "classnmf_forecast___tab1.html#af403c17c37d3aa6fa75ba26220b4dc57", null ], [ "getStartForecastYear", "classnmf_forecast___tab1.html#a0912fea0e3be291b65ff48ff798944dd", null ], + [ "isDeterministic", "classnmf_forecast___tab1.html#a5310907b60621ee288083f20546125eb", null ], [ "loadWidgets", "classnmf_forecast___tab1.html#a3be5f721cba76a77ff218e9c145b98ef", null ], [ "ResetOutputWidgetsForAggProd", "classnmf_forecast___tab1.html#aca5d5ea9f56ca9315273058031a2bde8", null ], - [ "saveSettings", "classnmf_forecast___tab1.html#a4d08998802a2b56f625b9cc39be81cb0", null ] + [ "saveSettings", "classnmf_forecast___tab1.html#a4d08998802a2b56f625b9cc39be81cb0", null ], + [ "setDeterministic", "classnmf_forecast___tab1.html#a38012e33c4e10eef823cad69ff353b48", null ] ]; \ No newline at end of file diff --git a/docs/html/classnmf_main_window-members.html b/docs/html/classnmf_main_window-members.html index ac0b7029..ba1b74d7 100644 --- a/docs/html/classnmf_main_window-members.html +++ b/docs/html/classnmf_main_window-members.html @@ -126,7 +126,9 @@
    callback_LoadDatabase(QString databaseName)nmfMainWindowslot
    callback_LoadDataStruct()nmfMainWindowslot
    callback_LoadProject()nmfMainWindowslot
    callback_NavigatorSelectionChanged()nmfMainWindowslot
    callback_ManagerModeViewerClose(bool state) (defined in nmfMainWindow)nmfMainWindowslot
    callback_NavigatorSelectionChanged()nmfMainWindowslot
    callback_openCSVFile(QPoint pos) (defined in nmfMainWindow)nmfMainWindowslot
    callback_OutputTypeCMB(QString Type, std::map< QString, QStringList > SortedForecastLabelsMap)nmfMainWindowslot
    callback_PreferencesMShotOkPB() (defined in nmfMainWindow)nmfMainWindowslot
    callback_PreferencesSetStyleSheet(QString style)nmfMainWindowslot
    callback_RunEstimation(bool showDiagnosticsChart)nmfMainWindowslot
    callback_RunForecast(std::string ForecastName, bool GenerateBiomass)nmfMainWindowslot
    callback_SaveMainSettings()nmfMainWindowslot
    callback_SaveSystem()nmfMainWindowslot
    callback_SelectCenterSurfacePoint()nmfMainWindowslot
    callback_SelectMinimumSurfacePoint()nmfMainWindowslot
    callback_SetChartType(std::string type, std::string method)nmfMainWindowslot
    callback_SetChartView2d(bool setTo2d)nmfMainWindowslot
    callback_SetOutputScenarioForecast()nmfMainWindowslot
    callback_Setup_Tab4_CompetitionFormCMB(QString type)nmfMainWindowslot
    callback_Setup_Tab4_GrowthFormCMB(QString type)nmfMainWindowslot
    callback_Setup_Tab4_HarvestFormCMB(QString type)nmfMainWindowslot
    callback_Setup_Tab4_ModelPresetsCMB(QString type)nmfMainWindowslot
    callback_Setup_Tab4_PredationFormCMB(QString type)nmfMainWindowslot
    callback_SetupTabChanged(int tab)nmfMainWindowslot
    callback_ShowChart(QString outputType, QString outputSpecies)nmfMainWindowslot
    callback_ShowChartBy(QString type)nmfMainWindowslot
    callback_ShowChartMohnsRho()nmfMainWindowslot
    callback_ShowChartMultiScenario(QStringList SortedForecastLabels)nmfMainWindowslot
    callback_ShowDiagnostics()nmfMainWindowslot
    callback_ShowDiagnosticsChart3d()nmfMainWindowslot
    callback_ShowRunMessage(QString fontName)nmfMainWindowslot
    callback_StoreOutputSpecies()nmfMainWindowslot
    callback_SubRunCompleted(int RunNum, int SubRunNum, int NumSubRuns)nmfMainWindowslot
    callback_SystemLoaded()nmfMainWindowslot
    callback_TableNamesOkPB() (defined in nmfMainWindow)nmfMainWindowslot
    callback_UpdateModelEquationSummary()nmfMainWindowslot
    callback_SaveOutputBiomassData(std::string ForecastName)nmfMainWindowslot
    callback_SaveSystem()nmfMainWindowslot
    callback_SelectCenterSurfacePoint()nmfMainWindowslot
    callback_SelectMinimumSurfacePoint()nmfMainWindowslot
    callback_SetChartType(std::string type, std::string method)nmfMainWindowslot
    callback_SetChartView2d(bool setTo2d)nmfMainWindowslot
    callback_SetOutputScenarioForecast()nmfMainWindowslot
    callback_Setup_Tab4_CompetitionFormCMB(QString type)nmfMainWindowslot
    callback_Setup_Tab4_GrowthFormCMB(QString type)nmfMainWindowslot
    callback_Setup_Tab4_HarvestFormCMB(QString type)nmfMainWindowslot
    callback_Setup_Tab4_ModelPresetsCMB(QString type)nmfMainWindowslot
    callback_Setup_Tab4_PredationFormCMB(QString type)nmfMainWindowslot
    callback_SetupTabChanged(int tab)nmfMainWindowslot
    callback_ShowChart(QString outputType, QString outputSpecies)nmfMainWindowslot
    callback_ShowChartBy(QString groupType)nmfMainWindowslot
    callback_ShowChartMohnsRho()nmfMainWindowslot
    callback_ShowChartMultiScenario(QStringList SortedForecastLabels)nmfMainWindowslot
    callback_ShowDiagnostics()nmfMainWindowslot
    callback_ShowDiagnosticsChart3d()nmfMainWindowslot
    callback_ShowRunMessage(QString fontName)nmfMainWindowslot
    callback_StoreOutputSpecies()nmfMainWindowslot
    callback_SubRunCompleted(int RunNum, int SubRunNum, int NumSubRuns)nmfMainWindowslot
    callback_SystemLoaded()nmfMainWindowslot
    callback_TableNamesOkPB() (defined in nmfMainWindow)nmfMainWindowslot
    callback_UpdateModelEquationSummary()nmfMainWindowslot
    callback_UpdateSeedValue(int isDeterministic) (defined in nmfMainWindow)nmfMainWindowslot
    callback_UpdateSummaryStatistics()nmfMainWindowslot
    context_Action(bool triggered) (defined in nmfMainWindow)nmfMainWindowslot
    createPopupMenu()nmfMainWindowprotected
    eventFilter(QObject *object, QEvent *event) (defined in nmfMainWindow)nmfMainWindowprotected
    isStartUpOK()nmfMainWindow
    KeyPressed(QKeyEvent *event) (defined in nmfMainWindow)nmfMainWindowsignal
    menu_importDatabase()nmfMainWindowslot
    menu_layoutDefault()nmfMainWindowslot
    menu_layoutOutput()nmfMainWindowslot
    menu_paste()nmfMainWindowslot
    menu_pasteAll()nmfMainWindowslot
    menu_preferences()nmfMainWindowslot
    menu_quit()nmfMainWindowslot
    menu_resetCursor()nmfMainWindowslot
    menu_saveAndShowCurrentRun()nmfMainWindowslot
    menu_saveAndShowCurrentRun(bool showDiagnosticChart)nmfMainWindowslot
    menu_saveCurrentRun()nmfMainWindowslot
    menu_saveSettings()nmfMainWindowslot
    menu_screenMultiShot()nmfMainWindowslot
    menu_screenShot()nmfMainWindowslot
    menu_screenShotAll()nmfMainWindowslot
    menu_selectAll()nmfMainWindowslot
    menu_setBees(bool toggle)nmfMainWindowslot
    menu_setNLopt(bool toggle)nmfMainWindowslot
    menu_showAllSavedRuns()nmfMainWindowslot
    menu_showCurrentRun()nmfMainWindowslot
    menu_showTableNames()nmfMainWindowslot
    menu_stopRun()nmfMainWindowslot
    menu_toggleManagerMode() (defined in nmfMainWindow)nmfMainWindowslot
    menu_openCSVFile()nmfMainWindowslot
    menu_paste()nmfMainWindowslot
    menu_pasteAll()nmfMainWindowslot
    menu_preferences()nmfMainWindowslot
    menu_quit()nmfMainWindowslot
    menu_resetCursor()nmfMainWindowslot
    menu_saveAndShowCurrentRun()nmfMainWindowslot
    menu_saveAndShowCurrentRun(bool showDiagnosticChart)nmfMainWindowslot
    menu_saveCurrentRun()nmfMainWindowslot
    menu_saveSettings()nmfMainWindowslot
    menu_screenMultiShot()nmfMainWindowslot
    menu_screenShot()nmfMainWindowslot
    menu_screenShotAll()nmfMainWindowslot
    menu_selectAll()nmfMainWindowslot
    menu_setBees(bool toggle)nmfMainWindowslot
    menu_setNLopt(bool toggle)nmfMainWindowslot
    menu_showAllSavedRuns()nmfMainWindowslot
    menu_showCurrentRun()nmfMainWindowslot
    menu_showTableNames()nmfMainWindowslot
    menu_stopRun()nmfMainWindowslot
    menu_toggleManagerMode() (defined in nmfMainWindow)nmfMainWindowslot
    menu_toggleManagerModeViewer() (defined in nmfMainWindow)nmfMainWindowslot
    menu_whatsThis()nmfMainWindowslot
    MouseMoved(QMouseEvent *event) (defined in nmfMainWindow)nmfMainWindowsignal
    mouseMoveEvent(QMouseEvent *event) (defined in nmfMainWindow)nmfMainWindowprotected
    nmfMainWindow(QWidget *parent=nullptr)nmfMainWindowexplicit
    ~nmfMainWindow() (defined in nmfMainWindow)nmfMainWindow
    MouseReleased(QMouseEvent *event) (defined in nmfMainWindow)nmfMainWindowsignal
    nmfMainWindow(QWidget *parent=nullptr)nmfMainWindowexplicit
    ~nmfMainWindow() (defined in nmfMainWindow)nmfMainWindow
    diff --git a/docs/html/classnmf_main_window.html b/docs/html/classnmf_main_window.html index e833012f..18c54862 100644 --- a/docs/html/classnmf_main_window.html +++ b/docs/html/classnmf_main_window.html @@ -133,6 +133,9 @@ + + @@ -227,6 +230,9 @@ void  + + + @@ -288,9 +294,9 @@ - - - + + + @@ -310,6 +316,12 @@ void  + + + + @@ -361,6 +373,10 @@ void  + + + @@ -440,6 +456,9 @@ + + @@ -449,6 +468,9 @@ + +

    Public Slots

    +void callback_UpdateSeedValue (int isDeterministic)
     
    void callback_CheckEstimationTablesAndRun ()
     Callback invoked when user Runs an Estimation.
    callback_SaveMainSettings ()
     Callback invoked when user wants to save the Qt Settings for the Main application page.
     
    void callback_SaveOutputBiomassData (std::string ForecastName)
     Callback invoked when user wants to save the output biomass data when generating a forecast. More...
     
    void callback_SaveSystem ()
     Callback invoked when user saves a new system.
    void callback_PreferencesSetStyleSheet (QString style)
     Callback invoked when user changes the application style from the Preferences dialog. More...
     
    void callback_ShowChartBy (QString type)
     Callback invoked when user changes the chart group type. More...
     
    void callback_ShowChartBy (QString groupType)
     Callback invoked when user changes the chart group type. More...
     
    void callback_StoreOutputSpecies ()
     Callback invoked when user is modifying the Population Parameters and needs to store the current value of the Output widget's species.
    callback_UpdateModelEquationSummary ()
     Callback invoked to update the Model Equation in the Setup page 4 summary text box.
     
    +void callback_openCSVFile (QPoint pos)
     
    +void context_Action (bool triggered)
     
    void menu_about ()
     Raises an About MSSPM Dialog. More...
     
    menu_layoutOutput ()
     Change the Application layout to one with the Output window torn off and placed to the side.
     
    +void menu_openCSVFile ()
     Open the CSV file that's associated with the current image file displayed in the REMORA viewer.
     
    void menu_paste ()
     Pastes the previously copied or cleared table cells.
    void menu_toggleManagerMode ()
     
    +void menu_toggleManagerModeViewer ()
     
    void callback_TableNamesOkPB ()
     
    void callback_ErrorFound (std::string errorMsg)
     
    +void callback_ManagerModeViewerClose (bool state)
     
    @@ -458,6 +480,9 @@ + +

    Signals

    void MouseMoved (QMouseEvent *event)
     
    +void MouseReleased (QMouseEvent *event)
     
    @@ -479,6 +504,9 @@ + + +

    Public Member Functions

    void mouseMoveEvent (QMouseEvent *event)
     
    QMenu * createPopupMenu ()
     Need to prevent Remora's window from appearing in main window's so have to create custom popupMenu. More...
     

    Detailed Description

    The MSSPM Main Window.

    @@ -1007,6 +1035,38 @@

    Member Function Documentation

    +
    + + +
    +
    + + + + + +
    + + + + + + + + +
    void nmfMainWindow::callback_SaveOutputBiomassData (std::string ForecastName)
    +
    +slot
    +
    + +

    Callback invoked when user wants to save the output biomass data when generating a forecast.

    +
    Parameters
    + + +
    ForecastName: name of Forecast that's currently being run
    +
    +
    +
    @@ -1320,7 +1380,7 @@

    Member Function Documentation

    - +
    @@ -1331,7 +1391,7 @@

    Member Function Documentation

    - +
    void nmfMainWindow::callback_ShowChartBy ( QString type)groupType)
    @@ -1345,7 +1405,7 @@

    Member Function Documentation

    Callback invoked when user changes the chart group type.

    Parameters
    - +
    type: type of chart grouping desired: species, guild, system
    groupType: type of chart grouping desired: species, guild, system
    @@ -1543,6 +1603,32 @@

    Member Function Documentation

    +
    +
    + +
    +
    + + + + + +
    + + + + + + + +
    QMenu * nmfMainWindow::createPopupMenu ()
    +
    +protected
    +
    + +

    Need to prevent Remora's window from appearing in main window's so have to create custom popupMenu.

    +
    Returns
    Custom context menu
    +
    diff --git a/docs/html/classnmf_main_window.js b/docs/html/classnmf_main_window.js index 69933020..2bf309ef 100644 --- a/docs/html/classnmf_main_window.js +++ b/docs/html/classnmf_main_window.js @@ -16,7 +16,9 @@ var classnmf_main_window = [ "callback_LoadDatabase", "classnmf_main_window.html#a83eb248517f5bee70ae2752750906d61", null ], [ "callback_LoadDataStruct", "classnmf_main_window.html#abdf25ab238dd454a1100d4616017d988", null ], [ "callback_LoadProject", "classnmf_main_window.html#aa354587d6efe9d1f185c89823b190d8c", null ], + [ "callback_ManagerModeViewerClose", "classnmf_main_window.html#aa54a952c7e993e957b57626267d21828", null ], [ "callback_NavigatorSelectionChanged", "classnmf_main_window.html#a32453977084ac27c001ded2d8e935fff", null ], + [ "callback_openCSVFile", "classnmf_main_window.html#a20c3ee3508981c43485dc32916a771c8", null ], [ "callback_OutputTypeCMB", "classnmf_main_window.html#a94bb2eb92595da329cd5d244fc62a12f", null ], [ "callback_PreferencesMShotOkPB", "classnmf_main_window.html#ad0ec62ef3b1b8822c16232249b8fb02b", null ], [ "callback_PreferencesSetStyleSheet", "classnmf_main_window.html#a34f5f6c819aa6b5089520fb7eaf12118", null ], @@ -32,6 +34,7 @@ var classnmf_main_window = [ "callback_RunEstimation", "classnmf_main_window.html#afd3db21c9438b3d6d7e36054a85f0b7c", null ], [ "callback_RunForecast", "classnmf_main_window.html#a9e74f61adba300e6ee77734a9fd2df62", null ], [ "callback_SaveMainSettings", "classnmf_main_window.html#a97e05e67f1ddd9adca3dcf2f983f9ad8", null ], + [ "callback_SaveOutputBiomassData", "classnmf_main_window.html#a39e87c91ebef2e0e0a57ddcab68628e4", null ], [ "callback_SaveSystem", "classnmf_main_window.html#ab8320932225fde3dbe7532d9ea5cbc57", null ], [ "callback_SelectCenterSurfacePoint", "classnmf_main_window.html#ac845ad139406ce916d2799bd5d8f5276", null ], [ "callback_SelectMinimumSurfacePoint", "classnmf_main_window.html#af792accc642640697e53bbe539e61935", null ], @@ -45,7 +48,7 @@ var classnmf_main_window = [ "callback_Setup_Tab4_PredationFormCMB", "classnmf_main_window.html#a236b45bcd30a122e3788909c8c81dcbc", null ], [ "callback_SetupTabChanged", "classnmf_main_window.html#ad13eec409191fb1253139a487c912f3c", null ], [ "callback_ShowChart", "classnmf_main_window.html#aa584e121877027bfad202af352d9962b", null ], - [ "callback_ShowChartBy", "classnmf_main_window.html#ae14e08c6f07f27597438a02af01700fa", null ], + [ "callback_ShowChartBy", "classnmf_main_window.html#a031ee87532aeacd41abfc4098e2dd80f", null ], [ "callback_ShowChartMohnsRho", "classnmf_main_window.html#afe5dd447f18b33a825b47fdd4d3fb875", null ], [ "callback_ShowChartMultiScenario", "classnmf_main_window.html#a3db2907b7ad6cfcc0cd53fe5471e41c1", null ], [ "callback_ShowDiagnostics", "classnmf_main_window.html#a410ccd17f905b4279384719c149fedab", null ], @@ -56,7 +59,10 @@ var classnmf_main_window = [ "callback_SystemLoaded", "classnmf_main_window.html#a3e0082084aa73d1ff41376517013b8e2", null ], [ "callback_TableNamesOkPB", "classnmf_main_window.html#acba0ef02945b35e9c445ba43151d2fb9", null ], [ "callback_UpdateModelEquationSummary", "classnmf_main_window.html#ae51df316bad8e821afba19f8f2f94359", null ], + [ "callback_UpdateSeedValue", "classnmf_main_window.html#a3617f49d74f3a128b63fd043354da763", null ], [ "callback_UpdateSummaryStatistics", "classnmf_main_window.html#a04f9838ce833a75b7c8f225d93fafa86", null ], + [ "context_Action", "classnmf_main_window.html#a70d384a9b632706476a366cdb878e025", null ], + [ "createPopupMenu", "classnmf_main_window.html#ad689f025aebec97275b9257a2c50ff50", null ], [ "eventFilter", "classnmf_main_window.html#a0f7e6431e66ad61ee29b11ecd0887d7f", null ], [ "isStartUpOK", "classnmf_main_window.html#a19bc4c57733ca92f5ce0166ef2ec4eda", null ], [ "KeyPressed", "classnmf_main_window.html#a7bed941f44cecf48ab27735d112f8323", null ], @@ -74,6 +80,7 @@ var classnmf_main_window = [ "menu_importDatabase", "classnmf_main_window.html#ac9d999d1bb30c1030db7a6ac465c7267", null ], [ "menu_layoutDefault", "classnmf_main_window.html#a0c02f5e986910c8a5c1271b2d885c81d", null ], [ "menu_layoutOutput", "classnmf_main_window.html#ac7e4e5ea5fd09f8f950e74c9da7c4642", null ], + [ "menu_openCSVFile", "classnmf_main_window.html#a22179c3dfd4db8fdc1c7b18da91c05f8", null ], [ "menu_paste", "classnmf_main_window.html#adf8264f5a01f79d5679963988ac9f543", null ], [ "menu_pasteAll", "classnmf_main_window.html#a1bd3effe90341f0413518c8c680dfd1c", null ], [ "menu_preferences", "classnmf_main_window.html#a0b7c78a34b5830c22c13a2caf4644713", null ], @@ -94,7 +101,9 @@ var classnmf_main_window = [ "menu_showTableNames", "classnmf_main_window.html#a7d06a686e89e20ca9e84427e07592121", null ], [ "menu_stopRun", "classnmf_main_window.html#a3f08c57d1a3fe7a0ef6eb4ec9b9ae5e6", null ], [ "menu_toggleManagerMode", "classnmf_main_window.html#a7b979c7bb44ce607a3a4ded5d4e488f8", null ], + [ "menu_toggleManagerModeViewer", "classnmf_main_window.html#aea183f37d099d7f3273a60f40d016701", null ], [ "menu_whatsThis", "classnmf_main_window.html#a64bce52e0998209531614754f980bbfb", null ], [ "MouseMoved", "classnmf_main_window.html#a45dc27e957c9ea75788c0e13f86ccf7e", null ], - [ "mouseMoveEvent", "classnmf_main_window.html#a8641b917a24d3d99bb70e100c882b93e", null ] + [ "mouseMoveEvent", "classnmf_main_window.html#a8641b917a24d3d99bb70e100c882b93e", null ], + [ "MouseReleased", "classnmf_main_window.html#ae7e34161d6345895ccf2caecc42d7ba4", null ] ]; \ No newline at end of file diff --git a/docs/html/dir_000005_000014.html b/docs/html/dir_000005_000014.html new file mode 100644 index 00000000..57f4e62a --- /dev/null +++ b/docs/html/dir_000005_000014.html @@ -0,0 +1,112 @@ + + + + + + +MSSPM: MSSPM_Main -> MSSPM_GuiManagerMode Relation + + + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    MSSPM +
    +
    +
    + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    + +
    + +
    +

    MSSPM_Main → MSSPM_GuiManagerMode Relation

    File in MSSPM_MainIncludes file in MSSPM_GuiManagerMode
    nmfMainWindow.hMSSPM_GuiManagerMode.h
    +
    + + + + diff --git a/docs/html/dir_8291466d3bbe86acdba4d4c7465b1826.js b/docs/html/dir_8291466d3bbe86acdba4d4c7465b1826.js index a500514b..7be81e8c 100644 --- a/docs/html/dir_8291466d3bbe86acdba4d4c7465b1826.js +++ b/docs/html/dir_8291466d3bbe86acdba4d4c7465b1826.js @@ -1,5 +1,5 @@ var dir_8291466d3bbe86acdba4d4c7465b1826 = [ - [ "MSSPM_GuiManagerMode.h", "_m_s_s_p_m___gui_manager_mode_8h_source.html", null ], - [ "precompiled_header.h", "_m_s_s_p_m___gui_manager_mode_2precompiled__header_8h_source.html", null ] + [ "precompiled_header.h", "_m_s_s_p_m___gui_manager_mode_2precompiled__header_8h_source.html", null ], + [ "REMORA.h", "_r_e_m_o_r_a_8h_source.html", null ] ]; \ No newline at end of file diff --git a/docs/html/files.html b/docs/html/files.html index 2347c54e..ca4b4623 100644 --- a/docs/html/files.html +++ b/docs/html/files.html @@ -132,8 +132,8 @@
     nmfForecastTab04.hGUI definition for the nmfForecast_Tab4 Forecast Run class
     precompiled_header.h
      MSSPM_GuiManagerMode
     MSSPM_GuiManagerMode.h
     precompiled_header.h
     precompiled_header.h
     REMORA.h
      MSSPM_GuiOutput
     mainpage.h
     nmfOutputControls.hGUI definition for the Control widgets class MSSPM_GuiOutputControls in the Output area
    + + + + + +
    +
    MSSPM +
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    + +
    + +
    +  + +

    - k -

    +
    +
    + + + + diff --git a/docs/html/functions_func_l.html b/docs/html/functions_func_l.html index 4c4280ff..afa7e201 100644 --- a/docs/html/functions_func_l.html +++ b/docs/html/functions_func_l.html @@ -92,6 +92,7 @@
  • f
  • g
  • i
  • +
  • k
  • l
  • m
  • n
  • diff --git a/docs/html/functions_func_m.html b/docs/html/functions_func_m.html index 062e1fd0..5f7154fa 100644 --- a/docs/html/functions_func_m.html +++ b/docs/html/functions_func_m.html @@ -92,6 +92,7 @@
  • f
  • g
  • i
  • +
  • k
  • l
  • m
  • n
  • @@ -176,6 +177,9 @@

    - m -

    • menu_layoutOutput() : nmfMainWindow
    • +
    • menu_openCSVFile() +: nmfMainWindow +
    • menu_paste() : nmfMainWindow
    • @@ -233,8 +237,11 @@

      - m -

      • menu_whatsThis() : nmfMainWindow
      • -
      • MSSPM_GuiManagerMode() -: MSSPM_GuiManagerMode +
      • MouseMoved() +: REMORA +
      • +
      • MouseReleased() +: REMORA
      • MSSPM_GuiOutputControls() : MSSPM_GuiOutputControls diff --git a/docs/html/functions_func_n.html b/docs/html/functions_func_n.html index 91f6bdb1..bf7697f1 100644 --- a/docs/html/functions_func_n.html +++ b/docs/html/functions_func_n.html @@ -92,6 +92,7 @@
      • f
      • g
      • i
      • +
      • k
      • l
      • m
      • n
      • diff --git a/docs/html/functions_func_o.html b/docs/html/functions_func_o.html index b14f75e9..9be9c965 100644 --- a/docs/html/functions_func_o.html +++ b/docs/html/functions_func_o.html @@ -92,6 +92,7 @@
      • f
      • g
      • i
      • +
      • k
      • l
      • m
      • n
      • diff --git a/docs/html/functions_func_p.html b/docs/html/functions_func_p.html index 637b754c..ea7f3079 100644 --- a/docs/html/functions_func_p.html +++ b/docs/html/functions_func_p.html @@ -92,6 +92,7 @@
      • f
      • g
      • i
      • +
      • k
      • l
      • m
      • n
      • diff --git a/docs/html/functions_func_q.html b/docs/html/functions_func_q.html index 74d05e54..5419a024 100644 --- a/docs/html/functions_func_q.html +++ b/docs/html/functions_func_q.html @@ -92,6 +92,7 @@
      • f
      • g
      • i
      • +
      • k
      • l
      • m
      • n
      • diff --git a/docs/html/functions_func_r.html b/docs/html/functions_func_r.html index 9cf8018f..85e453f2 100644 --- a/docs/html/functions_func_r.html +++ b/docs/html/functions_func_r.html @@ -92,6 +92,7 @@
      • f
      • g
      • i
      • +
      • k
      • l
      • m
      • n
      • @@ -167,6 +168,9 @@

        - r -

    diff --git a/docs/html/functions_func_w.html b/docs/html/functions_func_w.html index a63c8e75..2b73597a 100644 --- a/docs/html/functions_func_w.html +++ b/docs/html/functions_func_w.html @@ -92,6 +92,7 @@
  • f
  • g
  • i
  • +
  • k
  • l
  • m
  • n
  • diff --git a/docs/html/functions_g.html b/docs/html/functions_g.html index 3700489d..bcd145de 100644 --- a/docs/html/functions_g.html +++ b/docs/html/functions_g.html @@ -92,6 +92,7 @@
  • f
  • g
  • i
  • +
  • k
  • l
  • m
  • n
  • @@ -309,6 +310,9 @@

    - g -