Skip to content

Commit 52911cd

Browse files
author
Ezequiel Torres
committed
Added best indiv button and also added functionality to it
* Also added convergence and genealogy to the Experiment window * Change a little bit the show_best to let the matplotlib window to be the modal window * #36
1 parent a1c990e commit 52911cd

File tree

12 files changed

+238
-60
lines changed

12 files changed

+238
-60
lines changed

MLC/Application.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ class MLC_CALLBACKS:
1818

1919

2020
class Application(object):
21+
2122
def __init__(self, simulation, callbacks={}):
22-
self._set_numpy_parameters()
2323
self._config = Config.get_instance()
2424

2525
self._simulation = simulation
@@ -67,7 +67,7 @@ def __init__(self, simulation, callbacks={}):
6767

6868
# add callback to show best individual
6969
self.__callbacks_manager.subscribe(MLC_CALLBACKS.ON_NEW_GENERATION, self.show_best)
70-
self.__display_best = False
70+
self.__display_best = True
7171

7272
def _set_numpy_parameters(self):
7373
# Set printable resolution (don't alter numpy interval resolution)
@@ -95,6 +95,7 @@ def go(self, to_generation, from_generation=None, display_best=False):
9595
9696
:return:
9797
"""
98+
self._set_numpy_parameters()
9899
self.__display_best = display_best
99100

100101
if from_generation is None:
@@ -103,8 +104,8 @@ def go(self, to_generation, from_generation=None, display_best=False):
103104
lg.logger_.info("Running MLC from generation %s to %s" % (from_generation, to_generation))
104105

105106
if from_generation < self._mlc_repository.count_population():
106-
lg.logger_.info("Generations %s to %s discarded" % (from_generation+1, self._mlc_repository.count_population()))
107-
self._mlc_repository.remove_population_from(from_generation+1)
107+
lg.logger_.info("Generations %s to %s discarded" % (from_generation + 1, self._mlc_repository.count_population()))
108+
self._mlc_repository.remove_population_from(from_generation + 1)
108109

109110
# emit app start event
110111
self.__callbacks_manager.on_event(MLC_CALLBACKS.ON_START)
@@ -127,9 +128,9 @@ def go(self, to_generation, from_generation=None, display_best=False):
127128
last_population = self._mlc_repository.get_population(last_generation)
128129

129130
# obtain the next generation by evolving the lastone
130-
lg.logger_.info("Evolving to Population %s using population %s" % (last_generation+1, last_generation))
131+
lg.logger_.info("Evolving to Population %s using population %s" % (last_generation + 1, last_generation))
131132

132-
next_population = Simulation.create_empty_population_for(last_generation+1)
133+
next_population = Simulation.create_empty_population_for(last_generation + 1)
133134
next_population = last_population.evolve(next_population)
134135

135136
# continue with evolve if there are duplicated individuals
@@ -144,13 +145,16 @@ def go(self, to_generation, from_generation=None, display_best=False):
144145
self._mlc_repository.add_population(next_population)
145146

146147
# emit new generation event
147-
self.__callbacks_manager.on_event(MLC_CALLBACKS.ON_NEW_GENERATION, last_generation+1)
148+
self.__callbacks_manager.on_event(MLC_CALLBACKS.ON_NEW_GENERATION, last_generation + 1)
148149

149150
lg.logger_.info("MLC Simulation Finished")
150151

151152
# emit app finish event
152153
self.__callbacks_manager.on_event(MLC_CALLBACKS.ON_FINISH)
153154

155+
# Return the numpy warning configuration to its original value
156+
np.seterr(all='warn')
157+
154158
def get_simulation(self):
155159
return self._simulation
156160

@@ -196,7 +200,11 @@ def show_best(self, generation_number):
196200
population = self._mlc_repository.get_population(generation_number)
197201
best_index, best_indiv, cost = population.get_best_individual()
198202

199-
EvaluatorFactory.get_callback().show_best(best_index, best_indiv, cost, stop_on_graph)
203+
EvaluatorFactory.get_callback().show_best(index=best_index,
204+
indiv=best_indiv,
205+
cost=cost,
206+
generation=generation_number,
207+
block=stop_on_graph)
200208

201209
def _project_validations(self):
202210
# Check that the evaluation and preevaluation modules can be loaded
@@ -205,6 +213,7 @@ def _project_validations(self):
205213

206214

207215
class MLCCallbacksManager:
216+
208217
def __init__(self):
209218
self.__callbacks = {}
210219

@@ -222,4 +231,4 @@ def on_event(self, event_type, *args, **kwargs):
222231
return
223232

224233
for callback in self.__callbacks[event_type]:
225-
callback(*args, **kwargs)
234+
callback(*args, **kwargs)

MLC/GUI/Autogenerated/autogenerated.py

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,6 @@ def setupUi(self, ExperimentInProgressDialog):
223223
self.picture_groupBox.setObjectName("picture_groupBox")
224224
self.picture_layout = QtWidgets.QVBoxLayout(self.picture_groupBox)
225225
self.picture_layout.setObjectName("picture_layout")
226-
self.log_check = QtWidgets.QCheckBox(self.picture_groupBox)
227-
self.log_check.setObjectName("log_check")
228-
self.picture_layout.addWidget(self.log_check)
229226
self.indiv_chart = QtWidgets.QTextEdit(self.picture_groupBox)
230227
self.indiv_chart.setObjectName("indiv_chart")
231228
self.picture_layout.addWidget(self.indiv_chart)
@@ -267,8 +264,7 @@ def retranslateUi(self, ExperimentInProgressDialog):
267264
self.gen_label.setText(_translate("ExperimentInProgressDialog", "TextLabel"))
268265
self.indiv_label.setText(_translate("ExperimentInProgressDialog", "TextLabel"))
269266
self.picture_groupBox.setTitle(_translate("ExperimentInProgressDialog", "Individuals\' Costs"))
270-
self.log_check.setText(_translate("ExperimentInProgressDialog", "Log Scale"))
271-
self.cancel_button.setText(_translate("ExperimentInProgressDialog", "Stop Experiment"))
267+
self.cancel_button.setText(_translate("ExperimentInProgressDialog", "Cancel Experiment"))
272268

273269
# -*- coding: utf-8 -*-
274270

@@ -314,6 +310,11 @@ def setupUi(self, Experiment):
314310
self.textEdit.setObjectName("textEdit")
315311
self.chart_conf_layout.addWidget(self.textEdit)
316312
self.verticalLayout_4.addWidget(self.chart_conf_frame)
313+
self.line = QtWidgets.QFrame(self.frame_4)
314+
self.line.setFrameShape(QtWidgets.QFrame.HLine)
315+
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
316+
self.line.setObjectName("line")
317+
self.verticalLayout_4.addWidget(self.line)
317318
self.groupBox_7 = QtWidgets.QGroupBox(self.frame_4)
318319
self.groupBox_7.setObjectName("groupBox_7")
319320
self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_7)
@@ -379,11 +380,6 @@ def setupUi(self, Experiment):
379380
self.points_combo.setObjectName("points_combo")
380381
self.gridLayout_6.addWidget(self.points_combo, 9, 1, 1, 1)
381382
self.verticalLayout_4.addWidget(self.groupBox_7)
382-
self.line = QtWidgets.QFrame(self.frame_4)
383-
self.line.setFrameShape(QtWidgets.QFrame.HLine)
384-
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
385-
self.line.setObjectName("line")
386-
self.verticalLayout_4.addWidget(self.line)
387383
self.horizontalLayout_2.addWidget(self.frame_4)
388384
self.frame_3 = QtWidgets.QFrame(self.experiment_tab)
389385
self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
@@ -539,6 +535,20 @@ def setupUi(self, Experiment):
539535
self.pushButton_8.setObjectName("pushButton_8")
540536
self.verticalLayout_13.addWidget(self.pushButton_8)
541537
self.verticalLayout_11.addWidget(self.groupBox_3)
538+
self.groupBox_8 = QtWidgets.QGroupBox(self.right_menu_frame)
539+
self.groupBox_8.setObjectName("groupBox_8")
540+
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_8)
541+
self.verticalLayout_5.setObjectName("verticalLayout_5")
542+
self.best_indiv_button = QtWidgets.QPushButton(self.groupBox_8)
543+
self.best_indiv_button.setObjectName("best_indiv_button")
544+
self.verticalLayout_5.addWidget(self.best_indiv_button)
545+
self.convergence_button = QtWidgets.QPushButton(self.groupBox_8)
546+
self.convergence_button.setObjectName("convergence_button")
547+
self.verticalLayout_5.addWidget(self.convergence_button)
548+
self.genealogy_button = QtWidgets.QPushButton(self.groupBox_8)
549+
self.genealogy_button.setObjectName("genealogy_button")
550+
self.verticalLayout_5.addWidget(self.genealogy_button)
551+
self.verticalLayout_11.addWidget(self.groupBox_8)
542552
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
543553
self.verticalLayout_11.addItem(spacerItem1)
544554
self.horizontalLayout_5.addWidget(self.right_menu_frame)
@@ -587,7 +597,7 @@ def setupUi(self, Experiment):
587597
Experiment.setCentralWidget(self.centralWidget)
588598

589599
self.retranslateUi(Experiment)
590-
self.tabWidget.setCurrentIndex(0)
600+
self.tabWidget.setCurrentIndex(1)
591601
self.next_gen_button.clicked.connect(Experiment.on_next_gen_button_clicked)
592602
self.save_config_button.clicked.connect(Experiment.on_save_config_button_clicked)
593603
self.dimension_check.clicked.connect(Experiment.on_dimension_check_clicked)
@@ -609,6 +619,9 @@ def setupUi(self, Experiment):
609619
self.min_cost_combo.currentTextChanged['QString'].connect(Experiment.on_chart_config_changed)
610620
self.max_cost_combo.currentTextChanged['QString'].connect(Experiment.on_chart_config_changed)
611621
self.nan_color_combo.currentTextChanged['QString'].connect(Experiment.on_chart_config_changed)
622+
self.genealogy_button.clicked.connect(Experiment.on_genealogy_button_clicked)
623+
self.best_indiv_button.clicked.connect(Experiment.on_best_indiv_button_clicked)
624+
self.convergence_button.clicked.connect(Experiment.on_convergence_button_clicked)
612625
# QtCore.QMetaObject.connectSlotsByName(Experiment)
613626

614627
def retranslateUi(self, Experiment):
@@ -649,6 +662,10 @@ def retranslateUi(self, Experiment):
649662
self.pushButton_3.setText(_translate("Experiment", "Create"))
650663
self.pushButton_4.setText(_translate("Experiment", "Cut"))
651664
self.pushButton_8.setText(_translate("Experiment", "Import"))
665+
self.groupBox_8.setTitle(_translate("Experiment", "Graphics"))
666+
self.best_indiv_button.setText(_translate("Experiment", "Best Individual"))
667+
self.convergence_button.setText(_translate("Experiment", "Convergence"))
668+
self.genealogy_button.setText(_translate("Experiment", "Genealogy"))
652669
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Experiment", "Results"))
653670
self.groupBox.setTitle(_translate("Experiment", "Experiment properties"))
654671
self.import_config_button.setText(_translate("Experiment", "Import"))

MLC/GUI/Autogenerated/untitled/experiment.ui

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,36 @@
477477
</layout>
478478
</widget>
479479
</item>
480+
<item>
481+
<widget class="QGroupBox" name="groupBox_8">
482+
<property name="title">
483+
<string>Graphics</string>
484+
</property>
485+
<layout class="QVBoxLayout" name="verticalLayout_5">
486+
<item>
487+
<widget class="QPushButton" name="best_indiv_button">
488+
<property name="text">
489+
<string>Best Individual</string>
490+
</property>
491+
</widget>
492+
</item>
493+
<item>
494+
<widget class="QPushButton" name="convergence_button">
495+
<property name="text">
496+
<string>Convergence</string>
497+
</property>
498+
</widget>
499+
</item>
500+
<item>
501+
<widget class="QPushButton" name="genealogy_button">
502+
<property name="text">
503+
<string>Genealogy</string>
504+
</property>
505+
</widget>
506+
</item>
507+
</layout>
508+
</widget>
509+
</item>
480510
<item>
481511
<spacer name="verticalSpacer">
482512
<property name="orientation">
@@ -921,6 +951,54 @@
921951
</hint>
922952
</hints>
923953
</connection>
954+
<connection>
955+
<sender>genealogy_button</sender>
956+
<signal>clicked()</signal>
957+
<receiver>Experiment</receiver>
958+
<slot>on_genealogy_button_clicked()</slot>
959+
<hints>
960+
<hint type="sourcelabel">
961+
<x>835</x>
962+
<y>488</y>
963+
</hint>
964+
<hint type="destinationlabel">
965+
<x>480</x>
966+
<y>273</y>
967+
</hint>
968+
</hints>
969+
</connection>
970+
<connection>
971+
<sender>best_indiv_button</sender>
972+
<signal>clicked()</signal>
973+
<receiver>Experiment</receiver>
974+
<slot>on_best_indiv_button_clicked()</slot>
975+
<hints>
976+
<hint type="sourcelabel">
977+
<x>835</x>
978+
<y>433</y>
979+
</hint>
980+
<hint type="destinationlabel">
981+
<x>480</x>
982+
<y>273</y>
983+
</hint>
984+
</hints>
985+
</connection>
986+
<connection>
987+
<sender>convergence_button</sender>
988+
<signal>clicked()</signal>
989+
<receiver>Experiment</receiver>
990+
<slot>on_convergence_button_clicked()</slot>
991+
<hints>
992+
<hint type="sourcelabel">
993+
<x>835</x>
994+
<y>461</y>
995+
</hint>
996+
<hint type="destinationlabel">
997+
<x>480</x>
998+
<y>273</y>
999+
</hint>
1000+
</hints>
1001+
</connection>
9241002
</connections>
9251003
<slots>
9261004
<slot>on_closed_dialog()</slot>
@@ -940,5 +1018,8 @@
9401018
<slot>on_preev_edit_button_clicked()</slot>
9411019
<slot>on_gen_count_combo_changed(QString)</slot>
9421020
<slot>on_chart_config_changed(QString)</slot>
1021+
<slot>on_best_indiv_button_clicked()</slot>
1022+
<slot>on_convergence_button_clicked()</slot>
1023+
<slot>on_genealogy_button_clicked()</slot>
9431024
</slots>
9441025
</ui>

MLC/GUI/Experiment/ExperimentDialog.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,16 @@ def on_chart_config_changed(self, value_changed):
242242
.format(self._experiment_name))
243243
self._chart_conf.update_chart()
244244

245+
def on_best_indiv_button_clicked(self):
246+
logger.debug('[EXPERIMENT {0}] [BEST_INDIV_BUTTON] - Executing on_best_indiv_button_clicked function')
247+
self._mlc_local.show_best(self._experiment_name, self._current_gen)
248+
249+
def on_convergence_button_clicked(self):
250+
logger.debug('[EXPERIMENT {0}] [CONVERGENCE_BUTTON] - Executing on_convergence_button_clicked function')
251+
252+
def on_genealogy_button_clicked(self):
253+
logger.debug('[EXPERIMENT {0}] [GENEALOGY_BUTTON] - Executing on_genealogy_button_clicked function')
254+
245255
def _config_table_edited(self, left, right):
246256
config_table = self._autogenerated_object.config_table
247257
table_model = config_table.model()
@@ -281,8 +291,8 @@ def _db_view_edited(self, left, right):
281291
indiv_id = int(table_model.get_data(left.row(), 1))
282292
if response == QMessageBox.No:
283293
# Get the value stored in the database
284-
old_value = self._get_db_view_stored_value(model_index=left,
285-
table_model=table_model,
294+
old_value = self._get_db_view_stored_value(model_index=left,
295+
table_model=table_model,
286296
indiv_id=indiv_id)
287297
logger.info('[EXPERIMENT {0}] [DB_VIEW_EDITED] - '
288298
'Edition was canceled. Cell({1}, {2}) - Old value: {3}'
@@ -298,10 +308,10 @@ def _db_view_edited(self, left, right):
298308
except ValueError:
299309
logger.info("[EXPERIMENT {0}] [DB_VIEW_EDITED] - "
300310
"Cost inserted is not valid. Individual won't be updated)")
301-
QMessageBox.critical(self, "Invalid cost",
311+
QMessageBox.critical(self, "Invalid cost",
302312
"Cost inserted is not valid. Individual won't be updated ")
303-
old_value = self._get_db_view_stored_value(model_index=left,
304-
table_model=table_model,
313+
old_value = self._get_db_view_stored_value(model_index=left,
314+
table_model=table_model,
305315
indiv_id=indiv_id)
306316
table_model.set_data(left.row(), left.column(), str(old_value))
307317
return
@@ -315,7 +325,8 @@ def _db_view_edited(self, left, right):
315325
new_cost=float(value),
316326
new_ev_time=time.time(),
317327
generation=self._current_gen)
318-
QMessageBox.information(self, "Experiment updated",
328+
self._update_individuals_figure()
329+
QMessageBox.information(self, "Experiment updated",
319330
"Individual was succesfully updated")
320331
elif left.column() == 5:
321332
# TODO

MLC/Population/Population.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def update_individual(self, *a, **kw):
168168
def get_best_individual(self):
169169
best_indivs = [x[0] for x in sorted(enumerate(self._costs), key=lambda x: x[1])]
170170
best_index = self._individuals[best_indivs[0]]
171-
return best_index, self._mlc_repository.get_individual(best_index), self._costs[best_index]
171+
return best_index, self._mlc_repository.get_individual(best_index), self._costs[best_indivs[0]]
172172

173173
def evolve(self, next_population):
174174
# FIXME: It's not necessary to compute the creation of both subgenerations

MLC/api/MLCLocal.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,18 @@ def get_individuals(self, experiment_name):
224224
individuals = MLCRepository.get_instance().get_individuals_data()
225225
return individuals
226226

227+
def get_generation(self, experiment_name, generation_number):
228+
if experiment_name not in self._experiments:
229+
raise ExperimentNotExistException(experiment_name)
230+
231+
if experiment_name not in self._open_experiments:
232+
raise ClosedExperimentException("get_experiment_info", experiment_name)
233+
234+
# get simulation in order to load mlc experiment database
235+
simulation = self._open_experiments[experiment_name].get_simulation()
236+
237+
return simulation.get_generation(generation_number)
238+
227239
def get_individual(self, experiment_name, individual_id):
228240
if experiment_name not in self._experiments:
229241
raise ExperimentNotExistException(experiment_name)
@@ -247,17 +259,18 @@ def update_individual_cost(self, experiment_name, indiv_id, new_cost, new_ev_tim
247259

248260
MLCRepository.get_instance().update_individual_cost(indiv_id, new_cost, new_ev_time, generation)
249261

250-
def get_generation(self, experiment_name, generation_number):
262+
def show_best(self, experiment_name, generation_number):
251263
if experiment_name not in self._experiments:
252264
raise ExperimentNotExistException(experiment_name)
253265

254266
if experiment_name not in self._open_experiments:
255267
raise ClosedExperimentException("get_experiment_info", experiment_name)
256268

257-
# get simulation in order to load mlc experiment database
258-
simulation = self._open_experiments[experiment_name].get_simulation()
269+
experiment = self._open_experiments[experiment_name]
270+
simulation = experiment.get_simulation()
259271

260-
return simulation.get_generation(generation_number)
272+
app = Application(simulation)
273+
app.show_best(generation_number)
261274

262275
def _create_experiment_dir(self, experiment_name):
263276
"""

0 commit comments

Comments
 (0)