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 String fullseq = sequences[n].getSequenceString(c);
97 for (int h = 0; h < contigs.length; h += 3)
99 seqs[n] += fullseq.substring(p, contigs[h + 1]);
100 p = contigs[h + 1] + contigs[h + 2];
102 seqs[n] += fullseq.substring(p);
110 * @return visible number of columns in alignment view
112 public int getWidth() {
116 protected void setWidth(int width) {
120 * get the contiguous subalignments in an alignment view.
121 * @param gapCharacter char
122 * @return SequenceI[][]
124 public SequenceI[][] getVisibleContigs(char gapCharacter) {
127 if (sequences==null || width<=0)
129 if (contigs != null && contigs.length > 0)
134 for (int contig = 0; contig < contigs.length; contig += 3)
136 if ( (contigs[contig + 1] - start) > 0)
140 fwidth += contigs[contig + 2]; // end up with full region width (including hidden regions)
141 start = contigs[contig + 1] + contigs[contig + 2];
147 smsa = new SequenceI[njobs][];
150 for (int contig = 0; contig < contigs.length; contig += 3)
152 if (contigs[contig + 1] - start > 0)
154 SequenceI mseq[] = new SequenceI[sequences.length];
155 for (int s = 0; s < mseq.length; s++)
157 mseq[s] = sequences[s].getSeq(gapCharacter).getSubSequence(start,
158 contigs[contig + 1]);
163 start = contigs[contig + 1] + contigs[contig + 2];
167 SequenceI mseq[] = new SequenceI[sequences.length];
168 for (int s = 0; s < mseq.length; s++)
170 mseq[s] = sequences[s].getSeq(gapCharacter).getSubSequence(start,
179 smsa = new SequenceI[1][];
180 smsa[0] = new SequenceI[sequences.length];
181 for (int s = 0; s < sequences.length; s++)
183 smsa[0][s] = sequences[s].getSeq(gapCharacter);
189 * return full msa and hidden regions with visible blocks replaced with new sub alignments
190 * @param nvismsa SequenceI[][]
191 * @param orders AlignmentOrder[] corresponding to each SequenceI[] block.
194 public Object[] getUpdatedView(SequenceI[][] nvismsa, AlignmentOrder[] orders, char gapCharacter) {
195 if (sequences == null || width <= 0)
197 throw new Error("empty view cannot be updated.");
201 "nvismsa==null. use getAlignmentAndColumnSelection() instead.");
202 if (contigs != null && contigs.length > 0)
204 SequenceI[] alignment = new SequenceI[sequences.length];
205 ColumnSelection columnselection = new ColumnSelection();
206 if (contigs != null && contigs.length > 0)
212 for (int contig = 0; contig < contigs.length; contig += 3)
214 owidth += contigs[contig + 2]; // recover final column width
215 if (contigs[contig + 1] - start > 0)
217 int swidth = 0; // subalignment width
218 if (nvismsa[j] != null)
220 SequenceI mseq[] = nvismsa[j];
221 AlignmentOrder order=(orders==null) ? null : orders[j];
223 if (mseq.length!=sequences.length)
224 throw new Error("Mismatch between number of sequences in block "+j+" ("+mseq.length+") and the original view ("+sequences.length+")");
225 swidth = mseq[0].getLength(); // JBPNote: could ensure padded here.
226 for (int s = 0; s < mseq.length; s++)
228 if (alignment[s] == null)
230 alignment[s] = mseq[s];
234 alignment[s].setSequence(alignment[s].getSequence() +
235 mseq[s].getSequence());
236 if (mseq[s].getStart() <= mseq[s].getEnd())
238 alignment[s].setEnd(mseq[s].getEnd());
241 order.updateSequence(mseq[s], alignment[s]);
248 // recover original alignment block or place gaps
251 // recover input data
252 for (int s = 0; s < sequences.length; s++)
254 SequenceI oseq = sequences[s].getSeq(gapCharacter).getSubSequence(start,
255 contigs[contig + 1]);
256 if (swidth < oseq.getLength())
258 swidth = oseq.getLength();
260 if (alignment[s] == null)
266 alignment[s].setSequence(alignment[s].getSequence() +
268 if (oseq.getEnd() >= oseq.getStart())
270 alignment[s].setEnd(oseq.getEnd());
280 // advance to begining of visible region
281 start = contigs[contig + 1] + contigs[contig + 2];
282 // add hidden segment to right of next region
283 for (int s = 0; s < sequences.length; s++)
285 SequenceI hseq = sequences[s].getSeq(gapCharacter).getSubSequence(contigs[contig +
287 if (alignment[s] == null)
293 alignment[s].setSequence(alignment[s].getSequence() +
295 if (hseq.getEnd() >= hseq.getStart())
297 alignment[s].setEnd(hseq.getEnd());
301 // mark hidden segment as hidden in the new alignment
302 columnselection.hideColumns(nwidth, nwidth + contigs[contig + 2] - 1);
303 nwidth += contigs[contig + 2];
305 // Do final segment - if it exists
306 if (j < nvismsa.length)
309 if (nvismsa[j] != null)
311 SequenceI mseq[] = nvismsa[j];
312 AlignmentOrder order = (orders!=null) ? orders[j] : null;
313 swidth = mseq[0].getLength();
314 for (int s = 0; s < mseq.length; s++)
316 if (alignment[s] == null)
318 alignment[s] = mseq[s];
322 alignment[s].setSequence(alignment[s].getSequence() +
323 mseq[s].getSequence());
324 if (mseq[s].getEnd() >= mseq[s].getStart())
326 alignment[s].setEnd(mseq[s].getEnd());
329 order.updateSequence(mseq[s], alignment[s]);
338 // recover input data or place gaps
341 // recover input data
342 for (int s = 0; s < sequences.length; s++)
344 SequenceI oseq = sequences[s].getSeq(gapCharacter).getSubSequence(start,
346 if (swidth < oseq.getLength())
348 swidth = oseq.getLength();
350 if (alignment[s] == null)
356 alignment[s].setSequence(alignment[s].getSequence() +
358 if (oseq.getEnd() >= oseq.getStart())
360 alignment[s].setEnd(oseq.getEnd());
369 throw new Error("Padding not yet implemented.");
375 return new Object[] { alignment, columnselection};
377 if (nvismsa.length!=1)
378 throw new Error("Mismatch between visible blocks to update and number of contigs in view (contigs=0,blocks="+nvismsa.length);
379 if (nvismsa[0]!=null)
380 return new Object[] { nvismsa[0], new ColumnSelection()};
382 return getAlignmentAndColumnSelection(gapCharacter);