1 package jalview.ext.forester;
3 import jalview.datamodel.SequenceI;
4 import jalview.ext.archaeopteryx.DataConversions;
5 import jalview.math.MatrixI;
6 import jalview.util.MessageManager;
8 import java.io.IOException;
10 import java.text.DecimalFormat;
11 import java.text.NumberFormat;
12 import java.util.NoSuchElementException;
13 import java.util.stream.IntStream;
15 import org.forester.evoinference.matrix.distance.DistanceMatrix;
16 import org.forester.util.ForesterUtil;
17 import org.forester.util.IllegalFormatUseException;
19 public class ForesterMatrix implements DistanceMatrix
21 private final static NumberFormat PHYLIP_FORMATTER = new DecimalFormat(
22 "0.000000"); // straight from forester
24 private final MatrixI jalviewMatrix;
26 private final String[] identifiers;
28 public ForesterMatrix(final MatrixI jalviewInputMatrix,
29 final SequenceI[] matrixSequences)
31 this.jalviewMatrix = jalviewInputMatrix;
32 this.identifiers = new String[matrixSequences.length];
35 for (SequenceI sequence : matrixSequences)
37 identifiers[i] = sequence.getName();
43 public ForesterMatrix(final MatrixI jalviewInputMatrix,
44 final String[] matrixIdentifiers)
46 this.jalviewMatrix = jalviewInputMatrix;
47 this.identifiers = matrixIdentifiers;
52 public String getIdentifier(final int i)
54 return identifiers[i]; // add handling if index is out of bounds
59 public int getIndex(final String identifier)
62 return IntStream.range(0, identifiers.length)
63 .filter(x -> identifier.equals(identifiers[x])).findAny()
64 .getAsInt(); // stream to bypass otherwise having to duplicate the
68 catch (NoSuchElementException ex) {
69 throw new Error(MessageManager.formatMessage(
70 "exception.invalid_matrix_identifier", new String[]
76 * Returns the length of whichever is longest, columns or rows
81 return jalviewMatrix.getValues().length;
85 * See {@link MatrixI#getValue(int,int)} except that the order of column, row
86 * in the parameters is inverted here (as that is how forester demands it)
89 public double getValue(final int col, final int row)
91 return jalviewMatrix.getValue(row, col);
95 public void setIdentifier(final int i, final String identifier)
97 identifiers[i] = identifier;
102 * See {@link MatrixI#setValue()} except that the order of column, row in the
103 * parameters is inverted here (as that is how forester demands it)
106 public void setValue(final int col, final int row, final double distance)
108 jalviewMatrix.setValue(row, col, distance);
113 public StringBuffer toStringBuffer(Format format)
115 // TODO Auto-generated method stub
120 * See {@link MatrixI#getValues()}
123 public double[][] getValues()
125 return jalviewMatrix.getValues();
129 public void write(final Writer w) throws IOException // directly copied from
133 w.write(getSize() + "");
134 w.write(ForesterUtil.LINE_SEPARATOR);
135 for (int row = 0; row < getSize(); ++row)
137 if (!ForesterUtil.isEmpty(getIdentifier(row)))
139 w.write(ForesterUtil.pad(getIdentifier(row), 10, ' ', false)
146 throw new IllegalFormatUseException(
147 "Phylip format does not allow empty identifiers");
149 for (int col = 0; col < getSize(); ++col)
151 w.write(PHYLIP_FORMATTER.format(getValue(col, row)));
152 if (col < (getSize() - 1))
158 if (row < (getSize() - 1))
160 w.write(ForesterUtil.LINE_SEPARATOR);
166 public static DistanceMatrix convertJalviewToForester(
167 final MatrixI jalviewInputMatrix,
168 final SequenceI[] matrixSequences)
170 return DataConversions.createForesterDistanceMatrix(
171 jalviewInputMatrix, matrixSequences);
175 public static DistanceMatrix convertJalviewToForester(
176 final MatrixI jalviewInputMatrix,
177 final String[] matrixIdentifiers)
179 return DataConversions.createForesterDistanceMatrix(
180 jalviewInputMatrix, matrixIdentifiers);