JAL-1466 improved test and patched off by one that deleted one dataset residue from...
[jalview.git] / src / jalview / analysis / AlignmentUtils.java
1 package jalview.analysis;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import jalview.datamodel.SequenceI;
7 import jalview.datamodel.AlignmentI;
8
9 /**
10  * grab bag of useful alignment manipulation operations
11  * Expect these to be refactored elsewhere at some point.
12  * @author jimp
13  *
14  */
15 public class AlignmentUtils
16 {
17
18   /**
19    * given an existing alignment, create a new alignment including all, or up to flankSize additional symbols from each sequence's dataset sequence
20    * @param core
21    * @param flankSize
22    * @return AlignmentI
23    */
24   public static AlignmentI expandContext(AlignmentI core, int flankSize)
25   {
26     List<SequenceI> sq = new ArrayList<SequenceI>();
27     int maxoffset = 0;
28     for (SequenceI s:core.getSequences())
29     {
30       SequenceI newSeq = s.deriveSequence();
31       if (newSeq.getStart()>maxoffset)
32       {
33         maxoffset = newSeq.getStart();
34       }
35       sq.add(newSeq);
36     }
37     if (flankSize>-1) {
38       maxoffset = flankSize;
39     }
40     // now add offset to create a new expanded alignment
41     for (SequenceI s:sq)
42     {
43       SequenceI ds = s;
44       while (ds.getDatasetSequence()!=null) {
45         ds=ds.getDatasetSequence();
46       }
47       int s_end = s.findPosition(s.getStart()+s.getLength());
48       // find available flanking residues for sequence
49       int ustream_ds=s.getStart()-ds.getStart(),dstream_ds=ds.getEnd()-s_end;
50       
51       // build new flanked sequence
52       
53       // compute gap padding to start of flanking sequence
54       int offset=maxoffset - ustream_ds;
55       
56       // padding is gapChar x ( maxoffset - min(ustream_ds, flank)
57       if (flankSize>=0) {
58         if (flankSize<ustream_ds)
59         {
60         // take up to flankSize residues
61         offset = maxoffset-flankSize;
62         ustream_ds = flankSize;
63       }
64         if (flankSize<dstream_ds)
65         {
66           dstream_ds=flankSize;
67         }
68       }
69       char[] upstream = new String(ds.getSequence(s.getStart()-1-ustream_ds, s.getStart()-1)).toLowerCase().toCharArray();
70       char[] downstream = new String(ds.getSequence(s_end-1,s_end+1+dstream_ds)).toLowerCase().toCharArray();
71       char[] coreseq=s.getSequence();
72       char[] nseq = new char[offset+upstream.length+downstream.length+coreseq.length]; 
73       char c = core.getGapCharacter();
74       // TODO could lowercase the flanking regions
75       int p=0;
76       for (; p<offset;p++)
77       {
78         nseq[p] = c;
79       }
80 //      s.setSequence(new String(upstream).toLowerCase()+new String(coreseq) + new String(downstream).toLowerCase());
81       System.arraycopy(upstream, 0, nseq, p, upstream.length);
82       System.arraycopy(coreseq, 0, nseq, p+upstream.length, coreseq.length);
83       System.arraycopy(downstream, 0, nseq, p+coreseq.length+upstream.length, downstream.length);
84       s.setSequence(new String(nseq));
85       s.setStart(s.getStart()-ustream_ds);
86       s.setEnd(s_end+downstream.length);
87     }
88     AlignmentI newAl = new jalview.datamodel.Alignment(sq.toArray(new SequenceI[0]));
89     newAl.setDataset(core.getDataset());
90     return newAl;
91   }
92 }