Clover icon

Coverage Report

  1. Project Clover database Thu Nov 28 2024 18:06:40 GMT
  2. Package jalview.ws.rest.params

File SeqGroupIndexVector.java

 

Coverage histogram

../../../../img/srcFileCovDistChart7.png
31% of files have more coverage

Code metrics

42
87
8
1
299
228
33
0.38
10.88
8
4.12

Classes

Class Line # Actions
SeqGroupIndexVector 51 87 33
0.700729970.1%
 

Contributing tests

This file is covered by 208 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.ws.rest.params;
22   
23    import jalview.datamodel.AlignmentI;
24    import jalview.datamodel.SequenceGroup;
25    import jalview.datamodel.SequenceI;
26    import jalview.util.MessageManager;
27    import jalview.ws.params.OptionI;
28    import jalview.ws.params.simple.IntegerParameter;
29    import jalview.ws.params.simple.Option;
30    import jalview.ws.rest.AlignmentProcessor;
31    import jalview.ws.rest.InputType;
32    import jalview.ws.rest.NoValidInputDataException;
33    import jalview.ws.rest.RestJob;
34   
35    import java.io.UnsupportedEncodingException;
36    import java.util.ArrayList;
37    import java.util.Arrays;
38    import java.util.List;
39   
40    import org.apache.http.entity.mime.content.ContentBody;
41    import org.apache.http.entity.mime.content.StringBody;
42   
43    /**
44    * Represents the partitions defined on the alignment as indices e.g. for a
45    * partition (A,B,C),(D,E),(F) The indices would be 3,2,1. Note, the alignment
46    * must be ordered so groups are contiguous before this input type can be used.
47    *
48    * @author JimP
49    *
50    */
 
51    public class SeqGroupIndexVector extends InputType
52    implements AlignmentProcessor
53    {
 
54  3535 toggle public SeqGroupIndexVector()
55    {
56  3535 super(new Class[] { AlignmentI.class });
57    }
58   
59    /**
60    * separator for list of sequence Indices - default is ','
61    */
62    public String sep = ",";
63   
64    /**
65    * min size of each partition
66    */
67    public int minsize = 1;
68   
69    molType type;
70   
71    /**
72    * prepare the context alignment for this input
73    *
74    * @param al
75    * - alignment to be processed
76    * @return al or a new alignment with appropriate attributes/order for input
77    */
 
78  4 toggle @Override
79    public AlignmentI prepareAlignment(AlignmentI al)
80    {
81  4 jalview.analysis.AlignmentSorter.sortByGroup(al);
82  4 return al;
83    }
84   
 
85  2 toggle @Override
86    public ContentBody formatForInput(RestJob rj)
87    throws UnsupportedEncodingException, NoValidInputDataException
88    {
89  2 StringBuffer idvector = new StringBuffer();
90  2 boolean list = false;
91  2 AlignmentI al = rj.getAlignmentForInput(token, type);
92    // assume that alignment is properly ordered so groups form consecutive
93    // blocks
94  2 ArrayList<int[]> gl = new ArrayList<>();
95  2 int p = 0, lowest = al.getHeight(), highest = 0;
96  2 List<SequenceGroup> sgs = al.getGroups();
97  2 synchronized (sgs)
98    {
99  2 for (SequenceGroup sg : sgs)
100    {
101  10 if (sg.getSize() < minsize)
102    {
103  0 throw new NoValidInputDataException(MessageManager.formatMessage(
104    "exception.notvaliddata_group_contains_less_than_min_seqs",
105    new String[]
106    { Integer.valueOf(minsize).toString() }));
107    }
108    // TODO: refactor to sequenceGroup for efficiency -
109    // getAlignmentRowInterval(AlignmentI al)
110  10 int[] se = null;
111  10 for (SequenceI sq : sg.getSequencesInOrder(al))
112    {
113  66 p = al.findIndex(sq);
114  66 if (lowest > p)
115    {
116  4 lowest = p;
117    }
118  66 if (highest < p)
119    {
120  25 highest = p;
121    }
122  66 if (se == null)
123    {
124  10 se = new int[] { p, p };
125    }
126    else
127    {
128  56 if (p < se[0])
129    {
130  0 se[0] = p;
131    }
132  56 if (p > se[1])
133    {
134  56 se[1] = p;
135    }
136    }
137    }
138  10 if (se != null)
139    {
140  10 gl.add(se);
141    }
142    }
143    }
144    // are there any more sequences ungrouped that should be added as a single
145    // remaining group ? - these might be at the start or the end
146  2 if (gl.size() > 0)
147    {
148  2 if (lowest - 1 > minsize)
149    {
150  0 gl.add(0, new int[] { 0, lowest - 2 });
151    }
152  2 if ((al.getHeight() - 1 - highest) > minsize)
153    {
154  0 gl.add(new int[] { highest + 1, al.getHeight() - 1 });
155    }
156    }
157    else
158    {
159  0 gl.add(new int[] { 0, al.getHeight() - 1 });
160    }
161  2 if (min >= 0 && gl.size() < min)
162    {
163  0 throw new NoValidInputDataException(
164    "Not enough sequence groups for input. Need at least " + min
165    + " groups (including ungrouped regions).");
166    }
167  2 if (max > 0 && gl.size() > max)
168    {
169  0 throw new NoValidInputDataException(
170    "Too many sequence groups for input. Need at most " + max
171    + " groups (including ungrouped regions).");
172    }
173  2 int[][] vals = gl.toArray(new int[gl.size()][]);
174  2 int[] srt = new int[gl.size()];
175  12 for (int i = 0; i < vals.length; i++)
176    {
177  10 srt[i] = vals[i][0];
178    }
179  2 jalview.util.QuickSort.sort(srt, vals);
180  2 list = false;
181  2 int last = vals[0][0] - 1;
182  2 for (int[] range : vals)
183    {
184  10 if (range[1] > last)
185    {
186  10 if (list)
187    {
188  8 idvector.append(sep);
189    }
190  10 idvector.append(range[1] - last);
191  10 last = range[1];
192  10 list = true;
193    }
194    }
195  2 return new StringBody(idvector.toString());
196    }
197   
198    /**
199    * set minimum number of sequences allowed in a partition. Default is 1
200    * sequence.
201    *
202    * @param i
203    * (number greater than 1)
204    */
 
205  8 toggle public void setMinsize(int i)
206    {
207  8 if (minsize >= 1)
208    {
209  8 minsize = i;
210    }
211    else
212    {
213  0 minsize = 1;
214    }
215    }
216   
 
217  30 toggle @Override
218    public List<String> getURLEncodedParameter()
219    {
220  30 ArrayList<String> prms = new ArrayList<>();
221  30 super.addBaseParams(prms);
222  30 prms.add("minsize='" + minsize + "'");
223  30 prms.add("sep='" + sep + "'");
224  30 if (type != null)
225    {
226  0 prms.add("type='" + type + "'");
227    }
228  30 return prms;
229    }
230   
 
231  3542 toggle @Override
232    public String getURLtokenPrefix()
233    {
234  3542 return "PARTITION";
235    }
236   
 
237  7054 toggle @Override
238    public boolean configureProperty(String tok, String val,
239    StringBuffer warnings)
240    {
241   
242  7054 if (tok.startsWith("sep"))
243    {
244  3527 sep = val;
245  3527 return true;
246    }
247  3527 if (tok.startsWith("minsize"))
248    {
249  3527 try
250    {
251  3527 minsize = Integer.valueOf(val);
252  3527 if (minsize >= 0)
253    {
254  3527 return true;
255    }
256    } catch (Exception x)
257    {
258   
259    }
260  0 warnings.append("Invalid minsize value '" + val
261    + "'. Must be a positive integer.\n");
262    }
263  0 if (tok.startsWith("type"))
264    {
265  0 try
266    {
267  0 type = molType.valueOf(val);
268  0 return true;
269    } catch (Exception x)
270    {
271  0 warnings.append(
272    "Invalid molecule type '" + val + "'. Must be one of (");
273  0 for (molType v : molType.values())
274    {
275  0 warnings.append(" " + v);
276    }
277  0 warnings.append(")\n");
278    }
279    }
280  0 return false;
281    }
282   
 
283  0 toggle @Override
284    public List<OptionI> getOptions()
285    {
286  0 List<OptionI> lst = getBaseOptions();
287  0 lst.add(new Option("sep",
288    "Separator character between elements of vector", true, ",",
289    sep, Arrays.asList(new String[]
290    { " ", ",", ";", "\t", "|" }), null));
291  0 lst.add(new IntegerParameter("minsize",
292    "Minimum size of partition allowed by service", true, 1,
293    minsize, 1, 0));
294  0 lst.add(createMolTypeOption("type", "Sequence type", false, type,
295    molType.MIX));
296  0 return lst;
297    }
298   
299    }