Commit ff2967a5 authored by LIGNEUL CLEMENT's avatar LIGNEUL CLEMENT
Browse files

add see results feature + update documentation

parent 3230d158
......@@ -37,9 +37,9 @@ To use this program, it is necessary to have installed the most recent version o
## Installation
- Clone this repository
- Run `make install` in `easea-compiler-app/`
- The executable is located in `EASEA-compiler-app/`
- To remove the generated executable use `make clean`
- Run `sudo make install` in `easea-compiler-app/`
- To run the application run the executable in `EASEA-compiler-app/easea-compiler-app` or run `easea-compiler-app` if the command is installed
- To remove the generated executable use `make uninstall`
(DEV) To run the application execute `npm start`
......@@ -47,6 +47,5 @@ To use this program, it is necessary to have installed the most recent version o
## Next features
- See all results after the runs
- Analyze and repair csv files to fix the bug on very fast runs (<1s)
- Gitlab pages for documentation ?
= EASEA Compiler App Documentation
Clément Ligneul <clement.ligneul@etu.unistra.fr>
v1.1 2021-07-21
v1.2 2021-07-24
:toc: left
:toclevels: 4
:hide-uri-scheme:
......@@ -50,9 +50,9 @@ Note that if you are using macOS, plotly only works on version 10.10 or more (OS
Once the dependencies are installed :
- clone https://git.unistra.fr/ligneul/easea-compiler-app[this repository, window=_blank]
- run `npm install` in the main directory
- compile this app running `make` in the main directory
- run the executable in `EASEA-compiler-app/`
- run `make install` in the main directory
- now you can run the executable in `EASEA-compiler-app/` named `easea-compiler-app`. If the executable is installed, you can also run `easea-compiler-app` from anywhere
- run `make uninstall` in the main directory to uninstall the application
== Dev version
......@@ -262,6 +262,18 @@ image::images/island_menu.png[island menu image, 300, align=center]
- [underline]#Evaluate Immigrants# : ...
==== See Results
When all the runs are finished, a new button appears. It allows you to see the results of the different runs. This function is available only non <<Multi-objective problems, multi-objective problems>>.
image::images/end_run_batch.png[end run in batch image, 800, align=center]
image::images/results_1.png[results 1 image, 800, align=center]
To see another run result, use the slider :
image::images/results_6.png[results 6 image, 800, align=center]
=== Result Plot tab
After all the runs, if there is no problem during the execution, the application will generate a graph according to your compilation options.
......
......@@ -445,7 +445,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<div class="details">
<span id="author" class="author">Clément Ligneul</span><br>
<span id="email" class="email"><a href="mailto:clement.ligneul@etu.unistra.fr">clement.ligneul@etu.unistra.fr</a></span><br>
<span id="revnumber">version 1.1 2021-07-21</span>
<span id="revnumber">version 1.2 2021-07-24</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
......@@ -489,6 +489,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<li><a href="#_parents_options">Parents options</a></li>
<li><a href="#_offspring_options">Offspring options</a></li>
<li><a href="#_island_model_options">Island model options</a></li>
<li><a href="#_see_results">See Results</a></li>
</ul>
</li>
<li><a href="#_result_plot_tab">Result Plot tab</a>
......@@ -611,13 +612,13 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<p>clone <a href="https://git.unistra.fr/ligneul/easea-compiler-app" target="_blank" rel="noopener">this repository</a></p>
</li>
<li>
<p>run <code>npm install</code> in the main directory</p>
<p>run <code>make install</code> in the main directory</p>
</li>
<li>
<p>compile this app running <code>make</code> in the main directory</p>
<p>now you can run the executable in <code>EASEA-compiler-app/</code> named <code>easea-compiler-app</code>. If the executable is installed, you can also run <code>easea-compiler-app</code> from anywhere</p>
</li>
<li>
<p>run the executable in <code>EASEA-compiler-app/</code></p>
<p>run <code>make uninstall</code> in the main directory to uninstall the application</p>
</li>
</ul>
</div>
......@@ -985,6 +986,30 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_see_results">See Results</h4>
<div class="paragraph">
<p>When all the runs are finished, a new button appears. It allows you to see the results of the different runs. This function is available only non <a href="#_multi_objective_problems">multi-objective problems</a>.</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="images/end_run_batch.png" alt="end run in batch image" width="800">
</div>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="images/results_1.png" alt="results 1 image" width="800">
</div>
</div>
<div class="paragraph">
<p>To see another run result, use the slider :</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="images/results_6.png" alt="results 6 image" width="800">
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_result_plot_tab">Result Plot tab</h3>
......@@ -1191,8 +1216,8 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
</div>
<div id="footer">
<div id="footer-text">
Version 1.1 2021-07-21<br>
Last updated 2021-07-21 10:34:09 +0200
Version 1.2 2021-07-24<br>
Last updated 2021-07-24 10:33:15 +0200
</div>
</div>
</body>
......
= EASEA Compiler App Documentation
Clément Ligneul <clement.ligneul@etu.unistra.fr>
v1.1 2021-07-21
v1.2 2021-07-24
:toc: left
:toc-title: Table des matières
:toclevels: 4
......@@ -42,9 +42,9 @@ Notez que plotly ne fonctionne qu'à partir de la version 10.10 sur macOS (64 bi
Une fois les dépendances installées :
- clonez https://git.unistra.fr/ligneul/easea-compiler-app[ce dépôt, window=_blank]
- exécutez `npm install` dans le repertoire principal
- compilez l'exécutable avec `make` dans le répertoire principal
- lancez l'exécutable du répertoire `EASEA-compiler-app/`
- exécutez `make install` dans le repertoire principal
- vous pouvez maintenant lancer l'application avec l'exécutable `easea-compiler-app` dans le répertoire `EASEA-compiler-app/`. Si l'exécutable est installé vous pouvez lancer l'application avec `easea-compiler-app` depuis n'importe où.
- pour désinstaller l'application faites `make uninstall` depuis le répertoire principal
== Version développeur
......@@ -251,6 +251,18 @@ image::images/island_menu.png[island menu image, 300, align=center]
- [underline]#Evaluate Immigrants# : Réévaluer les individus migrants
==== See Results
Quand toutes les exécutions d'un batch sont terminées, un nouveau boutton apparaît. Il permet de consulter le resultat pour chacunes d'entre elles. Cette fonction n'est pas disponible pour des exécution sur des <<Problèmes multi-objectifs, problèmes multi-objectifs>>.
image::images/end_run_batch.png[end run in batch image, 800, align=center]
image::images/results_1.png[results 1 image, 800, align=center]
Pour voir les différents résultats, utilisez le curseur :
image::images/results_6.png[results 6 image, 800, align=center]
=== Onglet Result Plot
A la fin de toutes les exécutions, si aucune erreur n'est survenue, cette application va générer un graphe en fonction des paramètres de compilation utilisés.
......
......@@ -445,7 +445,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<div class="details">
<span id="author" class="author">Clément Ligneul</span><br>
<span id="email" class="email"><a href="mailto:clement.ligneul@etu.unistra.fr">clement.ligneul@etu.unistra.fr</a></span><br>
<span id="revnumber">version 1.1 2021-07-21</span>
<span id="revnumber">version 1.2 2021-07-24</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table des matières</div>
......@@ -484,6 +484,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<li><a href="#_parents_options">Parents options</a></li>
<li><a href="#_offspring_options">Offspring options</a></li>
<li><a href="#_island_model_options">Island model options</a></li>
<li><a href="#_see_results">See Results</a></li>
</ul>
</li>
<li><a href="#_onglet_result_plot">Onglet Result Plot</a>
......@@ -594,13 +595,13 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<p>clonez <a href="https://git.unistra.fr/ligneul/easea-compiler-app" target="_blank" rel="noopener">ce dépôt</a></p>
</li>
<li>
<p>exécutez <code>npm install</code> dans le repertoire principal</p>
<p>exécutez <code>make install</code> dans le repertoire principal</p>
</li>
<li>
<p>compilez l&#8217;exécutable avec <code>make</code> dans le répertoire principal</p>
<p>vous pouvez maintenant lancer l&#8217;application avec l&#8217;exécutable <code>easea-compiler-app</code> dans le répertoire <code>EASEA-compiler-app/</code>. Si l&#8217;exécutable est installé vous pouvez lancer l&#8217;application avec <code>easea-compiler-app</code> depuis n&#8217;importe où.</p>
</li>
<li>
<p>lancez l&#8217;exécutable du répertoire <code>EASEA-compiler-app/</code></p>
<p>pour désinstaller l&#8217;application faites <code>make uninstall</code> depuis le répertoire principal</p>
</li>
</ul>
</div>
......@@ -963,6 +964,30 @@ Par exemple, la première graine vaut 0 et nous avons un batch de taille 3. Si l
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_see_results">See Results</h4>
<div class="paragraph">
<p>Quand toutes les exécutions d&#8217;un batch sont terminées, un nouveau boutton apparaît. Il permet de consulter le resultat pour chacunes d&#8217;entre elles. Cette fonction n&#8217;est pas disponible pour des exécution sur des <a href="#_problèmes_multi_objectifs">problèmes multi-objectifs</a>.</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="images/end_run_batch.png" alt="end run in batch image" width="800">
</div>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="images/results_1.png" alt="results 1 image" width="800">
</div>
</div>
<div class="paragraph">
<p>Pour voir les différents résultats, utilisez le curseur :</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="images/results_6.png" alt="results 6 image" width="800">
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_onglet_result_plot">Onglet Result Plot</h3>
......@@ -1169,8 +1194,8 @@ Par exemple, la première graine vaut 0 et nous avons un batch de taille 3. Si l
</div>
<div id="footer">
<div id="footer-text">
Version 1.1 2021-07-21<br>
Last updated 2021-07-21 10:34:09 +0200
Version 1.2 2021-07-24<br>
Last updated 2021-07-24 10:33:12 +0200
</div>
</div>
</body>
......
......@@ -75,6 +75,6 @@ fig.update_layout(
),
)
fig.write_html("plotting/fig.html")
fig.write_html("/tmp/plotting/fig.html")
fig.write_image("plotting/fig.svg", engine="kaleido", scale=2)
fig.write_image("/tmp/plotting/fig.svg", engine="kaleido", scale=2)
......@@ -290,7 +290,7 @@ export class Compile {
var ez_makefile = this.ez_file_address.substring(0, this.ez_file_address.length - 2);
ez_makefile = ez_makefile.concat('mak');
var make_clean = output_compile.compile('make', ['-C', this.dir_path, '-f', ez_makefile, 'easeaclean']);
make_clean.stdout.on('data', (data) => {
output_compile.text.insertPlainText(data.toString());
});
......
......@@ -96,13 +96,13 @@ global_win.setStyleSheet(general_css);
global_win.addEventListener(WidgetEventTypes.Close, () => {
// console.log("On kill tout ici");
util.kill_all(running_proc);
fs.rmSync('./plotting', { recursive: true, force: true });
fs.rmSync('/tmp/plotting', { recursive: true, force: true });
});
// global_win.adjustSize();
// global_win.setFixedSize(global_win.size().width(), global_win.size().height());
fs.mkdir('plotting/', (err) => {
fs.mkdir('/tmp/plotting/', (err) => {
if (err && err.code !== 'EEXIST') {
console.log(err.message);
console.log(err);
......
......@@ -28,7 +28,7 @@ else :
treshold = ceil(nb_gen / nb_plots)
df = read_csv("plotting/data.csv")
df = read_csv("/tmp/plotting/data.csv")
fig = go.Figure()
......@@ -65,6 +65,6 @@ fig.update_xaxes(title_text="Generations")
fig.update_yaxes(title_text="Best Fitness")
fig.write_html("plotting/fig.html")
fig.write_html("/tmp/plotting/fig.html")
fig.write_image("plotting/fig.svg", engine="kaleido", scale=2)
fig.write_image("/tmp/plotting/fig.svg", engine="kaleido", scale=2)
import fs from 'fs';
export const data_csv = 'plotting/data.csv';
export const data_csv = '/tmp/plotting/data.csv';
export function parser(data: string): number[][] {
var str = data.toString()
......
......@@ -69,9 +69,9 @@ export class Plot_result {
if (isNaN(nb_gen)) {
var val = this.get_generations(run_obj.ez_file_address);
console.log('nb gen detected in file : ' + val);
if(val === -1){
if (val === -1) {
nb_gen = 30;
} else{
} else {
nb_gen = val;
run_obj.total_generations = val;
}
......@@ -81,10 +81,10 @@ export class Plot_result {
console.log('updating plot...');
this.btn_widget.setEnabled(false);
if(type === '2D'){
if (type === '2D') {
run = spawn('python3', [plot_path, nb_gen.toString(), plot_size.toString(), title], { timeout: 20000 });
} else if(type === '3D'){
} else if (type === '3D') {
run = spawn('python3', [plot_path, nb_gen.toString(), plot_size.toString(), csv_path, title, x_name, y_name, z_name], { timeout: 20000 });
} else {
return;
......@@ -183,7 +183,7 @@ export class Plot_result {
if (!path_file.endsWith('.svg'))
path_file += '.svg';
try {
fs.copyFileSync('plotting/fig.svg', path_file);
fs.copyFileSync('/tmp/plotting/fig.svg', path_file);
} catch (e) {
if (e)
new Win_alert(e, 'Save Static Plot');
......@@ -206,7 +206,7 @@ export class Plot_result {
if (!path_file.endsWith('.html'))
path_file += '.html';
fs.copyFileSync('plotting/fig.html', path_file);
fs.copyFileSync('/tmp/plotting/fig.html', path_file);
} catch (e) {
if (e)
new Win_alert(e, 'Save Interactive Plot');
......@@ -225,7 +225,7 @@ export class Plot_result {
const graph_option = new Update_graph_win();
this.update_graph.setFixedSize(150, 30);
this.update_graph.setText('Update Plot');
this.update_graph.addEventListener('clicked', () =>{
this.update_graph.addEventListener('clicked', () => {
graph_option.execution();
});
......@@ -240,9 +240,9 @@ export class Plot_result {
this.image_label.addEventListener(WidgetEventTypes.MouseButtonDblClick, () => {
if (os.type() === 'Linux') {
spawn('sensible-browser', ['plotting/fig.html']);
spawn('sensible-browser', ['/tmp/plotting/fig.html']);
} else if (os.type() === 'Darwin') {
spawn('open', ['plotting/fig.html']);
spawn('open', ['/tmp/plotting/fig.html']);
}
})
......
......@@ -7,7 +7,6 @@ import { Win_alert } from './win_alert';
import * as plot_generation from './plot_generation';
import { plot_obj, run_obj } from './index';
import { initial_proc } from './run_tab';
import * as util from './utilities';
require('child_process').spawn('node', ['--version'], {
......@@ -174,13 +173,41 @@ export class Pseudo_term {
run_obj.running_label.setText('Writing results ...');
run_obj.running_label.show();
plot_generation.parser(data);
// if(run_obj.plot_type === '2D'){
// //FAIRE ECRITURE DANS LE FICHIER CORRESPONDANT AU RANG DU RUN
// console.log('écriture du run ' + rank)
// if(rank)
// util.write_results(rank, data);
// }
if (run_obj.plot_type === '2D') {
if (rank) {
var array = String(data).split('\n');
for (var i = 0; i < array.length; i++) {
if (i > 3) {
array[i] = array[i].split(' ').join(' ');
array[i] = array[i].split('\t').join(' ');
}
if (run_obj.run_results[rank - 1]) {
run_obj.run_results[rank - 1] = run_obj.run_results[rank - 1].concat('\n' + array[i]);
} else {
run_obj.run_results[rank - 1] = array[i];
}
}
}
} else if (run_obj.plot_type === '3D') { // used when easea will change objective file names
var array = String(data).split('\n');
for (var i = 0; i < array.length - 2; i++) {
if (array[i].startsWith('Total execution time') ||
array[i].startsWith('Quality Metrics') ||
array[i].startsWith('HyperVolume') ||
array[i].startsWith('Generational distance') ||
array[i].startsWith('Inverted generational distance')
) {
array[i] = array[i].split('EASEA LOG [INFO]: ').join('');
if (run_obj.run_results[0]) {
run_obj.run_results[0] = run_obj.run_results[0].concat('\n' + array[i]);
} else {
run_obj.run_results[0] = array[i];
}
}
}
}
});
child.on('exit', (code) => {
......@@ -201,7 +228,7 @@ export class Pseudo_term {
run_obj.running_label.setText('Plotting results ...');
run_obj.running_label.show();
plot_obj.update_plot(process.cwd() + '/plotting/fig.svg', plot_size, type, run_obj.dir_path + '/objectives', '', '', '', '');
plot_obj.update_plot('/tmp/plotting/fig.svg', plot_size, type, run_obj.dir_path + '/objectives', '', '', '', '');
console.log("child process terminated with code " + code);
run_obj.finished_label.setText('Completed Runs : ' + (run_obj.batch_size - running_proc.length) + '/' + run_obj.batch_size);
......
import { AlignmentFlag, Orientation, WindowType, QDialog, QFont, QGridLayout, QLabel, QPlainTextEdit, QPushButton, QSlider, QWidget, TickPosition } from "@nodegui/nodegui";
import { general_css } from "./style";
import { run_obj } from ".";
export class Results_win {
window: QDialog;
layout: QGridLayout;
slider: QSlider;
console: QPlainTextEdit;
constructor() {
this.window = new QDialog();
this.window.setWindowTitle('Batch Results')
this.window.setWindowFlag(WindowType.CustomizeWindowHint, true);
this.window.setWindowFlag(WindowType.WindowCloseButtonHint, false);
this.layout = new QGridLayout();
this.window.setLayout(this.layout);
this.slider = new QSlider();
this.console = new QPlainTextEdit();
this.console.setFixedSize(1000, 450);
this.console.setReadOnly(true);
}
generate() {
var batch_size = run_obj.runned_proc;
// run number label
const run_label = new QLabel();
run_label.setText('Results for run ' + (this.slider.value() + 1));
run_label.setAlignment(AlignmentFlag.AlignCenter);
const label_font = new QFont();
label_font.setPointSize(18);
run_label.setFont(label_font);
// buttons
const btn_widget = new QWidget();
const btn_layout = new QGridLayout()
btn_widget.setLayout(btn_layout);
const btn_close = new QPushButton();
btn_close.setFixedSize(150, 30);
btn_close.setText('Close');
btn_close.addEventListener('clicked', () => {
this.window.close();
});
btn_layout.addWidget(btn_close, 0, 1);
// slider
const slider_widget = new QWidget();
const slider_layout = new QGridLayout();
slider_widget.setLayout(slider_layout);
this.slider.setRange(1, batch_size);
this.slider.setOrientation(Orientation.Horizontal);
this.slider.setSingleStep(1);
this.slider.setTickPosition(TickPosition.TicksBelow);
this.slider.setTickInterval(1);
this.slider.addEventListener('valueChanged', () => {
run_label.setText('Results for run ' + this.slider.value());
// write results
this.console.setPlainText('');
this.console.insertPlainText(run_obj.run_results[this.slider.value() - 1]);
});
slider_layout.addWidget(this.slider, 0, 0, 1, batch_size);
for (var i = 0; i < batch_size; i++) {
var run_rank = new QLabel();
run_rank.setText((i + 1).toString());
run_rank.setFixedSize(16, 30);
slider_layout.addWidget(run_rank, 1, i);
}
// display
this.layout.addWidget(run_label, 0, 0);
if (batch_size > 1)
this.layout.addWidget(slider_widget, 1, 0);
this.layout.addWidget(this.console, 2, 0, 3, 0);
this.layout.addWidget(btn_widget, 5, 0);
this.window.setStyleSheet(general_css);
this.window.adjustSize();
this.window.setFixedSize(this.window.size().width(), this.window.size().height());
}
execute() {
// write results
this.console.insertPlainText(run_obj.run_results[0]);
this.window.exec();
}
}
\ No newline at end of file
......@@ -83,7 +83,7 @@ export class Run_options {
const thread_edit = new QLineEdit();
thread_edit.setPlaceholderText('1');
thread_edit.setFixedSize(70, 30);
thread_edit.addEventListener('textChanged', () =>{
thread_edit.addEventListener('textChanged', () => {
const val = Number(thread_edit.text());
// if (!isNaN(val))
......
......@@ -11,6 +11,7 @@ import * as fs_extra from 'fs-extra';
import { Advanced_option_widget } from './advanced_option_widget';
import { running_plot } from './index';
import { ChildProcess } from 'child_process';
import { Results_win } from './results_win';
// first process
......@@ -35,6 +36,10 @@ export class Run_tab {
progress_bar: QProgressBar = new QProgressBar();
plot_type: string = '2D';
total_generations: number = 0;
results_button: QPushButton = new QPushButton();
run_results: string[] = [];
runned_proc: number = 1;
// buttons
activate_island_model: QCheckBox = new QCheckBox();
......@@ -134,6 +139,18 @@ export class Run_tab {
this.running_label.hide();
//see results
this.results_button = new QPushButton();
this.results_button.setFixedSize(150, 30);
this.results_button.setText('See Results');
this.results_button.addEventListener('clicked', () => {
const results = new Results_win();
results.generate();
results.execute();
});
this.results_button.hide();
// run button
this.run_btn.setText("Run !");
this.run_btn.setFixedSize(150, 30);
......@@ -163,10 +180,14 @@ export class Run_tab {
return;
}
for (var i = 0; i < this.batch_size; i++)
this.run_results[i] = '';
this.enable_buttons(false);
this.progress