\r
//SequenceData is a string representation of what the user\r
//sees. The display may contain hidden columns.\r
- CigarArray seqData=null;\r
+ public AlignmentView seqData=null;\r
\r
int[] done;\r
int noseqs;\r
* @param odata Cigar[]\r
* @param treefile NewickFile\r
*/\r
- public NJTree(SequenceI[] seqs, CigarArray odata, NewickFile treefile) {\r
+ public NJTree(SequenceI[] seqs, AlignmentView odata, NewickFile treefile) {\r
this(seqs, treefile);\r
if (odata!=null)\r
seqData = odata;\r
* @param end DOCUMENT ME!\r
*/\r
public NJTree(SequenceI[] sequence,\r
- CigarArray seqData,\r
+ AlignmentView seqData,\r
String type,\r
String pwtype,\r
int start, int end)\r
{\r
seqs[i] = new SeqCigar(sequence[i], start, end);\r
}\r
- this.seqData = new CigarArray(seqs);\r
- this.seqData.addOperation(CigarArray.M, end-start+1);\r
+ CigarArray sdata = new CigarArray(seqs);\r
+ sdata.addOperation(CigarArray.M, end-start+1);\r
+ this.seqData = new AlignmentView(sdata);\r
}\r
\r
if (!(type.equals("NJ")))\r
}\r
return sb.toString();\r
}\r
-\r
/**\r
* DOCUMENT ME!\r
*\r
* @param seqs SeqCigar[]
*/
public Alignment(SeqCigar[] alseqs) {
-
- SequenceI[] seqs = new SequenceI[alseqs.length];
- for (int i=0; i<alseqs.length; i++) {
- seqs[i] = alseqs[i].getSeq(this.gapCharacter);
- }
+ SequenceI[] seqs = SeqCigar.createAlignmentSequences(alseqs, gapCharacter, new ColumnSelection());
initAlignment(seqs);
}
/**
* JBPNote - must also check that compactAlignment resolves to a set of SeqCigars - or construct them appropriately.
* @param compactAlignment CigarArray
*/
- public Alignment(CigarArray compactAlignment) {
+ public static AlignmentI createAlignment(CigarArray compactAlignment) {
throw new Error("Alignment(CigarArray) not yet implemented");
// this(compactAlignment.refCigars);
}
--- /dev/null
+package jalview.datamodel;
+
+/**
+ * <p>Title: </p>
+ *
+ * <p>Description: </p>
+ *
+ * <p>Copyright: Copyright (c) 2004</p>
+ *
+ * <p>Company: Dundee University</p>
+ *
+ * @author not attributable
+ * @version 1.0
+ */
+public class AlignmentView
+{
+ /**
+ * Transient object compactly representing a 'view' of an alignment - with discontinuities marked.
+ */
+ private SeqCigar[] sequences = null;
+ private int[] contigs = null;
+ public AlignmentView(CigarArray seqcigararray)
+ {
+ if (!seqcigararray.isSeqCigarArray())
+ throw new Error("Implementation Error - can only make an alignment view from a CigarArray of sequences.");
+ contigs = seqcigararray.applyDeletions();
+ sequences = seqcigararray.getSeqCigarArray();
+ }
+
+ public void setSequences(SeqCigar[] sequences)
+ {
+ this.sequences = sequences;
+ }
+
+ public void setContigs(int[] contigs)
+ {
+ this.contigs = contigs;
+ }
+
+ public SeqCigar[] getSequences()
+ {
+ return sequences;
+ }
+
+ public int[] getContigs()
+ {
+ return contigs;
+ }
+ public Object[] getAlignmentAndColumnSelection(char gapCharacter) {
+ ColumnSelection colsel = new ColumnSelection();
+
+ return new Object[] { SeqCigar.createAlignmentSequences(sequences, gapCharacter, colsel), colsel};
+ }
+ /**
+ * getSequenceStrings
+ *
+ * @param c char
+ * @return String[]
+ */
+ public String[] getSequenceStrings(char c)
+ {
+ String[] seqs=new String[sequences.length];
+ for (int n=0; n<sequences.length; n++) {
+ seqs[n] = sequences[n].getSequenceString(c);
+ }
+ return seqs;
+ }
+}
{
return seqcigararray;
}
-
/**
* Apply CIGAR operations to several cigars in parallel
* will throw an error if any of cigar are actually CigarArrays.
* Combines the CigarArray cigar operations with the operations in each
* reference cigar - creating a new reference cigar
* @return Cigar[]
- */
+
public CigarBase[] getEditedCigars() {
return new CigarBase[] {};
}
+*/
+ /**
+ * applyDeletions
+ * edits underlying refCigars to propagate deleted regions, and removes deletion
+ * operations from CigarArray operation list.
+ * @return int[] position where deletion occured in cigarArray or null if none occured
+ */
+ public int[] applyDeletions()
+ {
+ java.util.Vector delpos=null;
+ if (length==0)
+ return null;
+ int cursor=0; // range counter for deletions
+ int vcursor=0; // visible column index
+ for (int i=0; i<length; i++) {
+ if (operation[i]!=D) {
+ if (operation[i]==M)
+ cursor+=range[i];
+ vcursor+=range[i];
+ }
+ else
+ {
+ if (delpos==null)
+ delpos=new java.util.Vector();
+ int delstart=cursor, delend=cursor+range[i]-1; // inclusive
+ delpos.add(new Integer(vcursor-1)); // index of left hand column of hidden region boundary
+ System.arraycopy(operation, i+1, operation, i, length-i);
+ System.arraycopy(range, i+1, range, i, length-i);
+ length--;
+ for (int s=0; s<refCigars.length; s++) {
+ refCigars[s].deleteRange(delstart, delend);
+ }
+ }
+ }
+ if (delpos!=null)
+ {
+ int[] pos=new int[delpos.size()];
+ for (int k = 0, l = delpos.size(); k < l; k++) {
+ pos[k] = ((Integer) delpos.get(k)).intValue();
+ delpos.set(k,null);
+ }
+ delpos=null;
+ return pos;
+ }
+ return null;
+ }
+ /**
+ *
+ * @return SeqCigar[] or null if CigarArray is not a SeqCigarArray (ie it does not resolve to set of seqCigars)
+ */
+ public SeqCigar[] getSeqCigarArray() {
+ if (!isSeqCigarArray())
+ return null;
+ SeqCigar[] sa = new SeqCigar[refCigars.length];
+ for (int i=0; i<refCigars.length; i++)
+ sa[i] = (SeqCigar) refCigars[i];
+ return sa;
+ }
}
}
if (reference!=null) {
int sbend = cursor+range[i];
- if (sbend>=rlength) {
+ if (sbend>rlength) {
sq.append(reference.substring(cursor, rlength));
while (sbend-- >= rlength)
{
}
/**
- * inefficient add one operation to cigar string
+ * add an operation to cigar string
* @param op char
* @param range int
*/
* NOTE: Insertion operations simply extend width of cigar result - affecting registration of alignment
* Deletion ops will shorten length of result - and affect registration of alignment
* Match ops will also affect length of result - affecting registration of alignment
- * (ie "10M".insert(4,I,3)->"4M3I3M")
- * (ie "10M".insert(4,D,3)->"4M3D3M")
- * (ie "5I5M".insert(4,I,3)->"8I5M")
- * (ie "5I5M".insert(4,D,3)->"4I3M")
- * if pos is beyond width - I operations are added before the operation
- * (ie "10M".insert(4,M,3)->"13M")
+ * (ie "10M".insert(4,I,3)->"4M3I3M") - (replace?)
+ * (ie "10M".insert(4,D,3)->"4M3D3M") - (shortens alignment)
+ * (ie "5I5M".insert(4,I,3)->"8I5M") - real insertion
+ * (ie "5I5M".insert(4,D,3)->"4I2D3M") - shortens aligment - I's are removed, Ms changed to Ds
+ * (ie "10M".insert(4,M,3)->"13M") - lengthens - Is changed to M, Ds changed to M.
* (ie "5I5M".insert(4,M,3)->"4I8M") - effectively shifts sequence left by 1 residue and extends it by 3
- * @param pos int
+ * ( "10D5M".insert(-1,M,3)->"3M7D5M")
+ * ( "10D5M".insert(0,M,3)->"7D8M")
+ * ( "10D5M".insert(1,M,3)->"10D8M")
+ *
+ * ( "1M10D5M".insert(0,M,3)->"1M10D8M")
+ * ( "1M10D5M".insert(1,M,3)->"
+ *
+ * if pos is beyond width - I operations are added before the operation
+ * @param pos int -1, 0-length of visible region, or greater to append new ops (with insertions in between)
* @param op char
* @param range int
- */
public void addOperationAt(int pos, char op, int range)
{
+ int cursor = -1; // mark the position for the current operation being edited.
+ int o = 0;
+ boolean last_d = false; // previous op was a deletion.
+ if (pos < -1)
+ throw new Error("pos<-1 is not supported.");
+ while (o<length) {
+ if (operation[o] != D)
+ {
+ if ( (cursor + this.range[o]) < pos)
+ {
+ cursor += this.range[o];
+ o++;
+ last_d=false;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else {
+ last_d=true;
+ o++;
+ }
+ }
+ if (o==length) {
+ // must insert more operations before pos
+ if (pos-cursor>0)
+ addInsertion(pos-cursor);
+ // then just add the new operation. Regardless of what it is.
+ addOperation(op, range);
+ } else {
+ int diff = pos - cursor;
+ int e_length = length-o; // new edit operation array length.
+ // diff<0 - can only happen before first insertion or match. - affects op and all following
+ // dif==0 - only when at first position of existing op -
+ // diff>0 - must preserve some existing operations
+ int[] e_range = new int[e_length];
+ System.arraycopy(this.range, o, e_range, 0, e_length);
+ char[] e_op = new char[e_length];
+ System.arraycopy(this.operation, o, e_op, 0, e_length);
+ length = o; // can now use add_operation to extend list.
+ int e_o=0; // current operation being edited.
+ switch (op) {
+ case M:
+ switch (e_op[e_o])
+ {
+ case M:
+ if (last_d && diff <= 0)
+ {
+ // reduce D's, if possible
+ if (range<=this.range[o-1]) {
+ this.range[o - 1] -= range;
+ } else {
+ this.range[o-1]=0;
+ }
+ if (this.range[o-1]==0)
+ o--; // lose this op.
+ }
+ e_range[e_o] += range; // just add more matched residues
+ break;
+ case I:
+ // change from insertion to match
+ if (last_d && diff<=0)
+ {
+ // reduce D's, if possible
+ if (range<=this.range[o-1]) {
+ this.range[o - 1] -= range;
+ } else {
+ this.range[o-1]=0;
+ }
+ if (this.range[o-1]==0)
+ o--; // lose this op.
+ }
+ e_range[e_o]
+ break;
+ default:
+ throw new Inp
+ }
+
+ break;
+ case I:
+ break;
+ case D:
+ }
+ break;
+ default:
+ throw new Error("Implementation Error: Unknown operation in addOperation!");
+ }
+ // finally, add remaining ops.
+ while (e_o<e_length) {
+ addOperation(e_op[e_o], e_range[e_o]);
+ e_o++;
+ }
+ }
}
+**/
+ /**
+ * Mark residues from start to end (inclusive) as deleted from the alignment, and removes any insertions.
+ * @param start int
+ * @param end int
+ */
+ public void deleteRange(int start, int end) {
+ if (length==0) {
+ // nothing to do here
+ return;
+ }
+ if (start<0 || start>end)
+ throw new Error("Implementation Error: deleteRange out of bounds: start must be non-negative and less than end.");
+ // find beginning
+ int cursor = 0; // mark the position for the current operation being edited.
+ int rlength=1+end-start; // number of positions to delete
+ int oldlen=length;
+ int o = 0;
+ boolean editing=false;
+ char[] oldops = operation;
+ int[] oldrange = range;
+ length=0;
+ operation = null;
+ range = null;
+ while (o<oldlen && cursor<=end && rlength>0) {
+ if (oldops[o] == D) {
+ // absorbed into new deleted region.
+ addDeleted(oldrange[o++]);
+ continue;
+ }
+ int remain = oldrange[o]; // number of op characters left to edit
+ if (!editing) {
+ if ( (cursor + remain) <= start)
+ {
+ addOperation(oldops[o],oldrange[o]);
+ cursor+=oldrange[o++];
+ continue; // next operation
+ }
+ editing=true;
+ // add operations before hidden region
+ if (start-cursor>0) {
+ addOperation(oldops[o], start- cursor);
+ remain -= start - cursor;
+ }
+ }
+ // start inserting new ops
+ if (o<oldlen && editing && rlength>0 && remain>0) {
+ switch (oldops[o]) {
+ case M:
+ if (rlength>remain) {
+ addDeleted(remain);
+ } else {
+ addDeleted(rlength);
+ if (remain-rlength>0)
+ this.addOperation(M,remain-rlength); // add remaining back.
+ rlength=0;
+ remain=0;
+ }
+ break;
+ case I:
+ if (remain-rlength>0) {
+ // only remove some gaps
+ addInsertion(remain-rlength);
+ rlength=0;
+ }
+ break;
+ case D:
+ throw new Error("Implementation error."); // do nothing;
+ default:
+ throw new Error("Implementation Error! Unknown operation '"+oldops[o]+"'");
+ }
+ rlength-=remain;
+ remain = oldrange[++o]; // number of op characters left to edit
+ }
+ }
+ // add remaining
+ while (o<oldlen) {
+ addOperation(oldops[o],oldrange[o++]);
+ }
+ //if (cursor<(start+1)) {
+ // ran out of ops - nothing to do here ?
+ // addInsertion(start-cursor);
+ //}
+ }
/**
* sum of ranges in cigar string
* @return int number of residues hidden, matched, or gaps inserted into sequence
* @param start alignment column
* @param end alignment column
* @return boolean true if residues were marked as deleted.
- */
public boolean deleteRange(int start, int end)
{
boolean deleted = false;
}
return deleted;
}
-
+*/
/**
* Return an ENSEMBL style cigar string where D may indicates excluded parts of seq
* @return String of form ([0-9]+[IMD])+
/**
- * DOCUMENT ME!
+ * propagate shift in alignment columns to column selection
*
- * @param start DOCUMENT ME!
- * @param change DOCUMENT ME!
+ * @param start beginning of edit
+ * @param change shift in edit (-ve or +ve number of columns)
*/
public void compensateForEdit(int start, int change)
{
package jalview.datamodel;
-import jalview.analysis.AlignSeq;
+import jalview.analysis.*;
+import jalview.util.ShiftList;
+import java.util.Vector;
public class SeqCigar
extends CigarSimple
{
-
- private SequenceI refseq=null;
+ /**
+ * start(inclusive) and end(exclusive) of subsequence on refseq
+ */
+ private int start, end;
+ private SequenceI refseq = null;
/**
* Reference dataset sequence for the cigar string
* @return SequenceI
*/
- public SequenceI getRefSeq() {
+ public SequenceI getRefSeq()
+ {
return refseq;
}
/**
+ *
+ * @return int start index of cigar ops on refSeq
+ */
+ public int getStart() {
+ return start;
+ }
+ /**
+ *
+ * @return int end index (exclusive) of cigar ops on refSeq
+ */
+ public int getEnd() {
+ return end;
+ }
+ /**
* Returns sequence as a string with cigar operations applied to it
* @return String
*/
public String getSequenceString(char GapChar)
{
- return (length==0) ? "" : (String) getSequenceAndDeletions(refseq.getSequence(), GapChar)[0];
+ return (length == 0) ? "" :
+ (String) getSequenceAndDeletions(refseq.getSequence().substring(start, end), GapChar)[0];
}
/**
* recreates a gapped and edited version of RefSeq or null for an empty cigar string
* @return SequenceI
*/
- public SequenceI getSeq(char GapChar) {
+ public SequenceI getSeq(char GapChar)
+ {
Sequence seq;
- if (refseq==null || length==0)
+ if (refseq == null || length == 0)
+ {
return null;
- Object[] edit_result=getSequenceAndDeletions(refseq.getSequence(), GapChar);
- if (edit_result==null)
- throw new Error("Implementation Error - unexpected null from getSequenceAndDeletions");
+ }
+ Object[] edit_result = getSequenceAndDeletions(refseq.getSequence().substring(start,end),
+ GapChar);
+ if (edit_result == null)
+ {
+ throw new Error(
+ "Implementation Error - unexpected null from getSequenceAndDeletions");
+ }
- seq = new Sequence(refseq.getName(), (String) edit_result[0], refseq.getStart()+((int[]) edit_result[1])[0], refseq.getStart()+((int[]) edit_result[1])[2]);
+ seq = new Sequence(refseq.getName(), (String) edit_result[0],
+ refseq.getStart() + start+( (int[]) edit_result[1])[0],
+ refseq.getStart() + start+( (int[]) edit_result[1])[2]);
seq.setDatasetSequence(refseq);
return seq;
}
+
/*
- We don't allow this - refseq is given at construction time only
+ We don't allow this - refseq is given at construction time only
public void setSeq(SequenceI seq) {
this.seq = seq;
- }
- */
+ }
+ */
/**
* internal constructor - sets seq to a gapless sequence derived from seq
* and prepends any 'D' operations needed to get to the first residue of seq.
* @param seq SequenceI
+ * @param initialDeletion true to mark initial dataset sequence residues as deleted in subsequence
+ * @param _s index of first position in seq
+ * @param _e index after last position in (possibly gapped) seq
* @return true if gaps are present in seq
*/
- private boolean _setSeq(SequenceI seq) {
- boolean hasgaps=false;
-
- if (seq==null)
- throw new Error("Implementation Error - _setSeq(null)");
-
- // Find correct sequence to reference and add initial hidden offset
- SequenceI ds = seq.getDatasetSequence();
- if (ds==null) {
- ds = new Sequence(seq.getName(),
- AlignSeq.extractGaps(jalview.util.Comparison.GapChars, new String(seq.getSequence())),
- seq.getStart(),
- seq.getEnd());
+ private boolean _setSeq(SequenceI seq, boolean initialDeletion, int _s, int _e)
+ {
+ boolean hasgaps = false;
+ if (seq == null)
+ {
+ throw new Error("Implementation Error - _setSeq(null,...)");
}
- // check that we haven't just duplicated an ungapped sequence.
- if (ds.getLength()==seq.getLength()) {
+ if (_s<0)
+ throw new Error("Implementation Error: _s="+_s);
+ String seq_string = seq.getSequence();
+ if (_e==0 || _e<_s || _e>seq_string.length())
+ _e=seq_string.length();
+ // resolve start and end positions relative to ungapped reference sequence
+ start = seq.findPosition(_s)-seq.getStart();
+ end = seq.findPosition(_e)-seq.getStart();
+ int l_ungapped = end-start;
+ // Find correct sequence to reference and correct start and end - if necessary
+ SequenceI ds = seq.getDatasetSequence();
+ if (ds == null)
+ {
+ // make a new dataset sequence
+ String ungapped = AlignSeq.extractGaps(jalview.util.Comparison.GapChars,
+ new String(seq_string));
+ l_ungapped=ungapped.length();
+ // check that we haven't just duplicated an ungapped sequence.
+ if (l_ungapped == seq.getLength())
+ {
ds = seq;
+ }
+ else
+ {
+ ds = new Sequence(seq.getName(), ungapped,
+ seq.getStart(),
+ seq.getStart()+ungapped.length()-1);
+ // JBPNote: this would be consistent but may not be useful
+ // seq.setDatasetSequence(ds);
+ }
+ }
+ // add in offset between seq and the dataset sequence
+ if (ds.getStart() < seq.getStart())
+ {
+ int offset=seq.getStart()-ds.getStart();
+ if (initialDeletion) {
+ // absolute cigar string
+ addDeleted(_s+offset);
+ start=0;
+ end+=offset;
} else {
- hasgaps = true;
+ // normal behaviour - just mark start and end subsequence
+ start+=offset;
+ end+=offset;
+
}
+
+ }
+
+ // any gaps to process ?
+ if (l_ungapped!=(_e-_s))
+ hasgaps=true;
+
this.refseq = ds;
- // Adjust offset
- if (ds.getStart()<seq.getStart()) {
- addDeleted(seq.getStart()-ds.getStart());
+
+ // Check offsets
+ if (end>ds.getLength()) {
+ throw new Error("SeqCigar: Possible implementation error: sequence is longer than dataset sequence");
+// end = ds.getLength();
}
+
return hasgaps;
}
+
/**
* directly initialise a cigar object with a sequence of range, operation pairs and a sequence to apply it to.
* operation and range should be relative to the seq.getStart()'th residue of the dataset seq resolved from seq.
* @param operation char[]
* @param range int[]
*/
- public SeqCigar(SequenceI seq, char operation[], int range[]) {
+ public SeqCigar(SequenceI seq, char operation[], int range[])
+ {
super();
- if (seq==null)
+ if (seq == null)
+ {
throw new Error("Implementation Bug. Null seq !");
- if (operation.length!=range.length) {
+ }
+ if (operation.length != range.length)
+ {
throw new Error("Implementation Bug. Cigar Operation list!= range list");
}
- if (operation!=null) {
- this.operation = new char[operation.length+_inc_length];
- this.range = new int[operation.length+_inc_length];
+ if (operation != null)
+ {
+ this.operation = new char[operation.length + _inc_length];
+ this.range = new int[operation.length + _inc_length];
- if (_setSeq(seq)) {
+ if (_setSeq(seq, false, 0, 0))
+ {
throw new Error("NOT YET Implemented: Constructing a Cigar object from a cigar string and a gapped sequence.");
}
- for (int i = this.length, j=0; j < operation.length; i++,j++)
+ for (int i = this.length, j = 0; j < operation.length; i++, j++)
{
char op = operation[j];
if (op != M && op != I && op != D)
{
throw new Error(
- "Implementation Bug. Cigar Operation '"+j+"' '"+op+"' not one of '"+M+"', '"+I+"', or '"+D+"'.");
+ "Implementation Bug. Cigar Operation '" + j + "' '" + op +
+ "' not one of '" + M + "', '" + I + "', or '" + D + "'.");
}
this.operation[i] = op;
this.range[i] = range[j];
}
- this.length+=operation.length;
- } else {
+ this.length += operation.length;
+ }
+ else
+ {
this.operation = null;
this.range = null;
- this.length=0;
- if (_setSeq(seq)) {
+ this.length = 0;
+ if (_setSeq(seq, false,0, 0))
+ {
throw new Error("NOT YET Implemented: Constructing a Cigar object from a cigar string and a gapped sequence.");
}
}
}
+
/**
* add range matched residues to cigar string
* @param range int
*/
- public void addMatch(int range) {
+ public void addMatch(int range)
+ {
this.addOperation(M, range);
}
+
/**
* Deleted regions mean that there will be discontinuous sequence numbering in the
* sequence returned by getSeq(char).
- * @return true if there are non-terminal deletions
+ * @return true if there deletions
*/
- public boolean hasDeletedRegions() {
- for (int i=1, l=length-1; i<l; i++) {
- if (operation[i]==D)
+ public boolean hasDeletedRegions()
+ {
+ for (int i = 0, l = length; i < l; i++)
+ {
+ if (operation[i] == D)
+ {
return true;
+ }
}
return false;
}
- protected static void addSequenceOps(CigarBase cigar, SequenceI seq, int startpos, int endpos) {
- char op = '\0';
- int range = 0;
- int p = 0, res = seq.getLength();
- startpos++;
- endpos++;
- while (p<res)
+
+ /**
+ * Adds
+ * insertion and match operations based on seq to the cigar up to
+ * the endpos column of seq.
+ *
+ * @param cigar CigarBase
+ * @param seq SequenceI
+ * @param startpos int
+ * @param endpos int
+ * @param initialDeletions if true then initial deletions will be added from start of seq to startpos
+ */
+ protected static void addSequenceOps(CigarBase cigar, SequenceI seq,
+ int startpos, int endpos, boolean initialDeletions)
{
- boolean isGap = jalview.util.Comparison.isGap(seq.getCharAt(p++));
- if ( (startpos <= p) && (p < endpos))
+ char op = '\0';
+ int range = 0;
+ int p = 0, res = seq.getLength();
+
+ if (!initialDeletions)
+ p=startpos;
+
+
+ while (p <= endpos)
{
- if (isGap)
+ boolean isGap = (p < res) ? jalview.util.Comparison.isGap(seq.getCharAt(p)) : true;
+ if ( (startpos <= p) && (p <= endpos))
{
- if (range > 0 && op != I)
+ if (isGap)
+ {
+ if (range > 0 && op != I)
+ {
+ cigar.addOperation(op, range);
+ range = 0;
+ }
+ op = I;
+ range++;
+ }
+ else
{
- cigar.addOperation(op, range);
- range = 0;
+ if (range > 0 && op != M)
+ {
+ cigar.addOperation(op, range);
+ range = 0;
+ }
+ op = M;
+ range++;
}
- op = I;
- range++;
}
else
{
- if (range > 0 && op != M)
+ if (!isGap)
{
- cigar.addOperation(op, range);
- range = 0;
+ if (range > 0 && op != D)
+ {
+ cigar.addOperation(op, range);
+ range = 0;
+ }
+ op = D;
+ range++;
}
- op = M;
- range++;
- }
- }
- else
- {
- if (!isGap)
- {
- if (range > 0 && op != D)
+ else
{
- cigar.addOperation(op, range);
- range = 0;
+ // do nothing - insertions are not made in flanking regions
}
- op = D;
- range++;
- }
- else
- {
- // do nothing - insertions are not recorded in flanking regions.
}
+ p++;
+ }
+ if (range > 0)
+ {
+ cigar.addOperation(op, range);
}
}
- if (range > 0)
- {
- cigar.addOperation(op, range);
- }
- }
+
/**
* create a cigar string for given sequence
* @param seq SequenceI
*/
- public SeqCigar(SequenceI seq) {
+ public SeqCigar(SequenceI seq)
+ {
super();
if (seq == null)
- throw new Error("Implementation error for new Cigar(SequenceI)");
- if (_setSeq(seq))
{
- // there is still work to do
- addSequenceOps(this, seq, 0, seq.getLength());
+ throw new Error("Implementation error for new Cigar(SequenceI)");
}
+ _setSeq(seq, false, 0, 0);
+ // there is still work to do
+ addSequenceOps(this, seq, 0, seq.getLength()-1, false);
}
- public SeqCigar(SequenceI seq, int start, int end) {
+
+ /**
+ * Create Cigar from a range of gaps and residues on a sequence object
+ * @param seq SequenceI
+ * @param start int - first column in range
+ * @param end int - last column in range
+ */
+ public SeqCigar(SequenceI seq, int start, int end)
+ {
super();
if (seq == null)
- throw new Error("Implementation error for new Cigar(SequenceI)");
- if (_setSeq(seq))
{
- // there is still work to do
- addSequenceOps(this, seq, start, end);
+ throw new Error("Implementation error for new Cigar(SequenceI)");
}
+ _setSeq(seq, false, start, end+1);
+ // there is still work to do
+ addSequenceOps(this, seq, start, end, false);
}
/**
Object[] opsandrange = parseCigarString(cigarString);
return new SeqCigar(seq, (char[]) opsandrange[0], (int[]) opsandrange[1]);
}
+
+ /**
+ * createAlignment
+ *
+ * @param alseqs SeqCigar[]
+ * @param gapCharacter char
+ * @return SequenceI[]
+ */
+ public static SequenceI[] createAlignmentSequences(SeqCigar[] alseqs,
+ char gapCharacter, ColumnSelection colsel)
+ {
+ SequenceI[] seqs = new SequenceI[alseqs.length];
+ Vector hiddenRegions=new Vector();
+ StringBuffer[] g_seqs = new StringBuffer[alseqs.length];
+ String[] alseqs_string=new String[alseqs.length];
+ Object[] gs_regions = new Object[alseqs.length];
+ for (int i = 0; i < alseqs.length; i++)
+ {
+ alseqs_string[i]=alseqs[i].getRefSeq().
+ getSequence().substring(alseqs[i].start,alseqs[i].end);
+ gs_regions[i] = alseqs[i].getSequenceAndDeletions(alseqs_string[i], gapCharacter); // gapped sequence, {start, start col, end. endcol}, hidden regions {{start, end, col}})
+ if (gs_regions[i] == null)
+ {
+ throw new Error("Implementation error: " + i +
+ "'th sequence Cigar has no operations.");
+ }
+ g_seqs[i] = new StringBuffer( (String) ( (Object[]) gs_regions[i])[0]); // the visible gapped sequence
+ }
+ // Now account for insertions.
+ // this is complicated because we must keep track of shifted positions in each sequence
+ ShiftList shifts = new ShiftList();
+ for (int i = 0; i < alseqs.length; i++)
+ {
+ Object[] gs_region = ( (Object[]) ( (Object[]) gs_regions[i])[2]);
+ if (gs_region != null)
+
+ {
+ for (int hr = 0; hr < gs_region.length; hr++)
+ {
+ int[] region = (int[]) gs_region[hr];
+ char[] insert = new char[region[1] - region[0] + 1];
+ for (int s = 0; s < insert.length; s++)
+ {
+ insert[s] = gapCharacter;
+ }
+ int inspos = shifts.shift(region[2]); // resolve insertion position in current alignment frame of reference
+ for (int s = 0; s < alseqs.length; s++)
+ {
+ if (s != i)
+ {
+ if (g_seqs[s].length() <= inspos)
+ {
+ // prefix insertion with more gaps.
+ for (int l = inspos - g_seqs[s].length(); l > 0; l--)
+ {
+ g_seqs[s].append(gapCharacter); // to debug - use a diffferent gap character here
+ }
+ }
+ g_seqs[s].insert(inspos, insert);
+ }
+ else
+ {
+ g_seqs[s].insert(inspos,
+ alseqs_string[i].substring(region[0], region[1] + 1));
+ }
+ }
+ shifts.addShift(region[2], insert.length); // update shift in alignment frame of reference
+ colsel.hideColumns(inspos, inspos+insert.length-1);
+ }
+ }
+ }
+ for (int i = 0; i < alseqs.length; i++)
+ {
+ int[] bounds = ( (int[]) ( (Object[]) gs_regions[i])[1]);
+ SequenceI ref = alseqs[i].getRefSeq();
+ seqs[i] = new Sequence(ref.getName(), g_seqs[i].toString(),
+ ref.getStart() + alseqs[i].start+bounds[0],
+ ref.getStart() + alseqs[i].start+bounds[2]);
+ seqs[i].setDatasetSequence(ref);
+ }
+ return seqs;
+ }
+
/**
* non rigorous testing
*/
* @param ex_cs_gapped String
* @return String
*/
- public static String testCigar_string(Sequence seq, String ex_cs_gapped) {
+ public static String testCigar_string(Sequence seq, String ex_cs_gapped)
+ {
SeqCigar c_sgapped = new SeqCigar(seq);
String cs_gapped = c_sgapped.getCigarstring();
if (!cs_gapped.equals(ex_cs_gapped))
- System.err.println("Failed getCigarstring: incorect string '"+cs_gapped+"' != "+ex_cs_gapped);
+ {
+ System.err.println("Failed getCigarstring: incorect string '" + cs_gapped +
+ "' != " + ex_cs_gapped);
+ }
return cs_gapped;
}
- public static boolean testSeqRecovery(SeqCigar gen_sgapped, SequenceI s_gapped) {
+
+ public static boolean testSeqRecovery(SeqCigar gen_sgapped,
+ SequenceI s_gapped)
+ {
+ // this is non-rigorous - start and end recovery is not tested.
SequenceI gen_sgapped_s = gen_sgapped.getSeq('-');
- if (!gen_sgapped_s.getSequence().equals(s_gapped.getSequence())) {
+ if (!gen_sgapped_s.getSequence().equals(s_gapped.getSequence()))
+ {
System.err.println("Couldn't reconstruct sequence.\n" +
gen_sgapped_s.getSequence() + "\n" +
s_gapped.getSequence());
}
return true;
}
- public static void main(String argv[]) throws Exception {
- Sequence s=new Sequence("MySeq", "asdfktryasdtqwrtsaslldddptyipqqwaslchvhttt",39,80);
+
+ public static void main(String argv[])
+ throws Exception
+ {
+ String o_seq;
+ Sequence s = new Sequence("MySeq",
+ o_seq = "asdfktryasdtqwrtsaslldddptyipqqwaslchvhttt",
+ 39, 80);
String orig_gapped;
- Sequence s_gapped=new Sequence("MySeq", orig_gapped="----asdf------ktryas---dtqwrtsasll----dddptyipqqwa----slchvhttt", 39,80);
- String ex_cs_gapped="4I4M6I6M3I11M4I12M4I9M";
+ Sequence s_gapped = new Sequence("MySeq",
+ orig_gapped = "----asdf------ktryas---dtqwrtsasll----dddptyipqqwa----slchvhttt",
+ 39, 80);
+ String ex_cs_gapped = "4I4M6I6M3I11M4I12M4I9M";
s_gapped.setDatasetSequence(s);
String sub_gapped_s;
- Sequence s_subsequence_gapped=new Sequence("MySeq", sub_gapped_s="------ktryas---dtqwrtsasll----dddptyipqqwa----slchvh", 43,77);
+ Sequence s_subsequence_gapped = new Sequence("MySeq",
+ sub_gapped_s = "------ktryas---dtqwrtsasll----dddptyipqqwa----slchvh",
+ 43, 77);
s_subsequence_gapped.setDatasetSequence(s);
SeqCigar c_null = new SeqCigar(s);
String cs_null = c_null.getCigarstring();
- if (cs_null.length()>0)
- System.err.println("Failed getCigarstring: Unexpected cigar operations:"+cs_null);
+ if (!cs_null.equals("42M"))
+ {
+ System.err.println(
+ "Failed to recover ungapped sequence cigar operations:" +
+ ( (cs_null == "") ? "empty string" : cs_null));
+ }
testCigar_string(s_gapped, ex_cs_gapped);
SeqCigar gen_sgapped = SeqCigar.parseCigar(s, ex_cs_gapped);
if (!gen_sgapped.getCigarstring().equals(ex_cs_gapped))
- System.err.println("Failed parseCigar("+ex_cs_gapped+")->getCigarString()->'"+gen_sgapped.getCigarstring()+"'");
+ {
+ System.err.println("Failed parseCigar(" + ex_cs_gapped +
+ ")->getCigarString()->'" + gen_sgapped.getCigarstring() +
+ "'");
+ }
testSeqRecovery(gen_sgapped, s_gapped);
// Test dataset resolution
SeqCigar sub_gapped = new SeqCigar(s_subsequence_gapped);
if (!testSeqRecovery(sub_gapped, s_subsequence_gapped))
- System.err.println("Failed recovery for subsequence of dataset sequence");
+ {
+ System.err.println("Failed recovery for subsequence of dataset sequence");
+ }
// width functions
- if (sub_gapped.getWidth()!=sub_gapped_s.length())
+ if (sub_gapped.getWidth() != sub_gapped_s.length())
+ {
System.err.println("Failed getWidth()");
+ }
sub_gapped.getFullWidth();
if (sub_gapped.hasDeletedRegions())
+ {
System.err.println("hasDeletedRegions is incorrect.");
+ }
// Test start-end region SeqCigar
- SeqCigar sub_se_gp= new SeqCigar(s_subsequence_gapped, 8, 48);
- if (sub_se_gp.getWidth()!=40)
- System.err.println("SeqCigar(seq, start, end) not properly clipped alignsequence.");
- System.out.println("Original sequence align:\n"+sub_gapped_s+"\nReconstructed window from 8 to 48\n"+"XXXXXXXX"+sub_se_gp.getSequenceString('-')+"...."+"\nCigar String:"+sub_se_gp.getCigarstring()+"");
+ SeqCigar sub_se_gp = new SeqCigar(s_subsequence_gapped, 8, 48);
+ if (sub_se_gp.getWidth() != 41)
+ {
+ System.err.println(
+ "SeqCigar(seq, start, end) not properly clipped alignsequence.");
+ }
+ System.out.println("Original sequence align:\n" + sub_gapped_s +
+ "\nReconstructed window from 8 to 48\n"
+ + "XXXXXXXX" + sub_se_gp.getSequenceString('-') + "..."
+ + "\nCigar String:" + sub_se_gp.getCigarstring() + "\n"
+ );
+ SequenceI ssgp = sub_se_gp.getSeq('-');
+ System.out.println("\t " + ssgp.getSequence());
+ for (int r = 0; r < 10; r++)
+ {
+ sub_se_gp = new SeqCigar(s_subsequence_gapped, 8, 48);
+ int sl = sub_se_gp.getWidth();
+ int st = sl - r - r;
+ for (int rs = 0; rs < 10; rs++)
+ {
+ int e = st + rs;
+ sub_se_gp.deleteRange(st, e);
+ String ssgapedseq = sub_se_gp.getSeq('-').getSequence();
+ System.out.println(st + "," + e + "\t:" + ssgapedseq);
+ }
+ }
+ {
+ SeqCigar[] set = new SeqCigar[]
+ {
+ new SeqCigar(s), new SeqCigar(s_subsequence_gapped, 8, 48),
+ new SeqCigar(s_gapped)};
+ Alignment al = new Alignment(set);
+ for (int i = 0; i < al.getHeight(); i++)
+ {
+ System.out.println("" + al.getSequenceAt(i).getName() + "\t" +
+ al.getSequenceAt(i).getStart() + "\t" +
+ al.getSequenceAt(i).getEnd() + "\t" +
+ al.getSequenceAt(i).getSequence());
+ }
+ }
+ {
+ System.out.println("Gapped.");
+ SeqCigar[] set = new SeqCigar[]
+ {
+ new SeqCigar(s), new SeqCigar(s_subsequence_gapped, 8, 48),
+ new SeqCigar(s_gapped)};
+ set[0].deleteRange(20, 25);
+ Alignment al = new Alignment(set);
+ for (int i = 0; i < al.getHeight(); i++)
+ {
+ System.out.println("" + al.getSequenceAt(i).getName() + "\t" +
+ al.getSequenceAt(i).getStart() + "\t" +
+ al.getSequenceAt(i).getEnd() + "\t" +
+ al.getSequenceAt(i).getSequence());
+ }
+ }
+// if (!ssgapedseq.equals("ryas---dtqqwa----slchvh"))
+// System.err.println("Subseqgaped\n------ktryas---dtqwrtsasll----dddptyipqqwa----slchvhryas---dtqwrtsasll--qwa----slchvh\n"+ssgapedseq+"\n"+sub_se_gp.getCigarstring());
}
}
Stack redoList = new Stack();\r
private int treeCount = 0;\r
\r
-\r
/**\r
- * Creates a new AlignFrame object.\r
- *\r
- * @param al DOCUMENT ME!\r
+ * new alignment window with hidden columns\r
+ * @param al AlignmentI\r
+ * @param hiddenColumns ColumnSelection or null\r
*/\r
- public AlignFrame(AlignmentI al)\r
- {\r
+ public AlignFrame(AlignmentI al, ColumnSelection hiddenColumns) {\r
\r
- viewport = new AlignViewport(al);\r
+ viewport = new AlignViewport(al, hiddenColumns);\r
\r
this.setDropTarget(new java.awt.dnd.DropTarget(this, this));\r
\r
\r
}\r
\r
+\r
+ /**\r
+ * Creates a new AlignFrame object.\r
+ *\r
+ * @param al DOCUMENT ME!\r
+ */\r
+ public AlignFrame(AlignmentI al)\r
+ {\r
+ this(al, null);\r
+ }\r
+\r
public AlignViewport getViewport()\r
{\r
return viewport;\r
* or just the selected set will be submitted for multiple alignment.\r
*\r
*/\r
- private SequenceI[] gatherSequencesForAlignment()\r
+ private jalview.datamodel.AlignmentView gatherSequencesForAlignment()\r
{\r
// Now, check we have enough sequences\r
- SequenceI[] msa = null;\r
+ AlignmentView msa = null;\r
\r
if ( (viewport.getSelectionGroup() != null) &&\r
(viewport.getSelectionGroup().getSize(false) > 1))\r
{\r
// JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
- SequenceGroup seqs = viewport.getSelectionGroup();\r
+ /*SequenceGroup seqs = viewport.getSelectionGroup();\r
int sz;\r
msa = new SequenceI[sz = seqs.getSize(false)];\r
\r
for (int i = 0; i < sz; i++)\r
{\r
msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
- }\r
+ } */\r
+ msa = viewport.getAlignmentView(true);\r
}\r
else\r
{\r
- Vector seqs = viewport.getAlignment().getSequences();\r
+ /*Vector seqs = viewport.getAlignment().getSequences();\r
\r
if (seqs.size() > 1)\r
{\r
{\r
msa[i] = (SequenceI) seqs.elementAt(i);\r
}\r
- }\r
+ }*/\r
+ msa = viewport.getAlignmentView(false);\r
}\r
return msa;\r
}\r
{\r
public void actionPerformed(ActionEvent e)\r
{\r
- SequenceI[] msa = gatherSequencesForAlignment();\r
+ AlignmentView msa = gatherSequencesForAlignment();\r
new jalview.ws.MsaWSClient(sh, title, msa,\r
false, true, viewport.getAlignment().getDataset(), af);\r
\r
{\r
public void actionPerformed(ActionEvent e)\r
{\r
- SequenceI[] msa = gatherSequencesForAlignment();\r
+ AlignmentView msa = gatherSequencesForAlignment();\r
new jalview.ws.MsaWSClient(sh, title, msa,\r
true, true, viewport.getAlignment().getDataset(), af);\r
\r
setAlignment(al);\r
init();\r
}\r
+ /**\r
+ * Create a new AlignViewport with hidden regions\r
+ * @param al AlignmentI\r
+ * @param hiddenColumns ColumnSelection\r
+ */\r
+ public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns) {\r
+ setAlignment(al);\r
+ if (hiddenColumns!=null) {\r
+ this.colSel = hiddenColumns;\r
+ if (hiddenColumns.getHiddenColumns() != null)\r
+ hasHiddenColumns = true;\r
+ }\r
+ init();\r
+ }\r
\r
void init()\r
{\r
iSize = selectionGroup.getSize(false);\r
seqs = selectionGroup.getSequencesInOrder(alignment);\r
start = selectionGroup.getStartRes();\r
- end = selectionGroup.getEndRes()+1;\r
+ end = selectionGroup.getEndRes(); // inclusive for start and end in SeqCigar constructor\r
}\r
else\r
{\r
iSize = alignment.getHeight();\r
seqs = alignment.getSequencesArray();\r
- end = alignment.getWidth();\r
+ end = alignment.getWidth()-1;\r
}\r
SeqCigar[] selseqs = new SeqCigar[iSize];\r
for(i=0; i<iSize; i++)\r
selseqs[i] = new SeqCigar(seqs[i], start, end);\r
}\r
selection=new CigarArray(selseqs);\r
-\r
- int[] hiddenregions = null;\r
- char[] hr_ops = null;\r
+ // now construct the CigarArray operations\r
if (hasHiddenColumns) {\r
- Vector _hiddenregions = new Vector();\r
Vector regions = colSel.getHiddenColumns();\r
- int blockStart = start, blockEnd=end;\r
int [] region;\r
int hideStart, hideEnd;\r
int last=start;\r
}\r
return selection;\r
}\r
-\r
+ /**\r
+ * return a compact representation of the current alignment selection to\r
+ * pass to an analysis function\r
+ * @param selectedOnly boolean true to just return the selected view\r
+ * @return AlignmentView\r
+ */\r
+ jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly) {\r
+ // JBPNote:\r
+ // this is here because the AlignmentView constructor modifies the CigarArray\r
+ // object. Refactoring of Cigar and alignment view representation should\r
+ // be done to remove redundancy.\r
+ CigarArray aligview = getViewAsCigars(selectedOnly);\r
+ if (aligview!=null)\r
+ return new AlignmentView(aligview);\r
+ return null;\r
+ }\r
/**\r
* This method returns the visible alignment as text, as\r
* seen on the GUI, ie if columns are hidden they will not\r
int top;\r
RotatableCanvas rc;\r
AlignViewport av;\r
- String [] seqstrings;\r
+ AlignmentView seqstrings;\r
SequenceI [] seqs;\r
\r
/**\r
\r
boolean sameLength = true;\r
\r
- seqstrings = av.getViewAsString(true);\r
-\r
- if (av.getSelectionGroup() == null)\r
+ seqstrings = av.getAlignmentView(av.getSelectionGroup()!=null);\r
+ if(av.getSelectionGroup()==null)\r
{\r
seqs = av.alignment.getSequencesArray();\r
}\r
{\r
seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);\r
}\r
-\r
- int length = seqs[0].getLength();\r
+ SeqCigar sq[]=seqstrings.getSequences();\r
+ int length = sq[0].getWidth();\r
\r
for (int i = 0; i < seqs.length; i++)\r
{\r
- if (seqs[i].getLength() != length)\r
+ if (sq[i].getWidth() != length)\r
{\r
sameLength = false;\r
break;\r
public void run()\r
{\r
try{\r
- pca = new PCA(seqstrings);\r
+ pca = new PCA(seqstrings.getSequenceStrings(' '));\r
pca.run();\r
\r
// Now find the component coordinates\r
\r
public void originalSeqData_actionPerformed(ActionEvent e)\r
{\r
- CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
- for (int i = 0; i < seqs.length; i++)\r
+ // this was cut'n'pasted from the equivalent TreePanel method - we should make this an abstract function of all jalview analysis windows\r
+ if (seqstrings==null)\r
{\r
- cap.appendText(new jalview.util.Format("%-" + 15 + "s").form(\r
- seqs[i].getName()));\r
- cap.appendText(" " + seqstrings[i] + "\n");\r
-\r
+ jalview.bin.Cache.log.info("Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");\r
+ return;\r
}\r
+ // decide if av alignment is sufficiently different to original data to warrant a new window to be created\r
+ // create new alignmnt window with hidden regions (unhiding hidden regions yields unaligned seqs)\r
+ // or create a selection box around columns in alignment view\r
+ // test Alignment(SeqCigar[])\r
+ Object[] alAndColsel = seqstrings.getAlignmentAndColumnSelection(av.\r
+ getGapCharacter());\r
+\r
+\r
+ if (alAndColsel != null && alAndColsel[0]!=null)\r
+ {\r
+ // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);\r
+\r
+ Alignment al = new Alignment((SequenceI[]) alAndColsel[0]);\r
+ Alignment dataset = av.getAlignment().getDataset();\r
+ if (dataset != null)\r
+ {\r
+ al.setDataset(dataset);\r
+ }\r
+\r
+ if (true)\r
+ {\r
+ // make a new frame!\r
+ AlignFrame af = new AlignFrame(al, (ColumnSelection) alAndColsel[1]);\r
+\r
+ //>>>This is a fix for the moment, until a better solution is found!!<<<\r
+ // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());\r
+\r
+ // af.addSortByOrderMenuItem(ServiceName + " Ordering",\r
+ // msaorder);\r
+\r
+ Desktop.addInternalFrame(af, "original Data for " + this.title,\r
+ AlignFrame.NEW_WINDOW_WIDTH,\r
+ AlignFrame.NEW_WINDOW_HEIGHT);\r
+ }\r
+ }\r
+ /* CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
+ for (int i = 0; i < seqs.length; i++)\r
+ {\r
+ cap.appendText(new jalview.util.Format("%-" + 15 + "s").form(\r
+ seqs[i].getName()));\r
+ cap.appendText(" " + seqstrings[i] + "\n");\r
\r
- Desktop.addInternalFrame(cap, "Original Data",\r
- 400, 400);\r
+ }\r
\r
+ Desktop.addInternalFrame(cap, "Original Data",\r
+ 400, 400);\r
+ */\r
}\r
\r
\r
class TreeLoader extends Thread\r
{\r
NewickFile newtree;\r
- jalview.datamodel.CigarArray odata=null;\r
+ jalview.datamodel.AlignmentView odata=null;\r
public TreeLoader(NewickFile newtree)\r
{\r
this.newtree = newtree;\r
{\r
int start, end;\r
SequenceI [] seqs;\r
- CigarArray seqStrings = av.getViewAsCigars(av.getSelectionGroup()!=null);\r
+ AlignmentView seqStrings = av.getAlignmentView(av.getSelectionGroup()!=null);\r
if(av.getSelectionGroup()==null)\r
{\r
start = 0;\r
\r
public void originalSeqData_actionPerformed(ActionEvent e)\r
{\r
- String originalData = tree.printOriginalSequenceData(av.getGapCharacter());\r
- if (originalData!=null) {\r
- CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
- cap.setText(originalData);\r
- Desktop.addInternalFrame(cap, "Original Data",\r
- 400, 400);\r
- } else {\r
- System.err.println("IMPLEMENTATION BUG! originalSeqData is not available.");\r
+ if (!tree.hasOriginalSequenceData())\r
+ {\r
+ jalview.bin.Cache.log.info("Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");\r
+ return;\r
}\r
-\r
+ // decide if av alignment is sufficiently different to original data to warrant a new window to be created\r
+ // create new alignmnt window with hidden regions (unhiding hidden regions yields unaligned seqs)\r
+ // or create a selection box around columns in alignment view\r
+ // test Alignment(SeqCigar[])\r
+ Object[] alAndColsel = tree.seqData.getAlignmentAndColumnSelection(av.\r
+ getGapCharacter());\r
+\r
+\r
+ if (alAndColsel != null && alAndColsel[0]!=null)\r
+ {\r
+ // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);\r
+\r
+ Alignment al = new Alignment((SequenceI[]) alAndColsel[0]);\r
+ Alignment dataset = av.getAlignment().getDataset();\r
+ if (dataset != null)\r
+ {\r
+ al.setDataset(dataset);\r
+ }\r
+\r
+ if (true)\r
+ {\r
+ // make a new frame!\r
+ AlignFrame af = new AlignFrame(al, (ColumnSelection) alAndColsel[1]);\r
+\r
+ //>>>This is a fix for the moment, until a better solution is found!!<<<\r
+ // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());\r
+\r
+ // af.addSortByOrderMenuItem(ServiceName + " Ordering",\r
+ // msaorder);\r
+\r
+ Desktop.addInternalFrame(af, "original Data for " + this.title,\r
+ AlignFrame.NEW_WINDOW_WIDTH,\r
+ AlignFrame.NEW_WINDOW_HEIGHT);\r
+ }\r
+ }\r
}\r
\r
\r
--- /dev/null
+package jalview.util;
+
+import java.util.*;
+
+/**
+ * ShiftList
+ * Simple way of mapping a linear series to a new linear range with new points introduced.
+ * Use at your own risk!
+ * <p>Title: ShiftList</p>
+ *
+ * <p>Description: </p>
+ *
+ * <p>Copyright: Copyright (c) 2004</p>
+ *
+ * <p>Company: Dundee University</p>
+ *
+ * @author not attributable
+ * @version 1.0
+ */
+public class ShiftList
+{
+ Vector shifts;
+ public ShiftList()
+ {
+ shifts = new Vector();
+ }
+
+ /**
+ * addShift
+ * @param pos start position for shift (in original reference frame)
+ * @param shift length of shift
+ */
+ public void addShift(int pos, int shift)
+ {
+ int sidx = 0;
+ int[] rshift=null;
+ while (sidx<shifts.size() && (rshift=(int[]) shifts.get(sidx))[0]<pos)
+ sidx++;
+ if (sidx==shifts.size())
+ shifts.insertElementAt(new int[] { pos, shift}, 0);
+ else
+ rshift[1]+=shift;
+ }
+
+ /**
+ * shift
+ *
+ * @param pos int
+ * @return int shifted position
+ */
+ public int shift(int pos)
+ {
+ if (shifts.size()==0)
+ return pos;
+ int shifted=pos;
+ int sidx=0;
+ int rshift[];
+ while (sidx<shifts.size()
+ &&
+ (rshift=((int[]) shifts.get(sidx++)))[0]<=pos) {
+ shifted += rshift[1];
+ }
+ return shifted;
+ }
+
+ /**
+ * clear all shifts
+ */
+ public void clear()
+ {
+ shifts.removeAllElements();
+ }
+
+}
*/\r
\r
public MsaWSClient(ext.vamsas.ServiceHandle sh, String altitle,\r
- SequenceI[] msa,\r
+ jalview.datamodel.AlignmentView msa,\r
boolean submitGaps, boolean preserveOrder,\r
Alignment seqdataset,\r
AlignFrame _alignFrame)\r
}\r
\r
\r
- private void startMsaWSClient(String altitle, SequenceI[] msa,\r
+ private void startMsaWSClient(String altitle, AlignmentView msa,\r
boolean submitGaps, boolean preserveOrder, Alignment seqdataset)\r
{\r
if (!locateWebService())\r
return true;\r
}\r
\r
+ protected String getServiceActionKey()\r
+ {\r
+ return "MsaWS";\r
+ }\r
+\r
+ protected String getServiceActionDescription()\r
+ {\r
+ return "Multiple Sequence Alignment";\r
+ }\r
+\r
protected class MsaWSThread\r
extends Thread implements WSClientI\r
{\r
\r
Alignment dataset; // dataset to which the new alignment will be associated.\r
\r
- MsaWSThread(String title, SequenceI[] msa, boolean subgaps,\r
+ MsaWSThread(String title, AlignmentView _msa, boolean subgaps,\r
boolean presorder, Alignment seqset)\r
{\r
+ // jbpnote - transformation should be above here - this is per sequence set contig, not for many contigs.\r
alTitle = title;\r
submitGaps = subgaps;\r
preserveOrder = presorder;\r
dataset = seqset;\r
OutputHeader = wsInfo.getProgressText();\r
SeqNames = new Hashtable();\r
-\r
+ SeqCigar[] msa = _msa.getSequences();\r
vamsas.objects.simple.Sequence[] seqarray = new vamsas.objects.simple.\r
Sequence[msa.length];\r
\r
- for (int i = 0; i < msa.length; i++)\r
+ for (int i = 0,n=0; i < msa.length; i++)\r
{\r
String newname = jalview.analysis.SeqsetUtils.unique_name(i);\r
-\r
+ SequenceI mseq = msa[i].getSeq('-');\r
// uniquify as we go\r
// TODO: JBPNote: this is a ubiquitous transformation - set of jalview seq objects to vamsas sequences with name preservation\r
SeqNames.put(newname,\r
- jalview.analysis.SeqsetUtils.SeqCharacterHash(msa[i]));\r
+ jalview.analysis.SeqsetUtils.SeqCharacterHash(mseq));\r
seqarray[i] = new vamsas.objects.simple.Sequence();\r
seqarray[i].setId(newname);\r
- seqarray[i].setSeq( (submitGaps) ? msa[i].getSequence()\r
+ seqarray[i].setSeq( (submitGaps) ? mseq.getSequence()\r
: AlignSeq.extractGaps(\r
jalview.util.Comparison.GapChars,\r
- msa[i].getSequence()));\r
+ mseq.getSequence()));\r
}\r
\r
this.seqs = new vamsas.objects.simple.SequenceSet();\r