<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin"/>
<classpathentry kind="lib" path="lib/jfreesvg-2.1.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.jar"/>
<classpathentry kind="output" path="classes"/>
</classpath>
label.automatically_associate_pdb_files_by_name = Automatically Associate PDB files by name
label.ignore_unmatched_dropped_files_info = <html>Do you want to <em>ignore</em> the {0} files whose names did not match any sequence IDs ?</html>
label.ignore_unmatched_dropped_files = Ignore unmatched dropped files?
+label.view_name_original = Original
label.enter_view_name = Enter View Name
label.enter_label = Enter label
label.enter_label_for_the_structure = Enter a label for the structure?
label.export_image = Export Image
label.vamsas_store = VAMSAS store
label.translate_cDNA = Translate cDNA
+label.cdna = cDNA
+label.link_cdna = Link cDNA
+label.link_cdna_tip = Link to any compatible cDNA alignments.<br>Sequences are linked that have the same name and compatible lengths.
+label.no_cdna = No compatible cDNA was found
+label.linked_cdna = {0} cDNA alignments linked
+label.cdna_all_linked = All {0} compatible cDNA alignments are already linked
+label.align_cdna = Align linked cDNA
+label.align_cdna_tip = Any linked cDNA sequences will be realigned to match this alignment.
+label.cdna_aligned = {0} sequences in {1} alignments were realigned
+label.view_as_cdna = Show aligned cDNA
+label.view_as_cdna_tip = Open a new alignment of the related cDNA sequences
+label.linked_view_title = {0} and {1}
+label.align = Align
label.extract_scores = Extract Scores
label.get_cross_refs = Get Cross References
label.sort_alignment_new_tree = Sort Alignment With New Tree
label.add_sequences = Add Sequences
label.new_window = New Window
+label.split_window = Split Window
label.refresh_available_sources = Refresh Available Sources
label.use_registry = Use Registry
label.add_local_source = Add Local Source
label.settings_for_param = Settings for {0}
label.view_params = View {0}
label.select_all_views = Select all views
+label.all_views = All Views
label.align_sequences_to_existing_alignment = Align sequences to an existing alignment
label.realign_with_params = Realign with {0}
label.calcname_with_default_settings = {0} with Defaults
label.normalise_logo = Normalise Logo
label.no_colour_selection_in_scheme = Please, make a colour selection before to apply colour scheme
label.no_colour_selection_warn = Error saving colour scheme
+label.open_linked_alignment? = Would you like to open as a separate alignment, with cDNA and protein linked?
+label.open_linked_alignment = Open linked alignment
+label.no_mappings = No mappings found
+label.mapping_failed = No sequence mapping could be made between the alignments.<br>A mapping requires sequence names to match, and equivalent sequence lengths.
+action.no = No
+label.for = for
label.select_by_annotation = Select By Annotation
action.select_by_annotation = Select by Annotation...
label.threshold_filter = Threshold Filter
label.search_filter = Search Filter
label.display_name = Display Label
label.description = Description
+
*/
package MCview;
-import java.io.*;
-import java.util.*;
+import jalview.analysis.AlignSeq;
+import jalview.appletgui.AlignmentPanel;
+import jalview.appletgui.FeatureRenderer;
+import jalview.appletgui.SequenceRenderer;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.structure.AtomSpec;
+import jalview.structure.StructureListener;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Image;
// JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug
-import java.awt.*;
-import java.awt.event.*;
-
-import jalview.analysis.*;
-import jalview.datamodel.*;
-
-import jalview.appletgui.*;
-import jalview.structure.*;
-import jalview.util.MessageManager;
+import java.awt.Panel;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.io.PrintStream;
+import java.util.List;
+import java.util.Vector;
public class AppletPDBCanvas extends Panel implements MouseListener,
MouseMotionListener, StructureListener
pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
+ {
pdbentry.setFile("INLINE" + pdb.id);
+ }
} catch (Exception ex)
{
{
mappingDetails.append("\n\nPDB Sequence is :\nSequence = "
- + ((PDBChain) pdb.chains.elementAt(i)).sequence
+ + pdb.chains.elementAt(i).sequence
.getSequenceAsString());
mappingDetails.append("\nNo of residues = "
- + ((PDBChain) pdb.chains.elementAt(i)).residues.size()
+ + pdb.chains.elementAt(i).residues.size()
+ "\n\n");
// Now lets compare the sequences to get
// Align the sequence to the pdb
// TODO: DNa/Pep switch
AlignSeq as = new AlignSeq(sequence,
- ((PDBChain) pdb.chains.elementAt(i)).sequence,
- ((PDBChain) pdb.chains.elementAt(i)).isNa ? AlignSeq.DNA
+ pdb.chains.elementAt(i).sequence,
+ pdb.chains.elementAt(i).isNa ? AlignSeq.DNA
: AlignSeq.PEP);
as.calcScoreMatrix();
as.traceAlignment();
mappingDetails.append("\nSEQ start/end " + seqstart + " " + seqend);
}
- mainchain = (PDBChain) pdb.chains.elementAt(maxchain);
+ mainchain = pdb.chains.elementAt(maxchain);
mainchain.pdbstart = pdbstart;
mainchain.pdbend = pdbend;
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- if (((PDBChain) pdb.chains.elementAt(ii)).isVisible)
+ if (pdb.chains.elementAt(ii).isVisible)
{
- Vector tmp = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector tmp = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < tmp.size(); i++)
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- if (((PDBChain) pdb.chains.elementAt(ii)).isVisible)
+ if (pdb.chains.elementAt(ii).isVisible)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < bonds.size(); i++)
{
}
}
- width[0] = (float) Math.abs(max[0] - min[0]);
- width[1] = (float) Math.abs(max[1] - min[1]);
- width[2] = (float) Math.abs(max[2] - min[2]);
+ width[0] = Math.abs(max[0] - min[0]);
+ width[1] = Math.abs(max[1] - min[1]);
+ width[2] = Math.abs(max[2] - min[2]);
maxwidth = width[0];
// Find centre coordinate
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- if (((PDBChain) pdb.chains.elementAt(ii)).isVisible)
+ if (pdb.chains.elementAt(ii).isVisible)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
bsize += bonds.size();
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- chain = (PDBChain) pdb.chains.elementAt(ii);
+ chain = pdb.chains.elementAt(ii);
for (int i = 0; i < chain.bonds.size(); i++)
{
repaint();
if (foundchain != -1)
{
- PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);
+ PDBChain chain = pdb.chains.elementAt(foundchain);
if (chain == mainchain)
{
if (fatom.alignmentMapping != -1)
PDBChain chain = null;
if (foundchain != -1)
{
- chain = (PDBChain) pdb.chains.elementAt(foundchain);
+ chain = pdb.chains.elementAt(foundchain);
if (chain == mainchain)
{
mouseOverStructure(fatom.resNumber, chain.id);
if ((evt.getModifiers() & Event.META_MASK) != 0)
{
- objmat.rotatez((float) ((mx - omx)));
+ objmat.rotatez(((mx - omx)));
}
else
{
- objmat.rotatex((float) ((omy - my)));
- objmat.rotatey((float) ((omx - mx)));
+ objmat.rotatex(((omy - my)));
+ objmat.rotatey(((omx - mx)));
}
// Alter the bonds
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < bonds.size(); i++)
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+ PDBChain chain = pdb.chains.elementAt(ii);
if (chain.isVisible)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < bonds.size(); i++)
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+ PDBChain chain = pdb.chains.elementAt(ii);
int truex;
Bond tmpBond = null;
if (chain.isVisible)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < bonds.size(); i++)
{
if (fatom != null) // )&& chain.ds != null)
{
- chain = (PDBChain) pdb.chains.elementAt(foundchain);
+ chain = pdb.chains.elementAt(foundchain);
}
}
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+ PDBChain chain = pdb.chains.elementAt(ii);
chain.isVisible = b;
}
mainchain.isVisible = true;
public void mouseOverStructure(int pdbResNum, String chain)
{
if (lastMessage == null || !lastMessage.equals(pdbResNum + chain))
+ {
ssm.mouseOverStructure(pdbResNum, chain, pdbentry.getFile());
+ }
lastMessage = pdbResNum + chain;
}
StringBuffer eval = new StringBuffer();
- public void highlightAtom(int atomIndex, int pdbResNum, String chain,
- String pdbfile)
+ /**
+ * Highlight the specified atoms in the structure.
+ *
+ * @param atoms
+ */
+ @Override
+ public void highlightAtoms(List<AtomSpec> atoms)
{
if (!seqColoursReady)
{
return;
}
-
- if (highlightRes != null && highlightRes.contains((atomIndex - 1) + ""))
+ for (AtomSpec atom : atoms)
{
- return;
+ int atomIndex = atom.getAtomIndex();
+
+ if (highlightRes != null
+ && highlightRes.contains((atomIndex - 1) + ""))
+ {
+ continue;
+ }
+
+ highlightAtom(atomIndex);
}
+ redrawneeded = true;
+ repaint();
+ }
+
+ /**
+ * @param atomIndex
+ */
+ protected void highlightAtom(int atomIndex)
+ {
int index = -1;
Bond tmpBond;
for (index = 0; index < mainchain.bonds.size(); index++)
break;
}
}
-
- redrawneeded = true;
- repaint();
}
public Color getColour(int atomIndex, int pdbResNum, String chain,
*/
package MCview;
-import java.io.*;
-import java.util.*;
-
+import jalview.analysis.AlignSeq;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.FeatureRenderer;
+import jalview.gui.SequenceRenderer;
+import jalview.structure.AtomSpec;
+import jalview.structure.StructureListener;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureSelectionManager;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
// JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-
-import jalview.analysis.*;
-import jalview.datamodel.*;
-import jalview.gui.*;
-import jalview.structure.*;
+import java.awt.Image;
+import java.awt.RenderingHints;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.io.PrintStream;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.JPanel;
+import javax.swing.ToolTipManager;
public class PDBCanvas extends JPanel implements MouseListener,
MouseMotionListener, StructureListener
pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
+ {
pdbentry.setFile("INLINE" + pdb.id);
+ }
} catch (Exception ex)
{
{
mappingDetails.append("\n\nPDB Sequence is :\nSequence = "
- + ((PDBChain) pdb.chains.elementAt(i)).sequence
+ + pdb.chains.elementAt(i).sequence
.getSequenceAsString());
mappingDetails.append("\nNo of residues = "
- + ((PDBChain) pdb.chains.elementAt(i)).residues.size()
+ + pdb.chains.elementAt(i).residues.size()
+ "\n\n");
// Now lets compare the sequences to get
// the start and end points.
// Align the sequence to the pdb
AlignSeq as = new AlignSeq(sequence,
- ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep");
+ pdb.chains.elementAt(i).sequence, "pep");
as.calcScoreMatrix();
as.traceAlignment();
PrintStream ps = new PrintStream(System.out)
mappingDetails.append("\nSEQ start/end " + seqstart + " " + seqend);
}
- mainchain = (PDBChain) pdb.chains.elementAt(maxchain);
+ mainchain = pdb.chains.elementAt(maxchain);
mainchain.pdbstart = pdbstart;
mainchain.pdbend = pdbend;
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- if (((PDBChain) pdb.chains.elementAt(ii)).isVisible)
+ if (pdb.chains.elementAt(ii).isVisible)
{
- Vector tmp = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector tmp = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < tmp.size(); i++)
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- if (((PDBChain) pdb.chains.elementAt(ii)).isVisible)
+ if (pdb.chains.elementAt(ii).isVisible)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < bonds.size(); i++)
{
* System.out.println("zmax " + max[2] + " min " + min[2]);
*/
- width[0] = (float) Math.abs(max[0] - min[0]);
- width[1] = (float) Math.abs(max[1] - min[1]);
- width[2] = (float) Math.abs(max[2] - min[2]);
+ width[0] = Math.abs(max[0] - min[0]);
+ width[1] = Math.abs(max[1] - min[1]);
+ width[2] = Math.abs(max[2] - min[2]);
maxwidth = width[0];
// Find centre coordinate
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- if (((PDBChain) pdb.chains.elementAt(ii)).isVisible)
+ if (pdb.chains.elementAt(ii).isVisible)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
bsize += bonds.size();
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- chain = (PDBChain) pdb.chains.elementAt(ii);
+ chain = pdb.chains.elementAt(ii);
for (int i = 0; i < chain.bonds.size(); i++)
{
repaint();
if (foundchain != -1)
{
- PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);
+ PDBChain chain = pdb.chains.elementAt(foundchain);
if (chain == mainchain)
{
if (fatom.alignmentMapping != -1)
PDBChain chain = null;
if (foundchain != -1)
{
- chain = (PDBChain) pdb.chains.elementAt(foundchain);
+ chain = pdb.chains.elementAt(foundchain);
if (chain == mainchain)
{
mouseOverStructure(fatom.resNumber, chain.id);
if ((evt.getModifiers() & Event.META_MASK) != 0)
{
- objmat.rotatez((float) ((mx - omx)));
+ objmat.rotatez(((mx - omx)));
}
else
{
- objmat.rotatex((float) ((my - omy)));
- objmat.rotatey((float) ((omx - mx)));
+ objmat.rotatex(((my - omy)));
+ objmat.rotatey(((omx - mx)));
}
// Alter the bonds
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < bonds.size(); i++)
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+ PDBChain chain = pdb.chains.elementAt(ii);
if (chain.isVisible)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < bonds.size(); i++)
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+ PDBChain chain = pdb.chains.elementAt(ii);
int truex;
Bond tmpBond = null;
if (chain.isVisible)
{
- Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;
+ Vector bonds = pdb.chains.elementAt(ii).bonds;
for (int i = 0; i < bonds.size(); i++)
{
if (fatom != null) // )&& chain.ds != null)
{
- chain = (PDBChain) pdb.chains.elementAt(foundchain);
+ chain = pdb.chains.elementAt(foundchain);
}
}
{
for (int ii = 0; ii < pdb.chains.size(); ii++)
{
- PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);
+ PDBChain chain = pdb.chains.elementAt(ii);
chain.isVisible = b;
}
mainchain.isVisible = true;
public void mouseOverStructure(int pdbResNum, String chain)
{
if (lastMessage == null || !lastMessage.equals(pdbResNum + chain))
+ {
ssm.mouseOverStructure(pdbResNum, chain, pdbentry.getFile());
+ }
lastMessage = pdbResNum + chain;
}
StringBuffer eval = new StringBuffer();
- public void highlightAtom(int atomIndex, int pdbResNum, String chain,
- String pdbfile)
+ /**
+ * Highlight the specified atoms in the structure.
+ *
+ * @param atoms
+ */
+ @Override
+ public void highlightAtoms(List<AtomSpec> atoms)
{
if (!seqColoursReady)
{
return;
}
- if (highlightRes != null && highlightRes.contains((atomIndex - 1) + ""))
+ for (AtomSpec atom : atoms)
{
- return;
+ int atomIndex = atom.getAtomIndex();
+ if (highlightRes != null
+ && highlightRes.contains((atomIndex - 1) + ""))
+ {
+ continue;
+ }
+
+ highlightAtom(atomIndex);
}
+ redrawneeded = true;
+ repaint();
+ }
+
+ /**
+ * Highlight the atom at the specified index.
+ *
+ * @param atomIndex
+ */
+ protected void highlightAtom(int atomIndex)
+ {
int index = -1;
Bond tmpBond;
for (index = 0; index < mainchain.bonds.size(); index++)
break;
}
}
-
- redrawneeded = true;
- repaint();
}
public Color getColour(int atomIndex, int pdbResNum, String chain,
}
/**
- * DOCUMENT ME!
+ * Returns the given sequence with all of the given gap characters removed.
*
- * @param gapChar
- * DOCUMENT ME!
+ * @param gapChars
+ * a string of characters to be treated as gaps
* @param seq
- * DOCUMENT ME!
+ * the input sequence
*
- * @return DOCUMENT ME!
+ * @return
*/
- public static String extractGaps(String gapChar, String seq)
+ public static String extractGaps(String gapChars, String seq)
{
- StringTokenizer str = new StringTokenizer(seq, gapChar);
- StringBuffer newString = new StringBuffer();
+ if (gapChars == null || seq == null)
+ {
+ return null;
+ }
+ StringTokenizer str = new StringTokenizer(seq, gapChars);
+ StringBuilder newString = new StringBuilder(seq.length());
while (str.hasMoreTokens())
{
*/
package jalview.analysis;
-import java.util.*;
-
-import jalview.datamodel.*;
-import jalview.util.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceNode;
+import jalview.util.Comparison;
+import jalview.util.MessageManager;
+import jalview.util.QuickSort;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* Routines for manipulating the order of a multiple sequence alignment TODO:
* @param tmp
* sequences as a vector
*/
- private static void setOrder(AlignmentI align, Vector tmp)
+ private static void setOrder(AlignmentI align, List<SequenceI> tmp)
{
setOrder(align, vectorSubsetToArray(tmp, align.getSequences()));
}
{
// MAINTAINS ORIGNAL SEQUENCE ORDER,
// ORDERS BY GROUP SIZE
- Vector groups = new Vector();
+ List<SequenceGroup> groups = new ArrayList<SequenceGroup>();
if (groups.hashCode() != lastGroupHash)
{
{
for (int j = 0; j < groups.size(); j++)
{
- SequenceGroup sg2 = (SequenceGroup) groups.elementAt(j);
+ SequenceGroup sg2 = groups.get(j);
if (sg.getSize() > sg2.getSize())
{
- groups.insertElementAt(sg, j);
+ groups.add(j, sg);
break;
}
if (!groups.contains(sg))
{
- groups.addElement(sg);
+ groups.add(sg);
}
}
// NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER
// /////////////////////////////////////////////
- Vector seqs = new Vector();
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
for (int i = 0; i < groups.size(); i++)
{
- SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
+ SequenceGroup sg = groups.get(i);
SequenceI[] orderedseqs = sg.getSequencesInOrder(align);
for (int j = 0; j < orderedseqs.length; j++)
{
- seqs.addElement(orderedseqs[j]);
+ seqs.add(orderedseqs[j]);
}
}
}
/**
- * Converts Vector to array. java 1.18 does not have Vector.toArray()
- *
- * @param tmp
- * Vector of SequenceI objects
- *
- * @return array of Sequence[]
- */
- private static SequenceI[] vectorToArray(Vector tmp)
- {
- SequenceI[] seqs = new SequenceI[tmp.size()];
-
- for (int i = 0; i < tmp.size(); i++)
- {
- seqs[i] = (SequenceI) tmp.elementAt(i);
- }
-
- return seqs;
- }
-
- /**
* Select sequences in order from tmp that is present in mask, and any
- * remaining seqeunces in mask not in tmp
+ * remaining sequences in mask not in tmp
*
* @param tmp
* thread safe collection of sequences
private static SequenceI[] vectorSubsetToArray(List<SequenceI> tmp,
List<SequenceI> mask)
{
+ // or?
+ // tmp2 = tmp.retainAll(mask);
+ // return tmp2.addAll(mask.removeAll(tmp2))
+
ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
int i, idx;
boolean[] tmask = new boolean[mask.size()];
public static void sortBy(AlignmentI align, AlignmentOrder order)
{
// Get an ordered vector of sequences which may also be present in align
- Vector tmp = order.getOrder();
+ List<SequenceI> tmp = order.getOrder();
if (lastOrder == order)
{
*
* @return DOCUMENT ME!
*/
- private static Vector getOrderByTree(AlignmentI align, NJTree tree)
+ private static List<SequenceI> getOrderByTree(AlignmentI align,
+ NJTree tree)
{
int nSeq = align.getHeight();
- Vector tmp = new Vector();
+ List<SequenceI> tmp = new ArrayList<SequenceI>();
tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences());
*/
public static void sortByTree(AlignmentI align, NJTree tree)
{
- Vector tmp = getOrderByTree(align, tree);
+ List<SequenceI> tmp = getOrderByTree(align, tree);
// tmp should properly permute align with tree.
if (lastTree != tree)
*
* @param align
* DOCUMENT ME!
- * @param seqs
+ * @param tmp
* DOCUMENT ME!
*/
- private static void addStrays(AlignmentI align, Vector seqs)
+ private static void addStrays(AlignmentI align, List<SequenceI> tmp)
{
int nSeq = align.getHeight();
for (int i = 0; i < nSeq; i++)
{
- if (!seqs.contains(align.getSequenceAt(i)))
+ if (!tmp.contains(align.getSequenceAt(i)))
{
- seqs.addElement(align.getSequenceAt(i));
+ tmp.add(align.getSequenceAt(i));
}
}
- if (nSeq != seqs.size())
+ if (nSeq != tmp.size())
{
System.err
.println("ERROR: Size still not right even after addStrays");
*
* @return DOCUMENT ME!
*/
- private static Vector _sortByTree(SequenceNode node, Vector tmp,
+ private static List<SequenceI> _sortByTree(SequenceNode node,
+ List<SequenceI> tmp,
List<SequenceI> seqset)
{
if (node == null)
// seqset.size()==0 ||
// seqset.contains(tmp)))
{
- tmp.addElement(node.element());
+ tmp.add((SequenceI) node.element());
}
}
}
*/
package jalview.analysis;
+import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
+import jalview.schemes.ResidueProperties;
+import jalview.util.MapList;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* grab bag of useful alignment manipulation operations Expect these to be
{
/**
+ * Represents the 3 possible results of trying to map one alignment to
+ * another.
+ */
+ public enum MappingResult
+ {
+ Mapped, NotMapped, AlreadyMapped
+ }
+
+ /**
* given an existing alignment, create a new alignment including all, or up to
* flankSize additional symbols from each sequence's dataset sequence
*
}
return result;
}
+
+ /**
+ * Returns a map of lists of sequences in the alignment, keyed by sequence
+ * name. For use in mapping between different alignment views of the same
+ * sequences.
+ *
+ * @see jalview.datamodel.AlignmentI#getSequencesByName()
+ */
+ public static Map<String, List<SequenceI>> getSequencesByName(
+ AlignmentI al)
+ {
+ Map<String, List<SequenceI>> theMap = new LinkedHashMap<String, List<SequenceI>>();
+ for (SequenceI seq : al.getSequences())
+ {
+ String name = seq.getName();
+ if (name != null)
+ {
+ List<SequenceI> seqs = theMap.get(name);
+ if (seqs == null)
+ {
+ seqs = new ArrayList<SequenceI>();
+ theMap.put(name, seqs);
+ }
+ seqs.add(seq);
+ }
+ }
+ return theMap;
+ }
+
+ /**
+ * Build mapping of protein to cDNA alignment. Mappings are made between
+ * sequences which have the same name and compatible lengths. Has a 3-valued
+ * result: either Mapped (at least one sequence mapping was created),
+ * AlreadyMapped (all possible sequence mappings already exist), or NotMapped
+ * (no possible sequence mappings exist).
+ *
+ * @param proteinAlignment
+ * @param cdnaAlignment
+ * @return
+ */
+ public static MappingResult mapProteinToCdna(
+ final AlignmentI proteinAlignment,
+ final AlignmentI cdnaAlignment)
+ {
+ boolean mappingPossible = false;
+ boolean mappingPerformed = false;
+
+ List<SequenceI> thisSeqs = proteinAlignment.getSequences();
+
+ /*
+ * Build a look-up of cDNA sequences by name, for matching purposes.
+ */
+ Map<String, List<SequenceI>> cdnaSeqs = cdnaAlignment
+ .getSequencesByName();
+
+ for (SequenceI aaSeq : thisSeqs)
+ {
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ List<SequenceI> candidates = cdnaSeqs.get(aaSeq.getName());
+ if (candidates == null)
+ {
+ /*
+ * No cDNA sequence with matching name, so no mapping possible for this
+ * protein sequence
+ */
+ continue;
+ }
+ mappingPossible = true;
+ for (SequenceI cdnaSeq : candidates)
+ {
+ if (!mappingExists(proteinAlignment.getCodonFrames(),
+ aaSeq.getDatasetSequence(), cdnaSeq.getDatasetSequence()))
+ {
+ MapList map = mapProteinToCdna(aaSeq, cdnaSeq);
+ if (map != null)
+ {
+ acf.addMap(cdnaSeq, aaSeq, map);
+ mappingPerformed = true;
+ }
+ }
+ }
+ proteinAlignment.addCodonFrame(acf);
+ }
+
+ /*
+ * If at least one mapping was possible but none was done, then the
+ * alignments are already as mapped as they can be.
+ */
+ if (mappingPossible && !mappingPerformed)
+ {
+ return MappingResult.AlreadyMapped;
+ }
+ else
+ {
+ return mappingPerformed ? MappingResult.Mapped
+ : MappingResult.NotMapped;
+ }
+ }
+
+ /**
+ * Answers true if the mappings include one between the given (dataset)
+ * sequences.
+ */
+ public static boolean mappingExists(Set<AlignedCodonFrame> set,
+ SequenceI aaSeq, SequenceI cdnaSeq)
+ {
+ if (set != null)
+ {
+ for (AlignedCodonFrame acf : set)
+ {
+ if (cdnaSeq == acf.getDnaForAaSeq(aaSeq))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Build a mapping (if possible) of a protein to a cDNA sequence. The cDNA
+ * must be three times the length of the protein, possibly after ignoring
+ * start and/or stop codons. Returns null if no mapping is determined.
+ *
+ * @param proteinSeqs
+ * @param cdnaSeq
+ * @return
+ */
+ public static MapList mapProteinToCdna(SequenceI proteinSeq,
+ SequenceI cdnaSeq)
+ {
+ String aaSeqString = proteinSeq.getDatasetSequence()
+ .getSequenceAsString();
+ String cdnaSeqString = cdnaSeq.getDatasetSequence()
+ .getSequenceAsString();
+ if (aaSeqString == null || cdnaSeqString == null)
+ {
+ return null;
+ }
+
+ final int mappedLength = 3 * aaSeqString.length();
+ int cdnaLength = cdnaSeqString.length();
+ int cdnaStart = 1;
+ int cdnaEnd = cdnaLength;
+ final int proteinStart = 1;
+ final int proteinEnd = aaSeqString.length();
+
+ /*
+ * If lengths don't match, try ignoring stop codon.
+ */
+ if (cdnaLength != mappedLength)
+ {
+ for (Object stop : ResidueProperties.STOP)
+ {
+ if (cdnaSeqString.toUpperCase().endsWith((String) stop))
+ {
+ cdnaEnd -= 3;
+ cdnaLength -= 3;
+ break;
+ }
+ }
+ }
+
+ /*
+ * If lengths still don't match, try ignoring start codon.
+ */
+ if (cdnaLength != mappedLength
+ && cdnaSeqString.toUpperCase().startsWith(
+ ResidueProperties.START))
+ {
+ cdnaStart += 3;
+ cdnaLength -= 3;
+ }
+
+ if (cdnaLength == mappedLength)
+ {
+ MapList map = new MapList(new int[]
+ { cdnaStart, cdnaEnd }, new int[]
+ { proteinStart, proteinEnd }, 3, 1);
+ return map;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Align sequence 'seq' to match the alignment of a mapped sequence. Note this
+ * currently assumes that we are aligning cDNA to match protein.
+ *
+ * @param seq
+ * the sequence to be realigned
+ * @param al
+ * the alignment whose sequence alignment is to be 'copied'
+ * @param gap
+ * character string represent a gap in the realigned sequence
+ * @param preserveUnmappedGaps
+ * @param preserveMappedGaps
+ * @return true if the sequence was realigned, false if it could not be
+ */
+ public static boolean alignSequenceAs(SequenceI seq, AlignmentI al,
+ String gap, boolean preserveMappedGaps,
+ boolean preserveUnmappedGaps)
+ {
+ /*
+ * Get any mappings from the source alignment to the target (dataset) sequence.
+ */
+ // TODO there may be one AlignedCodonFrame per dataset sequence, or one with
+ // all mappings. Would it help to constrain this?
+ List<AlignedCodonFrame> mappings = al.getCodonFrame(seq);
+ if (mappings == null)
+ {
+ return false;
+ }
+
+ /*
+ * Locate the aligned source sequence whose dataset sequence is mapped. We
+ * just take the first match here (as we can't align cDNA like more than one
+ * protein sequence).
+ */
+ SequenceI alignFrom = null;
+ AlignedCodonFrame mapping = null;
+ for (AlignedCodonFrame mp : mappings)
+ {
+ alignFrom = mp.findAlignedSequence(seq.getDatasetSequence(), al);
+ if (alignFrom != null)
+ {
+ mapping = mp;
+ break;
+ }
+ }
+
+ if (alignFrom == null)
+ {
+ return false;
+ }
+ alignSequenceAs(seq, alignFrom, mapping, gap, al.getGapCharacter(),
+ preserveMappedGaps, preserveUnmappedGaps);
+ return true;
+ }
+
+ /**
+ * Align sequence 'alignTo' the same way as 'alignFrom', using the mapping to
+ * match residues and codons. Flags control whether existing gaps in unmapped
+ * (intron) and mapped (exon) regions are preserved or not. Gaps linking intro
+ * and exon are only retained if both flags are set.
+ *
+ * @param alignTo
+ * @param alignFrom
+ * @param mapping
+ * @param myGap
+ * @param sourceGap
+ * @param preserveUnmappedGaps
+ * @param preserveMappedGaps
+ */
+ public static void alignSequenceAs(SequenceI alignTo,
+ SequenceI alignFrom,
+ AlignedCodonFrame mapping, String myGap, char sourceGap,
+ boolean preserveMappedGaps, boolean preserveUnmappedGaps)
+ {
+ // TODO generalise to work for Protein-Protein, dna-dna, dna-protein
+ final char[] thisSeq = alignTo.getSequence();
+ final char[] thatAligned = alignFrom.getSequence();
+ StringBuilder thisAligned = new StringBuilder(2 * thisSeq.length);
+
+ // aligned and dataset sequence positions, all base zero
+ int thisSeqPos = 0;
+ int sourceDsPos = 0;
+
+ int basesWritten = 0;
+ char myGapChar = myGap.charAt(0);
+ int ratio = myGap.length();
+
+ /*
+ * Traverse the aligned protein sequence.
+ */
+ int sourceGapMappedLength = 0;
+ boolean inExon = false;
+ for (char sourceChar : thatAligned)
+ {
+ if (sourceChar == sourceGap)
+ {
+ sourceGapMappedLength += ratio;
+ continue;
+ }
+
+ /*
+ * Found a residue. Locate its mapped codon (start) position.
+ */
+ sourceDsPos++;
+ // Note mapping positions are base 1, our sequence positions base 0
+ int[] mappedPos = mapping.getMappedRegion(alignTo, alignFrom,
+ sourceDsPos);
+ if (mappedPos == null)
+ {
+ /*
+ * Abort realignment if unmapped protein. Or could ignore it??
+ */
+ System.err.println("Can't align: no codon mapping to residue "
+ + sourceDsPos + "(" + sourceChar + ")");
+ return;
+ }
+
+ int mappedCodonStart = mappedPos[0]; // position (1...) of codon start
+ int mappedCodonEnd = mappedPos[mappedPos.length - 1]; // codon end pos
+ StringBuilder trailingCopiedGap = new StringBuilder();
+
+ /*
+ * Copy dna sequence up to and including this codon. Optionally, include
+ * gaps before the codon starts (in introns) and/or after the codon starts
+ * (in exons).
+ *
+ * Note this only works for 'linear' splicing, not reverse or interleaved.
+ * But then 'align dna as protein' doesn't make much sense otherwise.
+ */
+ int intronLength = 0;
+ while (basesWritten < mappedCodonEnd && thisSeqPos < thisSeq.length)
+ {
+ final char c = thisSeq[thisSeqPos++];
+ if (c != myGapChar)
+ {
+ basesWritten++;
+
+ if (basesWritten < mappedCodonStart)
+ {
+ /*
+ * Found an unmapped (intron) base. First add in any preceding gaps
+ * (if wanted).
+ */
+ if (preserveUnmappedGaps && trailingCopiedGap.length() > 0)
+ {
+ thisAligned.append(trailingCopiedGap.toString());
+ intronLength += trailingCopiedGap.length();
+ trailingCopiedGap = new StringBuilder();
+ }
+ intronLength++;
+ inExon = false;
+ }
+ else
+ {
+ final boolean startOfCodon = basesWritten == mappedCodonStart;
+ int gapsToAdd = calculateGapsToInsert(preserveMappedGaps,
+ preserveUnmappedGaps, sourceGapMappedLength, inExon,
+ trailingCopiedGap.length(), intronLength, startOfCodon);
+ for (int i = 0; i < gapsToAdd; i++)
+ {
+ thisAligned.append(myGapChar);
+ }
+ sourceGapMappedLength = 0;
+ inExon = true;
+ }
+ thisAligned.append(c);
+ trailingCopiedGap = new StringBuilder();
+ }
+ else
+ {
+ if (inExon && preserveMappedGaps)
+ {
+ trailingCopiedGap.append(myGapChar);
+ }
+ else if (!inExon && preserveUnmappedGaps)
+ {
+ trailingCopiedGap.append(myGapChar);
+ }
+ }
+ }
+ }
+
+ /*
+ * At end of protein sequence. Copy any remaining dna sequence, optionally
+ * including (intron) gaps. We do not copy trailing gaps in protein.
+ */
+ while (thisSeqPos < thisSeq.length)
+ {
+ final char c = thisSeq[thisSeqPos++];
+ if (c != myGapChar || preserveUnmappedGaps)
+ {
+ thisAligned.append(c);
+ }
+ }
+
+ /*
+ * All done aligning, set the aligned sequence.
+ */
+ alignTo.setSequence(new String(thisAligned));
+ }
+
+ /**
+ * Helper method to work out how many gaps to insert when realigning.
+ *
+ * @param preserveMappedGaps
+ * @param preserveUnmappedGaps
+ * @param sourceGapMappedLength
+ * @param inExon
+ * @param trailingCopiedGap
+ * @param intronLength
+ * @param startOfCodon
+ * @return
+ */
+ protected static int calculateGapsToInsert(boolean preserveMappedGaps,
+ boolean preserveUnmappedGaps, int sourceGapMappedLength,
+ boolean inExon, int trailingGapLength,
+ int intronLength, final boolean startOfCodon)
+ {
+ int gapsToAdd = 0;
+ if (startOfCodon)
+ {
+ /*
+ * Reached start of codon. Ignore trailing gaps in intron unless we are
+ * preserving gaps in both exon and intron. Ignore them anyway if the
+ * protein alignment introduces a gap at least as large as the intronic
+ * region.
+ */
+ if (inExon && !preserveMappedGaps)
+ {
+ trailingGapLength = 0;
+ }
+ if (!inExon && !(preserveMappedGaps && preserveUnmappedGaps))
+ {
+ trailingGapLength = 0;
+ }
+ if (inExon)
+ {
+ gapsToAdd = Math.max(sourceGapMappedLength, trailingGapLength);
+ }
+ else
+ {
+ if (intronLength + trailingGapLength <= sourceGapMappedLength)
+ {
+ gapsToAdd = sourceGapMappedLength - intronLength;
+ }
+ else
+ {
+ gapsToAdd = Math.min(intronLength + trailingGapLength
+ - sourceGapMappedLength, trailingGapLength);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * second or third base of codon; check for any gaps in dna
+ */
+ if (!preserveMappedGaps)
+ {
+ trailingGapLength = 0;
+ }
+ gapsToAdd = Math.max(sourceGapMappedLength, trailingGapLength);
+ }
+ return gapsToAdd;
+ }
}
--- /dev/null
+package jalview.analysis;
+
+import jalview.datamodel.AlignedCodon;
+
+import java.util.Comparator;
+
+/**
+ * Implements rules for comparing two aligned codons, i.e. determining whether
+ * they should occupy the same position in a translated protein alignment, or
+ * one or the other should 'follow' (by preceded by a gap).
+ *
+ * @author gmcarstairs
+ *
+ */
+public final class CodonComparator implements Comparator<AlignedCodon>
+{
+
+ @Override
+ public int compare(AlignedCodon ac1, AlignedCodon ac2)
+ {
+ if (ac1 == null || ac2 == null || ac1.equals(ac2))
+ {
+ return 0;
+ }
+
+ /**
+ * <pre>
+ * Case 1: if one starts before the other, and doesn't end after it, then it
+ * precedes. We ignore the middle base position here.
+ * A--GT
+ * -CT-G
+ * </pre>
+ */
+ if (ac1.pos1 < ac2.pos1 && ac1.pos3 <= ac2.pos3)
+ {
+ return -1;
+ }
+ if (ac2.pos1 < ac1.pos1 && ac2.pos3 <= ac1.pos3)
+ {
+ return 1;
+ }
+
+ /**
+ * <pre>
+ * Case 2: if one ends after the other, and doesn't start before it, then it
+ * follows. We ignore the middle base position here.
+ * -TG-A
+ * G-TC
+ * </pre>
+ */
+ if (ac1.pos3 > ac2.pos3 && ac1.pos1 >= ac2.pos1)
+ {
+ return 1;
+ }
+ if (ac2.pos3 > ac1.pos3 && ac2.pos1 >= ac1.pos1)
+ {
+ return -1;
+ }
+
+ /*
+ * Case 3: if start and end match, compare middle base positions.
+ */
+ if (ac1.pos1 == ac2.pos1 && ac1.pos3 == ac2.pos3)
+ {
+ return Integer.compare(ac1.pos2, ac2.pos2);
+ }
+
+ /*
+ * That just leaves the 'enclosing' case - one codon starts after but ends
+ * before the other. If the middle bases don't match, use their comparison
+ * (majority vote).
+ */
+ int compareMiddles = Integer.compare(ac1.pos2, ac2.pos2);
+ if (compareMiddles != 0)
+ {
+ return compareMiddles;
+ }
+
+ /**
+ * <pre>
+ * Finally just leaves overlap with matching middle base, e.g.
+ * -A-A-A
+ * G--GG
+ * In this case the choice is arbitrary whether to compare based on
+ * first or last base position. We pick the first. Note this preserves
+ * symmetricality of the comparison.
+ * </pre>
+ */
+ return Integer.compare(ac1.pos1, ac2.pos1);
+ }
+}
*/
package jalview.analysis;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Vector;
-import java.util.Hashtable;
-
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
-import jalview.datamodel.DBRefSource;
import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.ws.SequenceFetcher;
import jalview.ws.seqfetcher.ASequenceFetcher;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
/**
* Functions for cross-referencing sequence databases. user must first specify
* if cross-referencing from protein or dna (set dna==true)
{
Vector rseqs = new Vector();
Alignment ral = null;
- AlignedCodonFrame cf = new AlignedCodonFrame(0); // nominal width
+ AlignedCodonFrame cf = new AlignedCodonFrame(); // nominal width
for (int s = 0; s < seqs.length; s++)
{
SequenceI dss = seqs[s];
for (int r = 0; xrfs != null && r < xrfs.length; r++)
{
if (source != null && !source.equals(xrfs[r].getSource()))
+ {
continue;
+ }
if (xrfs[r].hasMap())
{
if (xrfs[r].getMap().getTo() != null)
{
found |= searchDataset(dss, xrfs[r], dataset, rseqs, cf); // ,false,!dna);
if (found)
+ {
xrfs[r] = null; // we've recovered seqs for this one.
+ }
}
}
}
for (int r = 0; r < xrfs.length; r++)
{
if (xrfs[r] != null)
+ {
t[l++] = xrfs[r];
+ }
}
xrfs = t;
try
{
boolean found = false;
if (lrfs == null)
+ {
return false;
+ }
for (int i = 0; i < lrfs.length; i++)
{
DBRefEntry xref = new DBRefEntry(lrfs[i]);
boolean found = false;
SequenceI[] typer = new SequenceI[1];
if (dataset == null)
+ {
return false;
+ }
if (dataset.getSequences() == null)
{
System.err.println("Empty dataset sequence set - NO VECTOR");
synchronized (ds = dataset.getSequences())
{
for (SequenceI nxt : ds)
+ {
if (nxt != null)
{
if (nxt.getDatasetSequence() != null)
}
}
+ }
}
return found;
}
*/
package jalview.analysis;
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.Vector;
-
+import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignedCodon;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
import jalview.datamodel.FeatureProperties;
+import jalview.datamodel.GraphLine;
import jalview.datamodel.Mapping;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
+import jalview.util.DBRefUtils;
import jalview.util.MapList;
import jalview.util.ShiftList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
public class Dna
{
- /**
+ private static final String STOP_X = "X";
+
+ private static final Comparator<AlignedCodon> comparator = new CodonComparator();
+
+ /*
+ * 'final' variables describe the inputs to the translation, which should not
+ * be modified.
+ */
+ final private List<SequenceI> selection;
+
+ final private String[] seqstring;
+
+ final private int[] contigs;
+
+ final private char gapChar;
+
+ final private AlignmentAnnotation[] annotations;
+
+ final private int dnaWidth;
+
+ final private Alignment dataset;
+
+ /*
+ * Working variables for the translation.
*
- * @param cdp1
- * @param cdp2
- * @return -1 if cdp1 aligns before cdp2, 0 if in the same column or cdp2 is
- * null, +1 if after cdp2
+ * The width of the translation-in-progress protein alignment.
*/
- private static int compare_codonpos(int[] cdp1, int[] cdp2)
- {
- if (cdp2 == null
- || (cdp1[0] == cdp2[0] && cdp1[1] == cdp2[1] && cdp1[2] == cdp2[2]))
- return 0;
- if (cdp1[0] < cdp2[0] || cdp1[1] < cdp2[1] || cdp1[2] < cdp2[2])
- return -1; // one base in cdp1 precedes the corresponding base in the
- // other codon
- return 1; // one base in cdp1 appears after the corresponding base in the
- // other codon.
- }
+ private int aaWidth = 0;
- /**
- * DNA->mapped protein sequence alignment translation given set of sequences
- * 1. id distinct coding regions within selected region for each sequence 2.
- * generate peptides based on inframe (or given) translation or (optionally
- * and where specified) out of frame translations (annotated appropriately) 3.
- * align peptides based on codon alignment
+ /*
+ * This array will be built up so that position i holds the codon positions
+ * e.g. [7, 9, 10] that match column i (base 0) in the aligned translation.
+ * Note this implies a contract that if two codons do not align exactly, their
+ * translated products must occupy different column positions.
*/
+ private AlignedCodon[] alignedCodons;
+
/**
- * id potential products from dna 1. search for distinct products within
- * selected region for each selected sequence 2. group by associated DB type.
- * 3. return as form for input into above function
+ * Constructor given a viewport and the visible contigs.
+ *
+ * @param viewport
+ * @param visibleContigs
*/
+ public Dna(AlignViewportI viewport, int[] visibleContigs)
+ {
+ this.selection = Arrays.asList(viewport.getSequenceSelection());
+ this.seqstring = viewport.getViewAsString(true);
+ this.contigs = visibleContigs;
+ this.gapChar = viewport.getGapCharacter();
+ this.annotations = viewport.getAlignment().getAlignmentAnnotation();
+ this.dnaWidth = viewport.getAlignment().getWidth();
+ this.dataset = viewport.getAlignment().getDataset();
+ }
+
/**
+ * Test whether codon positions cdp1 should align before, with, or after cdp2.
+ * Returns zero if all positions match (or either argument is null). Returns
+ * -1 if any position in the first codon precedes the corresponding position
+ * in the second codon. Else returns +1 (some position in the second codon
+ * precedes the corresponding position in the first).
+ *
+ * Note this is not necessarily symmetric, for example:
+ * <ul>
+ * <li>compareCodonPos([2,5,6], [3,4,5]) returns -1</li>
+ * <li>compareCodonPos([3,4,5], [2,5,6]) also returns -1</li>
+ * </ul>
*
+ * @param ac1
+ * @param ac2
+ * @return
*/
+ public static final int compareCodonPos(AlignedCodon ac1, AlignedCodon ac2)
+ {
+ return comparator.compare(ac1, ac2);
+ // return jalview_2_8_2compare(ac1, ac2);
+ }
+
/**
- * create a new alignment of protein sequences by an inframe translation of
- * the provided NA sequences
+ * Codon comparison up to Jalview 2.8.2. This rule is sequence order dependent
+ * - see http://issues.jalview.org/browse/JAL-1635
*
- * @param selection
- * @param seqstring
- * @param viscontigs
- * @param gapCharacter
- * @param annotations
- * @param aWidth
- * @param dataset
- * destination dataset for translated sequences and mappings
+ * @param ac1
+ * @param ac2
* @return
*/
- public static AlignmentI CdnaTranslate(SequenceI[] selection,
- String[] seqstring, int viscontigs[], char gapCharacter,
- AlignmentAnnotation[] annotations, int aWidth, Alignment dataset)
+ private static int jalview_2_8_2compare(AlignedCodon ac1, AlignedCodon ac2)
{
- return CdnaTranslate(selection, seqstring, null, viscontigs,
- gapCharacter, annotations, aWidth, dataset);
+ if (ac1 == null || ac2 == null || (ac1.equals(ac2)))
+ {
+ return 0;
+ }
+ if (ac1.pos1 < ac2.pos1 || ac1.pos2 < ac2.pos2 || ac1.pos3 < ac2.pos3)
+ {
+ // one base in cdp1 precedes the corresponding base in the other codon
+ return -1;
+ }
+ // one base in cdp1 appears after the corresponding base in the other codon.
+ return 1;
}
/**
*
- * @param selection
- * @param seqstring
- * @param product
- * - array of DbRefEntry objects from which exon map in seqstring is
- * derived
- * @param viscontigs
- * @param gapCharacter
- * @param annotations
- * @param aWidth
- * @param dataset
* @return
*/
- public static AlignmentI CdnaTranslate(SequenceI[] selection,
- String[] seqstring, DBRefEntry[] product, int viscontigs[],
- char gapCharacter, AlignmentAnnotation[] annotations, int aWidth,
- Alignment dataset)
+ public AlignmentI translateCdna()
{
- AlignedCodonFrame codons = new AlignedCodonFrame(aWidth); // stores hash of
- // subsequent
- // positions for
- // each codon
- // start position
- // in alignment
- int s, sSize = selection.length;
- Vector pepseqs = new Vector();
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+
+ alignedCodons = new AlignedCodon[dnaWidth];
+
+ int s;
+ int sSize = selection.size();
+ List<SequenceI> pepseqs = new ArrayList<SequenceI>();
for (s = 0; s < sSize; s++)
{
- SequenceI newseq = translateCodingRegion(selection[s], seqstring[s],
- viscontigs, codons, gapCharacter,
- (product != null) ? product[s] : null, false); // possibly
- // anonymous
- // product
+ SequenceI newseq = translateCodingRegion(selection.get(s),
+ seqstring[s], acf, pepseqs);
+
if (newseq != null)
{
- pepseqs.addElement(newseq);
+ pepseqs.add(newseq);
SequenceI ds = newseq;
if (dataset != null)
{
}
}
}
- if (codons.aaWidth == 0)
- return null;
- SequenceI[] newseqs = new SequenceI[pepseqs.size()];
- pepseqs.copyInto(newseqs);
+
+ SequenceI[] newseqs = pepseqs.toArray(new SequenceI[pepseqs.size()]);
AlignmentI al = new Alignment(newseqs);
- al.padGaps(); // ensure we look aligned.
+ // ensure we look aligned.
+ al.padGaps();
+ // link the protein translation to the DNA dataset
al.setDataset(dataset);
- translateAlignedAnnotations(annotations, al, codons);
- al.addCodonFrame(codons);
+ translateAlignedAnnotations(al, acf);
+ al.addCodonFrame(acf);
return al;
}
for (int gd = 0; gd < selection.length; gd++)
{
SequenceI dna = selection[gd];
- jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils
+ DBRefEntry[] dnarefs = DBRefUtils
.selectRefs(dna.getDBRef(),
jalview.datamodel.DBRefSource.DNACODINGDBS);
if (dnarefs != null)
{
// intersect with pep
- // intersect with pep
- Vector mappedrefs = new Vector();
+ List<DBRefEntry> mappedrefs = new ArrayList<DBRefEntry>();
DBRefEntry[] refs = dna.getDBRef();
for (int d = 0; d < refs.length; d++)
{
&& refs[d].getMap().getMap().getFromRatio() == 3
&& refs[d].getMap().getMap().getToRatio() == 1)
{
- mappedrefs.addElement(refs[d]); // add translated protein maps
+ mappedrefs.add(refs[d]); // add translated protein maps
}
}
- dnarefs = new DBRefEntry[mappedrefs.size()];
- mappedrefs.copyInto(dnarefs);
+ dnarefs = mappedrefs.toArray(new DBRefEntry[mappedrefs.size()]);
for (int d = 0; d < dnarefs.length; d++)
{
Mapping mp = dnarefs[d].getMap();
}
/**
- * generate a set of translated protein products from annotated sequenceI
+ * Translate nucleotide alignment annotations onto translated amino acid
+ * alignment using codon mapping codons
*
- * @param selection
- * @param viscontigs
- * @param gapCharacter
- * @param dataset
- * destination dataset for translated sequences
- * @param annotations
- * @param aWidth
- * @return
- */
- public static AlignmentI CdnaTranslate(SequenceI[] selection,
- int viscontigs[], char gapCharacter, Alignment dataset)
- {
- int alwidth = 0;
- Vector cdnasqs = new Vector();
- Vector cdnasqi = new Vector();
- Vector cdnaprod = new Vector();
- for (int gd = 0; gd < selection.length; gd++)
- {
- SequenceI dna = selection[gd];
- jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils
- .selectRefs(dna.getDBRef(),
- jalview.datamodel.DBRefSource.DNACODINGDBS);
- if (dnarefs != null)
- {
- // intersect with pep
- Vector mappedrefs = new Vector();
- DBRefEntry[] refs = dna.getDBRef();
- for (int d = 0; d < refs.length; d++)
- {
- if (refs[d].getMap() != null && refs[d].getMap().getMap() != null
- && refs[d].getMap().getMap().getFromRatio() == 3
- && refs[d].getMap().getMap().getToRatio() == 1)
- {
- mappedrefs.addElement(refs[d]); // add translated protein maps
- }
- }
- dnarefs = new DBRefEntry[mappedrefs.size()];
- mappedrefs.copyInto(dnarefs);
- for (int d = 0; d < dnarefs.length; d++)
- {
- Mapping mp = dnarefs[d].getMap();
- StringBuffer sqstr = new StringBuffer();
- if (mp != null)
- {
- Mapping intersect = mp.intersectVisContigs(viscontigs);
- // generate seqstring for this sequence based on mapping
-
- if (sqstr.length() > alwidth)
- alwidth = sqstr.length();
- cdnasqs.addElement(sqstr.toString());
- cdnasqi.addElement(dna);
- cdnaprod.addElement(intersect);
- }
- }
- }
- SequenceI[] cdna = new SequenceI[cdnasqs.size()];
- DBRefEntry[] prods = new DBRefEntry[cdnaprod.size()];
- String[] xons = new String[cdnasqs.size()];
- cdnasqs.copyInto(xons);
- cdnaprod.copyInto(prods);
- cdnasqi.copyInto(cdna);
- return CdnaTranslate(cdna, xons, prods, viscontigs, gapCharacter,
- null, alwidth, dataset);
- }
- return null;
- }
-
- /**
- * translate na alignment annotations onto translated amino acid alignment al
- * using codon mapping codons
- *
- * @param annotations
* @param al
- * @param codons
+ * the translated protein alignment
*/
- public static void translateAlignedAnnotations(
- AlignmentAnnotation[] annotations, AlignmentI al,
- AlignedCodonFrame codons)
+ protected void translateAlignedAnnotations(AlignmentI al,
+ AlignedCodonFrame acf)
{
- // //////////////////////////////
- // Copy annotations across
- //
// Can only do this for columns with consecutive codons, or where
// annotation is sequence associated.
- int pos, a, aSize;
if (annotations != null)
{
- for (int i = 0; i < annotations.length; i++)
+ for (AlignmentAnnotation annotation : annotations)
{
- // Skip any autogenerated annotation
- if (annotations[i].autoCalculated)
+ /*
+ * Skip hidden or autogenerated annotation. Also (for now), RNA
+ * secondary structure annotation. If we want to show this against
+ * protein we need a smarter way to 'translate' without generating
+ * invalid (unbalanced) structure annotation.
+ */
+ if (annotation.autoCalculated || !annotation.visible
+ || annotation.isRNA())
{
continue;
}
- aSize = codons.getaaWidth(); // aa alignment width.
- jalview.datamodel.Annotation[] anots = (annotations[i].annotations == null) ? null
- : new jalview.datamodel.Annotation[aSize];
+ int aSize = aaWidth;
+ Annotation[] anots = (annotation.annotations == null) ? null
+ : new Annotation[aSize];
if (anots != null)
{
- for (a = 0; a < aSize; a++)
+ for (int a = 0; a < aSize; a++)
{
// process through codon map.
- if (codons.codons[a] != null
- && codons.codons[a][0] == (codons.codons[a][2] - 2))
+ if (a < alignedCodons.length && alignedCodons[a] != null
+ && alignedCodons[a].pos1 == (alignedCodons[a].pos3 - 2))
{
- anots[a] = getCodonAnnotation(codons.codons[a],
- annotations[i].annotations);
+ anots[a] = getCodonAnnotation(alignedCodons[a],
+ annotation.annotations);
}
}
}
- jalview.datamodel.AlignmentAnnotation aa = new jalview.datamodel.AlignmentAnnotation(
- annotations[i].label, annotations[i].description, anots);
- aa.graph = annotations[i].graph;
- aa.graphGroup = annotations[i].graphGroup;
- aa.graphHeight = annotations[i].graphHeight;
- if (annotations[i].getThreshold() != null)
+ AlignmentAnnotation aa = new AlignmentAnnotation(annotation.label,
+ annotation.description, anots);
+ aa.graph = annotation.graph;
+ aa.graphGroup = annotation.graphGroup;
+ aa.graphHeight = annotation.graphHeight;
+ if (annotation.getThreshold() != null)
{
- aa.setThreshold(new jalview.datamodel.GraphLine(annotations[i]
+ aa.setThreshold(new GraphLine(annotation
.getThreshold()));
}
- if (annotations[i].hasScore)
+ if (annotation.hasScore)
{
- aa.setScore(annotations[i].getScore());
+ aa.setScore(annotation.getScore());
}
- if (annotations[i].sequenceRef != null)
+
+ final SequenceI seqRef = annotation.sequenceRef;
+ if (seqRef != null)
{
- SequenceI aaSeq = codons
- .getAaForDnaSeq(annotations[i].sequenceRef);
+ SequenceI aaSeq = acf.getAaForDnaSeq(seqRef);
if (aaSeq != null)
{
// aa.compactAnnotationArray(); // throw away alignment annotation
// positioning
aa.setSequenceRef(aaSeq);
- aa.createSequenceMapping(aaSeq, aaSeq.getStart(), true); // rebuild
- // mapping
+ // rebuild mapping
+ aa.createSequenceMapping(aaSeq, aaSeq.getStart(), true);
aa.adjustForAlignment();
aaSeq.addAlignmentAnnotation(aa);
}
-
}
al.addAnnotation(aa);
}
}
}
- private static Annotation getCodonAnnotation(int[] is,
+ private static Annotation getCodonAnnotation(AlignedCodon is,
Annotation[] annotations)
{
// Have a look at all the codon positions for annotation and put the first
// one found into the translated annotation pos.
int contrib = 0;
Annotation annot = null;
- for (int p = 0; p < 3; p++)
+ for (int p = 1; p <= 3; p++)
{
- if (annotations[is[p]] != null)
+ int dnaCol = is.getBaseColumn(p);
+ if (annotations[dnaCol] != null)
{
if (annot == null)
{
- annot = new Annotation(annotations[is[p]]);
+ annot = new Annotation(annotations[dnaCol]);
contrib = 1;
}
else
{
// merge with last
- Annotation cpy = new Annotation(annotations[is[p]]);
+ Annotation cpy = new Annotation(annotations[dnaCol]);
if (annot.colour == null)
{
annot.colour = cpy.colour;
}
if (contrib > 1)
{
- annot.value /= (float) contrib;
+ annot.value /= contrib;
}
return annot;
}
* sequence displayed under viscontigs visible columns
* @param seqstring
* ORF read in some global alignment reference frame
- * @param viscontigs
- * mapping from global reference frame to visible seqstring ORF read
- * @param codons
- * Definition of global ORF alignment reference frame
- * @param gapCharacter
- * @return sequence ready to be added to alignment.
- * @deprecated Use
- * {@link #translateCodingRegion(SequenceI,String,int[],AlignedCodonFrame,char,DBRefEntry,boolean)}
- * instead
- */
- public static SequenceI translateCodingRegion(SequenceI selection,
- String seqstring, int[] viscontigs, AlignedCodonFrame codons,
- char gapCharacter, DBRefEntry product)
- {
- return translateCodingRegion(selection, seqstring, viscontigs, codons,
- gapCharacter, product, false);
- }
-
- /**
- * Translate a na sequence
- *
- * @param selection
- * sequence displayed under viscontigs visible columns
- * @param seqstring
- * ORF read in some global alignment reference frame
- * @param viscontigs
- * mapping from global reference frame to visible seqstring ORF read
- * @param codons
+ * @param acf
* Definition of global ORF alignment reference frame
- * @param gapCharacter
- * @param starForStop
- * when true stop codons will translate as '*', otherwise as 'X'
+ * @param proteinSeqs
* @return sequence ready to be added to alignment.
*/
- public static SequenceI translateCodingRegion(SequenceI selection,
- String seqstring, int[] viscontigs, AlignedCodonFrame codons,
- char gapCharacter, DBRefEntry product, final boolean starForStop)
+ protected SequenceI translateCodingRegion(SequenceI selection,
+ String seqstring, AlignedCodonFrame acf,
+ List<SequenceI> proteinSeqs)
{
- java.util.List skip = new ArrayList();
+ List<int[]> skip = new ArrayList<int[]>();
int skipint[] = null;
ShiftList vismapping = new ShiftList(); // map from viscontigs to seqstring
// intervals
- int vc, scontigs[] = new int[viscontigs.length];
+ int vc;
+ int[] scontigs = new int[contigs.length];
int npos = 0;
- for (vc = 0; vc < viscontigs.length; vc += 2)
+ for (vc = 0; vc < contigs.length; vc += 2)
{
if (vc == 0)
{
- vismapping.addShift(npos, viscontigs[vc]);
+ vismapping.addShift(npos, contigs[vc]);
}
else
{
// hidden region
- vismapping.addShift(npos, viscontigs[vc] - viscontigs[vc - 1] + 1);
+ vismapping.addShift(npos, contigs[vc] - contigs[vc - 1] + 1);
}
- scontigs[vc] = viscontigs[vc];
- scontigs[vc + 1] = viscontigs[vc + 1];
+ scontigs[vc] = contigs[vc];
+ scontigs[vc + 1] = contigs[vc + 1];
}
- StringBuffer protein = new StringBuffer();
- String seq = seqstring.replace('U', 'T');
+ // allocate a roughly sized buffer for the protein sequence
+ StringBuilder protein = new StringBuilder(seqstring.length() / 2);
+ String seq = seqstring.replace('U', 'T').replace('u', 'T');
char codon[] = new char[3];
- int cdp[] = new int[3], rf = 0, lastnpos = 0, nend;
+ int cdp[] = new int[3];
+ int rf = 0;
+ int lastnpos = 0;
+ int nend;
int aspos = 0;
int resSize = 0;
for (npos = 0, nend = seq.length(); npos < nend; npos++)
{
- if (!jalview.util.Comparison.isGap(seq.charAt(npos)))
+ if (!Comparison.isGap(seq.charAt(npos)))
{
cdp[rf] = npos; // store position
codon[rf++] = seq.charAt(npos); // store base
}
- // filled an RF yet ?
if (rf == 3)
{
+ /*
+ * Filled up a reading frame...
+ */
+ AlignedCodon alignedCodon = new AlignedCodon(cdp[0], cdp[1], cdp[2]);
String aa = ResidueProperties.codonTranslate(new String(codon));
rf = 0;
+ final String gapString = String.valueOf(gapChar);
if (aa == null)
{
- aa = String.valueOf(gapCharacter);
+ aa = gapString;
if (skipint == null)
{
skipint = new int[]
- { cdp[0], cdp[2] };
+ { alignedCodon.pos1, alignedCodon.pos3 /* cdp[0], cdp[2] */};
}
- skipint[1] = cdp[2];
+ skipint[1] = alignedCodon.pos3; // cdp[2];
}
else
{
}
if (aa.equals("STOP"))
{
- aa = starForStop ? "*" : "X";
+ aa = STOP_X;
}
resSize++;
}
- // insert/delete gaps prior to this codon - if necessary
boolean findpos = true;
while (findpos)
{
- // first ensure that the codons array is long enough.
- codons.checkCodonFrameWidth(aspos);
- // now check to see if we place the aa at the current aspos in the
- // protein alignment
- switch (Dna.compare_codonpos(cdp, codons.codons[aspos]))
+ /*
+ * Compare this codon's base positions with those currently aligned to
+ * this column in the translation.
+ */
+ final int compareCodonPos = compareCodonPos(alignedCodon,
+ alignedCodons[aspos]);
+ switch (compareCodonPos)
{
case -1:
- codons.insertAAGap(aspos, gapCharacter);
+
+ /*
+ * This codon should precede the mapped positions - need to insert a
+ * gap in all prior sequences.
+ */
+ insertAAGap(aspos, proteinSeqs);
findpos = false;
break;
+
case +1:
- // this aa appears after the aligned codons at aspos, so prefix it
- // with a gap
- aa = "" + gapCharacter + aa;
+
+ /*
+ * This codon belongs after the aligned codons at aspos. Prefix it
+ * with a gap and try the next position.
+ */
+ aa = gapString + aa;
aspos++;
- // if (aspos >= codons.aaWidth)
- // codons.aaWidth = aspos + 1;
- break; // check the next position for alignment
+ break;
+
case 0:
- // codon aligns at aspos position.
+
+ /*
+ * Exact match - codon 'belongs' at this translated position.
+ */
findpos = false;
}
}
- // codon aligns with all other sequence residues found at aspos
protein.append(aa);
lastnpos = npos;
- if (codons.codons[aspos] == null)
+ if (alignedCodons[aspos] == null)
{
// mark this column as aligning to this aligned reading frame
- codons.codons[aspos] = new int[]
- { cdp[0], cdp[1], cdp[2] };
+ alignedCodons[aspos] = alignedCodon;
+ }
+ else if (!alignedCodons[aspos].equals(alignedCodon))
+ {
+ throw new IllegalStateException("Tried to coalign "
+ + alignedCodons[aspos].toString() + " with "
+ + alignedCodon.toString());
}
- if (aspos >= codons.aaWidth)
+ if (aspos >= aaWidth)
{
// update maximum alignment width
- // (we can do this without calling checkCodonFrameWidth because it was
- // already done above)
- codons.setAaWidth(aspos);
+ aaWidth = aspos;
}
// ready for next translated reading frame alignment position (if any)
aspos++;
protein.toString());
if (rf != 0)
{
- if (jalview.bin.Cache.log != null)
+ final String errMsg = "trimming contigs for incomplete terminal codon.";
+ if (Cache.log != null)
{
- jalview.bin.Cache.log
- .debug("trimming contigs for incomplete terminal codon.");
+ Cache.log.debug(errMsg);
}
else
{
- System.err
- .println("trimming contigs for incomplete terminal codon.");
+ System.err.println(errMsg);
}
// map and trim contigs to ORF region
vc = scontigs.length - 1;
scontigs = t;
}
if (vc <= 0)
+ {
scontigs = null;
+ }
}
if (scontigs != null)
{
scontigs[vc] = selection.findPosition(scontigs[vc]); // not from 1!
scontigs[vc + 1] = selection.findPosition(scontigs[vc + 1]); // exclusive
if (scontigs[vc + 1] == selection.getEnd())
+ {
break;
+ }
}
// trim trailing empty intervals.
if ((vc + 2) < scontigs.length)
MapList map = new MapList(scontigs, new int[]
{ 1, resSize }, 3, 1);
- // update newseq as if it was generated as mapping from product
-
- if (product != null)
- {
- newseq.setName(product.getSource() + "|"
- + product.getAccessionId());
- if (product.getMap() != null)
- {
- // Mapping mp = product.getMap();
- // newseq.setStart(mp.getPosition(scontigs[0]));
- // newseq.setEnd(mp
- // .getPosition(scontigs[scontigs.length - 1]));
- }
- }
transferCodedFeatures(selection, newseq, map, null, null);
- SequenceI rseq = newseq.deriveSequence(); // construct a dataset
- // sequence for our new
- // peptide, regardless.
- // store a mapping (this actually stores a mapping between the dataset
- // sequences for the two sequences
- codons.addMap(selection, rseq, map);
+
+ /*
+ * Construct a dataset sequence for our new peptide.
+ */
+ SequenceI rseq = newseq.deriveSequence();
+
+ /*
+ * Store a mapping (between the dataset sequences for the two
+ * sequences).
+ */
+ // SIDE-EFFECT: acf stores the aligned sequence reseq; to remove!
+ acf.addMap(selection, rseq, map);
return rseq;
}
}
}
/**
+ * Insert a gap into the aligned proteins and the codon mapping array.
+ *
+ * @param pos
+ * @param proteinSeqs
+ * @return
+ */
+ protected void insertAAGap(int pos,
+ List<SequenceI> proteinSeqs)
+ {
+ aaWidth++;
+ for (SequenceI seq : proteinSeqs)
+ {
+ seq.insertCharAt(pos, gapChar);
+ }
+
+ checkCodonFrameWidth();
+ if (pos < aaWidth)
+ {
+ aaWidth++;
+
+ /*
+ * Shift from [pos] to the end one to the right, and null out [pos]
+ */
+ System.arraycopy(alignedCodons, pos, alignedCodons, pos + 1,
+ alignedCodons.length - pos - 1);
+ alignedCodons[pos] = null;
+ }
+ }
+
+ /**
+ * Check the codons array can accommodate a single insertion, if not resize
+ * it.
+ */
+ protected void checkCodonFrameWidth()
+ {
+ if (alignedCodons[alignedCodons.length - 1] != null)
+ {
+ /*
+ * arraycopy insertion would bump a filled slot off the end, so expand.
+ */
+ AlignedCodon[] c = new AlignedCodon[alignedCodons.length + 10];
+ System.arraycopy(alignedCodons, 0, c, 0, alignedCodons.length);
+ alignedCodons = c;
+ }
+ }
+
+ /**
* Given a peptide newly translated from a dna sequence, copy over and set any
* features on the peptide from the DNA. If featureTypes is null, all features
* on the dna sequence are searched (rather than just the displayed ones), and
* @param pep
* @param map
* @param featureTypes
- * hash who's keys are the displayed feature type strings
+ * hash whose keys are the displayed feature type strings
* @param featureGroups
* hash where keys are feature groups and values are Boolean objects
* indicating if they are displayed.
*/
private static void transferCodedFeatures(SequenceI dna, SequenceI pep,
- MapList map, Hashtable featureTypes, Hashtable featureGroups)
+ MapList map, Map<String, Object> featureTypes,
+ Map<String, Boolean> featureGroups)
{
- SequenceFeature[] sf = (dna.getDatasetSequence() != null ? dna
+ SequenceFeature[] sfs = (dna.getDatasetSequence() != null ? dna
.getDatasetSequence() : dna).getSequenceFeatures();
Boolean fgstate;
- jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils
- .selectRefs(dna.getDBRef(),
- jalview.datamodel.DBRefSource.DNACODINGDBS);
+ DBRefEntry[] dnarefs = DBRefUtils.selectRefs(dna.getDBRef(),
+ DBRefSource.DNACODINGDBS);
if (dnarefs != null)
{
// intersect with pep
}
}
}
- if (sf != null)
+ if (sfs != null)
{
- for (int f = 0; f < sf.length; f++)
+ for (SequenceFeature sf : sfs)
{
- fgstate = (featureGroups == null) ? null : ((Boolean) featureGroups
- .get(sf[f].featureGroup));
- if ((featureTypes == null || featureTypes.containsKey(sf[f]
- .getType())) && (fgstate == null || fgstate.booleanValue()))
+ fgstate = (featureGroups == null) ? null : featureGroups
+ .get(sf.featureGroup);
+ if ((featureTypes == null || featureTypes.containsKey(sf.getType()))
+ && (fgstate == null || fgstate.booleanValue()))
{
- if (FeatureProperties.isCodingFeature(null, sf[f].getType()))
+ if (FeatureProperties.isCodingFeature(null, sf.getType()))
{
// if (map.intersectsFrom(sf[f].begin, sf[f].end))
{
boolean hasHiddenRows();
+ /**
+ * Returns a viewport which holds the cDna for this (protein), or vice versa,
+ * or null if none is set.
+ *
+ * @return
+ */
+ AlignViewportI getCodingComplement();
+
+
+ /**
+ * Sets the viewport which holds the cDna for this (protein), or vice versa.
+ * Implementation should guarantee that the reciprocal relationship is always
+ * set, i.e. each viewport is the complement of the other.
+ */
+ void setCodingComplement(AlignViewportI sl);
+
+ /**
+ * Answers true if viewport hosts DNA/RNA, else false.
+ *
+ * @return
+ */
+ boolean isNucleotide();
+
}
int hiddenOffset = viewport.getSelectionGroup().getStartRes();
for (int[] region : viewport.getColumnSelection().getHiddenColumns())
{
-
copiedHiddenColumns.addElement(new int[]
{ region[0] - hiddenOffset, region[1] - hiddenOffset });
}
import jalview.structure.SelectionSource;
import jalview.structure.SequenceListener;
import jalview.structure.StructureSelectionManager;
+import jalview.structure.VamsasSource;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
void setCursorPosition()
{
- SequenceI sequence = av.getAlignment().getSequenceAt(
- seqCanvas.cursorY);
+ SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY);
seqCanvas.cursorX = sequence.findIndex(getKeyboardNo1()) - 1;
scrollToVisible();
void setSelectionAreaAtCursor(boolean topLeft)
{
- SequenceI sequence = av.getAlignment().getSequenceAt(
- seqCanvas.cursorY);
+ SequenceI sequence = av.getAlignment().getSequenceAt(seqCanvas.cursorY);
if (av.getSelectionGroup() != null)
{
}
+ @Override
+ public VamsasSource getVamsasSource()
+ {
+ return this.ap == null ? null : this.ap.av;
+ }
+
public void updateColours(SequenceI seq, int index)
{
System.out.println("update the seqPanel colours");
mouseOverSequence(sequence, res, respos);
}
- StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: "
- + sequence.getName());
+ StringBuilder text = new StringBuilder();
+ text.append("Sequence ").append(Integer.toString(seq + 1))
+ .append(" ID: ").append(sequence.getName());
- Object obj = null;
+ String obj = null;
+ final String ch = String.valueOf(sequence.getCharAt(res));
if (av.getAlignment().isNucleotide())
{
- obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res)
- + "");
+ obj = ResidueProperties.nucleotideName.get(ch);
if (obj != null)
{
- text.append(" Nucleotide: ");
+ text.append(" Nucleotide: ").append(obj);
}
}
else
{
- obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + "");
+ obj = "X".equalsIgnoreCase(ch) ? "STOP"
+ : ResidueProperties.aa2Triplet.get(ch);
if (obj != null)
{
- text.append(" Residue: ");
+ text.append(" Residue: ").append(obj);
}
}
if (obj != null)
{
- if (obj != "")
- {
- text.append(obj + " (" + respos + ")");
- }
+ text.append(" (").append(Integer.toString(respos)).append(")");
}
ap.alignFrame.statusBar.setText(text.toString());
- StringBuffer tooltipText = new StringBuffer();
+ StringBuilder tooltipText = new StringBuilder();
SequenceGroup[] groups = av.getAlignment().findAllGroups(sequence);
if (groups != null)
{
if (!groups[g].getName().startsWith("JTreeGroup")
&& !groups[g].getName().startsWith("JGroup"))
{
- tooltipText.append(groups[g].getName() + " ");
+ tooltipText.append(groups[g].getName()).append(" ");
}
if (groups[g].getDescription() != null)
{
StringBuffer message = new StringBuffer();
if (groupEditing)
{
- message.append(MessageManager.getString("action.edit_group")).append(":");
+ message.append(MessageManager.getString("action.edit_group")).append(
+ ":");
if (editCommand == null)
{
- editCommand = new EditCommand(MessageManager.getString("action.edit_group"));
+ editCommand = new EditCommand(
+ MessageManager.getString("action.edit_group"));
}
}
else
{
- message.append(MessageManager.getString("label.edit_sequence")).append(" " + seq.getName());
+ message.append(MessageManager.getString("label.edit_sequence"))
+ .append(" " + seq.getName());
String label = seq.getName();
if (label.length() > 10)
{
}
if (editCommand == null)
{
- editCommand = new EditCommand(MessageManager.formatMessage("label.edit_params", new String[]{label}));
+ editCommand = new EditCommand(MessageManager.formatMessage(
+ "label.edit_params", new String[]
+ { label }));
}
}
}
else
{
- editCommand.appendEdit(Action.INSERT_GAP, groupSeqs,
- startres, startres - lastres, av.getAlignment(), true);
+ editCommand.appendEdit(Action.INSERT_GAP, groupSeqs, startres,
+ startres - lastres, av.getAlignment(), true);
}
}
else
}
else
{
- editCommand.appendEdit(Action.DELETE_GAP, groupSeqs,
- startres, lastres - startres, av.getAlignment(), true);
+ editCommand.appendEdit(Action.DELETE_GAP, groupSeqs, startres,
+ lastres - startres, av.getAlignment(), true);
}
}
editCommand.appendEdit(Action.DELETE_GAP, seq, blankColumn, 1,
av.getAlignment(), true);
- editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1,
- av.getAlignment(), true);
+ editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1, av.getAlignment(),
+ true);
}
void deleteChar(int j, SequenceI[] seq, int fixedColumn)
{
- editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1,
- av.getAlignment(), true);
+ editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1, av.getAlignment(),
+ true);
editCommand.appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1,
av.getAlignment(), true);
private static FeatureFetcher startFeatureFetching(final Vector dasSources)
{
FeatureFetcher ff = new FeatureFetcher();
- AlignFrame afs[] = Desktop.getAlignframes();
+ AlignFrame afs[] = Desktop.getAlignFrames();
if (afs == null || afs.length == 0)
{
return null;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Hashtable;
+import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
end = rs.findIndex(end);
if (csel != null)
{
- Vector cs = csel.getSelected();
+ List<Integer> cs = csel.getSelected();
csel.clear();
- for (int csi = 0, csiS = cs.size(); csi < csiS; csi++)
+ for (Integer selectedCol : cs)
{
- csel.addElement(rs.findIndex(((Integer) cs.elementAt(csi))
- .intValue()));
+ csel.addElement(rs.findIndex(selectedCol));
}
}
}
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
+import jalview.util.ReverseListIterator;
+import jalview.util.StringUtils;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+import java.util.Map;
/**
*
{
public enum Action
{
- INSERT_GAP, DELETE_GAP, CUT, PASTE, REPLACE, INSERT_NUC
+ INSERT_GAP()
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return DELETE_GAP;
+ }
+ },
+ DELETE_GAP()
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return INSERT_GAP;
+ }
+ },
+ CUT()
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return PASTE;
+ }
+ },
+ PASTE()
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return CUT;
+ }
+ },
+ REPLACE
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return REPLACE;
+ }
+ },
+ INSERT_NUC
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return null;
+ }
+ };
+ public abstract Action getUndoAction();
};
private List<Edit> edits = new ArrayList<Edit>();
}
/**
- * Add the given edit command to the stored list of commands.
+ * Add the given edit command to the stored list of commands. If simply
+ * expanding the range of the last command added, then modify it instead of
+ * adding a new command.
*
* @param e
*/
- protected void addEdit(Edit e)
+ public void addEdit(Edit e)
{
- edits.add(e);
+ if (!expandEdit(edits, e))
+ {
+ edits.add(e);
+ }
+ }
+
+ /**
+ * Returns true if the new edit is incorporated by updating (expanding the
+ * range of) the last edit on the list, else false. We can 'expand' the last
+ * edit if the new one is the same action, on the same sequences, and acts on
+ * a contiguous range. This is the case where a mouse drag generates a series
+ * of contiguous gap insertions or deletions.
+ *
+ * @param edits
+ * @param e
+ * @return
+ */
+ protected static boolean expandEdit(List<Edit> edits, Edit e)
+ {
+ if (edits == null || edits.isEmpty())
+ {
+ return false;
+ }
+ Edit lastEdit = edits.get(edits.size() - 1);
+ Action action = e.command;
+ if (lastEdit.command != action)
+ {
+ return false;
+ }
+
+ /*
+ * Both commands must act on the same sequences - compare the underlying
+ * dataset sequences, rather than the aligned sequences, which change as
+ * they are edited.
+ */
+ if (lastEdit.seqs.length != e.seqs.length)
+ {
+ return false;
+ }
+ for (int i = 0; i < e.seqs.length; i++)
+ {
+ if (lastEdit.seqs[i].getDatasetSequence() != e.seqs[i]
+ .getDatasetSequence())
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Check a contiguous edit; either
+ * <ul>
+ * <li>a new Insert <n> positions to the right of the last <insert n>, or</li>
+ * <li>a new Delete <n> gaps which is <n> positions to the left of the last
+ * delete.</li>
+ * </ul>
+ */
+ boolean contiguous = (action == Action.INSERT_GAP && e.position == lastEdit.position
+ + lastEdit.number)
+ || (action == Action.DELETE_GAP && e.position + e.number == lastEdit.position);
+ if (contiguous)
+ {
+ /*
+ * We are just expanding the range of the last edit. For delete gap, also
+ * moving the start position left.
+ */
+ lastEdit.number += e.number;
+ lastEdit.seqs = e.seqs;
+ if (action == Action.DELETE_GAP)
+ {
+ lastEdit.position--;
+ }
+ return true;
+ }
+ return false;
}
/**
edit.fullAlignmentHeight = true;
}
- edits.add(edit);
+ addEdit(edit);
+
+ if (performEdit)
+ {
+ performEdit(edit, views);
+ }
+ }
+
+ /**
+ * Overloaded method that accepts an Edit object with additional parameters.
+ *
+ * @param edit
+ * @param al
+ * @param performEdit
+ * @param views
+ */
+ final public void appendEdit(Edit edit, AlignmentI al,
+ boolean performEdit, AlignmentI[] views)
+ {
+ if (al.getHeight() == edit.seqs.length)
+ {
+ edit.al = al;
+ edit.fullAlignmentHeight = true;
+ }
+
+ addEdit(edit);
if (performEdit)
{
* @param commandIndex
* @param views
*/
- final void performEdit(int commandIndex, AlignmentI[] views)
+ public final void performEdit(int commandIndex, AlignmentI[] views)
{
ListIterator<Edit> iterator = edits.listIterator(commandIndex);
while (iterator.hasNext())
* @param edit
* @param views
*/
- protected void performEdit(Edit edit, AlignmentI[] views)
+ protected static void performEdit(Edit edit, AlignmentI[] views)
{
switch (edit.command)
{
*
* @param command
*/
- final private void insertGap(Edit command)
+ final private static void insertGap(Edit command)
{
for (int s = 0; s < command.seqs.length; s++)
{
- command.seqs[s].insertCharAt(command.position, command.number,
- command.gapChar);
+ command.seqs[s].insertCharAt(command.position,
+ command.number, command.gapChar);
// System.out.println("pos: "+command.position+" number: "+command.number);
}
*
* @param command
*/
- final private void deleteGap(Edit command)
+ final static private void deleteGap(Edit command)
{
for (int s = 0; s < command.seqs.length; s++)
{
* @param command
* @param views
*/
- void cut(Edit command, AlignmentI[] views)
+ static void cut(Edit command, AlignmentI[] views)
{
boolean seqDeleted = false;
command.string = new char[command.seqs.length][];
* @param command
* @param views
*/
- void paste(Edit command, AlignmentI[] views)
+ static void paste(Edit command, AlignmentI[] views)
{
StringBuffer tmp;
boolean newDSNeeded;
if (command.seqs[i].getLength() < 1)
{
// ie this sequence was deleted, we need to
- // read it to the alignment
+ // readd it to the alignment
if (command.alIndex[i] < command.al.getHeight())
{
List<SequenceI> sequences;
command.string = null;
}
- void replace(Edit command)
+ static void replace(Edit command)
{
StringBuffer tmp;
String oldstring;
}
}
- final void adjustAnnotations(Edit command, boolean insert,
+ final static void adjustAnnotations(Edit command, boolean insert,
boolean modifyVisibility, AlignmentI[] views)
{
AlignmentAnnotation[] annotations = null;
}
}
- final void adjustFeatures(Edit command, int index, int i, int j,
+ final static void adjustFeatures(Edit command, int index, int i, int j,
boolean insert)
{
SequenceI seq = command.seqs[index];
}
- class Edit
+ /**
+ * Returns the list of edit commands wrapped by this object.
+ *
+ * @return
+ */
+ public List<Edit> getEdits()
+ {
+ return this.edits;
+ }
+
+ /**
+ * Returns a map whose keys are the dataset sequences, and values their
+ * aligned sequences before the command edit list was applied. The aligned
+ * sequences are copies, which may be updated without affecting the originals.
+ *
+ * The command holds references to the aligned sequences (after editing). If
+ * the command is an 'undo',then the prior state is simply the aligned state.
+ * Otherwise, we have to derive the prior state by working backwards through
+ * the edit list to infer the aligned sequences before editing.
+ *
+ * Note: an alternative solution would be to cache the 'before' state of each
+ * edit, but this would be expensive in space in the common case that the
+ * original is never needed (edits are not mirrored).
+ *
+ * @return
+ * @throws IllegalStateException
+ * on detecting an edit command of a type that can't be unwound
+ */
+ public Map<SequenceI, SequenceI> priorState(boolean forUndo)
+ {
+ Map<SequenceI, SequenceI> result = new HashMap<SequenceI, SequenceI>();
+ if (getEdits() == null)
+ {
+ return result;
+ }
+ if (forUndo)
+ {
+ for (Edit e : getEdits())
+ {
+ for (SequenceI seq : e.getSequences())
+ {
+ SequenceI ds = seq.getDatasetSequence();
+ SequenceI preEdit = result.get(ds);
+ if (preEdit == null)
+ {
+ preEdit = new Sequence("", seq.getSequenceAsString());
+ preEdit.setDatasetSequence(ds);
+ result.put(ds, preEdit);
+ }
+ }
+ }
+ return result;
+ }
+
+ /*
+ * Work backwards through the edit list, deriving the sequences before each
+ * was applied. The final result is the sequence set before any edits.
+ */
+ Iterator<Edit> edits = new ReverseListIterator<Edit>(getEdits());
+ while (edits.hasNext())
+ {
+ Edit oldEdit = edits.next();
+ Action action = oldEdit.getAction();
+ int position = oldEdit.getPosition();
+ int number = oldEdit.getNumber();
+ final char gap = oldEdit.getGapCharacter();
+ for (SequenceI seq : oldEdit.getSequences())
+ {
+ SequenceI ds = seq.getDatasetSequence();
+ SequenceI preEdit = result.get(ds);
+ if (preEdit == null)
+ {
+ preEdit = new Sequence("", seq.getSequenceAsString());
+ preEdit.setDatasetSequence(ds);
+ result.put(ds, preEdit);
+ }
+ /*
+ * 'Undo' this edit action on the sequence (updating the value in the
+ * map).
+ */
+ if (ds != null)
+ {
+ if (action == Action.DELETE_GAP)
+ {
+ preEdit.setSequence(new String(StringUtils.insertCharAt(
+ preEdit.getSequence(), position,
+ number, gap)));
+ }
+ else if (action == Action.INSERT_GAP)
+ {
+ preEdit.setSequence(new String(StringUtils.deleteChars(
+ preEdit.getSequence(), position, position + number)));
+ }
+ else
+ {
+ System.err.println("Can't undo edit action " + action);
+ // throw new IllegalStateException("Can't undo edit action " +
+ // action);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ public class Edit
{
public SequenceI[] oldds;
char gapChar;
- Edit(Action command, SequenceI[] seqs, int position, int number,
+ public Edit(Action command, SequenceI[] seqs, int position, int number,
char gapChar)
{
this.command = command;
fullAlignmentHeight = (al.getHeight() == seqs.length);
}
+
+ public SequenceI[] getSequences()
+ {
+ return seqs;
+ }
+
+ public int getPosition()
+ {
+ return position;
+ }
+
+ public Action getAction()
+ {
+ return command;
+ }
+
+ public int getNumber()
+ {
+ return number;
+ }
+
+ public char getGapCharacter()
+ {
+ return gapChar;
+ }
+ }
+
+ /**
+ * Returns an iterator over the list of edit commands which traverses the list
+ * either forwards or backwards.
+ *
+ * @param forwards
+ * @return
+ */
+ public Iterator<Edit> getEditIterator(boolean forwards)
+ {
+ if (forwards)
+ {
+ return getEdits().iterator();
+ }
+ else
+ {
+ return new ReverseListIterator<Edit>(getEdits());
+ }
}
}
*/
package jalview.commands;
-import jalview.analysis.*;
-import jalview.datamodel.*;
+import jalview.analysis.AlignmentSorter;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+/**
+ * An undoable command to reorder the sequences in an alignment.
+ *
+ * @author gmcarstairs
+ *
+ */
public class OrderCommand implements CommandI
{
String description;
+ /*
+ * The sequence order before sorting (target order for an undo)
+ */
SequenceI[] seqs;
+ /*
+ * The sequence order specified by this command
+ */
SequenceI[] seqs2;
+ /*
+ * The alignment the command acts on
+ */
AlignmentI al;
+ /**
+ * Constructor given the 'undo' sequence order, and the (already) sorted
+ * alignment.
+ *
+ * @param description
+ * a text label for the 'undo' menu option
+ * @param seqs
+ * the sequence order for undo
+ * @param al
+ * the alignment as ordered by this command
+ */
public OrderCommand(String description, SequenceI[] seqs, AlignmentI al)
{
this.description = description;
{
AlignmentSorter.setOrder(al, seqs);
}
+
+ /**
+ * Returns the sequence order used to sort, or before sorting if undo=true.
+ *
+ * @param undo
+ * @return
+ */
+ public SequenceI[] getSequenceOrder(boolean undo)
+ {
+ return undo ? seqs : seqs2;
+ }
}
--- /dev/null
+package jalview.datamodel;
+
+/**
+ * Holds the aligned column positions (base 0) for one codon in a nucleotide
+ * sequence. The object is immutable once created.
+ *
+ * Example: in "G-AT-C-GA" the aligned codons are (0, 2, 3) and (5, 7, 8).
+ *
+ * @author gmcarstairs
+ *
+ */
+public final class AlignedCodon
+{
+ public final int pos1;
+
+ public final int pos2;
+
+ public final int pos3;
+
+ public AlignedCodon(int i, int j, int k)
+ {
+ pos1 = i;
+ pos2 = j;
+ pos3 = k;
+ }
+
+ /**
+ * Returns the column position for the given base (1, 2, 3).
+ *
+ * @param base
+ * @return
+ * @throws IllegalArgumentException
+ * if an argument value other than 1, 2 or 3 is supplied
+ */
+ public int getBaseColumn(int base)
+ {
+ if (base < 1 || base > 3)
+ {
+ throw new IllegalArgumentException(Integer.toString(base));
+ }
+ return base == 1 ? pos1 : (base == 2 ? pos2 : pos3);
+ }
+
+ /**
+ * Two aligned codons are equal if all their base positions are the same.
+ */
+ @Override
+ public boolean equals(Object o)
+ {
+ /*
+ * Equality with null value required for consistency with
+ * Dna.compareCodonPos
+ */
+ if (o == null)
+ {
+ return true;
+ }
+ if (!(o instanceof AlignedCodon))
+ {
+ return false;
+ }
+ AlignedCodon ac = (AlignedCodon) o;
+ return (pos1 == ac.pos1 && pos2 == ac.pos2 && pos3 == ac.pos3);
+ }
+
+ @Override
+ public String toString()
+ {
+ return "[" + pos1 + ", " + pos2 + ", " + pos3 + "]";
+ }
+}
*/
package jalview.datamodel;
-import java.util.Enumeration;
-import java.util.Vector;
-
import jalview.util.MapList;
/**
* 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.
*/
-
public class AlignedCodonFrame
{
- /**
- * array of nucleotide positions for aligned codons at column of aligned
- * proteins.
+
+ /*
+ * tied array of na Sequence objects.
*/
- public int[][] codons = null;
+ private SequenceI[] dnaSeqs = null;
- /**
- * width of protein sequence alignement implicit assertion that codons.length
- * >= aaWidth
+ /*
+ * tied array of Mappings to protein sequence Objects and SequenceI[]
+ * aaSeqs=null; MapLists where each maps from the corresponding dnaSeqs
+ * element to corresponding aaSeqs element
*/
- public int aaWidth = 0;
+ private Mapping[] dnaToProt = null;
/**
* initialise codon frame with a nominal alignment width
*
* @param aWidth
*/
- public AlignedCodonFrame(int aWidth)
- {
- if (aWidth <= 0)
- {
- codons = null;
- return;
- }
- codons = new int[aWidth][];
- for (int res = 0; res < aWidth; res++)
- codons[res] = null;
- }
-
- /**
- * ensure that codons array is at least as wide as aslen residues
- *
- * @param aslen
- * @return (possibly newly expanded) codon array
- */
- public int[][] checkCodonFrameWidth(int aslen)
- {
- if (codons.length <= aslen + 1)
- {
- // probably never have to do this ?
- int[][] c = new int[codons.length + 10][];
- for (int i = 0; i < codons.length; i++)
- {
- c[i] = codons[i];
- codons[i] = null;
- }
- codons = c;
- }
- return codons;
- }
-
- /**
- * @return width of aligned translated amino acid residues
- */
- public int getaaWidth()
- {
- return aaWidth;
- }
-
- /**
- * TODO: not an ideal solution - we reference the aligned amino acid sequences
- * in order to make insertions on them Better would be dnaAlignment and
- * aaAlignment reference....
- */
- Vector a_aaSeqs = new Vector();
-
- /**
- * increase aaWidth by one and insert a new aligned codon position space at
- * aspos.
- *
- * @param aspos
- */
- public void insertAAGap(int aspos, char gapCharacter)
+ public AlignedCodonFrame()
{
- // this aa appears before the aligned codons at aspos - so shift them in
- // each pair of mapped sequences
- aaWidth++;
- if (a_aaSeqs != null)
- {
- // we actually have to modify the aligned sequences here, so use the
- // a_aaSeqs vector
- Enumeration sq = a_aaSeqs.elements();
- while (sq.hasMoreElements())
- {
- ((SequenceI) sq.nextElement()).insertCharAt(aspos, gapCharacter);
- }
- }
- checkCodonFrameWidth(aspos);
- if (aspos < aaWidth)
- {
- aaWidth++;
- System.arraycopy(codons, aspos, codons, aspos + 1, codons.length
- - aspos - 1);
- codons[aspos] = null; // clear so new codon position can be marked.
- }
}
- public void setAaWidth(int aapos)
- {
- aaWidth = aapos;
- }
-
- /**
- * tied array of na Sequence objects.
- */
- SequenceI[] dnaSeqs = null;
-
- /**
- * tied array of Mappings to protein sequence Objects and SequenceI[]
- * aaSeqs=null; MapLists where eac maps from the corresponding dnaSeqs element
- * to corresponding aaSeqs element
- */
- Mapping[] dnaToProt = null;
-
/**
* add a mapping between the dataset sequences for the associated dna and
* protein sequence objects
// aaseq.transferAnnotation(dnaseq, new Mapping(map.getInverse()));
mp.to = (aaseq.getDatasetSequence() == null) ? aaseq : aaseq
.getDatasetSequence();
- a_aaSeqs.addElement(aaseq);
dnaToProt[nlen] = mp;
}
public SequenceI[] getAaSeqs()
{
if (dnaToProt == null)
+ {
return null;
+ }
SequenceI[] sqs = new SequenceI[dnaToProt.length];
for (int sz = 0; sz < dnaToProt.length; sz++)
{
public MapList[] getdnaToProt()
{
if (dnaToProt == null)
+ {
return null;
+ }
MapList[] sqs = new MapList[dnaToProt.length];
for (int sz = 0; sz < dnaToProt.length; sz++)
{
}
/**
+ * Return the corresponding aligned or dataset aa sequence for given dna
+ * sequence, null if not found.
*
* @param sequenceRef
- * @return null or corresponding aaSeq entry for dnaSeq entry
+ * @return
*/
public SequenceI getAaForDnaSeq(SequenceI dnaSeqRef)
{
for (int ds = 0; ds < dnaSeqs.length; ds++)
{
if (dnaSeqs[ds] == dnaSeqRef || dnaSeqs[ds] == dnads)
+ {
return dnaToProt[ds].to;
+ }
}
return null;
}
for (int as = 0; as < dnaToProt.length; as++)
{
if (dnaToProt[as].to == aaSeqRef || dnaToProt[as].to == aads)
+ {
return dnaSeqs[as];
+ }
}
return null;
}
}
}
}
+
+ /**
+ * Returns the DNA codon positions (base 1) for the given position (base 1) in
+ * a mapped protein sequence, or null if no mapping is found.
+ *
+ * Intended for use in aligning cDNA to match aligned protein. Only the first
+ * mapping found is returned, so not suitable for use if multiple protein
+ * sequences are mapped to the same cDNA (but aligning cDNA as protein is
+ * ill-defined for this case anyway).
+ *
+ * @param seq
+ * the DNA dataset sequence
+ * @param aaPos
+ * residue position (base 1) in a protein sequence
+ * @return
+ */
+ public int[] getDnaPosition(SequenceI seq, int aaPos)
+ {
+ /*
+ * Adapted from markMappedRegion().
+ */
+ MapList ml = null;
+ for (int i = 0; i < dnaToProt.length; i++)
+ {
+ if (dnaSeqs[i] == seq)
+ {
+ ml = getdnaToProt()[i];
+ break;
+ }
+ }
+ return ml == null ? null : ml.locateInFrom(aaPos, aaPos);
+ }
+
+ /**
+ * Convenience method to return the first aligned sequence in the given
+ * alignment whose dataset has a mapping with the given dataset sequence.
+ *
+ * @param seq
+ *
+ * @param al
+ * @return
+ */
+ public SequenceI findAlignedSequence(SequenceI seq, AlignmentI al)
+ {
+ /*
+ * Search mapped protein ('to') sequences first.
+ */
+ if (this.dnaToProt != null)
+ {
+ for (int i = 0; i < dnaToProt.length; i++)
+ {
+ if (this.dnaSeqs[i] == seq)
+ {
+ for (SequenceI sourceAligned : al.getSequences())
+ {
+ if (this.dnaToProt[i].to == sourceAligned.getDatasetSequence())
+ {
+ return sourceAligned;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Then try mapped dna sequences.
+ */
+ if (this.dnaToProt != null)
+ {
+ for (int i = 0; i < dnaToProt.length; i++)
+ {
+ if (this.dnaToProt[i].to == seq)
+ {
+ for (SequenceI sourceAligned : al.getSequences())
+ {
+ if (this.dnaSeqs[i] == sourceAligned.getDatasetSequence())
+ {
+ return sourceAligned;
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the region in the 'mappedFrom' sequence's dataset that is mapped to
+ * position 'pos' (base 1) in the 'mappedTo' sequence's dataset. The region is
+ * a set of start/end position pairs.
+ *
+ * @param mappedFrom
+ * @param mappedTo
+ * @param pos
+ * @return
+ */
+ public int[] getMappedRegion(SequenceI mappedFrom, SequenceI mappedTo,
+ int pos)
+ {
+ SequenceI targetDs = mappedFrom.getDatasetSequence() == null ? mappedFrom
+ : mappedFrom.getDatasetSequence();
+ SequenceI sourceDs = mappedTo.getDatasetSequence() == null ? mappedTo
+ : mappedTo.getDatasetSequence();
+ if (targetDs == null || sourceDs == null || dnaToProt == null)
+ {
+ return null;
+ }
+ for (int mi = 0; mi < dnaToProt.length; mi++)
+ {
+ if (dnaSeqs[mi] == targetDs && dnaToProt[mi].to == sourceDs)
+ {
+ int[] codon = dnaToProt[mi].map.locateInFrom(pos, pos);
+ if (codon != null) {
+ return codon;
+ }
+ }
+ }
+ return null;
+ }
}
*/
package jalview.datamodel;
+import jalview.analysis.AlignmentUtils;
+import jalview.io.FastaFile;
import jalview.util.MessageManager;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Hashtable;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.Vector;
/**
public Hashtable alignmentProperties;
+ private Set<AlignedCodonFrame> codonFrameList = new LinkedHashSet<AlignedCodonFrame>();
+
private void initAlignment(SequenceI[] seqs)
{
int i = 0;
}
/**
+ * Make a 'copy' alignment - sequences have new copies of features and
+ * annotations, but share the original dataset sequences.
+ */
+ public Alignment(AlignmentI al)
+ {
+ SequenceI[] seqs = al.getSequencesArray();
+ for (int i = 0; i < seqs.length; i++)
+ {
+ seqs[i] = new Sequence(seqs[i]);
+ }
+
+ /*
+ * Share the same dataset sequence mappings (if any). TODO: find a better
+ * place for these to live (alignment dataset?).
+ */
+ this.codonFrameList = ((Alignment) al).codonFrameList;
+
+ initAlignment(seqs);
+ }
+
+ /**
* Make an alignment from an array of Sequences.
*
* @param sequences
// this(compactAlignment.refCigars);
}
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
@Override
public List<SequenceI> getSequences()
{
}
/**
+ * Returns a map of lists of sequences keyed by sequence name.
+ *
+ * @return
+ */
+ @Override
+ public Map<String, List<SequenceI>> getSequencesByName()
+ {
+ return AlignmentUtils.getSequencesByName(this);
+ }
+
+ /**
* DOCUMENT ME!
*
* @param i
@Override
public void setSequenceAt(int i, SequenceI snew)
{
- SequenceI oldseq = getSequenceAt(i);
- deleteSequence(i);
synchronized (sequences)
{
+ deleteSequence(i);
sequences.set(i, snew);
}
}
synchronized (sequences)
{
sequences.remove(i);
+ hiddenSequences.adjustHeightSequenceDeleted(i);
}
- hiddenSequences.adjustHeightSequenceDeleted(i);
}
}
return true;
}
+ /**
+ * Delete all annotations, including auto-calculated if the flag is set true.
+ * Returns true if at least one annotation was deleted, else false.
+ *
+ * @param includingAutoCalculated
+ * @return
+ */
+ @Override
+ public boolean deleteAllAnnotations(boolean includingAutoCalculated)
+ {
+ boolean result = false;
+ for (AlignmentAnnotation alan : getAlignmentAnnotation())
+ {
+ if (!alan.autoCalculated || includingAutoCalculated)
+ {
+ deleteAnnotation(alan);
+ result = true;
+ }
+ }
+ return result;
+ }
+
/*
* (non-Javadoc)
*
return alignmentProperties;
}
- AlignedCodonFrame[] codonFrameList = null;
-
/*
* (non-Javadoc)
*
@Override
public void addCodonFrame(AlignedCodonFrame codons)
{
- if (codons == null)
+ if (codons != null)
{
- return;
+ codonFrameList.add(codons);
}
- if (codonFrameList == null)
- {
- codonFrameList = new AlignedCodonFrame[]
- { codons };
- return;
- }
- AlignedCodonFrame[] t = new AlignedCodonFrame[codonFrameList.length + 1];
- System.arraycopy(codonFrameList, 0, t, 0, codonFrameList.length);
- t[codonFrameList.length] = codons;
- codonFrameList = t;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see jalview.datamodel.AlignmentI#getCodonFrame(int)
- */
- @Override
- public AlignedCodonFrame getCodonFrame(int index)
- {
- return codonFrameList[index];
}
/*
* jalview.datamodel.AlignmentI#getCodonFrame(jalview.datamodel.SequenceI)
*/
@Override
- public AlignedCodonFrame[] getCodonFrame(SequenceI seq)
+ public List<AlignedCodonFrame> getCodonFrame(SequenceI seq)
{
- if (seq == null || codonFrameList == null)
+ if (seq == null)
{
return null;
}
- Vector cframes = new Vector();
- for (int f = 0; f < codonFrameList.length; f++)
+ List<AlignedCodonFrame> cframes = new ArrayList<AlignedCodonFrame>();
+ for (AlignedCodonFrame acf : codonFrameList)
{
- if (codonFrameList[f].involvesSequence(seq))
+ if (acf.involvesSequence(seq))
{
- cframes.addElement(codonFrameList[f]);
+ cframes.add(acf);
}
}
- if (cframes.size() == 0)
- {
- return null;
- }
- AlignedCodonFrame[] cfr = new AlignedCodonFrame[cframes.size()];
- cframes.copyInto(cfr);
- return cfr;
+ return cframes;
}
- /*
- * (non-Javadoc)
+ /**
+ * Sets the codon frame mappings (replacing any existing mappings).
+ *
+ * @see jalview.datamodel.AlignmentI#setCodonFrames()
+ */
+ @Override
+ public void setCodonFrames(Set<AlignedCodonFrame> acfs)
+ {
+ this.codonFrameList = acfs;
+ }
+
+ /**
+ * Returns the set of codon frame mappings. Any changes to the returned set
+ * will affect the alignment.
*
* @see jalview.datamodel.AlignmentI#getCodonFrames()
*/
@Override
- public AlignedCodonFrame[] getCodonFrames()
+ public Set<AlignedCodonFrame> getCodonFrames()
{
return codonFrameList;
}
{
return false;
}
- boolean removed = false;
- int i = 0, iSize = codonFrameList.length;
- while (i < iSize)
- {
- if (codonFrameList[i] == codons)
- {
- removed = true;
- if (i + 1 < iSize)
- {
- System.arraycopy(codonFrameList, i + 1, codonFrameList, i, iSize
- - i - 1);
- }
- iSize--;
- }
- else
- {
- i++;
- }
- }
- return removed;
+ return codonFrameList.remove(codons);
}
@Override
{
addAnnotation(alan[a]);
}
- AlignedCodonFrame[] acod = toappend.getCodonFrames();
- for (int a = 0; acod != null && a < acod.length; a++)
- {
- this.addCodonFrame(acod[a]);
- }
+
+ this.codonFrameList.addAll(toappend.getCodonFrames());
+
List<SequenceGroup> sg = toappend.getGroups();
if (sg != null)
{
{
return dataset;
}
+
+ /**
+ * Align this alignment like the given (mapped) one.
+ */
+ @Override
+ public int alignAs(AlignmentI al)
+ {
+ /*
+ * Currently retains unmapped gaps (in introns), regaps mapped regions
+ * (exons)
+ */
+ return alignAs(al, false, true);
+ }
+
+ /**
+ * Align this alignment 'the same as' the given one. Mapped sequences only are
+ * realigned. If both of the same type (nucleotide/protein) then align both
+ * identically. If this is nucleotide and the other is protein, make 3 gaps
+ * for each gap in the protein sequences. If this is protein and the other is
+ * nucleotide, insert a gap for each 3 gaps (or part thereof) between
+ * nucleotide bases. Does nothing if alignment of protein from cDNA is
+ * requested (not yet implemented).
+ *
+ * Parameters control whether gaps in exon (mapped) and intron (unmapped)
+ * regions are preserved. Gaps that connect introns to exons are treated
+ * conservatively, i.e. only preserved if both intron and exon gaps are
+ * preserved.
+ *
+ * @param al
+ * @param preserveMappedGaps
+ * if true, gaps within and between mapped codons are preserved
+ * @param preserveUnmappedGaps
+ * if true, gaps within and between unmapped codons are preserved
+ */
+// @Override
+ public int alignAs(AlignmentI al, boolean preserveMappedGaps,
+ boolean preserveUnmappedGaps)
+ {
+ // TODO should this method signature be the one in the interface?
+ int count = 0;
+ boolean thisIsNucleotide = this.isNucleotide();
+ boolean thatIsProtein = !al.isNucleotide();
+ if (!thatIsProtein && !thisIsNucleotide)
+ {
+ System.err
+ .println("Alignment of protein from cDNA not yet implemented");
+ return 0;
+ // todo: build it - a variant of Dna.CdnaTranslate()
+ }
+
+ char thisGapChar = this.getGapCharacter();
+ String gap = thisIsNucleotide && thatIsProtein ? String
+ .valueOf(new char[]
+ { thisGapChar, thisGapChar, thisGapChar }) : String
+ .valueOf(thisGapChar);
+
+ /*
+ * Get mappings from 'that' alignment's sequences to this.
+ */
+ for (SequenceI alignTo : getSequences())
+ {
+ count += AlignmentUtils.alignSequenceAs(alignTo, al, gap, preserveMappedGaps,
+ preserveUnmappedGaps) ? 1 : 0;
+ }
+ return count;
+ }
+
+ /**
+ * Returns the alignment in Fasta format. Behaviour of this method is not
+ * guaranteed between versions.
+ */
+ @Override
+ public String toString()
+ {
+ return new FastaFile().print(getSequencesArray());
+ }
+
+ /**
+ * Returns the set of distinct sequence names. No ordering is guaranteed.
+ */
+ @Override
+ public Set<String> getSequenceNames()
+ {
+ Set<String> names = new HashSet<String>();
+ for (SequenceI seq : getSequences())
+ {
+ names.add(seq.getName());
+ }
+ return names;
+ }
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.Enumeration;
import java.util.HashMap;
-import java.util.Hashtable;
+import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
/**
* map of positions in the associated annotation
*/
- public java.util.Hashtable<Integer, Annotation> sequenceMapping;
+ private Map<Integer, Annotation> sequenceMapping;
/** DOCUMENT ME!! */
public float graphMin;
: annotations[index + offset].secondaryStructure);
}
+ @Override
public String toString()
{
char[] string = new char[max - offset];
if (annotation.sequenceMapping != null)
{
Integer p = null;
- sequenceMapping = new Hashtable();
- Enumeration pos = annotation.sequenceMapping.keys();
- while (pos.hasMoreElements())
+ sequenceMapping = new HashMap<Integer, Annotation>();
+ Iterator<Integer> pos = annotation.sequenceMapping.keySet()
+ .iterator();
+ while (pos.hasNext())
{
// could optimise this!
- p = (Integer) pos.nextElement();
+ p = pos.next();
Annotation a = annotation.sequenceMapping.get(p);
if (a == null)
{
int epos = sequenceRef.findPosition(endRes);
if (sequenceMapping != null)
{
- Hashtable newmapping = new Hashtable();
- Enumeration e = sequenceMapping.keys();
- while (e.hasMoreElements())
+ Map<Integer, Annotation> newmapping = new HashMap<Integer, Annotation>();
+ Iterator<Integer> e = sequenceMapping.keySet().iterator();
+ while (e.hasNext())
{
- Integer pos = (Integer) e.nextElement();
+ Integer pos = e.next();
if (pos.intValue() >= spos && pos.intValue() <= epos)
{
newmapping.put(pos, sequenceMapping.get(pos));
*
* @return DOCUMENT ME!
*/
+ @Override
public String toString()
{
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder(256);
for (int i = 0; i < annotations.length; i++)
{
{
return;
}
- sequenceMapping = new java.util.Hashtable();
+ sequenceMapping = new HashMap<Integer, Annotation>();
int seqPos;
.getTo() == sq.getDatasetSequence()) : false;
// TODO build a better annotation element map and get rid of annotations[]
- Hashtable<Integer, Annotation> mapForsq = new Hashtable();
+ Map<Integer, Annotation> mapForsq = new HashMap<Integer, Annotation>();
if (sequenceMapping != null)
{
if (sp2sq != null)
{
if (mapping != null)
{
- Hashtable<Integer, Annotation> old = sequenceMapping, remap = new Hashtable<Integer, Annotation>();
+ Map<Integer, Annotation> old = sequenceMapping;
+ Map<Integer, Annotation> remap = new HashMap<Integer, Annotation>();
int index = -1;
for (int mp[] : mapping)
{
* This file is part of Jalview.
*
* Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * modify it under the terms of the GNU General License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Jalview is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
+ * PURPOSE. See the GNU General License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU General License
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Data structure to hold and manipulate a multiple sequence alignment
*
* @return Number of sequences in alignment
*/
- public int getHeight();
+ int getHeight();
/**
+ *
* Calculates the maximum width of the alignment, including gaps.
*
* @return Greatest sequence length within alignment.
*/
@Override
- public int getWidth();
+ int getWidth();
/**
* Calculates if this set of sequences (visible and invisible) are all the
*
* @return true if all sequences in alignment are the same length
*/
- public boolean isAligned();
+ boolean isAligned();
/**
* Calculates if this set of sequences is all the same length
* optionally exclude hidden sequences from test
* @return true if all (or just visible) sequences are the same length
*/
- public boolean isAligned(boolean includeHidden);
+ boolean isAligned(boolean includeHidden);
/**
* Gets sequences as a Synchronized collection
* @return All sequences in alignment.
*/
@Override
- public List<SequenceI> getSequences();
+ List<SequenceI> getSequences();
/**
* Gets sequences as a SequenceI[]
*
* @return All sequences in alignment.
*/
- public SequenceI[] getSequencesArray();
+ SequenceI[] getSequencesArray();
/**
* Find a specific sequence in this alignment.
*
* @return SequenceI at given index.
*/
- public SequenceI getSequenceAt(int i);
+ SequenceI getSequenceAt(int i);
+
+ /**
+ * Returns a map of lists of sequences keyed by sequence name.
+ *
+ * @return
+ */
+ Map<String, List<SequenceI>> getSequencesByName();
/**
* Add a new sequence to this alignment.
* @param seq
* New sequence will be added at end of alignment.
*/
- public void addSequence(SequenceI seq);
+ void addSequence(SequenceI seq);
/**
* Used to set a particular index of the alignment with the given sequence.
* @param seq
* New sequence to be inserted.
*/
- public void setSequenceAt(int i, SequenceI seq);
+ void setSequenceAt(int i, SequenceI seq);
/**
* Deletes a sequence from the alignment
* @param s
* Sequence to be deleted.
*/
- public void deleteSequence(SequenceI s);
+ void deleteSequence(SequenceI s);
/**
* Deletes a sequence from the alignment.
* @param i
* Index of sequence to be deleted.
*/
- public void deleteSequence(int i);
+ void deleteSequence(int i);
/**
* Finds sequence in alignment using sequence name as query.
*
* @return Sequence matching query, if found. If not found returns null.
*/
- public SequenceI findName(String name);
+ SequenceI findName(String name);
- public SequenceI[] findSequenceMatch(String name);
+ SequenceI[] findSequenceMatch(String name);
/**
* Finds index of a given sequence in the alignment.
*
* @return Index of sequence within the alignment or -1 if not found
*/
- public int findIndex(SequenceI s);
+ int findIndex(SequenceI s);
/**
* Finds group that given sequence is part of.
* @return First group found for sequence. WARNING : Sequences may be members
* of several groups. This method is incomplete.
*/
- public SequenceGroup findGroup(SequenceI s);
+ SequenceGroup findGroup(SequenceI s);
/**
* Finds all groups that a given sequence is part of.
*
* @return All groups containing given sequence.
*/
- public SequenceGroup[] findAllGroups(SequenceI s);
+ SequenceGroup[] findAllGroups(SequenceI s);
/**
* Adds a new SequenceGroup to this alignment.
* @param sg
* New group to be added.
*/
- public void addGroup(SequenceGroup sg);
+ void addGroup(SequenceGroup sg);
/**
* Deletes a specific SequenceGroup
* @param g
* Group will be deleted from alignment.
*/
- public void deleteGroup(SequenceGroup g);
+ void deleteGroup(SequenceGroup g);
/**
* Get all the groups associated with this alignment.
*
* @return All groups as a list.
*/
- public List<SequenceGroup> getGroups();
+ List<SequenceGroup> getGroups();
/**
* Deletes all groups from this alignment.
*/
- public void deleteAllGroups();
+ void deleteAllGroups();
/**
* Adds a new AlignmentAnnotation to this alignment
* @note Care should be taken to ensure that annotation is at least as wide as
* the longest sequence in the alignment for rendering purposes.
*/
- public void addAnnotation(AlignmentAnnotation aa);
+ void addAnnotation(AlignmentAnnotation aa);
/**
* moves annotation to a specified index in alignment annotation display stack
* @param index
* the destination position
*/
- public void setAnnotationIndex(AlignmentAnnotation aa, int index);
+ void setAnnotationIndex(AlignmentAnnotation aa, int index);
+
+ /**
+ * Delete all annotations, including auto-calculated if the flag is set true.
+ * Returns true if at least one annotation was deleted, else false.
+ *
+ * @param includingAutoCalculated
+ * @return
+ */
+ boolean deleteAllAnnotations(boolean includingAutoCalculated);
/**
* Deletes a specific AlignmentAnnotation from the alignment, and removes its
* the annotation to delete
* @return true if annotation was deleted from this alignment.
*/
- public boolean deleteAnnotation(AlignmentAnnotation aa);
+ boolean deleteAnnotation(AlignmentAnnotation aa);
/**
* Deletes a specific AlignmentAnnotation from the alignment, and optionally
* into the alignment
* @return true if annotation was deleted from this alignment.
*/
- public boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook);
+ boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook);
/**
* Get the annotation associated with this alignment (this can be null if no
* @return array of AlignmentAnnotation objects
*/
@Override
- public AlignmentAnnotation[] getAlignmentAnnotation();
+ AlignmentAnnotation[] getAlignmentAnnotation();
/**
* Change the gap character used in this alignment to 'gc'
* @param gc
* the new gap character.
*/
- public void setGapCharacter(char gc);
+ void setGapCharacter(char gc);
/**
* Get the gap character used in this alignment
*
* @return gap character
*/
- public char getGapCharacter();
+ char getGapCharacter();
/**
* Test for all nucleotide alignment
*
* @return true if alignment is nucleotide sequence
*/
- public boolean isNucleotide();
+ boolean isNucleotide();
/**
* Test if alignment contains RNA structure
*
* @return true if RNA structure AligmnentAnnotation was added to alignment
*/
- public boolean hasRNAStructure();
+ boolean hasRNAStructure();
/**
* Set alignment to be a nucleotide sequence
*
*/
- public void setNucleotide(boolean b);
+ void setNucleotide(boolean b);
/**
* Get the associated dataset for the alignment.
* @return Alignment containing dataset sequences or null of this is a
* dataset.
*/
- public Alignment getDataset();
+ Alignment getDataset();
/**
* Set the associated dataset for the alignment, or create one.
* @param dataset
* The dataset alignment or null to construct one.
*/
- public void setDataset(Alignment dataset);
+ void setDataset(Alignment dataset);
/**
* pads sequences with gaps (to ensure the set looks like an alignment)
*
* @return boolean true if alignment was modified
*/
- public boolean padGaps();
+ boolean padGaps();
- public HiddenSequences getHiddenSequences();
+ HiddenSequences getHiddenSequences();
/**
* Compact representation of alignment
*
* @return CigarArray
*/
- public CigarArray getCompactAlignment();
+ CigarArray getCompactAlignment();
/**
* Set an arbitrary key value pair for an alignment. Note: both key and value
* @param key
* @param value
*/
- public void setProperty(Object key, Object value);
+ void setProperty(Object key, Object value);
/**
* Get a named property from the alignment.
* @param key
* @return value of property
*/
- public Object getProperty(Object key);
+ Object getProperty(Object key);
/**
* Get the property hashtable.
*
* @return hashtable of alignment properties (or null if none are defined)
*/
- public Hashtable getProperties();
+ Hashtable getProperties();
/**
* add a reference to a frame of aligned codons for this alignment
*
* @param codons
*/
- public void addCodonFrame(AlignedCodonFrame codons);
+ void addCodonFrame(AlignedCodonFrame codons);
/**
* remove a particular codon frame reference from this alignment
* @param codons
* @return true if codon frame was removed.
*/
- public boolean removeCodonFrame(AlignedCodonFrame codons);
+ boolean removeCodonFrame(AlignedCodonFrame codons);
/**
* get all codon frames associated with this alignment
*
* @return
*/
- public AlignedCodonFrame[] getCodonFrames();
+ Set<AlignedCodonFrame> getCodonFrames();
/**
- * get a particular codon frame
- *
- * @param index
- * @return
+ * Set the codon frame mappings (replacing any existing set).
*/
- public AlignedCodonFrame getCodonFrame(int index);
+ void setCodonFrames(Set<AlignedCodonFrame> acfs);
/**
* get codon frames involving sequenceI
*/
- public AlignedCodonFrame[] getCodonFrame(SequenceI seq);
+ List<AlignedCodonFrame> getCodonFrame(SequenceI seq);
/**
* find sequence with given name in alignment
* tried
* @return matched sequence or null
*/
- public SequenceI findName(String token, boolean b);
+ SequenceI findName(String token, boolean b);
/**
* find next sequence with given name in alignment starting after a given
* tried
* @return matched sequence or null
*/
- public SequenceI findName(SequenceI startAfter, String token, boolean b);
+ SequenceI findName(SequenceI startAfter, String token, boolean b);
/**
* find first sequence in alignment which is involved in the given search
* @param results
* @return -1 or index of sequence in alignment
*/
- public int findIndex(SearchResults results);
+ int findIndex(SearchResults results);
/**
* append sequences and annotation from another alignment object to this one.
* @param toappend
* - the alignment to be appended.
*/
- public void append(AlignmentI toappend);
+ void append(AlignmentI toappend);
/**
* Justify the sequences to the left or right by deleting and inserting gaps
* true if alignment padded to right, false to justify to left
* @return true if alignment was changed TODO: return undo object
*/
- public boolean justify(boolean right);
+ boolean justify(boolean right);
/**
* add given annotation row at given position (0 is start, -1 is end)
* @param consensus
* @param i
*/
- public void addAnnotation(AlignmentAnnotation consensus, int i);
+ void addAnnotation(AlignmentAnnotation consensus, int i);
/**
* search for or create a specific annotation row on the alignment
*
* @return existing annotation matching the given attributes
*/
- public AlignmentAnnotation findOrCreateAnnotation(String name,
+ AlignmentAnnotation findOrCreateAnnotation(String name,
String calcId, boolean autoCalc, SequenceI seqRef,
SequenceGroup groupRef);
* @param up
* @param i
*/
- public void moveSelectedSequencesByOne(SequenceGroup sg,
+ void moveSelectedSequencesByOne(SequenceGroup sg,
Map<SequenceI, SequenceCollectionI> map, boolean up);
/**
*
* @param alignmentAnnotation
*/
- public void validateAnnotation(AlignmentAnnotation alignmentAnnotation);
+ void validateAnnotation(AlignmentAnnotation alignmentAnnotation);
+
+ /**
+ * Align this alignment the same as the given one. If both of the same type
+ * (nucleotide/protein) then align both identically. If this is nucleotide and
+ * the other is protein, make 3 gaps for each gap in the protein sequences. If
+ * this is protein and the other is nucleotide, insert a gap for each 3 gaps
+ * (or part thereof) between nucleotide bases. Returns the number of mapped
+ * sequences that were realigned .
+ *
+ * @param al
+ * @return
+ */
+ int alignAs(AlignmentI al);
+
+ /**
+ * Returns the set of distinct sequence names in the alignment.
+ *
+ * @return
+ */
+ Set<String> getSequenceNames();
}
*/
package jalview.datamodel;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
public class AlignmentOrder
{
private String Name;
- private Vector Order = null;
+ private List<SequenceI> Order = null;
/**
* Creates a new AlignmentOrder object.
* AlignmentOrder
*
* @param anOrder
- * Vector
*/
- public AlignmentOrder(Vector anOrder)
+ public AlignmentOrder(List<SequenceI> anOrder)
{
Order = anOrder;
}
*/
public AlignmentOrder(AlignmentI orderFrom)
{
- Order = new Vector();
+ Order = new ArrayList<SequenceI>();
- for (int i = 0, ns = orderFrom.getHeight(); i < ns; i++)
+ for (SequenceI seq : orderFrom.getSequences())
{
- Order.addElement(orderFrom.getSequenceAt(i));
+ Order.add(seq);
}
}
*/
public AlignmentOrder(SequenceI[] orderFrom)
{
- Order = new Vector();
-
- for (int i = 0, ns = orderFrom.length; i < ns; i++)
- {
- Order.addElement(orderFrom[i]);
- }
+ Order = new ArrayList<SequenceI>(Arrays.asList(orderFrom));
}
/**
* @param Order
* DOCUMENT ME!
*/
- public void setOrder(Vector Order)
+ public void setOrder(List<SequenceI> Order)
{
this.Order = Order;
}
*
* @return DOCUMENT ME!
*/
- public Vector getOrder()
+ public List<SequenceI> getOrder()
{
return Order;
}
int found = Order.indexOf(oldref);
if (found > -1)
{
- Order.setElementAt(newref, found);
+ Order.set(found, newref);
}
return found > -1;
}
* @param o
* @return true if o orders the same sequenceI objects in the same way
*/
- public boolean equals(AlignmentOrder o)
+ @Override
+ public boolean equals(Object o)
{
- return equals(o, true);
+ if (o == null || !(o instanceof AlignmentOrder))
+ {
+ return false;
+ }
+ return equals((AlignmentOrder) o, true);
}
/**
{
for (int i = 0, j = o.Order.size(); i < j; i++)
{
- if (Order.elementAt(i) != o.Order.elementAt(i))
+ if (Order.get(i) != o.Order.get(i))
{
return false;
}
}
if (Order != null && o.Order != null)
{
- Vector c, s;
+ List<SequenceI> c, s;
if (o.Order.size() > Order.size())
{
c = o.Order;
int last = -1;
for (int i = 0, j = s.size(); i < j; i++)
{
- int pos = c.indexOf(s.elementAt(i)); // JBPNote - optimize by
+ int pos = c.indexOf(s.get(i)); // JBPNote - optimize by
// incremental position search
if (pos > last)
{
import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
{
if (shiftrecord != null)
{
- Vector shifts = shiftrecord.shifts;
+ List<int[]> shifts = shiftrecord.getShifts();
if (shifts != null && shifts.size() > 0)
{
int shifted = 0;
for (int i = 0, j = shifts.size(); i < j; i++)
{
- int[] sh = (int[]) shifts.elementAt(i);
+ int[] sh = shifts.get(i);
// compensateForEdit(shifted+sh[0], sh[1]);
compensateForDelEdits(shifted + sh[0], sh[1]);
shifted -= sh[1];
* removes intersection of position,length ranges in deletions from the
* start,end regions marked in intervals.
*
- * @param deletions
+ * @param shifts
* @param intervals
* @return
*/
- private boolean pruneIntervalVector(Vector deletions, Vector intervals)
+ private boolean pruneIntervalVector(List<int[]> shifts, Vector intervals)
{
boolean pruned = false;
- int i = 0, j = intervals.size() - 1, s = 0, t = deletions.size() - 1;
+ int i = 0, j = intervals.size() - 1, s = 0, t = shifts.size() - 1;
int hr[] = (int[]) intervals.elementAt(i);
- int sr[] = (int[]) deletions.elementAt(s);
+ int sr[] = shifts.get(s);
while (i <= j && s <= t)
{
boolean trailinghn = hr[1] >= sr[0];
{ // leadinghc disjoint or not a deletion
if (s < t)
{
- sr = (int[]) deletions.elementAt(++s);
+ sr = shifts.get(++s);
}
else
{
// sr contained in hr
if (s < t)
{
- sr = (int[]) deletions.elementAt(++s);
+ sr = shifts.get(++s);
}
else
{
// operations.
}
- private boolean pruneColumnList(Vector deletion, Vector list)
+ private boolean pruneColumnList(List<int[]> shifts, Vector list)
{
- int s = 0, t = deletion.size();
- int[] sr = (int[]) list.elementAt(s++);
+ int s = 0, t = shifts.size();
+ int[] sr = shifts.get(s++);
boolean pruned = false;
int i = 0, j = list.size();
while (i < j && s <= t)
{
if (s < t)
{
- sr = (int[]) deletion.elementAt(s);
+ sr = shifts.get(s);
}
s++;
}
{
if (deletions != null)
{
- Vector shifts = deletions.shifts;
+ List<int[]> shifts = deletions.getShifts();
if (shifts != null && shifts.size() > 0)
{
// delete any intervals intersecting.
*/
public List<int[]> getHiddenColumns()
{
- return hiddenColumns == null ? Arrays.asList(new int[]
- {}) : hiddenColumns;
+ return hiddenColumns == null ? Collections.<int[]> emptyList()
+ : hiddenColumns;
}
/**
*/
package jalview.datamodel;
-import java.util.Vector;
-
import jalview.util.MapList;
+import java.util.Vector;
+
public class Mapping
{
/**
* 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
+ * sequence in the database coordinate system. It also takes care of step
+ * difference between coordinate systems.
*/
MapList map = null;
/**
- * The seuqence that map maps the associated seuqence to (if any).
+ * The sequence that map maps the associated sequence to (if any).
*/
SequenceI to = null;
* @param other
* @return
*/
- public boolean equals(Mapping other)
+ @Override
+ public boolean equals(Object o)
{
- if (other == null)
+ if (o == null || !(o instanceof Mapping))
+ {
return false;
+ }
+ Mapping other = (Mapping) o;
if (other == this)
+ {
return true;
+ }
if (other.to != to)
+ {
return false;
+ }
if ((map != null && other.map == null)
|| (map == null && other.map != null))
+ {
return false;
+ }
if (map.equals(other.map))
+ {
return true;
+ }
return false;
}
vf[v].setBegin(frange[i]);
vf[v].setEnd(frange[i + 1]);
if (frange.length > 2)
+ {
vf[v].setDescription(f.getDescription() + "\nPart " + (v + 1));
+ }
}
return vf;
}
from = (map.getToLowest() < from) ? from : map.getToLowest();
to = (map.getToHighest() > to) ? to : map.getToHighest();
if (from > to)
+ {
return null;
+ }
}
else
{
from = (map.getToHighest() > from) ? from : map.getToHighest();
to = (map.getToLowest() < to) ? to : map.getToLowest();
if (from < to)
+ {
return null;
+ }
}
return map.locateInFrom(from, to);
}
from = (map.getFromLowest() < from) ? from : map.getFromLowest();
to = (map.getFromHighest() > to) ? to : map.getFromHighest();
if (from > to)
+ {
return null;
+ }
}
else
{
from = (map.getFromHighest() > from) ? from : map.getFromHighest();
to = (map.getFromLowest() < to) ? to : map.getFromLowest();
if (from < to)
+ {
return null;
+ }
}
return map.locateInTo(from, to);
}
*/
package jalview.datamodel;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Holds a list of search result matches, where each match is a contiguous
+ * stretch of a single sequence.
+ *
+ * @author gmcarstairs
+ *
+ */
public class SearchResults
{
- Match[] matches;
+ private List<Match> matches = new ArrayList<Match>();
+
+ public class Match
+ {
+ SequenceI sequence;
+
+ int start;
+
+ int end;
+
+ public Match(SequenceI seq, int start, int end)
+ {
+ sequence = seq;
+ this.start = start;
+ this.end = end;
+ }
+
+ public SequenceI getSequence()
+ {
+ return sequence;
+ }
+
+ public int getStart()
+ {
+ return start;
+ }
+
+ public int getEnd()
+ {
+ return end;
+ }
+ }
/**
* This method replaces the old search results which merely held an alignment
*/
public void addResult(SequenceI seq, int start, int end)
{
- if (matches == null)
- {
- matches = new Match[]
- { new Match(seq, start, end) };
- return;
- }
-
- int mSize = matches.length;
-
- Match[] tmp = new Match[mSize + 1];
- int m;
- for (m = 0; m < mSize; m++)
- {
- tmp[m] = matches[m];
- }
-
- tmp[m] = new Match(seq, start, end);
-
- matches = tmp;
+ matches.add(new Match(seq, start, end));
}
/**
*/
public boolean involvesSequence(SequenceI sequence)
{
- if (matches == null || matches.length == 0)
- {
- return false;
- }
SequenceI ds = sequence.getDatasetSequence();
- for (int m = 0; m < matches.length; m++)
+ for (Match m : matches)
{
- if (matches[m].sequence != null
- && (matches[m].sequence == sequence || matches[m].sequence == ds))
+ if (m.sequence != null
+ && (m.sequence == sequence || m.sequence == ds))
{
return true;
}
*/
public int[] getResults(SequenceI sequence, int start, int end)
{
- if (matches == null)
+ if (matches.isEmpty())
{
return null;
}
int[] tmp = null;
int resultLength, matchStart = 0, matchEnd = 0;
boolean mfound;
- for (int m = 0; m < matches.length; m++)
+ for (Match m : matches)
{
mfound = false;
- if (matches[m].sequence == sequence)
+ if (m.sequence == sequence)
{
mfound = true;
// locate aligned position
- matchStart = sequence.findIndex(matches[m].start) - 1;
- matchEnd = sequence.findIndex(matches[m].end) - 1;
+ matchStart = sequence.findIndex(m.start) - 1;
+ matchEnd = sequence.findIndex(m.end) - 1;
}
- else if (matches[m].sequence == sequence.getDatasetSequence())
+ else if (m.sequence == sequence.getDatasetSequence())
{
mfound = true;
// locate region in local context
- matchStart = sequence.findIndex(matches[m].start) - 1;
- matchEnd = sequence.findIndex(matches[m].end) - 1;
+ matchStart = sequence.findIndex(m.start) - 1;
+ matchEnd = sequence.findIndex(m.end) - 1;
}
if (mfound)
{
public int getSize()
{
- return matches == null ? 0 : matches.length;
+ return matches.size();
}
public SequenceI getResultSequence(int index)
{
- return matches[index].sequence;
+ return matches.get(index).sequence;
}
- public int getResultStart(int index)
+ /**
+ * Returns the start position of the i'th match in the search results.
+ *
+ * @param i
+ * @return
+ */
+ public int getResultStart(int i)
{
- return matches[index].start;
+ return matches.get(i).start;
}
- public int getResultEnd(int index)
+ /**
+ * Returns the end position of the i'th match in the search results.
+ *
+ * @param i
+ * @return
+ */
+ public int getResultEnd(int i)
{
- return matches[index].end;
+ return matches.get(i).end;
}
- class Match
+ /**
+ * Returns true if no search result matches are held.
+ *
+ * @return
+ */
+ public boolean isEmpty()
{
- SequenceI sequence;
-
- int start;
-
- int end;
+ return matches.isEmpty();
+ }
- public Match(SequenceI seq, int start, int end)
- {
- sequence = seq;
- this.start = start;
- this.end = end;
- }
+ /**
+ * Returns the list of matches.
+ *
+ * @return
+ */
+ public List<Match> getResults()
+ {
+ return matches;
}
}
{
return;
}
+ // TODO use StringUtils.deleteChars
char[] tmp;
AlignmentAnnotation _aa = new AlignmentAnnotation(aa);
_aa.sequenceRef = datasetSequence;
_aa.adjustForAlignment(); // uses annotation's own record of
- // sequence-column mapping
+ // sequence-column mapping
datasetSequence.addAlignmentAnnotation(_aa);
}
}
String label)
{
List<AlignmentAnnotation> result = new ArrayList<AlignmentAnnotation>();
- if (this.annotation != null) {
- for (AlignmentAnnotation ann : annotation) {
+ if (this.annotation != null)
+ {
+ for (AlignmentAnnotation ann : annotation)
+ {
if (ann.calcId != null && ann.calcId.equals(calcId)
&& ann.label != null && ann.label.equals(label))
{
import java.awt.Color;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
{
if (seqsel != null)
{
- sequences = new Vector();
- Enumeration<SequenceI> sq = seqsel.sequences.elements();
- while (sq.hasMoreElements())
+ for (SequenceI seq : seqsel.sequences)
{
- sequences.addElement(sq.nextElement());
+ sequences.addElement(seq);
}
- ;
if (seqsel.groupName != null)
{
groupName = new String(seqsel.groupName);
{
SequenceGroup sgroup = new SequenceGroup(this);
SequenceI[] insect = getSequencesInOrder(alignment);
- sgroup.sequences = new Vector();
- for (int s = 0; insect != null && s < insect.length; s++)
+ sgroup.sequences = new Vector<SequenceI>();
+ if (insect != null)
{
- if (map == null || map.containsKey(insect[s]))
+ for (SequenceI seq : insect)
{
- sgroup.sequences.addElement(insect[s]);
+ if (map == null || map.containsKey(seq))
+ {
+ sgroup.sequences.addElement(seq);
+ }
}
}
// Enumeration en =getSequences(hashtable).elements();
public String getDescription();
/**
- * Return the alignment column for a sequence position * Return the alignment
- * position for a sequence position
+ * Return the alignment column for a sequence position
*
* @param pos
* lying from start to end
* if necessary and adjusting start and end positions accordingly.
*
* @param i
- * first column in range to delete
+ * first column in range to delete (inclusive)
* @param j
- * last column in range to delete
+ * last column in range to delete (exclusive)
*/
public void deleteChars(int i, int j);
/**
* DOCUMENT ME!
- *
- * @param i
+ * @param position
* DOCUMENT ME!
- * @param c
+ * @param ch
* DOCUMENT ME!
*/
- public void insertCharAt(int i, int length, char c);
+ public void insertCharAt(int position, int count, char ch);
/**
* DOCUMENT ME!
{ 1, dna.getLength() }, 1, 1));
// TODO: transform EMBL Database refs to canonical form
if (dbRefs != null)
+ {
for (Iterator i = dbRefs.iterator(); i.hasNext(); dna
.addDBRef((DBRefEntry) i.next()))
+ {
;
+ }
+ }
}
try
{
{
for (Iterator dbr = feature.dbRefs.iterator(); dbr.hasNext(); dna
.addDBRef((DBRefEntry) dbr.next()))
+ {
;
+ }
}
}
if (FeatureProperties.isCodingFeature(sourceDb, feature.getName()))
{
for (Iterator dbr = feature.dbRefs.iterator(); dbr.hasNext(); dna
.addDBRef((DBRefEntry) dbr.next()))
+ {
;
+ }
}
}
}
// { 1prstart, prstart + prseq.length() - 1 }, 3, 1);
pcdnaref.setMap(new Mapping(mp));
if (product != null)
+ {
product.addDBRef(pcdnaref);
+ }
}
}
sf.setEnd(exon[xint + 1]);
sf.setType(feature.getName());
sf.setFeatureGroup(sourceDb);
- sf.setDescription("Exon " + (1 + (int) (xint / 2))
+ sf.setDescription("Exon " + (1 + xint / 2)
+ " for protein '" + prname + "' EMBLCDS:" + prid);
sf.setValue(FeatureProperties.EXONPOS, new Integer(1 + xint));
sf.setValue(FeatureProperties.EXONPRODUCT, prname);
if (vals != null && vals.size() > 0)
{
- Enumeration kv = vals.elements();
+ Enumeration kv = vals.keys();
while (kv.hasMoreElements())
{
Object key = kv.nextElement();
if (key != null)
+ {
sf.setValue(key.toString(), vals.get(key));
+ }
}
}
dna.addSequenceFeature(sf);
import java.io.File;
import java.net.URL;
import java.security.AccessControlException;
-import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
return;
}
- String res;
int index;
Color col;
jmolHistory(false);
// TODO: Switch between nucleotide or aa selection expressions
- Enumeration en = ResidueProperties.aa3Hash.keys();
- StringBuffer command = new StringBuffer("select *;color white;");
- while (en.hasMoreElements())
+ StringBuilder command = new StringBuilder(128);
+ command.append("select *;color white;");
+ for (String res : ResidueProperties.aa3Hash.keySet())
{
- res = en.nextElement().toString();
- index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();
+ index = ResidueProperties.aa3Hash.get(res).intValue();
if (index > 20)
{
continue;
-/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * Jalview is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
package jalview.ext.rbvi.chimera;
import jalview.api.AlignmentViewPanel;
import java.awt.Color;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
}
AlignmentI alignment = alignmentv.getAlignment();
- for (jalview.structure.StructureMappingcommandSet cpdbbyseq : getColourBySequenceCommands(files, sr, fr, alignment))
+ for (jalview.structure.StructureMappingcommandSet cpdbbyseq : getColourBySequenceCommands(
+ files, sr, fr, alignment))
{
for (String command : cpdbbyseq.commands)
{
String[] files, SequenceRenderer sr, FeatureRenderer fr,
AlignmentI alignment)
{
- return ChimeraCommands
- .getColourBySequenceCommand(getSsm(), files, getSequence(), sr,
- fr,
- alignment);
+ return ChimeraCommands.getColourBySequenceCommand(getSsm(), files,
+ getSequence(), sr, fr, alignment);
}
/**
}
}
-
+
// End StructureListener
// //////////////////////////
eval.append("." + chain);
resetLastRes.append("." + chain);
}
-
+
viewer.sendChimeraCommand(eval.toString(), false);
viewerCommandHistory(true);
// viewer.startListening();
return;
}
- String res;
int index;
Color col;
// Chimera expects RBG values in the range 0-1
final double normalise = 255D;
viewerCommandHistory(false);
// TODO: Switch between nucleotide or aa selection expressions
- Enumeration en = ResidueProperties.aa3Hash.keys();
StringBuilder command = new StringBuilder(128);
command.append("color white;");
- while (en.hasMoreElements())
+ for (String res : ResidueProperties.aa3Hash.keySet())
{
- res = en.nextElement().toString();
- index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();
+ index = ResidueProperties.aa3Hash.get(res).intValue();
if (index > 20)
{
continue;
return chainNames;
}
-}
+}
\ No newline at end of file
import jalview.analysis.AAFrequency;
import jalview.analysis.AlignmentSorter;
import jalview.analysis.AlignmentUtils;
+import jalview.analysis.AlignmentUtils.MappingResult;
import jalview.analysis.Conservation;
import jalview.analysis.CrossRef;
-import jalview.analysis.NJTree;
+import jalview.analysis.Dna;
import jalview.analysis.ParseProperties;
import jalview.analysis.SequenceIdMatcher;
import jalview.api.AlignViewControllerGuiI;
import jalview.api.AlignViewControllerI;
+import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.api.analysis.ScoreModelI;
import jalview.bin.Cache;
import jalview.schemes.TurnColourScheme;
import jalview.schemes.UserColourScheme;
import jalview.schemes.ZappoColourScheme;
+import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import jalview.ws.jws1.Discoverer;
import jalview.ws.jws2.Jws2Discoverer;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Deque;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
+import java.util.Set;
import java.util.Vector;
import javax.swing.JButton;
IProgressIndicator, AlignViewControllerGuiI
{
- /** DOCUMENT ME!! */
public static final int DEFAULT_WIDTH = 700;
- /** DOCUMENT ME!! */
public static final int DEFAULT_HEIGHT = 500;
+ /*
+ * The currently displayed panel (selected tabbed view if more than one)
+ */
public AlignmentPanel alignPanel;
AlignViewport viewport;
public AlignViewControllerI avc;
- Vector alignPanels = new Vector();
+ List<AlignmentPanel> alignPanels = new ArrayList<AlignmentPanel>();
/**
* Last format used to load or save alignments in this window
reload.setEnabled(true);
}
+ /**
+ * Add a KeyListener with handlers for various KeyPressed and KeyReleased
+ * events
+ */
void addKeyListener()
{
addKeyListener(new KeyAdapter()
avc = new jalview.controller.AlignViewController(this, viewport,
alignPanel);
- alignPanels.addElement(ap);
+ alignPanels.add(ap);
PaintRefresher.Register(ap, ap.av.getSequenceSetId());
expandViews.setEnabled(true);
gatherViews.setEnabled(true);
tabbedPane.setVisible(true);
- AlignmentPanel first = (AlignmentPanel) alignPanels.firstElement();
+ AlignmentPanel first = alignPanels.get(0);
tabbedPane.addTab(first.av.viewName, first);
this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
}
public void setGUINucleotide(boolean nucleotide)
{
showTranslation.setVisible(nucleotide);
+ cdna.setVisible(!nucleotide);
conservationMenuItem.setEnabled(!nucleotide);
modifyConservation.setEnabled(!nucleotide);
showGroupConservation.setEnabled(!nucleotide);
rnahelicesColour.setEnabled(nucleotide);
purinePyrimidineColour.setEnabled(nucleotide);
- // Remember AlignFrame always starts as protein
- // if (!nucleotide)
- // {
- // showTr
- // calculateMenu.remove(calculateMenu.getItemCount() - 2);
- // }
}
/**
- * set up menus for the currently viewport. This may be called after any
+ * Builds codon mappings from this (protein) alignment to any compatible
+ * nucleotide alignments. Mappings are built between sequences with the same
+ * name and compatible lengths. Also makes the cDNA alignment a
+ * CommandListener for the protein alignment so that edits are mirrored.
+ */
+ @Override
+ protected void linkCdna_actionPerformed()
+ {
+ int linkedCount = 0;
+ int alreadyLinkedCount = 0;
+ final AlignmentI thisAlignment = this.alignPanel.getAlignment();
+
+ for (AlignFrame af : Desktop.getAlignFrames())
+ {
+ if (af.alignPanel != null)
+ {
+ final AlignmentI thatAlignment = af.alignPanel.getAlignment();
+ if (thatAlignment.isNucleotide())
+ {
+ MappingResult mapped = AlignmentUtils.mapProteinToCdna(
+ thisAlignment, thatAlignment);
+ if (mapped == MappingResult.AlreadyMapped)
+ {
+ alreadyLinkedCount++;
+ }
+ else if (mapped == MappingResult.Mapped)
+ {
+ final StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(Desktop.instance);
+ ssm.addMappings(thisAlignment.getCodonFrames());
+ // enable the next line to enable linked editing
+ // ssm.addCommandListener(af.getViewport());
+ linkedCount++;
+ }
+ }
+ }
+ }
+ String msg = "";
+ if (linkedCount == 0 && alreadyLinkedCount == 0)
+ {
+ msg = MessageManager.getString("label.no_cdna");
+ }
+ else if (linkedCount > 0)
+ {
+ msg = MessageManager.formatMessage("label.linked_cdna", linkedCount);
+ }
+ else
+ {
+ msg = MessageManager.formatMessage("label.cdna_all_linked",
+ alreadyLinkedCount);
+ }
+ setStatus(msg);
+ }
+
+ /**
+ * Align any linked cDNA to match the alignment of this (protein) alignment.
+ * Any mapped sequence regions will be realigned, unmapped sequences are not
+ * affected.
+ */
+ @Override
+ protected void alignCdna_actionPerformed()
+ {
+ int seqCount = 0;
+ int alignCount = 0;
+ final AlignmentI thisAlignment = this.alignPanel.getAlignment();
+ for (AlignFrame af : Desktop.getAlignFrames())
+ {
+ if (af.alignPanel != null)
+ {
+ final AlignmentI thatAlignment = af.alignPanel.getAlignment();
+ if (thatAlignment.isNucleotide())
+ {
+ int seqsAligned = thatAlignment.alignAs(thisAlignment);
+ seqCount += seqsAligned;
+ if (seqsAligned > 0)
+ {
+ af.alignPanel.alignmentChanged();
+ alignCount++;
+ }
+ }
+ }
+ }
+ setStatus(MessageManager.formatMessage("label.cdna_aligned", seqCount,
+ alignCount));
+ }
+ /**
+ * set up menus for the current viewport. This may be called after any
* operation that affects the data in the current view (selection changed,
* etc) to update the menus to reflect the new state.
*/
public void actionPerformed(ActionEvent e)
{
handler.cancelActivity(id);
- us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
+ us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new Object[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
}
});
progressPanel.add(cancel, BorderLayout.EAST);
if (value == JalviewFileChooser.APPROVE_OPTION)
{
currentFileFormat = chooser.getSelectedFormat();
- if (currentFileFormat == null)
+ while (currentFileFormat == null)
{
JOptionPane
.showInternalMessageDialog(
MessageManager
.getString("label.file_format_not_specified"),
JOptionPane.WARNING_MESSAGE);
+ currentFileFormat = chooser.getSelectedFormat();
value = chooser.showSaveDialog(this);
- return;
+ if (value != JalviewFileChooser.APPROVE_OPTION)
+ {
+ return;
+ }
}
fileName = chooser.getSelectedFile().getPath();
this.setTitle(file);
statusBar.setText(MessageManager.formatMessage(
"label.successfully_saved_to_file_in_format",
- new String[]
+ new Object[]
{ fileName, format }));
} catch (Exception ex)
{
if (!success)
{
JOptionPane.showInternalMessageDialog(this, MessageManager
- .formatMessage("label.couldnt_save_file", new String[]
+ .formatMessage("label.couldnt_save_file", new Object[]
{ fileName }), MessageManager
.getString("label.error_saving_file"),
JOptionPane.WARNING_MESSAGE);
viewport.getAlignment(), omitHidden,
viewport.getColumnSelection()));
Desktop.addInternalFrame(cap, MessageManager.formatMessage(
- "label.alignment_output_command", new String[]
+ "label.alignment_output_command", new Object[]
{ e.getActionCommand() }), 600, 500);
} catch (OutOfMemoryError oom)
{
// setClosed(true) is called
for (int i = 0; i < alignPanels.size(); i++)
{
- AlignmentPanel ap = (AlignmentPanel) alignPanels.elementAt(i);
+ AlignmentPanel ap = alignPanels.get(i);
ap.closePanel();
}
}
{
int index = tabbedPane.getSelectedIndex();
int closedindex = tabbedPane.indexOfComponent(alignPanel2);
- alignPanels.removeElement(alignPanel2);
+ alignPanels.remove(alignPanel2);
// Unnecessary
// if (viewport == alignPanel2.av)
// {
void updateEditMenuBar()
{
- if (viewport.historyList.size() > 0)
+ if (viewport.getHistoryList().size() > 0)
{
undoMenuItem.setEnabled(true);
- CommandI command = viewport.historyList.peek();
+ CommandI command = viewport.getHistoryList().peek();
undoMenuItem.setText(MessageManager.formatMessage(
- "label.undo_command", new String[]
+ "label.undo_command", new Object[]
{ command.getDescription() }));
}
else
undoMenuItem.setText(MessageManager.getString("action.undo"));
}
- if (viewport.redoList.size() > 0)
+ if (viewport.getRedoList().size() > 0)
{
redoMenuItem.setEnabled(true);
- CommandI command = viewport.redoList.peek();
+ CommandI command = viewport.getRedoList().peek();
redoMenuItem.setText(MessageManager.formatMessage(
- "label.redo_command", new String[]
+ "label.redo_command", new Object[]
{ command.getDescription() }));
}
else
{
if (command.getSize() > 0)
{
- viewport.historyList.push(command);
- viewport.redoList.clear();
+ viewport.addToHistoryList(command);
+ viewport.clearRedoList();
updateEditMenuBar();
viewport.updateHiddenColumns();
// viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
{
if (alignPanels != null)
{
- Enumeration e = alignPanels.elements();
AlignmentI[] als = new AlignmentI[alignPanels.size()];
- for (int i = 0; e.hasMoreElements(); i++)
+ int i = 0;
+ for (AlignmentPanel ap : alignPanels)
{
- als[i] = ((AlignmentPanel) e.nextElement()).av.getAlignment();
+ als[i++] = ap.av.getAlignment();
}
return als;
}
@Override
protected void undoMenuItem_actionPerformed(ActionEvent e)
{
- if (viewport.historyList.empty())
+ if (viewport.getHistoryList().isEmpty())
{
return;
}
- CommandI command = viewport.historyList.pop();
- viewport.redoList.push(command);
+ CommandI command = viewport.getHistoryList().pop();
+ viewport.addToRedoList(command);
command.undoCommand(getViewAlignments());
- AlignViewport originalSource = getOriginatingSource(command);
+ AlignmentViewport originalSource = getOriginatingSource(command);
updateEditMenuBar();
if (originalSource != null)
@Override
protected void redoMenuItem_actionPerformed(ActionEvent e)
{
- if (viewport.redoList.size() < 1)
+ if (viewport.getRedoList().size() < 1)
{
return;
}
- CommandI command = viewport.redoList.pop();
- viewport.historyList.push(command);
+ CommandI command = viewport.getRedoList().pop();
+ viewport.addToHistoryList(command);
command.doCommand(getViewAlignments());
- AlignViewport originalSource = getOriginatingSource(command);
+ AlignmentViewport originalSource = getOriginatingSource(command);
updateEditMenuBar();
if (originalSource != null)
}
}
- AlignViewport getOriginatingSource(CommandI command)
+ AlignmentViewport getOriginatingSource(CommandI command)
{
- AlignViewport originalSource = null;
+ AlignmentViewport originalSource = null;
// For sequence removal and addition, we need to fire
// the property change event FROM the viewport where the
// original alignment was altered
{
EditCommand editCommand = (EditCommand) command;
al = editCommand.getAlignment();
- Vector comps = (Vector) PaintRefresher.components.get(viewport
+ List<Component> comps = PaintRefresher.components.get(viewport
.getSequenceSetId());
- for (int i = 0; i < comps.size(); i++)
+ for (Component comp : comps)
{
- if (comps.elementAt(i) instanceof AlignmentPanel)
+ if (comp instanceof AlignmentPanel)
{
- if (al == ((AlignmentPanel) comps.elementAt(i)).av.getAlignment())
+ if (al == ((AlignmentPanel) comp).av.getAlignment())
{
- originalSource = ((AlignmentPanel) comps.elementAt(i)).av;
+ originalSource = ((AlignmentPanel) comp).av;
break;
}
}
viewport.getAlignment().moveSelectedSequencesByOne(sg,
viewport.getHiddenRepSequences(), up);
alignPanel.paintAlignment(true);
+
+ final AlignViewportI peer = viewport.getCodingComplement();
+ if (peer != null)
+ {
+ final SequenceGroup selectionGroup = peer.getSelectionGroup();
+ if (selectionGroup != null)
+ {
+ peer.getAlignment().moveSelectedSequencesByOne(
+ peer.getSelectionGroup(), peer.getHiddenRepSequences(), up);
+ ((AlignViewport) peer).getAlignPanel().paintAlignment(true);
+ }
+ }
}
synchronized void slideSequences(boolean right, int size)
{
- List<SequenceI> sg = new Vector();
+ List<SequenceI> sg = new ArrayList<SequenceI>();
if (viewport.cursorMode)
{
sg.add(viewport.getAlignment().getSequenceAt(
return;
}
- Vector invertGroup = new Vector();
+ List<SequenceI> invertGroup = new ArrayList<SequenceI>();
- for (int i = 0; i < viewport.getAlignment().getHeight(); i++)
+ for (SequenceI seq : viewport.getAlignment().getSequences())
{
- if (!sg.contains(viewport.getAlignment().getSequenceAt(i)))
+ if (!sg.contains(seq))
{
- invertGroup.add(viewport.getAlignment().getSequenceAt(i));
+ invertGroup.add(seq);
}
}
SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
for (int i = 0; i < invertGroup.size(); i++)
{
- seqs2[i] = (SequenceI) invertGroup.elementAt(i);
+ seqs2[i] = invertGroup.get(i);
}
SlideSequencesCommand ssc;
}
boolean appendHistoryItem = false;
- if (viewport.historyList != null && viewport.historyList.size() > 0
- && viewport.historyList.peek() instanceof SlideSequencesCommand)
+ Deque<CommandI> historyList = viewport.getHistoryList();
+ if (historyList != null
+ && historyList.size() > 0
+ && historyList.peek() instanceof SlideSequencesCommand)
{
appendHistoryItem = ssc
- .appendSlideCommand((SlideSequencesCommand) viewport.historyList
+ .appendSlideCommand((SlideSequencesCommand) historyList
.peek());
}
Desktop.jalviewClipboard = new Object[]
{ seqs, viewport.getAlignment().getDataset(), hiddenColumns };
statusBar.setText(MessageManager.formatMessage(
- "label.copied_sequences_to_clipboard", new String[]
+ "label.copied_sequences_to_clipboard", new Object[]
{ Integer.valueOf(seqs.length).toString() }));
}
alignment.getSequences());
if (alignPanels != null)
{
- for (AlignmentPanel ap : ((Vector<AlignmentPanel>) alignPanels))
+ for (AlignmentPanel ap : alignPanels)
{
ap.validateAnnotationDimensions(false);
}
addHistoryItem(removeGapCols);
statusBar.setText(MessageManager.formatMessage(
- "label.removed_empty_columns", new String[]
+ "label.removed_empty_columns", new Object[]
{ Integer.valueOf(removeGapCols.getSize()).toString() }));
// This is to maintain viewport position on first residue
.getSequences());
}
- // else
- {
- // if (justifySeqs>0)
- {
- // alignment.justify(justifySeqs!=RIGHT_JUSTIFY);
- }
- }
-
- // }
-
/**
* DOCUMENT ME!
*
new Finder();
}
+ /**
+ * Create a new view of the current alignment.
+ */
@Override
public void newView_actionPerformed(ActionEvent e)
{
- newView(true);
- }
+ /*
+ * Note if the current view has a protein/cdna complementary view
+ */
+ AlignViewportI linkedView = this.viewport.getCodingComplement();
- /**
- *
- * @param copyAnnotation
- * if true then duplicate all annnotation, groups and settings
- * @return new alignment panel, already displayed.
- */
- public AlignmentPanel newView(boolean copyAnnotation)
- {
- return newView(null, copyAnnotation);
- }
+ AlignmentPanel newPanel = newView(null, true);
- /**
- *
- * @param viewTitle
- * title of newly created view
- * @return new alignment panel, already displayed.
- */
- public AlignmentPanel newView(String viewTitle)
- {
- return newView(viewTitle, true);
+ /*
+ * If the original view has a protein/cdna linked view, make and link a new
+ * view there also.
+ */
+ // TODO refactor the hell out of this - move to a controller, lose the casts
+ // and direct member access, etc
+ if (linkedView != null)
+ {
+ AlignFrame linkedAlignFrame = ((AlignViewport) linkedView)
+ .getAlignPanel().alignFrame;
+ AlignmentPanel newLinkedPanel = linkedAlignFrame.newView(null, true);
+ newLinkedPanel.av.viewName = newPanel.av.viewName;
+ newPanel.av.setCodingComplement(newLinkedPanel.av);
+ final StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(Desktop.instance);
+ ssm.addCommandListener(newPanel.av);
+ ssm.addCommandListener(newLinkedPanel.av);
+
+ }
}
/**
+ * Creates and shows a new view of the current alignment.
*
* @param viewTitle
- * title of newly created view
+ * title of newly created view; if null, one will be generated
* @param copyAnnotation
* if true then duplicate all annnotation, groups and settings
* @return new alignment panel, already displayed.
*/
public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
{
+ /*
+ * Create a new AlignmentPanel (with its own, new Viewport)
+ */
AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel,
true);
if (!copyAnnotation)
{
- // just remove all the current annotation except for the automatic stuff
+ /*
+ * remove all groups and annotation except for the automatic stuff
+ */
newap.av.getAlignment().deleteAllGroups();
- for (AlignmentAnnotation alan : newap.av.getAlignment()
- .getAlignmentAnnotation())
- {
- if (!alan.autoCalculated)
- {
- newap.av.getAlignment().deleteAnnotation(alan);
- }
- ;
- }
+ newap.av.getAlignment().deleteAllAnnotations(false);
}
newap.av.gatherViewsHere = false;
if (viewport.viewName == null)
{
- viewport.viewName = "Original";
+ viewport.viewName = MessageManager
+ .getString("label.view_name_original");
}
- newap.av.historyList = viewport.historyList;
- newap.av.redoList = viewport.redoList;
+ /*
+ * Views share the same edits, undo and redo stacks, mappings.
+ */
+ newap.av.setHistoryList(viewport.getHistoryList());
+ newap.av.setRedoList(viewport.getRedoList());
+ newap.av.getAlignment().setCodonFrames(
+ viewport.getAlignment().getCodonFrames());
+
+ newap.av.viewName = getNewViewName(viewTitle);
+
+ addAlignmentPanel(newap, true);
+ newap.alignmentChanged();
+ if (alignPanels.size() == 2)
+ {
+ viewport.gatherViewsHere = true;
+ }
+ tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
+ return newap;
+ }
+
+ /**
+ * Make a new name for the view, ensuring it is unique within the current
+ * sequenceSetId. (This used to be essential for Jalview Project archives, but
+ * these now use viewId. Unique view names are still desirable for usability.)
+ *
+ * @param viewTitle
+ * @return
+ */
+ protected String getNewViewName(String viewTitle)
+ {
int index = Desktop.getViewCount(viewport.getSequenceSetId());
- // make sure the new view has a unique name - this is essential for Jalview
- // 2 archives
boolean addFirstIndex = false;
if (viewTitle == null || viewTitle.trim().length() == 0)
{
index = 1;// we count from 1 if given a specific name
}
String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
- Vector comps = (Vector) PaintRefresher.components.get(viewport
+
+ List<Component> comps = PaintRefresher.components.get(viewport
.getSequenceSetId());
- Vector existingNames = new Vector();
- for (int i = 0; i < comps.size(); i++)
- {
- if (comps.elementAt(i) instanceof AlignmentPanel)
- {
- AlignmentPanel ap = (AlignmentPanel) comps.elementAt(i);
- if (!existingNames.contains(ap.av.viewName))
- {
- existingNames.addElement(ap.av.viewName);
- }
- }
- }
+
+ List<String> existingNames = getExistingViewNames(comps);
while (existingNames.contains(newViewName))
{
newViewName = viewTitle + " " + (++index);
}
+ return newViewName;
+ }
- newap.av.viewName = newViewName;
-
- addAlignmentPanel(newap, true);
- newap.alignmentChanged();
-
- if (alignPanels.size() == 2)
+ /**
+ * Returns a list of distinct view names found in the given list of
+ * components. View names are held on the viewport of an AlignmentPanel.
+ *
+ * @param comps
+ * @return
+ */
+ protected List<String> getExistingViewNames(List<Component> comps)
+ {
+ List<String> existingNames = new ArrayList<String>();
+ for (Component comp : comps)
{
- viewport.gatherViewsHere = true;
+ if (comp instanceof AlignmentPanel)
+ {
+ AlignmentPanel ap = (AlignmentPanel) comp;
+ if (!existingNames.contains(ap.av.viewName))
+ {
+ existingNames.add(ap.av.viewName);
+ }
+ }
}
- tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
- return newap;
+ return existingNames;
}
+ /**
+ * Explode tabbed views into separate windows.
+ */
@Override
public void expandViews_actionPerformed(ActionEvent e)
{
Desktop.instance.explodeViews(this);
}
+ /**
+ * Gather views in separate windows back into a tabbed presentation.
+ */
@Override
public void gatherViews_actionPerformed(ActionEvent e)
{
StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
.formatAsHtml();
editPane.setText(MessageManager.formatMessage("label.html_content",
- new String[]
+ new Object[]
{ contents.toString() }));
JInternalFrame frame = new JInternalFrame();
frame.getContentPane().add(new JScrollPane(editPane));
- Desktop.instance.addInternalFrame(frame, MessageManager.formatMessage(
- "label.alignment_properties", new String[]
+ Desktop.addInternalFrame(frame, MessageManager.formatMessage(
+ "label.alignment_properties", new Object[]
{ getTitle() }), 500, 400);
}
OverviewPanel overview = new OverviewPanel(alignPanel);
frame.setContentPane(overview);
Desktop.addInternalFrame(frame, MessageManager.formatMessage(
- "label.overview_params", new String[]
+ "label.overview_params", new Object[]
{ this.getTitle() }), frame.getWidth(), frame.getHeight());
frame.pack();
frame.setLayer(JLayeredPane.PALETTE_LAYER);
{
Component[] menuItems = colourMenu.getMenuComponents();
- int i, iSize = menuItems.length;
- for (i = 0; i < iSize; i++)
+ int iSize = menuItems.length;
+ for (int i = 0; i < iSize; i++)
{
if (menuItems[i].getName() != null
&& menuItems[i].getName().equals("USER_DEFINED"))
@Override
public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)
{
- NewTreePanel("AV", "PID", "Average distance tree using PID");
+ newTreePanel("AV", "PID", "Average distance tree using PID");
}
/**
@Override
public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)
{
- NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");
+ newTreePanel("NJ", "PID", "Neighbour joining tree using PID");
}
/**
@Override
protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)
{
- NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
+ newTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
}
/**
@Override
protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)
{
- NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
+ newTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
}
/**
* @param title
* DOCUMENT ME!
*/
- void NewTreePanel(String type, String pwType, String title)
+ void newTreePanel(String type, String pwType, String title)
{
TreePanel tp;
public void addSortByOrderMenuItem(String title,
final AlignmentOrder order)
{
- final JMenuItem item = new JMenuItem(MessageManager.formatMessage("action.by_title_param", new String[]{title}));
+ final JMenuItem item = new JMenuItem(MessageManager.formatMessage("action.by_title_param", new Object[]{title}));
sort.add(item);
item.addActionListener(new java.awt.event.ActionListener()
{
{
String treecalcnm = MessageManager.getString("label.tree_calc_"
+ type.toLowerCase());
- for (final Object pwtype : ResidueProperties.scoreMatrices.keySet())
+ for (final String pwtype : ResidueProperties.scoreMatrices.keySet())
{
JMenuItem tm = new JMenuItem();
ScoreModelI sm = ResidueProperties.scoreMatrices.get(pwtype);
@Override
public void actionPerformed(ActionEvent e)
{
- NewTreePanel(type, (String) pwtype, title);
+ newTreePanel(type, pwtype, title);
}
});
calculateTree.add(tm);
}
sortByTreeMenu.removeAll();
- Vector comps = (Vector) PaintRefresher.components.get(viewport
+ List<Component> comps = PaintRefresher.components.get(viewport
.getSequenceSetId());
- Vector treePanels = new Vector();
- int i, iSize = comps.size();
- for (i = 0; i < iSize; i++)
+ List<TreePanel> treePanels = new ArrayList<TreePanel>();
+ for (Component comp : comps)
{
- if (comps.elementAt(i) instanceof TreePanel)
+ if (comp instanceof TreePanel)
{
- treePanels.add(comps.elementAt(i));
+ treePanels.add((TreePanel) comp);
}
}
- iSize = treePanels.size();
-
- if (iSize < 1)
+ if (treePanels.size() < 1)
{
sortByTreeMenu.setVisible(false);
return;
sortByTreeMenu.setVisible(true);
- for (i = 0; i < treePanels.size(); i++)
+ for (final TreePanel tp : treePanels)
{
- final TreePanel tp = (TreePanel) treePanels.elementAt(i);
final JMenuItem item = new JMenuItem(tp.getTitle());
- final NJTree tree = ((TreePanel) treePanels.elementAt(i)).getTree();
item.addActionListener(new java.awt.event.ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- tp.sortByTree_actionPerformed(null);
+ tp.sortByTree_actionPerformed();
addHistoryItem(tp.sortAlignmentIn(alignPanel));
}
} catch (Exception e)
{
}
- ;
}
final AlignFrame me = this;
buildingMenu = true;
.debug("Exception during web service menu building process.",
e);
}
- ;
}
});
} catch (Exception e)
{
}
- ;
-
buildingMenu = false;
}
}).start();
public void run()
{
final long sttime = System.currentTimeMillis();
- ths.setProgressBar(MessageManager.formatMessage("status.searching_for_sequences_from", new String[]{fsrc}), sttime);
+ ths.setProgressBar(MessageManager.formatMessage("status.searching_for_sequences_from", new Object[]{fsrc}), sttime);
try
{
Alignment ds = ths.getViewport().getAlignment().getDataset(); // update
sprods[s].updatePDBIds();
}
Alignment al = new Alignment(sprods);
- AlignedCodonFrame[] cf = prods.getCodonFrames();
+ Set<AlignedCodonFrame> cf = prods.getCodonFrames();
al.setDataset(ds);
- for (int s = 0; cf != null && s < cf.length; s++)
+ for (AlignedCodonFrame acf : cf)
{
- al.addCodonFrame(cf[s]);
- cf[s] = null;
+ al.addCodonFrame(acf);
}
AlignFrame naf = new AlignFrame(al, DEFAULT_WIDTH,
DEFAULT_HEIGHT);
jalview.bin.Cache.log.error("Error when finding crossreferences",
e);
}
- ths.setProgressBar(MessageManager.formatMessage("status.finished_searching_for_sequences_from", new String[]{fsrc}),
+ ths.setProgressBar(MessageManager.formatMessage("status.finished_searching_for_sequences_from", new Object[]{fsrc}),
sttime);
}
}
}
- @Override
- public void showProducts_actionPerformed(ActionEvent e)
- {
- // /////////////////////////////
- // Collect Data to be translated/transferred
-
- SequenceI[] selection = viewport.getSequenceSelection();
- AlignmentI al = null;
- try
- {
- al = jalview.analysis.Dna.CdnaTranslate(selection, viewport
- .getViewAsVisibleContigs(true), viewport.getGapCharacter(),
- viewport.getAlignment().getDataset());
- } catch (Exception ex)
- {
- al = null;
- jalview.bin.Cache.log.debug("Exception during translation.", ex);
- }
- if (al == null)
- {
- JOptionPane
- .showMessageDialog(
- Desktop.desktop,
- MessageManager
- .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation"),
- MessageManager.getString("label.translation_failed"),
- JOptionPane.WARNING_MESSAGE);
- }
- else
- {
- AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
- Desktop.addInternalFrame(af, MessageManager.formatMessage(
- "label.translation_of_params", new String[]
- { this.getTitle() }), DEFAULT_WIDTH, DEFAULT_HEIGHT);
- }
- }
-
+ /**
+ * Construct and display a new frame containing the translation of this
+ * frame's cDNA sequences to their aligned protein (amino acid) equivalents.
+ */
@Override
public void showTranslation_actionPerformed(ActionEvent e)
{
- // /////////////////////////////
- // Collect Data to be translated/transferred
-
- SequenceI[] selection = viewport.getSequenceSelection();
- String[] seqstring = viewport.getViewAsString(true);
AlignmentI al = null;
try
{
- al = jalview.analysis.Dna.CdnaTranslate(selection, seqstring,
- viewport.getViewAsVisibleContigs(true), viewport
- .getGapCharacter(), viewport.getAlignment()
- .getAlignmentAnnotation(), viewport.getAlignment()
- .getWidth(), viewport.getAlignment().getDataset());
+ Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
+
+ al = dna.translateCdna();
} catch (Exception ex)
{
- al = null;
jalview.bin.Cache.log.error(
"Exception during translation. Please report this !", ex);
- JOptionPane
- .showMessageDialog(
- Desktop.desktop,
- MessageManager
- .getString("label.error_when_translating_sequences_submit_bug_report"),
- MessageManager
- .getString("label.implementation_error")
- + MessageManager
- .getString("translation_failed"),
- JOptionPane.ERROR_MESSAGE);
+ final String msg = MessageManager
+ .getString("label.error_when_translating_sequences_submit_bug_report");
+ final String title = MessageManager
+ .getString("label.implementation_error")
+ + MessageManager.getString("translation_failed");
+ JOptionPane.showMessageDialog(Desktop.desktop, msg, title,
+ JOptionPane.ERROR_MESSAGE);
return;
}
- if (al == null)
+ if (al == null || al.getHeight() == 0)
{
- JOptionPane
- .showMessageDialog(
- Desktop.desktop,
- MessageManager
- .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation"),
- MessageManager.getString("label.translation_failed"),
- JOptionPane.WARNING_MESSAGE);
+ final String msg = MessageManager
+ .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
+ final String title = MessageManager
+ .getString("label.translation_failed");
+ JOptionPane.showMessageDialog(Desktop.desktop, msg, title,
+ JOptionPane.WARNING_MESSAGE);
}
else
{
AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
Desktop.addInternalFrame(af, MessageManager.formatMessage(
- "label.translation_of_params", new String[]
+ "label.translation_of_params", new Object[]
{ this.getTitle() }), DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ // enable next line for linked editing
+ // viewport.getStructureSelectionManager().addCommandListener(viewport);
}
}
MessageManager
.formatMessage(
"label.automatically_associate_pdb_files_with_sequences_same_name",
- new String[]
+ new Object[]
{ Integer.valueOf(
filesmatched
.size())
"<html>"+MessageManager
.formatMessage(
"label.ignore_unmatched_dropped_files_info",
- new String[]
+ new Object[]
{ Integer.valueOf(
filesnotmatched
.size())
{
jalview.io.JPredFile predictions = new jalview.io.JPredFile(
file, protocol);
- new JnetAnnotationMaker().add_annotation(predictions,
+ new JnetAnnotationMaker();
+ JnetAnnotationMaker.add_annotation(predictions,
viewport.getAlignment(), 0, false);
isAnnotation = true;
}
}
}
+ /**
+ * Method invoked by the ChangeListener on the tabbed pane, in other words
+ * when a different tabbed pane is selected by the user or programmatically.
+ */
@Override
public void tabSelectionChanged(int index)
{
if (index > -1)
{
- alignPanel = (AlignmentPanel) alignPanels.elementAt(index);
+ alignPanel = alignPanels.get(index);
viewport = alignPanel.av;
avc.setViewportAndAlignmentPanel(viewport, alignPanel);
setMenusFromViewport(viewport);
}
}
+ /**
+ * On right mouse click on view tab, prompt for and set new view name.
+ */
@Override
public void tabbedPane_mousePressed(MouseEvent e)
{
if (SwingUtilities.isRightMouseButton(e))
{
- String reply = JOptionPane.showInternalInputDialog(this,
- MessageManager.getString("label.enter_view_name"),
- MessageManager.getString("label.enter_view_name"),
+ String msg = MessageManager.getString("label.enter_view_name");
+ String reply = JOptionPane.showInternalInputDialog(this, msg, msg,
JOptionPane.QUESTION_MESSAGE);
if (reply != null)
{
viewport.viewName = reply;
+ // TODO warn if reply is in getExistingViewNames()?
tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
}
}
*
* @param av
*/
- public boolean closeView(AlignViewport av)
+ public boolean closeView(AlignmentViewport av)
{
if (viewport == av)
{
}
});
- fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from", new String[]{src.getDbName()})));
+ fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from", new Object[]{src.getDbName()})));
dfetch.add(fetchr);
comp++;
}
// fetch all entry
DbSourceProxy src = otherdb.get(0);
fetchr = new JMenuItem(MessageManager.formatMessage(
- "label.fetch_all_param", new String[]
+ "label.fetch_all_param", new Object[]
{ src.getDbSource() }));
fetchr.addActionListener(new ActionListener()
{
}
});
- fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from_all_sources", new String[]{Integer.valueOf(otherdb.size()).toString(), src.getDbSource(), src.getDbName()})));
+ fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from_all_sources", new Object[]{Integer.valueOf(otherdb.size()).toString(), src.getDbSource(), src.getDbName()})));
dfetch.add(fetchr);
comp++;
// and then build the rest of the individual menus
- ifetch = new JMenu(MessageManager.formatMessage("label.source_from_db_source", new String[]{src.getDbSource()}));
+ ifetch = new JMenu(MessageManager.formatMessage("label.source_from_db_source", new Object[]{src.getDbSource()}));
icomp = 0;
String imname = null;
int i = 0;
0, 10) + "..." : dbname;
if (imname == null)
{
- imname = MessageManager.formatMessage("label.from_msname", new String[]{sname});
+ imname = MessageManager.formatMessage("label.from_msname", new Object[]{sname});
}
fetchr = new JMenuItem(msname);
final DbSourceProxy[] dassrc =
});
fetchr.setToolTipText("<html>"
- + MessageManager.formatMessage("label.fetch_retrieve_from", new String[]{dbname}));
+ + MessageManager.formatMessage("label.fetch_retrieve_from", new Object[]{dbname}));
ifetch.add(fetchr);
++i;
if (++icomp >= mcomp || i == (otherdb.size()))
/**
*
- * @return alignment panels in this alignemnt frame
+ * @return alignment panels in this alignment frame
*/
- public List<AlignmentViewPanel> getAlignPanels()
+ public List<? extends AlignmentViewPanel> getAlignPanels()
{
- return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
+ return alignPanels == null ? Arrays.asList(alignPanel)
+ : alignPanels;
+ }
+
+ /**
+ * Open a new alignment window, with the cDNA associated with this (protein)
+ * alignment, aligned as is the protein.
+ */
+ @Override
+ protected void viewAsCdna_actionPerformed()
+ {
+ final AlignmentI alignment = getViewport().getAlignment();
+ Set<AlignedCodonFrame> mappings = alignment.getCodonFrames();
+ if (mappings == null)
+ {
+ return;
+ }
+ List<SequenceI> cdnaSeqs = new ArrayList<SequenceI>();
+ for (SequenceI aaSeq : alignment.getSequences()) {
+ for (AlignedCodonFrame acf : mappings) {
+ SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
+ if (dnaSeq != null)
+ {
+ /*
+ * There is a cDNA mapping for this protein sequence - add to new
+ * alignment. It will share the same dataset sequence as other mapped
+ * cDNA (no new mappings need to be created).
+ */
+ final Sequence newSeq = new Sequence(dnaSeq);
+ newSeq.setDatasetSequence(dnaSeq);
+ cdnaSeqs.add(newSeq);
+ }
+ }
+ }
+ if (cdnaSeqs.size() == 0)
+ {
+ // show a warning dialog no mapped cDNA
+ return;
+ }
+ AlignmentI cdna = new Alignment(cdnaSeqs.toArray(new SequenceI[cdnaSeqs
+ .size()]));
+ AlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+ cdna.alignAs(alignment);
+ String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
+ + this.title;
+ Desktop.addInternalFrame(alignFrame, newtitle,
+ AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+
}
}
*/
package jalview.gui;
+import jalview.analysis.AlignmentUtils;
+import jalview.analysis.AlignmentUtils.MappingResult;
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.analysis.NJTree;
import jalview.api.AlignViewportI;
import jalview.bin.Cache;
import jalview.commands.CommandI;
+import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.schemes.ColourSchemeProperty;
import jalview.schemes.UserColourScheme;
+import jalview.structure.CommandListener;
import jalview.structure.SelectionSource;
import jalview.structure.StructureSelectionManager;
import jalview.structure.VamsasSource;
+import jalview.util.MessageManager;
+import jalview.util.StringUtils;
import jalview.viewmodel.AlignmentViewport;
import jalview.ws.params.AutoCalcSetting;
import java.awt.Container;
import java.awt.Font;
import java.awt.Rectangle;
+import java.io.File;
+import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Deque;
import java.util.Hashtable;
-import java.util.Stack;
+import java.util.Set;
import java.util.Vector;
+import javax.swing.JInternalFrame;
+import javax.swing.JOptionPane;
+
/**
* DOCUMENT ME!
*
* @version $Revision: 1.141 $
*/
public class AlignViewport extends AlignmentViewport implements
- SelectionSource, VamsasSource, AlignViewportI
+ SelectionSource, VamsasSource, AlignViewportI, CommandListener
{
int startRes;
boolean gatherViewsHere = false;
- Stack<CommandI> historyList = new Stack<CommandI>();
+ private Deque<CommandI> historyList = new ArrayDeque<CommandI>();
- Stack<CommandI> redoList = new Stack<CommandI>();
+ private Deque<CommandI> redoList = new ArrayDeque<CommandI>();
int thresholdTextColour = 0;
return followSelection;
}
+ /**
+ * Send the current selection to be broadcast to any selection listeners.
+ */
public void sendSelection()
{
jalview.structure.StructureSelectionManager
{
AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(this
.getSequenceSetId());
- AlignmentPanel ap = null;
for (int p = 0; aps != null && p < aps.length; p++)
{
if (aps[p].av == this)
this.showAutocalculatedAbove = showAutocalculatedAbove;
}
+ /**
+ * Method called when another alignment's edit (or possibly other) command is
+ * broadcast to here.
+ *
+ * To allow for sequence mappings (e.g. protein to cDNA), we have to first
+ * 'unwind' the command on the source sequences (in simulation, not in fact),
+ * and then for each edit in turn:
+ * <ul>
+ * <li>compute the equivalent edit on the mapped sequences</li>
+ * <li>apply the mapped edit</li>
+ * <li>'apply' the source edit to the working copy of the source sequences</li>
+ * </ul>
+ *
+ * @param command
+ * @param undo
+ * @param ssm
+ */
+ @Override
+ public void mirrorCommand(CommandI command, boolean undo,
+ StructureSelectionManager ssm, VamsasSource source)
+ {
+ /*
+ * ...work in progress... do nothing unless we are a 'complement' of the
+ * source May replace this with direct calls not via SSM.
+ */
+ if (source instanceof AlignViewportI
+ && ((AlignViewportI) source).getCodingComplement() == this)
+ {
+ // ok to continue;
+ }
+ else
+ {
+ return;
+ }
+
+ CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(),
+ getGapCharacter());
+ if (mappedCommand != null)
+ {
+ AlignmentI[] views = getAlignPanel().alignFrame.getViewAlignments();
+ mappedCommand.doCommand(views);
+ getAlignPanel().alignmentChanged();
+ }
+ }
+
+ @Override
+ public VamsasSource getVamsasSource()
+ {
+ return this;
+ }
+
+ /**
+ * Add one command to the command history list.
+ *
+ * @param command
+ */
+ public void addToHistoryList(CommandI command)
+ {
+ if (this.historyList != null)
+ {
+ this.historyList.push(command);
+ broadcastCommand(command, false);
+ }
+ }
+
+ protected void broadcastCommand(CommandI command, boolean undo)
+ {
+ getStructureSelectionManager().commandPerformed(command, undo, getVamsasSource());
+ }
+
+ /**
+ * Add one command to the command redo list.
+ *
+ * @param command
+ */
+ public void addToRedoList(CommandI command)
+ {
+ if (this.redoList != null)
+ {
+ this.redoList.push(command);
+ }
+ broadcastCommand(command, true);
+ }
+
+ /**
+ * Clear the command redo list.
+ */
+ public void clearRedoList()
+ {
+ if (this.redoList != null)
+ {
+ this.redoList.clear();
+ }
+ }
+
+ public void setHistoryList(Deque<CommandI> list)
+ {
+ this.historyList = list;
+ }
+
+ public Deque<CommandI> getHistoryList()
+ {
+ return this.historyList;
+ }
+
+ public void setRedoList(Deque<CommandI> list)
+ {
+ this.redoList = list;
+ }
+
+ public Deque<CommandI> getRedoList()
+ {
+ return this.redoList;
+ }
+
+ /**
+ * Add the sequences from the given alignment to this viewport. Optionally,
+ * may give the user the option to open a new frame, or split panel, with cDNA
+ * and protein linked.
+ *
+ * @param al
+ * @param title
+ */
+ public void addAlignment(AlignmentI al, String title)
+ {
+ // TODO: promote to AlignViewportI? applet CutAndPasteTransfer is different
+
+ // refactored from FileLoader / CutAndPasteTransfer / SequenceFetcher with
+ // this comment:
+ // TODO: create undo object for this JAL-1101
+
+ /*
+ * If one alignment is protein and one nucleotide, with at least one
+ * sequence name in common, offer to open a linked alignment.
+ */
+ if (getAlignment().isNucleotide() != al.isNucleotide())
+ {
+ final Set<String> sequenceNames = getAlignment().getSequenceNames();
+ sequenceNames.retainAll(al.getSequenceNames());
+ if (!sequenceNames.isEmpty()) // at least one sequence name in both
+ {
+ if (openLinkedAlignment(al, title))
+ {
+ return;
+ }
+ }
+ }
+
+ for (int i = 0; i < al.getHeight(); i++)
+ {
+ getAlignment().addSequence(al.getSequenceAt(i));
+ }
+ // TODO this call was done by SequenceFetcher but not FileLoader or
+ // CutAndPasteTransfer. Is it needed?
+ setEndSeq(getAlignment().getHeight());
+ firePropertyChange("alignment", null, getAlignment().getSequences());
+ }
+
+ /**
+ * Show a dialog with the option to open and link (cDNA <-> protein) as a new
+ * alignment. Returns true if the new alignment was opened, false if not,
+ * because the user declined the offer.
+ *
+ * @param title
+ */
+ protected boolean openLinkedAlignment(AlignmentI al, String title)
+ {
+ String[] options = new String[]
+ { MessageManager.getString("action.no"),
+ MessageManager.getString("label.split_window"),
+ MessageManager.getString("label.new_window"), };
+ final String question = JvSwingUtils.wrapTooltip(true,
+ MessageManager.getString("label.open_linked_alignment?"));
+ int response = JOptionPane.showOptionDialog(Desktop.desktop, question,
+ MessageManager.getString("label.open_linked_alignment"),
+ JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
+ options, options[0]);
+
+ if (response != 1 && response != 2)
+ {
+ return false;
+ }
+ final boolean openSplitPane = (response == 1);
+ final boolean openInNewWindow = (response == 2);
+
+ /*
+ * Create the AlignFrame first (which creates the new alignment's datasets),
+ * before attempting sequence mapping.
+ */
+ AlignFrame newAlignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+ newAlignFrame.setTitle(title);
+
+ /*
+ * Identify protein and dna alignments. Make a copy of this one if opening
+ * in a new split pane.
+ */
+ AlignmentI thisAlignment = openSplitPane ? new Alignment(getAlignment())
+ : getAlignment();
+ AlignmentI protein = al.isNucleotide() ? thisAlignment : al;
+ final AlignmentI cdna = al.isNucleotide() ? al : thisAlignment;
+
+ newAlignFrame.statusBar.setText(MessageManager.formatMessage(
+ "label.successfully_loaded_file", new Object[]
+ { title }));
+
+ // TODO if we want this (e.g. to enable reload of the alignment from file),
+ // we will need to add parameters to the stack.
+ // if (!protocol.equals(AppletFormatAdapter.PASTE))
+ // {
+ // alignFrame.setFileName(file, format);
+ // }
+
+ if (openInNewWindow)
+ {
+ Desktop.addInternalFrame(newAlignFrame, title,
+ AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+ }
+
+ /*
+ * Try to find mappings for at least one sequence. Any mappings made will be
+ * added to the protein alignment.
+ */
+ MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, cdna);
+ final StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(Desktop.instance);
+ if (mapped != MappingResult.Mapped)
+ {
+ /*
+ * No mapping possible - warn the user, but leave window open.
+ */
+ final String msg = JvSwingUtils.wrapTooltip(true,
+ MessageManager.getString("label.mapping_failed"));
+ JOptionPane.showInternalMessageDialog(Desktop.desktop, msg,
+ MessageManager.getString("label.no_mappings"),
+ JOptionPane.WARNING_MESSAGE);
+ }
+
+ try
+ {
+ newAlignFrame.setMaximum(jalview.bin.Cache.getDefault(
+ "SHOW_FULLSCREEN",
+ false));
+ } catch (java.beans.PropertyVetoException ex)
+ {
+ }
+
+ if (openSplitPane)
+ {
+ /*
+ * Open in split pane. DNA sequence above, protein below.
+ */
+ AlignFrame copyMe = new AlignFrame(thisAlignment,
+ AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+ copyMe.setTitle(getAlignPanel().alignFrame.getTitle());
+ final AlignFrame proteinFrame = al.isNucleotide() ? copyMe
+ : newAlignFrame;
+ final AlignFrame cdnaFrame = al.isNucleotide() ? newAlignFrame
+ : copyMe;
+ protein = proteinFrame.viewport.getAlignment();
+
+ cdnaFrame.setVisible(true);
+ proteinFrame.setVisible(true);
+ String sep = String.valueOf(File.separatorChar);
+ String proteinShortName = StringUtils.getLastToken(
+ proteinFrame.getTitle(), sep);
+ String dnaShortName = StringUtils.getLastToken(cdnaFrame.getTitle(),
+ sep);
+ String linkedTitle = MessageManager.formatMessage(
+ "label.linked_view_title", dnaShortName, proteinShortName);
+ JInternalFrame splitFrame = new SplitFrame(cdnaFrame, proteinFrame);
+ Desktop.addInternalFrame(splitFrame, linkedTitle,
+ AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+
+ /*
+ * Set the frames to listen for each other's edit and sort commands.
+ */
+ ssm.addCommandListener(cdnaFrame.getViewport());
+ ssm.addCommandListener(proteinFrame.getViewport());
+
+ /*
+ * 'Coding complement' (dna/protein) views will mirror each others' edits,
+ * selections, sorting etc as decided from time to time by the relevant
+ * authorities.
+ */
+ proteinFrame.getViewport().setCodingComplement(cdnaFrame.getViewport());
+ }
+
+ /*
+ * Register the mappings (held on the protein alignment) with the
+ * StructureSelectionManager (for mouseover linking).
+ */
+ ssm.addMappings(protein.getCodonFrames());
+
+ return true;
+ }
+
public AnnotationColumnChooser getAnnotationColumnSelectionState()
{
return annotationColumnSelectionState;
* Creates a new AlignmentPanel object.
*
* @param af
- * DOCUMENT ME!
* @param av
- * DOCUMENT ME!
*/
public AlignmentPanel(AlignFrame af, final AlignViewport av)
{
*/
public void adjustmentValueChanged(AdjustmentEvent evt)
{
-
int oldX = av.getStartRes();
int oldY = av.getStartSeq();
if (alignFrame != null && !headless)
{
alignFrame.setProgressBar(MessageManager.formatMessage(
- "status.saving_file",
- new String[]
+ "status.saving_file", new Object[]
{ type.getLabel() }), progress);
}
try
.getStructureSelectionManager();
ssm.removeStructureViewerListener(getSeqPanel(), null);
ssm.removeSelectionListener(getSeqPanel());
+ ssm.removeEditListener(av);
+ ssm.removeStructureViewerListener(getSeqPanel(), null);
+ ssm.removeSelectionListener(getSeqPanel());
av.setAlignment(null);
av = null;
}
pop.addSeparator();
// av and sequencegroup need to implement same interface for
final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(
- MessageManager.getString("label.ignore_gaps_consensus"),
+ MessageManager.getString("label.ignore_gaps_consensus"),
(aa[selectedRow].groupRef != null) ? aa[selectedRow].groupRef
.getIgnoreGapsConsensus() : ap.av
.getIgnoreGapsConsensus());
if (aaa.groupRef != null)
{
final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
- MessageManager.getString("label.show_group_histogram"),
+ MessageManager.getString("label.show_group_histogram"),
aa[selectedRow].groupRef.isShowConsensusHistogram());
chist.addActionListener(new ActionListener()
{
});
pop.add(chist);
final JCheckBoxMenuItem cprofl = new JCheckBoxMenuItem(
- MessageManager.getString("label.show_group_logo"),
+ MessageManager.getString("label.show_group_logo"),
aa[selectedRow].groupRef.isShowSequenceLogo());
cprofl.addActionListener(new ActionListener()
{
});
pop.add(cprofl);
final JCheckBoxMenuItem cproflnorm = new JCheckBoxMenuItem(
- MessageManager.getString("label.normalise_group_logo"),
+ MessageManager.getString("label.normalise_group_logo"),
aa[selectedRow].groupRef.isNormaliseSequenceLogo());
cproflnorm.addActionListener(new ActionListener()
{
else
{
final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
- MessageManager.getString("label.show_histogram"), av.isShowConsensusHistogram());
+ MessageManager.getString("label.show_histogram"), av.isShowConsensusHistogram());
chist.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
});
pop.add(chist);
final JCheckBoxMenuItem cprof = new JCheckBoxMenuItem(
- MessageManager.getString("label.show_logo"), av.isShowSequenceLogo());
+ MessageManager.getString("label.show_logo"), av.isShowSequenceLogo());
cprof.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
});
pop.add(cprof);
final JCheckBoxMenuItem cprofnorm = new JCheckBoxMenuItem(
- MessageManager.getString("label.normalise_logo"), av.isNormaliseSequenceLogo());
+ MessageManager.getString("label.normalise_logo"), av.isNormaliseSequenceLogo());
cprofnorm.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
*/
package jalview.gui;
+import jalview.structure.AtomSpec;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
public void onWarningEmitted(String s)
{
- // TODO Auto-generated method stub
-
}
public void mouseClicked(MouseEvent e)
public void mouseEntered(MouseEvent arg0)
{
- // TODO Auto-generated method stub
-
}
public void mouseExited(MouseEvent arg0)
{
- // TODO Auto-generated method stub
-
}
public void mousePressed(MouseEvent arg0)
{
- // TODO Auto-generated method stub
-
}
public void mouseReleased(MouseEvent arg0)
{
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public Color getColour(int atomIndex, int pdbResNum, String chain,
- String pdbId)
- {
- // TODO Auto-generated method stub
- return null;
}
@Override
public String[] getPdbFile()
{
- // TODO Auto-generated method stub
return null;
}
@Override
- public void highlightAtom(int atomIndex, int pdbResNum, String chain,
- String pdbId)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void mouseOverStructure(int atomIndex, String strInfo)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
public void releaseReferences(Object svl)
{
- // TODO Auto-generated method stub
-
}
@Override
public void updateColours(Object source)
{
- // TODO Auto-generated method stub
-
}
@Override
public void componentHidden(ComponentEvent e)
{
- // TODO Auto-generated method stub
-
}
@Override
public void componentMoved(ComponentEvent e)
{
- // TODO Auto-generated method stub
-
}
@Override
public void componentResized(ComponentEvent e)
{
- // TODO Auto-generated method stub
-
}
@Override
public void componentShown(ComponentEvent e)
{
- // TODO Auto-generated method stub
-
}
@Override
public void onStructureRedrawn()
{
- // TODO Auto-generated method stub
-
}
@Override
public void onZoomLevelChanged()
{
- // TODO Auto-generated method stub
-
}
@Override
public void onTranslationChanged()
{
- // TODO Auto-generated method stub
+ }
+ @Override
+ public void highlightAtoms(List<AtomSpec> atoms)
+ {
}
}
-
-/*
- * public static void main(String[] args) { JTextField str = new
- * JTextField("ATGC");
- *
- * AppVarnaBinding vab = new AppVarnaBinding(); vab.varnagui.set_seq(str);
- * vab.varnagui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- * vab.varnagui.pack(); vab.varnagui.setVisible(true); } }
- */
import jalview.io.*;
import jalview.jbgui.*;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
/**
* Cut'n'paste files into the desktop See JAL-1105
public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer
{
- AlignViewport viewport;
+ AlignmentViewport viewport;
public CutAndPasteHtmlTransfer()
{
/**
* DOCUMENT ME!
*/
- public void setForInput(AlignViewport viewport)
+ public void setForInput(AlignmentViewport viewport)
{
this.viewport = viewport;
if (viewport != null)
*/
package jalview.gui;
-import java.awt.*;
-import java.awt.datatransfer.*;
-import java.awt.event.*;
-import javax.swing.*;
-
-import jalview.datamodel.*;
-import jalview.io.*;
-import jalview.jbgui.*;
+import jalview.datamodel.Alignment;
+import jalview.io.FormatAdapter;
+import jalview.io.IdentifyFile;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.jbgui.GCutAndPasteTransfer;
import jalview.util.MessageManager;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
+
/**
* Cut'n'paste files into the desktop See JAL-1105
*
if (al != null)
{
+ String title = MessageManager.formatMessage(
+ "label.input_cut_paste_params", new String[]
+ { format });
if (viewport != null)
{
- for (int i = 0; i < al.getHeight(); i++)
- {
- viewport.getAlignment().addSequence(al.getSequenceAt(i));
- }
-
- viewport.firePropertyChange("alignment", null, viewport
- .getAlignment().getSequences());
+ viewport.addAlignment(al, title);
}
else
{
AlignFrame af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
af.currentFileFormat = format;
- Desktop.addInternalFrame(af, MessageManager.formatMessage(
- "label.input_cut_paste_params", new String[]
- { format }), AlignFrame.DEFAULT_WIDTH,
+ Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
af.statusBar.setText(MessageManager
.getString("label.successfully_pasted_alignment_file"));
import jalview.structure.StructureSelectionManager;
import jalview.util.ImageMaker;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import jalview.ws.params.ParamManager;
import java.awt.BorderLayout;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
static final int yOffset = 30;
+ private static final int THREE = 3;
+
public static jalview.ws.jws1.Discoverer discoverer;
public static Object[] jalviewClipboard;
if (format.equals("URL NOT FOUND"))
{
JOptionPane.showInternalMessageDialog(Desktop.desktop,
- MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
+ MessageManager.formatMessage("label.couldnt_locate",
+ new Object[]
+ { url }), MessageManager
+ .getString("label.url_not_found"),
JOptionPane.WARNING_MESSAGE);
return;
return;
}
- AlignViewport source = null, target = null;
+ AlignmentViewport source = null, target = null;
if (frames[0] instanceof AlignFrame)
{
source = ((AlignFrame) frames[0]).getCurrentView();
public void run()
{
- setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
+ setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new Object[]{choice.getName()}),
choice.hashCode());
jalview.bin.Cache.setProperty("LAST_DIRECTORY",
choice.getParent());
ex);
JOptionPane.showMessageDialog(
me,
- MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
+ MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new Object[]{ choice.getName()}),
MessageManager.getString("label.couldnt_save_project"),
JOptionPane.WARNING_MESSAGE);
}
{
public void run()
{
- setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
+ setProgressBar(MessageManager.formatMessage(
+ "label.loading_jalview_project", new Object[]
+ { choice }),
choice.hashCode());
try
{
Cache.log.error("Problems whilst loading project from "
+ choice, ex);
JOptionPane.showMessageDialog(Desktop.desktop,
- MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
+ MessageManager
+ .formatMessage(
+ "label.error_whilst_loading_project_from",
+ new Object[]
+ { choice }),
MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
}
setProgressBar(null, choice.hashCode());
{
if (fileLoadingCount == 0)
{
- fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
+ fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
+ "label.loading_file", new Object[]
+ { fileName })));
}
fileLoadingCount++;
}
public static int getViewCount(String alignmentId)
{
- AlignViewport[] aps = getViewports(alignmentId);
+ AlignmentViewport[] aps = getViewports(alignmentId);
return (aps == null) ? 0 : aps.length;
}
*/
public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
{
- int count = 0;
if (Desktop.desktop == null)
{
// no frames created and in headless mode
// TODO: verify that frames are recoverable when in headless mode
return null;
}
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
- ArrayList aps = new ArrayList();
- for (int t = 0; t < frames.length; t++)
+ List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
+ AlignFrame[] frames = getAlignFrames();
+ if (frames == null)
{
- if (frames[t] instanceof AlignFrame)
+ return null;
+ }
+ for (AlignFrame af : frames)
+ {
+ for (AlignmentPanel ap : af.alignPanels)
{
- AlignFrame af = (AlignFrame) frames[t];
- for (int a = 0; a < af.alignPanels.size(); a++)
+ if (alignmentId.equals(ap.av.getSequenceSetId()))
{
- if (alignmentId.equals(((AlignmentPanel) af.alignPanels
- .elementAt(a)).av.getSequenceSetId()))
- {
- aps.add(af.alignPanels.elementAt(a));
- }
+ aps.add(ap);
}
}
+ // for (int a = 0; a < af.alignPanels.size(); a++)
+ // {
+ // if (alignmentId.equals(af.alignPanels
+ // .get(a).av.getSequenceSetId()))
+ // {
+ // aps.add(af.alignPanels.get(a));
+ // }
+ // }
}
if (aps.size() == 0)
{
return null;
}
- AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
- for (int t = 0; t < vap.length; t++)
- {
- vap[t] = (AlignmentPanel) aps.get(t);
- }
+ AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
return vap;
}
* unique alignment id
* @return all viewports on the alignment bound to sequenceSetId
*/
- public static AlignViewport[] getViewports(String sequenceSetId)
+ public static AlignmentViewport[] getViewports(String sequenceSetId)
{
- Vector viewp = new Vector();
+ List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
if (desktop != null)
{
- javax.swing.JInternalFrame[] frames = instance.getAllFrames();
+ AlignFrame[] frames = Desktop.getAlignFrames();
- for (int t = 0; t < frames.length; t++)
+ for (AlignFrame afr : frames)
{
- if (frames[t] instanceof AlignFrame)
+ if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
{
- AlignFrame afr = ((AlignFrame) frames[t]);
- if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
+ if (afr.alignPanels != null)
{
- if (afr.alignPanels != null)
+ for (AlignmentPanel ap : afr.alignPanels)
{
- for (int a = 0; a < afr.alignPanels.size(); a++)
+ if (sequenceSetId.equals(ap.av.getSequenceSetId()))
{
- if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
- .elementAt(a)).av.getSequenceSetId()))
- {
- viewp.addElement(((AlignmentPanel) afr.alignPanels
- .elementAt(a)).av);
- }
+ viewp.add(ap.av);
}
}
- else
- {
- viewp.addElement(((AlignFrame) frames[t]).getViewport());
- }
+ }
+ else
+ {
+ viewp.add(afr.getViewport());
}
}
}
if (viewp.size() > 0)
{
- AlignViewport[] vp = new AlignViewport[viewp.size()];
- viewp.copyInto(vp);
- return vp;
+ return viewp.toArray(new AlignmentViewport[viewp.size()]);
}
}
return null;
for (int i = 0; i < size; i++)
{
- AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
+ AlignmentPanel ap = af.alignPanels.get(i);
AlignFrame newaf = new AlignFrame(ap);
if (ap.av.explodedPosition != null
&& !ap.av.explodedPosition.equals(af.getBounds()))
boolean gatherThis = false;
for (int a = 0; a < af.alignPanels.size(); a++)
{
- AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
+ AlignmentPanel ap = af.alignPanels.get(a);
if (viewId.equals(ap.av.getSequenceSetId()))
{
gatherThis = true;
Desktop.desktop,
MessageManager.formatMessage(
"label.couldnt_import_as_vamsas_session",
- new String[]
+ new Object[]
{ fle }),
MessageManager
.getString("label.vamsas_document_import_failed"),
return false;
}
- setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
+ setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
file.hashCode());
try
{
v_client = new jalview.gui.VamsasApplication(this, file, null);
} catch (Exception ex)
{
- setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
+ setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
file.hashCode());
jalview.bin.Cache.log.error(
"New vamsas session from existing session file failed:", ex);
}
setupVamsasConnectedGui();
v_client.initial_update(); // TODO: thread ?
- setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
+ setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
file.hashCode());
return v_client.inSession();
}
JMenuItem sessit = new JMenuItem();
sessit.setText(sess[i]);
sessit.setToolTipText(MessageManager.formatMessage(
- "label.connect_to_session", new String[]
+ "label.connect_to_session", new Object[]
{ sess[i] }));
final Desktop dsktp = this;
final String mysesid = sess[i];
if (value == JalviewFileChooser.APPROVE_OPTION)
{
java.io.File choice = chooser.getSelectedFile();
- JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
+ JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new Object[]{choice.getName()}));
jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
String warnmsg = null;
String warnttl = null;
public class MyDesktopPane extends JDesktopPane implements Runnable
{
+ private static final float ONE_MB = 1048576f;
+
boolean showMemoryUsage = false;
Runtime runtime;
{
try
{
- maxMemory = runtime.maxMemory() / 1048576f;
- allocatedMemory = runtime.totalMemory() / 1048576f;
- freeMemory = runtime.freeMemory() / 1048576f;
+ maxMemory = runtime.maxMemory() / ONE_MB;
+ allocatedMemory = runtime.totalMemory() / ONE_MB;
+ freeMemory = runtime.freeMemory() / ONE_MB;
totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
percentUsage = (totalFreeMemory / maxMemory) * 100;
{
g.drawString(MessageManager.formatMessage(
"label.memory_stats",
- new String[]
+ new Object[]
{ df.format(totalFreeMemory), df.format(maxMemory),
df.format(percentUsage) }), 10,
getHeight() - fm.getHeight());
/**
* Accessor method to quickly get all the AlignmentFrames loaded.
+ *
+ * @return an array of AlignFrame, or null if none found
*/
- public static AlignFrame[] getAlignframes()
+ public static AlignFrame[] getAlignFrames()
{
JInternalFrame[] frames = Desktop.desktop.getAllFrames();
{
return null;
}
- Vector avp = new Vector();
- try
+ List<AlignFrame> avp = new ArrayList<AlignFrame>();
+ // REVERSE ORDER
+ for (int i = frames.length - 1; i > -1; i--)
{
- // REVERSE ORDER
- for (int i = frames.length - 1; i > -1; i--)
+ if (frames[i] instanceof AlignFrame)
{
- if (frames[i] instanceof AlignFrame)
+ avp.add((AlignFrame) frames[i]);
+ }
+ else if (frames[i] instanceof SplitFrame)
+ {
+ /*
+ * Also check for a split frame containing an AlignFrame
+ */
+ SplitFrame sf = (SplitFrame) frames[i];
+ if (sf.getTopComponent() instanceof AlignFrame)
{
- AlignFrame af = (AlignFrame) frames[i];
- avp.addElement(af);
+ avp.add((AlignFrame) sf.getTopComponent());
+ }
+ if (sf.getBottomComponent() instanceof AlignFrame)
+ {
+ avp.add((AlignFrame) sf.getBottomComponent());
}
}
- } catch (Exception ex)
- {
- ex.printStackTrace();
}
if (avp.size() == 0)
{
return null;
}
- AlignFrame afs[] = new AlignFrame[avp.size()];
- for (int i = 0, j = avp.size(); i < j; i++)
- {
- afs[i] = (AlignFrame) avp.elementAt(i);
- }
- avp.clear();
+ AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
return afs;
}
+ /**
+ * Returns an array of any AppJmol frames in the Desktop (or null if none).
+ *
+ * @return
+ */
public GStructureViewer[] getJmols()
{
JInternalFrame[] frames = Desktop.desktop.getAllFrames();
{
return null;
}
- Vector avp = new Vector();
- try
+ List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
+ // REVERSE ORDER
+ for (int i = frames.length - 1; i > -1; i--)
{
- // REVERSE ORDER
- for (int i = frames.length - 1; i > -1; i--)
+ if (frames[i] instanceof AppJmol)
{
- if (frames[i] instanceof AppJmol)
- {
- GStructureViewer af = (GStructureViewer) frames[i];
- avp.addElement(af);
- }
+ GStructureViewer af = (GStructureViewer) frames[i];
+ avp.add(af);
}
- } catch (Exception ex)
- {
- ex.printStackTrace();
}
if (avp.size() == 0)
{
return null;
}
- GStructureViewer afs[] = new GStructureViewer[avp.size()];
- for (int i = 0, j = avp.size(); i < j; i++)
- {
- afs[i] = (GStructureViewer) avp.elementAt(i);
- }
- avp.clear();
+ GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
return afs;
}
public void actionPerformed(ActionEvent e)
{
handler.cancelActivity(id);
- us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
+ us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new Object[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
}
});
progressPanel.add(cancel, BorderLayout.EAST);
/**
* This will return the first AlignFrame viewing AlignViewport av. It will
- * break if there are more than one AlignFrames viewing a particular av. This
+ * break if there are more than one AlignFrames viewing a particular av.
*
* @param av
* @return alignFrame for av
*/
- public static AlignFrame getAlignFrameFor(AlignViewport av)
+ public static AlignFrame getAlignFrameFor(AlignmentViewport av)
{
if (desktop != null)
{
{
if (progress != null)
{
- progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
+ progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new Object[]{url}), this.hashCode());
}
jalview.util.BrowserLauncher.openURL(url);
} catch (Exception ex)
import jalview.schemes.AnnotationColourGradient;
import jalview.schemes.GraduatedColor;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import jalview.ws.dbsources.das.api.jalviewSourceI;
import java.awt.BorderLayout;
{
SequenceI[] dataset, seqs;
int iSize;
- AlignViewport vp = af.getViewport();
+ AlignmentViewport vp = af.getViewport();
if (vp.getSelectionGroup() != null
&& vp.getSelectionGroup().getSize() > 0)
{
*/
package jalview.gui;
-import java.awt.*;
-import java.awt.image.*;
+import jalview.datamodel.SequenceI;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
import java.util.List;
-import javax.swing.*;
-
-import jalview.datamodel.*;
+import javax.swing.JPanel;
/**
* DOCUMENT ME!
{
selectSeq(seq);
}
+ // TODO is this addition ok here?
+ av.isSelectionGroupChanged(true);
+
alignPanel.paintAlignment(true);
}
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
+import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.StructureViewerModel;
import jalview.datamodel.StructureViewerModel.StructureData;
import jalview.schemabinding.version2.AlcodMap;
-import jalview.schemabinding.version2.Alcodon;
import jalview.schemabinding.version2.AlcodonFrame;
import jalview.schemabinding.version2.Annotation;
import jalview.schemabinding.version2.AnnotationColours;
*/
public void saveState(JarOutputStream jout)
{
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ AlignFrame[] frames = Desktop.getAlignFrames(); // Desktop.desktop.getAllFrames();
if (frames == null)
{
// REVERSE ORDER
for (int i = frames.length - 1; i > -1; i--)
{
- if (frames[i] instanceof AlignFrame)
+ AlignFrame af = frames[i];
+ // skip ?
+ if (skipList != null
+ && skipList
+ .containsKey(af.getViewport().getSequenceSetId()))
{
- AlignFrame af = (AlignFrame) frames[i];
- // skip ?
- if (skipList != null
- && skipList.containsKey(af.getViewport()
- .getSequenceSetId()))
- {
- continue;
- }
+ continue;
+ }
+
+ String shortName = af.getTitle();
- String shortName = af.getTitle();
+ if (shortName.indexOf(File.separatorChar) > -1)
+ {
+ shortName = shortName.substring(shortName
+ .lastIndexOf(File.separatorChar) + 1);
+ }
+
+ int count = 1;
- if (shortName.indexOf(File.separatorChar) > -1)
+ while (shortNames.contains(shortName))
+ {
+ if (shortName.endsWith("_" + (count - 1)))
{
- shortName = shortName.substring(shortName
- .lastIndexOf(File.separatorChar) + 1);
+ shortName = shortName.substring(0, shortName.lastIndexOf("_"));
}
- int count = 1;
+ shortName = shortName.concat("_" + count);
+ count++;
+ }
- while (shortNames.contains(shortName))
- {
- if (shortName.endsWith("_" + (count - 1)))
- {
- shortName = shortName
- .substring(0, shortName.lastIndexOf("_"));
- }
+ shortNames.addElement(shortName);
- shortName = shortName.concat("_" + count);
- count++;
- }
+ if (!shortName.endsWith(".xml"))
+ {
+ shortName = shortName + ".xml";
+ }
- shortNames.addElement(shortName);
+ int ap, apSize = af.alignPanels.size();
- if (!shortName.endsWith(".xml"))
+ for (ap = 0; ap < apSize; ap++)
+ {
+ AlignmentPanel apanel = af.alignPanels.get(ap);
+ String fileName = apSize == 1 ? shortName : ap + shortName;
+ if (!fileName.endsWith(".xml"))
{
- shortName = shortName + ".xml";
+ fileName = fileName + ".xml";
}
- int ap, apSize = af.alignPanels.size();
+ saveState(apanel, fileName, jout);
- for (ap = 0; ap < apSize; ap++)
+ String dssid = getDatasetIdRef(af.getViewport().getAlignment()
+ .getDataset());
+ if (!dsses.containsKey(dssid))
{
- AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
- .elementAt(ap);
- String fileName = apSize == 1 ? shortName : ap + shortName;
- if (!fileName.endsWith(".xml"))
- {
- fileName = fileName + ".xml";
- }
-
- saveState(apanel, fileName, jout);
-
- String dssid = getDatasetIdRef(af.getViewport().getAlignment()
- .getDataset());
- if (!dsses.containsKey(dssid))
- {
- dsses.put(dssid, af);
- }
-
+ dsses.put(dssid, af);
}
}
}
{
try
{
- int ap, apSize = af.alignPanels.size();
+ int ap = 0;
+ int apSize = af.alignPanels.size();
FileOutputStream fos = new FileOutputStream(jarFile);
JarOutputStream jout = new JarOutputStream(fos);
Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
- for (ap = 0; ap < apSize; ap++)
+ for (AlignmentPanel apanel : af.alignPanels)
{
- AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
- .elementAt(ap);
String jfileName = apSize == 1 ? fileName : fileName + ap;
+ ap++;
if (!jfileName.endsWith(".xml"))
{
jfileName = jfileName + ".xml";
{
byte[] data = new byte[(int) file.length()];
jout.putNextEntry(new JarEntry(entry.getId()));
- dis = new DataInputStream(
- new FileInputStream(file));
+ dis = new DataInputStream(new FileInputStream(file));
dis.readFully(data);
DataOutputStream dout = new DataOutputStream(jout);
jal = av.getAlignment();
}
// SAVE MAPPINGS
- if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
+ if (jal.getCodonFrames() != null)
{
- jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
- for (int i = 0; i < jac.length; i++)
+ Set<AlignedCodonFrame> jac = jal.getCodonFrames();
+ for (AlignedCodonFrame acf : jac)
{
AlcodonFrame alc = new AlcodonFrame();
vamsasSet.addAlcodonFrame(alc);
- for (int p = 0; p < jac[i].aaWidth; p++)
- {
- Alcodon cmap = new Alcodon();
- if (jac[i].codons[p] != null)
- {
- // Null codons indicate a gapped column in the translated peptide
- // alignment.
- cmap.setPos1(jac[i].codons[p][0]);
- cmap.setPos2(jac[i].codons[p][1]);
- cmap.setPos3(jac[i].codons[p][2]);
- }
- alc.addAlcodon(cmap);
- }
- if (jac[i].getProtMappings() != null
- && jac[i].getProtMappings().length > 0)
+ if (acf.getProtMappings() != null
+ && acf.getProtMappings().length > 0)
{
- SequenceI[] dnas = jac[i].getdnaSeqs();
- jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
+ SequenceI[] dnas = acf.getdnaSeqs();
+ jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
for (int m = 0; m < pmaps.length; m++)
{
AlcodMap alcmap = new AlcodMap();
alc.addAlcodMap(alcmap);
}
}
+
+// {
+// AlcodonFrame alc = new AlcodonFrame();
+// vamsasSet.addAlcodonFrame(alc);
+// for (int p = 0; p < acf.aaWidth; p++)
+// {
+// Alcodon cmap = new Alcodon();
+// if (acf.codons[p] != null)
+// {
+// // Null codons indicate a gapped column in the translated peptide
+// // alignment.
+// cmap.setPos1(acf.codons[p][0]);
+// cmap.setPos2(acf.codons[p][1]);
+// cmap.setPos3(acf.codons[p][2]);
+// }
+// alc.addAlcodon(cmap);
+// }
+// if (acf.getProtMappings() != null
+// && acf.getProtMappings().length > 0)
+// {
+// SequenceI[] dnas = acf.getdnaSeqs();
+// jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
+// for (int m = 0; m < pmaps.length; m++)
+// {
+// AlcodMap alcmap = new AlcodMap();
+// alcmap.setDnasq(seqHash(dnas[m]));
+// alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
+// false));
+// alc.addAlcodMap(alcmap);
+// }
+// }
}
}
{
jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
- String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
- .getRenderOrder().toArray(new String[0]);
+ String[] renderOrder = ap.getSeqPanel().seqCanvas
+ .getFeatureRenderer().getRenderOrder()
+ .toArray(new String[0]);
Vector settingsAdded = new Vector();
Object gstyle = null;
}
else
{
- setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer()
+ setting.setColour(ap.getSeqPanel().seqCanvas
+ .getFeatureRenderer()
.getColour(renderOrder[ro]).getRGB());
}
settingsAdded.addElement(key);
}
// is groups actually supposed to be a map here ?
- en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().getFeatureGroups()
- .iterator();
+ en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
+ .getFeatureGroups().iterator();
Vector groupsAdded = new Vector();
while (en.hasNext())
{
for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
.size(); c++)
{
- int[] region = av.getColumnSelection()
- .getHiddenColumns().get(c);
+ int[] region = av.getColumnSelection().getHiddenColumns()
+ .get(c);
HiddenColumns hc = new HiddenColumns();
hc.setStart(region[0]);
hc.setEnd(region[1]);
Pdbids pdb, PDBEntry entry, List<String> viewIds,
String matchedFile, StructureViewerBase viewFrame)
{
- final AAStructureBindingModel bindingModel = viewFrame
- .getBinding();
- for (int peid = 0; peid < bindingModel
- .getPdbCount(); peid++)
+ final AAStructureBindingModel bindingModel = viewFrame.getBinding();
+ for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
{
final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
final String pdbId = pdbentry.getId();
if (!pdbId.equals(entry.getId())
&& !(entry.getId().length() > 4 && entry.getId()
- .toLowerCase()
- .startsWith(pdbId.toLowerCase())))
+ .toLowerCase().startsWith(pdbId.toLowerCase())))
{
continue;
}
{
matchedFile = pdbentry.getFile();
}
- else if (!matchedFile.equals(pdbentry
- .getFile()))
+ else if (!matchedFile.equals(pdbentry.getFile()))
{
Cache.log
.warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
// 1QIP==1qipA)
String statestring = viewFrame.getStateInfo();
- for (int smap = 0; smap < viewFrame.getBinding()
- .getSequence()[peid].length; smap++)
+ for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
{
// if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
if (jds == viewFrame.getBinding().getSequence()[peid][smap])
final String viewId = viewFrame.getViewId();
state.setViewId(viewId);
state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
- state.setColourwithAlignPanel(viewFrame
- .isUsedforcolourby(ap));
+ state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
state.setColourByJmol(viewFrame.isColouredByViewer());
/*
* Only store each structure viewer's state once in each XML document.
return false;
}
}
- throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
+ throw new Error(MessageManager.formatMessage(
+ "error.unsupported_version_calcIdparam", new String[]
+ { calcIdParam.toString() }));
}
/**
}
}
StructureSelectionManager.getStructureSelectionManager(
- Desktop.instance)
- .registerPDBEntry(entry);
+ Desktop.instance).registerPDBEntry(entry);
al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
}
}
AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
for (int i = 0; i < alc.length; i++)
{
- jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
- alc[i].getAlcodonCount());
- if (alc[i].getAlcodonCount() > 0)
- {
- Alcodon[] alcods = alc[i].getAlcodon();
- for (int p = 0; p < cf.codons.length; p++)
- {
- if (alcods[p].hasPos1() && alcods[p].hasPos2()
- && alcods[p].hasPos3())
- {
- // translated codons require three valid positions
- cf.codons[p] = new int[3];
- cf.codons[p][0] = (int) alcods[p].getPos1();
- cf.codons[p][1] = (int) alcods[p].getPos2();
- cf.codons[p][2] = (int) alcods[p].getPos3();
- }
- else
- {
- cf.codons[p] = null;
- }
- }
- }
+ AlignedCodonFrame cf = new AlignedCodonFrame();
if (alc[i].getAlcodMapCount() > 0)
{
AlcodMap[] maps = alc[i].getAlcodMap();
for (int m = 0; m < maps.length; m++)
{
- SequenceI dnaseq = seqRefIds
- .get(maps[m].getDnasq());
+ SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
// Load Mapping
jalview.datamodel.Mapping mapping = null;
// attach to dna sequence reference.
}
al.addCodonFrame(cf);
}
-
}
// ////////////////////////////////
for (int s = 0; s < groups[i].getSeqCount(); s++)
{
String seqId = groups[i].getSeq(s) + "";
- jalview.datamodel.SequenceI ts = seqRefIds
- .get(seqId);
+ jalview.datamodel.SequenceI ts = seqRefIds.get(seqId);
if (ts != null)
{
for (int s = 0; s < structureStateCount; s++)
{
// check to see if we haven't already created this structure view
- final StructureState structureState = ids[p].getStructureState(s);
+ final StructureState structureState = ids[p]
+ .getStructureState(s);
String sviewid = (structureState.getViewId() == null) ? null
- : structureState.getViewId()
- + uniqueSetSuffix;
+ : structureState.getViewId() + uniqueSetSuffix;
jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
// Originally : ids[p].getFile()
// : TODO: verify external PDB file recovery still works in normal
// Desktop.desktop.getComponentAt(x, y);
// TODO: NOW: check that this recovers the PDB file correctly.
String pdbFile = loadPDBFile(jprovider, ids[p].getId());
- jalview.datamodel.SequenceI seq = seqRefIds
- .get(jseqs[i].getId() + "");
+ jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
+ .getId() + "");
if (sviewid == null)
{
sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
}
if (!structureViewers.containsKey(sviewid))
{
- structureViewers.put(sviewid, new StructureViewerModel(x, y, width, height,
- false, false, true));
+ structureViewers.put(sviewid, new StructureViewerModel(x, y,
+ width, height, false, false, true));
// Legacy pre-2.7 conversion JAL-823 :
// do not assume any view has to be linked for colour by
// sequence
* pre-2.7 projects)
*/
boolean colourByViewer = jmoldat.isColourByViewer();
- colourByViewer &= structureState
- .hasColourByJmol() ? structureState
+ colourByViewer &= structureState.hasColourByJmol() ? structureState
.getColourByJmol() : true;
jmoldat.setColourByViewer(colourByViewer);
}
}
}
- // Instantiate the associated structure views
- for (Entry<String, StructureViewerModel> entry : structureViewers.entrySet())
+ // Instantiate the associated structure views
+ for (Entry<String, StructureViewerModel> entry : structureViewers
+ .entrySet())
{
- createOrLinkStructureViewer(entry, af, ap);
- }
+ createOrLinkStructureViewer(entry, af, ap);
+ }
}
/**
* @param viewerData
* @param af
*/
- protected void createChimeraViewer(Entry<String, StructureViewerModel> viewerData,
- AlignFrame af)
+ protected void createChimeraViewer(
+ Entry<String, StructureViewerModel> viewerData, AlignFrame af)
{
final StructureViewerModel data = viewerData.getValue();
String chimeraSession = data.getStateData();
boolean colourBySequence = data.isColourWithAlignPanel();
// TODO can/should this be done via StructureViewer (like Jmol)?
- final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs
- .size()]);
- final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs.size()][]);
+ final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
+ final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
+ .size()][]);
new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray,
- seqsArray,
- colourByChimera, colourBySequence);
+ seqsArray, colourByChimera, colourBySequence);
}
else
{
* @param af
*/
protected void createJmolViewer(
- final Entry<String, StructureViewerModel> viewerData, AlignFrame af)
+ final Entry<String, StructureViewerModel> viewerData,
+ AlignFrame af)
{
final StructureViewerModel svattrib = viewerData.getValue();
String state = svattrib.getStateData();
newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
pdbfilenames.add(filedat.getFilePath());
pdbids.add(filedat.getPdbId());
- seqmaps.add(filedat.getSeqList()
- .toArray(new SequenceI[0]));
+ seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
newFileLoc.append("\"");
cp = ecp + 1; // advance beyond last \" and set cursor so we can
// look for next file statement.
newFileLoc.append(filedat.getFilePath());
pdbfilenames.add(filedat.getFilePath());
pdbids.add(filedat.getPdbId());
- seqmaps.add(filedat.getSeqList()
- .toArray(new SequenceI[0]));
+ seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
newFileLoc.append(" \"");
newFileLoc.append(filedat.getFilePath());
newFileLoc.append("\"");
* Post jalview 2.4 schema includes structure view id
*/
if (sviewid != null
- && ((StructureViewerBase) frame).getViewId().equals(
- sviewid))
+ && ((StructureViewerBase) frame).getViewId()
+ .equals(sviewid))
{
comp = (AppJmol) frame;
// todo: break?
if (av != null)
{
// propagate shared settings to this new view
- af.viewport.historyList = av.historyList;
- af.viewport.redoList = av.redoList;
+ af.viewport.setHistoryList(av.getHistoryList());
+ af.viewport.setRedoList(av.getRedoList());
}
else
{
{
// JBP TODO: Check this is called for AlCodonFrames to support recovery of
// xRef Codon Maps
- jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
- .get(vamsasSeq.getId());
- jalview.datamodel.SequenceI dsq = null;
+ SequenceI sq = seqRefIds.get(vamsasSeq.getId());
+ SequenceI dsq = null;
if (sq != null && sq.getDatasetSequence() != null)
{
dsq = sq.getDatasetSequence();
* local sequence definition
*/
Sequence ms = mc.getSequence();
- jalview.datamodel.Sequence djs = null;
+ SequenceI djs = null;
String sqid = ms.getDsseqid();
if (sqid != null && sqid.length() > 0)
{
/*
* recover dataset sequence
*/
- djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
+ djs = seqRefIds.get(sqid);
}
else
{
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
+import javax.swing.JScrollBar;
import javax.swing.SwingConstants;
/**
}
}
+ /**
+ * Returns the proportion of its range that a scrollbar's position represents,
+ * as a value between 0 and 1. For example if the whole range is from 0 to
+ * 200, then a position of 40 gives proportion = 0.2.
+ *
+ * @see http://www.javalobby.org/java/forums/t33050.html#91885334
+ *
+ * @param scroll
+ * @return
+ */
+ public static float getScrollBarProportion(JScrollBar scroll)
+ {
+ /*
+ * The extent (scroll handle width) deduction gives the true operating range
+ * of possible positions.
+ */
+ int possibleRange = scroll.getMaximum() - scroll.getMinimum()
+ - scroll.getModel().getExtent();
+ float valueInRange = scroll.getValue()
+ - (scroll.getModel().getExtent() / 2f);
+ float proportion = valueInRange / possibleRange;
+ return proportion;
+ }
+
+ /**
+ * Returns the scroll bar position in its range that would match the given
+ * proportion (between 0 and 1) of the whole. For example if the whole range
+ * is from 0 to 200, then a proportion of 0.25 gives position 50.
+ *
+ * @param scrollbar
+ * @param proportion
+ * @return
+ */
+ public static int getScrollValueForProportion(JScrollBar scrollbar,
+ float proportion)
+ {
+ /*
+ * The extent (scroll handle width) deduction gives the true operating range
+ * of possible positions.
+ */
+ float fraction = proportion
+ * (scrollbar.getMaximum() - scrollbar.getMinimum() - scrollbar
+ .getModel().getExtent())
+ + (scrollbar.getModel().getExtent() / 2f);
+ return Math.min(Math.round(fraction), scrollbar.getMaximum());
+ }
+
public static void jvInitComponent(AbstractButton comp, String i18nString)
{
setColorAndFont(comp);
import jalview.jbgui.GPCAPanel;
import jalview.schemes.ResidueProperties;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import jalview.viewmodel.PCAModel;
import java.awt.BorderLayout;
AlignmentPanel ap;
- AlignViewport av;
+ AlignmentViewport av;
PCAModel pcaModel;
*/
package jalview.gui;
-import java.util.*;
-import java.util.List;
-
-import java.awt.*;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
-import jalview.datamodel.*;
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
/**
* Route datamodel/view update events for a sequence set to any display
*/
public class PaintRefresher
{
- static Hashtable components;
+ static Map<String, List<Component>> components = new HashMap<String, List<Component>>();
/**
- * DOCUMENT ME!
+ * Add the given component to those registered under the given sequence set
+ * id. Does nothing if already added.
*
* @param comp
- * DOCUMENT ME!
* @param al
- * DOCUMENT ME!
*/
public static void Register(Component comp, String seqSetId)
{
- if (components == null)
- {
- components = new Hashtable();
- }
-
if (components.containsKey(seqSetId))
{
- Vector comps = (Vector) components.get(seqSetId);
+ List<Component> comps = components.get(seqSetId);
if (!comps.contains(comp))
{
- comps.addElement(comp);
+ comps.add(comp);
}
}
else
{
- Vector vcoms = new Vector();
- vcoms.addElement(comp);
+ List<Component> vcoms = new ArrayList<Component>();
+ vcoms.add(comp);
components.put(seqSetId, vcoms);
}
}
+ /**
+ * Remove this component from all registrations. Also removes a registered
+ * sequence set id if there are no remaining components registered against it.
+ *
+ * @param comp
+ */
public static void RemoveComponent(Component comp)
{
- if (components == null)
- {
- return;
- }
-
- Enumeration en = components.keys();
- while (en.hasMoreElements())
+ List<String> emptied = new ArrayList<String>();
+ for (Entry<String, List<Component>> registered : components.entrySet())
{
- String id = en.nextElement().toString();
- Vector comps = (Vector) components.get(id);
+ String id = registered.getKey();
+ List<Component> comps = components.get(id);
comps.remove(comp);
- if (comps.size() == 0)
+ if (comps.isEmpty())
{
- components.remove(id);
+ emptied.add(id);
}
}
+
+ /*
+ * Remove now empty ids after the above (to avoid
+ * ConcurrentModificationException).
+ */
+ for (String id : emptied)
+ {
+ components.remove(id);
+ }
}
public static void Refresh(Component source, String id)
public static void Refresh(Component source, String id,
boolean alignmentChanged, boolean validateSequences)
{
- if (components == null)
- {
- return;
- }
-
- Component comp;
- Vector comps = (Vector) components.get(id);
+ List<Component> comps = components.get(id);
if (comps == null)
{
return;
}
- Enumeration e = comps.elements();
- while (e.hasMoreElements())
+ for (Component comp : comps)
{
- comp = (Component) e.nextElement();
-
if (comp == source)
{
continue;
static AlignmentPanel[] getAssociatedPanels(String id)
{
- if (components == null)
- {
- return new AlignmentPanel[0];
- }
- ;
- Vector comps = (Vector) components.get(id);
+ List<Component> comps = components.get(id);
if (comps == null)
{
return new AlignmentPanel[0];
}
- ;
- Vector tmp = new Vector();
- int i, iSize = comps.size();
- for (i = 0; i < iSize; i++)
+ List<AlignmentPanel> tmp = new ArrayList<AlignmentPanel>();
+ for (Component comp : comps)
{
- if (comps.elementAt(i) instanceof AlignmentPanel)
+ if (comp instanceof AlignmentPanel)
{
- tmp.addElement(comps.elementAt(i));
+ tmp.add((AlignmentPanel) comp);
}
}
- AlignmentPanel[] result = new AlignmentPanel[tmp.size()];
- tmp.toArray(result);
-
- return result;
+ return tmp.toArray(new AlignmentPanel[tmp.size()]);
}
}
import jalview.datamodel.SequenceI;
import jalview.jbgui.GPairwiseAlignPanel;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import java.awt.event.ActionEvent;
import java.util.Vector;
public class PairwiseAlignPanel extends GPairwiseAlignPanel
{
- AlignViewport av;
+ AlignmentViewport av;
Vector sequences;
* @param av
* DOCUMENT ME!
*/
- public PairwiseAlignPanel(AlignViewport av)
+ public PairwiseAlignPanel(AlignmentViewport av)
{
super();
this.av = av;
}
int gsize = sg.getSize();
- SequenceI[] hseqs;
-
- hseqs = new SequenceI[gsize];
-
- int index = 0;
- for (int i = 0; i < gsize; i++)
- {
- hseqs[index++] = sg.getSequenceAt(i);
- }
+ SequenceI[] hseqs = sg.getSequences().toArray(new SequenceI[gsize]);
ap.av.hideSequence(hseqs);
// refresh(); TODO: ? needed ?
}
CommandI command = historyList.pop();
- if (ap.av.historyList.contains(command))
+ if (ap.av.getHistoryList().contains(command))
{
command.undoCommand(af.getViewAlignments());
- ap.av.historyList.remove(command);
+ ap.av.getHistoryList().remove(command);
ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
af.updateEditMenuBar();
}
import jalview.datamodel.*;
import jalview.math.*;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
/**
* DOCUMENT ME!
float scalefactor = 1;
- AlignViewport av;
+ AlignmentViewport av;
AlignmentPanel ap;
maxX = (i - startx + 1) * av.charWidth + fm.stringWidth(string);
}
- gg.drawLine(
- ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
- y + 2,
- ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
- y + (fm.getDescent() * 2));
+ gg.drawLine(((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
+ y + 2, ((i - startx - 1) * av.charWidth)
+ + (av.charWidth / 2), y + (fm.getDescent() * 2));
}
else
{
- gg.drawLine(
- ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
- y + fm.getDescent(),
- ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
- y + (fm.getDescent() * 2));
+ gg.drawLine(((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
+ y + fm.getDescent(), ((i - startx - 1) * av.charWidth)
+ + (av.charWidth / 2), y + (fm.getDescent() * 2));
}
}
int blockStart = startRes;
int blockEnd = endRes;
- for (int i = 0; regions != null && i < regions.size(); i++)
+ for (int[] region : regions)
{
- int[] region = regions.get(i);
int hideStart = region[0];
int hideEnd = region[1];
*/
package jalview.gui;
+import jalview.api.AlignViewportI;
import jalview.commands.EditCommand;
import jalview.commands.EditCommand.Action;
+import jalview.commands.EditCommand.Edit;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SearchResults;
import jalview.datamodel.Sequence;
import jalview.structure.SelectionSource;
import jalview.structure.SequenceListener;
import jalview.structure.StructureSelectionManager;
+import jalview.structure.VamsasSource;
+import jalview.util.Comparison;
+import jalview.util.MappingUtils;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
import java.awt.Color;
return seq;
}
+ /**
+ * When all of a sequence of edits are complete, put the resulting edit list
+ * on the history stack (undo list), and reset flags for editing in progress.
+ */
void endEditing()
{
- if (editCommand != null && editCommand.getSize() > 0)
+ try
+ {
+ if (editCommand != null && editCommand.getSize() > 0)
+ {
+ ap.alignFrame.addHistoryItem(editCommand);
+ av.firePropertyChange("alignment", null, av.getAlignment()
+ .getSequences());
+ }
+ } finally
{
- ap.alignFrame.addHistoryItem(editCommand);
- av.firePropertyChange("alignment", null, av.getAlignment()
- .getSequences());
+ /*
+ * Tidy up come what may...
+ */
+ startseq = -1;
+ lastres = -1;
+ editingSeqs = false;
+ groupEditing = false;
+ keyboardNo1 = null;
+ keyboardNo2 = null;
+ editCommand = null;
}
-
- startseq = -1;
- lastres = -1;
- editingSeqs = false;
- groupEditing = false;
- keyboardNo1 = null;
- keyboardNo2 = null;
- editCommand = null;
}
void setCursorRow()
}
@Override
+ public VamsasSource getVamsasSource()
+ {
+ return this.ap == null ? null : this.ap.av;
+ }
+ @Override
public void updateColours(SequenceI seq, int index)
{
System.out.println("update the seqPanel colours");
int setStatusMessage(SequenceI sequence, int res, int seq)
{
int pos = -1;
- StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: "
- + sequence.getName());
+ StringBuilder text = new StringBuilder(32);
+ text.append("Sequence " + (seq + 1) + " ID: " + sequence.getName());
- Object obj = null;
+ String residue = null;
+ /*
+ * Try to translate the display character to residue name (null for gap).
+ */
+ final String displayChar = String.valueOf(sequence.getCharAt(res));
if (av.getAlignment().isNucleotide())
{
- obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res)
- + "");
- if (obj != null)
+ residue = ResidueProperties.nucleotideName.get(displayChar);
+ if (residue != null)
{
- text.append(" Nucleotide: ");
+ text.append(" Nucleotide: ").append(residue);
}
}
else
{
- obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + "");
- if (obj != null)
+ residue = "X".equalsIgnoreCase(displayChar) ? "STOP"
+ : ResidueProperties.aa2Triplet.get(displayChar);
+ if (residue != null)
{
- text.append(" Residue: ");
+ text.append(" Residue: ").append(residue);
}
}
- if (obj != null)
+ if (residue != null)
{
pos = sequence.findPosition(res);
- if (obj != "")
- {
- text.append(obj + " (" + pos + ")");
- }
+ text.append(" (").append(Integer.toString(pos)).append(")");
}
ap.alignFrame.statusBar.setText(text.toString());
return pos;
}
}
- StringBuffer message = new StringBuffer();
+ StringBuilder message = new StringBuilder(64);
if (groupEditing)
{
message.append("Edit group:");
}
else
{
- editCommand.appendEdit(Action.INSERT_GAP, groupSeqs,
- startres, startres - lastres, av.getAlignment(), true);
+ appendEdit(Action.INSERT_GAP, groupSeqs, startres, startres
+ - lastres);
}
}
else
}
else
{
- editCommand.appendEdit(Action.DELETE_GAP, groupSeqs,
- startres, lastres - startres, av.getAlignment(), true);
+ appendEdit(Action.DELETE_GAP, groupSeqs, startres, lastres
+ - startres);
}
}
}
else
{
- editCommand.appendEdit(Action.INSERT_GAP, new SequenceI[]
- { seq }, lastres, startres - lastres, av.getAlignment(), true);
+ appendEdit(Action.INSERT_GAP, new SequenceI[]
+ { seq }, lastres, startres - lastres);
}
}
else
{
for (int j = lastres; j > startres; j--)
{
- if (!jalview.util.Comparison.isGap(seq.getCharAt(startres)))
+ if (!Comparison.isGap(seq.getCharAt(startres)))
{
endEditing();
break;
int max = 0;
for (int m = startres; m < lastres; m++)
{
- if (!jalview.util.Comparison.isGap(seq.getCharAt(m)))
+ if (!Comparison.isGap(seq.getCharAt(m)))
{
break;
}
if (max > 0)
{
- editCommand.appendEdit(Action.DELETE_GAP,
- new SequenceI[]
- { seq }, startres, max, av.getAlignment(), true);
+ appendEdit(Action.DELETE_GAP, new SequenceI[]
+ { seq }, startres, max);
}
}
}
}
else
{
- editCommand.appendEdit(Action.INSERT_NUC, new SequenceI[]
- { seq }, lastres, startres - lastres, av.getAlignment(), true);
+ appendEdit(Action.INSERT_NUC, new SequenceI[]
+ { seq }, lastres, startres - lastres);
}
}
}
}
}
- editCommand.appendEdit(Action.DELETE_GAP, seq, blankColumn, 1,
- av.getAlignment(), true);
+ appendEdit(Action.DELETE_GAP, seq, blankColumn, 1);
- editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1,
- av.getAlignment(), true);
+ appendEdit(Action.INSERT_GAP, seq, j, 1);
}
+ /**
+ * Helper method to add and perform one edit action.
+ *
+ * @param action
+ * @param seq
+ * @param pos
+ * @param count
+ */
+ protected void appendEdit(Action action, SequenceI[] seq, int pos,
+ int count)
+ {
+
+ final Edit edit = new EditCommand().new Edit(action, seq, pos, count,
+ av.getAlignment().getGapCharacter());
+
+ editCommand.appendEdit(edit, av.getAlignment(),
+ true, null);
+ }
+
void deleteChar(int j, SequenceI[] seq, int fixedColumn)
{
- editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1,
- av.getAlignment(), true);
+ appendEdit(Action.DELETE_GAP, seq, j, 1);
- editCommand.appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1,
- av.getAlignment(), true);
+ appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1);
}
/**
// handles selection messages...
// TODO: extend config options to allow user to control if selections may be
// shared between viewports.
- if (av == source
- || !av.followSelection
- || (av.isSelectionGroupChanged(false) || av
- .isColSelChanged(false))
- || (source instanceof AlignViewport && ((AlignViewport) source)
- .getSequenceSetId().equals(av.getSequenceSetId())))
+ boolean iSentTheSelection = (av == source
+ || (source instanceof AlignViewport && ((AlignmentViewport) source)
+ .getSequenceSetId().equals(av.getSequenceSetId())));
+ if (iSentTheSelection || !av.followSelection)
+ {
+ return;
+ }
+
+ /*
+ * Ignore the selection if there is one of our own pending.
+ */
+ if (av.isSelectionGroupChanged(false) || av.isColSelChanged(false))
+ {
+ return;
+ }
+
+ /*
+ * Check for selection in a view of which this one is a dna/protein
+ * complement.
+ */
+ if (selectionFromTranslation(seqsel, colsel, source))
{
return;
}
+
// do we want to thread this ? (contention with seqsel and colsel locks, I
// suspect)
// rules are: colsel is copied if there is a real intersection between
// sequence selection
- boolean repaint = false, copycolsel = true;
- // if (!av.isSelectionGroupChanged(false))
+ boolean repaint = false;
+ boolean copycolsel = true;
+
+ SequenceGroup sgroup = null;
+ if (seqsel != null && seqsel.getSize() > 0)
{
- SequenceGroup sgroup = null;
- if (seqsel != null && seqsel.getSize() > 0)
+ if (av.getAlignment() == null)
{
- if (av.getAlignment() == null)
- {
- jalview.bin.Cache.log.warn("alignviewport av SeqSetId="
- + av.getSequenceSetId() + " ViewId=" + av.getViewId()
- + " 's alignment is NULL! returning immediatly.");
- return;
- }
- sgroup = seqsel.intersect(av.getAlignment(),
- (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
- if ((sgroup == null || sgroup.getSize() == 0)
- || (colsel == null || colsel.size() == 0))
- {
- // don't copy columns if the region didn't intersect.
- copycolsel = false;
- }
+ jalview.bin.Cache.log.warn("alignviewport av SeqSetId="
+ + av.getSequenceSetId() + " ViewId=" + av.getViewId()
+ + " 's alignment is NULL! returning immediately.");
+ return;
}
- if (sgroup != null && sgroup.getSize() > 0)
+ sgroup = seqsel.intersect(av.getAlignment(),
+ (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
+ if ((sgroup == null || sgroup.getSize() == 0)
+ || (colsel == null || colsel.size() == 0))
{
- av.setSelectionGroup(sgroup);
+ // don't copy columns if the region didn't intersect.
+ copycolsel = false;
}
- else
- {
- av.setSelectionGroup(null);
- }
- av.isSelectionGroupChanged(true);
- repaint = true;
}
+ if (sgroup != null && sgroup.getSize() > 0)
+ {
+ av.setSelectionGroup(sgroup);
+ }
+ else
+ {
+ av.setSelectionGroup(null);
+ }
+ av.isSelectionGroupChanged(true);
+ repaint = true;
+
if (copycolsel)
{
// the current selection is unset or from a previous message
av.isColSelChanged(true);
repaint = true;
}
+
if (copycolsel
&& av.hasHiddenColumns()
&& (av.getColumnSelection() == null || av.getColumnSelection()
{
System.err.println("Bad things");
}
- if (repaint)
+ if (repaint) // always true!
{
// probably finessing with multiple redraws here
PaintRefresher.Refresh(this, av.getSequenceSetId());
// ap.paintAlignment(false);
}
}
+
+ /**
+ * If this panel is a cdna/protein translation view of the selection source,
+ * tries to map the source selection to a local one, and returns true. Else
+ * returns false.
+ *
+ * @param seqsel
+ * @param colsel
+ * @param source
+ */
+ protected boolean selectionFromTranslation(SequenceGroup seqsel,
+ ColumnSelection colsel, SelectionSource source)
+ {
+ if (!(source instanceof AlignViewportI)) {
+ return false;
+ }
+ final AlignViewportI sourceAv = (AlignViewportI) source;
+ if (sourceAv.getCodingComplement() != av && av.getCodingComplement() != sourceAv)
+ {
+ return false;
+ }
+
+ /*
+ * Map sequence selection
+ */
+ SequenceGroup sg = MappingUtils.mapSequenceGroup(seqsel, sourceAv, av);
+ av.setSelectionGroup(sg);
+ av.isSelectionGroupChanged(true);
+
+ /*
+ * Map column selection
+ */
+ ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
+ av);
+ av.setColumnSelection(cs);
+ av.isColSelChanged(true);
+
+ PaintRefresher.Refresh(this, av.getSequenceSetId());
+
+ return true;
+ }
}
*/
package jalview.gui;
-import java.util.*;
-import java.util.List;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-import javax.swing.tree.DefaultMutableTreeNode;
-
-import com.stevesoft.pat.Regex;
-
-import jalview.datamodel.*;
-import jalview.io.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.io.FormatAdapter;
+import jalview.io.IdentifyFile;
import jalview.util.DBRefUtils;
import jalview.util.MessageManager;
import jalview.ws.dbsources.das.api.DasSourceRegistryI;
import jalview.ws.seqfetcher.DbSourceProxy;
+
import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingConstants;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import com.stevesoft.pat.Regex;
public class SequenceFetcher extends JPanel implements Runnable
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
+ {
ok_actionPerformed();
+ }
}
});
jPanel3.setLayout(borderLayout1);
}
else
{
- for (int i = 0; i < al.getHeight(); i++)
- {
- alignFrame.viewport.getAlignment().addSequence(
- al.getSequenceAt(i)); // this
- // also
- // creates
- // dataset
- // sequence
- // entries
- }
- alignFrame.viewport.setEndSeq(alignFrame.viewport.getAlignment()
- .getHeight());
- alignFrame.viewport.getAlignment().getWidth();
- alignFrame.viewport.firePropertyChange("alignment", null,
- alignFrame.viewport.getAlignment().getSequences());
+ alignFrame.viewport.addAlignment(al, title);
}
}
return al;
--- /dev/null
+package jalview.gui;
+
+import jalview.jbgui.GSplitFrame;
+
+import java.awt.Component;
+import java.awt.MouseInfo;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.util.Map.Entry;
+
+import javax.swing.AbstractAction;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.KeyStroke;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+
+public class SplitFrame extends GSplitFrame
+{
+ private static final long serialVersionUID = 1L;
+
+ public SplitFrame(JComponent top, JComponent bottom)
+ {
+ super(top, bottom);
+ init();
+ }
+
+ /**
+ * Initialise this frame.
+ */
+ protected void init()
+ {
+ setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 20);
+
+ addCloseFrameListener();
+
+ addKeyListener();
+
+ addKeyBindings();
+
+ }
+
+ /**
+ * Add a listener to tidy up when the frame is closed.
+ */
+ protected void addCloseFrameListener()
+ {
+ addInternalFrameListener(new InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosed(InternalFrameEvent evt)
+ {
+ if (getTopComponent() instanceof AlignFrame)
+ {
+ ((AlignFrame) getTopComponent())
+ .closeMenuItem_actionPerformed(true);
+ }
+ if (getBottomComponent() instanceof AlignFrame)
+ {
+ ((AlignFrame) getBottomComponent())
+ .closeMenuItem_actionPerformed(true);
+ }
+ };
+ });
+ }
+
+ /**
+ * Add a key listener that delegates to whichever split component the mouse is
+ * in (or does nothing if neither).
+ */
+ protected void addKeyListener()
+ {
+ // TODO Key Bindings rather than KeyListener are recommended for Swing
+ addKeyListener(new KeyAdapter() {
+
+ @Override
+ public void keyPressed(KeyEvent e)
+ {
+ Component c = getComponentAtMouse();
+ if (c != null)
+ {
+ for (KeyListener kl : c.getKeyListeners())
+ {
+ kl.keyPressed(e);
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e)
+ {
+ Component c = getComponentAtMouse();
+ if (c != null)
+ {
+ for (KeyListener kl : c.getKeyListeners())
+ {
+ kl.keyReleased(e);
+ }
+ }
+ }
+
+ });
+ }
+
+ /**
+ * Returns the split pane component the mouse is in, or null if neither.
+ *
+ * @return
+ */
+ protected Component getComponentAtMouse()
+ {
+ Point loc = MouseInfo.getPointerInfo().getLocation();
+
+ if (isIn(loc, getTopComponent())) {
+ return getTopComponent();
+ }
+ else if (isIn(loc, getBottomComponent()))
+ {
+ return getBottomComponent();
+ }
+ return null;
+ }
+
+ private boolean isIn(Point loc, JComponent comp)
+ {
+ Point p = comp.getLocationOnScreen();
+ Rectangle r = new Rectangle(p.x, p.y, comp.getWidth(), comp.getHeight());
+ return r.contains(loc);
+ }
+
+ /**
+ * Set key bindings (recommended for Swing over key accelerators). For now,
+ * delegate to the corresponding key accelerator for the AlignFrame that the
+ * mouse is in. Hopefully can be simplified in future if AlignFrame is changed
+ * to use key bindings rather than accelerators.
+ */
+ private void addKeyBindings()
+ {
+ if (getTopComponent() instanceof AlignFrame)
+ {
+ for (Entry<KeyStroke, JMenuItem> acc : ((AlignFrame) getTopComponent())
+ .getAccelerators().entrySet())
+ {
+
+ final KeyStroke ks = acc.getKey();
+ this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, ks);
+ this.getActionMap().put(ks, new AbstractAction()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ Component c = getComponentAtMouse();
+ if (c instanceof AlignFrame)
+ {
+ for (ActionListener a : ((AlignFrame) c).getAccelerators()
+ .get(ks).getActionListeners())
+ {
+
+ a.actionPerformed(null);
+ }
+ }
+ }
+ });
+ }
+ /*
+ * Disable unwanted here
+ */
+ // X expand views - wrecks the split pane view
+ KeyStroke key_X = KeyStroke.getKeyStroke(KeyEvent.VK_X, 0, false);
+ disableAccelerator(key_X);
+ }
+ }
+
+ /**
+ * Ugly hack for Proof of Concept that disables the key binding in this frame
+ * _and_ disables the bound menu item _and_ removes the key accelerator in the
+ * child frames.
+ *
+ * @param key
+ */
+ protected void disableAccelerator(KeyStroke key)
+ {
+ disableAccelerator(key, getTopComponent());
+ disableAccelerator(key, getBottomComponent());
+ this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).remove(key);
+ }
+
+ /**
+ * Disable the menu item for which this key is the accelerator, also removes
+ * its action listeners to prevent key accelerator working.
+ *
+ * @param key
+ * @param comp
+ */
+ private void disableAccelerator(KeyStroke key, JComponent comp)
+ {
+ // HACKED ONLY FOR PROOF OF CONCEPT
+ // Proper solution might involve explicit 'configure menu' method on
+ // AlignFrame, or
+ // changing key listeners to key bindings in AlignFrame, or both
+ if (comp instanceof AlignFrame)
+ {
+ JMenuItem mi = ((AlignFrame) comp).getAccelerators().get(key);
+ if (mi != null)
+ {
+ mi.setEnabled(false);
+ for (ActionListener al : mi.getActionListeners())
+ {
+ mi.removeActionListener(al);
+ }
+ }
+ }
+ }
+}
*/
package jalview.gui;
-import java.util.*;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.print.*;
-import javax.swing.*;
-
-import jalview.analysis.*;
-import jalview.datamodel.*;
-import jalview.schemes.*;
-import jalview.util.*;
+import jalview.analysis.Conservation;
+import jalview.analysis.NJTree;
+import jalview.api.AlignViewportI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceNode;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.ResidueProperties;
+import jalview.schemes.UserColourScheme;
+import jalview.structure.SelectionSource;
+import jalview.util.Format;
+import jalview.util.MappingUtils;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.swing.JColorChooser;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
/**
* DOCUMENT ME!
* @version $Revision$
*/
public class TreeCanvas extends JPanel implements MouseListener, Runnable,
- Printable, MouseMotionListener
+ Printable, MouseMotionListener, SelectionSource
{
/** DOCUMENT ME!! */
public static final String PLACEHOLDER = " * ";
if (node.element() instanceof SequenceI)
{
- SequenceI seq = (SequenceI) ((SequenceNode) node).element();
+ SequenceI seq = (SequenceI) node.element();
if (av.getSequenceColour(seq) == Color.white)
{
Rectangle rect = new Rectangle(xend + 10, ypos - charHeight / 2,
charWidth, charHeight);
- nameHash.put((SequenceI) node.element(), rect);
+ nameHash.put(node.element(), rect);
// Colour selected leaves differently
SequenceGroup selected = av.getSelectionGroup();
if ((selected != null)
&& selected.getSequences(null).contains(
- (SequenceI) node.element()))
+ node.element()))
{
g.setColor(Color.gray);
int xend = (int) (height * scale) + offx;
int ypos = (int) (node.ycount * chunk) + offy;
- g.setColor(((SequenceNode) node).color.darker());
+ g.setColor(node.color.darker());
// Draw horizontal line
g.drawLine(xstart, ypos, xend, ypos);
{
for (int a = 0; a < aps.length; a++)
{
- aps[a].av.setSequenceColour((SequenceI) node.element(), c);
+ final SequenceI seq = (SequenceI) node.element();
+ aps[a].av.setSequenceColour(seq, c);
}
}
}
labelLength = fm.stringWidth(longestName) + 20; // 20 allows for scrollbar
- float wscale = (float) (width - labelLength - (offx * 2))
+ float wscale = (width - labelLength - (offx * 2))
/ tree.getMaxHeight();
SequenceNode top = tree.getTopNode();
g2.setColor(Color.gray);
}
- int x = (int) ((threshold * (float) (getWidth() - labelLength - (2 * offx))) + offx);
+ int x = (int) ((threshold * (getWidth() - labelLength - (2 * offx))) + offx);
g2.drawLine(x, 0, x, getHeight());
}
AlignmentPanel[] aps = getAssociatedPanels();
+ // TODO push calls below into a single AlignViewportI method?
+ // see also AlignViewController.deleteGroups
for (int a = 0; a < aps.length; a++)
{
aps[a].av.setSelectionGroup(null);
aps[a].av.getAlignment().deleteAllGroups();
aps[a].av.clearSequenceColours();
}
+ if (av.getCodingComplement() != null)
+ {
+ av.getCodingComplement().setSelectionGroup(null);
+ av.getCodingComplement().getAlignment().deleteAllGroups();
+ av.getCodingComplement().clearSequenceColours();
+ }
colourGroups();
}
// sg.recalcConservation();
sg.setName("JTreeGroup:" + sg.hashCode());
sg.setIdColour(col);
+
for (int a = 0; a < aps.length; a++)
{
if (aps[a].av.getGlobalColourScheme() != null
aps[a].av.getAlignment().addGroup(new SequenceGroup(sg));
}
+
+ // TODO can we push all of the below into AlignViewportI?
+ av.getAlignment().addGroup(sg);
+ final AlignViewportI codingComplement = av.getCodingComplement();
+ if (codingComplement != null)
+ {
+ SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, av,
+ codingComplement);
+ if (mappedGroup.getSequences().size() > 0)
+ {
+ codingComplement.getAlignment().addGroup(mappedGroup);
+ for (SequenceI seq : mappedGroup.getSequences())
+ {
+ codingComplement.setSequenceColour(seq,
+ mappedGroup.getIdColour().brighter());
+ }
+ }
+ }
}
+
// notify the panel to redo any group specific stuff.
for (int a = 0; a < aps.length; a++)
{
// to any Jmols listening in
}
+ if (av.getCodingComplement() != null)
+ {
+ ((AlignViewport) av.getCodingComplement()).getAlignPanel().updateAnnotation();
+ /*
+ * idPanel. repaint ()
+ */
+ }
}
/**
associateLeavesMenu.add(item);
}
- final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem("All Views");
+ final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem(
+ "label.all_views");
buttonGroup.add(itemf);
itemf.setSelected(treeCanvas.applyToAllViews);
itemf.addActionListener(new ActionListener()
av.setCurrentTree(tree);
if (av.getSortByTree())
{
- sortByTree_actionPerformed(null);
+ sortByTree_actionPerformed();
}
}
}
// msaorder);
Desktop.addInternalFrame(af, MessageManager.formatMessage(
- "label.original_data_for_params", new String[]
+ "label.original_data_for_params", new Object[]
{ this.title }), AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
}
*
* @param e
*/
- public void sortByTree_actionPerformed(ActionEvent e)
+ @Override
+ public void sortByTree_actionPerformed()
{
if (treeCanvas.applyToAllViews)
import jalview.structure.VamsasListener;
import jalview.structure.VamsasSource;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
-import java.util.Enumeration;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.Iterator;
public void end_session(boolean promptUser)
{
if (!inSession())
+ {
throw new Error(MessageManager.getString("error.jalview_no_connected_vamsas_session"));
+ }
Cache.log.info("Jalview disconnecting from the Vamsas Session.");
try
{
int i = -1;
- public void mouseOver(SequenceI seq, int index,
+ @Override
+ public void mouseOverSequence(SequenceI seq, int index,
VamsasSource source)
{
if (jv2vobj == null)
+ {
return;
+ }
if (seq != last || i != index)
{
VorbaId v = (VorbaId) jv2vobj.get(seq);
AlignmentI visal = null;
if (source instanceof AlignViewport)
{
- visal = ((AlignViewport) source).getAlignment();
+ visal = ((AlignmentViewport) source).getAlignment();
}
SelectionMessage sm = null;
if ((seqsel == null || seqsel.getSize() == 0)
{
// the empty selection.
sm = new SelectionMessage("jalview", new String[]
- { ((AlignViewport) source).getSequenceSetId() }, null,
+ { ((AlignmentViewport) source).getSequenceSetId() }, null,
true);
}
else
{
// gather selected columns outwith the sequence positions
// too
- Enumeration cols = colsel.getSelected().elements();
- while (cols.hasMoreElements())
+ for (Object obj : colsel.getSelected())
{
- int ival = ((Integer) cols.nextElement()).intValue();
+ int ival = ((Integer) obj).intValue();
Pos p = new Pos();
p.setI(ival + 1);
range.addPos(p);
*/
protected void updateWebServiceMenus()
{
- for (AlignFrame alignFrame : Desktop.getAlignframes())
+ for (AlignFrame alignFrame : Desktop.getAlignFrames())
{
alignFrame.BuildWebServiceMenu();
}
* List of valid format strings used in the isValidFormat method
*/
public static final String[] READABLE_FORMATS = new String[]
- { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH",
- "PDB", "JnetFile", "RNAML", PhylipFile.FILE_DESC, "HTML" }; // ,
- // "SimpleBLAST"
- // };
+ { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH",
+ "PDB", "JnetFile", "RNAML", PhylipFile.FILE_DESC, "HTML" };
+
+ /**
+ * List of readable format file extensions by application in order
+ * corresponding to READABLE_FNAMES
+ */
+ public static final String[] READABLE_EXTENSIONS = new String[]
+ { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
+ "sto,stk", "xml,rnaml", PhylipFile.FILE_EXT, "jar,jvp", "html" };
+
+ /**
+ * List of readable formats by application in order corresponding to
+ * READABLE_EXTENSIONS
+ */
+ public static final String[] READABLE_FNAMES = new String[]
+ { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Stockholm",
+ "RNAML", PhylipFile.FILE_DESC, "Jalview", "HTML" };
/**
* List of valid format strings for use by callers of the formatSequences
{ "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "STH",
PhylipFile.FILE_DESC, "Jalview" };
- /**
- * List of readable format file extensions by application in order
- * corresponding to READABLE_FNAMES
- */
- public static final String[] READABLE_EXTENSIONS = new String[]
- { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
- "jar,jvp", "sto,stk", "xml,rnaml", PhylipFile.FILE_EXT,
- "html" }; // ".blast"
-
- /**
- * List of readable formats by application in order corresponding to
- * READABLE_EXTENSIONS
- */
- public static final String[] READABLE_FNAMES = new String[]
- { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Jalview",
- "Stockholm", "RNAML", PhylipFile.FILE_DESC, "HTML" };// ,
-
- // "SimpleBLAST"
- // };
-
public static String INVALID_CHARACTERS = "Contains invalid characters";
// TODO: make these messages dynamic
}
if (viewport != null)
{
- // TODO: create undo object for this JAL-1101
- for (int i = 0; i < al.getHeight(); i++)
- {
- viewport.getAlignment().addSequence(al.getSequenceAt(i));
- }
- viewport.firePropertyChange("alignment", null, viewport
- .getAlignment().getSequences());
+ viewport.addAlignment(al, title);
}
else
{
import jalview.io.vamsas.DatastoreRegistry;
import jalview.io.vamsas.Rangetype;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import java.io.IOException;
import java.util.Enumeration;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import java.util.Vector;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
-import uk.ac.vamsas.client.*;
-import uk.ac.vamsas.objects.core.*;
+import uk.ac.vamsas.client.IClientAppdata;
+import uk.ac.vamsas.client.IClientDocument;
+import uk.ac.vamsas.client.Vobject;
+import uk.ac.vamsas.client.VorbaId;
+import uk.ac.vamsas.objects.core.Alignment;
+import uk.ac.vamsas.objects.core.AlignmentSequence;
+import uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation;
+import uk.ac.vamsas.objects.core.AnnotationElement;
+import uk.ac.vamsas.objects.core.DataSet;
+import uk.ac.vamsas.objects.core.DataSetAnnotations;
+import uk.ac.vamsas.objects.core.DbRef;
+import uk.ac.vamsas.objects.core.Entry;
+import uk.ac.vamsas.objects.core.Glyph;
+import uk.ac.vamsas.objects.core.Local;
+import uk.ac.vamsas.objects.core.MapType;
+import uk.ac.vamsas.objects.core.Mapped;
+import uk.ac.vamsas.objects.core.Property;
+import uk.ac.vamsas.objects.core.Provenance;
+import uk.ac.vamsas.objects.core.RangeAnnotation;
+import uk.ac.vamsas.objects.core.RangeType;
+import uk.ac.vamsas.objects.core.Seg;
+import uk.ac.vamsas.objects.core.Sequence;
+import uk.ac.vamsas.objects.core.SequenceType;
+import uk.ac.vamsas.objects.core.VAMSAS;
import uk.ac.vamsas.objects.utils.Properties;
/*
private void buildSkipList()
{
skipList = new Hashtable();
- AlignFrame[] al = Desktop.getAlignframes();
+ AlignFrame[] al = Desktop.getAlignFrames();
for (int f = 0; al != null && f < al.length; f++)
{
skipList.put(al[f].getViewport().getSequenceSetId(), al[f]);
* @return true if alignment associated with this view will be stored in
* document.
*/
- public boolean alignmentWillBeSkipped(AlignViewport av)
+ public boolean alignmentWillBeSkipped(AlignmentViewport av)
{
return (!av.getAlignment().isAligned());
}
- private void addToSkipList(AlignViewport av)
+ private void addToSkipList(AlignmentViewport av)
{
if (skipList == null)
{
an.addProperty(Properties.newProperty(THRESHOLD,
Properties.FLOATTYPE, "" + alan.getThreshold().value));
if (alan.getThreshold().label != null)
+ {
an.addProperty(Properties.newProperty(THRESHOLD + "Name",
Properties.STRINGTYPE, "" + alan.getThreshold().label));
+ }
}
((DataSet) sref.getV_parent()).addDataSetAnnotations(an);
bindjvvobj(alan, an);
// sync,
// and if any contain more than one view, then remove the one generated by
// document update.
- AlignViewport views[], av = null;
+ AlignmentViewport views[], av = null;
AlignFrame af = null;
Iterator newviews = newAlignmentViews.iterator();
while (newviews.hasNext())
{
- av = (AlignViewport) newviews.next();
+ av = (AlignmentViewport) newviews.next();
af = Desktop.getAlignFrameFor(av);
// TODO implement this : af.getNumberOfViews
String seqsetidobj = av.getSequenceSetId();
// to the align frames.
boolean gathered = false;
String newviewid = null;
- AlignedCodonFrame[] mappings = av.getAlignment().getCodonFrames();
+ Set<AlignedCodonFrame> mappings = av.getAlignment()
+ .getCodonFrames();
for (int i = 0; i < views.length; i++)
{
if (views[i] != av)
{
// ensure sequence mappings from vamsas document view still
// active
- if (mappings != null && mappings.length > 0)
+ if (mappings != null)
{
jalview.structure.StructureSelectionManager
.getStructureSelectionManager(Desktop.instance)
uk.ac.vamsas.objects.core.Alignment alignment = dataset
.getAlignment(al);
// TODO check this handles multiple views properly
- AlignViewport av = findViewport(alignment);
+ AlignmentViewport av = findViewport(alignment);
jalview.datamodel.AlignmentI jal = null;
if (av != null)
return newAlignmentViews.size();
}
- public AlignViewport findViewport(Alignment alignment)
+ public AlignmentViewport findViewport(Alignment alignment)
{
- AlignViewport av = null;
- AlignViewport[] avs = Desktop
+ AlignmentViewport av = null;
+ AlignmentViewport[] avs = Desktop
.getViewports((String) getvObj2jv(alignment));
if (avs != null)
{
Cache.log.warn("Failed to parse threshold property");
}
if (val != null)
+ {
if (gl == null)
{
gl = new GraphLine(val.floatValue(), "", java.awt.Color.black);
{
gl.value = val.floatValue();
}
+ }
}
else if (props[p].getName().equalsIgnoreCase(THRESHOLD + "Name"))
{
if (gl == null)
+ {
gl = new GraphLine(0, "", java.awt.Color.black);
+ }
gl.label = props[p].getContent();
}
}
return vobj2jv;
}
- public void storeSequenceMappings(AlignViewport viewport, String title)
+ public void storeSequenceMappings(AlignmentViewport viewport, String title)
throws Exception
{
- AlignViewport av = viewport;
+ AlignmentViewport av = viewport;
try
{
jalview.datamodel.AlignmentI jal = av.getAlignment();
}
// Store any sequence mappings.
- if (av.getAlignment().getCodonFrames() != null
- && av.getAlignment().getCodonFrames().length > 0)
+ Set<AlignedCodonFrame> cframes = av.getAlignment().getCodonFrames();
+ if (cframes != null)
{
- jalview.datamodel.AlignedCodonFrame[] cframes = av.getAlignment()
- .getCodonFrames();
- for (int cf = 0; cf < cframes.length; cf++)
+ for (AlignedCodonFrame acf : cframes)
{
- if (cframes[cf].getdnaSeqs() != null
- && cframes[cf].getdnaSeqs().length > 0)
+ if (acf.getdnaSeqs() != null && acf.getdnaSeqs().length > 0)
{
- jalview.datamodel.SequenceI[] dmps = cframes[cf].getdnaSeqs();
- jalview.datamodel.Mapping[] mps = cframes[cf].getProtMappings();
+ jalview.datamodel.SequenceI[] dmps = acf.getdnaSeqs();
+ jalview.datamodel.Mapping[] mps = acf.getProtMappings();
for (int smp = 0; smp < mps.length; smp++)
{
uk.ac.vamsas.objects.core.SequenceType mfrom = (SequenceType) getjv2vObj(dmps[smp]);
*/
package jalview.io.vamsas;
-import java.util.Vector;
-
import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.Mapping;
import jalview.datamodel.SequenceI;
import jalview.gui.Desktop;
import jalview.io.VamsasAppDatastore;
-import uk.ac.vamsas.client.Vobject;
+
+import java.util.Vector;
+
import uk.ac.vamsas.objects.core.AlignmentSequence;
import uk.ac.vamsas.objects.core.DataSet;
import uk.ac.vamsas.objects.core.Sequence;
jalview.bin.Cache.log.info("Ignoring non sequence-sequence mapping");
return;
}
- mobj = this.getvObj2jv((Vobject) sdloc);
+ mobj = this.getvObj2jv(sdloc);
if (mobj instanceof SequenceI)
{
from = (SequenceI) mobj;
}
- mobj = this.getvObj2jv((Vobject) sdmap);
+ mobj = this.getvObj2jv(sdmap);
if (mobj instanceof SequenceI)
{
to = (SequenceI) mobj;
}
// create mapping storage object and make each dataset alignment reference
// it.
- jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc
- .getV_parent());
- jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap
- .getV_parent());
- AlignedCodonFrame afc = new AlignedCodonFrame(0);
+ AlignmentI dsLoc = (AlignmentI) getvObj2jv(sdloc.getV_parent());
+ AlignmentI dsMap = (AlignmentI) getvObj2jv(sdmap.getV_parent());
+ AlignedCodonFrame acf = new AlignedCodonFrame();
if (dsLoc != null && dsLoc != dsMap)
{
- dsLoc.addCodonFrame(afc);
+ dsLoc.addCodonFrame(acf);
}
if (dsMap != null)
{
- dsMap.addCodonFrame(afc);
+ dsMap.addCodonFrame(acf);
}
// create and add the new mapping to (each) dataset's codonFrame
mapping = new jalview.util.MapList(mapping.getToRanges(),
mapping.getFromRanges(), mapping.getToRatio(),
mapping.getFromRatio());
- afc.addMap(to, from, mapping);
+ acf.addMap(to, from, mapping);
}
else
{
mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense
- afc.addMap(from, to, mapping);
+ acf.addMap(from, to, mapping);
}
}
else
{
mapping = this.parsemapType(sequenceMapping, 1, 1); // correct sense
- afc.addMap(from, to, mapping);
+ acf.addMap(from, to, mapping);
}
bindjvvobj(mapping, sequenceMapping);
jalview.structure.StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance).addMappings(
- new AlignedCodonFrame[]
- { afc });
+ .getStructureSelectionManager(Desktop.instance).addMapping(acf);
// Try to link up any conjugate database references in the two sequences
// matchConjugateDBRefs(from, to, mapping);
// Try to propagate any dbrefs across this mapping.
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.datamodel.SequenceNode;
-import jalview.gui.AlignViewport;
import jalview.gui.TreePanel;
import jalview.io.NewickFile;
import jalview.io.VamsasAppDatastore;
+import jalview.viewmodel.AlignmentViewport;
import uk.ac.vamsas.client.Vobject;
import uk.ac.vamsas.objects.core.AlignmentSequence;
import uk.ac.vamsas.objects.core.Entry;
*/
public Object[] recoverInputData(Provenance tp)
{
- AlignViewport javport = null;
+ AlignmentViewport javport = null;
jalview.datamodel.AlignmentI jal = null;
jalview.datamodel.CigarArray view = null;
for (int pe = 0; pe < tp.getEntryCount(); pe++)
return null;
}
- private AlignViewport getViewport(Vobject v_parent)
+ private AlignmentViewport getViewport(Vobject v_parent)
{
if (v_parent instanceof uk.ac.vamsas.objects.core.Alignment)
{
int i = -1;
- public void mouseOver(SequenceI seq, int index, VamsasSource source)
+ @Override
+ public void mouseOverSequence(SequenceI seq, int index,
+ VamsasSource source)
{
if (seq != last || i != index)
{
*/
package jalview.javascript;
-import java.awt.Color;
-import java.util.ArrayList;
-
import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureRenderer;
import jalview.api.SequenceRenderer;
import jalview.bin.JalviewLite;
import jalview.datamodel.SequenceI;
import jalview.ext.jmol.JmolCommands;
+import jalview.structure.AtomSpec;
import jalview.structure.StructureListener;
import jalview.structure.StructureMapping;
import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Propagate events involving PDB structures associated with sequences to a
* javascript function. Generally, the javascript handler is called with a
return modelSet;
}
- @Override
public void mouseOverStructure(int atomIndex, String strInfo)
{
}
@Override
- public void highlightAtom(int atomIndex, int pdbResNum, String chain,
- String pdbId)
+ public void highlightAtoms(List<AtomSpec> atoms)
{
- String[] st = new String[0];
- try
- {
- executeJavascriptFunction(_listenerfn, st = new String[]
- { "mouseover", "" + pdbId, "" + chain, "" + (pdbResNum),
- "" + atomIndex });
- } catch (Exception ex)
+ for (AtomSpec atom : atoms)
{
- System.err.println("Couldn't execute callback with " + _listenerfn
- + " using args { " + st[0] + ", " + st[1] + ", " + st[2]
- + "," + st[3] + "\n");
- ex.printStackTrace();
-
+ try
+ {
+ // TODO is this right? StructureSelectionManager passes pdbFile as the
+ // field that is interpreted (in 2.8.2) as pdbId?
+ executeJavascriptFunction(_listenerfn, new String[]
+ { "mouseover", "" + atom.getPdbFile(),
+ "" + atom.getChain(),
+ "" + (atom.getPdbResNum()), "" + atom.getAtomIndex() });
+ } catch (Exception ex)
+ {
+ System.err.println("Couldn't execute callback with " + _listenerfn
+ + " for atomSpec: " + atom);
+ ex.printStackTrace();
+ }
}
-
}
@Override
}
@Override
- public Color getColour(int atomIndex, int pdbResNum, String chain,
- String pdbId)
- {
- return null;
- }
-
- @Override
public AlignFrame getAlignFrame()
{
// associated with all alignframes, always.
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTabbedPane;
+import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.MenuEvent;
protected JMenuItem showTranslation = new JMenuItem();
+ protected JMenu cdna = new JMenu();
+
protected JMenuItem extractScores = new JMenuItem();
protected JMenuItem expandAlignment = new JMenuItem();
private boolean showAutoCalculatedAbove = false;
+ private Map<KeyStroke, JMenuItem> accelerators = new HashMap<KeyStroke, JMenuItem>();
+
public GAlignFrame()
{
try
JMenuItem item = new JMenuItem(
jalview.io.FormatAdapter.WRITEABLE_FORMATS[i]);
- item.addActionListener(new java.awt.event.ActionListener()
+ item.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
private void jbInit() throws Exception
{
fileMenu.setText(MessageManager.getString("action.file"));
+
saveAs.setText(MessageManager.getString("action.save_as") + "...");
- saveAs.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_S, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask()
- | java.awt.event.KeyEvent.SHIFT_MASK, false));
- saveAs.addActionListener(new ActionListener()
+ ActionListener al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
saveAs_actionPerformed(e);
}
- });
+ };
+ KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask()
+ | KeyEvent.SHIFT_MASK, false);
+ addMenuActionAndAccelerator(keyStroke, saveAs, al);
+
closeMenuItem.setText(MessageManager.getString("action.close"));
- closeMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_W, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- closeMenuItem.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
closeMenuItem_actionPerformed(false);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, closeMenuItem, al);
+
editMenu.setText(MessageManager.getString("action.edit"));
viewMenu.setText(MessageManager.getString("action.view"));
annotationsMenu.setText(MessageManager.getString("action.annotations"));
colourMenu.setText(MessageManager.getString("action.colour"));
calculateMenu.setText(MessageManager.getString("action.calculate"));
webService.setText(MessageManager.getString("action.web_service"));
+
selectAllSequenceMenuItem.setText(MessageManager
.getString("action.select_all"));
- selectAllSequenceMenuItem.setAccelerator(javax.swing.KeyStroke
- .getKeyStroke(java.awt.event.KeyEvent.VK_A, Toolkit
- .getDefaultToolkit().getMenuShortcutKeyMask(), false));
- selectAllSequenceMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- selectAllSequenceMenuItem_actionPerformed(e);
- }
- });
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ selectAllSequenceMenuItem_actionPerformed(e);
+ }
+ };
+ addMenuActionAndAccelerator(keyStroke, selectAllSequenceMenuItem, al);
+
deselectAllSequenceMenuItem.setText(MessageManager
.getString("action.deselect_all"));
- deselectAllSequenceMenuItem.setAccelerator(javax.swing.KeyStroke
- .getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, 0, false));
- deselectAllSequenceMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- deselectAllSequenceMenuItem_actionPerformed(e);
- }
- });
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
+ al = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ deselectAllSequenceMenuItem_actionPerformed(e);
+ }
+ };
+ addMenuActionAndAccelerator(keyStroke, deselectAllSequenceMenuItem, al);
+
invertSequenceMenuItem.setText(MessageManager
.getString("action.invert_sequence_selection"));
- invertSequenceMenuItem.setAccelerator(javax.swing.KeyStroke
- .getKeyStroke(java.awt.event.KeyEvent.VK_I, Toolkit
- .getDefaultToolkit().getMenuShortcutKeyMask(), false));
- invertSequenceMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- invertSequenceMenuItem_actionPerformed(e);
- }
- });
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_I, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ invertSequenceMenuItem_actionPerformed(e);
+ }
+ };
+ addMenuActionAndAccelerator(keyStroke, invertSequenceMenuItem, al);
+
grpsFromSelection.setText(MessageManager
.getString("action.make_groups_selection"));
- grpsFromSelection.addActionListener(new java.awt.event.ActionListener()
+ grpsFromSelection.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
.getString("action.view_flanking_regions"));
expandAlignment.setToolTipText(MessageManager
.getString("label.view_flanking_regions"));
- expandAlignment.addActionListener(new java.awt.event.ActionListener()
+ expandAlignment.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
remove2LeftMenuItem.setText(MessageManager
.getString("action.remove_left"));
- remove2LeftMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_L, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- remove2LeftMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- remove2LeftMenuItem_actionPerformed(e);
- }
- });
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_L, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ remove2LeftMenuItem_actionPerformed(e);
+ }
+ };
+ addMenuActionAndAccelerator(keyStroke, remove2LeftMenuItem, al);
+
remove2RightMenuItem.setText(MessageManager
.getString("action.remove_right"));
- remove2RightMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_R, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- remove2RightMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- remove2RightMenuItem_actionPerformed(e);
- }
- });
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_R, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ remove2RightMenuItem_actionPerformed(e);
+ }
+ };
+ addMenuActionAndAccelerator(keyStroke, remove2RightMenuItem, al);
+
removeGappedColumnMenuItem.setText(MessageManager
.getString("action.remove_empty_columns"));
- removeGappedColumnMenuItem.setAccelerator(javax.swing.KeyStroke
- .getKeyStroke(java.awt.event.KeyEvent.VK_E, Toolkit
- .getDefaultToolkit().getMenuShortcutKeyMask(), false));
- removeGappedColumnMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- removeGappedColumnMenuItem_actionPerformed(e);
- }
- });
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ removeGappedColumnMenuItem_actionPerformed(e);
+ }
+ };
+ addMenuActionAndAccelerator(keyStroke, removeGappedColumnMenuItem, al);
+
removeAllGapsMenuItem.setText(MessageManager
.getString("action.remove_all_gaps"));
- removeAllGapsMenuItem.setAccelerator(javax.swing.KeyStroke
- .getKeyStroke(java.awt.event.KeyEvent.VK_E, Toolkit
- .getDefaultToolkit().getMenuShortcutKeyMask()
- | java.awt.event.KeyEvent.SHIFT_MASK, false));
- removeAllGapsMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- removeAllGapsMenuItem_actionPerformed(e);
- }
- });
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask()
+ | KeyEvent.SHIFT_MASK, false);
+ al = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ removeAllGapsMenuItem_actionPerformed(e);
+ }
+ };
+ addMenuActionAndAccelerator(keyStroke, removeAllGapsMenuItem, al);
+
justifyLeftMenuItem.setText(MessageManager
.getString("action.left_justify_alignment"));
- justifyLeftMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- justifyLeftMenuItem_actionPerformed(e);
- }
- });
+ justifyLeftMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ justifyLeftMenuItem_actionPerformed(e);
+ }
+ });
justifyRightMenuItem.setText(MessageManager
.getString("action.right_justify_alignment"));
- justifyRightMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- justifyRightMenuItem_actionPerformed(e);
- }
- });
+ justifyRightMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ justifyRightMenuItem_actionPerformed(e);
+ }
+ });
viewBoxesMenuItem.setText(MessageManager.getString("action.boxes"));
viewBoxesMenuItem.setState(true);
- viewBoxesMenuItem.addActionListener(new java.awt.event.ActionListener()
+ viewBoxesMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
viewTextMenuItem.setText(MessageManager.getString("action.text"));
viewTextMenuItem.setState(true);
- viewTextMenuItem.addActionListener(new java.awt.event.ActionListener()
+ viewTextMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
showNonconservedMenuItem.setText(MessageManager
.getString("label.show_non_conversed"));
showNonconservedMenuItem.setState(false);
- showNonconservedMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- showUnconservedMenuItem_actionPerformed(e);
- }
- });
+ showNonconservedMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showUnconservedMenuItem_actionPerformed(e);
+ }
+ });
sortPairwiseMenuItem.setText(MessageManager
.getString("action.by_pairwise_id"));
- sortPairwiseMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- sortPairwiseMenuItem_actionPerformed(e);
- }
- });
+ sortPairwiseMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ sortPairwiseMenuItem_actionPerformed(e);
+ }
+ });
sortIDMenuItem.setText(MessageManager.getString("action.by_id"));
- sortIDMenuItem.addActionListener(new java.awt.event.ActionListener()
+ sortIDMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
sortLengthMenuItem
.setText(MessageManager.getString("action.by_length"));
- sortLengthMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- sortLengthMenuItem_actionPerformed(e);
- }
- });
+ sortLengthMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ sortLengthMenuItem_actionPerformed(e);
+ }
+ });
sortGroupMenuItem.setText(MessageManager.getString("action.by_group"));
- sortGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
+ sortGroupMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
sortGroupMenuItem_actionPerformed(e);
}
});
- removeRedundancyMenuItem.setText(MessageManager
- .getString("action.remove_redundancy").concat("..."));
- removeRedundancyMenuItem.setAccelerator(javax.swing.KeyStroke
- .getKeyStroke(java.awt.event.KeyEvent.VK_D, Toolkit
- .getDefaultToolkit().getMenuShortcutKeyMask(), false));
- removeRedundancyMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- removeRedundancyMenuItem_actionPerformed(e);
- }
- });
+
+ removeRedundancyMenuItem.setText(MessageManager.getString(
+ "action.remove_redundancy").concat("..."));
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ removeRedundancyMenuItem_actionPerformed(e);
+ }
+ };
+ addMenuActionAndAccelerator(keyStroke, removeRedundancyMenuItem, al);
+
pairwiseAlignmentMenuItem.setText(MessageManager
.getString("action.pairwise_alignment"));
- pairwiseAlignmentMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- pairwiseAlignmentMenuItem_actionPerformed(e);
- }
- });
+ pairwiseAlignmentMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ pairwiseAlignmentMenuItem_actionPerformed(e);
+ }
+ });
PCAMenuItem.setText(MessageManager
.getString("label.principal_component_analysis"));
- PCAMenuItem.addActionListener(new java.awt.event.ActionListener()
+ PCAMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
averageDistanceTreeMenuItem.setText(MessageManager
.getString("label.average_distance_identity"));
- averageDistanceTreeMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- averageDistanceTreeMenuItem_actionPerformed(e);
- }
- });
+ averageDistanceTreeMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ averageDistanceTreeMenuItem_actionPerformed(e);
+ }
+ });
neighbourTreeMenuItem.setText(MessageManager
.getString("label.neighbour_joining_identity"));
- neighbourTreeMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- neighbourTreeMenuItem_actionPerformed(e);
- }
- });
+ neighbourTreeMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ neighbourTreeMenuItem_actionPerformed(e);
+ }
+ });
this.getContentPane().setLayout(borderLayout1);
alignFrameMenuBar.setFont(new java.awt.Font("Verdana", 0, 11));
statusBar.setBackground(Color.white);
.getString("label.out_to_textbox"));
clustalColour.setText(MessageManager.getString("label.clustalx"));
- clustalColour.addActionListener(new java.awt.event.ActionListener()
+ clustalColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
}
});
zappoColour.setText(MessageManager.getString("label.zappo"));
- zappoColour.addActionListener(new java.awt.event.ActionListener()
+ zappoColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
}
});
taylorColour.setText(MessageManager.getString("label.taylor"));
- taylorColour.addActionListener(new java.awt.event.ActionListener()
+ taylorColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
hydrophobicityColour.setText(MessageManager
.getString("label.hydrophobicity"));
- hydrophobicityColour
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- hydrophobicityColour_actionPerformed(e);
- }
- });
+ hydrophobicityColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hydrophobicityColour_actionPerformed(e);
+ }
+ });
helixColour.setText(MessageManager.getString("label.helix_propensity"));
- helixColour.addActionListener(new java.awt.event.ActionListener()
+ helixColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
strandColour.setText(MessageManager
.getString("label.strand_propensity"));
- strandColour.addActionListener(new java.awt.event.ActionListener()
+ strandColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
}
});
turnColour.setText(MessageManager.getString("label.turn_propensity"));
- turnColour.addActionListener(new java.awt.event.ActionListener()
+ turnColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
}
});
buriedColour.setText(MessageManager.getString("label.buried_index"));
- buriedColour.addActionListener(new java.awt.event.ActionListener()
+ buriedColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
userDefinedColour.setText(MessageManager
.getString("action.user_defined"));
- userDefinedColour.addActionListener(new java.awt.event.ActionListener()
+ userDefinedColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
PIDColour
.setText(MessageManager.getString("label.percentage_identity"));
- PIDColour.addActionListener(new java.awt.event.ActionListener()
+ PIDColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
BLOSUM62Colour
.setText(MessageManager.getString("label.blosum62_score"));
- BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()
+ BLOSUM62Colour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
}
});
nucleotideColour.setText(MessageManager.getString("label.nucleotide"));
- nucleotideColour.addActionListener(new java.awt.event.ActionListener()
+ nucleotideColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
purinePyrimidineColour.setText(MessageManager
.getString("label.purine_pyrimidine"));
- purinePyrimidineColour
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- purinePyrimidineColour_actionPerformed(e);
- }
- });
+ purinePyrimidineColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ purinePyrimidineColour_actionPerformed(e);
+ }
+ });
RNAInteractionColour.setText("RNA Interaction type");
- RNAInteractionColour
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- RNAInteractionColour_actionPerformed(e);
- }
- });
+ RNAInteractionColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ RNAInteractionColour_actionPerformed(e);
+ }
+ });
/*
* covariationColour.setText("Covariation");
- * covariationColour.addActionListener(new java.awt.event.ActionListener() {
- * public void actionPerformed(ActionEvent e) {
- * covariationColour_actionPerformed(e); } });
+ * covariationColour.addActionListener(new ActionListener() { public void
+ * actionPerformed(ActionEvent e) { covariationColour_actionPerformed(e); }
+ * });
*/
avDistanceTreeBlosumMenuItem.setText(MessageManager
.getString("label.average_distance_bloslum62"));
- avDistanceTreeBlosumMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- avTreeBlosumMenuItem_actionPerformed(e);
- }
- });
+ avDistanceTreeBlosumMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ avTreeBlosumMenuItem_actionPerformed(e);
+ }
+ });
njTreeBlosumMenuItem.setText(MessageManager
.getString("label.neighbour_blosum62"));
- njTreeBlosumMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- njTreeBlosumMenuItem_actionPerformed(e);
- }
- });
+ njTreeBlosumMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ njTreeBlosumMenuItem_actionPerformed(e);
+ }
+ });
annotationPanelMenuItem.setActionCommand("");
annotationPanelMenuItem.setText(MessageManager
.getString("label.show_annotations"));
});
colourTextMenuItem.setText(MessageManager
.getString("label.colour_text"));
- colourTextMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- colourTextMenuItem_actionPerformed(e);
- }
- });
+ colourTextMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ colourTextMenuItem_actionPerformed(e);
+ }
+ });
htmlMenuItem.setText(MessageManager.getString("label.html"));
- htmlMenuItem.addActionListener(new java.awt.event.ActionListener()
+ htmlMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
overviewMenuItem.setText(MessageManager
.getString("label.overview_window"));
- overviewMenuItem.addActionListener(new java.awt.event.ActionListener()
+ overviewMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
overviewMenuItem_actionPerformed(e);
}
});
+
undoMenuItem.setEnabled(false);
undoMenuItem.setText(MessageManager.getString("action.undo"));
- undoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_Z, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- undoMenuItem.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
undoMenuItem_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, undoMenuItem, al);
+
redoMenuItem.setEnabled(false);
redoMenuItem.setText(MessageManager.getString("action.redo"));
- redoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_Y, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- redoMenuItem.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
redoMenuItem_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, redoMenuItem, al);
+
conservationMenuItem.setText(MessageManager
.getString("action.by_conservation"));
- conservationMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- conservationMenuItem_actionPerformed(e);
- }
- });
+ conservationMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ conservationMenuItem_actionPerformed(e);
+ }
+ });
noColourmenuItem.setText(MessageManager.getString("label.none"));
- noColourmenuItem.addActionListener(new java.awt.event.ActionListener()
+ noColourmenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
}
});
wrapMenuItem.setText(MessageManager.getString("label.wrap"));
- wrapMenuItem.addActionListener(new java.awt.event.ActionListener()
+ wrapMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
wrapMenuItem_actionPerformed(e);
}
});
+
printMenuItem.setText(MessageManager.getString("action.print") + "...");
- printMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_P, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- printMenuItem.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_P, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
printMenuItem_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, printMenuItem, al);
+
renderGapsMenuItem
.setText(MessageManager.getString("action.show_gaps"));
renderGapsMenuItem.setState(true);
- renderGapsMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- renderGapsMenuItem_actionPerformed(e);
- }
- });
+ renderGapsMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ renderGapsMenuItem_actionPerformed(e);
+ }
+ });
+
findMenuItem.setText(MessageManager.getString("action.find"));
- findMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_F, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
findMenuItem.setToolTipText(JvSwingUtils.wrapTooltip(true,
MessageManager.getString("label.find_tip")));
- findMenuItem.addActionListener(new java.awt.event.ActionListener()
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
findMenuItem_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, findMenuItem, al);
+
abovePIDThreshold.setText(MessageManager
.getString("label.above_identity_threshold"));
- abovePIDThreshold.addActionListener(new java.awt.event.ActionListener()
+ abovePIDThreshold.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
buttonGroup.add(showAutoLast);
showAutoFirst.setText(MessageManager.getString("label.show_first"));
showAutoFirst.setSelected(Cache.getDefault(
- Preferences.SHOW_AUTOCALC_ABOVE,
- false));
+ Preferences.SHOW_AUTOCALC_ABOVE, false));
showAutoFirst.addActionListener(new ActionListener()
{
@Override
});
nucleotideColour.setText(MessageManager.getString("label.nucleotide"));
- nucleotideColour.addActionListener(new java.awt.event.ActionListener()
+ nucleotideColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
deleteGroups
.setText(MessageManager.getString("action.undefine_groups"));
- deleteGroups.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_U, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- deleteGroups.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_U, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
deleteGroups_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, deleteGroups, al);
+
createGroup.setText(MessageManager.getString("action.create_groups"));
- createGroup.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_G, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- createGroup.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
createGroup_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, createGroup, al);
+
unGroup.setText(MessageManager.getString("action.remove_group"));
- unGroup.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_G, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask()
- | java.awt.event.KeyEvent.SHIFT_MASK, false));
- unGroup.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask()
+ | KeyEvent.SHIFT_MASK, false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
unGroup_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, unGroup, al);
+
copy.setText(MessageManager.getString("action.copy"));
- copy.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_C, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
- copy.addActionListener(new java.awt.event.ActionListener()
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
copy_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, copy, al);
+
cut.setText(MessageManager.getString("action.cut"));
- cut.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_X, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- cut.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
cut_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, cut, al);
+
delete.setText(MessageManager.getString("action.delete"));
- delete.addActionListener(new java.awt.event.ActionListener()
+ delete.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
delete_actionPerformed(e);
}
});
+
pasteMenu.setText(MessageManager.getString("action.paste"));
pasteNew.setText(MessageManager.getString("label.to_new_alignment"));
- pasteNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_V, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask()
- | java.awt.event.KeyEvent.SHIFT_MASK, false));
- pasteNew.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask()
+ | KeyEvent.SHIFT_MASK, false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
pasteNew_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, pasteNew, al);
+
pasteThis.setText(MessageManager.getString("label.to_this_alignment"));
- pasteThis.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_V, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- pasteThis.addActionListener(new java.awt.event.ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
pasteThis_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, pasteThis, al);
+
applyToAllGroups.setText(MessageManager
.getString("label.apply_colour_to_all_groups"));
- applyToAllGroups.addActionListener(new java.awt.event.ActionListener()
+ applyToAllGroups.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
applyToAllGroups_actionPerformed(e);
}
});
- createPNG.addActionListener(new java.awt.event.ActionListener()
+ createPNG.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
createPNG.setText("PNG");
font.setText(MessageManager.getString("action.font"));
- font.addActionListener(new java.awt.event.ActionListener()
+ font.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
seqLimits.setText(MessageManager
.getString("label.show_sequence_limits"));
seqLimits.setState(jalview.bin.Cache.getDefault("SHOW_JVSUFFIX", true));
- seqLimits.addActionListener(new java.awt.event.ActionListener()
+ seqLimits.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
}
});
epsFile.setText("EPS");
- epsFile.addActionListener(new java.awt.event.ActionListener()
+ epsFile.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
createSVG.setText("SVG");
- createSVG.addActionListener(new java.awt.event.ActionListener()
+ createSVG.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
.getString("label.load_tree_for_sequence_set"));
LoadtreeMenuItem.setText(MessageManager
.getString("label.load_associated_tree"));
- LoadtreeMenuItem.addActionListener(new java.awt.event.ActionListener()
+ LoadtreeMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
scaleAbove.setVisible(false);
scaleAbove.setText(MessageManager.getString("action.scale_above"));
- scaleAbove.addActionListener(new java.awt.event.ActionListener()
+ scaleAbove.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
scaleLeft.setVisible(false);
scaleLeft.setSelected(true);
scaleLeft.setText(MessageManager.getString("action.scale_left"));
- scaleLeft.addActionListener(new java.awt.event.ActionListener()
+ scaleLeft.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
scaleRight.setVisible(false);
scaleRight.setSelected(true);
scaleRight.setText(MessageManager.getString("action.scale_right"));
- scaleRight.addActionListener(new java.awt.event.ActionListener()
+ scaleRight.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
centreColumnLabelsMenuItem.setState(false);
centreColumnLabelsMenuItem.setText(MessageManager
.getString("label.centre_column_labels"));
- centreColumnLabelsMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- centreColumnLabels_actionPerformed(e);
- }
- });
+ centreColumnLabelsMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ centreColumnLabels_actionPerformed(e);
+ }
+ });
followHighlightMenuItem.setVisible(true);
followHighlightMenuItem.setState(true);
followHighlightMenuItem.setText(MessageManager
modifyPID.setText(MessageManager
.getString("label.modify_identity_thereshold"));
- modifyPID.addActionListener(new java.awt.event.ActionListener()
+ modifyPID.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
modifyConservation.setText(MessageManager
.getString("label.modify_conservation_thereshold"));
- modifyConservation
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- modifyConservation_actionPerformed(e);
- }
- });
+ modifyConservation.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ modifyConservation_actionPerformed(e);
+ }
+ });
sortByTreeMenu
.setText(MessageManager.getString("action.by_tree_order"));
sort.setText(MessageManager.getString("action.sort"));
showTranslation_actionPerformed(e);
}
});
+
+ /*
+ * cDNA menu options
+ */
+ cdna.setText(MessageManager.getString("label.cdna"));
+ // link to available cDNA
+ JMenuItem linkCdna = new JMenuItem(
+ MessageManager.getString("label.link_cdna"));
+ linkCdna.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ MessageManager.getString("label.link_cdna_tip")));
+ linkCdna.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ linkCdna_actionPerformed();
+ }
+ });
+ cdna.add(linkCdna);
+ // align linked cDNA
+ JMenuItem alignCdna = new JMenuItem(
+ MessageManager.getString("label.align_cdna"));
+ alignCdna.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ MessageManager.getString("label.align_cdna_tip")));
+ alignCdna.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ alignCdna_actionPerformed();
+ }
+ });
+ cdna.add(alignCdna);
+
+ // view alignment as cDNA (when known)
+ JMenuItem viewAsCdna = new JMenuItem(
+ MessageManager.getString("label.view_as_cdna"));
+ viewAsCdna.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ MessageManager.getString("label.view_as_cdna_tip")));
+ viewAsCdna.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ viewAsCdna_actionPerformed();
+ }
+ });
+ cdna.add(viewAsCdna);
+
extractScores.setText(MessageManager.getString("label.extract_scores")
+ "...");
extractScores.addActionListener(new ActionListener()
extractScores_actionPerformed(e);
}
});
- extractScores.setVisible(true); // JBPNote: TODO: make gui for regex based
- // score extraction
+ extractScores.setVisible(true);
+ // JBPNote: TODO: make gui for regex based score extraction
+
+ // for show products actions see AlignFrame.canShowProducts
showProducts.setText(MessageManager.getString("label.get_cross_refs"));
- /*
- * showProducts.addActionListener(new ActionListener() {
- *
- * public void actionPerformed(ActionEvent e) {
- * showProducts_actionPerformed(e); } });
- */
openFeatureSettings.setText(MessageManager
.getString("label.feature_settings"));
openFeatureSettings.addActionListener(new ActionListener()
hiddenMarkers_actionPerformed(e);
}
});
+
invertColSel.setText(MessageManager
.getString("action.invert_column_selection"));
- invertColSel.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_I, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask()
- | java.awt.event.KeyEvent.ALT_MASK, false));
- invertColSel.addActionListener(new ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_I,
+ Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
+ | KeyEvent.ALT_MASK, false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
invertColSel_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, invertColSel, al);
+
tabbedPane.addChangeListener(new javax.swing.event.ChangeListener()
{
@Override
tabbedPane_focusGained(e);
}
});
+
save.setText(MessageManager.getString("action.save"));
- save.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_S, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- save.addActionListener(new ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
save_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, save, al);
+
reload.setEnabled(false);
reload.setText(MessageManager.getString("action.reload"));
reload.addActionListener(new ActionListener()
reload_actionPerformed(e);
}
});
+
newView.setText(MessageManager.getString("action.new_view"));
- newView.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_T, Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask(), false));
- newView.addActionListener(new ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit
+ .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
newView_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, newView, al);
+
tabbedPane.setToolTipText("<html><i>"
+ MessageManager.getString("label.rename_tab_eXpand_reGroup")
+ "</i></html>");
idRightAlign_actionPerformed(e);
}
});
+
gatherViews.setEnabled(false);
gatherViews.setText(MessageManager.getString("action.gather_views"));
- gatherViews.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_G, 0, false));
- gatherViews.addActionListener(new ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, 0, false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
gatherViews_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, gatherViews, al);
+
expandViews.setEnabled(false);
expandViews.setText(MessageManager.getString("action.expand_views"));
- expandViews.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_X, 0, false));
- expandViews.addActionListener(new ActionListener()
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_X, 0, false);
+ al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
expandViews_actionPerformed(e);
}
- });
+ };
+ addMenuActionAndAccelerator(keyStroke, expandViews, al);
+
pageSetup
.setText(MessageManager.getString("action.page_setup") + "...");
pageSetup.addActionListener(new ActionListener()
calculateMenu.add(PCAMenuItem);
calculateMenu.addSeparator();
calculateMenu.add(showTranslation);
+ calculateMenu.add(cdna);
calculateMenu.add(showProducts);
calculateMenu.add(autoCalculate);
calculateMenu.add(sortByTree);
}
/**
+ * 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.
+ *
+ * @param keyStroke
+ * @param menuItem
+ * @param actionListener
+ */
+ protected void addMenuActionAndAccelerator(KeyStroke keyStroke,
+ JMenuItem menuItem, ActionListener actionListener)
+ {
+ menuItem.setAccelerator(keyStroke);
+ accelerators.put(keyStroke, menuItem);
+ menuItem.addActionListener(actionListener);
+ }
+
+ protected void viewAsCdna_actionPerformed()
+ {
+ }
+
+ protected void alignCdna_actionPerformed()
+ {
+ }
+
+ protected void linkCdna_actionPerformed()
+ {
+ }
+
+ /**
* Action on clicking sort annotations by type.
*
* @param sortOrder
{
}
- protected void showProducts_actionPerformed(ActionEvent e)
- {
- }
-
protected void buildSortByAnnotationScoresMenu()
{
}
{
this.annotationSortOrder = annotationSortOrder;
}
+
+ public Map<KeyStroke, JMenuItem> getAccelerators()
+ {
+ return this.accelerators;
+ }
}
--- /dev/null
+package jalview.jbgui;
+
+import javax.swing.JComponent;
+import javax.swing.JInternalFrame;
+import javax.swing.JSplitPane;
+
+public class GSplitFrame extends JInternalFrame
+{
+ private static final long serialVersionUID = 1L;
+
+ private JComponent topComponent;
+
+ private JComponent bottomComponent;
+
+ /**
+ * Constructor
+ *
+ * @param top
+ * @param bottom
+ */
+ public GSplitFrame(JComponent top, JComponent bottom)
+ {
+ this.topComponent = top;
+ this.bottomComponent = bottom;
+ JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, top,
+ bottom);
+ splitPane.setVisible(true);
+ add(splitPane);
+ splitPane.setDividerLocation(0.5d);
+ splitPane.setResizeWeight(0.5d);
+ splitPane.setDividerSize(0);
+ }
+
+ public JComponent getTopComponent()
+ {
+ return topComponent;
+ }
+
+ public JComponent getBottomComponent()
+ {
+ return bottomComponent;
+ }
+}
import jalview.util.MessageManager;
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-import javax.swing.event.*;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JInternalFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
public class GTreePanel extends JInternalFrame
{
{
public void actionPerformed(ActionEvent e)
{
- sortByTree_actionPerformed(e);
+ sortByTree_actionPerformed();
}
});
font.setText(MessageManager.getString("action.font"));
{
}
- public void sortByTree_actionPerformed(ActionEvent e)
+ public void sortByTree_actionPerformed()
{
}
import java.awt.Color;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
public static final int[] purinepyrimidineIndex;
- public static final Hashtable aa3Hash = new Hashtable();
+ public static final Map<String, Integer> aa3Hash = new HashMap<String, Integer>();
- public static final Hashtable aa2Triplet = new Hashtable();
+ public static final Map<String, String> aa2Triplet = new HashMap<String, String>();
- public static final Hashtable nucleotideName = new Hashtable();
+ public static final Map<String, String> nucleotideName = new HashMap<String, String>();
static
{
public static Vector STOP = new Vector();
+ public static String START = "ATG";
+
static
{
codonHash.put("K", Lys);
return hyd;
}
- public static Hashtable getAA3Hash()
+ public static Map<String, Integer> getAA3Hash()
{
return aa3Hash;
}
--- /dev/null
+package jalview.structure;
+
+/**
+ * Java bean representing an atom in a PDB (or similar) structure model.
+ *
+ * @author gmcarstairs
+ *
+ */
+public class AtomSpec
+{
+ // TODO clarify do we want pdbFile here, or pdbId?
+ // compare highlightAtom in 2.8.2 for JalviewJmolBinding and
+ // javascript.MouseOverStructureListener
+ private String pdbFile;
+
+ private String chain;
+
+ private int pdbResNum;
+
+ private int atomIndex;
+
+ /**
+ * Constructor
+ *
+ * @param pdbFile
+ * @param chain
+ * @param resNo
+ * @param atomNo
+ */
+ public AtomSpec(String pdbFile, String chain, int resNo, int atomNo)
+ {
+ this.pdbFile = pdbFile;
+ this.chain = chain;
+ this.pdbResNum = resNo;
+ this.atomIndex = atomNo;
+ }
+
+ public String getPdbFile()
+ {
+ return pdbFile;
+ }
+
+ public String getChain()
+ {
+ return chain;
+ }
+
+ public int getPdbResNum()
+ {
+ return pdbResNum;
+ }
+
+ public int getAtomIndex()
+ {
+ return atomIndex;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "pdbFile: " + pdbFile + ", chain: " + chain + ", res: "
+ + pdbResNum + ", atom: " + atomIndex;
+ }
+}
--- /dev/null
+package jalview.structure;
+
+import jalview.commands.CommandI;
+
+/**
+ * Defines a listener for commands performed on another alignment. This is to
+ * support linked editing of two alternative representations of an alignment (in
+ * particular, cDNA and protein).
+ *
+ * @author gmcarstairs
+ *
+ */
+public interface CommandListener
+{
+ /**
+ * The listener may attempt to perform the specified command; the region acted
+ * on is determined by a callback to the StructureSelectionManager (which
+ * holds mappings between alignments).
+ *
+ * @param command
+ * @param undo
+ * @param ssm
+ * @param source
+ * the originator of the command
+ */
+ public void mirrorCommand(CommandI command, boolean undo,
+ StructureSelectionManager ssm, VamsasSource source);
+
+ /**
+ * Temporary workaround to make check for source == listener work.
+ *
+ * @return
+ */
+ public VamsasSource getVamsasSource();
+}
*/
package jalview.structure;
-import jalview.datamodel.*;
+import jalview.datamodel.SequenceI;
+
public interface SequenceListener
{
public void highlightSequence(jalview.datamodel.SearchResults results);
public void updateColours(SequenceI sequence, int index);
+
+ public VamsasSource getVamsasSource();
+
}
*/
package jalview.structure;
+import java.util.List;
+
public interface StructureListener
{
/**
- *
- * @return list of structure files (unique IDs/filenames) that this listener
- * handles messages for, or null if generic listener (only used by
- * removeListener method)
+ * Returns a list of structure files (unique IDs/filenames) that this listener
+ * handles messages for, or null if generic listener (only used by
+ * removeListener method)
*/
public String[] getPdbFile();
/**
- * NOT A LISTENER METHOD! called by structure viewer when the given
- * atom/structure has been moused over. Typically, implementors call
- * StructureSelectionManager.mouseOverStructure
- *
- * @param atomIndex
- * @param strInfo
- */
- public void mouseOverStructure(int atomIndex, String strInfo);
-
- /**
- * called by StructureSelectionManager to inform viewer to highlight given
- * atomspec
+ * Called by StructureSelectionManager to inform viewer to highlight given
+ * atom positions
*
- * @param atomIndex
- * @param pdbResNum
- * @param chain
- * @param pdbId
+ * @param atoms
*/
- public void highlightAtom(int atomIndex, int pdbResNum, String chain,
- String pdbId);
+ public void highlightAtoms(List<AtomSpec> atoms);
/**
- * called by StructureSelectionManager when the colours of a sequence
+ * Called by StructureSelectionManager when the colours of a sequence
* associated with a structure have changed.
*
* @param source
public void updateColours(Object source);
/**
- * called by Jalview to get the colour for the given atomspec
- *
- * @param atomIndex
- * @param pdbResNum
- * @param chain
- * @param pdbId
- * @return
- */
- public java.awt.Color getColour(int atomIndex, int pdbResNum,
- String chain, String pdbId);
-
- /**
- * called by structureSelectionManager to instruct implementor to release any
+ * Called by structureSelectionManager to instruct implementor to release any
* direct references it may hold to the given object (typically, these are
* Jalview alignment panels).
*
import jalview.analysis.AlignSeq;
import jalview.api.StructureSelectionManagerProvider;
+import jalview.commands.CommandI;
+import jalview.commands.EditCommand;
+import jalview.commands.OrderCommand;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SearchResults;
import jalview.datamodel.SequenceI;
import jalview.io.AppletFormatAdapter;
+import jalview.util.MappingUtils;
import jalview.util.MessageManager;
import java.io.PrintStream;
+import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.IdentityHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.Vector;
import MCview.Atom;
{
static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
- StructureMapping[] mappings;
+ private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
- private boolean processSecondaryStructure = false,
- secStructServices = false, addTempFacAnnot = false;
+ private boolean processSecondaryStructure = false;
+
+ private boolean secStructServices = false;
+
+ private boolean addTempFacAnnot = false;
+
+ /*
+ * Set of any registered mappings between (dataset) sequences.
+ */
+ Set<AlignedCodonFrame> seqmappings = new LinkedHashSet<AlignedCodonFrame>();
+
+ /*
+ * Reference counters for the above mappings. Remove mappings when ref count
+ * goes to zero.
+ */
+ Map<AlignedCodonFrame, Integer> seqMappingRefCounts = new HashMap<AlignedCodonFrame, Integer>();
+
+ private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
+
+ private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
/**
* @return true if will try to use external services for processing secondary
*/
public void reportMapping()
{
- if (mappings == null)
+ if (mappings.isEmpty())
{
System.err.println("reportMapping: No PDB/Sequence mappings.");
}
else
{
- System.err.println("reportMapping: There are " + mappings.length
+ System.err.println("reportMapping: There are " + mappings.size()
+ " mappings.");
- for (int m = 0; m < mappings.length; m++)
+ int i = 0;
+ for (StructureMapping sm : mappings)
{
- System.err.println("mapping " + m + " : " + mappings[m].pdbfile);
+ System.err.println("mapping " + i++ + " : " + sm.pdbfile);
}
}
}
}
}
+ /**
+ * Returns the file name for a mapped PDB id (or null if not mapped).
+ *
+ * @param pdbid
+ * @return
+ */
public String alreadyMappedToFile(String pdbid)
{
- if (mappings != null)
+ for (StructureMapping sm : mappings)
{
- for (int i = 0; i < mappings.length; i++)
+ if (sm.getPdbId().equals(pdbid))
{
- if (mappings[i].getPdbId().equals(pdbid))
- {
- return mappings[i].pdbfile;
- }
+ return sm.pdbfile;
}
}
return null;
mappingDetails.toString());
if (forStructureView)
{
-
- if (mappings == null)
- {
- mappings = new StructureMapping[1];
- }
- else
- {
- StructureMapping[] tmp = new StructureMapping[mappings.length + 1];
- System.arraycopy(mappings, 0, tmp, 0, mappings.length);
- mappings = tmp;
- }
-
- mappings[mappings.length - 1] = newMapping;
+ mappings.add(newMapping);
}
maxChain.transferResidueAnnotation(newMapping, sqmpping);
}
}
}
- if (pdbs.size() > 0 && mappings != null)
+ if (pdbs.size() > 0)
{
- Vector tmp = new Vector();
- for (int i = 0; i < mappings.length; i++)
+ List<StructureMapping> tmp = new ArrayList<StructureMapping>();
+ for (StructureMapping sm : mappings)
{
- if (!pdbs.contains(mappings[i].pdbfile))
+ if (!pdbs.contains(sm.pdbfile))
{
- tmp.addElement(mappings[i]);
+ tmp.add(sm);
}
}
- mappings = new StructureMapping[tmp.size()];
- tmp.copyInto(mappings);
+ mappings = tmp;
}
}
// old or prematurely sent event
return;
}
- boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null;
SearchResults results = null;
SequenceI lastseq = null;
int lastipos = -1, indexpos;
{
results = new SearchResults();
}
- if (mappings != null)
+ for (StructureMapping sm : mappings)
{
- for (int j = 0; j < mappings.length; j++)
+ if (sm.pdbfile.equals(pdbfile) && sm.pdbchain.equals(chain))
{
- if (mappings[j].pdbfile.equals(pdbfile)
- && mappings[j].pdbchain.equals(chain))
+ indexpos = sm.getSeqPos(pdbResNum);
+ if (lastipos != indexpos && lastseq != sm.sequence)
{
- indexpos = mappings[j].getSeqPos(pdbResNum);
- if (lastipos != indexpos && lastseq != mappings[j].sequence)
+ results.addResult(sm.sequence, indexpos, indexpos);
+ lastipos = indexpos;
+ lastseq = sm.sequence;
+ // construct highlighted sequence list
+ for (AlignedCodonFrame acf : seqmappings)
{
- results.addResult(mappings[j].sequence, indexpos, indexpos);
- lastipos = indexpos;
- lastseq = mappings[j].sequence;
- // construct highlighted sequence list
- if (seqmappings != null)
- {
-
- Enumeration e = seqmappings.elements();
- while (e.hasMoreElements())
-
- {
- ((AlignedCodonFrame) e.nextElement()).markMappedRegion(
- mappings[j].sequence, indexpos, results);
- }
- }
+ acf.markMappedRegion(sm.sequence, indexpos, results);
}
-
}
}
}
}
}
- Vector seqmappings = null; // should be a simpler list of mapped seuqence
-
/**
* highlight regions associated with a position (indexpos) in seq
*
* @param seq
- * the sequeence that the mouse over occured on
+ * the sequence that the mouse over occurred on
* @param indexpos
* the absolute position being mouseovered in seq (0 to seq.length())
* @param index
public void mouseOverSequence(SequenceI seq, int indexpos, int index,
VamsasSource source)
{
- boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null;
+ boolean hasSequenceListeners = handlingVamsasMo
+ || !seqmappings.isEmpty();
SearchResults results = null;
if (index == -1)
{
index = seq.findPosition(indexpos);
}
- StructureListener sl;
- int atomNo = 0;
for (int i = 0; i < listeners.size(); i++)
{
Object listener = listeners.elementAt(i);
if (listener == source)
{
+ // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
+ // Temporary fudge with SequenceListener.getVamsasSource()
continue;
}
if (listener instanceof StructureListener)
{
- sl = (StructureListener) listener;
- if (mappings == null)
- {
- continue;
- }
- for (int j = 0; j < mappings.length; j++)
- {
- if (mappings[j].sequence == seq
- || mappings[j].sequence == seq.getDatasetSequence())
- {
- atomNo = mappings[j].getAtomNum(index);
-
- if (atomNo > 0)
- {
- sl.highlightAtom(atomNo, mappings[j].getPDBResNum(index),
- mappings[j].pdbchain, mappings[j].pdbfile);
- }
- }
- }
+ highlightStructure((StructureListener) listener, seq, index);
}
else
{
- if (relaySeqMappings && hasSequenceListeners
- && listener instanceof SequenceListener)
+ if (listener instanceof SequenceListener)
{
- // DEBUG
- // System.err.println("relay Seq " + seq.getDisplayId(false) + " " +
- // index);
-
- if (results == null)
+ final SequenceListener seqListener = (SequenceListener) listener;
+ if (hasSequenceListeners
+ && seqListener.getVamsasSource() != source)
{
- results = new SearchResults();
- if (index >= seq.getStart() && index <= seq.getEnd())
+ if (relaySeqMappings)
{
- // construct highlighted sequence list
-
- if (seqmappings != null)
+ if (results == null)
{
- Enumeration e = seqmappings.elements();
- while (e.hasMoreElements())
-
- {
- ((AlignedCodonFrame) e.nextElement()).markMappedRegion(
- seq, index, results);
- }
+ results = MappingUtils.buildSearchResults(seq, index,
+ seqmappings);
}
- // hasSequenceListeners = results.getSize() > 0;
if (handlingVamsasMo)
{
- // maybe have to resolve seq to a dataset seqeunce...
- // add in additional direct sequence and/or dataset sequence
- // highlighting
results.addResult(seq, index, index);
+
}
+ seqListener.highlightSequence(results);
}
}
- if (hasSequenceListeners)
- {
- ((SequenceListener) listener).highlightSequence(results);
- }
}
else if (listener instanceof VamsasListener && !handlingVamsasMo)
{
- // DEBUG
- // System.err.println("Vamsas from Seq " + seq.getDisplayId(false) + "
- // " +
- // index);
- // pass the mouse over and absolute position onto the
- // VamsasListener(s)
- ((VamsasListener) listener).mouseOver(seq, indexpos, source);
+ ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
+ source);
}
else if (listener instanceof SecondaryStructureListener)
{
}
/**
+ * Send suitable messages to a StructureListener to highlight atoms
+ * corresponding to the given sequence position.
+ *
+ * @param sl
+ * @param seq
+ * @param index
+ */
+ protected void highlightStructure(StructureListener sl, SequenceI seq,
+ int index)
+ {
+ int atomNo;
+ List<AtomSpec> atoms = new ArrayList<AtomSpec>();
+ for (StructureMapping sm : mappings)
+ {
+ if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence())
+ {
+ atomNo = sm.getAtomNum(index);
+
+ if (atomNo > 0)
+ {
+ atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
+ .getPDBResNum(index), atomNo));
+ }
+ }
+ }
+ sl.highlightAtoms(atoms);
+ }
+
+ /**
* true if a mouse over event from an external (ie Vamsas) source is being
* handled
*/
public StructureMapping[] getMapping(String pdbfile)
{
- Vector tmp = new Vector();
- if (mappings != null)
- {
- for (int i = 0; i < mappings.length; i++)
+ List<StructureMapping> tmp = new ArrayList<StructureMapping>();
+ for (StructureMapping sm : mappings)
{
- if (mappings[i].pdbfile.equals(pdbfile))
+ if (sm.pdbfile.equals(pdbfile))
{
- tmp.addElement(mappings[i]);
+ tmp.add(sm);
}
- }
}
- StructureMapping[] ret = new StructureMapping[tmp.size()];
- for (int i = 0; i < tmp.size(); i++)
- {
- ret[i] = (StructureMapping) tmp.elementAt(i);
- }
-
- return ret;
+ return tmp.toArray(new StructureMapping[tmp.size()]);
}
public String printMapping(String pdbfile)
{
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < mappings.length; i++)
+ StringBuilder sb = new StringBuilder(64);
+ for (StructureMapping sm : mappings)
{
- if (mappings[i].pdbfile.equals(pdbfile))
+ if (sm.pdbfile.equals(pdbfile))
{
- sb.append(mappings[i].mappingDetails);
+ sb.append(sm.mappingDetails);
}
}
return sb.toString();
}
- private int[] seqmappingrefs = null; // refcount for seqmappings elements
-
- private synchronized void modifySeqMappingList(boolean add,
- AlignedCodonFrame[] codonFrames)
+ /**
+ * Decrement the reference counter for each of the given mappings, and remove
+ * it entirely if its reference counter reduces to zero.
+ *
+ * @param set
+ */
+ public void removeMappings(Set<AlignedCodonFrame> set)
{
- if (!add && (seqmappings == null || seqmappings.size() == 0))
- {
- return;
- }
- if (seqmappings == null)
+ if (set != null)
{
- seqmappings = new Vector();
+ for (AlignedCodonFrame acf : set)
+ {
+ removeMapping(acf);
+ }
}
- if (codonFrames != null && codonFrames.length > 0)
+ }
+
+ /**
+ * Decrement the reference counter for the given mapping, and remove it
+ * entirely if its reference counter reduces to zero.
+ *
+ * @param acf
+ */
+ public void removeMapping(AlignedCodonFrame acf)
+ {
+ if (acf != null && seqmappings.contains(acf))
{
- for (int cf = 0; cf < codonFrames.length; cf++)
+ int count = seqMappingRefCounts.get(acf);
+ count--;
+ if (count > 0)
{
- if (seqmappings.contains(codonFrames[cf]))
- {
- if (add)
- {
- seqmappingrefs[seqmappings.indexOf(codonFrames[cf])]++;
- }
- else
- {
- if (--seqmappingrefs[seqmappings.indexOf(codonFrames[cf])] <= 0)
- {
- int pos = seqmappings.indexOf(codonFrames[cf]);
- int[] nr = new int[seqmappingrefs.length - 1];
- if (pos > 0)
- {
- System.arraycopy(seqmappingrefs, 0, nr, 0, pos);
- }
- if (pos < seqmappingrefs.length - 1)
- {
- System.arraycopy(seqmappingrefs, pos + 1, nr, 0,
- seqmappingrefs.length - pos - 2);
- }
- }
- }
- }
- else
- {
- if (add)
- {
- seqmappings.addElement(codonFrames[cf]);
-
- int[] nsr = new int[(seqmappingrefs == null) ? 1
- : seqmappingrefs.length + 1];
- if (seqmappingrefs != null && seqmappingrefs.length > 0)
- {
- System.arraycopy(seqmappingrefs, 0, nsr, 0,
- seqmappingrefs.length);
- }
- nsr[(seqmappingrefs == null) ? 0 : seqmappingrefs.length] = 1;
- seqmappingrefs = nsr;
- }
- }
+ seqMappingRefCounts.put(acf, count);
+ }
+ else
+ {
+ seqmappings.remove(acf);
+ seqMappingRefCounts.remove(acf);
}
}
}
- public void removeMappings(AlignedCodonFrame[] codonFrames)
+ /**
+ * Add each of the given codonFrames to the stored set. If not aready present,
+ * increments its reference count instead.
+ *
+ * @param set
+ */
+ public void addMappings(Set<AlignedCodonFrame> set)
{
- modifySeqMappingList(false, codonFrames);
+ if (set != null)
+ {
+ for (AlignedCodonFrame acf : set)
+ {
+ addMapping(acf);
+ }
+ }
}
- public void addMappings(AlignedCodonFrame[] codonFrames)
+ /**
+ * Add the given mapping to the stored set, or if already stored, increment
+ * its reference counter.
+ */
+ public void addMapping(AlignedCodonFrame acf)
{
- modifySeqMappingList(true, codonFrames);
+ if (acf != null)
+ {
+ if (seqmappings.contains(acf))
+ {
+ seqMappingRefCounts.put(acf, seqMappingRefCounts.get(acf) + 1);
+ }
+ else
+ {
+ seqmappings.add(acf);
+ seqMappingRefCounts.put(acf, 1);
+ }
+ }
}
- Vector<SelectionListener> sel_listeners = new Vector<SelectionListener>();
-
public void addSelectionListener(SelectionListener selecter)
{
if (!sel_listeners.contains(selecter))
{
- sel_listeners.addElement(selecter);
+ sel_listeners.add(selecter);
}
}
{
if (sel_listeners.contains(toremove))
{
- sel_listeners.removeElement(toremove);
+ sel_listeners.remove(toremove);
}
}
jalview.datamodel.SequenceGroup selection,
jalview.datamodel.ColumnSelection colsel, SelectionSource source)
{
- if (sel_listeners != null && sel_listeners.size() > 0)
+ for (SelectionListener slis : sel_listeners)
{
- Enumeration listeners = sel_listeners.elements();
- while (listeners.hasMoreElements())
+ if (slis != source)
{
- SelectionListener slis = ((SelectionListener) listeners
- .nextElement());
- if (slis != source)
- {
- slis.selection(selection, colsel, source);
- }
- ;
+ slis.selection(selection, colsel, source);
}
}
}
}
}
- public void finalize() throws Throwable
- {
- if (listeners != null)
- {
- listeners.clear();
- listeners = null;
- }
- if (pdbIdFileName != null)
- {
- pdbIdFileName.clear();
- pdbIdFileName = null;
- }
- if (sel_listeners != null)
- {
- sel_listeners.clear();
- sel_listeners = null;
- }
- if (view_listeners != null)
- {
- view_listeners.clear();
- view_listeners = null;
- }
- mappings = null;
- seqmappingrefs = null;
- }
-
/**
* release all references associated with this manager provider
*
} catch (Throwable x)
{
}
- ;
}
}
}
}
}
+ public void addCommandListener(CommandListener cl)
+ {
+ if (!commandListeners.contains(cl))
+ {
+ commandListeners.add(cl);
+ }
+ }
+
+ public boolean hasCommandListener(CommandListener cl)
+ {
+ return this.commandListeners.contains(cl);
+ }
+
+ public boolean removeEditListener(CommandListener l)
+ {
+ return commandListeners.remove(l);
+ }
+
+ /**
+ * Forward a command to any command listeners (except for the command's
+ * source).
+ *
+ * @param command
+ * the command to be broadcast (in its form after being performed)
+ * @param undo
+ * if true, the command was being 'undone'
+ * @param source
+ */
+ public void commandPerformed(CommandI command, boolean undo,
+ VamsasSource source)
+ {
+ for (CommandListener listener : commandListeners)
+ {
+ listener.mirrorCommand(command, undo, this, source);
+ }
+ }
+
+ /**
+ * Returns a new CommandI representing the given command as mapped to the
+ * given sequences. If no mapping could be made, or the command is not of a
+ * mappable kind, returns null.
+ *
+ * @param command
+ * @param undo
+ * @param mapTo
+ * @param gapChar
+ * @return
+ */
+ public CommandI mapCommand(CommandI command, boolean undo,
+ final AlignmentI mapTo, char gapChar)
+ {
+ if (command instanceof EditCommand)
+ {
+ return MappingUtils.mapEditCommand((EditCommand) command, undo,
+ mapTo, gapChar, seqmappings);
+ }
+ else if (command instanceof OrderCommand)
+ {
+ return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
+ mapTo, seqmappings);
+ }
+ return null;
+ }
}
*/
public interface VamsasListener
{
- public void mouseOver(SequenceI seq, int index, VamsasSource source);
+ public void mouseOverSequence(SequenceI seq, int index,
+ VamsasSource source);
}
import jalview.api.StructureSelectionManagerProvider;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
+import jalview.structure.AtomSpec;
import jalview.structure.StructureListener;
import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
-import java.awt.event.ComponentEvent;
import java.util.ArrayList;
import java.util.List;
/**
+ *
* A base class to hold common function for protein structure model binding.
* Initial version created by refactoring JMol and Chimera binding models, but
* other structure viewers could in principle be accommodated in future.
}
}
+ @Override
+ public void highlightAtoms(List<AtomSpec> atoms)
+ {
+ if (atoms != null)
+ {
+ for (AtomSpec atom : atoms)
+ {
+ highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
+ atom.getChain(), atom.getPdbFile());
+ }
+ }
+ }
+
+ // TODO Jmol and Chimera seem to expect pdbFile, javascript listener pdbId
+ protected abstract void highlightAtom(int atomIndex, int pdbResNum,
+ String chain, String pdbFile);
+
}
\ No newline at end of file
*/
package jalview.util;
-import jalview.datamodel.*;
+import jalview.datamodel.SequenceI;
/**
- * DOCUMENT ME!
- *
- * @author $author$
- * @version $Revision$
+ * Assorted methods for analysing or comparing sequences.
*/
public class Comparison
{
- /** DOCUMENT ME!! */
- public static final String GapChars = " .-";
+ private static final int EIGHTY_FIVE = 85;
+
+ private static final int TO_UPPER_CASE = 'a' - 'A';
+
+ private static final char GAP_SPACE = ' ';
+
+ private static final char GAP_DOT = '.';
+
+ private static final char GAP_DASH = '-';
+
+ public static final String GapChars = new String(new char[]
+ { GAP_SPACE, GAP_DOT, GAP_DASH });
/**
* DOCUMENT ME!
int ilen = si.length() - 1;
int jlen = sj.length() - 1;
- while (jalview.util.Comparison.isGap(si.charAt(start + ilen)))
+ while (Comparison.isGap(si.charAt(start + ilen)))
{
ilen--;
}
- while (jalview.util.Comparison.isGap(sj.charAt(start + jlen)))
+ while (Comparison.isGap(sj.charAt(start + jlen)))
{
jlen--;
}
}
/**
- * DOCUMENT ME!
+ * Answers true if the supplied character is a recognised gap character, else
+ * false. Currently hard-coded to recognise '-', '-' or ' ' (hyphen / dot /
+ * space).
*
* @param c
- * DOCUMENT ME!
*
- * @return DOCUMENT ME!
+ * @return
*/
public static final boolean isGap(char c)
{
- return (c == '-' || c == '.' || c == ' ') ? true : false;
+ return (c == GAP_DASH || c == GAP_DOT || c == GAP_SPACE) ? true : false;
}
+ /**
+ * Answers true if more than 85% of the sequence residues (ignoring gaps) are
+ * A, G, C, T or U, else false. This is just a heuristic guess and may give a
+ * wrong answer (as AGCT are also animo acid codes).
+ *
+ * @param seqs
+ * @return
+ */
public static final boolean isNucleotide(SequenceI[] seqs)
{
- int i = 0, iSize = seqs.length, j, jSize;
- float nt = 0, aa = 0;
- char c;
- while (i < iSize)
+ if (seqs == null)
+ {
+ return false;
+ }
+ int ntCount = 0;
+ int aaCount = 0;
+ for (SequenceI seq : seqs)
{
- jSize = seqs[i].getLength();
- for (j = 0; j < jSize; j++)
+ for (char c : seq.getSequence())
{
- c = seqs[i].getCharAt(j);
if ('a' <= c && c <= 'z')
{
- c -= ('a' - 'A');
+ c -= TO_UPPER_CASE;
}
if (c == 'A' || c == 'G' || c == 'C' || c == 'T' || c == 'U')
{
- nt++;
+ ntCount++;
}
- else if (!jalview.util.Comparison.isGap(seqs[i].getCharAt(j)))
+ else if (!Comparison.isGap(c))
{
- aa++;
+ aaCount++;
}
}
- i++;
}
- if ((nt / (nt + aa)) > 0.85f)
+ /*
+ * Check for nucleotide count > 85% of total count (in a form that evades
+ * int / float conversion or divide by zero).
+ */
+ if (ntCount * 100 > EIGHTY_FIVE * (ntCount + aaCount))
{
return true;
}
*/
package jalview.util;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
/**
- * MapList Simple way of bijectively mapping a non-contiguous linear range to
- * another non-contiguous linear range Use at your own risk! TODO: efficient
- * implementation of private posMap method TODO: test/ensure that sense of from
- * and to ratio start position is conserved (codon start position recovery)
- * TODO: optimize to use int[][] arrays rather than vectors.
+ * A simple way of bijectively mapping a non-contiguous linear range to another
+ * non-contiguous linear range.
+ *
+ * Use at your own risk!
+ *
+ * TODO: efficient implementation of private posMap method
+ *
+ * TODO: test/ensure that sense of from and to ratio start position is conserved
+ * (codon start position recovery)
*/
public class MapList
{
+
/*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
+ * Subregions (base 1) described as { [start1, end1], [start2, end2], ...}
+ */
+ private List<int[]> fromShifts = new ArrayList<int[]>();
+
+ /*
+ * Same format as fromShifts, for the 'mapped to' sequence
+ */
+ private List<int[]> toShifts = new ArrayList<int[]>();
+
+ /*
+ * number of steps in fromShifts to one toRatio unit
+ */
+ private int fromRatio;
+
+ /*
+ * number of steps in toShifts to one fromRatio
+ */
+ private int toRatio;
+
+ /*
+ * lowest and highest value in the from Map
*/
- public boolean equals(MapList obj)
+ private int fromLowest;
+
+ private int fromHighest;
+
+ /*
+ * lowest and highest value in the to Map
+ */
+ private int toLowest;
+
+ private int toHighest;
+
+ /**
+ * Two MapList objects are equal if they are the same object, or they both
+ * have populated shift ranges and all values are the same.
+ */
+ @Override
+ public boolean equals(Object o)
{
+ if (o == null || !(o instanceof MapList))
+ {
+ return false;
+ }
+
+ MapList obj = (MapList) o;
if (obj == this)
- return true;
- if (obj != null && obj.fromRatio == fromRatio && obj.toRatio == toRatio
- && obj.fromShifts != null && obj.toShifts != null)
{
- int i, iSize = fromShifts.size(), j, jSize = obj.fromShifts.size();
- if (iSize != jSize)
- return false;
- for (i = 0, iSize = fromShifts.size(), j = 0, jSize = obj.fromShifts
- .size(); i < iSize;)
- {
- int[] mi = (int[]) fromShifts.elementAt(i++);
- int[] mj = (int[]) obj.fromShifts.elementAt(j++);
- if (mi[0] != mj[0] || mi[1] != mj[1])
- return false;
- }
- iSize = toShifts.size();
- jSize = obj.toShifts.size();
- if (iSize != jSize)
- return false;
- for (i = 0, j = 0; i < iSize;)
- {
- int[] mi = (int[]) toShifts.elementAt(i++);
- int[] mj = (int[]) obj.toShifts.elementAt(j++);
- if (mi[0] != mj[0] || mi[1] != mj[1])
- return false;
- }
return true;
}
- return false;
+ if (obj.fromRatio != fromRatio || obj.toRatio != toRatio
+ || obj.fromShifts == null || obj.toShifts == null)
+ {
+ return false;
+ }
+ return Arrays
+ .deepEquals(fromShifts.toArray(), obj.fromShifts.toArray())
+ && Arrays
+ .deepEquals(toShifts.toArray(), obj.toShifts.toArray());
}
- public Vector fromShifts;
-
- public Vector toShifts;
-
- int fromRatio; // number of steps in fromShifts to one toRatio unit
-
- int toRatio; // number of steps in toShifts to one fromRatio
-
/**
+ * Returns the flattened 'from' ranges as [start1, end1, start2, end2, ...]
*
- * @return series of intervals mapped in from
+ * @return
*/
public int[] getFromRanges()
{
return getRanges(fromShifts);
}
+ /**
+ * Returns the flattened 'to' ranges as [start1, end1, start2, end2, ...]
+ *
+ * @return
+ */
public int[] getToRanges()
{
return getRanges(toShifts);
}
- private int[] getRanges(Vector shifts)
+ /**
+ * Flattens a list of [start, end] into a single [start1, end1, start2,
+ * end2,...] array.
+ *
+ * @param shifts
+ * @return
+ */
+ protected static int[] getRanges(List<int[]> shifts)
{
int[] rnges = new int[2 * shifts.size()];
- Enumeration e = shifts.elements();
int i = 0;
- while (e.hasMoreElements())
+ for (int[] r : shifts)
{
- int r[] = (int[]) e.nextElement();
rnges[i++] = r[0];
rnges[i++] = r[1];
}
}
/**
- * lowest and highest value in the from Map
- */
- int[] fromRange = null;
-
- /**
- * lowest and highest value in the to Map
- */
- int[] toRange = null;
-
- /**
*
* @return length of mapped phrase in from
*/
public int getFromLowest()
{
- return fromRange[0];
+ return fromLowest;
}
public int getFromHighest()
{
- return fromRange[1];
+ return fromHighest;
}
public int getToLowest()
{
- return toRange[0];
+ return toLowest;
}
public int getToHighest()
{
- return toRange[1];
- }
-
- private void ensureRange(int[] limits, int pos)
- {
- if (limits[0] > pos)
- limits[0] = pos;
- if (limits[1] < pos)
- limits[1] = pos;
+ return toHighest;
}
+ /**
+ * Constructor.
+ *
+ * @param from
+ * contiguous regions as [start1, end1, start2, end2, ...]
+ * @param to
+ * same format as 'from'
+ * @param fromRatio
+ * phrase length in 'from' (e.g. 3 for dna)
+ * @param toRatio
+ * phrase length in 'to' (e.g. 1 for protein)
+ */
public MapList(int from[], int to[], int fromRatio, int toRatio)
{
- fromRange = new int[]
- { from[0], from[1] };
- toRange = new int[]
- { to[0], to[1] };
-
- fromShifts = new Vector();
+ fromLowest = from[0];
+ fromHighest = from[1];
for (int i = 0; i < from.length; i += 2)
{
- ensureRange(fromRange, from[i]);
- ensureRange(fromRange, from[i + 1]);
+ fromLowest = Math.min(fromLowest, from[i]);
+ fromHighest = Math.max(fromHighest, from[i + 1]);
- fromShifts.addElement(new int[]
+ fromShifts.add(new int[]
{ from[i], from[i + 1] });
}
- toShifts = new Vector();
+
+ toLowest = to[0];
+ toHighest = to[1];
for (int i = 0; i < to.length; i += 2)
{
- ensureRange(toRange, to[i]);
- ensureRange(toRange, to[i + 1]);
- toShifts.addElement(new int[]
+ toLowest = Math.min(toLowest, to[i]);
+ toHighest = Math.max(toHighest, to[i + 1]);
+ toShifts.add(new int[]
{ to[i], to[i + 1] });
}
this.fromRatio = fromRatio;
this.toRatio = toRatio;
}
+ /**
+ * Copy constructor. Creates an identical mapping.
+ *
+ * @param map
+ */
public MapList(MapList map)
{
- this.fromRange = new int[]
- { map.fromRange[0], map.fromRange[1] };
- this.toRange = new int[]
- { map.toRange[0], map.toRange[1] };
+ // TODO not used - remove?
+ this.fromLowest = map.fromLowest;
+ this.fromHighest = map.fromHighest;
+ this.toLowest = map.toLowest;
+ this.toHighest = map.toHighest;
+
this.fromRatio = map.fromRatio;
this.toRatio = map.toRatio;
if (map.fromShifts != null)
{
- this.fromShifts = new Vector();
- Enumeration e = map.fromShifts.elements();
- while (e.hasMoreElements())
+ for (int[] r : map.fromShifts)
{
- int[] el = (int[]) e.nextElement();
- fromShifts.addElement(new int[]
- { el[0], el[1] });
+ fromShifts.add(new int[]
+ { r[0], r[1] });
}
}
if (map.toShifts != null)
{
- this.toShifts = new Vector();
- Enumeration e = map.toShifts.elements();
- while (e.hasMoreElements())
+ for (int[] r : map.toShifts)
{
- int[] el = (int[]) e.nextElement();
- toShifts.addElement(new int[]
- { el[0], el[1] });
+ toShifts.add(new int[]
+ { r[0], r[1] });
}
}
}
* @return int[][] { int[] { fromStart, fromFinish, toStart, toFinish }, int
* [fromFinish-fromStart+2] { toStart..toFinish mappings}}
*/
- public int[][] makeFromMap()
+ protected int[][] makeFromMap()
{
+ // TODO not used - remove??
return posMap(fromShifts, fromRatio, toShifts, toRatio);
}
*
* @return int[to position]=position mapped in from
*/
- public int[][] makeToMap()
+ protected int[][] makeToMap()
{
+ // TODO not used - remove??
return posMap(toShifts, toRatio, fromShifts, fromRatio);
}
/**
* construct an int map for intervals in intVals
*
- * @param intVals
+ * @param shiftTo
* @return int[] { from, to pos in range }, int[range.to-range.from+1]
* returning mapped position
*/
- private int[][] posMap(Vector intVals, int ratio, Vector toIntVals,
+ private int[][] posMap(List<int[]> shiftTo, int ratio,
+ List<int[]> shiftFrom,
int toRatio)
{
- int iv = 0, ivSize = intVals.size();
+ // TODO not used - remove??
+ int iv = 0, ivSize = shiftTo.size();
if (iv >= ivSize)
{
return null;
}
- int[] intv = (int[]) intVals.elementAt(iv++);
+ int[] intv = shiftTo.get(iv++);
int from = intv[0], to = intv[1];
if (from > to)
{
}
while (iv < ivSize)
{
- intv = (int[]) intVals.elementAt(iv++);
+ intv = shiftTo.get(iv++);
if (intv[0] < from)
{
from = intv[0];
int mp[][] = new int[to - from + 2][];
for (int i = 0; i < mp.length; i++)
{
- int[] m = shift(i + from, intVals, ratio, toIntVals, toRatio);
+ int[] m = shift(i + from, shiftTo, ratio, shiftFrom, toRatio);
if (m != null)
{
if (i == 0)
* shifts.insertElementAt(new int[] { pos, shift}, sidx); else
* rshift[1]+=shift; }
*/
+
/**
* shift from pos to To(pos)
*
/**
*
- * @param fromShifts
+ * @param shiftTo
* @param fromRatio
- * @param toShifts
+ * @param shiftFrom
* @param toRatio
* @return
*/
- private int[] shift(int pos, Vector fromShifts, int fromRatio,
- Vector toShifts, int toRatio)
+ protected static int[] shift(int pos, List<int[]> shiftTo, int fromRatio,
+ List<int[]> shiftFrom, int toRatio)
{
- int[] fromCount = countPos(fromShifts, pos);
+ // TODO: javadoc; tests
+ int[] fromCount = countPos(shiftTo, pos);
if (fromCount == null)
{
return null;
}
int fromRemainder = (fromCount[0] - 1) % fromRatio;
int toCount = 1 + (((fromCount[0] - 1) / fromRatio) * toRatio);
- int[] toPos = countToPos(toShifts, toCount);
+ int[] toPos = countToPos(shiftFrom, toCount);
if (toPos == null)
{
return null; // throw new Error("Bad Mapping!");
/**
* count how many positions pos is along the series of intervals.
*
- * @param intVals
+ * @param shiftTo
* @param pos
* @return number of positions or null if pos is not within intervals
*/
- private int[] countPos(Vector intVals, int pos)
+ protected static int[] countPos(List<int[]> shiftTo, int pos)
{
- int count = 0, intv[], iv = 0, ivSize = intVals.size();
+ int count = 0, intv[], iv = 0, ivSize = shiftTo.size();
while (iv < ivSize)
{
- intv = (int[]) intVals.elementAt(iv++);
+ intv = shiftTo.get(iv++);
if (intv[0] <= intv[1])
{
if (pos >= intv[0] && pos <= intv[1])
/**
* count out pos positions into a series of intervals and return the position
*
- * @param intVals
+ * @param shiftFrom
* @param pos
* @return position pos in interval set
*/
- private int[] countToPos(Vector intVals, int pos)
+ protected static int[] countToPos(List<int[]> shiftFrom, int pos)
{
- int count = 0, diff = 0, iv = 0, ivSize = intVals.size(), intv[] =
+ int count = 0, diff = 0, iv = 0, ivSize = shiftFrom.size();
+ int[] intv =
{ 0, 0 };
while (iv < ivSize)
{
- intv = (int[]) intVals.elementAt(iv++);
+ intv = shiftFrom.get(iv++);
diff = intv[1] - intv[0];
if (diff >= 0)
{
* find series of intervals mapping from start-end in the From map.
*
* @param start
- * position in to map
+ * position mapped 'to'
* @param end
- * position in to map
- * @return series of ranges in from map
+ * position mapped 'to'
+ * @return series of [start, end] ranges in sequence mapped 'from'
*/
public int[] locateInFrom(int start, int end)
{
// inefficient implementation
int fromStart[] = shiftTo(start);
- int fromEnd[] = shiftTo(end); // needs to be inclusive of end of symbol
- // position
- if (fromStart == null || fromEnd == null)
- return null;
- int iv[] = getIntervals(fromShifts, fromStart, fromEnd, fromRatio);
- return iv;
+ // needs to be inclusive of end of symbol position
+ int fromEnd[] = shiftTo(end);
+
+ return getIntervals(fromShifts, fromStart, fromEnd, fromRatio);
}
/**
* find series of intervals mapping from start-end in the to map.
*
* @param start
- * position in from map
+ * position mapped 'from'
* @param end
- * position in from map
- * @return series of ranges in to map
+ * position mapped 'from'
+ * @return series of [start, end] ranges in sequence mapped 'to'
*/
public int[] locateInTo(int start, int end)
{
- // inefficient implementation
int toStart[] = shiftFrom(start);
int toEnd[] = shiftFrom(end);
- if (toStart == null || toEnd == null)
- return null;
- int iv[] = getIntervals(toShifts, toStart, toEnd, toRatio);
- return iv;
+ return getIntervals(toShifts, toStart, toEnd, toRatio);
}
/**
* like shift - except returns the intervals in the given vector of shifts
* which were spanned in traversing fromStart to fromEnd
*
- * @param fromShifts2
+ * @param shiftFrom
* @param fromStart
* @param fromEnd
* @param fromRatio2
* @return series of from,to intervals from from first position of starting
* region to final position of ending region inclusive
*/
- private int[] getIntervals(Vector fromShifts2, int[] fromStart,
+ protected static int[] getIntervals(List<int[]> shiftFrom,
+ int[] fromStart,
int[] fromEnd, int fromRatio2)
{
+ if (fromStart == null || fromEnd == null)
+ {
+ return null;
+ }
int startpos, endpos;
startpos = fromStart[0]; // first position in fromStart
endpos = fromEnd[0]; // last position in fromEnd
int endindx = (fromRatio2 - 1); // additional positions to get to last
// position from endpos
- int intv = 0, intvSize = fromShifts2.size();
+ int intv = 0, intvSize = shiftFrom.size();
int iv[], i = 0, fs = -1, fe_s = -1, fe = -1; // containing intervals
// search intervals to locate ones containing startpos and count endindx
// positions on from endpos
while (intv < intvSize && (fs == -1 || fe == -1))
{
- iv = (int[]) fromShifts2.elementAt(intv++);
+ iv = shiftFrom.get(intv++);
if (fe_s > -1)
{
endpos = iv[0]; // start counting from beginning of interval
i++;
}
if (fs == fe && fe == -1)
+ {
return null;
- Vector ranges = new Vector();
+ }
+ List<int[]> ranges = new ArrayList<int[]>();
if (fs <= fe)
{
intv = fs;
i = fs;
// truncate initial interval
- iv = (int[]) fromShifts2.elementAt(intv++);
+ iv = shiftFrom.get(intv++);
iv = new int[]
{ iv[0], iv[1] };// clone
if (i == fs)
+ {
iv[0] = startpos;
+ }
while (i != fe)
{
- ranges.addElement(iv); // add initial range
- iv = (int[]) fromShifts2.elementAt(intv++); // get next interval
+ ranges.add(iv); // add initial range
+ iv = shiftFrom.get(intv++); // get next interval
iv = new int[]
{ iv[0], iv[1] };// clone
i++;
}
if (i == fe)
+ {
iv[1] = endpos;
- ranges.addElement(iv); // add only - or final range
+ }
+ ranges.add(iv); // add only - or final range
}
else
{
// walk from end of interval.
- i = fromShifts2.size() - 1;
+ i = shiftFrom.size() - 1;
while (i > fs)
{
i--;
}
- iv = (int[]) fromShifts2.elementAt(i);
+ iv = shiftFrom.get(i);
iv = new int[]
{ iv[1], iv[0] };// reverse and clone
// truncate initial interval
}
while (--i != fe)
{ // fix apparent logic bug when fe==-1
- ranges.addElement(iv); // add (truncated) reversed interval
- iv = (int[]) fromShifts2.elementAt(i);
+ ranges.add(iv); // add (truncated) reversed interval
+ iv = shiftFrom.get(i);
iv = new int[]
{ iv[1], iv[0] }; // reverse and clone
}
// interval is already reversed
iv[1] = endpos;
}
- ranges.addElement(iv); // add only - or final range
+ ranges.add(iv); // add only - or final range
}
// create array of start end intervals.
int[] range = null;
i = 0;
while (intv < intvSize)
{
- iv = (int[]) ranges.elementAt(intv);
+ iv = ranges.get(intv);
range[i++] = iv[0];
range[i++] = iv[1];
- ranges.setElementAt(null, intv++); // remove
+ ranges.set(intv++, null); // remove
}
}
return range;
*/
public int getToPosition(int mpos)
{
+ // TODO not used - remove??
int[] mp = shiftTo(mpos);
if (mp != null)
{
*/
public int getMappedPosition(int pos)
{
+ // TODO not used - remove??
int[] mp = shiftFrom(pos);
if (mp != null)
{
public int[] getMappedWord(int pos)
{
+ // TODO not used - remove??
int[] mp = shiftFrom(pos);
if (mp != null)
{
}
/**
- * test routine. not incremental.
- *
- * @param ml
- * @param fromS
- * @param fromE
- */
- public static void testMap(MapList ml, int fromS, int fromE)
- {
- for (int from = 1; from <= 25; from++)
- {
- int[] too = ml.shiftFrom(from);
- System.out.print("ShiftFrom(" + from + ")==");
- if (too == null)
- {
- System.out.print("NaN\n");
- }
- else
- {
- System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")");
- System.out.print("\t+--+\t");
- int[] toofrom = ml.shiftTo(too[0]);
- if (toofrom != null)
- {
- if (toofrom[0] != from)
- {
- System.err.println("Mapping not reflexive:" + from + " "
- + too[0] + "->" + toofrom[0]);
- }
- System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0]
- + " % " + toofrom[1] + " (" + toofrom[2] + ")");
- }
- else
- {
- System.out.println("ShiftTo(" + too[0] + ")=="
- + "NaN! - not Bijective Mapping!");
- }
- }
- }
- int mmap[][] = ml.makeFromMap();
- System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " "
- + mmap[0][2] + " " + mmap[0][3] + " ");
- for (int i = 1; i <= mmap[1].length; i++)
- {
- if (mmap[1][i - 1] == -1)
- {
- System.out.print(i + "=XXX");
-
- }
- else
- {
- System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1]));
- }
- if (i % 20 == 0)
- {
- System.out.print("\n");
- }
- else
- {
- System.out.print(",");
- }
- }
- // test range function
- System.out.print("\nTest locateInFrom\n");
- {
- int f = mmap[0][2], t = mmap[0][3];
- while (f <= t)
- {
- System.out.println("Range " + f + " to " + t);
- int rng[] = ml.locateInFrom(f, t);
- if (rng != null)
- {
- for (int i = 0; i < rng.length; i++)
- {
- System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
- }
- }
- else
- {
- System.out.println("No range!");
- }
- System.out.print("\nReversed\n");
- rng = ml.locateInFrom(t, f);
- if (rng != null)
- {
- for (int i = 0; i < rng.length; i++)
- {
- System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
- }
- }
- else
- {
- System.out.println("No range!");
- }
- System.out.print("\n");
- f++;
- t--;
- }
- }
- System.out.print("\n");
- mmap = ml.makeToMap();
- System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " "
- + mmap[0][2] + " " + mmap[0][3] + " ");
- for (int i = 1; i <= mmap[1].length; i++)
- {
- if (mmap[1][i - 1] == -1)
- {
- System.out.print(i + "=XXX");
-
- }
- else
- {
- System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1]));
- }
- if (i % 20 == 0)
- {
- System.out.print("\n");
- }
- else
- {
- System.out.print(",");
- }
- }
- System.out.print("\n");
- // test range function
- System.out.print("\nTest locateInTo\n");
- {
- int f = mmap[0][2], t = mmap[0][3];
- while (f <= t)
- {
- System.out.println("Range " + f + " to " + t);
- int rng[] = ml.locateInTo(f, t);
- if (rng != null)
- {
- for (int i = 0; i < rng.length; i++)
- {
- System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
- }
- }
- else
- {
- System.out.println("No range!");
- }
- System.out.print("\nReversed\n");
- rng = ml.locateInTo(t, f);
- if (rng != null)
- {
- for (int i = 0; i < rng.length; i++)
- {
- System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
- }
- }
- else
- {
- System.out.println("No range!");
- }
- f++;
- t--;
- System.out.print("\n");
- }
- }
-
- }
-
- public static void main(String argv[])
- {
- MapList ml = new MapList(new int[]
- { 1, 5, 10, 15, 25, 20 }, new int[]
- { 51, 1 }, 1, 3);
- MapList ml1 = new MapList(new int[]
- { 1, 3, 17, 4 }, new int[]
- { 51, 1 }, 1, 3);
- MapList ml2 = new MapList(new int[]
- { 1, 60 }, new int[]
- { 1, 20 }, 3, 1);
- // test internal consistency
- int to[] = new int[51];
- MapList.testMap(ml, 1, 60);
- MapList mldna = new MapList(new int[]
- { 2, 2, 6, 8, 12, 16 }, new int[]
- { 1, 3 }, 3, 1);
- int[] frm = mldna.locateInFrom(1, 1);
- testLocateFrom(mldna, 1, 1, new int[]
- { 2, 2, 6, 7 });
- MapList.testMap(mldna, 1, 3);
- /*
- * for (int from=1; from<=51; from++) { int[] too=ml.shiftTo(from); int[]
- * toofrom=ml.shiftFrom(too[0]);
- * System.out.println("ShiftFrom("+from+")=="+too[0]+" %
- * "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); }
- */
- System.out.print("Success?\n"); // if we get here - something must be
- // working!
- }
-
- private static void testLocateFrom(MapList mldna, int i, int j, int[] ks)
- {
- int[] frm = mldna.locateInFrom(i, j);
- if (frm == ks || java.util.Arrays.equals(frm, ks))
- {
- System.out.println("Success test locate from " + i + " to " + j);
- }
- else
- {
- System.err.println("Failed test locate from " + i + " to " + j);
- for (int c = 0; c < frm.length; c++)
- {
- System.err.print(frm[c] + ((c % 2 == 0) ? "," : ";"));
- }
- System.err.println("Expected");
- for (int c = 0; c < ks.length; c++)
- {
- System.err.print(ks[c] + ((c % 2 == 0) ? "," : ";"));
- }
- }
- }
-
- /**
*
* @return a MapList whose From range is this maplist's To Range, and vice
* versa
*/
public boolean containsEither(boolean local, MapList map)
{
+ // TODO not used - remove?
if (local)
{
return ((getFromLowest() >= map.getFromLowest() && getFromHighest() <= map
--- /dev/null
+package jalview.util;
+
+import jalview.analysis.AlignmentSorter;
+import jalview.api.AlignViewportI;
+import jalview.commands.CommandI;
+import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
+import jalview.commands.EditCommand.Edit;
+import jalview.commands.OrderCommand;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignViewport;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Helper methods for manipulations involving sequence mappings.
+ *
+ * @author gmcarstairs
+ *
+ */
+public final class MappingUtils
+{
+
+ /**
+ * Helper method to map a CUT or PASTE command.
+ *
+ * @param edit
+ * the original command
+ * @param undo
+ * if true, the command is to be undone
+ * @param targetSeqs
+ * the mapped sequences to apply the mapped command to
+ * @param result
+ * the mapped EditCommand to add to
+ * @param mappings
+ */
+ protected static void mapCutOrPaste(Edit edit, boolean undo,
+ List<SequenceI> targetSeqs, EditCommand result,
+ Set<AlignedCodonFrame> mappings)
+ {
+ Action action = edit.getAction();
+ if (undo)
+ {
+ action = action.getUndoAction();
+ }
+ // TODO write this
+ System.err.println("MappingUtils.mapCutOrPaste not yet implemented");
+ }
+
+ /**
+ * Returns a new EditCommand representing the given command as mapped to the
+ * given sequences. If there is no mapping, returns null.
+ *
+ * @param command
+ * @param undo
+ * @param mapTo
+ * @param gapChar
+ * @param mappings
+ * @return
+ */
+ public static EditCommand mapEditCommand(EditCommand command,
+ boolean undo, final AlignmentI mapTo, char gapChar,
+ Set<AlignedCodonFrame> mappings)
+ {
+ /*
+ * For now, only support mapping from protein edits to cDna
+ */
+ if (!mapTo.isNucleotide())
+ {
+ return null;
+ }
+
+ /*
+ * Cache a copy of the target sequences so we can mimic successive edits on
+ * them. This lets us compute mappings for all edits in the set.
+ */
+ Map<SequenceI, SequenceI> targetCopies = new HashMap<SequenceI, SequenceI>();
+ for (SequenceI seq : mapTo.getSequences())
+ {
+ SequenceI ds = seq.getDatasetSequence();
+ if (ds != null)
+ {
+ final SequenceI copy = new Sequence("", new String(
+ seq.getSequence()));
+ copy.setDatasetSequence(ds);
+ targetCopies.put(ds, copy);
+ }
+ }
+
+ /*
+ * Compute 'source' sequences as they were before applying edits:
+ */
+ Map<SequenceI, SequenceI> originalSequences = command.priorState(undo);
+
+ EditCommand result = new EditCommand();
+ Iterator<Edit> edits = command.getEditIterator(!undo);
+ while (edits.hasNext())
+ {
+ Edit edit = edits.next();
+ if (edit.getAction() == Action.CUT
+ || edit.getAction() == Action.PASTE)
+ {
+ mapCutOrPaste(edit, undo, mapTo.getSequences(), result, mappings);
+ }
+ else if (edit.getAction() == Action.INSERT_GAP
+ || edit.getAction() == Action.DELETE_GAP)
+ {
+ mapInsertOrDelete(edit, undo, originalSequences,
+ mapTo.getSequences(), targetCopies, gapChar, result,
+ mappings);
+ }
+ }
+ return result.getSize() > 0 ? result : null;
+ }
+
+ /**
+ * Helper method to map an edit command to insert or delete gaps.
+ *
+ * @param edit
+ * the original command
+ * @param undo
+ * if true, the action is to undo the command
+ * @param originalSequences
+ * the sequences the command acted on
+ * @param targetSeqs
+ * @param targetCopies
+ * @param gapChar
+ * @param result
+ * the new EditCommand to add mapped commands to
+ * @param mappings
+ */
+ protected static void mapInsertOrDelete(Edit edit, boolean undo,
+ Map<SequenceI, SequenceI> originalSequences,
+ final List<SequenceI> targetSeqs,
+ Map<SequenceI, SequenceI> targetCopies, char gapChar,
+ EditCommand result, Set<AlignedCodonFrame> mappings)
+ {
+ Action action = edit.getAction();
+
+ /*
+ * Invert sense of action if an Undo.
+ */
+ if (undo)
+ {
+ action = action.getUndoAction();
+ }
+ final int count = edit.getNumber();
+ final int editPos = edit.getPosition();
+ for (SequenceI seq : edit.getSequences())
+ {
+ /*
+ * Get residue position at (or to right of) edit location. Note we use our
+ * 'copy' of the sequence before editing for this.
+ */
+ SequenceI ds = seq.getDatasetSequence();
+ if (ds == null)
+ {
+ continue;
+ }
+ final SequenceI actedOn = originalSequences.get(ds);
+ final int seqpos = actedOn.findPosition(editPos);
+
+ /*
+ * Determine all mappings from this position to mapped sequences.
+ */
+ SearchResults sr = buildSearchResults(seq, seqpos, mappings);
+
+ if (!sr.isEmpty())
+ {
+ for (SequenceI targetSeq : targetSeqs)
+ {
+ ds = targetSeq.getDatasetSequence();
+ if (ds == null)
+ {
+ continue;
+ }
+ SequenceI copyTarget = targetCopies.get(ds);
+ final int[] match = sr.getResults(copyTarget, 0,
+ copyTarget.getLength());
+ if (match != null)
+ {
+ final int ratio = 3; // TODO: compute this - how?
+ final int mappedCount = count * ratio;
+
+ /*
+ * Shift Delete start position left, as it acts on positions to its
+ * right.
+ */
+ int mappedEditPos = action == Action.DELETE_GAP ? match[0]
+ - mappedCount : match[0];
+ Edit e = result.new Edit(action, new SequenceI[]
+ { targetSeq }, mappedEditPos, mappedCount, gapChar);
+ result.addEdit(e);
+
+ /*
+ * and 'apply' the edit to our copy of its target sequence
+ */
+ if (action == Action.INSERT_GAP)
+ {
+ copyTarget.setSequence(new String(StringUtils.insertCharAt(
+ copyTarget.getSequence(), mappedEditPos, mappedCount,
+ gapChar)));
+ }
+ else if (action == Action.DELETE_GAP)
+ {
+ copyTarget.setSequence(new String(StringUtils.deleteChars(
+ copyTarget.getSequence(), mappedEditPos,
+ mappedEditPos + mappedCount)));
+ }
+ }
+ }
+ }
+ /*
+ * and 'apply' the edit to our copy of its source sequence
+ */
+ if (action == Action.INSERT_GAP)
+ {
+ actedOn.setSequence(new String(StringUtils.insertCharAt(
+ actedOn.getSequence(), editPos, count, gapChar)));
+ }
+ else if (action == Action.DELETE_GAP)
+ {
+ actedOn.setSequence(new String(StringUtils.deleteChars(
+ actedOn.getSequence(), editPos, editPos + count)));
+ }
+ }
+ }
+
+ /**
+ * Returns a SearchResults object describing the mapped region corresponding
+ * to the specified sequence position.
+ *
+ * @param seq
+ * @param index
+ * @param seqmappings
+ * @return
+ */
+ public static SearchResults buildSearchResults(SequenceI seq, int index,
+ Set<AlignedCodonFrame> seqmappings)
+ {
+ SearchResults results;
+ results = new SearchResults();
+ if (index >= seq.getStart() && index <= seq.getEnd())
+ {
+ for (AlignedCodonFrame acf : seqmappings)
+ {
+ acf.markMappedRegion(seq, index, results);
+ }
+ }
+ return results;
+ }
+
+ /**
+ * Returns a (possibly empty) SequenceGroup containing any sequences in the
+ * mapped viewport corresponding to the given group in the source viewport.
+ *
+ * @param sg
+ * @param mapFrom
+ * @param mapTo
+ * @return
+ */
+ public static SequenceGroup mapSequenceGroup(SequenceGroup sg,
+ AlignViewportI mapFrom, AlignViewportI mapTo)
+ {
+ /*
+ * Note the SequenceGroup holds aligned sequences, the mappings hold dataset
+ * sequences.
+ */
+ boolean targetIsNucleotide = mapTo.isNucleotide();
+ AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo;
+ Set<AlignedCodonFrame> codonFrames = protein.getAlignment()
+ .getCodonFrames();
+
+ /*
+ * Copy group name, colours, but not sequences
+ */
+ SequenceGroup mappedGroup = new SequenceGroup(sg);
+ mappedGroup.clear();
+ // TODO set width of mapped group
+
+ for (SequenceI selected : sg.getSequences())
+ {
+ for (AlignedCodonFrame acf : codonFrames)
+ {
+ SequenceI mappedSequence = targetIsNucleotide ? acf
+ .getDnaForAaSeq(selected) : acf.getAaForDnaSeq(selected);
+ if (mappedSequence != null)
+ {
+ for (SequenceI seq : mapTo.getAlignment().getSequences())
+ {
+ if (seq.getDatasetSequence() == mappedSequence)
+ {
+ mappedGroup.addSequence(seq, false);
+ break;
+ }
+ }
+ }
+ }
+ }
+ return mappedGroup;
+ }
+
+ /**
+ * Returns an OrderCommand equivalent to the given one, but acting on mapped
+ * sequences as described by the mappings, or null if no mapping can be made.
+ *
+ * @param command
+ * the original order command
+ * @param undo
+ * if true, the action is to undo the sort
+ * @param mapTo
+ * the alignment we are mapping to
+ * @param mappings
+ * the mappings available
+ * @return
+ */
+ public static CommandI mapOrderCommand(OrderCommand command,
+ boolean undo, AlignmentI mapTo, Set<AlignedCodonFrame> mappings)
+ {
+ SequenceI[] sortOrder = command.getSequenceOrder(undo);
+ List<SequenceI> mappedOrder = new ArrayList<SequenceI>();
+ int j = 0;
+ for (SequenceI seq : sortOrder)
+ {
+ for (AlignedCodonFrame acf : mappings)
+ {
+ /*
+ * Try protein-to-Dna, failing that try dna-to-protein
+ */
+ SequenceI mappedSeq = acf.getDnaForAaSeq(seq);
+ if (mappedSeq == null)
+ {
+ mappedSeq = acf.getAaForDnaSeq(seq);
+ }
+ if (mappedSeq != null)
+ {
+ for (SequenceI seq2 : mapTo.getSequences())
+ {
+ if (seq2.getDatasetSequence() == mappedSeq)
+ {
+ mappedOrder.add(seq2);
+ j++;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Return null if no mappings made.
+ */
+ if (j == 0)
+ {
+ return null;
+ }
+
+ /*
+ * Add any unmapped sequences on the end of the sort in their original
+ * ordering.
+ */
+ if (j < mapTo.getHeight())
+ {
+ for (SequenceI seq : mapTo.getSequences())
+ {
+ if (!mappedOrder.contains(seq))
+ {
+ mappedOrder.add(seq);
+ }
+ }
+ }
+
+ /*
+ * Have to align the sequences before constructing the OrderCommand - which
+ * then realigns them?!?
+ */
+ final SequenceI[] mappedOrderArray = mappedOrder
+ .toArray(new SequenceI[mappedOrder.size()]);
+ SequenceI[] oldOrder = mapTo.getSequencesArray();
+ AlignmentSorter.sortBy(mapTo, new AlignmentOrder(mappedOrderArray));
+ final OrderCommand result = new OrderCommand(command.getDescription(),
+ oldOrder, mapTo);
+ return result;
+ }
+
+ /**
+ * Returns a ColumnSelection in the 'mapTo' view which corresponds to the
+ * given selection in the 'mapFrom' view. We assume one is nucleotide, the
+ * other is protein (and holds the mappings from codons to protein residues).
+ *
+ * @param colsel
+ * @param mapFrom
+ * @param mapTo
+ * @return
+ */
+ public static ColumnSelection mapColumnSelection(ColumnSelection colsel,
+ AlignViewportI mapFrom, AlignViewport mapTo)
+ {
+ boolean targetIsNucleotide = mapTo.isNucleotide();
+ AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo;
+ Set<AlignedCodonFrame> codonFrames = protein.getAlignment()
+ .getCodonFrames();
+ ColumnSelection mappedColumns = new ColumnSelection();
+ char fromGapChar = mapFrom.getAlignment().getGapCharacter();
+
+ for (Object obj : colsel.getSelected())
+ {
+ int col = ((Integer) obj).intValue();
+ int mappedToMin = Integer.MAX_VALUE;
+ int mappedToMax = Integer.MIN_VALUE;
+
+ /*
+ * For each sequence in the 'from' alignment
+ */
+ for (SequenceI fromSeq : mapFrom.getAlignment().getSequences())
+ {
+ /*
+ * Ignore gaps (unmapped anyway)
+ */
+ if (fromSeq.getCharAt(col) == fromGapChar)
+ {
+ continue;
+ }
+
+ /*
+ * Get the residue position and find the mapped position.
+ */
+ int residuePos = fromSeq.findPosition(col);
+ SearchResults sr = buildSearchResults(fromSeq, residuePos,
+ codonFrames);
+ for (Match m : sr.getResults())
+ {
+ int mappedStartResidue = m.getStart();
+ int mappedEndResidue = m.getEnd();
+ SequenceI mappedSeq = m.getSequence();
+
+ /*
+ * Locate the aligned sequence whose dataset is mappedSeq. TODO a
+ * datamodel that can do this efficiently.
+ */
+ for (SequenceI toSeq : mapTo.getAlignment().getSequences())
+ {
+ if (toSeq.getDatasetSequence() == mappedSeq)
+ {
+ int mappedStartCol = toSeq.findIndex(mappedStartResidue);
+ int mappedEndCol = toSeq.findIndex(mappedEndResidue);
+ mappedToMin = Math.min(mappedToMin, mappedStartCol);
+ mappedToMax = Math.max(mappedToMax, mappedEndCol);
+ // System.out.println(fromSeq.getName() + " mapped to cols "
+ // + mappedStartCol + ":" + mappedEndCol);
+ break;
+ // TODO remove break if we ever want to map one to many sequences
+ }
+ }
+ }
+ }
+ /*
+ * Add mapped columns to mapped selection (converting base 1 to base 0)
+ */
+ for (int i = mappedToMin; i <= mappedToMax; i++)
+ {
+ mappedColumns.addElement(i - 1);
+ }
+ }
+ return mappedColumns;
+ }
+
+}
--- /dev/null
+package jalview.util;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * An iterator that traverses a list backwards.
+ *
+ * @author gmcarstairs (and checked against
+ * org.codehaus.groovey.runtime.ReverseListIterator)
+ *
+ * @param <E>
+ */
+public class ReverseListIterator<E> implements Iterator<E>
+{
+
+ private ListIterator<E> iterator;
+
+ public ReverseListIterator(List<E> stuff)
+ {
+ this.iterator = stuff.listIterator(stuff.size());
+ }
+ @Override
+ public boolean hasNext()
+ {
+ return iterator.hasPrevious();
+ }
+
+ @Override
+ public E next()
+ {
+ return iterator.previous();
+ }
+
+ @Override
+ public void remove()
+ {
+ iterator.remove();
+ }
+
+}
*/
package jalview.util;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
/**
* ShiftList Simple way of mapping a linear series to a new linear range with
*/
public class ShiftList
{
- public Vector shifts;
+ private List<int[]> shifts;
public ShiftList()
{
- shifts = new Vector();
+ shifts = new ArrayList<int[]>();
}
/**
{
int sidx = 0;
int[] rshift = null;
- while (sidx < shifts.size()
- && (rshift = (int[]) shifts.elementAt(sidx))[0] < pos)
+ while (sidx < shifts.size() && (rshift = shifts.get(sidx))[0] < pos)
{
sidx++;
}
if (sidx == shifts.size())
{
- shifts.insertElementAt(new int[]
- { pos, shift }, sidx);
+ shifts.add(sidx, new int[]
+ { pos, shift });
}
else
{
int sidx = 0;
int rshift[];
while (sidx < shifts.size()
- && (rshift = ((int[]) shifts.elementAt(sidx++)))[0] <= pos)
+ && (rshift = (shifts.get(sidx++)))[0] <= pos)
{
shifted += rshift[1];
}
*/
public void clear()
{
- shifts.removeAllElements();
+ shifts.clear();
}
/**
{
for (int i = 0, j = shifts.size(); i < j; i++)
{
- int[] sh = (int[]) shifts.elementAt(i);
+ int[] sh = shifts.get(i);
if (sh != null)
{
- inverse.shifts.addElement(new int[]
+ inverse.shifts.add(new int[]
{ sh[0], -sh[1] });
}
}
}
/**
- * parse a 1d map of position 1<i<n to L<pos[i]<N such as that returned from
- * SequenceI.gapMap()
+ * parse a 1d map of position 1<i<n to L<pos[i]<N such as that
+ * returned from SequenceI.gapMap()
*
* @param gapMap
* @return shifts from map index to mapped position
}
return shiftList;
}
+
+ public List<int[]> getShifts()
+ {
+ return shifts;
+ }
}
--- /dev/null
+package jalview.util;
+
+
+public class StringUtils
+{
+
+ /**
+ * Returns a new character array, after inserting characters into the given
+ * character array.
+ *
+ * @param in
+ * the character array to insert into
+ * @param position
+ * the 0-based position for insertion
+ * @param count
+ * the number of characters to insert
+ * @param ch
+ * the character to insert
+ */
+ public static final char[] insertCharAt(char[] in, int position,
+ int count,
+ char ch)
+ {
+ char[] tmp = new char[in.length + count];
+
+ if (position >= in.length)
+ {
+ System.arraycopy(in, 0, tmp, 0, in.length);
+ position = in.length;
+ }
+ else
+ {
+ System.arraycopy(in, 0, tmp, 0, position);
+ }
+
+ int index = position;
+ while (count > 0)
+ {
+ tmp[index++] = ch;
+ count--;
+ }
+
+ if (position < in.length)
+ {
+ System.arraycopy(in, position, tmp, index,
+ in.length - position);
+ }
+
+ return tmp;
+ }
+
+ /**
+ * Delete
+ *
+ * @param in
+ * @param from
+ * @param to
+ * @return
+ */
+ public static final char[] deleteChars(char[] in, int from, int to)
+ {
+ if (from >= in.length)
+ {
+ return in;
+ }
+
+ char[] tmp;
+
+ if (to >= in.length)
+ {
+ tmp = new char[from];
+ System.arraycopy(in, 0, tmp, 0, from);
+ to = in.length;
+ }
+ else
+ {
+ tmp = new char[in.length - to + from];
+ System.arraycopy(in, 0, tmp, 0, from);
+ System.arraycopy(in, to, tmp, from, in.length - to);
+ }
+ return tmp;
+ }
+
+ /**
+ * Returns the last part of 'input' after the last occurrence of 'token'. For
+ * example to extract only the filename from a full path or URL.
+ *
+ * @param input
+ * @param token
+ * a delimiter which must be in regular expression format
+ * @return
+ */
+ public static String getLastToken(String input, String token)
+ {
+ if (input == null)
+ {
+ return null;
+ }
+ if (token == null)
+ {
+ return input;
+ }
+ String[] st = input.split(token);
+ return st[st.length - 1];
+ }
+}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.Annotation;
+import jalview.datamodel.CigarArray;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceCollectionI;
import java.awt.Color;
import java.util.ArrayList;
import java.util.BitSet;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
*/
public abstract class AlignmentViewport implements AlignViewportI
{
+ /*
+ * A viewport that hosts the cDna view of this (protein), or vice versa (if
+ * set).
+ */
+ AlignViewportI codingComplement = null;
+
/**
* alignment displayed in the viewport. Please use get/setter
*/
protected boolean showConsensus = true;
- Hashtable sequenceColours;
+ private Map<SequenceI, Color> sequenceColours = new HashMap<SequenceI, Color>();
/**
* Property change listener for changes in alignment
}
@Override
- public abstract void sendSelection();
-
- @Override
public void invertColumnSelection()
{
colSel.invertColumnSelection(0, alignment.getWidth());
@Override
- public jalview.datamodel.CigarArray getViewAsCigars(
+ public CigarArray getViewAsCigars(
boolean selectedRegionOnly)
{
- return new jalview.datamodel.CigarArray(alignment, colSel,
+ return new CigarArray(alignment, colSel,
(selectedRegionOnly ? selectionGroup : null));
}
this.displayReferenceSeq = displayReferenceSeq;
}
+ @Override
public boolean isColourByReferenceSeq()
{
return alignment.hasSeqrep() && colourByReferenceSeq;
}
+ @Override
public void setColourByReferenceSeq(boolean colourByReferenceSeq)
{
this.colourByReferenceSeq = colourByReferenceSeq;
@Override
public Color getSequenceColour(SequenceI seq)
{
- Color sqc = Color.white;
- if (sequenceColours != null)
- {
- sqc = (Color) sequenceColours.get(seq);
- if (sqc == null)
- {
- sqc = Color.white;
- }
- }
- return sqc;
+ Color sqc = sequenceColours.get(seq);
+ return (sqc == null ? Color.white : sqc);
}
@Override
public void setSequenceColour(SequenceI seq, Color col)
{
- if (sequenceColours == null)
- {
- sequenceColours = new Hashtable();
- }
-
if (col == null)
{
sequenceColours.remove(seq);
@Override
public void updateSequenceIdColours()
{
- if (sequenceColours == null)
- {
- sequenceColours = new Hashtable();
- }
for (SequenceGroup sg : alignment.getGroups())
{
if (sg.idColour != null)
@Override
public void clearSequenceColours()
{
- sequenceColours = null;
+ sequenceColours.clear();
};
+ @Override
+ public AlignViewportI getCodingComplement()
+ {
+ return this.codingComplement;
+ }
+
+ /**
+ * Set this as the (cDna/protein) complement of the given viewport. Also
+ * ensures the reverse relationship is set on the given viewport.
+ */
+ @Override
+ public void setCodingComplement(AlignViewportI av)
+ {
+ if (this == av)
+ {
+ System.err.println("Ignoring recursive setCodingComplement request");
+ }
+ else
+ {
+ this.codingComplement = av;
+ // avoid infinite recursion!
+ if (av.getCodingComplement() != this)
+ {
+ av.setCodingComplement(this);
+ }
+ }
+ }
+
+ @Override
+ public boolean isNucleotide()
+ {
+ return getAlignment() == null ? false : getAlignment().isNucleotide();
+ }
+
FeaturesDisplayedI featuresDisplayed = null;
@Override
{
this.rightAlignIds = rightAlignIds;
}
-
}
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.WebserviceInfo;
-import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
import jalview.util.MessageManager;
+import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
public abstract class AWSThread extends Thread
{
/**
* dataset sequence relationships to be propagated onto new results
*/
- protected AlignedCodonFrame[] codonframe = null;
+ protected Set<AlignedCodonFrame> codonframe = null;
/**
* are there jobs still running in this thread.
} catch (Exception ex)
{
// Deal with Transaction exceptions
- wsInfo.appendProgressText(jobs[j].jobnum,
- MessageManager.formatMessage("info.server_exception", new String[]{WebServiceName,ex.getMessage()}));
+ wsInfo.appendProgressText(jobs[j].jobnum, MessageManager
+ .formatMessage("info.server_exception", new Object[]
+ { WebServiceName, ex.getMessage() }));
// always output the exception's stack trace to the log
Cache.log.warn(WebServiceName + " job(" + jobs[j].jobnum
+ ") Server exception.");
{
Cache.log
.debug("WebServiceJob poll loop finished with no jobs created.");
- wsInfo.setStatus(wsInfo.STATE_STOPPED_ERROR);
+ wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
wsInfo.appendProgressText(MessageManager.getString("info.no_jobs_ran"));
wsInfo.setFinishedNoResults();
}
SequenceI[] alignment = al.getSequencesArray();
for (int sq = 0; sq < alignment.length; sq++)
{
- for (int i = 0; i < codonframe.length; i++)
+ for (AlignedCodonFrame acf : codonframe)
{
- if (codonframe[i] != null
- && codonframe[i].involvesSequence(alignment[sq]))
+ final SequenceI seq = alignment[sq];
+ if (acf != null && acf.involvesSequence(seq))
{
- al.addCodonFrame(codonframe[i]);
- codonframe[i] = null;
+ al.addCodonFrame(acf);
break;
}
}
WsUrl = wsurl2;
if (alframe != null)
{
- AlignedCodonFrame[] cf = alframe.getViewport().getAlignment()
+ Set<AlignedCodonFrame> cf = alframe.getViewport().getAlignment()
.getCodonFrames();
if (cf != null)
{
- codonframe = new AlignedCodonFrame[cf.length];
- System.arraycopy(cf, 0, codonframe, 0, cf.length);
+ codonframe = new LinkedHashSet<AlignedCodonFrame>();
+ codonframe.addAll(cf);
}
}
}
*/
package jalview.analysis;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
+import jalview.analysis.AlignmentUtils.MappingResult;
+import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Mapping;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.io.AppletFormatAdapter;
+import jalview.io.FormatAdapter;
+import jalview.util.MapList;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
public class AlignmentUtilsTests
{
+ // @formatter:off
+ private static final String TEST_DATA =
+ "# STOCKHOLM 1.0\n" +
+ "#=GS D.melanogaster.1 AC AY119185.1/838-902\n" +
+ "#=GS D.melanogaster.2 AC AC092237.1/57223-57161\n" +
+ "#=GS D.melanogaster.3 AC AY060611.1/560-627\n" +
+ "D.melanogaster.1 G.AGCC.CU...AUGAUCGA\n" +
+ "#=GR D.melanogaster.1 SS ................((((\n" +
+ "D.melanogaster.2 C.AUUCAACU.UAUGAGGAU\n" +
+ "#=GR D.melanogaster.2 SS ................((((\n" +
+ "D.melanogaster.3 G.UGGCGCU..UAUGACGCA\n" +
+ "#=GR D.melanogaster.3 SS (.(((...(....(((((((\n" +
+ "//";
+
+ private static final String AA_SEQS_1 =
+ ">Seq1Name\n" +
+ "K-QY--L\n" +
+ ">Seq2Name\n" +
+ "-R-FP-W-\n";
+
+ private static final String CDNA_SEQS_1 =
+ ">Seq1Name\n" +
+ "AC-GG--CUC-CAA-CT\n" +
+ ">Seq2Name\n" +
+ "-CG-TTA--ACG---AAGT\n";
+
+ private static final String CDNA_SEQS_2 =
+ ">Seq1Name\n" +
+ "GCTCGUCGTACT\n" +
+ ">Seq2Name\n" +
+ "GGGTCAGGCAGT\n";
+ // @formatter:on
+
public static Sequence ts=new Sequence("short","ASDASDASDASDASDASDASDASDASDASDASDASDASD");
+
@Test
public void testExpandFlanks()
{
assertTrue("Flanking sequence not the same as original dataset sequence.\n"+ung+"\n"+sq.getDatasetSequence().getSequenceAsString(),ung.equalsIgnoreCase(sq.getDatasetSequence().getSequenceAsString()));
}
}
+ }
}
+
+ /**
+ * Test method that returns a map of lists of sequences by sequence name.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testGetSequencesByName() throws IOException
+ {
+ final String data = ">Seq1Name\nKQYL\n" + ">Seq2Name\nRFPW\n"
+ + ">Seq1Name\nABCD\n";
+ AlignmentI al = loadAlignment(data, "FASTA");
+ Map<String, List<SequenceI>> map = AlignmentUtils
+ .getSequencesByName(al);
+ assertEquals(2, map.keySet().size());
+ assertEquals(2, map.get("Seq1Name").size());
+ assertEquals("KQYL", map.get("Seq1Name").get(0).getSequenceAsString());
+ assertEquals("ABCD", map.get("Seq1Name").get(1).getSequenceAsString());
+ assertEquals(1, map.get("Seq2Name").size());
+ assertEquals("RFPW", map.get("Seq2Name").get(0).getSequenceAsString());
+ }
+ /**
+ * Helper method to load an alignment and ensure dataset sequences are set up.
+ *
+ * @param data
+ * @param format TODO
+ * @return
+ * @throws IOException
+ */
+ protected AlignmentI loadAlignment(final String data, String format) throws IOException
+ {
+ Alignment a = new FormatAdapter().readFile(data,
+ AppletFormatAdapter.PASTE, format);
+ a.setDataset(null);
+ return a;
+ }
+ /**
+ * Test mapping of protein to cDNA.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testMapProteinToCdna() throws IOException
+ {
+ // protein: Human + Mouse, 3 residues
+ AlignmentI protein = loadAlignment(
+ ">Human\nKQY\n>Mouse\nAFP\n>Worm\nRST\n",
+ "FASTA");
+ // cDNA: Mouse, Human, Mouse, 9 bases
+ // @formatter:off
+ String dnaData =
+ ">Mouse\nGAAATCCAG\n" +
+ ">Human\nTTCGATTAC\n" +
+ ">Mouse\nGTCGTTTGC\n" +
+ ">Mouse\nGTCGTTTGCgac\n" + // not mapped - wrong length
+ ">Fly\nGTCGTTTGC\n"; // not mapped - no name match
+ // @formatter:on
+ AlignmentI cdna1 = loadAlignment(
+ dnaData,
+ "FASTA");
+ MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, cdna1);
+ assertEquals(mapped, MappingResult.Mapped);
+
+ /*
+ * Check two mappings (one for Mouse, one for Human)
+ */
+ assertEquals(2, protein.getCodonFrames().size());
+ assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size());
+ assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size());
+
+ /*
+ * Inspect mapping for Human protein
+ */
+ AlignedCodonFrame humanMapping = protein.getCodonFrame(
+ protein.getSequenceAt(0)).get(0);
+ assertEquals(1, humanMapping.getdnaSeqs().length);
+ assertEquals(cdna1.getSequenceAt(1).getDatasetSequence(),
+ humanMapping.getdnaSeqs()[0]);
+ Mapping[] protMappings = humanMapping.getProtMappings();
+ assertEquals(1, protMappings.length);
+ MapList mapList = protMappings[0].getMap();
+ assertEquals(3, mapList.getFromRatio());
+ assertEquals(1, mapList.getToRatio());
+ assertTrue(Arrays.equals(new int[]
+ { 1, 9 }, mapList.getFromRanges()));
+ assertTrue(Arrays.equals(new int[]
+ { 1, 3 }, mapList.getToRanges()));
+
+ /*
+ * Inspect mappings for Mouse protein
+ */
+ AlignedCodonFrame mouseMapping1 = protein.getCodonFrame(
+ protein.getSequenceAt(1)).get(0);
+ assertEquals(2, mouseMapping1.getdnaSeqs().length);
+ assertEquals(cdna1.getSequenceAt(0).getDatasetSequence(),
+ mouseMapping1.getdnaSeqs()[0]);
+ assertEquals(cdna1.getSequenceAt(2).getDatasetSequence(),
+ mouseMapping1.getdnaSeqs()[1]);
+ protMappings = mouseMapping1.getProtMappings();
+ assertEquals(2, protMappings.length);
+ for (int i = 0; i < 2; i++)
+ {
+ mapList = protMappings[i].getMap();
+ assertEquals(3, mapList.getFromRatio());
+ assertEquals(1, mapList.getToRatio());
+ assertTrue(Arrays.equals(new int[]
+ { 1, 9 }, mapList.getFromRanges()));
+ assertTrue(Arrays.equals(new int[]
+ { 1, 3 }, mapList.getToRanges()));
+ }
+ }
+
+ /**
+ * Test mapping of protein to cDNA which may include start and/or stop codons.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testMapProteinToCdna_stopStartCodons() throws IOException
+ {
+ // protein: Human + Mouse, 3 residues
+ AlignmentI protein = loadAlignment(
+ ">Human\nKQY\n>Mouse\nAFP\n>Worm\nRST\n", "FASTA");
+ // @formatter:off
+ String dnaData =
+ ">Mouse\natgGAAATCCAG\n" + // Mouse with start codon
+ ">Human\nTTCGATtactaa\n" + // Human with stop codon TAA
+ ">Mouse\nGTCGTTTGctaG\n" + // Mouse with stop codon TAG
+ ">Human\nGTCGTTTgctGa\n" + // Human with stop codon TGA
+ ">Mouse\nATGGTCGTTTGCtag\n"; // Mouse with start and stop codons
+ // @formatter:on
+ AlignmentI cdna1 = loadAlignment(
+ dnaData,
+ "FASTA");
+ MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, cdna1);
+ assertEquals(mapped, MappingResult.Mapped);
+
+ /*
+ * Check two mappings (one for Mouse, one for Human)
+ */
+ assertEquals(2, protein.getCodonFrames().size());
+ assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size());
+ assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size());
+
+ /*
+ * Inspect mapping for Human protein - should map to 2nd and 4th cDNA seqs
+ */
+ AlignedCodonFrame humanMapping = protein.getCodonFrame(
+ protein.getSequenceAt(0)).get(0);
+ assertEquals(2, humanMapping.getdnaSeqs().length);
+ assertEquals(cdna1.getSequenceAt(1).getDatasetSequence(),
+ humanMapping.getdnaSeqs()[0]);
+ assertEquals(cdna1.getSequenceAt(3).getDatasetSequence(),
+ humanMapping.getdnaSeqs()[1]);
+ Mapping[] protMappings = humanMapping.getProtMappings();
+ // two mappings, both to cDNA with stop codon
+ assertEquals(2, protMappings.length);
+ MapList mapList = protMappings[0].getMap();
+ assertEquals(3, mapList.getFromRatio());
+ assertEquals(1, mapList.getToRatio());
+ assertTrue(Arrays.equals(new int[]
+ { 1, 9 }, mapList.getFromRanges()));
+ assertTrue(Arrays.equals(new int[]
+ { 1, 3 }, mapList.getToRanges()));
+ mapList = protMappings[1].getMap();
+ assertEquals(3, mapList.getFromRatio());
+ assertEquals(1, mapList.getToRatio());
+ assertTrue(Arrays.equals(new int[]
+ { 1, 9 }, mapList.getFromRanges()));
+ assertTrue(Arrays.equals(new int[]
+ { 1, 3 }, mapList.getToRanges()));
+
+ /*
+ * Inspect mapping for Mouse protein - should map to 1st/3rd/5th cDNA seqs
+ */
+ AlignedCodonFrame mouseMapping = protein.getCodonFrame(
+ protein.getSequenceAt(1)).get(0);
+ assertEquals(3, mouseMapping.getdnaSeqs().length);
+ assertEquals(cdna1.getSequenceAt(0).getDatasetSequence(),
+ mouseMapping.getdnaSeqs()[0]);
+ assertEquals(cdna1.getSequenceAt(2).getDatasetSequence(),
+ mouseMapping.getdnaSeqs()[1]);
+ assertEquals(cdna1.getSequenceAt(4).getDatasetSequence(),
+ mouseMapping.getdnaSeqs()[2]);
+
+ // three mappings
+ protMappings = mouseMapping.getProtMappings();
+ assertEquals(3, protMappings.length);
+
+ // first mapping to cDNA with start codon
+ mapList = protMappings[0].getMap();
+ assertEquals(3, mapList.getFromRatio());
+ assertEquals(1, mapList.getToRatio());
+ assertTrue(Arrays.equals(new int[]
+ { 4, 12 }, mapList.getFromRanges()));
+ assertTrue(Arrays.equals(new int[]
+ { 1, 3 }, mapList.getToRanges()));
+
+ // second mapping to cDNA with stop codon
+ mapList = protMappings[1].getMap();
+ assertEquals(3, mapList.getFromRatio());
+ assertEquals(1, mapList.getToRatio());
+ assertTrue(Arrays.equals(new int[]
+ { 1, 9 }, mapList.getFromRanges()));
+ assertTrue(Arrays.equals(new int[]
+ { 1, 3 }, mapList.getToRanges()));
+
+ // third mapping to cDNA with start and stop codon
+ mapList = protMappings[2].getMap();
+ assertEquals(3, mapList.getFromRatio());
+ assertEquals(1, mapList.getToRatio());
+ assertTrue(Arrays.equals(new int[]
+ { 4, 12 }, mapList.getFromRanges()));
+ assertTrue(Arrays.equals(new int[]
+ { 1, 3 }, mapList.getToRanges()));
+ }
+
+ /**
+ * Test for the alignSequenceAs method that takes two sequences and a mapping.
+ */
+ @Test
+ public void testAlignSequenceAs_withMapping_noIntrons()
+ {
+ MapList map = new MapList(new int[]
+ { 1, 6 }, new int[]
+ { 1, 2 }, 3, 1);
+
+ /*
+ * No existing gaps in dna:
+ */
+ checkAlignSequenceAs("GGGAAA", "-A-L-", false, false, map,
+ "---GGG---AAA");
+
+ /*
+ * Now introduce gaps in dna but ignore them when realigning.
+ */
+ checkAlignSequenceAs("-G-G-G-A-A-A-", "-A-L-", false, false, map,
+ "---GGG---AAA");
+
+ /*
+ * Now include gaps in dna when realigning. First retaining 'mapped' gaps
+ * only, i.e. those within the exon region.
+ */
+ checkAlignSequenceAs("-G-G--G-A--A-A-", "-A-L-", true, false, map,
+ "---G-G--G---A--A-A");
+
+ /*
+ * Include all gaps in dna when realigning (within and without the exon
+ * region). The leading gap, and the gaps between codons, are subsumed by
+ * the protein alignment gap.
+ */
+ checkAlignSequenceAs("-G-GG--AA-A-", "-A-L-", true, true, map,
+ "---G-GG---AA-A-");
+
+ /*
+ * Include only unmapped gaps in dna when realigning (outside the exon
+ * region). The leading gap, and the gaps between codons, are subsumed by
+ * the protein alignment gap.
+ */
+ checkAlignSequenceAs("-G-GG--AA-A-", "-A-L-", false, true, map,
+ "---GGG---AAA-");
+ }
+
+ /**
+ * Test for the alignSequenceAs method that takes two sequences and a mapping.
+ */
+ @Test
+ public void testAlignSequenceAs_withMapping_withIntrons()
+ {
+ /*
+ * Exons at codon 2 (AAA) and 4 (TTT)
+ */
+ MapList map = new MapList(new int[]
+ { 4, 6, 10, 12 }, new int[]
+ { 1, 2 }, 3, 1);
+
+ /*
+ * Simple case: no gaps in dna
+ */
+ checkAlignSequenceAs("GGGAAACCCTTTGGG", "--A-L-", false, false, map,
+ "GGG---AAACCCTTTGGG");
+
+ /*
+ * Add gaps to dna - but ignore when realigning.
+ */
+ checkAlignSequenceAs("-G-G-G--A--A---AC-CC-T-TT-GG-G-", "--A-L-",
+ false, false, map, "GGG---AAACCCTTTGGG");
+
+ /*
+ * Add gaps to dna - include within exons only when realigning.
+ */
+ checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-",
+ true, false, map, "GGG---A--A---ACCCT-TTGGG");
+
+ /*
+ * Include gaps outside exons only when realigning.
+ */
+ checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-",
+ false, true, map, "-G-G-GAAAC-CCTTT-GG-G-");
+
+ /*
+ * Include gaps following first intron if we are 'preserving mapped gaps'
+ */
+ checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-",
+ true, true, map, "-G-G-G--A--A---A-C-CC-T-TT-GG-G-");
+
+ /*
+ * Include all gaps in dna when realigning.
+ */
+ checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-",
+ true, true, map, "-G-G-G--A--A---A-C-CC-T-TT-GG-G-");
+ }
+
+ /**
+ * Test for the case where not all of the protein sequence is mapped to cDNA.
+ */
+ @Test
+ public void testAlignSequenceAs_withMapping_withUnmappedProtein()
+ {
+
+ /*
+ * Exons at codon 2 (AAA) and 4 (TTT) mapped to A and P
+ */
+ final MapList map = new MapList(new int[]
+ { 4, 6, 10, 12 }, new int[]
+ { 1, 1, 3, 3 }, 3, 1);
+
+
+ /*
+ * Expect alignment does nothing (aborts realignment). Change this test
+ * first if different behaviour wanted.
+ */
+ checkAlignSequenceAs("GGGAAACCCTTTGGG", "-A-L-P-", false,
+ false, map, "GGGAAACCCTTTGGG");
+ }
+
+ /**
+ * Helper method that performs and verifies the method under test.
+ *
+ * @param dnaSeq
+ * @param proteinSeq
+ * @param preserveMappedGaps
+ * @param preserveUnmappedGaps
+ * @param map
+ * @param expected
+ */
+ protected void checkAlignSequenceAs(final String dnaSeq,
+ final String proteinSeq, final boolean preserveMappedGaps,
+ final boolean preserveUnmappedGaps, MapList map,
+ final String expected)
+ {
+ SequenceI dna = new Sequence("Seq1", dnaSeq);
+ dna.createDatasetSequence();
+ SequenceI protein = new Sequence("Seq1", proteinSeq);
+ protein.createDatasetSequence();
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map);
+
+ AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-',
+ preserveMappedGaps, preserveUnmappedGaps);
+ assertEquals(expected, dna.getSequenceAsString());
+ }
+
+ /**
+ * Test for the alignSequenceAs method where we preserve gaps in introns only.
+ */
+ @Test
+ public void testAlignSequenceAs_keepIntronGapsOnly()
+ {
+
+ /*
+ * Intron GGGAAA followed by exon CCCTTT
+ */
+ MapList map = new MapList(new int[]
+ { 7, 12 }, new int[]
+ { 1, 2 }, 3, 1);
+
+ checkAlignSequenceAs("GG-G-AA-A-C-CC-T-TT", "AL",
+ false, true, map, "GG-G-AA-ACCCTTT");
}
}
--- /dev/null
+package jalview.analysis;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.io.FastaFile;
+
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Generates, and outputs in Fasta format, a random DNA alignment for given
+ * sequence length and count. Will regenerate the same alignment each time if
+ * the same random seed is used (so may be used for reproducible unit tests).
+ * Not guaranteed to reproduce the same results between versions, as the rules
+ * may get tweaked to produce more 'realistic' results.
+ *
+ * Arguments:
+ * <ul>
+ * <li>length (number of bases in each sequence)</li>
+ * <li>height (number of sequences)</li>
+ * <li>a whole number random seed</li>
+ * <li>percentage of gaps to include (0-100)</li>
+ * <li>percentage chance of variation of each position (0-100)</li>
+ * </ul>
+ *
+ * @author gmcarstairs
+ *
+ */
+public class DnaAlignmentGenerator
+{
+ private static final char GAP = '-';
+
+ private static final char ZERO = '0';
+
+ private static final char[] BASES = new char[]
+ { 'G', 'T', 'C', 'A' };
+
+ private Random random;
+
+ /**
+ * Outputs a DNA 'alignment' where each position is a random choice from
+ * 'GTCA-'.
+ *
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ if (args.length != 5)
+ {
+ usage();
+ return;
+ }
+ int width = Integer.parseInt(args[0]);
+ int height = Integer.parseInt(args[1]);
+ long randomSeed = Long.valueOf(args[2]);
+ int gapPercentage = Integer.valueOf(args[3]);
+ int changePercentage = Integer.valueOf(args[4]);
+ AlignmentI al = new DnaAlignmentGenerator().generate(width, height,
+ randomSeed, gapPercentage, changePercentage);
+
+ System.out.println("; " + height + " sequences of " + width
+ + " bases with " + gapPercentage + "% gaps and "
+ + changePercentage + "% mutations (random seed = " + randomSeed
+ + ")");
+ System.out.println(new FastaFile().print(al.getSequencesArray()));
+ }
+
+ /**
+ * Print parameter help.
+ */
+ private static void usage()
+ {
+ System.out.println("Usage:");
+ System.out.println("arg0: number of (non-gap) bases per sequence");
+ System.out.println("arg1: number sequences");
+ System.out
+ .println("arg2: an integer as random seed (same seed = same results)");
+ System.out.println("arg3: percentage of gaps to (randomly) generate");
+ System.out
+ .println("arg4: percentage of 'mutations' to (randomly) generate");
+ System.out.println("Example: DnaAlignmentGenerator 12 15 387 10 5");
+ System.out
+ .println("- 15 sequences of 12 bases each, approx 10% gaps and 5% mutations, random seed = 387");
+
+ }
+
+ /**
+ * Default constructor
+ */
+ public DnaAlignmentGenerator()
+ {
+
+ }
+
+ /**
+ * Outputs a DNA 'alignment' of given width and height, where each position is
+ * a random choice from 'GTCA-'.
+ *
+ * @param width
+ * @param height
+ * @param randomSeed
+ * @param changePercentage
+ * @param gapPercentage
+ */
+ public AlignmentI generate(int width, int height, long randomSeed,
+ int gapPercentage, int changePercentage)
+ {
+ SequenceI[] seqs = new SequenceI[height];
+ random = new Random(randomSeed);
+ seqs[0] = generateSequence(1, width, gapPercentage);
+ for (int seqno = 1; seqno < height; seqno++)
+ {
+ seqs[seqno] = generateAnotherSequence(seqs[0].getSequence(),
+ seqno + 1, width, changePercentage);
+ }
+ AlignmentI al = new Alignment(seqs);
+ return al;
+ }
+
+ /**
+ * Outputs a DNA 'sequence' of given length, with some random gaps included.
+ *
+ * @param seqno
+ * @param length
+ * @param gapPercentage
+ */
+ private SequenceI generateSequence(int seqno, int length,
+ int gapPercentage)
+ {
+ StringBuilder seq = new StringBuilder(length);
+
+ /*
+ * Loop till we've added 'length' bases (excluding gaps)
+ */
+ for (int count = 0; count < length;)
+ {
+ boolean addGap = random.nextInt(100) < gapPercentage;
+ char c = addGap ? GAP : BASES[random.nextInt(Integer.MAX_VALUE) % 4];
+ seq.append(c);
+ if (!addGap)
+ {
+ count++;
+ }
+ }
+ final String seqName = "SEQ" + seqno;
+ final String seqString = seq.toString();
+ SequenceI sq = new Sequence(seqName, seqString);
+ sq.createDatasetSequence();
+ return sq;
+ }
+
+ /**
+ * Generate a sequence approximately aligned to the first one.
+ *
+ * @param ds
+ * @param seqno
+ * @param width
+ * number of bases
+ * @param changePercentage
+ * @return
+ */
+ private SequenceI generateAnotherSequence(char[] ds, int seqno,
+ int width, int changePercentage)
+ {
+ int length = ds.length;
+ char[] seq = new char[length];
+ Arrays.fill(seq, ZERO);
+ int gapsWanted = length - width;
+ int gapsAdded = 0;
+
+ /*
+ * First 'randomly' mimic gaps in model sequence.
+ */
+ for (int pos = 0; pos < length; pos++)
+ {
+ if (ds[pos] == GAP)
+ {
+ /*
+ * Add a gap at the same position with changePercentage likelihood
+ */
+ seq[pos] = randomCharacter(GAP, changePercentage);
+ if (seq[pos] == GAP)
+ {
+ gapsAdded++;
+ }
+ }
+ }
+
+ /*
+ * Next scatter any remaining gaps (if any) at random. This gives an even
+ * distribution.
+ */
+ while (gapsAdded < gapsWanted)
+ {
+ boolean added = false;
+ while (!added)
+ {
+ int pos = random.nextInt(length);
+ if (seq[pos] != GAP)
+ {
+ seq[pos] = GAP;
+ added = true;
+ gapsAdded++;
+ }
+ }
+ }
+
+ /*
+ * Finally fill in the rest with randomly mutated bases.
+ */
+ for (int pos = 0; pos < length; pos++)
+ {
+ if (seq[pos] == ZERO)
+ {
+ char c = randomCharacter(ds[pos], changePercentage);
+ seq[pos] = c;
+ }
+ }
+ final String seqName = "SEQ" + seqno;
+ final String seqString = new String(seq);
+ SequenceI sq = new Sequence(seqName, seqString);
+ sq.createDatasetSequence();
+ return sq;
+ }
+
+ /**
+ * Returns a random character that is changePercentage% likely to match the
+ * given type (as base or gap).
+ *
+ * @param changePercentage
+ *
+ * @param c
+ * @return
+ */
+ private char randomCharacter(char c, int changePercentage)
+ {
+ final boolean mutation = random.nextInt(100) < changePercentage;
+
+ if (!mutation)
+ {
+ return c;
+ }
+
+ char newchar = c;
+ while (newchar == c)
+ {
+ newchar = BASES[random.nextInt(Integer.MAX_VALUE) % 4];
+ }
+ return newchar;
+ }
+}
--- /dev/null
+package jalview.analysis;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import jalview.api.AlignViewportI;
+import jalview.datamodel.AlignedCodon;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignViewport;
+import jalview.io.FormatAdapter;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+public class DnaTest
+{
+ // @formatter:off
+ // AA encoding codons as ordered on the Jalview help page Amino Acid Table
+ private static String fasta = ">B\n" + "GCT" + "GCC" + "GCA" + "GCG"
+ + "TGT" + "TGC" + "GAT" + "GAC" + "GAA" + "GAG" + "TTT" + "TTC"
+ + "GGT" + "GGC" + "GGA" + "GGG" + "CAT" + "CAC" + "ATT" + "ATC"
+ + "ATA" + "AAA" + "AAG" + "TTG" + "TTA" + "CTT" + "CTC" + "CTA"
+ + "CTG" + "ATG" + "AAT" + "AAC" + "CCT" + "CCC" + "CCA" + "CCG"
+ + "CAA" + "CAG" + "CGT" + "CGC" + "CGA" + "CGG" + "AGA" + "AGG"
+ + "TCT" + "TCC" + "TCA" + "TCG" + "AGT" + "AGC" + "ACT" + "ACC"
+ + "ACA" + "ACG" + "GTT" + "GTC" + "GTA" + "GTG" + "TGG" + "TAT"
+ + "TAC" + "TAA" + "TAG" + "TGA";
+
+ private static String JAL_1312_example_align_fasta = ">B.FR.83.HXB2_LAI_IIIB_BRU_K03455/45-306\n"
+ + "ATGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAATTAAAACATATAGTATGGGCAAGCAG\n"
+ + "GGAGCTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATACTGGGACA\n"
+ + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAGATCATTATATAATACAGTAGCAACCCTCTATTG\n"
+ + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAC\n"
+ + ">gi|27804621|gb|AY178912.1|/1-259\n"
+ + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n"
+ + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGGACA\n"
+ + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
+ + "TGTTCATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAT\n"
+ + ">gi|27804623|gb|AY178913.1|/1-259\n"
+ + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n"
+ + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGAACA\n"
+ + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
+ + "TGTTCATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n"
+ + ">gi|27804627|gb|AY178915.1|/1-260\n"
+ + "-TGGGAAAA-ATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n"
+ + "GGAGCTAGAACGATTCGCAGTTAACCCTGGCCTGTTAGAAACATCAGAAGGTTGTAGACAAATATTGGGACA\n"
+ + "GCTACAACCATCCCTTGAGACAGGATCAGAAGAACTTAAATCATTATWTAATACCATAGCAGTCCTCTATTG\n"
+ + "TGTACATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAG\n"
+ + ">gi|27804631|gb|AY178917.1|/1-261\n"
+ + "-TGGGAAAAAATTCGGTTGAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n"
+ + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACACCAGAAGGCTGTAGACAAATACTGGGACA\n"
+ + "GCTACAACCGTCCCTTCAGACAGGATCGGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
+ + "TGTGCATCAAAGGATAGATGTAAAAGACACCAAGGAGGCTTTAGAC\n"
+ + ">gi|27804635|gb|AY178919.1|/1-261\n"
+ + "-TGGGAGAGAATTCGGTTACGGCCAGGAGGAAAGAAAAAATATAAATTGAAACATATAGTATGGGCAGGCAG\n"
+ + "AGAGCTAGATCGATTCGCAGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAGATATTGGGACA\n"
+ + "GCTACAACCGTCCCTTAAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
+ + "TGTACATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n"
+ + ">gi|27804641|gb|AY178922.1|/1-261\n"
+ + "-TGGGAGAAAATTCGGTTACGGCCAGGGGGAAAGAAAAGATATAAGTTAAAACATATAGTATGGGCAAGCAG\n"
+ + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAAATACTGGGACA\n"
+ + "GTTACACCCATCCCTTCATACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
+ + "TGTGCATCAAAGGATAGAAGTAAAAGACACCAAGGAAGCTTTAGAC\n"
+ + ">gi|27804647|gb|AY178925.1|/1-261\n"
+ + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATCAATTAAAACATGTAGTATGGGCAAGCAG\n"
+ + "GGAACTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n"
+ + "GCTACAACCATCCCTTCAGACAGGATCAGAGGAACTTAAATCATTATTTAATACAGTAGCAGTCCTCTATTG\n"
+ + "TGTACATCAAAGAATAGATGTAAAAGACACCAAGGAAGCTCTAGAA\n"
+ + ">gi|27804649|gb|AY178926.1|/1-261\n"
+ + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n"
+ + "GGAGCTAGAACGATTCGCGGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAACTACTGGGACA\n"
+ + "GTTACAACCATCCCTTCAGACAGGATCAGAAGAACTCAAATCATTATATAATACAATAGCAACCCTCTATTG\n"
+ + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCCTTAGAT\n"
+ + ">gi|27804653|gb|AY178928.1|/1-261\n"
+ + "-TGGGAAAGAATTCGGTTAAGGCCAGGGGGAAAGAAACAATATAAATTAAAACATATAGTATGGGCAAGCAG\n"
+ + "GGAGCTAGACCGATTCGCACTTAACCCCGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n"
+ + "GCTACAATCGTCCCTTCAGACAGGATCAGAAGAACTTAGATCACTATATAATACAGTAGCAGTCCTCTATTG\n"
+ + "TGTGCATCAAAAGATAGATGTAAAAGACACCAAGGAAGCCTTAGAC\n"
+ + ">gi|27804659|gb|AY178931.1|/1-261\n"
+ + "-TGGGAAAAAATTCGGTTACGGCCAGGAGGAAAGAAAAGATATAAATTAAAACATATAGTATGGGCAAGCAG\n"
+ + "GGAGCTAGAACGATTYGCAGTTAATCCTGGCCTTTTAGAAACAGCAGAAGGCTGTAGACAAATACTGGGACA\n"
+ + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
+ + "TGTACATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAA\n";
+ // @formatter:on
+
+ /**
+ * Corner case for this test is the presence of codons after codons that were
+ * not translated.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testTranslateCdna_withUntranslatableCodons()
+ throws IOException
+ {
+ AlignmentI alf = new FormatAdapter().readFile(
+ JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE,
+ "FASTA");
+ ColumnSelection cs = new ColumnSelection();
+ AlignViewportI av = new AlignViewport(alf, cs);
+ Dna dna = new Dna(av, new int[]
+ { 0, alf.getWidth() - 1 });
+ AlignmentI translated = dna.translateCdna();
+ assertNotNull("Couldn't do a full width translation of test data.",
+ translated);
+ }
+
+ /**
+ * Test variant in which 15 column blocks at a time are translated (the rest
+ * hidden).
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testTranslateCdna_withUntranslatableCodonsAndHiddenColumns()
+ throws IOException
+ {
+ AlignmentI alf = new FormatAdapter().readFile(
+ JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE,
+ "FASTA");
+ int vwidth = 15;
+ for (int ipos = 0; ipos + vwidth < alf.getWidth(); ipos += vwidth)
+ {
+ ColumnSelection cs = new ColumnSelection();
+ if (ipos > 0)
+ {
+ cs.hideColumns(0, ipos - 1);
+ }
+ cs.hideColumns(ipos + vwidth, alf.getWidth());
+ int[] vcontigs = cs.getVisibleContigs(0, alf.getWidth());
+ AlignViewportI av = new AlignViewport(alf, cs);
+ Dna dna = new Dna(av, vcontigs);
+ AlignmentI transAlf = dna.translateCdna();
+
+ assertTrue("Translation failed (ipos=" + ipos
+ + ") No alignment data.", transAlf != null);
+ assertTrue("Translation failed (ipos=" + ipos + ") Empty alignment.",
+ transAlf.getHeight() > 0);
+ assertTrue("Translation failed (ipos=" + ipos + ") Translated "
+ + transAlf.getHeight() + " sequences from " + alf.getHeight()
+ + " sequences", alf.getHeight() == transAlf.getHeight());
+ }
+ }
+
+ /**
+ * Test simple translation to Amino Acids (with STOP codons translated to X).
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testTranslateCdna_simple() throws IOException
+ {
+ AlignmentI alf = new FormatAdapter().readFile(fasta,
+ FormatAdapter.PASTE, "FASTA");
+ ColumnSelection cs = new ColumnSelection();
+ AlignViewportI av = new AlignViewport(alf, cs);
+ Dna dna = new Dna(av, new int[]
+ { 0, alf.getWidth() - 1 });
+ AlignmentI translated = dna.translateCdna();
+ String aa = translated.getSequenceAt(0).getSequenceAsString();
+ assertEquals(
+ "AAAACCDDEEFFGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVWYYXXX",
+ aa);
+ }
+
+ /**
+ * Test translation excluding hidden columns.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testTranslateCdna_hiddenColumns() throws IOException
+ {
+ AlignmentI alf = new FormatAdapter().readFile(fasta,
+ FormatAdapter.PASTE, "FASTA");
+ ColumnSelection cs = new jalview.datamodel.ColumnSelection();
+ cs.hideColumns(6, 14); // hide codons 3/4/5
+ cs.hideColumns(24, 35); // hide codons 9-12
+ cs.hideColumns(177, 191); // hide codons 60-64
+ AlignViewportI av = new AlignViewport(alf, cs);
+ Dna dna = new Dna(av, new int[]
+ { 0, alf.getWidth() - 1 });
+ AlignmentI translated = dna.translateCdna();
+ String aa = translated.getSequenceAt(0).getSequenceAsString();
+ assertEquals("AACDDGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVW", aa);
+ }
+
+ /**
+ * Use this test to help debug into any cases of interest.
+ */
+ @Test
+ public void testCompareCodonPos_oneOnly()
+ {
+ assertFollows("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1
+ }
+
+ /**
+ * Tests for method that compares 'alignment' of two codon position triplets.
+ */
+ @Test
+ public void testCompareCodonPos()
+ {
+ /*
+ * Returns 0 for any null argument
+ */
+ assertEquals(0, Dna.compareCodonPos(new AlignedCodon(1, 2, 3), null));
+ assertEquals(0, Dna.compareCodonPos(null, new AlignedCodon(1, 2, 3)));
+
+ /*
+ * Work through 27 combinations. First 9 cases where first position matches.
+ */
+ assertMatches("AAA", "GGG"); // 2 and 3 match
+ assertFollows("AA-A", "GGG"); // 2 matches, 3 shifted seq1
+ assertPrecedes("AAA", "GG-G"); // 2 matches, 3 shifted seq2
+ assertFollows("A-AA", "GG-G"); // 2 shifted seq1, 3 matches
+ assertFollows("A-A-A", "GG-G"); // 2 shifted seq1, 3 shifted seq1
+ assertPrecedes("A-AA", "GG--G"); // 2 shifted seq1, 3 shifted seq2
+ assertPrecedes("AA-A", "G-GG"); // 2 shifted seq2, 3 matches
+ assertFollows("AA--A", "G-GG"); // 2 shifted seq2, 3 shifted seq1
+ assertPrecedes("AAA", "G-GG"); // 2 shifted seq2, 3 shifted seq2
+
+ /*
+ * 9 cases where first position is shifted in first sequence.
+ */
+ assertFollows("-AAA", "G-GG"); // 2 and 3 match
+ assertFollows("-AA-A", "G-GG"); // 2 matches, 3 shifted seq1
+ // 'enclosing' case: pick first to start precedes
+ assertFollows("-AAA", "G-G-G"); // 2 matches, 3 shifted seq2
+ assertFollows("-A-AA", "G-G-G"); // 2 shifted seq1, 3 matches
+ assertFollows("-A-A-A", "G-G-G"); // 2 shifted seq1, 3 shifted seq1
+ // 'enclosing' case: pick first to start precedes
+ assertFollows("-A-AA", "G-G--G"); // 2 shifted seq1, 3 shifted seq2
+ assertFollows("-AA-A", "G--GG"); // 2 shifted seq2, 3 matches
+ assertFollows("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1
+ assertPrecedes("-AAA", "G--GG"); // 2 shifted seq2, 3 shifted seq2
+
+ /*
+ * 9 cases where first position is shifted in second sequence.
+ */
+ assertPrecedes("A-AA", "-GGG"); // 2 and 3 match
+ assertPrecedes("A-A-A", "-GGG"); // 2 matches, 3 shifted seq1
+ assertPrecedes("A-AA", "-GG-G"); // 2 matches, 3 shifted seq2
+ assertPrecedes("A--AA", "-GG-G"); // 2 shifted seq1, 3 matches
+ // 'enclosing' case with middle base deciding:
+ assertFollows("A--AA", "-GGG"); // 2 shifted seq1, 3 shifted seq1
+ assertPrecedes("A--AA", "-GG--G"); // 2 shifted seq1, 3 shifted seq2
+ assertPrecedes("AA-A", "-GGG"); // 2 shifted seq2, 3 matches
+ assertPrecedes("AA--A", "-GGG"); // 2 shifted seq2, 3 shifted seq1
+ assertPrecedes("AAA", "-GGG"); // 2 shifted seq2, 3 shifted seq2
+ }
+
+ /**
+ * This test generates a random cDNA alignment and its translation, then
+ * reorders the cDNA and retranslates, and verifies that the translations are
+ * the same (apart from ordering).
+ */
+ @Test
+ public void testTranslateCdna_sequenceOrderIndependent()
+ {
+ /*
+ * Generate cDNA - 8 sequences of 12 bases each.
+ */
+ AlignmentI cdna = new DnaAlignmentGenerator().generate(12, 8, 97, 5, 5);
+ ColumnSelection cs = new ColumnSelection();
+ AlignViewportI av = new AlignViewport(cdna, cs);
+ Dna dna = new Dna(av, new int[]
+ { 0, cdna.getWidth() - 1 });
+ AlignmentI translated = dna.translateCdna();
+
+ /*
+ * Jumble the cDNA sequences and translate.
+ */
+ SequenceI[] sorted = new SequenceI[cdna.getHeight()];
+ final int[] jumbler = new int[]
+ { 6, 7, 3, 4, 2, 0, 1, 5 };
+ int seqNo = 0;
+ for (int i : jumbler)
+ {
+ sorted[seqNo++] = cdna.getSequenceAt(i);
+ }
+ AlignmentI cdnaReordered = new Alignment(sorted);
+ av = new AlignViewport(cdnaReordered, cs);
+ dna = new Dna(av, new int[]
+ { 0, cdna.getWidth() - 1 });
+ AlignmentI translated2 = dna.translateCdna();
+
+ /*
+ * Check translated sequences are the same in both alignments.
+ */
+ System.out.println("Original");
+ System.out.println(translated.toString());
+ System.out.println("Sorted");
+ System.out.println(translated2.toString());
+
+ int sortedSequenceIndex = 0;
+ for (int originalSequenceIndex : jumbler)
+ {
+ final String translation1 = translated.getSequenceAt(
+ originalSequenceIndex).getSequenceAsString();
+ final String translation2 = translated2.getSequenceAt(sortedSequenceIndex)
+ .getSequenceAsString();
+ assertEquals(translation2, translation1);
+ sortedSequenceIndex++;
+ }
+ }
+
+ /**
+ * Test that all the cases in testCompareCodonPos have a 'symmetric'
+ * comparison (without checking the actual comparison result).
+ */
+ @Test
+ public void testCompareCodonPos_isSymmetric()
+ {
+ assertSymmetric("AAA", "GGG");
+ assertSymmetric("AA-A", "GGG");
+ assertSymmetric("AAA", "GG-G");
+ assertSymmetric("A-AA", "GG-G");
+ assertSymmetric("A-A-A", "GG-G");
+ assertSymmetric("A-AA", "GG--G");
+ assertSymmetric("AA-A", "G-GG");
+ assertSymmetric("AA--A", "G-GG");
+ assertSymmetric("AAA", "G-GG");
+ assertSymmetric("-AAA", "G-GG");
+ assertSymmetric("-AA-A", "G-GG");
+ assertSymmetric("-AAA", "G-G-G");
+ assertSymmetric("-A-AA", "G-G-G");
+ assertSymmetric("-A-A-A", "G-G-G");
+ assertSymmetric("-A-AA", "G-G--G");
+ assertSymmetric("-AA-A", "G--GG");
+ assertSymmetric("-AA--A", "G--GG");
+ assertSymmetric("-AAA", "G--GG");
+ assertSymmetric("A-AA", "-GGG");
+ assertSymmetric("A-A-A", "-GGG");
+ assertSymmetric("A-AA", "-GG-G");
+ assertSymmetric("A--AA", "-GG-G");
+ assertSymmetric("A--AA", "-GGG");
+ assertSymmetric("A--AA", "-GG--G");
+ assertSymmetric("AA-A", "-GGG");
+ assertSymmetric("AA--A", "-GGG");
+ assertSymmetric("AAA", "-GGG");
+ }
+
+ private void assertSymmetric(String codon1, String codon2)
+ {
+ assertEquals("Comparison of '" + codon1 + "' and '" + codon2
+ + " not symmetric", Integer.signum(compare(codon1, codon2)),
+ -Integer.signum(compare(codon2, codon1)));
+ }
+
+ /**
+ * Assert that the first sequence should map to the same position as the
+ * second in a translated alignment. Also checks that this is true if the
+ * order of the codons is reversed.
+ *
+ * @param codon1
+ * @param codon2
+ */
+ private void assertMatches(String codon1, String codon2)
+ {
+ assertEquals("Expected '" + codon1 + "' matches '" + codon2 + "'", 0,
+ compare(codon1, codon2));
+ assertEquals("Expected '" + codon2 + "' matches '" + codon1 + "'", 0,
+ compare(codon2, codon1));
+ }
+
+ /**
+ * Assert that the first sequence should precede the second in a translated
+ * alignment
+ *
+ * @param codon1
+ * @param codon2
+ */
+ private void assertPrecedes(String codon1, String codon2)
+ {
+ assertEquals("Expected '" + codon1 + "' precedes '" + codon2 + "'",
+ -1, compare(codon1, codon2));
+ }
+
+ /**
+ * Assert that the first sequence should follow the second in a translated
+ * alignment
+ *
+ * @param codon1
+ * @param codon2
+ */
+ private void assertFollows(String codon1, String codon2)
+ {
+ assertEquals("Expected '" + codon1 + "' follows '" + codon2 + "'", 1,
+ compare(codon1, codon2));
+ }
+
+ /**
+ * Convert two nucleotide strings to base positions and pass to
+ * Dna.compareCodonPos, return the result.
+ *
+ * @param s1
+ * @param s2
+ * @return
+ */
+ private int compare(String s1, String s2)
+ {
+ final AlignedCodon cd1 = convertCodon(s1);
+ final AlignedCodon cd2 = convertCodon(s2);
+ System.out.println("K: " + s1 + " " + cd1.toString());
+ System.out.println("G: " + s2 + " " + cd2.toString());
+ System.out.println();
+ return Dna.compareCodonPos(cd1, cd2);
+ }
+
+ /**
+ * Convert a string e.g. "-GC-T" to base positions e.g. [1, 2, 4]. The string
+ * should have exactly 3 non-gap characters, and use '-' for gaps.
+ *
+ * @param s
+ * @return
+ */
+ private AlignedCodon convertCodon(String s)
+ {
+ int[] codon = new int[3];
+ int i = 0;
+ for (int j = 0; j < s.length(); j++)
+ {
+ if (s.charAt(j) != '-')
+ {
+ codon[i++] = j;
+ }
+ }
+ return new AlignedCodon(codon[0], codon[1], codon[2]);
+ }
+
+ /**
+ * Weirdly, maybe worth a test to prove the helper method of this test class.
+ */
+ @Test
+ public void testConvertCodon()
+ {
+ assertEquals("[0, 1, 2]", convertCodon("AAA").toString());
+ assertEquals("[0, 2, 5]", convertCodon("A-A--A").toString());
+ assertEquals("[1, 3, 4]", convertCodon("-A-AA-").toString());
+ }
+}
+++ /dev/null
-/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * Jalview is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.analysis;
-
-import static org.junit.Assert.*;
-import jalview.datamodel.ColumnSelection;
-
-import java.io.IOException;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-public class DnaTranslation
-{
-
- private static String JAL_1312_example_align_fasta = ">B.FR.83.HXB2_LAI_IIIB_BRU_K03455/45-306\n"
- + "ATGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAATTAAAACATATAGTATGGGCAAGCAG\n"
- + "GGAGCTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATACTGGGACA\n"
- + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAGATCATTATATAATACAGTAGCAACCCTCTATTG\n"
- + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAC\n"
- + ">gi|27804621|gb|AY178912.1|/1-259\n"
- + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n"
- + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGGACA\n"
- + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
- + "TGTTCATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAT\n"
- + ">gi|27804623|gb|AY178913.1|/1-259\n"
- + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n"
- + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGAACA\n"
- + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
- + "TGTTCATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n"
- + ">gi|27804627|gb|AY178915.1|/1-260\n"
- + "-TGGGAAAA-ATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n"
- + "GGAGCTAGAACGATTCGCAGTTAACCCTGGCCTGTTAGAAACATCAGAAGGTTGTAGACAAATATTGGGACA\n"
- + "GCTACAACCATCCCTTGAGACAGGATCAGAAGAACTTAAATCATTATWTAATACCATAGCAGTCCTCTATTG\n"
- + "TGTACATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAG\n"
- + ">gi|27804631|gb|AY178917.1|/1-261\n"
- + "-TGGGAAAAAATTCGGTTGAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n"
- + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACACCAGAAGGCTGTAGACAAATACTGGGACA\n"
- + "GCTACAACCGTCCCTTCAGACAGGATCGGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
- + "TGTGCATCAAAGGATAGATGTAAAAGACACCAAGGAGGCTTTAGAC\n"
- + ">gi|27804635|gb|AY178919.1|/1-261\n"
- + "-TGGGAGAGAATTCGGTTACGGCCAGGAGGAAAGAAAAAATATAAATTGAAACATATAGTATGGGCAGGCAG\n"
- + "AGAGCTAGATCGATTCGCAGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAGATATTGGGACA\n"
- + "GCTACAACCGTCCCTTAAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
- + "TGTACATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n"
- + ">gi|27804641|gb|AY178922.1|/1-261\n"
- + "-TGGGAGAAAATTCGGTTACGGCCAGGGGGAAAGAAAAGATATAAGTTAAAACATATAGTATGGGCAAGCAG\n"
- + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAAATACTGGGACA\n"
- + "GTTACACCCATCCCTTCATACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
- + "TGTGCATCAAAGGATAGAAGTAAAAGACACCAAGGAAGCTTTAGAC\n"
- + ">gi|27804647|gb|AY178925.1|/1-261\n"
- + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATCAATTAAAACATGTAGTATGGGCAAGCAG\n"
- + "GGAACTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n"
- + "GCTACAACCATCCCTTCAGACAGGATCAGAGGAACTTAAATCATTATTTAATACAGTAGCAGTCCTCTATTG\n"
- + "TGTACATCAAAGAATAGATGTAAAAGACACCAAGGAAGCTCTAGAA\n"
- + ">gi|27804649|gb|AY178926.1|/1-261\n"
- + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n"
- + "GGAGCTAGAACGATTCGCGGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAACTACTGGGACA\n"
- + "GTTACAACCATCCCTTCAGACAGGATCAGAAGAACTCAAATCATTATATAATACAATAGCAACCCTCTATTG\n"
- + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCCTTAGAT\n"
- + ">gi|27804653|gb|AY178928.1|/1-261\n"
- + "-TGGGAAAGAATTCGGTTAAGGCCAGGGGGAAAGAAACAATATAAATTAAAACATATAGTATGGGCAAGCAG\n"
- + "GGAGCTAGACCGATTCGCACTTAACCCCGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n"
- + "GCTACAATCGTCCCTTCAGACAGGATCAGAAGAACTTAGATCACTATATAATACAGTAGCAGTCCTCTATTG\n"
- + "TGTGCATCAAAAGATAGATGTAAAAGACACCAAGGAAGCCTTAGAC\n"
- + ">gi|27804659|gb|AY178931.1|/1-261\n"
- + "-TGGGAAAAAATTCGGTTACGGCCAGGAGGAAAGAAAAGATATAAATTAAAACATATAGTATGGGCAAGCAG\n"
- + "GGAGCTAGAACGATTYGCAGTTAATCCTGGCCTTTTAGAAACAGCAGAAGGCTGTAGACAAATACTGGGACA\n"
- + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n"
- + "TGTACATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAA\n";
-
- @Test
- public void translationWithUntranslatableCodonsTest()
- {
- // Corner case for this test is the presence of codons after codons that
- // were not translated.
- jalview.datamodel.AlignmentI alf = null;
- try
- {
- alf = new jalview.io.FormatAdapter().readFile(
- JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE,
- "FASTA");
- } catch (IOException x)
- {
- x.printStackTrace();
- fail("Unexpected IOException (" + x.getMessage()
- + ") - check test environment");
- }
- {
- // full translation
- ColumnSelection cs = new jalview.datamodel.ColumnSelection();
- assertNotNull("Couldn't do a full width translation of test data.",
- jalview.analysis.Dna.CdnaTranslate(
- alf.getSequencesArray(),
- cs.getVisibleSequenceStrings(0, alf.getWidth(),
- alf.getSequencesArray()), new int[]
- { 0, alf.getWidth() - 1 }, alf.getGapCharacter(),
- null, alf.getWidth(), null));
- }
- int vwidth = 15; // translate in 15 base stretches
- for (int ipos = 0; ipos + vwidth < alf.getWidth(); ipos += vwidth)
- {
- ColumnSelection cs = new jalview.datamodel.ColumnSelection();
- if (ipos > 0)
- {
- cs.hideColumns(0, ipos - 1);
- }
- cs.hideColumns(ipos + vwidth, alf.getWidth());
- int[] vcontigs = cs.getVisibleContigs(0, alf.getWidth());
- String[] sel = cs.getVisibleSequenceStrings(0, alf.getWidth(),
- alf.getSequencesArray());
- jalview.datamodel.AlignmentI transAlf = jalview.analysis.Dna
- .CdnaTranslate(alf.getSequencesArray(), sel, vcontigs,
- alf.getGapCharacter(), null, alf.getWidth(), null);
-
- assertTrue("Translation failed (ipos=" + ipos
- + ") No alignment data.", transAlf != null);
- assertTrue("Translation failed (ipos=" + ipos + ") Empty algnment.",
- transAlf.getHeight() > 0);
- assertTrue("Translation failed (ipos=" + ipos + ") Translated "
- + transAlf.getHeight() + " sequences from " + alf.getHeight()
- + " sequences", alf.getHeight() == transAlf.getHeight());
- }
-
- }
-}
*/
package jalview.analysis;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import jalview.datamodel.Mapping;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
}
}
+ @Test
+ public void testExtractGaps()
+ {
+ assertNull(AlignSeq.extractGaps(null, null));
+ assertNull(AlignSeq.extractGaps(". -", null));
+ assertNull(AlignSeq.extractGaps(null, "AB-C"));
+
+ assertEquals("ABCD", AlignSeq.extractGaps(" .-", ". -A-B.C D."));
+ }
}
package jalview.commands;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
import jalview.commands.EditCommand.Action;
import jalview.commands.EditCommand.Edit;
import jalview.datamodel.Alignment;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import java.util.Map;
+
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
testee = new EditCommand();
seqs = new SequenceI[4];
seqs[0] = new Sequence("seq0", "abcdefghjk");
+ seqs[0].setDatasetSequence(new Sequence("seq0ds", "abcdefghjk"));
seqs[1] = new Sequence("seq1", "fghjklmnopq");
+ seqs[1].setDatasetSequence(new Sequence("seq1ds", "fghjklmnopq"));
seqs[2] = new Sequence("seq2", "qrstuvwxyz");
+ seqs[2].setDatasetSequence(new Sequence("seq2ds", "qrstuvwxyz"));
seqs[3] = new Sequence("seq3", "1234567890");
+ seqs[3].setDatasetSequence(new Sequence("seq3ds", "1234567890"));
al = new Alignment(seqs);
al.setGapCharacter('?');
}
assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
assertEquals("1234567890", seqs[3].getSequenceAsString());
seqs[1] = new Sequence("seq1", "fghjZXYnopq");
+ }
+
+ /**
+ * Test that the addEdit command correctly merges insert gap commands when
+ * possible.
+ */
+ @Test
+ public void testAddEdit_multipleInsertGap()
+ {
+ /*
+ * 3 insert gap in a row (aka mouse drag right):
+ */
+ Edit e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[]
+ { seqs[0] }, 1, 1, al);
+ testee.addEdit(e);
+ SequenceI edited = new Sequence("seq0", "a?bcdefghjk");
+ edited.setDatasetSequence(seqs[0].getDatasetSequence());
+ e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[]
+ { edited }, 2, 1, al);
+ testee.addEdit(e);
+ edited = new Sequence("seq0", "a??bcdefghjk");
+ edited.setDatasetSequence(seqs[0].getDatasetSequence());
+ e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[]
+ { edited }, 3, 1, al);
+ testee.addEdit(e);
+ assertEquals(1, testee.getSize());
+ assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction());
+ assertEquals(1, testee.getEdit(0).getPosition());
+ assertEquals(3, testee.getEdit(0).getNumber());
+
+ /*
+ * Add a non-contiguous edit - should not be merged.
+ */
+ e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[]
+ { edited }, 5, 2, al);
+ testee.addEdit(e);
+ assertEquals(2, testee.getSize());
+ assertEquals(5, testee.getEdit(1).getPosition());
+ assertEquals(2, testee.getEdit(1).getNumber());
+
+ /*
+ * Add a Delete after the Insert - should not be merged.
+ */
+ e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
+ { edited }, 6, 2, al);
+ testee.addEdit(e);
+ assertEquals(3, testee.getSize());
+ assertEquals(Action.DELETE_GAP, testee.getEdit(2).getAction());
+ assertEquals(6, testee.getEdit(2).getPosition());
+ assertEquals(2, testee.getEdit(2).getNumber());
+ }
+
+ /**
+ * Test that the addEdit command correctly merges delete gap commands when
+ * possible.
+ */
+ @Test
+ public void testAddEdit_multipleDeleteGap()
+ {
+ /*
+ * 3 delete gap in a row (aka mouse drag left):
+ */
+ seqs[0].setSequence("a???bcdefghjk");
+ Edit e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
+ { seqs[0] }, 4, 1, al);
+ testee.addEdit(e);
+ assertEquals(1, testee.getSize());
+
+ SequenceI edited = new Sequence("seq0", "a??bcdefghjk");
+ edited.setDatasetSequence(seqs[0].getDatasetSequence());
+ e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
+ { edited }, 3, 1, al);
+ testee.addEdit(e);
+ assertEquals(1, testee.getSize());
+
+ edited = new Sequence("seq0", "a?bcdefghjk");
+ edited.setDatasetSequence(seqs[0].getDatasetSequence());
+ e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
+ { edited }, 2, 1, al);
+ testee.addEdit(e);
+ assertEquals(1, testee.getSize());
+ assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction());
+ assertEquals(2, testee.getEdit(0).getPosition());
+ assertEquals(3, testee.getEdit(0).getNumber());
+
+ /*
+ * Add a non-contiguous edit - should not be merged.
+ */
+ e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
+ { edited }, 2, 1, al);
+ testee.addEdit(e);
+ assertEquals(2, testee.getSize());
+ assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction());
+ assertEquals(2, testee.getEdit(1).getPosition());
+ assertEquals(1, testee.getEdit(1).getNumber());
+
+ /*
+ * Add an Insert after the Delete - should not be merged.
+ */
+ e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[]
+ { edited }, 1, 1, al);
+ testee.addEdit(e);
+ assertEquals(3, testee.getSize());
+ assertEquals(Action.INSERT_GAP, testee.getEdit(2).getAction());
+ assertEquals(1, testee.getEdit(2).getPosition());
+ assertEquals(1, testee.getEdit(2).getNumber());
+ }
+
+ /**
+ * Test that the addEdit command correctly handles 'remove gaps' edits for the
+ * case when they appear contiguous but are acting on different sequences.
+ * They should not be merged.
+ */
+ @Test
+ public void testAddEdit_removeAllGaps()
+ {
+ seqs[0].setSequence("a???bcdefghjk");
+ Edit e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
+ { seqs[0] }, 4, 1, al);
+ testee.addEdit(e);
+
+ seqs[1].setSequence("f??ghjklmnopq");
+ Edit e2 = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
+ { seqs[1] }, 3, 1, al);
+ testee.addEdit(e2);
+ assertEquals(2, testee.getSize());
+ assertSame(e, testee.getEdit(0));
+ assertSame(e2, testee.getEdit(1));
+ }
+
+ /**
+ * Test that the addEdit command correctly merges insert gap commands acting
+ * on a multi-sequence selection.
+ */
+ @Test
+ public void testAddEdit_groupInsertGaps()
+ {
+ /*
+ * 2 insert gap in a row (aka mouse drag right), on two sequences:
+ */
+ Edit e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[]
+ { seqs[0], seqs[1] }, 1, 1, al);
+ testee.addEdit(e);
+ SequenceI seq1edited = new Sequence("seq0", "a?bcdefghjk");
+ seq1edited.setDatasetSequence(seqs[0].getDatasetSequence());
+ SequenceI seq2edited = new Sequence("seq1", "f?ghjklmnopq");
+ seq2edited.setDatasetSequence(seqs[1].getDatasetSequence());
+ e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[]
+ { seq1edited, seq2edited }, 2, 1, al);
+ testee.addEdit(e);
+
+ assertEquals(1, testee.getSize());
+ assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction());
+ assertEquals(1, testee.getEdit(0).getPosition());
+ assertEquals(2, testee.getEdit(0).getNumber());
+ assertEquals(seqs[0].getDatasetSequence(), testee.getEdit(0)
+ .getSequences()[0].getDatasetSequence());
+ assertEquals(seqs[1].getDatasetSequence(), testee.getEdit(0)
+ .getSequences()[1].getDatasetSequence());
+ }
+
+ /**
+ * Test for 'undoing' a series of gap insertions.
+ * <ul>
+ * <li>Start: ABCDEF insert 2 at pos 1</li>
+ * <li>next: A--BCDEF insert 1 at pos 4</li>
+ * <li>next: A--B-CDEF insert 2 at pos 0</li>
+ * <li>last: --A--B-CDEF</li>
+ * </ul>
+ */
+ @Test
+ public void testPriorState_multipleInserts()
+ {
+ EditCommand command = new EditCommand();
+ SequenceI seq = new Sequence("", "--A--B-CDEF");
+ SequenceI ds = new Sequence("", "ABCDEF");
+ seq.setDatasetSequence(ds);
+ SequenceI[] seqs = new SequenceI[]
+ { seq };
+ Edit e = command.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-');
+ command.addEdit(e);
+ e = command.new Edit(Action.INSERT_GAP, seqs, 4, 1, '-');
+ command.addEdit(e);
+ e = command.new Edit(Action.INSERT_GAP, seqs, 0, 2, '-');
+ command.addEdit(e);
+
+ Map<SequenceI, SequenceI> unwound = command.priorState(false);
+ assertEquals("ABCDEF", unwound.get(ds).getSequenceAsString());
+ }
+
+ /**
+ * Test for 'undoing' a series of gap deletions.
+ * <ul>
+ * <li>Start: A-B-C delete 1 at pos 1</li>
+ * <li>Next: AB-C delete 1 at pos 2</li>
+ * <li>End: ABC</li>
+ * </ul>
+ */
+ @Test
+ public void testPriorState_removeAllGaps()
+ {
+ EditCommand command = new EditCommand();
+ SequenceI seq = new Sequence("", "ABC");
+ SequenceI ds = new Sequence("", "ABC");
+ seq.setDatasetSequence(ds);
+ SequenceI[] seqs = new SequenceI[]
+ { seq };
+ Edit e = command.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
+ command.addEdit(e);
+ e = command.new Edit(Action.DELETE_GAP, seqs, 2, 1, '-');
+ command.addEdit(e);
+
+ Map<SequenceI, SequenceI> unwound = command.priorState(false);
+ assertEquals("A-B-C", unwound.get(ds).getSequenceAsString());
+ }
+
+ /**
+ * Test for 'undoing' a single delete edit.
+ */
+ @Test
+ public void testPriorState_singleDelete()
+ {
+ EditCommand command = new EditCommand();
+ SequenceI seq = new Sequence("", "ABCDEF");
+ SequenceI ds = new Sequence("", "ABCDEF");
+ seq.setDatasetSequence(ds);
+ SequenceI[] seqs = new SequenceI[]
+ { seq };
+ Edit e = command.new Edit(Action.DELETE_GAP, seqs, 2, 2, '-');
+ command.addEdit(e);
+
+ Map<SequenceI, SequenceI> unwound = command.priorState(false);
+ assertEquals("AB--CDEF", unwound.get(ds).getSequenceAsString());
+ }
+
+ /**
+ * Test 'undoing' a single gap insertion edit command.
+ */
+ @Test
+ public void testPriorState_singleInsert()
+ {
+ EditCommand command = new EditCommand();
+ SequenceI seq = new Sequence("", "AB---CDEF");
+ SequenceI ds = new Sequence("", "ABCDEF");
+ seq.setDatasetSequence(ds);
+ SequenceI[] seqs = new SequenceI[]
+ { seq };
+ Edit e = command.new Edit(Action.INSERT_GAP, seqs, 2, 3, '-');
+ command.addEdit(e);
+
+ Map<SequenceI, SequenceI> unwound = command.priorState(false);
+ assertEquals("ABCDEF", unwound.get(ds).getSequenceAsString());
+ }
+
+ /**
+ * Test that mimics 'remove all gaps' action. This generates delete gap edits
+ * for contiguous gaps in each sequence separately.
+ */
+ @Test
+ public void testPriorState_removeGapsMultipleSeqs()
+ {
+ EditCommand command = new EditCommand();
+ String original1 = "--ABC-DEF";
+ String original2 = "FG-HI--J";
+ String original3 = "M-NOPQ";
+
+ /*
+ * Two edits for the first sequence
+ */
+ SequenceI seq = new Sequence("", "ABC-DEF");
+ SequenceI ds1 = new Sequence("", "ABCDEF");
+ seq.setDatasetSequence(ds1);
+ SequenceI[] seqs = new SequenceI[]
+ { seq };
+ Edit e = command.new Edit(Action.DELETE_GAP, seqs, 0, 2, '-');
+ command.addEdit(e);
+ seq = new Sequence("", "ABCDEF");
+ seq.setDatasetSequence(ds1);
+ seqs = new SequenceI[]
+ { seq };
+ e = command.new Edit(Action.DELETE_GAP, seqs, 3, 1, '-');
+ command.addEdit(e);
+
+ /*
+ * Two edits for the second sequence
+ */
+ seq = new Sequence("", "FGHI--J");
+ SequenceI ds2 = new Sequence("", "FGHIJ");
+ seq.setDatasetSequence(ds2);
+ seqs = new SequenceI[]
+ { seq };
+ e = command.new Edit(Action.DELETE_GAP, seqs, 2, 1, '-');
+ command.addEdit(e);
+ seq = new Sequence("", "FGHIJ");
+ seq.setDatasetSequence(ds2);
+ seqs = new SequenceI[]
+ { seq };
+ e = command.new Edit(Action.DELETE_GAP, seqs, 4, 2, '-');
+ command.addEdit(e);
+
+ /*
+ * One edit for the third sequence.
+ */
+ seq = new Sequence("", "MNOPQ");
+ SequenceI ds3 = new Sequence("", "MNOPQ");
+ seq.setDatasetSequence(ds3);
+ seqs = new SequenceI[]
+ { seq };
+ e = command.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
+ command.addEdit(e);
+
+ Map<SequenceI, SequenceI> unwound = command.priorState(false);
+ assertEquals(original1, unwound.get(ds1).getSequenceAsString());
+ assertEquals(original2, unwound.get(ds2).getSequenceAsString());
+ assertEquals(original3, unwound.get(ds3).getSequenceAsString());
+ }
+
+ /**
+ * Test that mimics 'remove all gapped columns' action. This generates a
+ * series Delete Gap edits that each act on all sequences that share a gapped
+ * column region.
+ */
+ @Test
+ public void testPriorState_removeGappedCols()
+ {
+ EditCommand command = new EditCommand();
+ String original1 = "--ABC--DEF";
+ String original2 = "-G-HI--J";
+ String original3 = "-M-NO--PQ";
+
+ /*
+ * First edit deletes the first column.
+ */
+ SequenceI seq1 = new Sequence("", "-ABC--DEF");
+ SequenceI ds1 = new Sequence("", "ABCDEF");
+ seq1.setDatasetSequence(ds1);
+ SequenceI seq2 = new Sequence("", "G-HI--J");
+ SequenceI ds2 = new Sequence("", "GHIJ");
+ seq2.setDatasetSequence(ds2);
+ SequenceI seq3 = new Sequence("", "M-NO--PQ");
+ SequenceI ds3 = new Sequence("", "MNOPQ");
+ seq3.setDatasetSequence(ds3);
+ SequenceI[] seqs = new SequenceI[]
+ { seq1, seq2, seq3 };
+ Edit e = command.new Edit(Action.DELETE_GAP, seqs, 0, 1, '-');
+ command.addEdit(e);
+
+ /*
+ * Second edit deletes what is now columns 4 and 5.
+ */
+ seq1 = new Sequence("", "-ABCDEF");
+ seq1.setDatasetSequence(ds1);
+ seq2 = new Sequence("", "G-HIJ");
+ seq2.setDatasetSequence(ds2);
+ seq3 = new Sequence("", "M-NOPQ");
+ seq3.setDatasetSequence(ds3);
+ seqs = new SequenceI[]
+ { seq1, seq2, seq3 };
+ e = command.new Edit(Action.DELETE_GAP, seqs, 4, 2, '-');
+ command.addEdit(e);
+ Map<SequenceI, SequenceI> unwound = command.priorState(false);
+ assertEquals(original1, unwound.get(ds1).getSequenceAsString());
+ assertEquals(original2, unwound.get(ds2).getSequenceAsString());
+ assertEquals(original3, unwound.get(ds3).getSequenceAsString());
+ assertEquals(ds1, unwound.get(ds1).getDatasetSequence());
+ assertEquals(ds2, unwound.get(ds2).getDatasetSequence());
+ assertEquals(ds3, unwound.get(ds3).getDatasetSequence());
}
}
--- /dev/null
+package jalview.datamodel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import jalview.util.MapList;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class AlignedCodonFrameTest
+{
+
+ /**
+ * Test the method that locates the first aligned sequence that has a mapping.
+ */
+ @Test
+ public void testFindAlignedSequence()
+ {
+ AlignmentI cdna = new Alignment(new SequenceI[]
+ {});
+ final Sequence seq1 = new Sequence("Seq1", "C-G-TA-GC");
+ seq1.createDatasetSequence();
+ cdna.addSequence(seq1);
+ final Sequence seq2 = new Sequence("Seq2", "-TA-GG-GG");
+ seq2.createDatasetSequence();
+ cdna.addSequence(seq2);
+
+ AlignmentI aa = new Alignment(new SequenceI[]
+ {});
+ final Sequence aseq1 = new Sequence("Seq1", "-P-R");
+ aseq1.createDatasetSequence();
+ aa.addSequence(aseq1);
+ final Sequence aseq2 = new Sequence("Seq2", "-LY-");
+ aseq2.createDatasetSequence();
+ aa.addSequence(aseq2);
+
+ /*
+ * Mapping from first DNA sequence to second AA sequence.
+ */
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+
+ assertNull(acf.findAlignedSequence(seq1, aa));
+
+ MapList map = new MapList(new int[]
+ { 1, 6 }, new int[]
+ { 1, 2 }, 3, 1);
+ acf.addMap(seq1.getDatasetSequence(), aseq2.getDatasetSequence(), map);
+
+ /*
+ * DNA seq1 maps to AA seq2
+ */
+ assertEquals(aa.getSequenceAt(1),
+ acf.findAlignedSequence(cdna
+ .getSequenceAt(0).getDatasetSequence(), aa));
+
+ assertEquals(cdna.getSequenceAt(0),
+ acf.findAlignedSequence(aa
+ .getSequenceAt(1).getDatasetSequence(), cdna));
+ }
+
+ /**
+ * Test the method that locates the mapped codon for a protein position.
+ */
+ @Test
+ public void testGetMappedRegion()
+ {
+ // introns lower case, exons upper case
+ final Sequence seq1 = new Sequence("Seq1", "c-G-TA-gC-gT-T");
+ seq1.createDatasetSequence();
+ final Sequence seq2 = new Sequence("Seq2", "-TA-gG-Gg-CG-a");
+ seq2.createDatasetSequence();
+
+ final Sequence aseq1 = new Sequence("Seq1", "-P-R");
+ aseq1.createDatasetSequence();
+ final Sequence aseq2 = new Sequence("Seq2", "-LY-");
+ aseq2.createDatasetSequence();
+
+ /*
+ * First with no mappings
+ */
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+
+ assertNull(acf.getMappedRegion(seq1, aseq1, 1));
+
+ /*
+ * Set up the mappings for the exons (upper-case bases)
+ */
+ MapList map = new MapList(new int[]
+ { 2, 4, 6, 6, 8, 9 }, new int[]
+ { 1, 2 }, 3, 1);
+ acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map);
+ map = new MapList(new int[]
+ { 1, 2, 4, 5, 7, 8 }, new int[]
+ { 1, 2 }, 3, 1);
+ acf.addMap(seq2.getDatasetSequence(), aseq2.getDatasetSequence(), map);
+
+ assertEquals("[2, 4]",
+ Arrays.toString(acf.getMappedRegion(seq1, aseq1, 1)));
+ assertEquals("[6, 6, 8, 9]",
+ Arrays.toString(acf.getMappedRegion(seq1, aseq1, 2)));
+ assertEquals("[1, 2, 4, 4]",
+ Arrays.toString(acf.getMappedRegion(seq2, aseq2, 1)));
+ assertEquals("[5, 5, 7, 8]",
+ Arrays.toString(acf.getMappedRegion(seq2, aseq2, 2)));
+
+ /*
+ * No mapping from sequence 1 to sequence 2
+ */
+ assertNull(acf.getMappedRegion(seq1, aseq2, 1));
+ }
+}
--- /dev/null
+package jalview.datamodel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class AlignedCodonTest
+{
+
+ @Test
+ public void testEquals()
+ {
+ AlignedCodon ac = new AlignedCodon(1, 3, 4);
+ assertTrue(ac.equals(null));
+ assertFalse(ac.equals("hello"));
+ assertFalse(ac.equals(new AlignedCodon(1, 3, 5)));
+ assertTrue(ac.equals(new AlignedCodon(1, 3, 4)));
+ assertTrue(ac.equals(ac));
+ }
+
+ @Test
+ public void testToString() {
+ AlignedCodon ac = new AlignedCodon(1, 3, 4);
+ assertEquals("[1, 3, 4]", ac.toString());
+ }
+}
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import jalview.io.AppletFormatAdapter;
+import jalview.io.FormatAdapter;
+import jalview.util.MapList;
import java.io.IOException;
import java.util.Iterator;
"D.melanogaster.3 G.UGGCGCU..UAUGACGCA\n" +
"#=GR D.melanogaster.3 SS (.(((...(....(((((((\n" +
"//";
+
+ private static final String AA_SEQS_1 =
+ ">Seq1Name\n" +
+ "K-QY--L\n" +
+ ">Seq2Name\n" +
+ "-R-FP-W-\n";
+
+ private static final String CDNA_SEQS_1 =
+ ">Seq1Name\n" +
+ "AC-GG--CUC-CAA-CT\n" +
+ ">Seq2Name\n" +
+ "-CG-TTA--ACG---AAGT\n";
+
+ private static final String CDNA_SEQS_2 =
+ ">Seq1Name\n" +
+ "GCTCGUCGTACT\n" +
+ ">Seq2Name\n" +
+ "GGGTCAGGCAGT\n";
// @formatter:on
+ private AlignmentI al;
- private Alignment al;
+ /**
+ * Helper method to load an alignment and ensure dataset sequences are set up.
+ *
+ * @param data
+ * @param format
+ * TODO
+ * @return
+ * @throws IOException
+ */
+ protected AlignmentI loadAlignment(final String data, String format)
+ throws IOException
+ {
+ Alignment a = new FormatAdapter().readFile(data,
+ AppletFormatAdapter.PASTE, format);
+ a.setDataset(null);
+ return a;
+ }
/*
* Read in Stockholm format test data including secondary structure
@Before
public void setUp() throws IOException
{
- al = new jalview.io.FormatAdapter().readFile(TEST_DATA,
- AppletFormatAdapter.PASTE, "STH");
- for (int i = 0; i < al.getSequencesArray().length; ++i)
+ al = loadAlignment(TEST_DATA, "STH");
+ int i = 0;
+ for (AlignmentAnnotation ann : al.getAlignmentAnnotation())
{
- al.addAnnotation(al.getSequenceAt(i).getAnnotation()[0]);
- al.getSequenceAt(i).getAnnotation()[0].setCalcId("CalcIdFor"
- + al.getSequenceAt(i).getName());
+ ann.setCalcId("CalcIdFor" + al.getSequenceAt(i).getName());
+ i++;
}
}
assertEquals("D.melanogaster.2", ann.sequenceRef.getName());
assertFalse(iter.hasNext());
}
+
+ @Test
+ public void testDeleteAllAnnotations_includingAutocalculated()
+ {
+ AlignmentAnnotation aa = new AlignmentAnnotation("Consensus",
+ "Consensus", 0.5);
+ aa.autoCalculated = true;
+ al.addAnnotation(aa);
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+ assertEquals("Wrong number of annotations before deleting", 4,
+ anns.length);
+ al.deleteAllAnnotations(true);
+ assertEquals("Not all deleted", 0, al.getAlignmentAnnotation().length);
+ }
+
+ @Test
+ public void testDeleteAllAnnotations_excludingAutocalculated()
+ {
+ AlignmentAnnotation aa = new AlignmentAnnotation("Consensus",
+ "Consensus", 0.5);
+ aa.autoCalculated = true;
+ al.addAnnotation(aa);
+ AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
+ assertEquals("Wrong number of annotations before deleting", 4,
+ anns.length);
+ al.deleteAllAnnotations(false);
+ assertEquals("Not just one annotation left", 1,
+ al.getAlignmentAnnotation().length);
+ }
+
+ /**
+ * Tests for realigning as per a supplied alignment: Dna as Dna.
+ *
+ * Note: AlignedCodonFrame's state variables are named for protein-to-cDNA
+ * mapping, but can be exploited for a general 'sequence-to-sequence' mapping
+ * as here.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testAlignAs_dnaAsDna() throws IOException
+ {
+ // aligned cDNA:
+ AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA");
+ // unaligned cDNA:
+ AlignmentI al2 = loadAlignment(CDNA_SEQS_2, "FASTA");
+
+ /*
+ * Make mappings between sequences. The 'aligned cDNA' is playing the role
+ * of what would normally be protein here.
+ */
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ MapList ml = new MapList(new int[]
+ { 1, 12 }, new int[]
+ { 1, 12 }, 1, 1);
+ acf.addMap(al2.getSequenceAt(0), al1.getSequenceAt(0), ml);
+ acf.addMap(al2.getSequenceAt(1), al1.getSequenceAt(1), ml);
+ al1.addCodonFrame(acf);
+
+ ((Alignment) al2).alignAs(al1, false, true);
+ assertEquals("GC-TC--GUC-GTA-CT", al2.getSequenceAt(0)
+ .getSequenceAsString());
+ assertEquals("-GG-GTC--AGG---CAGT", al2.getSequenceAt(1)
+ .getSequenceAsString());
+ }
+
+ /**
+ * Aligning protein from cDNA yet to be implemented, does nothing.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testAlignAs_proteinAsCdna() throws IOException
+ {
+ AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA");
+ AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA");
+ String before0 = al2.getSequenceAt(0).getSequenceAsString();
+ String before1 = al2.getSequenceAt(1).getSequenceAsString();
+
+ ((Alignment) al2).alignAs(al1, false, true);
+ assertEquals(before0, al2.getSequenceAt(0).getSequenceAsString());
+ assertEquals(before1, al2.getSequenceAt(1).getSequenceAsString());
+ }
+
+ /**
+ * Test aligning cdna as per protein alignment.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testAlignAs_cdnaAsProtein() throws IOException
+ {
+ /*
+ * Load alignments and add mappings for cDNA to protein
+ */
+ AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA");
+ AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA");
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ MapList ml = new MapList(new int[]
+ { 1, 12 }, new int[]
+ { 1, 4 }, 3, 1);
+ acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml);
+ acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml);
+ al2.addCodonFrame(acf);
+
+ /*
+ * Realign DNA; currently keeping existing gaps in introns only
+ */
+ ((Alignment) al1).alignAs(al2, false, true);
+ assertEquals("ACG---GCUCCA------ACT", al1.getSequenceAt(0)
+ .getSequenceAsString());
+ assertEquals("---CGT---TAACGA---AGT", al1.getSequenceAt(1)
+ .getSequenceAsString());
+ }
+
+ /**
+ * Test aligning dna as per protein alignment, for the case where there are
+ * introns (i.e. some dna sites have no mapping from a peptide).
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testAlignAs_dnaAsProtein_withIntrons() throws IOException
+ {
+ /*
+ * Load alignments and add mappings for cDNA to protein
+ */
+ String dna1 = "A-Aa-gG-GCC-cT-TT";
+ String dna2 = "c--CCGgg-TT--T-AA-A";
+ AlignmentI al1 = loadAlignment(">Seq1\n" + dna1 + "\n>Seq2\n" + dna2
+ + "\n", "FASTA");
+ AlignmentI al2 = loadAlignment(">Seq1\n-P--YK\n>Seq2\nG-T--F\n",
+ "FASTA");
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ // Seq1 has intron at dna positions 3,4,9 so splice is AAG GCC TTT
+ // Seq2 has intron at dna positions 1,5,6 so splice is CCG TTT AAA
+ MapList ml1 = new MapList(new int[]
+ { 1, 2, 5, 8, 10, 12 }, new int[]
+ { 1, 3 }, 3, 1);
+ acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml1);
+ MapList ml2 = new MapList(new int[]
+ { 2, 4, 7, 12 }, new int[]
+ { 1, 3 }, 3, 1);
+ acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml2);
+ al2.addCodonFrame(acf);
+
+ /*
+ * Align ignoring gaps in dna introns and exons
+ */
+ ((Alignment) al1).alignAs(al2, false, false);
+ assertEquals("---AAagG------GCCcTTT", al1.getSequenceAt(0)
+ .getSequenceAsString());
+ // note 1 gap in protein corresponds to 'gg-' in DNA (3 positions)
+ assertEquals("cCCGgg-TTT------AAA", al1.getSequenceAt(1)
+ .getSequenceAsString());
+
+ /*
+ * Reset and realign, preserving gaps in dna introns and exons
+ */
+ al1.getSequenceAt(0).setSequence(dna1);
+ al1.getSequenceAt(1).setSequence(dna2);
+ ((Alignment) al1).alignAs(al2, true, true);
+ // String dna1 = "A-Aa-gG-GCC-cT-TT";
+ // String dna2 = "c--CCGgg-TT--T-AA-A";
+ // assumption: we include 'the greater of' protein/dna gap lengths, not both
+ assertEquals("---A-Aa-gG------GCC-cT-TT", al1.getSequenceAt(0)
+ .getSequenceAsString());
+ assertEquals("c--CCGgg-TT--T------AA-A", al1.getSequenceAt(1)
+ .getSequenceAsString());
+ }
}
--- /dev/null
+package jalview.datamodel;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+
+public class ColumnSelectionTest
+{
+
+ @Test
+ public void testAddElement()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(2);
+ cs.addElement(5);
+ List<Integer> sel = cs.getSelected();
+ assertEquals(2, sel.size());
+ assertEquals(new Integer(2), sel.get(0));
+ assertEquals(new Integer(5), sel.get(1));
+ }
+
+ /**
+ * Test the remove method - in particular to verify that remove(int i) removes
+ * the element whose value is i, _NOT_ the i'th element.
+ */
+ @Test
+ public void testRemoveElement()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(2);
+ cs.addElement(5);
+
+ // removing elements not in the list has no effect
+ cs.removeElement(0);
+ cs.removeElement(1);
+ List<Integer> sel = cs.getSelected();
+ assertEquals(2, sel.size());
+ assertEquals(new Integer(2), sel.get(0));
+ assertEquals(new Integer(5), sel.get(1));
+
+ // removing an element in the list removes it
+ cs.removeElement(2);
+ assertEquals(1, sel.size());
+ assertEquals(new Integer(5), sel.get(0));
+ }
+}
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import java.util.Arrays;
import java.util.List;
import org.junit.Before;
assertSame(annotation2, anns[1]);
}
+
+ @Test
+ public void testGetStartGetEnd()
+ {
+ SequenceI seq = new Sequence("test", "ABCDEF");
+ assertEquals(1, seq.getStart());
+ assertEquals(6, seq.getEnd());
+
+ seq = new Sequence("test", "--AB-C-DEF--");
+ assertEquals(1, seq.getStart());
+ assertEquals(6, seq.getEnd());
+
+ seq = new Sequence("test", "----");
+ assertEquals(1, seq.getStart());
+ assertEquals(0, seq.getEnd()); // ??
+ }
+
+ /**
+ * Tests for the method that returns an alignment column position (base 1) for
+ * a given sequence position (base 1).
+ */
+ @Test
+ public void testFindIndex()
+ {
+ SequenceI seq = new Sequence("test", "ABCDEF");
+ assertEquals(0, seq.findIndex(0));
+ assertEquals(1, seq.findIndex(1));
+ assertEquals(5, seq.findIndex(5));
+ assertEquals(6, seq.findIndex(6));
+ assertEquals(6, seq.findIndex(9));
+
+ seq = new Sequence("test", "-A--B-C-D-E-F--");
+ assertEquals(2, seq.findIndex(1));
+ assertEquals(5, seq.findIndex(2));
+ assertEquals(7, seq.findIndex(3));
+
+ // before start returns 0
+ assertEquals(0, seq.findIndex(0));
+ assertEquals(0, seq.findIndex(-1));
+
+ // beyond end returns last residue column
+ assertEquals(13, seq.findIndex(99));
+
+ }
+
+ /**
+ * Tests for the method that returns a dataset sequence position (base 1) for
+ * an aligned column position (base 0).
+ */
+ @Test
+ public void testFindPosition()
+ {
+ SequenceI seq = new Sequence("test", "ABCDEF");
+ assertEquals(1, seq.findPosition(0));
+ assertEquals(6, seq.findPosition(5));
+ // assertEquals(-1, seq.findPosition(6)); // fails
+
+ seq = new Sequence("test", "AB-C-D--");
+ assertEquals(1, seq.findPosition(0));
+ assertEquals(2, seq.findPosition(1));
+ // gap position 'finds' residue to the right (not the left as per javadoc)
+ assertEquals(3, seq.findPosition(2));
+ assertEquals(3, seq.findPosition(3));
+ assertEquals(4, seq.findPosition(4));
+ assertEquals(4, seq.findPosition(5));
+ // returns 1 more than sequence length if off the end ?!?
+ assertEquals(5, seq.findPosition(6));
+ assertEquals(5, seq.findPosition(7));
+
+ seq = new Sequence("test", "--AB-C-DEF--");
+ assertEquals(1, seq.findPosition(0));
+ assertEquals(1, seq.findPosition(1));
+ assertEquals(1, seq.findPosition(2));
+ assertEquals(2, seq.findPosition(3));
+ assertEquals(3, seq.findPosition(4));
+ assertEquals(3, seq.findPosition(5));
+ assertEquals(4, seq.findPosition(6));
+ assertEquals(4, seq.findPosition(7));
+ assertEquals(5, seq.findPosition(8));
+ assertEquals(6, seq.findPosition(9));
+ assertEquals(7, seq.findPosition(10));
+ assertEquals(7, seq.findPosition(11));
+ }
+
+ @Test
+ public void testDeleteChars()
+ {
+ SequenceI seq = new Sequence("test", "ABCDEF");
+ assertEquals(1, seq.getStart());
+ assertEquals(6, seq.getEnd());
+ seq.deleteChars(2, 3);
+ assertEquals("ABDEF", seq.getSequenceAsString());
+ assertEquals(1, seq.getStart());
+ assertEquals(5, seq.getEnd());
+
+ seq = new Sequence("test", "ABCDEF");
+ seq.deleteChars(0, 2);
+ assertEquals("CDEF", seq.getSequenceAsString());
+ assertEquals(3, seq.getStart());
+ assertEquals(6, seq.getEnd());
+ }
+
+ @Test
+ public void testInsertCharAt()
+ {
+ // non-static methods:
+ SequenceI seq = new Sequence("test", "ABCDEF");
+ seq.insertCharAt(0, 'z');
+ assertEquals("zABCDEF", seq.getSequenceAsString());
+ seq.insertCharAt(2, 2, 'x');
+ assertEquals("zAxxBCDEF", seq.getSequenceAsString());
+
+ // for static method see StringUtilsTest
+ }
+
+ /**
+ * Test the method that returns an array of aligned sequence positions where
+ * the array index is the data sequence position (both base 0).
+ */
+ @Test
+ public void testGapMap()
+ {
+ SequenceI seq = new Sequence("test", "-A--B-CD-E--F-");
+ seq.createDatasetSequence();
+ assertEquals("[1, 4, 6, 7, 9, 12]", Arrays.toString(seq.gapMap()));
+ }
}
--- /dev/null
+package jalview.gui;
+
+import static org.junit.Assert.assertEquals;
+
+import javax.swing.JScrollBar;
+
+import org.junit.Test;
+
+public class JvSwingUtilsTest
+{
+
+ @Test
+ public void testGetScrollBarProportion()
+ {
+ /*
+ * orientation, value, extent (width), min, max
+ */
+ JScrollBar sb = new JScrollBar(0, 125, 50, 0, 450);
+
+ /*
+ * operating range is 25 - 425 (400 wide) so value 125 is 100/400ths of this
+ * range
+ */
+ assertEquals(0.25f, JvSwingUtils.getScrollBarProportion(sb), 0.001f);
+ }
+
+ @Test
+ public void testGetScrollValueForProportion()
+ {
+ /*
+ * orientation, value, extent (width), min, max
+ */
+ JScrollBar sb = new JScrollBar(0, 125, 50, 0, 450);
+
+ /*
+ * operating range is 25 - 425 (400 wide) so value 125 is a quarter of this
+ * range
+ */
+ assertEquals(125, JvSwingUtils.getScrollValueForProportion(sb, 0.25f));
+ }
+}
--- /dev/null
+package jalview.gui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import java.awt.Component;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JPanel;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PaintRefresherTest
+{
+ // TODO would prefer PaintRefresher to be a single rather than static
+ @Before
+ public void setUp()
+ {
+ PaintRefresher.components.clear();
+ }
+
+ @After
+ public void tearDown()
+ {
+ PaintRefresher.components.clear();
+ }
+
+ @Test
+ public void testRegister()
+ {
+ JPanel jp = new JPanel();
+ JPanel jp2 = new JPanel();
+ JPanel jp3 = new JPanel();
+ JPanel jp4 = new JPanel();
+ PaintRefresher.Register(jp, "22");
+ PaintRefresher.Register(jp, "22");
+ PaintRefresher.Register(jp2, "22");
+ PaintRefresher.Register(jp3, "33");
+ PaintRefresher.Register(jp3, "44");
+ PaintRefresher.Register(jp4, "44");
+
+ Map<String, List<Component>> registered = PaintRefresher.components;
+ assertEquals(3, registered.size());
+ assertEquals(2, registered.get("22").size());
+ assertEquals(1, registered.get("33").size());
+ assertEquals(2, registered.get("44").size());
+ assertTrue(registered.get("22").contains(jp));
+ assertTrue(registered.get("22").contains(jp2));
+ assertTrue(registered.get("33").contains(jp3));
+ assertTrue(registered.get("44").contains(jp3));
+ assertTrue(registered.get("44").contains(jp4));
+ }
+
+ @Test
+ public void testRemoveComponent()
+ {
+ Map<String, List<Component>> registered = PaintRefresher.components;
+
+ // no error with an empty PaintRefresher
+ JPanel jp = new JPanel();
+ JPanel jp2 = new JPanel();
+ PaintRefresher.RemoveComponent(jp);
+ assertTrue(registered.isEmpty());
+
+ /*
+ * Add then remove one item
+ */
+ PaintRefresher.Register(jp, "11");
+ PaintRefresher.RemoveComponent(jp);
+ assertTrue(registered.isEmpty());
+
+ /*
+ * Add one item under two ids, then remove it. It is removed from both ids,
+ * and the now empty id is removed.
+ */
+ PaintRefresher.Register(jp, "11");
+ PaintRefresher.Register(jp, "22");
+ PaintRefresher.Register(jp2, "22");
+ PaintRefresher.RemoveComponent(jp);
+ // "11" is removed as now empty, only 22/jp2 left
+ assertEquals(1, registered.size());
+ assertEquals(1, registered.get("22").size());
+ assertTrue(registered.get("22").contains(jp2));
+ }
+
+ @Test
+ public void testGetAssociatedPanels()
+ {
+ SequenceI [] seqs = new SequenceI[]{new Sequence("", "ABC")};
+ Alignment al = new Alignment(seqs);
+
+ /*
+ * AlignFrame constructor has side-effects: AlignmentPanel is constructed,
+ * and SeqCanvas, IdPanel, AlignmentPanel are all registered under the
+ * sequence set id of the viewport.
+ */
+ AlignViewport av = new AlignViewport(al);
+ AlignFrame af = new AlignFrame(al, 4, 1);
+ AlignmentPanel ap1 = af.alignPanel;
+ AlignmentPanel[] panels = PaintRefresher.getAssociatedPanels(av
+ .getSequenceSetId());
+ assertEquals(1, panels.length);
+ assertSame(ap1, panels[0]);
+
+ panels = PaintRefresher.getAssociatedPanels(av.getSequenceSetId() + 1);
+ assertEquals(0, panels.length);
+ }
+}
@Test
public void gatherViewsHere() throws Exception
{
- int origCount = Desktop.getAlignframes() == null ? 0 : Desktop
- .getAlignframes().length;
+ int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop
+ .getAlignFrames().length;
AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", FormatAdapter.FILE);
assertTrue("Didn't read in the example file correctly.", af != null);
assertTrue("Didn't gather the views in the example file.",
- Desktop.getAlignframes().length == 1 + origCount);
+ Desktop.getAlignFrames().length == 1 + origCount);
}
--- /dev/null
+package jalview.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import org.junit.Test;
+
+public class ComparisonTest
+{
+
+ @Test
+ public void testIsGap()
+ {
+ assertTrue(Comparison.isGap('-'));
+ assertTrue(Comparison.isGap('.'));
+ assertTrue(Comparison.isGap(' '));
+ assertFalse(Comparison.isGap('X'));
+ assertFalse(Comparison.isGap('x'));
+ assertFalse(Comparison.isGap('*'));
+ assertFalse(Comparison.isGap('G'));
+ }
+
+ /**
+ * Test for isNucleotide is that sequences in a dataset are more than 85%
+ * AGCTU. Test is not case-sensitive and ignores gaps.
+ */
+ @Test
+ public void testIsNucleotide() {
+ SequenceI seq = new Sequence("eightypercent", "agctuAGCPV");
+ assertFalse(Comparison.isNucleotide(new SequenceI[]
+ { seq }));
+
+ seq = new Sequence("eightyfivepercent", "agctuAGCPVagctuAGCUV");
+ assertFalse(Comparison.isNucleotide(new SequenceI[]
+ { seq }));
+
+ seq = new Sequence("nineypercent", "agctuAGCgVagctuAGCUV");
+ assertTrue(Comparison.isNucleotide(new SequenceI[]
+ { seq }));
+
+ seq = new Sequence("eightyfivepercentgapped",
+ "--agc--tuA--GCPV-a---gct-uA-GC---UV");
+ assertFalse(Comparison.isNucleotide(new SequenceI[]
+ { seq }));
+
+ seq = new Sequence("nineypercentgapped",
+ "ag--ct-u-A---GC---g----Vag--c---tuAGCUV");
+ assertTrue(Comparison.isNucleotide(new SequenceI[]
+ { seq }));
+
+ seq = new Sequence("allgap", "---------");
+ assertFalse(Comparison.isNucleotide(new SequenceI[]
+ { seq }));
+
+ seq = new Sequence("DNA", "ACTugGCCAG");
+ SequenceI seq2 = new Sequence("Protein", "FLIMVSPTYW");
+ assertTrue(Comparison.isNucleotide(new SequenceI[]
+ { seq, seq, seq, seq, seq, seq, seq, seq, seq, seq2 })); // 90% DNA
+ assertFalse(Comparison.isNucleotide(new SequenceI[]
+ { seq, seq, seq, seq, seq, seq, seq, seq, seq2, seq2 })); // 80% DNA
+
+ seq = new Sequence("ProteinThatLooksLikeDNA", "WYATGCCTGAgtcgt");
+ // 12/14 = 85.7%
+ assertTrue(Comparison.isNucleotide(new SequenceI[]
+ { seq }));
+
+ assertFalse(Comparison.isNucleotide(null));
+ }
+
+ /**
+ * Test percentage identity calculation for two sequences.
+ */
+ @Test
+ public void testPID_matchGaps()
+ {
+ String seq1 = "ABCDEF";
+ String seq2 = "abcdef";
+ assertEquals("identical", 100f, Comparison.PID(seq1, seq2), 0.001f);
+
+ // comparison range defaults to length of first sequence
+ seq2 = "abcdefghijklmnopqrstuvwxyz";
+ assertEquals("identical", 100f, Comparison.PID(seq1, seq2), 0.001f);
+
+ seq2 = "a---bcdef";
+ }
+}
--- /dev/null
+package jalview.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MapListTest
+{
+
+ @Test
+ public void testSomething()
+ {
+ MapList ml = new MapList(new int[]
+ { 1, 5, 10, 15, 25, 20 }, new int[]
+ { 51, 1 }, 1, 3);
+ MapList ml1 = new MapList(new int[]
+ { 1, 3, 17, 4 }, new int[]
+ { 51, 1 }, 1, 3);
+ MapList ml2 = new MapList(new int[]
+ { 1, 60 }, new int[]
+ { 1, 20 }, 3, 1);
+ // test internal consistency
+ int to[] = new int[51];
+ testMap(ml, 1, 60);
+ MapList mldna = new MapList(new int[]
+ { 2, 2, 6, 8, 12, 16 }, new int[]
+ { 1, 3 }, 3, 1);
+ int[] frm = mldna.locateInFrom(1, 1);
+ testLocateFrom(mldna, 1, 1, new int[]
+ { 2, 2, 6, 7 });
+ testMap(mldna, 1, 3);
+ /*
+ * for (int from=1; from<=51; from++) { int[] too=ml.shiftTo(from); int[]
+ * toofrom=ml.shiftFrom(too[0]);
+ * System.out.println("ShiftFrom("+from+")=="+too[0]+" %
+ * "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); }
+ */
+ }
+
+ private static void testLocateFrom(MapList mldna, int i, int j, int[] ks)
+ {
+ int[] frm = mldna.locateInFrom(i, j);
+ Assert.assertEquals("Failed test locate from " + i + " to " + j,
+ Arrays.toString(frm), Arrays.toString(ks));
+ }
+
+ /**
+ * test routine. not incremental.
+ *
+ * @param ml
+ * @param fromS
+ * @param fromE
+ */
+ private void testMap(MapList ml, int fromS, int fromE)
+ {
+ // todo convert to JUnit style tests
+ for (int from = 1; from <= 25; from++)
+ {
+ int[] too = ml.shiftFrom(from);
+ System.out.print("ShiftFrom(" + from + ")==");
+ if (too == null)
+ {
+ System.out.print("NaN\n");
+ }
+ else
+ {
+ System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")");
+ System.out.print("\t+--+\t");
+ int[] toofrom = ml.shiftTo(too[0]);
+ if (toofrom != null)
+ {
+ if (toofrom[0] != from)
+ {
+ System.err.println("Mapping not reflexive:" + from + " "
+ + too[0] + "->" + toofrom[0]);
+ }
+ System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0]
+ + " % " + toofrom[1] + " (" + toofrom[2] + ")");
+ }
+ else
+ {
+ System.out.println("ShiftTo(" + too[0] + ")=="
+ + "NaN! - not Bijective Mapping!");
+ }
+ }
+ }
+ int mmap[][] = ml.makeFromMap();
+ System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " "
+ + mmap[0][2] + " " + mmap[0][3] + " ");
+ for (int i = 1; i <= mmap[1].length; i++)
+ {
+ if (mmap[1][i - 1] == -1)
+ {
+ System.out.print(i + "=XXX");
+
+ }
+ else
+ {
+ System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1]));
+ }
+ if (i % 20 == 0)
+ {
+ System.out.print("\n");
+ }
+ else
+ {
+ System.out.print(",");
+ }
+ }
+ // test range function
+ System.out.print("\nTest locateInFrom\n");
+ {
+ int f = mmap[0][2], t = mmap[0][3];
+ while (f <= t)
+ {
+ System.out.println("Range " + f + " to " + t);
+ int rng[] = ml.locateInFrom(f, t);
+ if (rng != null)
+ {
+ for (int i = 0; i < rng.length; i++)
+ {
+ System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
+ }
+ }
+ else
+ {
+ System.out.println("No range!");
+ }
+ System.out.print("\nReversed\n");
+ rng = ml.locateInFrom(t, f);
+ if (rng != null)
+ {
+ for (int i = 0; i < rng.length; i++)
+ {
+ System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
+ }
+ }
+ else
+ {
+ System.out.println("No range!");
+ }
+ System.out.print("\n");
+ f++;
+ t--;
+ }
+ }
+ System.out.print("\n");
+ mmap = ml.makeToMap();
+ System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " "
+ + mmap[0][2] + " " + mmap[0][3] + " ");
+ for (int i = 1; i <= mmap[1].length; i++)
+ {
+ if (mmap[1][i - 1] == -1)
+ {
+ System.out.print(i + "=XXX");
+
+ }
+ else
+ {
+ System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1]));
+ }
+ if (i % 20 == 0)
+ {
+ System.out.print("\n");
+ }
+ else
+ {
+ System.out.print(",");
+ }
+ }
+ System.out.print("\n");
+ // test range function
+ System.out.print("\nTest locateInTo\n");
+ {
+ int f = mmap[0][2], t = mmap[0][3];
+ while (f <= t)
+ {
+ System.out.println("Range " + f + " to " + t);
+ int rng[] = ml.locateInTo(f, t);
+ if (rng != null)
+ {
+ for (int i = 0; i < rng.length; i++)
+ {
+ System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
+ }
+ }
+ else
+ {
+ System.out.println("No range!");
+ }
+ System.out.print("\nReversed\n");
+ rng = ml.locateInTo(t, f);
+ if (rng != null)
+ {
+ for (int i = 0; i < rng.length; i++)
+ {
+ System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
+ }
+ }
+ else
+ {
+ System.out.println("No range!");
+ }
+ f++;
+ t--;
+ System.out.print("\n");
+ }
+ }
+ }
+
+ /**
+ * Tests for method that locates ranges in the 'from' map for given range in
+ * the 'to' map.
+ */
+ @Test
+ public void testLocateInFrom_noIntrons()
+ {
+ /*
+ * Simple mapping with no introns
+ */
+ int[] codons = new int[]
+ { 1, 12 };
+ int[] protein = new int[]
+ { 1, 4 };
+ MapList ml = new MapList(codons, protein, 3, 1);
+ assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(1, 1)));
+ assertEquals("[4, 6]", Arrays.toString(ml.locateInFrom(2, 2)));
+ assertEquals("[7, 9]", Arrays.toString(ml.locateInFrom(3, 3)));
+ assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4)));
+ assertEquals("[1, 6]", Arrays.toString(ml.locateInFrom(1, 2)));
+ assertEquals("[1, 9]", Arrays.toString(ml.locateInFrom(1, 3)));
+ assertEquals("[1, 12]", Arrays.toString(ml.locateInFrom(1, 4)));
+ assertEquals("[4, 9]", Arrays.toString(ml.locateInFrom(2, 3)));
+ assertEquals("[4, 12]", Arrays.toString(ml.locateInFrom(2, 4)));
+ assertEquals("[7, 12]", Arrays.toString(ml.locateInFrom(3, 4)));
+ assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4)));
+
+ assertNull(ml.locateInFrom(0, 0));
+ assertNull(ml.locateInFrom(1, 5));
+ assertNull(ml.locateInFrom(-1, 1));
+ }
+
+ /**
+ * Tests for method that locates ranges in the 'from' map for given range in
+ * the 'to' map.
+ */
+ @Test
+ public void testLocateInFrom_withIntrons()
+ {
+ /*
+ * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e.
+ * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18
+ */
+ int[] codons =
+ { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
+ int[] protein =
+ { 1, 4 };
+ MapList ml = new MapList(codons, protein, 3, 1);
+ assertEquals("[2, 3, 5, 5]", Arrays.toString(ml.locateInFrom(1, 1)));
+ assertEquals("[6, 7, 9, 9]", Arrays.toString(ml.locateInFrom(2, 2)));
+ assertEquals("[10, 10, 12, 12, 14, 14]",
+ Arrays.toString(ml.locateInFrom(3, 3)));
+ assertEquals("[16, 18]", Arrays.toString(ml.locateInFrom(4, 4)));
+ }
+
+ /**
+ * Tests for method that locates ranges in the 'to' map for given range in the
+ * 'from' map.
+ */
+ @Test
+ public void testLocateInTo_noIntrons()
+ {
+ /*
+ * Simple mapping with no introns
+ */
+ int[] codons = new int[]
+ { 1, 12 };
+ int[] protein = new int[]
+ { 1, 4 };
+ MapList ml = new MapList(codons, protein, 3, 1);
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 3)));
+ assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6)));
+ assertEquals("[3, 3]", Arrays.toString(ml.locateInTo(7, 9)));
+ assertEquals("[4, 4]", Arrays.toString(ml.locateInTo(10, 12)));
+ assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 6)));
+ assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(1, 9)));
+ assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(1, 12)));
+ assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6)));
+ assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(4, 12)));
+
+ /*
+ * A part codon is treated as if a whole one.
+ */
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 1)));
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 2)));
+ assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 4)));
+ assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(2, 8)));
+ assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(3, 11)));
+ assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(5, 11)));
+
+ assertNull(ml.locateInTo(0, 0));
+ assertNull(ml.locateInTo(1, 13));
+ assertNull(ml.locateInTo(-1, 1));
+ }
+
+ /**
+ * Tests for method that locates ranges in the 'to' map for given range in the
+ * 'from' map.
+ */
+ @Test
+ public void testLocateInTo_withIntrons()
+ {
+ /*
+ * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e.
+ * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18
+ */
+ int[] codons =
+ { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
+ /*
+ * Mapped proteins at positions 1, 3, 4, 6 in the sequence
+ */
+ int[] protein =
+ { 1, 1, 3, 4, 6, 6 };
+ MapList ml = new MapList(codons, protein, 3, 1);
+
+ /*
+ * Can't map from an unmapped position
+ */
+ assertNull(ml.locateInTo(1, 2));
+ assertNull(ml.locateInTo(2, 4));
+ assertNull(ml.locateInTo(4, 4));
+
+ /*
+ * Valid range or subrange of codon1 maps to protein1.
+ */
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 2)));
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 3)));
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 5)));
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 3)));
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 5)));
+
+ // codon position 6 starts the next protein:
+ assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.locateInTo(3, 6)));
+
+ // codon positions 7 to 17 (part) cover proteins 2/3/4 at positions 3/4/6
+ assertEquals("[3, 4, 6, 6]", Arrays.toString(ml.locateInTo(7, 17)));
+
+ }
+
+ /**
+ * Test equals method.
+ */
+ @Test
+ public void testEquals()
+ {
+ int[] codons = new int[]
+ { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
+ int[] protein = new int[]
+ { 1, 4 };
+ MapList ml = new MapList(codons, protein, 3, 1);
+ MapList ml1 = new MapList(codons, protein, 3, 1); // same values
+ MapList ml2 = new MapList(codons, protein, 2, 1); // fromRatio differs
+ MapList ml3 = new MapList(codons, protein, 3, 2); // toRatio differs
+ codons[2] = 4;
+ MapList ml6 = new MapList(codons, protein, 3, 1); // fromShifts differ
+ protein[1] = 3;
+ MapList ml7 = new MapList(codons, protein, 3, 1); // toShifts differ
+
+ assertTrue(ml.equals(ml));
+ assertTrue(ml.equals(ml1));
+ assertTrue(ml1.equals(ml));
+
+ assertFalse(ml.equals(null));
+ assertFalse(ml.equals("hello"));
+ assertFalse(ml.equals(ml2));
+ assertFalse(ml.equals(ml3));
+ assertFalse(ml.equals(ml6));
+ assertFalse(ml.equals(ml7));
+ assertFalse(ml6.equals(ml7));
+
+ try
+ {
+ MapList ml4 = new MapList(codons, null, 3, 1); // toShifts null
+ assertFalse(ml.equals(ml4));
+ } catch (NullPointerException e)
+ {
+ // actually thrown by constructor before equals can be called
+ }
+ try
+ {
+ MapList ml5 = new MapList(null, protein, 3, 1); // fromShifts null
+ assertFalse(ml.equals(ml5));
+ } catch (NullPointerException e)
+ {
+ // actually thrown by constructor before equals can be called
+ }
+ }
+
+ /**
+ * Test for the method that flattens a list of ranges into a single array.
+ */
+ @Test
+ public void testGetRanges()
+ {
+ List<int[]> ranges = new ArrayList<int[]>();
+ ranges.add(new int[]
+ { 2, 3 });
+ ranges.add(new int[]
+ { 5, 6 });
+ assertEquals("[2, 3, 5, 6]", Arrays.toString(MapList.getRanges(ranges)));
+ }
+
+ /**
+ * Check state after construction
+ */
+ @Test
+ public void testConstructor()
+ {
+ int[] codons =
+ { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
+ int[] protein =
+ { 1, 1, 3, 4, 6, 6 };
+ MapList ml = new MapList(codons, protein, 3, 1);
+ assertEquals(3, ml.getFromRatio());
+ assertEquals(2, ml.getFromLowest());
+ assertEquals(18, ml.getFromHighest());
+ assertEquals(1, ml.getToLowest());
+ assertEquals(6, ml.getToHighest());
+ assertEquals("[2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18]",
+ Arrays.toString(ml.getFromRanges()));
+ assertEquals("[1, 1, 3, 4, 6, 6]", Arrays.toString(ml.getToRanges()));
+
+ /*
+ * Also copy constructor
+ */
+ MapList ml2 = new MapList(ml);
+ assertEquals(3, ml2.getFromRatio());
+ assertEquals(2, ml2.getFromLowest());
+ assertEquals(18, ml2.getFromHighest());
+ assertEquals(1, ml2.getToLowest());
+ assertEquals(6, ml2.getToHighest());
+ assertEquals("[2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18]",
+ Arrays.toString(ml2.getFromRanges()));
+ assertEquals("[1, 1, 3, 4, 6, 6]", Arrays.toString(ml2.getToRanges()));
+ }
+
+ /**
+ * Test the method that creates an inverse mapping
+ */
+ @Test
+ public void testGetInverse()
+ {
+ int[] codons =
+ { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
+ int[] protein =
+ { 1, 1, 3, 4, 6, 6 };
+
+ MapList ml = new MapList(codons, protein, 3, 1);
+ MapList ml2 = ml.getInverse();
+ assertEquals(ml.getFromRatio(), ml2.getToRatio());
+ assertEquals(ml.getFromRatio(), ml2.getToRatio());
+ assertEquals(ml.getToHighest(), ml2.getFromHighest());
+ assertEquals(ml.getFromHighest(), ml2.getToHighest());
+ assertEquals(Arrays.toString(ml.getFromRanges()),
+ Arrays.toString(ml2.getToRanges()));
+ assertEquals(Arrays.toString(ml.getToRanges()),
+ Arrays.toString(ml2.getFromRanges()));
+ }
+}
--- /dev/null
+package jalview.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+public class ShiftListTest
+{
+
+ @Test
+ public void testParseMap()
+ {
+ assertNull(ShiftList.parseMap(null));
+ assertNull(ShiftList.parseMap(new int[]
+ {}));
+
+ /*
+ * Gap map showing residues in aligned positions 2,3,6,8,9,10,12
+ */
+ int[] gm = new int[]
+ { 2, 3, 6, 8, 9, 10, 12 };
+ List<int[]> shifts = ShiftList.parseMap(gm).getShifts();
+ assertEquals(4, shifts.size());
+
+ // TODO are these results (which pass) correct??
+ assertEquals("[0, 2]", Arrays.toString(shifts.get(0)));
+ assertEquals("[4, 2]", Arrays.toString(shifts.get(1)));
+ assertEquals("[7, 1]", Arrays.toString(shifts.get(2)));
+ assertEquals("[11, 1]", Arrays.toString(shifts.get(3)));
+ }
+}
--- /dev/null
+package jalview.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class StringUtilsTest
+{
+
+ @Test
+ public void testInsertCharAt()
+ {
+ char[] c1 = "ABC".toCharArray();
+ char[] expected = new char[]
+ { 'A', 'B', 'C', 'w', 'w' };
+ assertTrue(Arrays.equals(expected,
+ StringUtils.insertCharAt(c1, 3, 2, 'w')));
+ expected = new char[]
+ { 'A', 'B', 'C', 'w', 'w' };
+ assertTrue(Arrays.equals(expected,
+ StringUtils.insertCharAt(c1, 4, 2, 'w')));
+ assertTrue(Arrays.equals(expected,
+ StringUtils.insertCharAt(c1, 5, 2, 'w')));
+ assertTrue(Arrays.equals(expected,
+ StringUtils.insertCharAt(c1, 6, 2, 'w')));
+ assertTrue(Arrays.equals(expected,
+ StringUtils.insertCharAt(c1, 7, 2, 'w')));
+ }
+
+ @Test
+ public void testDeleteChars()
+ {
+ char[] c1 = "ABC".toCharArray();
+
+ // delete second position
+ assertTrue(Arrays.equals(new char[]
+ { 'A', 'C' }, StringUtils.deleteChars(c1, 1, 2)));
+
+ // delete positions 1 and 2
+ assertTrue(Arrays.equals(new char[]
+ { 'C' }, StringUtils.deleteChars(c1, 0, 2)));
+
+ // delete positions 1-3
+ assertTrue(Arrays.equals(new char[]
+ {}, StringUtils.deleteChars(c1, 0, 3)));
+
+ // delete position 3
+ assertTrue(Arrays.equals(new char[]
+ { 'A', 'B' }, StringUtils.deleteChars(c1, 2, 3)));
+
+ // out of range deletion is ignore
+ assertTrue(Arrays.equals(c1, StringUtils.deleteChars(c1, 3, 4)));
+ }
+
+ @Test
+ public void testGetLastToken()
+ {
+ assertNull(StringUtils.getLastToken(null, null));
+ assertNull(StringUtils.getLastToken(null, "/"));
+ assertEquals("a", StringUtils.getLastToken("a", null));
+
+ assertEquals("abc", StringUtils.getLastToken("abc", "/"));
+ assertEquals("c", StringUtils.getLastToken("abc", "b"));
+ assertEquals("file1.dat", StringUtils.getLastToken(
+ "file://localhost:8080/data/examples/file1.dat", "/"));
+ }
+}