4e7026e3fdf7df23f0ad4aa5d365de82b0c61b0f
[jalview.git] / src / jalview / ws / rest / params / SeqGroupIndexVector.java
1 package jalview.ws.rest.params;
2
3 import jalview.datamodel.AlignmentI;
4 import jalview.datamodel.SequenceGroup;
5 import jalview.datamodel.SequenceI;
6 import jalview.ws.rest.AlignmentProcessor;
7 import jalview.ws.rest.InputType;
8 import jalview.ws.rest.NoValidInputDataException;
9 import jalview.ws.rest.RestJob;
10 import jalview.ws.rest.InputType.molType;
11
12 import java.io.UnsupportedEncodingException;
13 import java.util.ArrayList;
14 import java.util.Vector;
15
16 import org.apache.http.entity.mime.content.ContentBody;
17 import org.apache.http.entity.mime.content.StringBody;
18
19 /**
20  * Represents the partitions defined on the alignment as indices e.g. for a
21  * partition (A,B,C),(D,E),(F) The indices would be 3,2,1. Note, the alignment
22  * must be ordered so groups are contiguous before this input type can be used.
23  * 
24  * @author JimP
25  * 
26  */
27 public class SeqGroupIndexVector extends InputType implements
28         AlignmentProcessor
29 {
30   public SeqGroupIndexVector()
31   {
32     super(new Class[]
33     { AlignmentI.class });
34   }
35
36   /**
37    * separator for list of sequence Indices - default is ','
38    */
39   public String sep = ",";
40
41   /**
42    * min size of each partition
43    */
44   public int minsize = 1;
45
46   molType type;
47
48   /**
49    * prepare the context alignment for this input
50    * 
51    * @param al
52    *          - alignment to be processed
53    * @return al or a new alignment with appropriate attributes/order for input
54    */
55   public AlignmentI prepareAlignment(AlignmentI al)
56   {
57     jalview.analysis.AlignmentSorter.sortByGroup(al);
58     return al;
59   }
60
61   @Override
62   public ContentBody formatForInput(RestJob rj)
63           throws UnsupportedEncodingException, NoValidInputDataException
64   {
65     StringBuffer idvector = new StringBuffer();
66     boolean list = false;
67     AlignmentI al = rj.getAlignmentForInput(token, type);
68     // assume that alignment is properly ordered so groups form consecutive
69     // blocks
70     ArrayList<int[]> gl = new ArrayList<int[]>();
71     for (SequenceGroup sg : (Vector<SequenceGroup>) al.getGroups())
72     {
73       if (sg.getSize()<minsize)
74       {
75         throw new NoValidInputDataException("Group contains less than "+minsize+" sequences.");
76       }
77       // TODO: refactor to sequenceGroup for efficiency -
78       // getAlignmentRowInterval(AlignmentI al)
79       int[] se = null;
80       for (SequenceI sq : sg.getSequencesInOrder(al))
81       {
82         int p = al.findIndex(sq);
83         if (se == null)
84         {
85           se = new int[]
86           { p, p };
87         }
88         else
89         {
90           if (p < se[0])
91             se[0] = p;
92           if (p > se[1])
93             se[1] = p;
94         }
95       }
96       if (se != null)
97       {
98         gl.add(se);
99       }
100     }
101     int[][] vals = gl.toArray(new int[gl.size()][]);
102     int[] srt = new int[gl.size()];
103     for (int i = 0; i < vals.length; i++)
104       srt[i] = vals[i][0];
105     jalview.util.QuickSort.sort(srt, vals);
106     list = false;
107     int last = vals[0][0] - 1;
108     for (int[] range : vals)
109     {
110       if (range[1] > last)
111       {
112         if (list)
113         {
114           idvector.append(sep);
115         }
116         idvector.append(range[1] - last);
117         last = range[1];
118         list = true;
119       }
120     }
121     return new StringBody(idvector.toString());
122   }
123
124 }