import jalview.util.MapList;
import jalview.util.MappingUtils;
+import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
public class AlignedCodonFrame
{
- /*
- * Data bean to hold mappings from one sequence to another
- */
- private class SequenceToSequenceMapping
- {
- private SequenceI fromSeq;
-
- private Mapping mapping;
-
- SequenceToSequenceMapping(SequenceI from, Mapping map)
- {
- this.fromSeq = from;
- this.mapping = map;
- }
-
- /**
- * Readable representation for debugging only, not guaranteed not to change
- */
- @Override
- public String toString()
- {
- return String.format("From %s %s", fromSeq.getName(),
- mapping.toString());
- }
- }
-
- private List<SequenceToSequenceMapping> mappings;
+ private List<SequenceMapping> mappings;
/**
* Constructor
*/
public AlignedCodonFrame()
{
- mappings = new ArrayList<SequenceToSequenceMapping>();
+ mappings = new ArrayList<>();
}
/**
*/
public void addMap(SequenceI dnaseq, SequenceI aaseq, MapList map)
{
+ addMap(dnaseq, aaseq, map, null);
+ }
+
+ /**
+ * Adds a mapping between the dataset sequences for the associated dna and
+ * protein sequence objects
+ *
+ * @param dnaseq
+ * @param aaseq
+ * @param map
+ * @param mapFromId
+ */
+ public void addMap(SequenceI dnaseq, SequenceI aaseq, MapList map,
+ String mapFromId)
+ {
// JBPNote DEBUG! THIS !
// dnaseq.transferAnnotation(aaseq, mp);
// aaseq.transferAnnotation(dnaseq, new Mapping(map.getInverse()));
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
+ * note that 'adding' a duplicate map does nothing; this protects against
+ * creating duplicate mappings in AlignedCodonFrame
*/
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
if (ssm.fromSeq == fromSeq && ssm.mapping.to == toSeq)
{
* otherwise, add a new sequence mapping
*/
Mapping mp = new Mapping(toSeq, map);
- mappings.add(new SequenceToSequenceMapping(fromSeq, mp));
+ mp.setMappedFromId(mapFromId);
+ mappings.add(new SequenceMapping(fromSeq, mp));
}
public SequenceI[] getdnaSeqs()
{
// TODO return a list instead?
// return dnaSeqs;
- List<SequenceI> seqs = new ArrayList<SequenceI>();
- for (SequenceToSequenceMapping ssm : mappings)
+ List<SequenceI> seqs = new ArrayList<>();
+ for (SequenceMapping ssm : mappings)
{
seqs.add(ssm.fromSeq);
}
public SequenceI[] getAaSeqs()
{
// TODO not used - remove?
- List<SequenceI> seqs = new ArrayList<SequenceI>();
- for (SequenceToSequenceMapping ssm : mappings)
+ List<SequenceI> seqs = new ArrayList<>();
+ for (SequenceMapping ssm : mappings)
{
seqs.add(ssm.mapping.to);
}
public MapList[] getdnaToProt()
{
- List<MapList> maps = new ArrayList<MapList>();
- for (SequenceToSequenceMapping ssm : mappings)
+ List<MapList> maps = new ArrayList<>();
+ for (SequenceMapping ssm : mappings)
{
maps.add(ssm.mapping.map);
}
public Mapping[] getProtMappings()
{
- List<Mapping> maps = new ArrayList<Mapping>();
- for (SequenceToSequenceMapping ssm : mappings)
+ List<Mapping> maps = new ArrayList<>();
+ for (SequenceMapping ssm : mappings)
{
maps.add(ssm.mapping);
}
* @param seq
* @return
*/
- public Mapping getMappingForSequence(SequenceI seq)
+ public Mapping getMappingForSequence(SequenceI seq, boolean cdsOnly)
{
SequenceI seqDs = seq.getDatasetSequence();
seqDs = seqDs != null ? seqDs : seq;
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
if (ssm.fromSeq == seqDs || ssm.mapping.to == seqDs)
{
- return ssm.mapping;
+ if (!cdsOnly || ssm.fromSeq.getName().startsWith("CDS")
+ || ssm.mapping.to.getName().startsWith("CDS"))
+ {
+ return ssm.mapping;
+ }
}
}
return null;
public SequenceI getAaForDnaSeq(SequenceI dnaSeqRef)
{
SequenceI dnads = dnaSeqRef.getDatasetSequence();
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
if (ssm.fromSeq == dnaSeqRef || ssm.fromSeq == dnads)
{
public SequenceI getDnaForAaSeq(SequenceI aaSeqRef)
{
SequenceI aads = aaSeqRef.getDatasetSequence();
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
if (ssm.mapping.to == aaSeqRef || ssm.mapping.to == aads)
{
* where highlighted regions go
*/
public void markMappedRegion(SequenceI seq, int index,
- SearchResults results)
+ SearchResultsI results)
{
int[] codon;
SequenceI ds = seq.getDatasetSequence();
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
if (ssm.fromSeq == seq || ssm.fromSeq == ds)
{
*/
MapList ml = null;
int i = 0;
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
if (ssm.fromSeq == seq)
{
/**
* Convenience method to return the first aligned sequence in the given
- * alignment whose dataset has a mapping with the given dataset sequence.
+ * alignment whose dataset has a mapping with the given (aligned or dataset)
+ * sequence.
*
* @param seq
*
/*
* Search mapped protein ('to') sequences first.
*/
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
- if (ssm.fromSeq == seq)
+ if (ssm.fromSeq == seq || ssm.fromSeq == seq.getDatasetSequence())
{
for (SequenceI sourceAligned : al.getSequences())
{
/*
* Then try mapped dna sequences.
*/
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
- if (ssm.mapping.to == seq)
+ if (ssm.mapping.to == seq
+ || ssm.mapping.to == seq.getDatasetSequence())
{
for (SequenceI sourceAligned : al.getSequences())
{
{
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;
}
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
/*
* try mapping from target to query
{
MapList ml = null;
SequenceI dnaSeq = null;
- List<char[]> result = new ArrayList<char[]>();
+ List<char[]> result = new ArrayList<>();
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
- if (ssm.mapping.to == protein)
+ if (ssm.mapping.to == protein
+ && ssm.mapping.getMap().getFromRatio() == 3)
{
ml = ssm.mapping.map;
dnaSeq = ssm.fromSeq;
* 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;
}
/**
- * Returns any mappings found which are to (or from) the given sequence, and
- * to distinct sequences.
+ * Returns any mappings found which are from the given sequence, and to
+ * distinct sequences.
*
* @param seq
* @return
*/
- public List<Mapping> getMappingsForSequence(SequenceI seq)
+ 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;
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
final Mapping mapping = ssm.mapping;
- if (ssm.fromSeq == seqDs || mapping.to == seqDs)
+ if (ssm.fromSeq == seqDs)
{
if (!related.contains(mapping.to))
{
*/
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;
/*
* check for replaceable DNA ('map from') sequences
*/
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
{
SequenceI dna = ssm.fromSeq;
if (dna instanceof SequenceDummy
{
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 ds = seq.getDatasetSequence();
- for (SequenceToSequenceMapping ssm : mappings)
+ for (SequenceMapping ssm : mappings)
/*
* 'from' sequences
*/
{
return mappings.isEmpty();
}
+
+ /**
+ * Method for debug / inspection purposes only, may change in future
+ */
+ @Override
+ public String toString()
+ {
+ return mappings == null ? "null" : mappings.toString();
+ }
+
+ /**
+ * Returns the first mapping found that is between 'fromSeq' and 'toSeq', or
+ * null if none found
+ *
+ * @param fromSeq
+ * aligned or dataset sequence
+ * @param toSeq
+ * aligned or dataset sequence
+ * @return
+ */
+ public Mapping getMappingBetween(SequenceI fromSeq, SequenceI toSeq)
+ {
+ SequenceI dssFrom = fromSeq.getDatasetSequence() == null ? fromSeq
+ : fromSeq.getDatasetSequence();
+ SequenceI dssTo = toSeq.getDatasetSequence() == null ? toSeq
+ : toSeq.getDatasetSequence();
+
+ for (SequenceMapping mapping : mappings)
+ {
+ SequenceI from = mapping.fromSeq;
+ SequenceI to = mapping.mapping.to;
+ if ((from == dssFrom && to == dssTo)
+ || (from == dssTo && to == dssFrom))
+ {
+ return mapping.mapping;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns a hashcode derived from the list of sequence mappings
+ *
+ * @see SequenceMapping#hashCode()
+ * @see AbstractList#hashCode()
+ */
+ @Override
+ public int hashCode()
+ {
+ return this.mappings.hashCode();
+ }
+
+ /**
+ * Two AlignedCodonFrame objects are equal if they hold the same ordered list
+ * of mappings
+ *
+ * @see SequenceToSequenceMapping#
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof AlignedCodonFrame))
+ {
+ return false;
+ }
+ return this.mappings.equals(((AlignedCodonFrame) obj).mappings);
+ }
+
+ public List<SequenceMapping> getMappings()
+ {
+ return mappings;
+ }
}