22import java.awt.BasicStroke;
23import java.awt.BorderLayout;
25import java.awt.Component;
26import java.awt.Cursor;
27import java.awt.Dimension;
28import java.awt.FlowLayout;
30import java.awt.event.ActionEvent;
31import java.awt.event.ActionListener;
32import java.awt.event.ComponentAdapter;
33import java.awt.event.ComponentEvent;
34import java.awt.event.ItemEvent;
35import java.awt.event.ItemListener;
36import java.awt.geom.Ellipse2D;
38import java.io.FileFilter;
39import java.io.IOException;
40import java.util.ArrayList;
41import java.util.Collections;
42import java.util.Comparator;
43import java.util.HashMap;
46import java.util.concurrent.atomic.AtomicInteger;
47import java.util.stream.IntStream;
49import javax.swing.DefaultListModel;
50import javax.swing.GroupLayout;
51import javax.swing.JButton;
52import javax.swing.JCheckBox;
53import javax.swing.JCheckBoxMenuItem;
54import javax.swing.JComponent;
55import javax.swing.JLabel;
56import javax.swing.JList;
57import javax.swing.JOptionPane;
58import javax.swing.JPanel;
59import javax.swing.JPopupMenu;
60import javax.swing.JScrollPane;
61import javax.swing.JSplitPane;
62import javax.swing.JTextField;
63import javax.swing.ListSelectionModel;
64import javax.swing.SwingConstants;
65import javax.swing.UIManager;
67import org.jfree.chart.ChartMouseEvent;
68import org.jfree.chart.ChartMouseListener;
69import org.jfree.chart.ChartPanel;
70import org.jfree.chart.JFreeChart;
71import org.jfree.chart.axis.NumberAxis;
72import org.jfree.chart.editor.ChartEditor;
73import org.jfree.chart.editor.ChartEditorManager;
74import org.jfree.chart.entity.PlotEntity;
75import org.jfree.chart.entity.XYItemEntity;
76import org.jfree.chart.labels.XYToolTipGenerator;
77import org.jfree.chart.plot.DatasetRenderingOrder;
78import org.jfree.chart.plot.SeriesRenderingOrder;
79import org.jfree.chart.plot.XYPlot;
80import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
81import org.jfree.chart.ui.RectangleEdge;
82import org.jfree.data.xy.DefaultXYDataset;
83import org.jfree.data.xy.XYDataset;
85import denoptim.constants.DENOPTIMConstants;
86import denoptim.exception.DENOPTIMException;
87import denoptim.files.FileUtils;
88import denoptim.graph.CandidateLW;
89import denoptim.io.DenoptimIO;
90import denoptim.logging.CounterID;
91import denoptim.utils.GeneralUtils;
152 new HashMap<CounterID,DefaultXYDataset>();
162 private final String
NL = System.getProperty(
"line.separator");
199 private final Color[]
colors =
new Color[] {Color.black,
200 Color.decode(
"#354ccd"),
201 Color.decode(
"#1e9222"),
202 Color.decode(
"#9eca2f"),
203 Color.decode(
"#28cbad"),
204 Color.decode(
"#dea0c8"),
205 Color.decode(
"#dd6835"),
206 Color.decode(
"#b70505"),
207 Color.decode(
"#a42ac4")};
213 new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
216 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
217 1.0f,
new float[] {2f, 2f}, 0.0f),
219 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
220 1.0f,
new float[] {5f, 2f}, 0.0f),
222 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
223 1.0f,
new float[] {2f, 2f, 5f, 2f}, 0.0f),
225 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
226 1.0f,
new float[] {2f, 2f, 2f, 2f, 5f, 2f}, 0.0f),
228 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
229 1.0f,
new float[] {2f, 2f, 2f, 2f, 2f, 2f, 5f, 2f}, 0.0f),
231 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
232 1.0f,
new float[] {2f, 2f, 5f, 2f, 5f, 2f}, 0.0f),
234 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
235 1.0f,
new float[] {2f, 2f, 2f, 2f, 5f, 2f, 5f, 2f}, 0.0f),
237 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
238 1.0f,
new float[] {2f, 2f, 2f, 2f, 2f, 2f,
239 5f, 2f, 5f, 2f, 5f, 2f}, 0.0f),
257 super.setLayout(
new BorderLayout());
269 this.setLayout(
new BorderLayout());
281 evoSeriesBtn =
new JButton(
"Show/Hide Population Stats");
284 "<html><body width='%1s'>Click to select which population "
285 +
"statistics to plot in the top plot.",300));
287 public void actionPerformed(ActionEvent e) {
296 "<html><body width='%1s'>Click to select which monitored event "
297 +
"counts to plot in the bottom plot.",300));
299 public void actionPerformed(ActionEvent e) {
309 JButton rstView =
new JButton(
"Reset Charts");
310 rstView.addActionListener(
new ActionListener() {
311 public void actionPerformed(ActionEvent e) {
312 evoPlot.getDomainAxis().setAutoRange(
true);
313 evoPlot.getRangeAxis().setAutoRange(
true);
314 evoPlot.getDomainAxis().setLowerBound(-0.5);
319 if (c instanceof JCheckBoxMenuItem)
322 if (((JCheckBoxMenuItem) c).getText().startsWith(
"Max")
323 || ((JCheckBoxMenuItem) c).getText().startsWith(
"Min"))
324 ((JCheckBoxMenuItem) c).setSelected(
true);
326 ((JCheckBoxMenuItem) c).setSelected(
false);
337 cb.setSelected(
true);
339 cb.setSelected(
false);
349 lblTotItems.setHorizontalAlignment(SwingConstants.RIGHT);
350 lblTotItems.setPreferredSize(
new Dimension(300,28));
358 +
"graph representation of the selected candidate.");
360 public void actionPerformed(ActionEvent e) {
361 mainPanel.setCursor(Cursor.getPredefinedCursor(
362 Cursor.WAIT_CURSOR));
366 mainPanel.setCursor(Cursor.getPredefinedCursor(
367 Cursor.DEFAULT_CURSOR));
375 "<html><body width='%1s'>Open a "
376 +
"new tab for inspecting the graph representation of all "
377 +
"members of the population. "
378 +
"Opens a dialog to specify which generation to consider of "
379 +
"the selected candidate.",300));
381 public void actionPerformed(ActionEvent e) {
392 genId = Integer.parseInt((String) res);
393 }
catch (Throwable t) {
395 String.format(
"<html><body width='%1s'>String '"
396 + res+
"' could not be used to identify "
398 +
"Please, type an integer 0, 1, 2,...", 300),
400 JOptionPane.PLAIN_MESSAGE,
401 UIManager.getIcon(
"OptionPane.errorIcon"));
407 String.format(
"<html><body width='%1s'>"
408 +
"List of members of generation " + genId
409 +
" could not be found. Generation summary "
410 +
"missing or not properly formatted.",300),
412 JOptionPane.PLAIN_MESSAGE,
413 UIManager.getIcon(
"OptionPane.errorIcon"));
420 mainPanel.setCursor(Cursor.getPredefinedCursor(
421 Cursor.WAIT_CURSOR));
426 mainPanel.setCursor(Cursor.getPredefinedCursor(
427 Cursor.DEFAULT_CURSOR));
428 }
catch (IOException e1)
430 e1.printStackTrace();
432 String.format(
"<html><body width='%1s'>"
433 +
"List of members of generation " + genId
434 +
" could not be collected. Hint: "
435 + e1.getMessage(), 300),
437 JOptionPane.PLAIN_MESSAGE,
438 UIManager.getIcon(
"OptionPane.errorIcon"));
439 mainPanel.setCursor(Cursor.getPredefinedCursor(
440 Cursor.DEFAULT_CURSOR));
450 System.out.println(
"File collecting members of the population "
451 +
"at generation " + genId +
": "+ pathtoTmpFile);
459 "<html><body width='%1s'>Open a "
460 +
"new tab for inspecting the graph representation of all "
461 +
"members of the final population. ",300));
463 public void actionPerformed(ActionEvent e) {
466 File finalPopFolder =
new File(
srcFolder,
"Final");
467 if (!finalPopFolder.exists())
470 String.format(
"<html><body width='%1s'>"
471 +
"Cannot find folder '" + finalPopFolder
472 +
"'. Final population not found.", 300),
474 JOptionPane.ERROR_MESSAGE,
475 UIManager.getIcon(
"OptionPane.errorIcon"));
476 mainPanel.setCursor(Cursor.getPredefinedCursor(
477 Cursor.DEFAULT_CURSOR));
480 mainPanel.setCursor(Cursor.getPredefinedCursor(
481 Cursor.WAIT_CURSOR));
482 List<String> filesToMerge =
new ArrayList<String>();
483 for (File fitFile : finalPopFolder.listFiles(
new FileFilter() {
486 public boolean accept(File pathname) {
487 if (pathname.getName().endsWith(
496 filesToMerge.add(fitFile.getAbsolutePath());
502 mainPanel.setCursor(Cursor.getPredefinedCursor(
503 Cursor.DEFAULT_CURSOR));
504 }
catch (IOException e1)
506 e1.printStackTrace();
508 String.format(
"<html><body width='%1s'>"
509 +
"List of members of final population "
510 +
" could not be collected. Hint: "
511 + e1.getMessage(), 400),
513 JOptionPane.PLAIN_MESSAGE,
514 UIManager.getIcon(
"OptionPane.errorIcon"));
515 mainPanel.setCursor(Cursor.getPredefinedCursor(
516 Cursor.DEFAULT_CURSOR));
526 System.out.println(
"File collecting members of the final "
527 +
"population: "+ pathtoTmpFile);
534 GroupLayout lyoCtrlPanelRow1 =
new GroupLayout(
ctrlPanelRow1);
536 lyoCtrlPanelRow1.setAutoCreateGaps(
true);
537 lyoCtrlPanelRow1.setAutoCreateContainerGaps(
true);
538 lyoCtrlPanelRow1.setHorizontalGroup(
539 lyoCtrlPanelRow1.createSequentialGroup()
542 lyoCtrlPanelRow1.setVerticalGroup(lyoCtrlPanelRow1.createParallelGroup()
547 GroupLayout lyoCtrlPanel =
new GroupLayout(
ctrlPanel);
549 lyoCtrlPanel.setAutoCreateGaps(
true);
550 lyoCtrlPanel.setAutoCreateContainerGaps(
true);
551 lyoCtrlPanel.setHorizontalGroup(lyoCtrlPanel.createParallelGroup()
554 lyoCtrlPanel.setVerticalGroup(lyoCtrlPanel.createSequentialGroup()
562 centralPanel.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
565 rightPanel.setOrientation(JSplitPane.VERTICAL_SPLIT);
582 this.add(commandsPane, BorderLayout.SOUTH);
583 JButton btnCanc =
new JButton(
"Close Tab");
584 btnCanc.setToolTipText(
"Closes this GARun Inspector.");
586 commandsPane.
add(btnCanc);
588 JButton btnHelp =
new JButton(
"?");
589 btnHelp.setToolTipText(
"<html>Hover over buttons and fields "
590 +
"to get a tip.<br>"
591 +
"Click the '?' button for further instructions.</html>");
592 btnHelp.addActionListener(
new ActionListener() {
593 public void actionPerformed(ActionEvent e) {
594 String txt =
"<html><body width='%1s'>"
595 +
"<p>Selection of candidates:"
597 +
"<li>Click on a dot in the chart to load the "
599 +
"representation of that candidates.</li>"
600 +
"<li>Click away from any dot to reset the molecular "
605 +
"<li>zoom in: click-and-drag "
606 +
"from the top-left to the bottom-right "
607 +
"corners of the new region of the plot to focus on."
609 +
"<li>Use the <code>Reset Chart View</code> to reset "
611 +
"<li>Right-click to get advanced controls and "
612 +
"options, inclusing exporting the charts as PNG or "
616 JOptionPane.showMessageDialog(btnHelp, String.format(txt, 300),
618 JOptionPane.PLAIN_MESSAGE);
621 commandsPane.
add(btnHelp);
630 @SuppressWarnings(
"serial")
635 super(refForPlacement,
false);
636 this.setTitle(
"Choose Generation");
638 Dimension sizeNameFields =
new Dimension(200,
639 (
int) (
new JTextField()).getPreferredSize().getHeight());
641 JPanel rowOne =
new JPanel(
new FlowLayout(FlowLayout.LEFT));
642 JLabel lblVarName =
new JLabel(
"Generation Number:");
643 JTextField txtVarName =
new JTextField();
644 txtVarName.setPreferredSize(sizeNameFields);
645 rowOne.add(lblVarName);
646 rowOne.add(txtVarName);
648 addToCentralPane(rowOne);
650 this.btnDone.addActionListener(
new ActionListener() {
653 public void actionPerformed(ActionEvent e) {
654 if (txtVarName.getText().equals(
""))
658 result = txtVarName.getText();
663 this.getRootPane().setDefaultButton(this.btnDone);
664 this.btnCanc.addActionListener(
new ActionListener() {
667 public void actionPerformed(ActionEvent e) {
679 if (!file.isDirectory() || !file.exists())
681 JOptionPane.showMessageDialog(parent,
682 "Could not read data from folder '" + file +
"'!",
684 JOptionPane.PLAIN_MESSAGE,
685 UIManager.getIcon(
"OptionPane.errorIcon"));
689 mainPanel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
693 System.out.println(
"Importing data from '" +
srcFolder +
"'...");
696 Map<Integer,double[]> popProperties =
new HashMap<Integer,double[]>();
698 int largestGenId = -1;
699 for (File genFolder : file.listFiles(
new FileFilter() {
702 public boolean accept(File pathname) {
703 if (pathname.getName().startsWith(
"Gen")
704 && pathname.isDirectory())
713 int genId = Integer.parseInt(genFolder.getName().substring(3));
714 int padSize = genFolder.getName().substring(3).length();
717 genId, parent, popProperties);
718 if (genId>largestGenId)
719 largestGenId = genId;
722 System.out.println(
"Imported "+
allIndividuals.size()+
" individuals.");
747 candsWithFitnessData[1][j] = item.
getFitness();
749 datasetAllFit.addSeries(
"Candidates_with_fitness", candsWithFitnessData);
755 int numGen = popProperties.keySet().size();
756 double[][] popMin =
new double[2][numGen];
757 double[][] popMax =
new double[2][numGen];
758 double[][] popMean =
new double[2][numGen];
759 double[][] popMedian =
new double[2][numGen];
760 for (
int i=0; i<numGen; i++)
762 double[] values = popProperties.get(i);
764 popMin[1][i] = values[0];
766 popMax[1][i] = values[1];
768 popMean[1][i] = values[2];
770 popMedian[1][i] = values[3];
782 NumberAxis xAxis =
new NumberAxis(
"Generation");
783 xAxis.setRange(-0.5, numGen-0.5);
784 xAxis.setAutoRangeIncludesZero(
false);
785 NumberAxis yAxis =
new NumberAxis(
"Fitness");
786 yAxis.setAutoRangeIncludesZero(
false);
787 evoPlot =
new XYPlot(
null,xAxis,yAxis,
null);
792 evoChart.getLegend().setPosition(RectangleEdge.BOTTOM);
794 evoPlot.getDomainAxis().setLowerBound(-0.5);
795 evoPlot.setBackgroundPaint(Color.WHITE);
796 evoPlot.setDomainGridlinePaint(Color.LIGHT_GRAY);
797 evoPlot.setRangeGridlinePaint(Color.LIGHT_GRAY);
798 evoPlot.setSeriesRenderingOrder(SeriesRenderingOrder.FORWARD);
806 evoPlot.setDatasetRenderingOrder(DatasetRenderingOrder.REVERSE);
809 Shape shape0 =
new Ellipse2D.Double(
814 XYLineAndShapeRenderer renderer0 =
815 new XYLineAndShapeRenderer(
false,
true);
819 evoPlot.setRenderer(0, renderer0);
820 renderer0.setSeriesShape(0, shape0);
821 renderer0.setSeriesPaint(0, Color.red);
822 renderer0.setSeriesFillPaint(0, Color.red);
823 renderer0.setSeriesOutlinePaint(0, Color.BLACK);
824 renderer0.setUseOutlinePaint(
true);
825 renderer0.setUseFillPaint(
true);
828 Shape shape1 =
new Ellipse2D.Double(
833 XYLineAndShapeRenderer renderer1 =
834 new XYLineAndShapeRenderer(
false,
true);
836 evoPlot.setRenderer(1, renderer1);
837 renderer1.setSeriesShape(0, shape1);
838 renderer1.setSeriesPaint(0,
new Color(192, 192, 192, 60));
839 renderer1.setSeriesFillPaint(0,
new Color(192, 192, 192, 60));
840 renderer1.setSeriesOutlinePaint(0, Color.GRAY);
841 renderer1.setUseOutlinePaint(
true);
842 renderer1.setUseFillPaint(
true);
849 XYLineAndShapeRenderer renderer2 =
850 new XYLineAndShapeRenderer(
true,
false);
852 evoPlot.setRenderer(2, renderer2);
853 renderer2.setSeriesPaint(0, Color.blue);
855 JCheckBoxMenuItem cbmiMin =
new JCheckBoxMenuItem(
856 "Minimum Fitness in Population");
857 cbmiMin.setForeground(Color.blue);
858 cbmiMin.setSelected(
true);
859 cbmiMin.addItemListener(
new ItemListener(){
861 public void itemStateChanged(ItemEvent e)
863 if (cbmiMin.isSelected())
865 renderer2.setSeriesVisible(0,
true);
867 renderer2.setSeriesVisible(0,
false);
874 XYLineAndShapeRenderer renderer3 =
875 new XYLineAndShapeRenderer(
true,
false);
877 evoPlot.setRenderer(3, renderer3);
878 renderer3.setSeriesPaint(0, Color.blue);
880 JCheckBoxMenuItem cbmiMax =
new JCheckBoxMenuItem(
881 "Maximum Fitness in Population");
882 cbmiMax.setForeground(Color.blue);
883 cbmiMax.setSelected(
true);
884 cbmiMax.addItemListener(
new ItemListener(){
886 public void itemStateChanged(ItemEvent e)
888 if (cbmiMax.isSelected())
890 renderer3.setSeriesVisible(0,
true);
892 renderer3.setSeriesVisible(0,
false);
899 XYLineAndShapeRenderer renderer4 =
900 new XYLineAndShapeRenderer(
true,
false);
902 evoPlot.setRenderer(4, renderer4);
903 renderer4.setSeriesPaint(0, Color.red);
904 renderer4.setSeriesStroke(0,
new BasicStroke(
905 2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
906 1.0f,
new float[] {10.0f, 6.0f}, 0.0f));
907 renderer4.setSeriesVisible(0,
false);
908 JCheckBoxMenuItem cbmiMean =
new JCheckBoxMenuItem(
909 "Mean of Fitness in Population");
910 cbmiMean.setForeground(Color.red);
911 cbmiMean.setSelected(
false);
912 cbmiMean.addItemListener(
new ItemListener(){
914 public void itemStateChanged(ItemEvent e)
916 if (cbmiMean.isSelected())
918 renderer4.setSeriesVisible(0,
true);
920 renderer4.setSeriesVisible(0,
false);
927 XYLineAndShapeRenderer renderer5 =
928 new XYLineAndShapeRenderer(
true,
false);
930 evoPlot.setRenderer(5, renderer5);
931 renderer5.setSeriesPaint(0, Color.decode(
"#22BB22"));
932 renderer5.setSeriesStroke(0,
new BasicStroke(
933 2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
934 1.0f,
new float[] {3.0f, 6.0f}, 0.0f));
935 renderer5.setSeriesVisible(0,
false);
936 JCheckBoxMenuItem cbmiMedian =
new JCheckBoxMenuItem(
937 "Median of Fitness in Population");
938 cbmiMedian.setForeground(Color.decode(
"#22BB22"));
939 cbmiMedian.setSelected(
false);
940 cbmiMedian.addItemListener(
new ItemListener(){
942 public void itemStateChanged(ItemEvent e)
944 if (cbmiMedian.isSelected())
946 renderer5.setSeriesVisible(0,
true);
948 renderer5.setSeriesVisible(0,
false);
959 rightUpPanel.addComponentListener(
new ComponentAdapter() {
961 public void componentResized(ComponentEvent e) {
962 evoChartPanel.setMaximumDrawHeight(e.getComponent().getHeight());
963 evoChartPanel.setMaximumDrawWidth(e.getComponent().getWidth());
964 evoChartPanel.setMinimumDrawWidth(e.getComponent().getWidth());
965 evoChartPanel.setMinimumDrawHeight(e.getComponent().getHeight());
970 ChartEditor ce = ChartEditorManager.getChartEditor(
evoChart);
976 XYToolTipGenerator ttg =
new XYToolTipGenerator() {
978 public String generateToolTip(XYDataset data,
int sId,
int itemId)
986 if (overlappingItems.size()>1)
987 return "Overlapping Items";
992 renderer1.setDefaultToolTipGenerator(ttg);
995 evoChartPanel.addChartMouseListener(
new ChartMouseListener() {
998 public void chartMouseMoved(ChartMouseEvent e) {
1003 public void chartMouseClicked(ChartMouseEvent e)
1005 if (e.getEntity() instanceof XYItemEntity)
1007 XYDataset ds = ((XYItemEntity)e.getEntity()).getDataset();
1013 int serId = ((XYItemEntity)e.getEntity()).getSeriesIndex();
1016 int itemId = ((XYItemEntity) e.getEntity()).getItem();
1027 if (choosenItem!=
null)
1032 else if (e.getEntity() instanceof PlotEntity)
1043 mainPanel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1051 Map<Integer,
double[]> popProperties)
1054 File genSummary =
new File(genFolder, summaryName);
1055 System.out.println(
"Reading "+genSummary);
1056 boolean readPopMembers =
false;
1060 readPopMembers =
true;
1062 JOptionPane.showMessageDialog(parent,
1063 "<html>File '" + genSummary +
"' not found!<br>"
1064 +
"There will be holes in the min/max/mean profile."
1067 JOptionPane.PLAIN_MESSAGE,
1068 UIManager.getIcon(
"OptionPane.errorIcon"));
1069 popProperties.put(genId,
new double[] {
1070 Double.NaN, Double.NaN, Double.NaN, Double.NaN});
1074 boolean foundCandidateFilesInThisGen =
false;
1075 for (File fitFile : genFolder.listFiles(
new FileFilter() {
1078 public boolean accept(File pathname) {
1079 if (pathname.getName().endsWith(
1093 e1.printStackTrace();
1094 JOptionPane.showMessageDialog(parent,
1095 "Could not read data from to '" + fitFile +
"'! "
1096 +
NL + e1.getMessage(),
1098 JOptionPane.PLAIN_MESSAGE,
1099 UIManager.getIcon(
"OptionPane.errorIcon"));
1108 foundCandidateFilesInThisGen =
true;
1112 if (!foundCandidateFilesInThisGen)
1116 JOptionPane.showMessageDialog(parent,
1117 String.format(
"<html><body width='%1s'>"
1118 +
"This evolutionary experiment seems to "
1119 +
"have been run with the "
1120 +
"'FP-DontWriteCandidatesOnDisk' option. "
1121 +
"Therefore, the definition of candidates "
1122 +
"encountered during the evolution is not "
1123 +
"present on disk. "
1124 +
"We'll show only how the trace of such "
1125 +
"candidates in the evolution. You may try "
1126 +
"to inspect the final generation, "
1127 +
"if present, by clicking on '"
1131 JOptionPane.WARNING_MESSAGE,
1132 UIManager.getIcon(
"OptionPane.errorIcon"));
1135 readPopMembers =
false;
1156 cand.setGeneration(genId);
1164 e1.printStackTrace();
1173 List<String> membersPathnames =
new ArrayList<String>(
1178 e1.printStackTrace();
1179 JOptionPane.showMessageDialog(parent,
1180 String.format(
"<html><body width='%1s'>"
1181 +
"File '" + genSummary +
"' has been found, "
1182 +
"but pathnames to population members could "
1183 +
"not be read.</html>", 400),
1185 JOptionPane.PLAIN_MESSAGE,
1186 UIManager.getIcon(
"OptionPane.errorIcon"));
1247 File eaMonitorDumps =
new File(runFolder +
".eaMonitor");
1248 if (!eaMonitorDumps.exists())
1254 ArrayList<String> lines =
null;
1260 e1.printStackTrace();
1270 String[] words = lines.get(0).trim().split(
"\\s+");
1271 String[] headers = IntStream.range(3, words.length)
1272 .mapToObj(i -> words[i])
1273 .toArray(String[]::new);
1276 List<double[][]> xyData =
new ArrayList<double[][]>();
1277 for (
int iSeries=0; iSeries<headers.length; iSeries++)
1278 xyData.add(
new double[2][lines.size()-1]);
1280 int iRecordsKept = -1;
1281 for (
int iRecordr=1; iRecordr<lines.size(); iRecordr++)
1283 String line = lines.get(iRecordr).trim();
1286 if (!line.startsWith(
"SUMMARY"))
1290 String[] values = line.split(
"\\s+");
1291 for (
int iSeries=3; iSeries<values.length; iSeries++)
1293 xyData.get(iSeries-3)[0][iRecordsKept] =
1294 Double.valueOf(values[2]);
1295 xyData.get(iSeries-3)[1][iRecordsKept] =
1296 Double.valueOf(values[iSeries]);
1302 NumberAxis xAxis =
new NumberAxis(
"Generation");
1304 xAxis.setRange(-0.5, Double.valueOf(iRecordsKept)-0.5);
1305 xAxis.setAutoRangeIncludesZero(
false);
1308 NumberAxis yAxis =
new NumberAxis(
"#");
1309 yAxis.setAutoRangeIncludesZero(
false);
1313 monitorChart =
new JFreeChart(
null, JFreeChart.DEFAULT_TITLE_FONT,
1316 monitorChart.getLegend().setPosition(RectangleEdge.BOTTOM);
1320 monitorPlot.setDomainGridlinePaint(Color.LIGHT_GRAY);
1321 monitorPlot.setRangeGridlinePaint(Color.LIGHT_GRAY);
1326 XYLineAndShapeRenderer renderer0 =
1327 new XYLineAndShapeRenderer(
false,
true);
1328 monitorPlot.setDataset(0,
new DefaultXYDataset());
1333 for (
int iSeries=0; iSeries<headers.length; iSeries++)
1335 DefaultXYDataset dataset =
new DefaultXYDataset();
1336 dataset.addSeries(headers[iSeries], xyData.get(iSeries));
1339 XYLineAndShapeRenderer serierRenderer =
1340 new XYLineAndShapeRenderer(
true,
false);
1344 serierRenderer.setSeriesPaint(0,
colors[iColor]);
1345 serierRenderer.setSeriesStroke(0,
strokes[iStroke]);
1348 JCheckBox cbi =
new JCheckBox(
1350 cbi.setForeground(
colors[iColor]);
1351 cbi.setToolTipText(String.format(
"<html><body width='%1s'>"
1353 +
".</html>", 300));
1358 serierRenderer.setSeriesVisible(0,
false);
1361 cbi.setSelected(
true);
1364 cbi.addItemListener(
new ItemListener(){
1366 public void itemStateChanged(ItemEvent e)
1368 if (cbi.isSelected())
1370 serierRenderer.setSeriesVisible(0,
true);
1372 serierRenderer.setSeriesVisible(0,
false);
1380 if (iColor >=
colors.length)
1383 if (iStroke <
strokes.length-1)
1398 public void componentResized(ComponentEvent e) {
1407 ChartEditor ce = ChartEditorManager.getChartEditor(
monitorChart);
1421 double toleranceY = Math.abs(
evoPlot.getRangeAxis()
1422 .getRange().getLength() * 0.02);
1424 double toleranceX = Math.abs(
evoPlot.getDomainAxis()
1425 .getRange().getLength() * 0.01);
1427 List<CandidateLW> overlappingItems =
1428 new ArrayList<CandidateLW>();
1429 while (nItems<maxNeighbours &&
1440 if (deltaY > toleranceY)
1444 if (deltaX > toleranceX)
1446 overlappingItems.add(c);
1450 while (nItems<maxNeighbours && (initPos-nItems)>-1)
1460 if (deltaY > toleranceY)
1464 if (deltaX > toleranceX)
1466 overlappingItems.add(0,c);
1469 return overlappingItems;
1475 List<CandidateLW> overlappingItems)
1477 switch (overlappingItems.size())
1482 return overlappingItems.get(0);
1485 DefaultListModel<String> listModel =
new DefaultListModel<String>();
1486 JList<String> optionsList =
new JList<String>(listModel);
1487 overlappingItems.stream().forEach(c -> listModel.addElement(c.getName()));
1488 optionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
1490 JPanel chooseItem =
new JPanel();
1491 JLabel header =
new JLabel(
"Select item to visualize:");
1492 JScrollPane scrollPane =
new JScrollPane(optionsList);
1493 chooseItem.add(header);
1494 chooseItem.add(scrollPane);
1496 int res = JOptionPane.showConfirmDialog(parent,
1498 "Choose Among Overlapping Items",
1499 JOptionPane.OK_CANCEL_OPTION,
1500 JOptionPane.PLAIN_MESSAGE,
1502 if (res != JOptionPane.OK_OPTION)
1506 return overlappingItems.get(optionsList.getSelectedIndex());
1533 mainPanel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1535 double[][] selectedCandsData =
new double[2][1];
1537 for (
int i=0; i<1; i++)
1553 mainPanel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
General set of constants used in DENOPTIM.
static final String FITFILENAMEEXTOUT
Ending and extension of output file of external fitness provider.
static void mergeIntoOneFile(String destinationPathname, List< String > sourcePathnames)
Copies the content of all the files specified in the list of sources and places it into the destinati...
A light-weight candidate is a very low-demanding collection of data upon a specific candidate item.
void setGeneration(int genId)
Remove the card from the deck of cards and takes care of removing also the entry in the list of activ...
Class of GUI panels meant to occupy one card in the deck-of-cards layout of the main panel.
GUIMainPanel mainPanel
The main panel (cards deck)
A panel that understands DENOPTIM graphs and allows to create and edit them.
void importGraphsFromFile(File file)
Imports graphs from file.
Modal dialog that asks the user for a generation number.
GenerationChoiceDialog(Component refForPlacement)
int compare(CandidateLW c1, CandidateLW c2)
A panel that allows to inspect the output of an artificial evolution experiment.
static final long serialVersionUID
Version UID.
final BasicStroke[] strokes
Predefined line strokes.
DefaultXYDataset datasetAllFit
void renderViewWithoutSelectedItems()
Map< CounterID, DefaultXYDataset > monitorDatasets
void readOneGeneration(File genFolder, String summaryName, int genId, Component parent, Map< Integer, double[]> popProperties)
DefaultXYDataset datasetPopMedian
boolean warnedAboutMissingCandFiles
void buildAndFillMonitorPlot(File runFolder, JComponent parent)
Modal dialog to display visual examples of line colors and strokes.
DefaultXYDataset datasetPopMean
void renderViewWithSelectedItem(CandidateLW item)
Map< Integer, List< String > > candsPerGeneration
Pathways of population members collected by generation id.
DefaultXYDataset datasetSelected
DefaultXYDataset datasetPopMin
ChartPanel monitorChartPanel
String nameFirstMonitorSeries
Records the name of the first series in the monitor plot to facilitate its recovery upon chart reset.
List< CandidateLW > getOverlappingItems(CandidateLW item, int maxNeighbours)
ArrayList< CandidateLW > allIndividuals
void importGARunData(File file, JComponent parent)
MoleculeViewPanel molViewer
static AtomicInteger evolInspectorTabUID
Unique identified for instances of this handler.
JPanel ctrlPanelRow1Right
JPopupMenu evoSeriesCheckList
JButton openGeneratinGraphs
Button offering the possibility to load the graphs of the population at a given time (i....
ScrollableJPupupMenu monitorSeriesCheckList
JButton openFinalPopGraphs
Button offering the possibility to load the graphs of the final population.
Map< Integer, CandidateLW > candsWithFitnessMap
void initialize()
Initialize the panel and add buttons.
DefaultXYDataset datasetPopMax
JButton openSingleGraph
Button offering the possibility to load the graph inspector for a selected item.
final Color[] colors
Predefined list of data series colors.
GUIInspectGARun(GUIMainPanel mainPanel)
Constructor.
String pathToSelectedItem
Storage of pathname to the item selected in the chart.
CandidateLW choseAmongPossiblyOverlapping(JComponent parent, List< CandidateLW > overlappingItems)
The main panel is a deck of cards that occupies all the GUI frame.
Component add(Component comp)
Add a component and a reference to such component in the main tool bar.
Object showDialog()
Shows the dialog and restrains the modality to it, until the dialog gets closed.
The collection of tunable preferences.
static boolean showLegenInMonitorPlot
Choice of displaying legend in monitor plot.
static boolean showLegenInEvolutionPlot
Choice of displaying legend in evolution plot.
static int chartPointSize
Evolutionary Inspector: size of points.
A panel with a molecular viewer and data table.
void clearAll(boolean dataIsComing)
Removes the currently visualized molecule and AP table.
void loadChemicalStructureFromFile(String pathName)
Loads a structure in the Jmol viewer.
static String getTempFile(String tmpFileName)
Returns the pathname to a tmp file.
Utility methods for input/output.
static List< String > readPopulationMemberPathnames(File file)
Read the pathnames to the population members from a FileFormat#GENSUMMARY file.
static double[] readPopulationProps(File file)
Read the min, max, mean, and median of a population from FileFormat#GENSUMMARY file.
static List< CandidateLW > readLightWeightCandidate(File file)
Read only selected data from a GA produced items.
static ArrayList< String > readList(String fileName)
Read list of data as text.
static List< CandidateLW > readPopulationMembersTraces(File file)
Read the minimal info that can be found in a FileFormat#GENSUMMARY file about the members of a popula...
static String getPaddedString(int count, int number)
returns the padded string with zeroes placed to the left of 'number' up to reach the desired number o...
String getPrettyName()
Returns a string representing the mane of this counter in a way that is pretty enough to be shown in ...