/*
* Copyright (C) 2015 Daniel Dietsch (dietsch@informatik.uni-freiburg.de)
* Copyright (C) 2015 University of Freiburg
*
* This file is part of the ULTIMATE Test Library.
*
* The ULTIMATE Test Library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ULTIMATE Test Library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the ULTIMATE Test Library. If not, see .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify the ULTIMATE Test Library, or any covered work, by linking
* or combining it with Eclipse RCP (or a modified version of Eclipse RCP),
* containing parts covered by the terms of the Eclipse Public License, the
* licensors of the ULTIMATE Test Library grant you additional permission
* to convey the resulting work.
*/
package de.uni_freiburg.informatik.ultimate.test.logs.summaries;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import de.uni_freiburg.informatik.ultimate.test.UltimateTestSuite;
import de.uni_freiburg.informatik.ultimate.util.CoreUtil;
import de.uni_freiburg.informatik.ultimate.util.csv.ICsvProviderProvider;
/**
*
* Note: This summary is work in progress and not complete! Do not use it until this message vanishes.
*
* @author Daniel Dietsch (dietsch@informatik.uni-freiburg.de)
*
*/
public class LatexPlotSummary extends LatexSummary {
private final int mLatexTableHeaderCount;
public LatexPlotSummary(final Class extends UltimateTestSuite> ultimateTestSuite,
final Collection>> benchmarks,
final ColumnDefinition[] columnDefinitions) {
super(ultimateTestSuite, benchmarks, columnDefinitions);
mLatexTableHeaderCount = (int) mColumnDefinitions.stream().filter(a -> a.getLatexColumnTitle() != null).count();
}
@Override
public String getLog() {
final StringBuilder sb = new StringBuilder();
final PartitionedResults results = partitionResults(mResults.entrySet());
makeTables(sb, results);
return sb.toString();
}
@Override
public String getFilenameExtension() {
return ".tex";
}
private void makeTables(final StringBuilder sb, final PartitionedResults results) {
final Set tools =
CoreUtil.selectDistinct(results.All, entry -> entry.getKey().getToolchain().getName());
final String br = CoreUtil.getPlatformLineSeparator();
appendPreamble(sb, br);
// appendLatexFigureBegin(sb, br);
// for funName, filesAndNames in latexFigures:
// sortedByName = sorted(filesAndNames, key=lambda x : x[1])
// f.write('\\resizebox*{0.45\\textwidth}{!}{%\n')
// appendLatexFigure(sb, 'x', 'y', sortedByName, namesAndStylesDict, funName)
// f.write('}\n')
// appendLatexFigureEnd(sb, br,name);
for (final String tool : tools) {
// make table header
sb.append("\\begin{longtabu} to \\linewidth {lcllc");
for (int i = 0; i < mLatexTableHeaderCount; ++i) {
sb.append("r");
}
sb.append("}").append(br);
sb.append("\\toprule").append(br);
sb.append(" \\header{}& ").append(br);
sb.append(" \\header{\\#}&").append(br);
sb.append(" \\header{Result}&").append(br);
sb.append(" \\header{Variant}& ").append(br);
sb.append(" \\header{Count}&").append(br);
int i = 0;
for (final ColumnDefinition cd : mColumnDefinitions) {
if (cd.getLatexColumnTitle() == null) {
continue;
}
sb.append(" \\header{");
sb.append(removeInvalidCharsForLatex(cd.getLatexColumnTitle()));
sb.append("}");
i++;
if (i < mLatexTableHeaderCount) {
sb.append("&");
} else {
sb.append("\\\\");
}
sb.append(br);
}
sb.append(" \\cmidrule(r){2-");
sb.append(5 + mLatexTableHeaderCount);
sb.append("}").append(br);
// make table body
final PartitionedResults resultsPerTool = partitionResults(
CoreUtil.where(results.All, entry -> entry.getKey().getToolchain().getName().equals(tool)));
// end table
sb.append("\\caption{Results for ").append(removeInvalidCharsForLatex(tool)).append(".}").append(br);
sb.append("\\end{longtabu}").append(br);
}
// append finishing code
appendEnd(sb, br);
}
// private void appendLatexFigureBegin(StringBuilder sb, String br) {
// sb.append("\\onecolumn").append(br);
// sb.append("\\begin{figure}").append(br);
// sb.append("\\centering").append(br);
// sb.append(" \\begin{tikzpicture}").append(br);
// sb.append(" \\begin{customlegend}[legend columns=' + str(len(namesAndStyles) / 2) + ',legend
// style={align=left,draw=none,column sep=2ex,thick},").append(br);
// sb.append(" legend entries={' + legendentriesstr + '}]").append(br);
// for name, (file, style) in namesAndStyles:
// sb.append(" \\addlegendimage{' + style + '}").append(br);
// sb.append(" \\end{customlegend}").append(br);
// sb.append(" \\end{tikzpicture}").append(br);
//
// }
private void appendEnd(final StringBuilder sb, final String br) {
sb.append("\\end{document}").append(br);
}
private void appendPreamble(final StringBuilder sb, final String br) {
// append preamble
sb.append("\\documentclass{article}").append(br);
sb.append("\\usepackage[table,dvipsnames]{xcolor}").append(br);
sb.append("\\usepackage[utf8]{inputenc}").append(br);
sb.append("\\usepackage{pgfplots}").append(br);
sb.append("\\usepackage{pgfkeys}").append(br);
sb.append("\\usepackage{xspace}").append(br);
sb.append(br);
// table commands
sb.append("\\newcommand{\\headcolor}{}").append(br);
sb.append("\\newcommand{\\header}[1]{\\parbox{2.8em}{\\centering #1}\\headcolor}").append(br);
sb.append("\\newcommand{\\folder}[1]{\\parbox{5em}{#1}}").append(br);
// commands for plots
sb.append("% argument #1: any options").append(br);
sb.append("\\newenvironment{customlegend}[1][]{%").append(br);
sb.append(" \\begingroup").append(br);
sb.append(" % inits/clears the lists (which might be populated from previous").append(br);
sb.append(" % axes):").append(br);
sb.append(" \\csname pgfplots@init@cleared@structures\\endcsname").append(br);
sb.append(" \\pgfplotsset{#1}%").append(br);
sb.append("}{%").append(br);
sb.append(" % draws the legend:").append(br);
sb.append(" \\csname pgfplots@createlegend\\endcsname").append(br);
sb.append(" \\endgroup").append(br);
sb.append("}%").append(br);
sb.append(br);
sb.append("% makes \\addlegendimage available (typically only available within an").append(br);
sb.append("% axis environment):").append(br);
sb.append("\\def\\addlegendimage{\\csname pgfplots@addlegendimage\\endcsname}").append(br);
sb.append(br);
sb.append("\\pgfplotsset{every axis/.append style={thick}}").append(br);
sb.append(br);
sb.append("\\definecolor{s1}{RGB}{228,26,28}").append(br);
sb.append("\\definecolor{s2}{RGB}{55,126,184}").append(br);
sb.append("\\definecolor{s3}{RGB}{77,175,74}").append(br);
sb.append("\\definecolor{s4}{RGB}{152,78,163}").append(br);
sb.append("\\definecolor{s5}{RGB}{255,127,0}").append(br);
sb.append("\\definecolor{s6}{RGB}{255,255,51}").append(br);
sb.append("\\definecolor{s7}{RGB}{166,86,40}").append(br);
sb.append("\\definecolor{s8}{RGB}{247,129,191}").append(br);
sb.append("\\definecolor{s9}{RGB}{153,153,153}").append(br);
sb.append("\\pgfplotsset{").append(br);
sb.append(" mark repeat/.style={").append(br);
sb.append(" scatter,").append(br);
sb.append(" scatter src=x,").append(br);
sb.append(" scatter/@pre marker code/.code={").append(br);
sb.append(" \\pgfmathtruncatemacro\\usemark{").append(br);
sb.append(" or(mod(\\coordindex,#1)==0, (\\coordindex==(\\numcoords-1))").append(br);
sb.append(" }").append(br);
sb.append(" \\ifnum\\usemark=0").append(br);
sb.append(" \\pgfplotsset{mark=none}").append(br);
sb.append(" \\fi").append(br);
sb.append(" },").append(br);
sb.append(" scatter/@post marker code/.code={}").append(br);
sb.append(" }").append(br);
sb.append("}").append(br);
sb.append("\\pgfplotsset{cycle list={%").append(br);
for (final String style : getLatexPlotStyles()) {
sb.append("{").append(style).append("},").append(br);
}
sb.append("}}").append(br);
sb.append(br);
sb.append("\\begin{document}").append(br);
}
private List getLatexPlotStyles() {
// plotstylesLines = zip(mLatexColors, mLatexPlotLines)
// plotstylesMarks = zip(mLatexColors[len(mLatexPlotLines):], mLatexPlotMarks)
// acc = []
// for color, linestyle in plotstylesLines:
// acc.append('draw=' + color + ',' + linestyle)
// for color, markstyle in plotstylesMarks:
// acc.append('mark repeat={' + str(mLatexPlotMarkRepeat) + '},draw=' + color + ',solid,mark=' + markstyle)
// for color in mLatexColors[len(plotstylesLines) + len(plotstylesMarks):]:
// acc.append('draw=' + color + ',solid')
// return acc
final List rtr = new ArrayList<>();
return rtr;
}
private static final class PlotStyleProvider {
// # Those are the presets s1 to s9 and all the remaining dvips colors of xcolor
private static final String[] LATEX_COLORS = new String[] { "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8",
"s9", "Black", "OliveGreen", "Apricot", "Aquamarine", "Bittersweet", "Blue", "BlueGreen", "BlueViolet",
"BrickRed", "Brown", "BurntOrange", "CadetBlue", "CarnationPink", "Cerulean", "CornflowerBlue", "Cyan",
"Dandelion", "DarkOrchid", "Emerald", "ForestGreen", "Fuchsia", "Goldenrod", "Gray", "Green",
"GreenYellow", "JungleGreen", "Lavender", "LimeGreen", "Magenta", "Mahogany", "Maroon", "Melon",
"MidnightBlue", "Mulberry", "NavyBlue", "Orange", "OrangeRed", "Orchid", "Peach", "Periwinkle",
"PineGreen", "Plum", "ProcessBlue", "Purple", "RawSienna", "Red", "RedOrange", "RedViolet", "Rhodamine",
"RoyalBlue", "RoyalPurple", "RubineRed", "Salmon", "SeaGreen", "Sepia", "SkyBlue", "SpringGreen", "Tan",
"TealBlue", "Thistle", "Turquoise", "Violet", "VioletRed", "White", "WildStrawberry", "Yellow",
"YellowGreen", "YellowOrange" };
private static final String[] LATEX_MARKS =
new String[] { null, "star", "triangle", "diamond", "x", "|", "10-pointed-star", "pentagon", "o" };
private static final String[] LATEX_LINES = new String[] { "solid", "dotted", "dashed" };
private static final int LATEX_PLOT_MARK_REPEAT = 10;
private final String mColor;
private final String mLinestyle;
private final String mMarkstyle;
private PlotStyleProvider(final String color, final String linestyle, final String markstyle) {
mColor = color;
mLinestyle = linestyle;
mMarkstyle = markstyle;
}
private static List getPlotStyles(final int totalStyles) {
final List rtr = new ArrayList<>();
int color = 0;
int line = 0;
int mark = 0;
while (rtr.size() < totalStyles) {
rtr.add(new PlotStyleProvider(LATEX_COLORS[color], LATEX_LINES[line], LATEX_MARKS[mark]));
color = (color + 1) % LATEX_COLORS.length;
if (mark == 0) {
line = (line + 1) % LATEX_LINES.length;
}
if (line == 0) {
mark = (mark + 1) % LATEX_MARKS.length;
}
}
return rtr;
}
private String getMarkstyle() {
return mMarkstyle;
}
private String getLinestyle() {
return mLinestyle;
}
private String getColor() {
return mColor;
}
private String getMarkRepeat() {
return String.valueOf(LATEX_PLOT_MARK_REPEAT);
}
}
}