Merge branch 'kjvdh/features/PhylogenyViewer_tabbedsupport' into merge/2_11_2/kjvdh...
[jalview.git] / src / jalview / ext / forester / ForesterMatrix.java
diff --git a/src/jalview/ext/forester/ForesterMatrix.java b/src/jalview/ext/forester/ForesterMatrix.java
new file mode 100644 (file)
index 0000000..a12dc1d
--- /dev/null
@@ -0,0 +1,184 @@
+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