--- /dev/null
+package jalview.ext.forester;
+
+import jalview.datamodel.SequenceI;
+import jalview.math.MatrixI;
+import jalview.util.MessageManager;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.NoSuchElementException;
+import java.util.stream.IntStream;
+
+import org.forester.evoinference.matrix.distance.DistanceMatrix;
+import org.forester.util.ForesterUtil;
+import org.forester.util.IllegalFormatUseException;
+
+public class ForesterMatrix implements DistanceMatrix
+{
+ private final static NumberFormat PHYLIP_FORMATTER = new DecimalFormat(
+ "0.000000"); // straight from forester
+
+ private final MatrixI jalviewMatrix;
+
+ private final String[] identifiers;
+
+ public ForesterMatrix(final MatrixI jalviewInputMatrix,
+ final SequenceI[] matrixSequences)
+ {
+ this.jalviewMatrix = jalviewInputMatrix;
+ this.identifiers = new String[matrixSequences.length];
+
+ int i = 0;
+ for (SequenceI sequence : matrixSequences)
+ {
+ identifiers[i] = sequence.getName();
+ i++;
+ }
+
+ }
+
+ public ForesterMatrix(final MatrixI jalviewInputMatrix,
+ final String[] matrixIdentifiers)
+ {
+ this.jalviewMatrix = jalviewInputMatrix;
+ this.identifiers = matrixIdentifiers;
+
+ }
+
+ @Override
+ public String getIdentifier(final int i)
+ {
+ return identifiers[i]; // add handling if index is out of bounds
+ }
+
+
+ @Override
+ public int getIndex(final String identifier)
+ {
+ try {
+ return IntStream.range(0, identifiers.length)
+ .filter(x -> identifier.equals(identifiers[x])).findAny()
+ .getAsInt(); // stream to bypass otherwise having to duplicate the
+ // list
+ // with Arrays.aslist
+ }
+ catch (NoSuchElementException ex) {
+ throw new Error(MessageManager.formatMessage(
+ "exception.invalid_matrix_identifier", new String[]
+ { identifier }));
+ }
+ }
+
+ /**
+ * Returns the length of whichever is longest, columns or rows
+ */
+ @Override
+ public int getSize()
+ {
+ return jalviewMatrix.getValues().length;
+ }
+
+ /**
+ * See {@link MatrixI#getValue(int,int)} except that the order of column, row
+ * in the parameters is inverted here (as that is how forester demands it)
+ */
+ @Override
+ public double getValue(final int col, final int row)
+ {
+ return jalviewMatrix.getValue(row, col);
+ }
+
+ @Override
+ public void setIdentifier(final int i, final String identifier)
+ {
+ identifiers[i] = identifier;
+
+ }
+
+ /**
+ * See {@link MatrixI#setValue()} except that the order of column, row in the
+ * parameters is inverted here (as that is how forester demands it)
+ */
+ @Override
+ public void setValue(final int col, final int row, final double distance)
+ {
+ jalviewMatrix.setValue(row, col, distance);
+
+ }
+
+ @Override
+ public StringBuffer toStringBuffer(Format format)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * See {@link MatrixI#getValues()}
+ */
+ @Override
+ public double[][] getValues()
+ {
+ return jalviewMatrix.getValues();
+ }
+
+ @Override
+ public void write(final Writer w) throws IOException // directly copied from
+ // forester
+ {
+ w.write(" ");
+ w.write(getSize() + "");
+ w.write(ForesterUtil.LINE_SEPARATOR);
+ for (int row = 0; row < getSize(); ++row)
+ {
+ if (!ForesterUtil.isEmpty(getIdentifier(row)))
+ {
+ w.write(ForesterUtil.pad(getIdentifier(row), 10, ' ', false)
+ .toString());
+ w.write(' ');
+ w.write(' ');
+ }
+ else
+ {
+ throw new IllegalFormatUseException(
+ "Phylip format does not allow empty identifiers");
+ }
+ for (int col = 0; col < getSize(); ++col)
+ {
+ w.write(PHYLIP_FORMATTER.format(getValue(col, row)));
+ if (col < (getSize() - 1))
+ {
+ w.write(' ');
+ w.write(' ');
+ }
+ }
+ if (row < (getSize() - 1))
+ {
+ w.write(ForesterUtil.LINE_SEPARATOR);
+ }
+ }
+
+ }
+
+ public static DistanceMatrix convertJalviewToForester(
+ final MatrixI jalviewInputMatrix,
+ final SequenceI[] matrixSequences)
+ {
+ return DataConversions.createForesterDistanceMatrix(
+ jalviewInputMatrix, matrixSequences);
+
+ }
+
+ public static DistanceMatrix convertJalviewToForester(
+ final MatrixI jalviewInputMatrix,
+ final String[] matrixIdentifiers)
+ {
+ return DataConversions.createForesterDistanceMatrix(
+ jalviewInputMatrix, matrixIdentifiers);
+
+ }
+
+
+}
\ No newline at end of file