JAL-2795 added error catching for invalid identifier
[jalview.git] / src / jalview / ext / forester / ForesterMatrix.java
1 package jalview.ext.forester;
2
3 import jalview.datamodel.Sequence;
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 Sequence[] sequences;
26
27   private final String[] identifiers;
28
29   public ForesterMatrix(final MatrixI jalviewInputMatrix,
30           final Sequence[] matrixSequences)
31   {
32     this.jalviewMatrix = jalviewInputMatrix;
33     this.sequences = matrixSequences;
34     this.identifiers = new String[sequences.length];
35
36     int i = 0;
37
38     for (Sequence sequence : sequences)
39     {
40       identifiers[i] = sequence.getName();
41       i++;
42     }
43
44   }
45
46   public ForesterMatrix(final MatrixI jalviewInputMatrix,
47           final String[] matrixIdentifiers)
48   {
49     this.jalviewMatrix = jalviewInputMatrix;
50     this.identifiers = matrixIdentifiers;
51
52   }
53
54   @Override
55   public String getIdentifier(final int i)
56   {
57     return identifiers[i];
58   }
59
60
61   @Override
62   public int getIndex(final String identifier)
63   {
64     try {
65     return IntStream.range(0, identifiers.length)
66             .filter(x -> identifier.equals(identifiers[x])).findAny()
67             .getAsInt();
68     }
69     catch (NoSuchElementException ex) {
70       throw new Error(MessageManager.formatMessage(
71               "exception.invalid_matrix_identifier", new String[]
72               { identifier }));
73     }
74   }
75
76   /**
77    * Returns the length of whichever is longest, columns or rows
78    */
79   @Override
80   public int getSize()
81   {
82     return jalviewMatrix.getValues().length;
83   }
84
85   /**
86    * See {@link MatrixI#getValue(int,int)} except that the order of column, row
87    * in the parameters is inverted here (as that is how forester demands it)
88    */
89   @Override
90   public double getValue(final int col, final int row)
91   {
92     return jalviewMatrix.getValue(row, col);
93   }
94
95   @Override
96   public void setIdentifier(final int i, final String identifier)
97   {
98     identifiers[i] = identifier;
99
100   }
101
102   /**
103    * See {@link MatrixI#setValue()} except that the order of column, row in the
104    * parameters is inverted here (as that is how forester demands it)
105    */
106   @Override
107   public void setValue(final int col, final int row, final double distance)
108   {
109     jalviewMatrix.setValue(row, col, distance);
110
111   }
112
113   @Override
114   public StringBuffer toStringBuffer(Format format)
115   {
116     // TODO Auto-generated method stub
117     return null;
118   }
119
120   /**
121    * See {@link MatrixI#getValues()}
122    */
123   @Override
124   public double[][] getValues()
125   {
126     return jalviewMatrix.getValues();
127   }
128
129   @Override
130   public void write(final Writer w) throws IOException // directly copied from
131                                                  // forester
132   {
133     w.write("    ");
134     w.write(getSize() + "");
135     w.write(ForesterUtil.LINE_SEPARATOR);
136     for (int row = 0; row < getSize(); ++row)
137     {
138       if (!ForesterUtil.isEmpty(getIdentifier(row)))
139       {
140         w.write(ForesterUtil.pad(getIdentifier(row), 10, ' ', false)
141                 .toString());
142         w.write(' ');
143         w.write(' ');
144       }
145       else
146       {
147         throw new IllegalFormatUseException(
148                 "Phylip format does not allow empty identifiers");
149       }
150       for (int col = 0; col < getSize(); ++col)
151       {
152         w.write(PHYLIP_FORMATTER.format(getValue(col, row)));
153         if (col < (getSize() - 1))
154         {
155           w.write(' ');
156           w.write(' ');
157         }
158       }
159       if (row < (getSize() - 1))
160       {
161         w.write(ForesterUtil.LINE_SEPARATOR);
162       }
163     }
164
165   }
166
167
168 }