package uk.ac.rhul.cs.cl1.io;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.List;
import uk.ac.rhul.cs.cl1.quality.DummyQualityFunction;
import uk.ac.rhul.cs.cl1.NodeSet;
import uk.ac.rhul.cs.cl1.quality.QualityFunction;
import uk.ac.rhul.cs.utils.StringUtils;
/**
* Writes a clustering to a stream in CSV format.
*
* The table will contain some basic statistics about the clusters such as
* their size, density, internal and boundary weight etc.
*
* @author ntamas
*/
public class CSVClusteringWriter extends AbstractClusteringWriter {
private String columnSep;
private String doubleQuoteChar;
private String quoteChar;
private String quoteTriggers;
private QualityFunction qualityFunction = null;
public CSVClusteringWriter() {
this(",", "\"");
}
public CSVClusteringWriter(String columnSep, String quoteChar) {
super();
this.setColumnSeparator(columnSep);
this.setQuoteChar(quoteChar);
this.setQualityFunction(null);
}
public void setColumnSeparator(String columnSep) {
this.columnSep = columnSep;
this.quoteTriggers = " " + this.columnSep + this.quoteChar;
}
public void setQualityFunction(QualityFunction qualityFunction) {
if (qualityFunction == null)
qualityFunction = new DummyQualityFunction();
this.qualityFunction = qualityFunction;
}
public void setQuoteChar(String quoteChar) {
this.quoteChar = quoteChar;
this.quoteTriggers = " " + this.columnSep + this.quoteChar;
this.doubleQuoteChar = this.quoteChar + this.quoteChar;
}
public void writeClustering(List<? extends NodeSet> clustering,
OutputStream stream) throws IOException {
PrintWriter wr = new PrintWriter(stream);
String[] parts = {
"Cluster", "Size", "Density", "Internal weight",
"Boundary weight", "Quality", "P-value", "Members"
};
int clusterIndex = 0;
wr.println(StringUtils.join(parts, columnSep));
for (NodeSet nodeSet: clustering) {
clusterIndex++;
parts[0] = Integer.toString(clusterIndex);
parts[1] = Integer.toString(nodeSet.size());
parts[2] = quote(String.format("%.4g", nodeSet.getDensity()));
parts[3] = quote(String.format("%.4g", nodeSet.getTotalInternalEdgeWeight()));
parts[4] = quote(String.format("%.4g", nodeSet.getTotalBoundaryEdgeWeight()));
parts[5] = quote(String.format("%.4g", qualityFunction.calculate(nodeSet)));
parts[6] = quote(String.format("%g", nodeSet.getSignificance()));
parts[7] = quote(nodeSet.toString(" "));
wr.println(StringUtils.join(parts, columnSep));
}
wr.flush();
}
private String quote(String str) {
if (!StringUtils.containsAny(str, quoteTriggers))
return str;
return quoteChar + str.replace(quoteChar, doubleQuoteChar) + quoteChar;
}
}