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