/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9)
- * Copyright (C) 2015 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
*
* This file is part of Jalview.
*
*/
package jalview.datamodel;
+import jalview.util.Comparison;
import jalview.util.MapList;
import java.util.Iterator;
private final char[] alignedSeq;
/*
+ * the sequence start residue
+ */
+ private int start;
+
+ /*
* Next position (base 0) in the aligned sequence
*/
private int alignedColumn = 0;
/**
* Constructor
*
- * @param cs
- * the aligned sequence characters
+ * @param seq
+ * the aligned sequence
* @param gapChar
*/
- public AlignedCodonIterator(char[] cs, char gapChar)
+ public AlignedCodonIterator(SequenceI seq, char gapChar)
{
- this.alignedSeq = cs;
+ this.alignedSeq = seq.getSequence();
+ this.start = seq.getStart();
this.gap = gapChar;
fromRanges = map.getFromRanges().iterator();
toRanges = map.getToRanges().iterator();
int[] alignedCodon = getAlignedCodon(codon);
String peptide = getPeptide();
+ int peptideCol = toPosition - 1 - Mapping.this.to.getStart();
return new AlignedCodon(alignedCodon[0], alignedCodon[1],
- alignedCodon[2], peptide);
+ alignedCodon[2], peptide, peptideCol);
}
/**
* sequence.
*
* @return
+ * @throws NoSuchElementException
+ * if the 'toRange' is exhausted (nothing to map to)
*/
private String getPeptide()
{
// i.e. code like getNextCodon()
if (toPosition <= currentToRange[1])
{
- char pep = Mapping.this.to.getSequence()[toPosition - 1];
+ SequenceI seq = Mapping.this.to;
+ char pep = seq.getSequence()[toPosition - seq.getStart()];
toPosition++;
return String.valueOf(pep);
}
*/
private int getAlignedColumn(int sequencePos)
{
- while (alignedBases < sequencePos
- && alignedColumn < alignedSeq.length)
+ /*
+ * allow for offset e.g. treat pos 8 as 2 if sequence starts at 7
+ */
+ int truePos = sequencePos - (start - 1);
+ while (alignedBases < truePos && alignedColumn < alignedSeq.length)
{
- if (alignedSeq[alignedColumn++] != gap)
+ char c = alignedSeq[alignedColumn++];
+ if (c != gap && !Comparison.isGap(c))
{
alignedBases++;
}
}
- /**
+ /*
* Contains the start-end pairs mapping from the associated sequence to the
* sequence in the database coordinate system. It also takes care of step
* difference between coordinate systems.
*/
MapList map = null;
- /**
+ /*
* The sequence that map maps the associated sequence to (if any).
*/
SequenceI to = null;
+ /*
+ * optional sequence id for the 'from' ranges
+ */
+ private String mappedFromId;
+
public Mapping(MapList map)
{
super();
map = new MapList(map2.map);
}
to = map2.to;
+ mappedFromId = map2.mappedFromId;
}
}
/**
* Equals that compares both the to references and MapList mappings.
*
- * @param other
+ * @param o
* @return
+ * @see MapList#equals
*/
@Override
public boolean equals(Object o)
{
- // TODO should override Object.hashCode() to ensure that equal objects have
- // equal hashcodes
if (o == null || !(o instanceof Mapping))
{
return false;
}
/**
+ * Returns a hashCode made from the sequence and maplist
+ */
+ @Override
+ public int hashCode()
+ {
+ int hashCode = (this.to == null ? 1 : this.to.hashCode());
+ if (this.map != null)
+ {
+ hashCode = hashCode * 31 + this.map.hashCode();
+ }
+
+ return hashCode;
+ }
+
+ /**
* get the 'initial' position in the associated sequence for a position in the
* mapped reference frame
*
*
* @see java.lang.Object#finalize()
*/
+ @Override
protected void finalize() throws Throwable
{
map = null;
super.finalize();
}
+ /**
+ * Returns an iterator which can serve up the aligned codon column positions
+ * and their corresponding peptide products
+ *
+ * @param seq
+ * an aligned (i.e. possibly gapped) sequence
+ * @param gapChar
+ * @return
+ */
public Iterator<AlignedCodon> getCodonIterator(SequenceI seq, char gapChar)
{
- return new AlignedCodonIterator(seq.getSequence(), gapChar);
+ return new AlignedCodonIterator(seq, gapChar);
+ }
+
+ /**
+ * Readable representation for debugging only, not guaranteed not to change
+ */
+ @Override
+ public String toString()
+ {
+ return String.format("%s %s", this.map.toString(), this.to == null ? ""
+ : this.to.getName());
+ }
+
+ /**
+ * Returns the identifier for the 'from' range sequence, or null if not set
+ *
+ * @return
+ */
+ public String getMappedFromId()
+ {
+ return mappedFromId;
+ }
+
+ /**
+ * Sets the identifier for the 'from' range sequence
+ */
+ public void setMappedFromId(String mappedFromId)
+ {
+ this.mappedFromId = mappedFromId;
}
}