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