recover original data for tree and pca as alignment view.
[jalview.git] / src / jalview / datamodel / CigarArray.java
1 package jalview.datamodel;
2
3 public class CigarArray extends CigarBase
4 {
5     /**
6      * Do CIGAR operations on a set of sequences from many other cigars
7      * BAD THINGS WILL HAPPEN IF A CIGARARRAY IS PASSED TO A CIGARARRAY
8      * or a CIGARCIGAR is given a CIGARARRAY to insert gaps into.
9      */
10     /**
11      * array of subject cigars
12      */
13     public CigarSimple refCigars[]=null;
14     private boolean seqcigararray=false;
15   private CigarArray() {
16     super();
17   }
18
19   /**
20    * isSeqCigarArray()
21    * @return boolean true if all refCigars resolve to a SeqCigar or a CigarCigar
22    */
23   public boolean isSeqCigarArray()
24   {
25     return seqcigararray;
26   }
27   /**
28    * Apply CIGAR operations to several cigars in parallel
29    * will throw an error if any of cigar are actually CigarArrays.
30    * @param cigar Cigar[]
31    */
32   public CigarArray(CigarSimple[] cigars) {
33     super();
34     seqcigararray = true;
35     if (cigars != null && cigars.length > 0)
36     {
37       refCigars = new CigarSimple[cigars.length];
38       for (int c = 0; c < cigars.length; c++)
39       {
40         refCigars[c] = cigars[c];
41         if (! ( (cigars[c] instanceof SeqCigar)
42                || cigars[c] instanceof CigarCigar))
43         {
44           seqcigararray = false;
45         }
46       }
47     }
48   }
49   /**
50    * @see Cigar.getSequenceAndDeletions
51    * @param GapChar char
52    * @return Object[][]
53    */
54   protected Object[][] getArrayofSequenceAndDeletions(char GapChar) {
55       if (refCigars == null || refCigars.length == 0 || length == 0) {
56         return null;
57       }
58       Object[][] sqanddels = new Object[refCigars.length][];
59       for (int c=0; c<refCigars.length; c++) {
60         String refString = refCigars[c].getSequenceString(GapChar);
61         if (refString != null)
62         {
63           sqanddels[c] = getSequenceAndDeletions(refString, GapChar);
64         } else {
65           sqanddels[c] = null;
66         }
67       }
68       return sqanddels;
69     }
70   /**
71    * NOTE: this is an improper sequence string function
72    * @return String formed by newline concatenated results of applying CIGAR operations to each reference object in turn.
73    * @param GapChar char
74    * @return '\n' separated strings (empty results included as \n\n)
75    */
76   public String getSequenceString(char GapChar)
77   {
78     if (length==0 || refCigars==null)
79       return "";
80     StringBuffer seqStrings = new StringBuffer();
81     Object[][] sqanddels = getArrayofSequenceAndDeletions(GapChar);
82     for (int c=0; c<refCigars.length; c++) {
83       if (sqanddels[c]!=null) {
84         seqStrings.append( (String) sqanddels[c][0]);
85         sqanddels[c][0] = null;
86       }
87       seqStrings.append('\n');
88     }
89     return seqStrings.toString();
90   }
91   /**
92    * return string results of applying cigar string to all reference cigars
93    * @param GapChar char
94    * @return String[]
95    */
96   public String[] getSequenceStrings(char GapChar) {
97
98     if (length==0 || refCigars==null || refCigars.length==0)
99       return null;
100     Object[][] sqanddels = getArrayofSequenceAndDeletions(GapChar);
101     String[] seqs = new String[sqanddels.length];
102     for (int c=0; c<refCigars.length; c++) {
103       seqs[c] = (String) sqanddels[c][0];
104     }
105     return seqs;
106   }
107   /**
108    * Combines the CigarArray cigar operations with the operations in each
109    * reference cigar - creating a new reference cigar
110    * @return Cigar[]
111
112   public CigarBase[] getEditedCigars() {
113
114     return new CigarBase[] {};
115   }
116 */
117   /**
118    * applyDeletions
119    * edits underlying refCigars to propagate deleted regions, and removes deletion
120    * operations from CigarArray operation list.
121    * @return int[] position where deletion occured in cigarArray or null if none occured
122    */
123   public int[] applyDeletions()
124   {
125     java.util.Vector delpos=null;
126     if (length==0)
127       return null;
128     int cursor=0; // range counter for deletions
129     int vcursor=0; // visible column index
130     for (int i=0; i<length; i++) {
131       if (operation[i]!=D) {
132         if (operation[i]==M)
133           cursor+=range[i];
134         vcursor+=range[i];
135       }
136       else
137       {
138         if (delpos==null)
139           delpos=new java.util.Vector();
140         int delstart=cursor, delend=cursor+range[i]-1; // inclusive
141         delpos.add(new Integer(vcursor-1)); // index of left hand column of hidden region boundary
142         System.arraycopy(operation, i+1, operation, i, length-i);
143         System.arraycopy(range, i+1, range, i, length-i);
144         length--;
145         for (int s=0; s<refCigars.length; s++) {
146           refCigars[s].deleteRange(delstart, delend);
147         }
148       }
149     }
150     if (delpos!=null)
151     {
152       int[] pos=new int[delpos.size()];
153       for (int k = 0, l = delpos.size(); k < l; k++) {
154         pos[k] = ((Integer) delpos.get(k)).intValue();
155         delpos.set(k,null);
156       }
157       delpos=null;
158       return pos;
159     }
160     return null;
161   }
162   /**
163    *
164    * @return SeqCigar[] or null if CigarArray is not a SeqCigarArray (ie it does not resolve to set of seqCigars)
165    */
166   public SeqCigar[] getSeqCigarArray() {
167     if (!isSeqCigarArray())
168       return null;
169     SeqCigar[] sa = new SeqCigar[refCigars.length];
170     for (int i=0; i<refCigars.length; i++)
171       sa[i] = (SeqCigar) refCigars[i];
172     return sa;
173   }
174 }