*/
package jalview.datamodel;
-import jalview.util.MapList;
-import jalview.util.MappingUtils;
-
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
+import jalview.util.MapList;
+import jalview.util.MappingUtils;
+
/**
* Stores mapping between the columns of a protein alignment and a DNA alignment
* and a list of individual codon to amino acid mappings between sequences.
return that.mapping == null;
}
// TODO: can simplify by asserting fromSeq is a dataset sequence
- return (this.fromSeq == that.fromSeq || (this.fromSeq != null
- && that.fromSeq != null
- && this.fromSeq.getDatasetSequence() != null && this.fromSeq
- .getDatasetSequence() == that.fromSeq.getDatasetSequence()))
+ return (this.fromSeq == that.fromSeq
+ || (this.fromSeq != null && that.fromSeq != null
+ && this.fromSeq.getDatasetSequence() != null
+ && this.fromSeq.getDatasetSequence() == that.fromSeq
+ .getDatasetSequence()))
&& this.mapping.equals(that.mapping);
}
{
return mapping;
}
+
+ /**
+ * Returns true if the mapping covers the full length of the given sequence.
+ * This allows us to distinguish the CDS that codes for a protein from
+ * another overlapping CDS in the parent dna sequence.
+ *
+ * @param seq
+ * @return
+ */
+ public boolean covers(SequenceI seq)
+ {
+ List<int[]> mappedRanges = null;
+ MapList mapList = mapping.getMap();
+ if (fromSeq == seq || fromSeq == seq.getDatasetSequence())
+ {
+ mappedRanges = mapList.getFromRanges();
+ }
+ else if (mapping.to == seq || mapping.to == seq.getDatasetSequence())
+ {
+ mappedRanges = mapList.getToRanges();
+ }
+ else
+ {
+ return false;
+ }
+
+ /*
+ * check that each mapped range lies within the sequence range
+ * (necessary for circular CDS - example EMBL:J03321:AAA91567)
+ * and mapped length covers (at least) sequence length
+ */
+ int length = 0;
+ for (int[] range : mappedRanges)
+ {
+ int from = Math.min(range[0], range[1]);
+ int to = Math.max(range[0], range[1]);
+ if (from < seq.getStart() || to > seq.getEnd())
+ {
+ return false;
+ }
+ length += (to - from + 1);
+ }
+ // add 1 to mapped length to allow for a mapped stop codon
+ if (length + 1 < (seq.getEnd() - seq.getStart() + 1))
+ {
+ return false;
+ }
+ return true;
+ }
}
private List<SequenceToSequenceMapping> mappings;
*/
public AlignedCodonFrame()
{
- mappings = new ArrayList<SequenceToSequenceMapping>();
+ mappings = new ArrayList<>();
}
/**
SequenceI fromSeq = (dnaseq.getDatasetSequence() == null) ? dnaseq
: dnaseq.getDatasetSequence();
- SequenceI toSeq = (aaseq.getDatasetSequence() == null) ? aaseq : aaseq
- .getDatasetSequence();
+ SequenceI toSeq = (aaseq.getDatasetSequence() == null) ? aaseq
+ : aaseq.getDatasetSequence();
/*
* if we already hold a mapping between these sequences, just add to it
{
// TODO return a list instead?
// return dnaSeqs;
- List<SequenceI> seqs = new ArrayList<SequenceI>();
+ List<SequenceI> seqs = new ArrayList<>();
for (SequenceToSequenceMapping ssm : mappings)
{
seqs.add(ssm.fromSeq);
public SequenceI[] getAaSeqs()
{
// TODO not used - remove?
- List<SequenceI> seqs = new ArrayList<SequenceI>();
+ List<SequenceI> seqs = new ArrayList<>();
for (SequenceToSequenceMapping ssm : mappings)
{
seqs.add(ssm.mapping.to);
public MapList[] getdnaToProt()
{
- List<MapList> maps = new ArrayList<MapList>();
+ List<MapList> maps = new ArrayList<>();
for (SequenceToSequenceMapping ssm : mappings)
{
maps.add(ssm.mapping.map);
public Mapping[] getProtMappings()
{
- List<Mapping> maps = new ArrayList<Mapping>();
+ List<Mapping> maps = new ArrayList<>();
for (SequenceToSequenceMapping ssm : mappings)
{
maps.add(ssm.mapping);
/**
* Returns the first mapping found which is to or from the given sequence, or
- * null.
+ * null if none is found
*
* @param seq
* @return
}
/**
+ * Return the corresponding aligned or dataset dna sequence for given amino
+ * acid sequence, or null if not found. returns the sequence from the first
+ * mapping found that involves the protein sequence.
*
- * @param sequenceRef
- * @return null or corresponding aaSeq entry for dnaSeq entry
+ * @param aaSeqRef
+ * @return
*/
public SequenceI getDnaForAaSeq(SequenceI aaSeqRef)
{
* where highlighted regions go
*/
public void markMappedRegion(SequenceI seq, int index,
- SearchResults results)
+ SearchResultsI results)
{
int[] codon;
SequenceI ds = seq.getDatasetSequence();
{
SequenceI targetDs = target.getDatasetSequence() == null ? target
: target.getDatasetSequence();
- SequenceI queryDs = query.getDatasetSequence() == null ? query : query
- .getDatasetSequence();
+ SequenceI queryDs = query.getDatasetSequence() == null ? query
+ : query.getDatasetSequence();
if (targetDs == null || queryDs == null /*|| dnaToProt == null*/)
{
return null;
{
MapList ml = null;
SequenceI dnaSeq = null;
- List<char[]> result = new ArrayList<char[]>();
+ List<char[]> result = new ArrayList<>();
for (SequenceToSequenceMapping ssm : mappings)
{
* Read off the mapped nucleotides (converting to position base 0)
*/
codonPos = MappingUtils.flattenRanges(codonPos);
- char[] dna = dnaSeq.getSequence();
int start = dnaSeq.getStart();
- result.add(new char[] { dna[codonPos[0] - start],
- dna[codonPos[1] - start], dna[codonPos[2] - start] });
+ char c1 = dnaSeq.getCharAt(codonPos[0] - start);
+ char c2 = dnaSeq.getCharAt(codonPos[1] - start);
+ char c3 = dnaSeq.getCharAt(codonPos[2] - start);
+ result.add(new char[] { c1, c2, c3 });
}
}
return result.isEmpty() ? null : result;
*/
public List<Mapping> getMappingsFromSequence(SequenceI seq)
{
- List<Mapping> result = new ArrayList<Mapping>();
- List<SequenceI> related = new ArrayList<SequenceI>();
+ List<Mapping> result = new ArrayList<>();
+ List<SequenceI> related = new ArrayList<>();
SequenceI seqDs = seq.getDatasetSequence();
seqDs = seqDs != null ? seqDs : seq;
*/
protected int realiseWith(SequenceI seq, boolean doUpdate)
{
- SequenceI ds = seq.getDatasetSequence() != null ? seq
- .getDatasetSequence() : seq;
+ SequenceI ds = seq.getDatasetSequence() != null
+ ? seq.getDatasetSequence()
+ : seq;
int count = 0;
/*
{
int start = replacement.getStart();
int end = replacement.getEnd();
- boolean mappingOverlapsSequence = (mapStart >= start && mapStart <= end)
- || (mapEnd >= start && mapEnd <= end);
+ boolean mappingOverlapsSequence = (mapStart >= start
+ && mapStart <= end) || (mapEnd >= start && mapEnd <= end);
if (mappingOverlapsSequence)
{
return true;
{
SequenceI dssFrom = fromSeq.getDatasetSequence() == null ? fromSeq
: fromSeq.getDatasetSequence();
- SequenceI dssTo = toSeq.getDatasetSequence() == null ? toSeq : toSeq
- .getDatasetSequence();
+ SequenceI dssTo = toSeq.getDatasetSequence() == null ? toSeq
+ : toSeq.getDatasetSequence();
for (SequenceToSequenceMapping mapping : mappings)
{
* Two AlignedCodonFrame objects are equal if they hold the same ordered list
* of mappings
*
- * @see SequenceToSequenceMapping#
+ * @see SequenceToSequenceMapping#equals
*/
@Override
public boolean equals(Object obj)
{
return mappings;
}
+
+ /**
+ * Returns the first mapping found which is between the two given sequences,
+ * and covers the full extent of both.
+ *
+ * @param seq1
+ * @param seq2
+ * @return
+ */
+ public SequenceToSequenceMapping getCoveringMapping(SequenceI seq1,
+ SequenceI seq2)
+ {
+ for (SequenceToSequenceMapping mapping : mappings)
+ {
+ if (mapping.covers(seq2) && mapping.covers(seq1))
+ {
+ return mapping;
+ }
+ }
+ return null;
+ }
}