1 package jalview.ext.forester;
3 import jalview.datamodel.SequenceI;
4 import jalview.math.MatrixI;
5 import jalview.util.MessageManager;
7 import java.io.IOException;
9 import java.text.DecimalFormat;
10 import java.text.NumberFormat;
11 import java.util.NoSuchElementException;
12 import java.util.stream.IntStream;
14 import org.forester.evoinference.matrix.distance.DistanceMatrix;
15 import org.forester.util.ForesterUtil;
16 import org.forester.util.IllegalFormatUseException;
18 public class ForesterMatrix implements DistanceMatrix
20 private final static NumberFormat PHYLIP_FORMATTER = new DecimalFormat(
21 "0.000000"); // straight from forester
23 private final MatrixI jalviewMatrix;
25 private final String[] identifiers;
27 public ForesterMatrix(final MatrixI jalviewInputMatrix,
28 final SequenceI[] matrixSequences)
30 this.jalviewMatrix = jalviewInputMatrix;
31 this.identifiers = new String[matrixSequences.length];
34 for (SequenceI sequence : matrixSequences)
36 identifiers[i] = sequence.getName();
42 public ForesterMatrix(final MatrixI jalviewInputMatrix,
43 final String[] matrixIdentifiers)
45 this.jalviewMatrix = jalviewInputMatrix;
46 this.identifiers = matrixIdentifiers;
51 public String getIdentifier(final int i)
53 return identifiers[i]; // add handling if index is out of bounds
58 public int getIndex(final String identifier)
61 return IntStream.range(0, identifiers.length)
62 .filter(x -> identifier.equals(identifiers[x])).findAny()
63 .getAsInt(); // stream to bypass otherwise having to duplicate the
67 catch (NoSuchElementException ex) {
68 throw new Error(MessageManager.formatMessage(
69 "exception.invalid_matrix_identifier", new String[]
75 * Returns the length of whichever is longest, columns or rows
80 return jalviewMatrix.getValues().length;
84 * See {@link MatrixI#getValue(int,int)} except that the order of column, row
85 * in the parameters is inverted here (as that is how forester demands it)
88 public double getValue(final int col, final int row)
90 return jalviewMatrix.getValue(row, col);
94 public void setIdentifier(final int i, final String identifier)
96 identifiers[i] = identifier;
101 * See {@link MatrixI#setValue()} except that the order of column, row in the
102 * parameters is inverted here (as that is how forester demands it)
105 public void setValue(final int col, final int row, final double distance)
107 jalviewMatrix.setValue(row, col, distance);
112 public StringBuffer toStringBuffer(Format format)
114 // TODO Auto-generated method stub
119 * See {@link MatrixI#getValues()}
122 public double[][] getValues()
124 return jalviewMatrix.getValues();
128 public void write(final Writer w) throws IOException // directly copied from
132 w.write(getSize() + "");
133 w.write(ForesterUtil.LINE_SEPARATOR);
134 for (int row = 0; row < getSize(); ++row)
136 if (!ForesterUtil.isEmpty(getIdentifier(row)))
138 w.write(ForesterUtil.pad(getIdentifier(row), 10, ' ', false)
145 throw new IllegalFormatUseException(
146 "Phylip format does not allow empty identifiers");
148 for (int col = 0; col < getSize(); ++col)
150 w.write(PHYLIP_FORMATTER.format(getValue(col, row)));
151 if (col < (getSize() - 1))
157 if (row < (getSize() - 1))
159 w.write(ForesterUtil.LINE_SEPARATOR);
165 public static DistanceMatrix convertJalviewToForester(
166 final MatrixI jalviewInputMatrix,
167 final SequenceI[] matrixSequences)
169 return DataConversions.createForesterDistanceMatrix(
170 jalviewInputMatrix, matrixSequences);
174 public static DistanceMatrix convertJalviewToForester(
175 final MatrixI jalviewInputMatrix,
176 final String[] matrixIdentifiers)
178 return DataConversions.createForesterDistanceMatrix(
179 jalviewInputMatrix, matrixIdentifiers);