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

add paths & output log for each run

parent a50a5b7b
......@@ -3,41 +3,41 @@ __email__ = "clement.ligneul@etu.unistra.fr"
import plotly.express as px
from pandas.io.parsers import read_csv
import sys
from sys import argv, stderr
# arguments [nb_gen, nb_plots, csv_file, title, f1, f2, f3]
# arguments [nb_gen, nb_plots, csv_file, title, f1, f2, f3, tmp dir]
if len(sys.argv) != 8:
if len(argv) != 9:
print(
"Usage : "
+ sys.argv[0]
+ " <nb of generations> <nb of plots> <csv file> <title> <f1> <f2> <f3>",
file=sys.stderr,
+ argv[0]
+ " <nb of generations> <nb of plots> <csv file> <title> <f1> <f2> <f3> <tmp_path> ",
file=stderr,
)
exit(1)
if sys.argv[4]:
titre = sys.argv[4]
if argv[4]:
titre = argv[4]
else:
titre = "Results"
if sys.argv[5]:
name_x = sys.argv[5]
if argv[5]:
name_x = argv[5]
else:
name_x = "f1"
if sys.argv[6]:
name_y = sys.argv[6]
if argv[6]:
name_y = argv[6]
else:
name_y = "f2"
if sys.argv[7]:
name_z = sys.argv[7]
if argv[7]:
name_z = argv[7]
else:
name_z = "f3"
df = read_csv(
sys.argv[3], header=0, delimiter=" ", usecols=[0, 1, 2], names=["f1", "f2", "f3"]
argv[3], header=0, delimiter=" ", usecols=[0, 1, 2], names=["f1", "f2", "f3"]
)
fig = px.scatter_3d(
......@@ -77,6 +77,6 @@ fig.update_layout(
),
)
fig.write_html("/tmp/plotting/fig.html")
fig.write_html(argv[8] + "fig.html")
fig.write_image("/tmp/plotting/fig.svg", engine="kaleido", scale=2)
fig.write_image(argv[8] + "fig.svg", engine="kaleido", scale=2)
......@@ -7,7 +7,10 @@ import { Win_alert } from './win_alert';
import { plot_obj, run_obj } from './index';
import * as util from './utilities';
import { FileMode, QCheckBox, QWidget, QLabel, QFileDialog, QGridLayout, QPushButton, QBoxLayout, AlignmentFlag } from '@nodegui/nodegui';
import { cwd } from 'process';
import { cwd, exit } from 'process';
import fs from 'fs';
import * as paths from './paths';
// buttons dimensions
const btn_width = 110;
......@@ -278,6 +281,7 @@ export class Compile {
output_compile.action_animation.stop();
// movie_loader.stop();
if(code === 0) {
plot_obj.graph_option.nb_plots = 1;
this.ready = 1;
run_obj.setReady(1);
if (this.nsgaii || this.nsgaiii || this.asrea || this.ibea || this.cdas) {
......@@ -285,11 +289,13 @@ export class Compile {
plot_obj.graph_option.axe_z_box.widget.show();
plot_obj.graph_option.plots.widget.hide();
plot_obj.graph_option.color_palet.hide();
run_obj.activate_island_model.setEnabled(false);
} else {
run_obj.plot_type = '2D';
plot_obj.graph_option.axe_z_box.widget.hide();
plot_obj.graph_option.plots.widget.show();
plot_obj.graph_option.color_palet.show();
run_obj.activate_island_model.setEnabled(true);
}
output_compile.action_label.setText('Compilation succeed');
output_compile.action_animation.setFileName(cwd() + '/src/assets/ok_icon.png');
......
......@@ -68,32 +68,30 @@ export class Offspring_options_win {
surviving_offspring.layout.addWidget(surviving_off_type);
// reduce offspring operator
// reduce operator options
const reduce_off_op_widget = new QWidget();
const reduce_off_op_layout = new QBoxLayout(0);
const reduce_off_op_label = new QLabel();
reduce_off_op_label.setText('Reduce Final Operator :');
reduce_off_op_label.setFixedSize(155, 30);
reduce_off_op_widget.setLayout(reduce_off_op_layout);
const combo_reduce_off_op = new QComboBox();
reduce_off_op_layout.addWidget(reduce_off_op_label);
reduce_off_op_layout.addWidget(combo_reduce_off_op);
combo_reduce_off_op.setFixedSize(120, 30);
combo_reduce_off_op.addItem(undefined, 'Tournament');
combo_reduce_off_op.addItem(undefined, 'Deterministic');
combo_reduce_off_op.addItem(undefined, 'Roulette');
combo_reduce_off_op.addItem(undefined, 'Random');
combo_reduce_off_op.addEventListener('currentTextChanged', (val) => {
if (val === 'Tournament' || val === '') {
const reduce_off_op_label = new QLabel();
reduce_off_op_label.setText('Reduce Operator :');
const reduce_off_op_combo = new QComboBox();
reduce_off_op_combo.setFixedSize(120,30);
reduce_off_op_combo.addItem(undefined, 'Tournament');
reduce_off_op_combo.addItem(undefined, 'Deterministic');
reduce_off_op_combo.addItem(undefined, 'Roulette');
reduce_off_op_combo.addItem(undefined, 'Random');
reduce_off_op_combo.addEventListener('currentTextChanged', (text) => {
if (text === 'Tournament') {
reduce_off_pressure.widget.setEnabled(true);
} else {
reduce_off_pressure.widget.setEnabled(false);
reduce_off_pressure.text_edit.clear();
}
this.reduce_op = val;
this.reduce_op = text;
});
reduce_off_op_layout.addWidget(reduce_off_op_label);
reduce_off_op_layout.addWidget(reduce_off_op_combo);
const reduce_off_pressure = new Advanced_option_widget('Reduce Pressure :', 0, '2.0');
reduce_off_pressure.text_edit.addEventListener('textChanged', () => {
......@@ -156,7 +154,7 @@ export class Offspring_options_win {
const reset_btn = new QPushButton();
reset_btn.setText('Reset');
reset_btn.addEventListener('clicked', () => {
combo_reduce_off_op.setCurrentIndex(0);
reduce_off_op_combo.setCurrentIndex(0);
reduce_off_pressure.text_edit.clear();
......
......@@ -52,32 +52,30 @@ export class Parent_options_win {
this.surviving = val;
});
// reduce offspring operator
// reduce operator options
const reduce_parent_op_widget = new QWidget();
const reduce_parent_op_layout = new QBoxLayout(0);
const reduce_parent_op_label = new QLabel();
reduce_parent_op_label.setText('Reduce Final Operator :');
reduce_parent_op_label.setFixedSize(155, 30);
reduce_parent_op_widget.setLayout(reduce_parent_op_layout);
const combo_reduce_parent_op = new QComboBox();
reduce_parent_op_layout.addWidget(reduce_parent_op_label);
reduce_parent_op_layout.addWidget(combo_reduce_parent_op);
combo_reduce_parent_op.setFixedSize(120, 30);
combo_reduce_parent_op.addItem(undefined, 'Tournament');
combo_reduce_parent_op.addItem(undefined, 'Deterministic');
combo_reduce_parent_op.addItem(undefined, 'Roulette');
combo_reduce_parent_op.addItem(undefined, 'Random');
combo_reduce_parent_op.addEventListener('currentTextChanged', (val) => {
if (val === 'Tournament' || val === '') {
const reduce_parent_op_label = new QLabel();
reduce_parent_op_label.setText('Reduce Operator :');
const reduce_parent_op_combo = new QComboBox();
reduce_parent_op_combo.setFixedSize(120,30);
reduce_parent_op_combo.addItem(undefined, 'Tournament');
reduce_parent_op_combo.addItem(undefined, 'Deterministic');
reduce_parent_op_combo.addItem(undefined, 'Roulette');
reduce_parent_op_combo.addItem(undefined, 'Random');
reduce_parent_op_combo.addEventListener('currentTextChanged', (text) => {
if (text === 'Tournament') {
reduce_parent_pressure.widget.setEnabled(true);
} else {
reduce_parent_pressure.widget.setEnabled(false);
reduce_parent_pressure.text_edit.clear();
}
this.reduce_op = val;
this.reduce_op = text;
});
reduce_parent_op_layout.addWidget(reduce_parent_op_label);
reduce_parent_op_layout.addWidget(reduce_parent_op_combo);
const reduce_parent_pressure = new Advanced_option_widget('Reduce pressure :', 0, '2.0');
reduce_parent_pressure.text_edit.addEventListener('textChanged', () => {
......@@ -134,7 +132,7 @@ export class Parent_options_win {
reset_btn.addEventListener('clicked', () => {
surviving_parent.text_edit.clear();
reduce_parent_pressure.text_edit.clear();
combo_reduce_parent_op.setCurrentIndex(0);
reduce_parent_op_combo.setCurrentIndex(0);
});
reset_btn.setFixedSize(100, 25);
......
/**
* @author Clément Ligneul <clement.ligneul@etu.unistra.fr>
*/
export var ui_dir_path:string = 'easea-ui/';
export var dir_tmp_path:string = 'easea-ui/.tmp/';
export var dir_results_path:string = 'easea-ui/results/';
export var svg_graph_path:string = dir_tmp_path + 'fig.svg';
export var html_graph_path:string = dir_tmp_path + 'fig.html';
\ No newline at end of file
__author__ = "Clément Ligneul"
__email__ = "clement.ligneul@etu.unistra.fr"
from pandas.io.parsers import read_csv
import plotly.express as px
from sys import argv, stderr
# from python_modules.plotly import graph_objects
# from python_modules.plotly.subplots import make_subplots
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import sys
from math import ceil
# parameters = [nb_gen, nb_plots, title, x_axis, y_axis, color]
if len(sys.argv) < 4:
from pandas.io.parsers import read_csv
from math import ceil
# parameters = [path, nb_gen, nb_plots, title, x_axis, y_axis, color]
# print("ok")
# exit(0)
if len(argv) < 5:
print(
"Usage : "
+ sys.argv[0]
+ " <nb of generations> <nb of plots> <title> <x_axis> <y_axis> <[optional]color>",
file=sys.stderr,
+ argv[0]
+ "<path> <nb of generations> <nb of plots> <title> <x_axis> <y_axis> <[optional]color>",
file=stderr,
)
exit(1)
# number of generations
nb_gen = int(sys.argv[1])
nb_gen = int(argv[2])
# number of violin plots
nb_plots = int(sys.argv[2])
nb_plots = int(argv[3])
# plot title
if sys.argv[3]:
titre = sys.argv[3]
if argv[4]:
titre = argv[4]
else:
titre = "Results"
treshold = ceil(nb_gen / nb_plots)
df = read_csv("/tmp/plotting/data.csv")
df = read_csv(argv[1] + "data.csv")
# fig = make_subplots(rows=4, cols=1, subplot_titles="Results")
fig = go.Figure()
for i in range(1, nb_plots + 1):
......@@ -43,13 +51,13 @@ for i in range(1, nb_plots + 1):
else:
n = "<" + str((i) * treshold)
if len(sys.argv) == 7 and sys.argv[6] != "":
if len(argv) == 7 and argv[7] != "":
fig.add_trace(
go.Violin(
y=df["BEST_FIT"][df["GEN"] < (i * treshold)][
df["GEN"] >= treshold * (i - 1)
],
fillcolor=sys.argv[6],
fillcolor=argv[7],
line_color="black",
name=n,
)
......@@ -75,25 +83,26 @@ fig.update_layout(
"x": 0.5,
"xanchor": "center",
"yanchor": "top",
}
},
# height=5000
)
if len(sys.argv) >= 5:
if str(sys.argv[4]) != "f1" and str(sys.argv[4]) != "":
fig.update_xaxes(title_text=sys.argv[4])
if len(argv) >= 6:
if str(argv[5]) != "f1" and str(argv[5]) != "":
fig.update_xaxes(title_text=argv[5])
else:
fig.update_xaxes(title_text="Generations")
else:
fig.update_xaxes(title_text="Generations")
if len(sys.argv) >= 6:
if str(sys.argv[5]) != "f2" and str(sys.argv[5]) != "":
fig.update_yaxes(title_text=sys.argv[5])
if len(argv) >= 7:
if str(argv[5]) != "f2" and str(argv[6]) != "":
fig.update_yaxes(title_text=argv[6])
else:
fig.update_yaxes(title_text="Best Fitness")
else:
fig.update_yaxes(title_text="Best Fitness")
fig.write_html("/tmp/plotting/fig.html")
fig.write_html(argv[1] + "fig.html")
fig.write_image("/tmp/plotting/fig.svg", engine="kaleido", scale=2)
fig.write_image(argv[1] + "fig.svg", engine="kaleido", scale=2)
......@@ -3,8 +3,8 @@
*/
import fs from 'fs';
export const data_csv = '/tmp/plotting/data.csv';
import { run_obj } from '.';
import * as paths from './paths';
export function parser(data: string): number[][] {
var str = data.toString()
......@@ -56,18 +56,37 @@ export function print_data(array: number[][]) {
}
}
export function write_in_file(buffer: string) {
var fd: number;
export function write_in_file(buffer: string, file?: string, id?: string) {
let fd = -1;
let fd2 = -1;
try {
fd = fs.openSync(data_csv, 'ax');
if(file){
fd2 = fs.openSync(file, 'ax');
} else {
fd = fs.openSync(run_obj.dir_path + paths.dir_tmp_path + 'data.csv', 'ax');
}
} catch {
fd = fs.openSync(data_csv, 'a');
fs.writeFileSync(fd, buffer);
fs.closeSync(fd);
if(file){
fd2 = fs.openSync(file, 'a');
fs.writeFileSync(fd2, buffer);
fs.closeSync(fd2);
} else {
fd = fs.openSync(run_obj.dir_path + paths.dir_tmp_path + 'data.csv', 'a');
fs.writeFileSync(fd, buffer);
fs.closeSync(fd);
}
return;
}
var init_buf = 'GEN,TIME,PLAN_EVAL,ACTU_EVAL,BEST_FIT,AVG_FIT,WORST_FIT,STD_DEV';
fs.writeFileSync(fd, init_buf + '\n' + buffer);
fs.closeSync(fd);
let init_buf = 'GEN,TIME,PLAN_EVAL,ACTU_EVAL,BEST_FIT,AVG_FIT,WORST_FIT,STD_DEV';
if(!file){
fs.writeFileSync(fd, init_buf + '\n' + buffer);
fs.closeSync(fd);
} else {
if(id){
init_buf = 'batch id : ' + id + '\nBatch size : ' + run_obj.batch_size + '\n';
fs.writeFileSync(fd2, init_buf + '\n' + buffer);
fs.closeSync(fd2);
}
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import { run_obj } from './index'
import os from 'os'
import { Win_alert } from "./win_alert";
import { Update_graph_win } from "./update_graph_win";
import * as paths from './paths';
const SCRIPT_2D_PATH = 'src/plot.py';
......@@ -89,13 +90,13 @@ export class Plot_result {
this.btn_widget.setEnabled(false);
if (type === '2D') {
if(color ) {
run = spawn('python3', [plot_path, nb_gen.toString(), plot_size.toString(), title, x_name, y_name, color], { timeout: 20000 });
if(color) {
run = spawn('python3', [plot_path, run_obj.dir_path + paths.dir_tmp_path, nb_gen.toString(), plot_size.toString(), title, x_name, y_name, color], { timeout: 20000 });
} else {
run = spawn('python3', [plot_path, nb_gen.toString(), plot_size.toString(), title], { timeout: 20000 });
run = spawn('python3', [plot_path, run_obj.dir_path + paths.dir_tmp_path, nb_gen.toString(), plot_size.toString(), title], { timeout: 20000 });
}
} 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 });
run = spawn('python3', [plot_path, nb_gen.toString(), plot_size.toString(), csv_path, title, x_name, y_name, z_name, run_obj.dir_path + paths.dir_tmp_path], { timeout: 20000 });
} else {
return;
}
......@@ -126,7 +127,7 @@ export class Plot_result {
} else {
this.image_label.setFixedSize(210, 30);
this.image_label.setText('Error : graph not found');
console.log('Error : graph not found');
console.log('Error : graph not found' + path);
}
} else {
this.image_label.setFixedSize(210, 30);
......@@ -198,10 +199,10 @@ export class Plot_result {
if (!path_file.endsWith('.svg'))
path_file += '.svg';
try {
fs.copyFileSync('/tmp/plotting/fig.svg', path_file);
fs.copyFileSync(run_obj.dir_path + paths.svg_graph_path, path_file);
} catch (e) {
if (e) {
new Win_alert(e + "", 'Save Static Plot');
new Win_alert(e + '', 'Save Static Plot');
return;
}
}
......@@ -222,7 +223,7 @@ export class Plot_result {
if (!path_file.endsWith('.html'))
path_file += '.html';
fs.copyFileSync('/tmp/plotting/fig.html', path_file);
fs.copyFileSync(run_obj.dir_path + paths.html_graph_path, path_file);
} catch (e) {
if (e)
new Win_alert(e + "", 'Save Interactive Plot');
......@@ -257,9 +258,9 @@ export class Plot_result {
this.image_label.addEventListener(WidgetEventTypes.MouseButtonDblClick, () => {
if (os.type() === 'Linux') {
spawn('sensible-browser', ['/tmp/plotting/fig.html']);
spawn('sensible-browser', [run_obj.dir_path + paths.html_graph_path]);
} else if (os.type() === 'Darwin') {
spawn('open', ['/tmp/plotting/fig.html']);
spawn('open', [run_obj.dir_path + paths.html_graph_path]);
}
})
......
......@@ -2,14 +2,16 @@
* @author Clément Ligneul <clement.ligneul@etu.unistra.fr>
*/
const { QGridLayout } = require("@nodegui/nodegui");
import { QWidget, QLabel, QPushButton, QTextBrowser, TextInteractionFlag, QMovie, QBoxLayout, Direction } from '@nodegui/nodegui';
import { QWidget, QLabel, QPushButton, QTextBrowser, QGridLayout, TextInteractionFlag, QMovie, QBoxLayout, Direction } from '@nodegui/nodegui';
import { spawn } from 'child_process';
import { spawnSync } from 'child_process';
import { running_plot, running_proc } from './index';
import { Win_alert } from './win_alert';
import * as plot_generation from './plot_generation';
import { plot_obj, run_obj } from './index';
import { write_in_file } from './plot_generation';
import * as paths from './paths';
require('child_process').spawn('node', ['--version'], {
env: {
......@@ -83,7 +85,7 @@ export class Pseudo_term {
this.text.insertPlainText('\n$ ' + command + ' ' + res + '\n');
}
process.env.EZ_PATH = '/usr/local/easena/'
// process.env.EZ_PATH = '/usr/local/easena/'
let child = spawn(command, array_params, {
cwd: dir,
env: process.env
......@@ -124,7 +126,7 @@ export class Pseudo_term {
this.text.insertPlainText('\n$ ' + command + ' ' + res + '\n');
}
process.env.EZ_PATH = '/usr/local/easena/';
// process.env.EZ_PATH = '/usr/local/easena/';
let child = spawnSync(command, array_params, {
cwd: dir,
env: process.env
......@@ -146,7 +148,7 @@ export class Pseudo_term {
}
}
run(cmd: string, plot_size: number, print:boolean, params?: string, dir?: string, rank?: number) {
run(cmd: string, plot_size: number, print:boolean, file: string, params?: string, dir?: string, rank?: number) {
let array_params: string[] = [];
let params_tmp: string[] = [];
......@@ -166,7 +168,7 @@ export class Pseudo_term {
for(let i = 0; i < params_tmp.length; i++)
array_params.push(params_tmp[i]);
process.env.EZ_PATH = '/usr/local/easena/';
// process.env.EZ_PATH = '/usr/local/easena/';
let child = spawn('stdbuf', array_params, { // stdbuf allows reducing buffer size to line size (live terminal)
cwd: dir,
......@@ -207,7 +209,8 @@ export class Pseudo_term {
run_obj.running_label.show();
plot_generation.parser(data);
if (run_obj.island_model) {
// local islands
if (run_obj.island_obj.local && run_obj.island_model) {
if(rank){
let array = String(data).split('\n');
......@@ -224,8 +227,15 @@ export class Pseudo_term {
}
}
// write_in_file(data, file, run_obj.batch_id.toString());
if(rank){
write_in_file(data, file + '_island_' + (rank%run_obj.island_obj.nb_isl_per_run) + '_run_' + (Math.floor(run_obj.batch_size - rank/run_obj.island_obj.nb_isl_per_run) + 1) + '.log', run_obj.batch_id.toString());
} else {
console.log('Error write_in_file : no rank');
}
// classic run
} else if (run_obj.plot_type === '2D') {
if (rank) {
let array = String(data).split('\n');
for (let i = 0; i < array.length; i++) {
......@@ -240,6 +250,11 @@ export class Pseudo_term {
}
}
}
// write run results in a file
write_in_file(data, file, run_obj.batch_id.toString());
// multi objectives
} else if (run_obj.plot_type === '3D') { // used when easea will change objective file names
let array = String(data).split('\n');
for (let i = 0; i < array.length - 2; i++) {
......@@ -256,6 +271,7 @@ export class Pseudo_term {
} else {
run_obj.run_results[0] = array[i];
}
write_in_file(array[i] + '\n', file, run_obj.batch_id.toString());
}
}
}
......@@ -303,7 +319,7 @@ export class Pseudo_term {
run_obj.running_label.setText('Plotting results ...');
run_obj.running_label.show();
// util.fix_csv(); // file correction (not used)
plot_obj.update_plot('/tmp/plotting/fig.svg', plot_size, run_obj.plot_type, run_obj.dir_path + '/objectives', '', '', '', '');
plot_obj.update_plot(run_obj.dir_path + paths.svg_graph_path, plot_size, run_obj.plot_type, run_obj.dir_path + 'objectives', '', '', '', '');
run_obj.finished_label.setText('Completed Runs : ' + (run_obj.batch_size - running_proc.length) + '/' + run_obj.batch_size);
}
......
......@@ -259,6 +259,8 @@ export class Run_options {
this.select_op = val;
});
select_op_layout.addWidget(select_op_label);
select_op_layout.addWidget(combo_select_op);
const select_pressure = new Advanced_option_widget('Selection Pressure :', 2, '2.0');
select_pressure.text_edit.addEventListener('textChanged', () => {
......@@ -301,8 +303,10 @@ export class Run_options {
this.reduce_final_op = val;
});
reduce_final_op_layout.addWidget(reduce_final_op_label);
reduce_final_op_layout.addWidget(combo_reduce_final_op);
const reduce_final_pressure = new Advanced_option_widget('Reduce Final Pressure :', 2, '2.0');
const reduce_final_pressure = new Advanced_option_widget('Final Reduce Pressure :', 2, '2.0');
reduce_final_pressure.text_edit.addEventListener('textChanged', () => {
var text = reduce_final_pressure.text_edit.text();
var val = Number(text);
......