JAL-1953 moved DataConversions to Forester package
[jalview.git] / src / jalview / ext / forester / ForesterMatrix.java
1 package jalview.ext.forester;
2
3 import jalview.datamodel.SequenceI;
4 import jalview.math.MatrixI;
5 import jalview.util.MessageManager;
6
7 import java.io.IOException;
8 import java.io.Writer;
9 import java.text.DecimalFormat;
10 import java.text.NumberFormat;
11 import java.util.NoSuchElementException;
12 import java.util.stream.IntStream;
13
14 import org.forester.evoinference.matrix.distance.DistanceMatrix;
15 import org.forester.util.ForesterUtil;
16 import org.forester.util.IllegalFormatUseException;
17
18 public class ForesterMatrix implements DistanceMatrix
19 {
20   private final static NumberFormat PHYLIP_FORMATTER = new DecimalFormat(
21           "0.000000"); // straight from forester
22
23   private final MatrixI jalviewMatrix;
24
25   private final String[] identifiers;
26
27   public ForesterMatrix(final MatrixI jalviewInputMatrix,
28           final SequenceI[] matrixSequences)
29   {
30     this.jalviewMatrix = jalviewInputMatrix;
31     this.identifiers = new String[matrixSequences.length];
32
33     int i = 0;
34     for (SequenceI sequence : matrixSequences)
35     {
36       identifiers[i] = sequence.getName();
37       i++;
38     }
39
40   }
41
42   public ForesterMatrix(final MatrixI jalviewInputMatrix,
43           final String[] matrixIdentifiers)
44   {
45     this.jalviewMatrix = jalviewInputMatrix;
46     this.identifiers = matrixIdentifiers;
47
48   }
49
50   @Override
51   public String getIdentifier(final int i)
52   {
53     return identifiers[i]; // add handling if index is out of bounds
54   }
55
56
57   @Override
58   public int getIndex(final String identifier)
59   {
60     try {
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
64                            // list
65                            // with Arrays.aslist
66     }
67     catch (NoSuchElementException ex) {
68       throw new Error(MessageManager.formatMessage(
69               "exception.invalid_matrix_identifier", new String[]
70               { identifier }));
71     }
72   }
73
74   /**
75    * Returns the length of whichever is longest, columns or rows
76    */
77   @Override
78   public int getSize()
79   {
80     return jalviewMatrix.getValues().length;
81   }
82
83   /**
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)
86    */
87   @Override
88   public double getValue(final int col, final int row)
89   {
90     return jalviewMatrix.getValue(row, col);
91   }
92
93   @Override
94   public void setIdentifier(final int i, final String identifier)
95   {
96     identifiers[i] = identifier;
97
98   }
99
100   /**
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)
103    */
104   @Override
105   public void setValue(final int col, final int row, final double distance)
106   {
107     jalviewMatrix.setValue(row, col, distance);
108
109   }
110
111   @Override
112   public StringBuffer toStringBuffer(Format format)
113   {
114     // TODO Auto-generated method stub
115     return null;
116   }
117
118   /**
119    * See {@link MatrixI#getValues()}
120    */
121   @Override
122   public double[][] getValues()
123   {
124     return jalviewMatrix.getValues();
125   }
126
127   @Override
128   public void write(final Writer w) throws IOException // directly copied from
129                                                  // forester
130   {
131     w.write("    ");
132     w.write(getSize() + "");
133     w.write(ForesterUtil.LINE_SEPARATOR);
134     for (int row = 0; row < getSize(); ++row)
135     {
136       if (!ForesterUtil.isEmpty(getIdentifier(row)))
137       {
138         w.write(ForesterUtil.pad(getIdentifier(row), 10, ' ', false)
139                 .toString());
140         w.write(' ');
141         w.write(' ');
142       }
143       else
144       {
145         throw new IllegalFormatUseException(
146                 "Phylip format does not allow empty identifiers");
147       }
148       for (int col = 0; col < getSize(); ++col)
149       {
150         w.write(PHYLIP_FORMATTER.format(getValue(col, row)));
151         if (col < (getSize() - 1))
152         {
153           w.write(' ');
154           w.write(' ');
155         }
156       }
157       if (row < (getSize() - 1))
158       {
159         w.write(ForesterUtil.LINE_SEPARATOR);
160       }
161     }
162
163   }
164
165   public static DistanceMatrix convertJalviewToForester(
166           final MatrixI jalviewInputMatrix,
167           final SequenceI[] matrixSequences)
168   {
169     return DataConversions.createForesterDistanceMatrix(
170             jalviewInputMatrix, matrixSequences);
171
172   }
173
174   public static DistanceMatrix convertJalviewToForester(
175           final MatrixI jalviewInputMatrix,
176           final String[] matrixIdentifiers)
177   {
178     return DataConversions.createForesterDistanceMatrix(
179             jalviewInputMatrix, matrixIdentifiers);
180
181   }
182
183
184 }