import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Map;
+import java.util.Map.Entry;
import fr.orsay.lri.varna.models.rna.RNA;
// System.out.println("featuregroup " + _rnasecstr[0].getFeatureGroup());
}
- public java.util.Hashtable sequenceMapping;
+ public java.util.Hashtable<Integer, Annotation> sequenceMapping;
/** DOCUMENT ME!! */
public float graphMin;
{
return isrna;
}
+
+ /**
+ * transfer annotation to the given sequence using the given mapping from the
+ * current positions or an existing sequence mapping
+ *
+ * @param sq
+ * @param sp2sq
+ * map involving sq as To or From
+ */
+ public void liftOver(SequenceI sq, Mapping sp2sq)
+ {
+ boolean mapIsTo = (sp2sq != null) ? (sp2sq.getTo() == sq || sp2sq
+ .getTo() == sq.getDatasetSequence()) : false;
+
+ // TODO build a better annotation element map and get rid of annotations[]
+ Hashtable<Integer, Annotation> mapForsq = new Hashtable();
+ if (sequenceMapping != null)
+ {
+ if (sp2sq != null)
+ {
+ for (Entry<Integer, Annotation> ie : sequenceMapping.entrySet())
+ {
+ Integer mpos = Integer.valueOf(mapIsTo ? sp2sq
+ .getMappedPosition(ie.getKey()) : sp2sq.getPosition(ie
+ .getKey()));
+ if (mpos >= sq.getStart() && mpos <= sq.getEnd())
+ {
+ mapForsq.put(mpos, ie.getValue());
+ }
+ }
+ sequenceMapping = mapForsq;
+ sequenceRef = sq;
+ adjustForAlignment();
+ }
+ else
+ {
+ // trim positions
+ }
+ }
+
+ }
}
--- /dev/null
+package jalview.datamodel;
+
+import static org.junit.Assert.*;
+
+import java.awt.Frame;
+
+import javax.swing.JFrame;
+import javax.swing.SwingWorker;
+
+import jalview.analysis.AlignSeq;
+import jalview.gui.AlignFrame;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.FormatAdapter;
+
+import org.junit.Test;
+
+public class AlignmentAnnotationTests
+{
+ /**
+ * create some dummy annotation derived from the sequence
+ *
+ * @param sq
+ */
+ public static void createAnnotation(SequenceI sq)
+ {
+ Annotation[] al = new Annotation[sq.getLength()];
+ for (int i = 0; i < al.length; i++)
+ {
+ al[i] = new Annotation(new Annotation("" + sq.getCharAt(i), "",
+ (char) 0, (float) sq.findPosition(i)));
+ }
+ AlignmentAnnotation alan = new AlignmentAnnotation("For "
+ + sq.getName(), "Fake alignment annot", al);
+ // create a sequence mapping for the annotation vector in its current state
+ alan.createSequenceMapping(sq, sq.getStart(), false);
+ sq.addAlignmentAnnotation(alan);
+ }
+
+ /**
+ * use this to test annotation derived from method above as it is transferred
+ * across different sequences derived from same dataset coordinate frame
+ *
+ * @param ala
+ */
+ public static void testAnnotTransfer(AlignmentAnnotation ala)
+ {
+ assertEquals(
+ "Failed - need annotation created by createAnnotation method",
+ ala.description, "Fake alignment annot");
+ ala.adjustForAlignment();
+ for (int p = 0; p < ala.annotations.length; p++)
+ {
+ if (ala.annotations[p] != null)
+ {
+ assertEquals("Mismatch at position " + p
+ + " between annotation position value and sequence"
+ + ala.annotations[p], (int) ala.annotations[p].value,
+ ala.sequenceRef.findPosition(p));
+ }
+ }
+ }
+
+ /**
+ * Tests the liftOver method and also exercises the functions for remapping
+ * annotation across different reference sequences. Here, the test is between
+ * different dataset frames (annotation transferred by mapping between
+ * sequences)
+ */
+ @Test
+ public void testLiftOver()
+ {
+ SequenceI sqFrom = new Sequence("fromLong", "QQQCDEWGH");
+ sqFrom.setStart(10);
+ sqFrom.setEnd(sqFrom.findPosition(sqFrom.getLength() - 1));
+ SequenceI sqTo = new Sequence("toShort", "RCDEW");
+ sqTo.setStart(20);
+ sqTo.setEnd(sqTo.findPosition(sqTo.getLength() - 1));
+ createAnnotation(sqTo);
+ AlignmentAnnotation origTo = sqTo.getAnnotation()[0];
+ createAnnotation(sqFrom);
+ AlignmentAnnotation origFrom = sqFrom.getAnnotation()[0];
+ AlignSeq align = AlignSeq.doGlobalNWAlignment(sqFrom, sqTo,
+ AlignSeq.PEP);
+ SequenceI alSeq1 = new Sequence(sqFrom.getName(), align.getAStr1());
+ alSeq1.setStart(sqFrom.getStart() + align.getSeq1Start() - 1);
+ alSeq1.setEnd(sqFrom.getStart() + align.getSeq1End() - 1);
+ alSeq1.setDatasetSequence(sqFrom);
+ SequenceI alSeq2 = new Sequence(sqTo.getName(), align.getAStr2());
+ alSeq2.setStart(sqTo.getStart() + align.getSeq2Start() - 1);
+ alSeq2.setEnd(sqTo.getStart() + align.getSeq2End() - 1);
+ alSeq2.setDatasetSequence(sqTo);
+ System.out.println(new AppletFormatAdapter().formatSequences("STH",
+ new Alignment(new SequenceI[]
+ { sqFrom, alSeq1, sqTo, alSeq2 }), true));
+
+ Mapping mp = align.getMappingFromS1(false);
+
+ AlignmentAnnotation almap1 = new AlignmentAnnotation(
+ sqTo.getAnnotation()[0]);
+ almap1.liftOver(sqFrom, mp);
+ assertEquals(almap1.sequenceRef, sqFrom);
+ alSeq1.addAlignmentAnnotation(almap1);
+ almap1.setSequenceRef(alSeq1);
+ almap1.adjustForAlignment();
+ AlignmentAnnotation almap2 = new AlignmentAnnotation(
+ sqFrom.getAnnotation()[0]);
+ almap2.liftOver(sqTo, mp);
+ assertEquals(almap2.sequenceRef, sqTo);
+
+ alSeq2.addAlignmentAnnotation(almap2);
+ almap2.setSequenceRef(alSeq2);
+ almap2.adjustForAlignment();
+
+ AlignmentI all = new Alignment(new SequenceI[]
+ { alSeq1, alSeq2 });
+ all.addAnnotation(almap1);
+ all.addAnnotation(almap2);
+ System.out.println(new AppletFormatAdapter().formatSequences("STH",
+ all, true));
+
+ for (int p = 0; p < alSeq1.getLength(); p++)
+ {
+ Annotation orig1, trans1, orig2, trans2;
+ trans2 = almap2.annotations[p];
+ orig2 = origFrom.annotations[alSeq1.findPosition(p)
+ - sqFrom.getStart()];
+ orig1 = origTo.annotations[alSeq2.findPosition(p) - sqTo.getStart()];
+ trans1 = almap1.annotations[p];
+ if (trans1 == trans2)
+ {
+ System.out.println("Pos " + p + " mismatch");
+ continue;
+ }
+ assertEquals(
+ "Mismatch on Original From and transferred annotation on 2",
+ (orig2 != null) ? orig2.toString() : null,
+ (trans2 != null) ? trans2.toString() : null);
+ assertEquals(
+ "Mismatch on Original To and transferred annotation on 1",
+ (orig1 != null) ? orig1.toString() : null,
+ (trans1 != null) ? trans1.toString() : null);
+ String alm1 = ""
+ + (almap1.annotations.length > p ? almap1.annotations[p].displayCharacter
+ : "Out of range");
+ String alm2 = ""
+ + (almap2.annotations.length > p ? almap2.annotations[p].displayCharacter
+ : "Out of range");
+ assertEquals("Position " + p + " " + alm1 + " " + alm2, alm1, alm2);
+ }
+ // new jalview.io.FormatAdapter().formatSequences("STOCKHOLM", n)
+ }
+
+}