label.export_image = Export Image
label.vamsas_store = VAMSAS store
label.translate_cDNA = Translate as cDNA
+label.reverse = Reverse
+label.reverse_complement = Reverse Complement
label.linked_view_title = Linked cDNA and protein view
label.align = Align
label.extract_scores = Extract Scores
}
}
}
+
+ /**
+ * Returns an alignment consisting of the reversed (and optionally
+ * complemented) sequences set in this object's constructor
+ *
+ * @param complement
+ * @return
+ */
+ public AlignmentI reverseCdna(boolean complement)
+ {
+ int sSize = selection.size();
+ List<SequenceI> reversed = new ArrayList<SequenceI>();
+ for (int s = 0; s < sSize; s++)
+ {
+ SequenceI newseq = reverseSequence(selection.get(s).getName(),
+ seqstring[s], complement);
+
+ if (newseq != null)
+ {
+ reversed.add(newseq);
+ }
+ }
+
+ SequenceI[] newseqs = reversed.toArray(new SequenceI[reversed.size()]);
+ AlignmentI al = new Alignment(newseqs);
+ ((Alignment) al).createDatasetAlignment();
+ return al;
+ }
+
+ /**
+ * Returns a reversed, and optionally complemented, sequence. The new
+ * sequence's name is the original name with "|rev" or "|revcomp" appended.
+ * aAcCgGtT and DNA ambiguity codes are complemented, any other characters are
+ * left unchanged.
+ *
+ * @param seq
+ * @param complement
+ * @return
+ */
+ public static SequenceI reverseSequence(String seqName, String sequence,
+ boolean complement)
+ {
+ String newName = seqName + "|rev" + (complement ? "comp" : "");
+ char[] originalSequence = sequence.toCharArray();
+ int length = originalSequence.length;
+ char[] reversedSequence = new char[length];
+
+ for (int i = 0; i < length; i++)
+ {
+ reversedSequence[length - i - 1] = complement ? getComplement(originalSequence[i])
+ : originalSequence[i];
+ }
+ SequenceI reversed = new Sequence(newName, reversedSequence, 1, length);
+ return reversed;
+ }
+
+ /**
+ * Returns dna complement (preserving case) for aAcCgGtTuU. Ambiguity codes
+ * are treated as on http://reverse-complement.com/. Anything else is left
+ * unchanged.
+ *
+ * @param c
+ * @return
+ */
+ public static char getComplement(char c)
+ {
+ char result = c;
+ switch (c) {
+ case 'a':
+ result = 't';
+ break;
+ case 'A':
+ result = 'T';
+ break;
+ case 'c':
+ result = 'g';
+ break;
+ case 'C':
+ result = 'G';
+ break;
+ case 'g':
+ result = 'c';
+ break;
+ case 'G':
+ result = 'C';
+ break;
+ case 't':
+ result = 'a';
+ break;
+ case 'T':
+ result = 'A';
+ break;
+ case 'u':
+ result = 'a';
+ break;
+ case 'U':
+ result = 'A';
+ break;
+ case 'r':
+ result = 'y';
+ break;
+ case 'R':
+ result = 'Y';
+ break;
+ case 'y':
+ result = 'r';
+ break;
+ case 'Y':
+ result = 'R';
+ break;
+ case 'k':
+ result = 'm';
+ break;
+ case 'K':
+ result = 'M';
+ break;
+ case 'm':
+ result = 'k';
+ break;
+ case 'M':
+ result = 'K';
+ break;
+ case 'b':
+ result = 'v';
+ break;
+ case 'B':
+ result = 'V';
+ break;
+ case 'v':
+ result = 'b';
+ break;
+ case 'V':
+ result = 'B';
+ break;
+ case 'd':
+ result = 'h';
+ break;
+ case 'D':
+ result = 'H';
+ break;
+ case 'h':
+ result = 'd';
+ break;
+ case 'H':
+ result = 'D';
+ break;
+ }
+
+ return result;
+ }
}
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
-import java.util.Set;
import java.util.Vector;
import javax.swing.JCheckBoxMenuItem;
public void setGUINucleotide(boolean nucleotide)
{
showTranslation.setVisible(nucleotide);
+ showReverse.setVisible(nucleotide);
+ showReverseComplement.setVisible(nucleotide);
conservationMenuItem.setEnabled(!nucleotide);
modifyConservation.setEnabled(!nucleotide);
showGroupConservation.setEnabled(!nucleotide);
// TODO 1: no mappings are set up for EMBL product
// TODO 2: if they were, should add them to protein alignment, not
// dna
- Set<AlignedCodonFrame> cf = prods.getCodonFrames();
+ List<AlignedCodonFrame> cf = prods.getCodonFrames();
for (AlignedCodonFrame acf : cf)
{
al.addCodonFrame(acf);
{
// TODO no longer a menu action - refactor as required
final AlignmentI alignment = getViewport().getAlignment();
- Set<AlignedCodonFrame> mappings = alignment.getCodonFrames();
+ List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
if (mappings == null)
{
return;
sf.setComplementVisible(this, show);
}
}
+
+ /**
+ * Generate the reverse (optionally complemented) of the selected sequences,
+ * and add them to the alignment
+ */
+ @Override
+ protected void showReverse_actionPerformed(boolean complement)
+ {
+ AlignmentI al = null;
+ try
+ {
+ Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
+
+ al = dna.reverseCdna(complement);
+ viewport.addAlignment(al, "");
+ } catch (Exception ex)
+ {
+ System.err.println(ex.getMessage());
+ return;
+ }
+ }
}
class PrintThread extends Thread
protected JMenuItem showTranslation = new JMenuItem();
+ protected JMenuItem showReverse = new JMenuItem();
+
+ protected JMenuItem showReverseComplement = new JMenuItem();
+
protected JMenu showProducts = new JMenu();
protected JMenuItem rnahelicesColour = new JMenuItem();
showTranslation_actionPerformed(e);
}
});
+ showReverse.setText(MessageManager.getString("label.reverse"));
+ showReverse.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showReverse_actionPerformed(false);
+ }
+ });
+ showReverseComplement.setText(MessageManager
+ .getString("label.reverse_complement"));
+ showReverseComplement.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showReverse_actionPerformed(true);
+ }
+ });
JMenuItem extractScores = new JMenuItem(
MessageManager.getString("label.extract_scores"));
calculateMenu.add(PCAMenuItem);
calculateMenu.addSeparator();
calculateMenu.add(showTranslation);
+ calculateMenu.add(showReverse);
+ calculateMenu.add(showReverseComplement);
calculateMenu.add(showProducts);
calculateMenu.add(autoCalculate);
calculateMenu.add(sortByTree);
}
/**
+ * Generate the reverse sequence (or reverse complement if the flag is true)
+ * and add it to the alignment
+ *
+ * @param complement
+ */
+ protected void showReverse_actionPerformed(boolean complement)
+ {
+ }
+
+ /**
* Adds the given action listener and key accelerator to the given menu item.
* Also saves in a lookup table to support lookup of action by key stroke.
*
return this.splitFrame;
}
- protected void showComplement_actionPerformed(boolean state)
+ protected void showComplement_actionPerformed(boolean complement)
{
}
}
assertEquals("[0, 2, 5]", convertCodon("A-A--A").toString());
assertEquals("[1, 3, 4]", convertCodon("-A-AA-").toString());
}
+
+ /**
+ * Test dna complementing
+ */
+ @Test(groups = "Functional")
+ public void testGetComplement()
+ {
+ assertEquals('t', Dna.getComplement('a'));
+ assertEquals('T', Dna.getComplement('A'));
+ assertEquals('a', Dna.getComplement('t'));
+ assertEquals('A', Dna.getComplement('T'));
+ assertEquals('c', Dna.getComplement('g'));
+ assertEquals('C', Dna.getComplement('G'));
+ assertEquals('g', Dna.getComplement('c'));
+ assertEquals('G', Dna.getComplement('C'));
+ // note uU --> aA but not vice versa
+ assertEquals('a', Dna.getComplement('u'));
+ assertEquals('A', Dna.getComplement('U'));
+ // ambiguity codes, see http://www.bioinformatics.org/sms/iupac.html
+ assertEquals('r', Dna.getComplement('y'));
+ assertEquals('R', Dna.getComplement('Y'));
+ assertEquals('y', Dna.getComplement('r'));
+ assertEquals('Y', Dna.getComplement('R'));
+ assertEquals('k', Dna.getComplement('m'));
+ assertEquals('K', Dna.getComplement('M'));
+ assertEquals('m', Dna.getComplement('k'));
+ assertEquals('M', Dna.getComplement('K'));
+ assertEquals('b', Dna.getComplement('v'));
+ assertEquals('B', Dna.getComplement('V'));
+ assertEquals('v', Dna.getComplement('b'));
+ assertEquals('V', Dna.getComplement('B'));
+ assertEquals('d', Dna.getComplement('h'));
+ assertEquals('D', Dna.getComplement('H'));
+ assertEquals('h', Dna.getComplement('d'));
+ assertEquals('H', Dna.getComplement('D'));
+ assertEquals('Q', Dna.getComplement('Q'));
+ }
+
+ @Test(groups = "Functional")
+ public void testReverseSequence()
+ {
+ String seq = "AcGtUrYkMbVdHNX";
+
+ // reverse:
+ SequenceI reversed = Dna.reverseSequence("Seq1", seq, false);
+ assertEquals(new StringBuilder(seq).reverse()
+ .toString(), reversed.getSequenceAsString());
+ assertEquals("Seq1|rev", reversed.getName());
+
+ // reverse complement:
+ SequenceI revcomp = Dna.reverseSequence("Seq1", seq, true);
+ assertEquals("XNDhBvKmRyAaCgT", revcomp.getSequenceAsString());
+ assertEquals("Seq1|revcomp", revcomp.getName());
+ }
}