2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 package jalview.datamodel;
26 * <p>Description: </p>
28 * <p>Copyright: Copyright (c) 2004</p>
30 * <p>Company: Dundee University</p>
32 * @author not attributable
35 public class AlignmentView
38 * Transient object compactly representing a 'view' of an alignment - with discontinuities marked.
40 private SeqCigar[] sequences = null;
41 private int[] contigs = null;
43 public AlignmentView(CigarArray seqcigararray)
45 if (!seqcigararray.isSeqCigarArray())
46 throw new Error("Implementation Error - can only make an alignment view from a CigarArray of sequences.");
47 //contigs = seqcigararray.applyDeletions();
48 contigs = seqcigararray.getDeletedRegions();
49 sequences = seqcigararray.getSeqCigarArray();
50 width = seqcigararray.getWidth(); // visible width
53 public void setSequences(SeqCigar[] sequences)
55 this.sequences = sequences;
58 public void setContigs(int[] contigs)
60 this.contigs = contigs;
63 public SeqCigar[] getSequences()
68 public int[] getContigs()
73 * get the full alignment and a columnselection object marking the hidden regions
74 * @param gapCharacter char
75 * @return Object[] { SequenceI[], ColumnSelection}
77 public Object[] getAlignmentAndColumnSelection(char gapCharacter) {
78 ColumnSelection colsel = new ColumnSelection();
80 return new Object[] { SeqCigar.createAlignmentSequences(sequences, gapCharacter, colsel, contigs), colsel};
88 public String[] getSequenceStrings(char c)
90 String[] seqs=new String[sequences.length];
91 for (int n=0; n<sequences.length; n++) {
92 seqs[n] = sequences[n].getSequenceString(c);
98 * @return visible number of columns in alignment view
100 public int getWidth() {
104 protected void setWidth(int width) {
108 * get the contiguous subalignments in an alignment view.
109 * @param gapCharacter char
110 * @return SequenceI[][]
112 public SequenceI[][] getVisibleContigs(char gapCharacter) {
115 if (sequences==null || width<=0)
117 if (contigs != null && contigs.length > 0)
122 for (int contig = 0; contig < contigs.length; contig += 3)
124 if ( (contigs[contig + 1] - start) > 0)
128 fwidth += contigs[contig + 2]; // end up with full region width (including hidden regions)
129 start = contigs[contig + 1] + contigs[contig + 2];
135 smsa = new SequenceI[njobs][];
138 for (int contig = 0; contig < contigs.length; contig += 3)
140 if (contigs[contig + 1] - start > 0)
142 SequenceI mseq[] = new SequenceI[sequences.length];
143 for (int s = 0; s < mseq.length; s++)
145 mseq[s] = sequences[s].getSeq(gapCharacter).getSubSequence(start,
146 contigs[contig + 1]);
151 start = contigs[contig + 1] + contigs[contig + 2];
155 SequenceI mseq[] = new SequenceI[sequences.length];
156 for (int s = 0; s < mseq.length; s++)
158 mseq[s] = sequences[s].getSeq(gapCharacter).getSubSequence(start,
167 smsa = new SequenceI[1][];
168 smsa[0] = new SequenceI[sequences.length];
169 for (int s = 0; s < sequences.length; s++)
171 smsa[0][s] = sequences[s].getSeq(gapCharacter);
177 * return full msa and hidden regions with visible blocks replaced with new sub alignments
178 * @param nvismsa SequenceI[][]
179 * @param orders AlignmentOrder[] corresponding to each SequenceI[] block.
182 public Object[] getUpdatedView(SequenceI[][] nvismsa, AlignmentOrder[] orders, char gapCharacter) {
183 if (sequences == null || width <= 0)
185 throw new Error("empty view cannot be updated.");
189 "nvismsa==null. use getAlignmentAndColumnSelection() instead.");
190 if (contigs != null && contigs.length > 0)
192 SequenceI[] alignment = new SequenceI[sequences.length];
193 ColumnSelection columnselection = new ColumnSelection();
194 if (contigs != null && contigs.length > 0)
200 for (int contig = 0; contig < contigs.length; contig += 3)
202 owidth += contigs[contig + 2]; // recover final column width
203 if (contigs[contig + 1] - start > 0)
205 int swidth = 0; // subalignment width
206 if (nvismsa[j] != null)
208 SequenceI mseq[] = nvismsa[j];
209 AlignmentOrder order=(orders==null) ? null : orders[j];
211 if (mseq.length!=sequences.length)
212 throw new Error("Mismatch between number of sequences in block "+j+" ("+mseq.length+") and the original view ("+sequences.length+")");
213 swidth = mseq[0].getLength(); // JBPNote: could ensure padded here.
214 for (int s = 0; s < mseq.length; s++)
216 if (alignment[s] == null)
218 alignment[s] = mseq[s];
222 alignment[s].setSequence(alignment[s].getSequence() +
223 mseq[s].getSequence());
224 if (mseq[s].getStart() <= mseq[s].getEnd())
226 alignment[s].setEnd(mseq[s].getEnd());
229 order.updateSequence(mseq[s], alignment[s]);
236 // recover original alignment block or place gaps
239 // recover input data
240 for (int s = 0; s < sequences.length; s++)
242 SequenceI oseq = sequences[s].getSeq(gapCharacter).getSubSequence(start,
243 contigs[contig + 1]);
244 if (swidth < oseq.getLength())
246 swidth = oseq.getLength();
248 if (alignment[s] == null)
254 alignment[s].setSequence(alignment[s].getSequence() +
256 if (oseq.getEnd() >= oseq.getStart())
258 alignment[s].setEnd(oseq.getEnd());
268 // advance to begining of visible region
269 start = contigs[contig + 1] + contigs[contig + 2];
270 // add hidden segment to right of next region
271 for (int s = 0; s < sequences.length; s++)
273 SequenceI hseq = sequences[s].getSeq(gapCharacter).getSubSequence(contigs[contig +
275 if (alignment[s] == null)
281 alignment[s].setSequence(alignment[s].getSequence() +
283 if (hseq.getEnd() >= hseq.getStart())
285 alignment[s].setEnd(hseq.getEnd());
289 // mark hidden segment as hidden in the new alignment
290 columnselection.hideColumns(nwidth, nwidth + contigs[contig + 2] - 1);
291 nwidth += contigs[contig + 2];
293 // Do final segment - if it exists
294 if (j < nvismsa.length)
297 if (nvismsa[j] != null)
299 SequenceI mseq[] = nvismsa[j];
300 AlignmentOrder order = (orders!=null) ? orders[j] : null;
301 swidth = mseq[0].getLength();
302 for (int s = 0; s < mseq.length; s++)
304 if (alignment[s] == null)
306 alignment[s] = mseq[s];
310 alignment[s].setSequence(alignment[s].getSequence() +
311 mseq[s].getSequence());
312 if (mseq[s].getEnd() >= mseq[s].getStart())
314 alignment[s].setEnd(mseq[s].getEnd());
317 order.updateSequence(mseq[s], alignment[s]);
326 // recover input data or place gaps
329 // recover input data
330 for (int s = 0; s < sequences.length; s++)
332 SequenceI oseq = sequences[s].getSeq(gapCharacter).getSubSequence(start,
334 if (swidth < oseq.getLength())
336 swidth = oseq.getLength();
338 if (alignment[s] == null)
344 alignment[s].setSequence(alignment[s].getSequence() +
346 if (oseq.getEnd() >= oseq.getStart())
348 alignment[s].setEnd(oseq.getEnd());
357 throw new Error("Padding not yet implemented.");
363 return new Object[] { alignment, columnselection};
365 if (nvismsa.length!=1)
366 throw new Error("Mismatch between visible blocks to update and number of contigs in view (contigs=0,blocks="+nvismsa.length);
367 if (nvismsa[0]!=null)
368 return new Object[] { nvismsa[0], new ColumnSelection()};
370 return getAlignmentAndColumnSelection(gapCharacter);