package jalview.ws.rest.params; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.ws.rest.AlignmentProcessor; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; import jalview.ws.rest.RestServiceDescription; import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.Vector; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.StringBody; /** * Represents the partitions defined on the alignment as indices e.g. for a * partition (A,B,C),(D,E),(F) The indices would be 3,2,1. Note, the alignment * must be ordered so groups are contiguous before this input type can be used. * * @author JimP * */ public class SeqGroupIndexVector extends InputType implements AlignmentProcessor { public SeqGroupIndexVector() { super(new Class[] { AlignmentI.class }); } /** * separator for list of sequence Indices - default is ',' */ public String sep = ","; /** * min size of each partition */ public int minsize = 1; molType type; /** * prepare the context alignment for this input * * @param al * - alignment to be processed * @return al or a new alignment with appropriate attributes/order for input */ public AlignmentI prepareAlignment(AlignmentI al) { jalview.analysis.AlignmentSorter.sortByGroup(al); return al; } @Override public ContentBody formatForInput(RestJob rj) throws UnsupportedEncodingException, NoValidInputDataException { StringBuffer idvector = new StringBuffer(); boolean list = false; AlignmentI al = rj.getAlignmentForInput(token, type); // assume that alignment is properly ordered so groups form consecutive // blocks ArrayList gl = new ArrayList(); int p=0; for (SequenceGroup sg : (Vector) al.getGroups()) { if (sg.getSize() se[1]) se[1] = p; } } if (se != null) { gl.add(se); } } // are there any more sequences ungrouped that should be added as a single remaining group ? - these might be at the start or the end if (gl.size()>0) { int[] tail=gl.get(0); if (tail[0]>0) { if (1+tail[0]>minsize) { gl.add(0,new int[] { 0,tail[0]-1}); } else { // lets be intelligent here - if the remaining sequences aren't enough to make a final group, then don't make one. // throw new NoValidInputDataException("Group from remaining ungrouped sequences in input contains less than "+minsize+" sequences."); } } else { tail=gl.get(gl.size()-1); if (1+tail[1]minsize) { gl.add(new int[] { tail[1]+1, al.getHeight()-1}); } else { // lets be intelligent here - if the remaining sequences aren't enough to make a final group, then don't make one. // throw new NoValidInputDataException("Group from remaining ungrouped sequences in input contains less than "+minsize+" sequences."); } } } } else { gl.add(new int[] { 0, al.getHeight()-1}); } if (min>=0 && gl.size()0 && gl.size()>max) { throw new NoValidInputDataException("Too many sequence groups for input. Need at most "+max+" groups (including ungrouped regions)."); } int[][] vals = gl.toArray(new int[gl.size()][]); int[] srt = new int[gl.size()]; for (int i = 0; i < vals.length; i++) srt[i] = vals[i][0]; jalview.util.QuickSort.sort(srt, vals); list = false; int last = vals[0][0] - 1; for (int[] range : vals) { if (range[1] > last) { if (list) { idvector.append(sep); } idvector.append(range[1] - last); last = range[1]; list = true; } } return new StringBody(idvector.toString()); } /** * set minimum number of sequences allowed in a partition. Default is 1 sequence. * @param i (number greater than 1) */ public void setMinsize(int i) { if (minsize>=1) { minsize=i; } else { minsize=1; } } @Override public List getURLEncodedParameter() { ArrayList prms = new ArrayList(); super.addBaseParams(prms); prms.add("minsize='"+ minsize+"'"); prms.add("sep='"+ sep+"'"); if (type!=null) { prms.add("type='"+type+"'"); } return prms; } @Override public String getURLtokenPrefix() { return "PARTITION"; } @Override public boolean configureProperty(String tok, String val, StringBuffer warnings) { if (tok.startsWith("sep")) { sep=val; return true; } if (tok.startsWith("minsize")) { try { minsize=Integer.valueOf(val); if (minsize>=0) return true; } catch (Exception x) { } warnings.append("Invalid minsize value '"+val+"'. Must be a positive integer.\n"); } if (tok.startsWith("type")) { try { type=molType.valueOf(val); return true; } catch (Exception x) { warnings.append("Invalid molecule type '"+val+"'. Must be one of ("); for (molType v:molType.values()) { warnings.append(" "+v); } warnings.append(")\n"); } } return false; } }