label.load_features_annotations = Load Features/Annotations ...
label.export_features = Export Features ...
label.export_annotations = Export Annotations ...
-label.jalview_copy = Copy (Jalview Only)
-label.jalview_cut = Cut (Jalview Only)
label.to_upper_case = To Upper Case
label.to_lower_case = To Lower Case
label.toggle_case = Toggle Case
label.load_tree_for_sequence_set = Load a tree for this sequence set
label.export_image = Export Image
label.vamsas_store = VAMSAS store
-label.translate_cDNA = Translate cDNA
+label.translate_cDNA = Translate as 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.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.linked_view_title = Linked cDNA and protein view
label.align = Align
label.extract_scores = Extract Scores
label.get_cross_refs = Get Cross References
final AlignmentI proteinAlignment,
final AlignmentI cdnaAlignment)
{
+ if (proteinAlignment == null || cdnaAlignment == null)
+ {
+ return MappingResult.NotMapped;
+ }
+
boolean mappingPossible = false;
boolean mappingPerformed = false;
public static MapList mapProteinToCdna(SequenceI proteinSeq,
SequenceI cdnaSeq)
{
- String aaSeqString = proteinSeq.getDatasetSequence()
- .getSequenceAsString();
- String cdnaSeqString = cdnaSeq.getDatasetSequence()
- .getSequenceAsString();
+ /*
+ * Here we handle either dataset sequence set (desktop) or absent (applet)
+ */
+ final SequenceI proteinDataset = proteinSeq.getDatasetSequence();
+ String aaSeqString = proteinDataset != null ? proteinDataset
+ .getSequenceAsString() : proteinSeq.getSequenceAsString();
+ final SequenceI cdnaDataset = cdnaSeq.getDatasetSequence();
+ String cdnaSeqString = cdnaDataset != null ? cdnaDataset
+ .getSequenceAsString() : cdnaSeq.getSequenceAsString();
if (aaSeqString == null || cdnaSeqString == null)
{
return null;
Menu editMenu = new Menu(MessageManager.getString("action.edit"));
- MenuItem copy = new MenuItem(
- MessageManager.getString("label.jalview_copy"));
+ MenuItem copy = new MenuItem(MessageManager.getString("action.copy"));
- MenuItem cut = new MenuItem(MessageManager.getString("label.jalview_cut"));
+ MenuItem cut = new MenuItem(MessageManager.getString("action.cut"));
MenuItem toUpper = new MenuItem(
MessageManager.getString("label.to_upper_case"));
import java.net.URL;
import java.net.URLEncoder;
import java.util.Arrays;
+import java.util.Deque;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
void updateEditMenuBar()
{
- if (viewport.historyList.size() > 0)
+ if (viewport.getHistoryList().size() > 0)
{
undoMenuItem.setEnabled(true);
- CommandI command = (CommandI) viewport.historyList.peek();
+ CommandI command = viewport.getHistoryList().peek();
undoMenuItem.setLabel(MessageManager.formatMessage(
- "label.undo_command", new String[]
+ "label.undo_command", new Object[]
{ command.getDescription() }));
}
else
undoMenuItem.setLabel(MessageManager.getString("action.undo"));
}
- if (viewport.redoList.size() > 0)
+ if (viewport.getRedoList().size() > 0)
{
redoMenuItem.setEnabled(true);
- CommandI command = (CommandI) viewport.redoList.peek();
+ CommandI command = viewport.getRedoList().peek();
redoMenuItem.setLabel(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.removeAllElements();
+ viewport.addToHistoryList(command);
+ viewport.clearRedoList();
updateEditMenuBar();
viewport.updateHiddenColumns();
}
*/
protected void undoMenuItem_actionPerformed()
{
- if (viewport.historyList.size() < 1)
+ if (viewport.getHistoryList().isEmpty())
{
return;
}
- CommandI command = (CommandI) viewport.historyList.pop();
- viewport.redoList.push(command);
+ CommandI command = viewport.getHistoryList().pop();
+ viewport.addToRedoList(command);
command.undoCommand(null);
AlignViewport originalSource = getOriginatingSource(command);
*/
protected void redoMenuItem_actionPerformed()
{
- if (viewport.redoList.size() < 1)
+ if (viewport.getRedoList().isEmpty())
{
return;
}
- CommandI command = (CommandI) viewport.redoList.pop();
- viewport.historyList.push(command);
+ CommandI command = viewport.getRedoList().pop();
+ viewport.addToHistoryList(command);
command.doCommand(null);
AlignViewport originalSource = getOriginatingSource(command);
}
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());
}
newaf.setTitle(title.toString());
- newaf.viewport.historyList = viewport.historyList;
- newaf.viewport.redoList = viewport.redoList;
+ newaf.viewport.setHistoryList(viewport.getHistoryList());
+ newaf.viewport.setRedoList(viewport.getRedoList());
return newaf;
}
// view cannot be closed if its actually on the page
fileMenu.remove(closeMenuItem);
fileMenu.remove(3); // Remove Separator
- embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar,
- FONT_ARIAL_PLAIN_11, false, false); // use our own fonts.
+ // construct embedded menu, using default font
+ embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, false, false);
// and actually add the components to the applet area
theApplet.setLayout(new BorderLayout());
theApplet.add(embeddedMenu, BorderLayout.NORTH);
import jalview.analysis.NJTree;
import jalview.api.AlignViewportI;
import jalview.bin.JalviewLite;
+import jalview.commands.CommandI;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.Sequence;
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.viewmodel.AlignmentViewport;
import java.awt.Font;
-import java.util.Stack;
public class AlignViewport extends AlignmentViewport implements
- AlignViewportI, SelectionSource, VamsasSource
+ AlignViewportI, SelectionSource, VamsasSource, CommandListener
{
int startRes;
boolean MAC = false;
- Stack historyList = new Stack();
-
- Stack redoList = new Stack();
-
private AnnotationColumnChooser annotationColumnSelectionState;
public void finalize()
public void sendSelection()
{
- jalview.structure.StructureSelectionManager
- .getStructureSelectionManager(applet).sendSelection(
+ getStructureSelectionManager().sendSelection(
new SequenceGroup(getSelectionGroup()),
new ColumnSelection(getColumnSelection()), this);
}
/**
+ * Returns an instance of the StructureSelectionManager scoped to this applet
+ * instance.
+ *
+ * @return
+ */
+ @Override
+ public StructureSelectionManager getStructureSelectionManager()
+ {
+ return jalview.structure.StructureSelectionManager
+ .getStructureSelectionManager(applet);
+ }
+
+ /**
* synthesize a column selection if none exists so it covers the given
* selection group. if wholewidth is false, no column selection is made if the
* selection group covers the whole alignment width.
this.annotationColumnSelectionState = annotationColumnSelectionState;
}
+ @Override
+ public void mirrorCommand(CommandI command, boolean undo,
+ StructureSelectionManager ssm, VamsasSource source)
+ {
+ // TODO refactor so this can be pulled up to superclass or controller
+ /*
+ * 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)
+ {
+ mappedCommand.doCommand(null);
+ firePropertyChange("alignment", null, getAlignment().getSequences());
+
+ // ap.scalePanelHolder.repaint();
+ // ap.repaint();
+ }
+ }
+
+ @Override
+ public VamsasSource getVamsasSource()
+ {
+ return this;
+ }
+
}
*/
package jalview.appletgui;
-import jalview.util.MessageManager;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.PopupMenu;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
-import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Map;
/**
* This class implements a pattern for embedding toolbars as a panel with popups
protected static final Font FONT_ARIAL_PLAIN_11 = new Font(
"Arial", Font.PLAIN, 11);
+ public static final Font DEFAULT_MENU_FONT = FONT_ARIAL_PLAIN_11;
+
/**
* map from labels to popup menus for the embedded menubar
*/
- protected Hashtable embeddedPopup;
+ protected Map<Label, PopupMenu> embeddedPopup = new HashMap<Label, PopupMenu>();
/**
* the embedded menu is built on this and should be added to the frame at the
// DEBUG Hint: can test embedded menus by inserting true here.
if (new jalview.util.Platform().isAMac())
{
- // Build the embedded menu panel
- embeddedMenu = makeEmbeddedPopupMenu(topMenuBar, FONT_ARIAL_PLAIN_11,
- true, false); // try to pickup system font.
+ // Build the embedded menu panel, allowing override with system font
+ embeddedMenu = makeEmbeddedPopupMenu(topMenuBar, true, false);
setMenuBar(null);
// add the components to the Panel area.
add(embeddedMenu, BorderLayout.NORTH);
* menuBar from the Frame if it is already attached.
*
* @param menuBar
- * @param font
* @param overrideFonts
* @param append
* true means existing menu will be emptied before adding new
* elements
* @return
*/
- protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, Font font,
+ protected Panel makeEmbeddedPopupMenu(MenuBar menuBar,
boolean overrideFonts, boolean append)
{
if (!append)
{
- if (embeddedPopup != null)
- {
- embeddedPopup.clear(); // TODO: check if j1.1
- }
+ embeddedPopup.clear(); // TODO: check if j1.1
if (embeddedMenu != null)
{
embeddedMenu.removeAll();
}
}
- if (embeddedPopup == null)
- {
- embeddedPopup = new Hashtable();
- }
-
- embeddedMenu = makeEmbeddedPopupMenu(menuBar, font,
- overrideFonts, embeddedPopup, new Panel(), this);
+ embeddedMenu = makeEmbeddedPopupMenu(menuBar, DEFAULT_MENU_FONT,
+ overrideFonts, new Panel(), this);
return embeddedMenu;
}
* must be non-null
* @param font
* @param overrideFonts
- * @param embeddedPopup
- * must be non-null
* @param embeddedMenu
* if null, a new panel will be created and returned
* @param clickHandler
*/
protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, Font font,
boolean overrideFonts,
- Hashtable embeddedPopup, Panel embeddedMenu,
+ Panel embeddedMenu,
MouseListener clickHandler)
{
- if (embeddedPopup == null)
- {
- throw new Error(MessageManager.getString("error.implementation_error_embeddedpopup_not_null"));
- }
if (overrideFonts)
{
Font mbf = menuBar.getFont();
*/
PopupMenu getPopupMenu(Label source)
{
- return (PopupMenu) embeddedPopup.get(source);
+ return embeddedPopup.get(source);
}
public void mouseClicked(MouseEvent evt)
{
if (embeddedPopup != null)
{
- Enumeration e = embeddedPopup.keys();
- while (e.hasMoreElements())
+ for (Label lb : embeddedPopup.keySet())
{
- Label lb = (Label) e.nextElement();
lb.removeMouseListener(this);
}
embeddedPopup.clear();
*/
package jalview.appletgui;
+import jalview.api.ViewStyleI;
import jalview.util.MessageManager;
-import java.awt.*;
-import java.awt.event.*;
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Choice;
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
public class FontChooser extends Panel implements ActionListener,
ItemListener
Font oldFont;
+ int oldCharWidth = 0;
+
boolean init = true;
Frame frame;
this.ap = ap;
oldFont = ap.av.getFont();
+ oldCharWidth = ap.av.getViewStyle().getCharWidth();
init();
}
if (ap != null)
{
ap.av.setFont(oldFont);
+ ViewStyleI style = ap.av.getViewStyle();
+ if (style.getCharWidth() != oldCharWidth)
+ {
+ style.setCharWidth(oldCharWidth);
+ ap.av.setViewStyle(style);
+ }
ap.paintAlignment(true);
}
else if (tp != null)
CommandI command = (CommandI) historyList.pop();
command.undoCommand(null);
- if (ap.av.historyList.contains(command))
+ if (ap.av.getHistoryList().contains(command))
{
- ap.av.historyList.removeElement(command);
+ ap.av.getHistoryList().remove(command);
ap.alignFrame.updateEditMenuBar();
ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
}
*/
package jalview.appletgui;
+import jalview.api.AlignViewportI;
import jalview.commands.EditCommand;
import jalview.commands.EditCommand.Action;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.schemes.ResidueProperties;
+import jalview.structure.SelectionListener;
import jalview.structure.SelectionSource;
import jalview.structure.SequenceListener;
import jalview.structure.StructureSelectionManager;
import jalview.structure.VamsasSource;
+import jalview.util.MappingUtils;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
import java.util.Vector;
public class SeqPanel extends Panel implements MouseMotionListener,
- MouseListener, SequenceListener
+ MouseListener, SequenceListener, SelectionListener
{
public SeqCanvas seqCanvas;
seqCanvas.addMouseListener(this);
ssm = StructureSelectionManager.getStructureSelectionManager(av.applet);
ssm.addStructureViewerListener(this);
+ ssm.addSelectionListener(this);
seqCanvas.repaint();
}
{
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
ap.scrollTo(column, column, ap.av.startSeq, true, true);
}
+ /**
+ * 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);
+
+ firePropertyChange("alignment", null, av.getAlignment().getSequences());
+ // PaintRefresher.Refresh(this, av.getSequenceSetId());
+
+ return true;
+ }
+
}
package jalview.appletgui;
+import jalview.analysis.AlignmentUtils;
+import jalview.analysis.AlignmentUtils.MappingResult;
+import jalview.api.ViewStyleI;
import jalview.bin.JalviewLite;
+import jalview.datamodel.AlignmentI;
+import jalview.structure.StructureSelectionManager;
import java.awt.BorderLayout;
import java.awt.GridLayout;
addAlignFrameComponents(topFrame, topPanel);
addAlignFrameComponents(bottomFrame, bottomPanel);
+
+ /*
+ * Try to make and add dna/protein sequence mappings
+ */
+ final AlignViewport topViewport = topFrame.viewport;
+ final AlignViewport bottomViewport = bottomFrame.viewport;
+ final AlignmentI topAlignment = topViewport.getAlignment();
+ final AlignmentI bottomAlignment = bottomViewport.getAlignment();
+ // topAlignment.setDataset(null);
+ // bottomAlignment.setDataset(null);
+ AlignViewport cdna = topAlignment.isNucleotide() ? topViewport
+ : (bottomAlignment.isNucleotide() ? bottomViewport : null);
+ AlignViewport protein = !topAlignment.isNucleotide() ? topViewport
+ : (!bottomAlignment.isNucleotide() ? bottomViewport : null);
+ MappingResult mapped = AlignmentUtils.mapProteinToCdna(
+ protein.getAlignment(), cdna.getAlignment());
+ if (mapped != MappingResult.NotMapped)
+ {
+ final StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(topViewport.applet);
+ ssm.addMappings(protein.getAlignment().getCodonFrames());
+ topViewport.setCodingComplement(bottomViewport);
+ ssm.addCommandListener(cdna);
+ ssm.addCommandListener(protein);
+ }
+
+ /*
+ * Expand protein to 3 times character width of dna
+ */
+ if (protein != null && cdna != null)
+ {
+ ViewStyleI vs = protein.getViewStyle();
+ vs.setCharWidth(3 * vs.getCharWidth());
+ protein.setViewStyle(vs);
+ }
+
}
/**
private void addAlignFrameComponents(AlignFrame af, Panel panel)
{
panel.setLayout(new BorderLayout());
- Panel menuPanel = makeEmbeddedPopupMenu(af.getMenuBar(), FONT_ARIAL_PLAIN_11, true, false);
+ Panel menuPanel = af
+ .makeEmbeddedPopupMenu(af.getMenuBar(), true, false);
panel.add(menuPanel, BorderLayout.NORTH);
panel.add(af.statusBar, BorderLayout.SOUTH);
panel.add(af.alignPanel, BorderLayout.CENTER);
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.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
import jalview.util.Format;
+import jalview.util.MappingUtils;
import java.awt.Color;
import java.awt.Dimension;
av.setSelectionGroup(null);
av.getAlignment().deleteAllGroups();
av.clearSequenceColours();
+ final AlignViewportI codingComplement = av.getCodingComplement();
+ if (codingComplement != null)
+ {
+ codingComplement.setSelectionGroup(null);
+ codingComplement.getAlignment().deleteAllGroups();
+ codingComplement.clearSequenceColours();
+ }
colourGroups();
av.getAlignment().addGroup(sg);
+ // TODO this is duplicated with gui TreeCanvas - refactor
+ 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())
+ {
+ // TODO why does gui require col.brighter() here??
+ codingComplement.setSequenceColour(seq, col);
+ }
+ }
+ }
+
}
ap.updateAnnotation();
-
+ if (av.getCodingComplement() != null)
+ {
+ ((AlignViewport) av.getCodingComplement()).firePropertyChange(
+ "alignment", null, ap.av.getAlignment().getSequences());
+ }
}
public void setShowDistances(boolean state)
if ((al != null) && (al.getHeight() > 0))
{
dbgMsg("Successfully loaded file.");
+ al.setDataset(null);
AlignFrame newAlignFrame = new AlignFrame(al, applet,
resolvedFile, embedded, false);
newAlignFrame.setTitle(resolvedFile);
return false;
}
+ /**
+ * Remove all sequences from the group (leaving other properties unchanged).
+ */
public void clear()
{
sequences.clear();
/**
* Construct and display a new frame containing the translation of this
- * frame's cDNA sequences to their aligned protein (amino acid) equivalents.
+ * frame's DNA sequences to their aligned protein (amino acid) equivalents.
*/
@Override
public void showTranslation_actionPerformed(ActionEvent e)
{
AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
af.setFileFormat(this.currentFileFormat);
- Desktop.addInternalFrame(af, MessageManager.formatMessage(
+ final String newTitle = MessageManager.formatMessage(
"label.translation_of_params", new Object[]
- { this.getTitle() }), DEFAULT_WIDTH, DEFAULT_HEIGHT);
- // enable next line for linked editing
+ { this.getTitle() });
+ af.setTitle(newTitle);
+ viewport.openSplitFrame(af, viewport.getAlignment());
+ // Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ // // enable next line for linked editing
// viewport.getStructureSelectionManager().addCommandListener(viewport);
}
}
import java.awt.Dimension;
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.Set;
import java.util.Vector;
* @version $Revision: 1.141 $
*/
public class AlignViewport extends AlignmentViewport implements
- SelectionSource, VamsasSource, AlignViewportI, CommandListener
+ SelectionSource, AlignViewportI, CommandListener
{
int startRes;
private boolean gatherViewsHere = false;
- private Deque<CommandI> historyList = new ArrayDeque<CommandI>();
-
- private Deque<CommandI> redoList = new ArrayDeque<CommandI>();
-
private AnnotationColumnChooser annotationColumnSelectionState;
/**
* Creates a new AlignViewport object.
}
}
+ /**
+ * Returns the (Desktop) instance of the StructureSelectionManager
+ */
+ @Override
public StructureSelectionManager getStructureSelectionManager()
{
return StructureSelectionManager
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.
+ * 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)
}
}
- @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
* added to the protein alignment.
*/
MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, cdna);
- final StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
if (mapped != MappingResult.Mapped)
{
/*
if (openSplitPane)
{
- // TODO: move this kind of constructor stuff to a factory/controller
- // method ?
- /*
- * 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 = proteinFrame.getTitle().substring(
- proteinFrame.getTitle().lastIndexOf(sep) + 1);
- String dnaShortName = cdnaFrame.getTitle().substring(
- cdnaFrame.getTitle().lastIndexOf(sep) + 1);
- String linkedTitle = MessageManager.formatMessage(
- "label.linked_view_title", dnaShortName, proteinShortName);
- JInternalFrame splitFrame = new SplitFrame(cdnaFrame, proteinFrame);
- Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1);
-
- /*
- * 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());
+ protein = openSplitFrame(newAlignFrame, thisAlignment);
}
/*
* Register the mappings (held on the protein alignment) with the
* StructureSelectionManager (for mouseover linking).
*/
+ final StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(Desktop.instance);
ssm.addMappings(protein.getCodonFrames());
return true;
}
+ /**
+ * Helper method to open a new SplitFrame holding linked dna and protein
+ * alignments.
+ *
+ * @param newAlignFrame
+ * containing a new alignment to be shown
+ * @param existingAlignment
+ * an existing alignment to be copied for display in the split frame
+ * @return the protein alignment in the split frame
+ */
+ protected AlignmentI openSplitFrame(AlignFrame newAlignFrame,
+ AlignmentI existingAlignment)
+ {
+ // TODO: move this to a factory/controller method ?
+ /*
+ * Open in split pane. DNA sequence above, protein below.
+ */
+ AlignFrame copyMe = new AlignFrame(existingAlignment,
+ AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+ copyMe.setTitle(getAlignPanel().alignFrame.getTitle());
+
+ AlignmentI al = newAlignFrame.viewport.getAlignment();
+ final AlignFrame proteinFrame = al.isNucleotide() ? copyMe
+ : newAlignFrame;
+ final AlignFrame cdnaFrame = al.isNucleotide() ? newAlignFrame
+ : copyMe;
+ AlignmentI protein = proteinFrame.viewport.getAlignment();
+
+ cdnaFrame.setVisible(true);
+ proteinFrame.setVisible(true);
+ String linkedTitle = MessageManager
+ .getString("label.linked_view_title");
+ JInternalFrame splitFrame = new SplitFrame(cdnaFrame, proteinFrame);
+ Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1);
+
+ /*
+ * Set the frames to listen for each other's edit and sort commands.
+ */
+ final StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(Desktop.instance);
+ 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());
+ return protein;
+ }
+
public AnnotationColumnChooser getAnnotationColumnSelectionState()
{
return annotationColumnSelectionState;
for (res = 0; res < alwidth; res++)
{
text = new StringBuffer();
- Object obj = null;
+ String triplet = null;
if (av.getAlignment().isNucleotide())
{
- obj = ResidueProperties.nucleotideName.get(seq.getCharAt(res)
+ triplet = ResidueProperties.nucleotideName.get(seq
+ .getCharAt(res)
+ "");
}
else
{
- obj = ResidueProperties.aa2Triplet.get(seq.getCharAt(res)
+ triplet = ResidueProperties.aa2Triplet.get(seq.getCharAt(res)
+ "");
}
- if (obj == null)
+ if (triplet == null)
{
continue;
}
- String triplet = obj.toString();
int alIndex = seq.findPosition(res);
gSize = groups.length;
for (g = 0; g < gSize; g++)
import jalview.datamodel.SequenceI;
import jalview.jbgui.GFinder;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import java.awt.event.ActionEvent;
import java.util.Vector;
private static final int WIDTH = 340;
- AlignViewport av;
+ AlignmentViewport av;
AlignmentPanel ap;
* @param viewport
* @param alignPanel
*/
- public Finder(AlignViewport viewport, AlignmentPanel alignPanel)
+ public Finder(AlignmentViewport viewport, AlignmentPanel alignPanel)
{
av = viewport;
ap = alignPanel;
if (view.getSequenceSetId() != null)
{
- jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
+ AlignmentViewport av = (AlignmentViewport) viewportsAdded
.get(uniqueSeqSetId);
af.viewport.setSequenceSetId(uniqueSeqSetId);
package jalview.gui;
+import jalview.api.ViewStyleI;
+import jalview.datamodel.AlignmentI;
import jalview.jbgui.GAlignFrame;
import jalview.jbgui.GSplitFrame;
import jalview.structure.StructureSelectionManager;
+import jalview.viewmodel.AlignmentViewport;
import java.awt.Component;
import java.awt.Toolkit;
{
setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 20);
+ setCharacterWidth();
+
addCloseFrameListener();
addKeyListener();
}
/**
+ * Set the character width for protein to 3 times that for dna.
+ */
+ private void setCharacterWidth()
+ {
+ final AlignViewport topViewport = ((AlignFrame) getTopFrame()).viewport;
+ final AlignViewport bottomViewport = ((AlignFrame) getBottomFrame()).viewport;
+ final AlignmentI topAlignment = topViewport.getAlignment();
+ final AlignmentI bottomAlignment = bottomViewport.getAlignment();
+ AlignmentViewport cdna = topAlignment.isNucleotide() ? topViewport
+ : (bottomAlignment.isNucleotide() ? bottomViewport : null);
+ AlignmentViewport protein = !topAlignment.isNucleotide() ? topViewport
+ : (!bottomAlignment.isNucleotide() ? bottomViewport : null);
+ if (protein != null && cdna != null)
+ {
+ ViewStyleI vs = cdna.getViewStyle();
+ vs.setCharWidth(3 * vs.getCharWidth());
+ protein.setViewStyle(vs);
+ }
+ }
+
+ /**
* Add a listener to tidy up when the frame is closed.
*/
protected void addCloseFrameListener()
codingComplement.getAlignment().addGroup(mappedGroup);
for (SequenceI seq : mappedGroup.getSequences())
{
- codingComplement.setSequenceColour(seq,
- mappedGroup.getIdColour().brighter());
+ codingComplement.setSequenceColour(seq, col.brighter());
}
}
}
import jalview.jbgui.GTreePanel;
import jalview.schemes.ResidueProperties;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import java.awt.Font;
import java.awt.Graphics;
return treeCanvas.av.getAlignment();
}
- public AlignViewport getViewPort()
+ public AlignmentViewport getViewPort()
{
return treeCanvas.av;
}
public CommandI sortAlignmentIn(AlignmentPanel ap)
{
- AlignViewport av = ap.av;
+ AlignmentViewport av = ap.av;
SequenceI[] oldOrder = av.getAlignment().getSequencesArray();
AlignmentSorter.sortByTree(av.getAlignment(), tree);
CommandI undo;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.exceptions.NoFileSelectedException;
-import jalview.gui.AlignViewport;
import jalview.gui.AlignmentPanel;
import jalview.gui.FeatureRenderer;
import jalview.json.binding.v1.BioJsAlignmentPojo;
import jalview.json.binding.v1.BioJsSeqPojo;
import jalview.schemes.ColourSchemeProperty;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import java.awt.Color;
import java.io.BufferedReader;
public class BioJsHTMLOutput
{
- private AlignViewport av;
+ private AlignmentViewport av;
private jalview.api.FeatureRenderer fr;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.gui.AlignViewport;
import java.util.ArrayList;
import java.util.HashMap;
}
/*
- * Have to align the sequences before constructing the OrderCommand - which
- * then realigns them?!?
+ * Have to sort the sequences before constructing the OrderCommand - which
+ * then resorts them?!?
*/
final SequenceI[] mappedOrderArray = mappedOrder
.toArray(new SequenceI[mappedOrder.size()]);
* @return
*/
public static ColumnSelection mapColumnSelection(ColumnSelection colsel,
- AlignViewportI mapFrom, AlignViewport mapTo)
+ AlignViewportI mapFrom, AlignViewportI mapTo)
{
boolean targetIsNucleotide = mapTo.isNucleotide();
AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo;
ColumnSelection mappedColumns = new ColumnSelection();
char fromGapChar = mapFrom.getAlignment().getGapCharacter();
+ // FIXME allow for hidden columns
+
+ /*
+ * For each mapped column, find the range of columns that residues in that
+ * column map to.
+ */
for (Object obj : colsel.getSelected())
{
int col = ((Integer) obj).intValue();
// System.out.println(fromSeq.getName() + " mapped to cols "
// + mappedStartCol + ":" + mappedEndCol);
break;
- // TODO remove break if we ever want to map one to many sequences
+ // note: remove break if we ever want to map one to many sequences
}
}
}
}
/*
- * Add mapped columns to mapped selection (converting base 1 to base 0)
+ * Add the range of mapped columns to the mapped selection (converting
+ * base 1 to base 0). Note that this may include intron-only regions which
+ * lie between the start and end ranges of the selection.
*/
for (int i = mappedToMin; i <= mappedToMax; i++)
{
import jalview.api.AlignmentViewPanel;
import jalview.api.FeaturesDisplayedI;
import jalview.api.ViewStyleI;
+import jalview.commands.CommandI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.PIDColourScheme;
import jalview.schemes.ResidueProperties;
+import jalview.structure.CommandListener;
+import jalview.structure.StructureSelectionManager;
+import jalview.structure.VamsasSource;
import jalview.viewmodel.styles.ViewStyle;
import jalview.workers.AlignCalcManager;
import jalview.workers.ConsensusThread;
import jalview.workers.StrucConsensusThread;
import java.awt.Color;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.BitSet;
+import java.util.Deque;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
*
*/
public abstract class AlignmentViewport implements AlignViewportI,
- ViewStyleI
+ ViewStyleI, CommandListener, VamsasSource
{
protected ViewStyleI viewStyle = new ViewStyle();
*/
AlignViewportI codingComplement = null;
+ FeaturesDisplayedI featuresDisplayed = null;
+
+ protected Deque<CommandI> historyList = new ArrayDeque<CommandI>();
+
+ protected Deque<CommandI> redoList = new ArrayDeque<CommandI>();
+
/**
* @param name
* @see jalview.api.ViewStyleI#setFontName(java.lang.String)
return getAlignment() == null ? false : getAlignment().isNucleotide();
}
- FeaturesDisplayedI featuresDisplayed = null;
-
@Override
public FeaturesDisplayedI getFeaturesDisplayed()
{
{
viewStyle.setShowNPFeats(shownpfeats);
}
+
+ public abstract StructureSelectionManager getStructureSelectionManager();
+
+ /**
+ * 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;
+ }
+
+ @Override
+ public VamsasSource getVamsasSource()
+ {
+ return this;
+ }
}
seq.createDatasetSequence();
assertEquals("[1, 4, 6, 7, 9, 12]", Arrays.toString(seq.gapMap()));
}
+
+ /**
+ * Test the method that gets sequence features, either from the sequence or
+ * its dataset.
+ */
+ @Test
+ public void testGetSequenceFeatures()
+ {
+ SequenceI seq = new Sequence("test", "GATCAT");
+ seq.createDatasetSequence();
+
+ assertNull(seq.getSequenceFeatures());
+
+ /*
+ * SequenceFeature on sequence
+ */
+ SequenceFeature sf = new SequenceFeature();
+ seq.addSequenceFeature(sf);
+ SequenceFeature[] sfs = seq.getSequenceFeatures();
+ assertEquals(1, sfs.length);
+ assertSame(sf, sfs[0]);
+
+ /*
+ * SequenceFeature on sequence and dataset sequence; returns that on
+ * sequence
+ */
+ SequenceFeature sf2 = new SequenceFeature();
+ seq.getDatasetSequence().addSequenceFeature(sf2);
+ sfs = seq.getSequenceFeatures();
+ assertEquals(1, sfs.length);
+ assertSame(sf, sfs[0]);
+
+ /*
+ * SequenceFeature on dataset sequence only
+ */
+ seq.setSequenceFeatures(null);
+ sfs = seq.getSequenceFeatures();
+ assertEquals(1, sfs.length);
+ assertSame(sf2, sfs[0]);
+
+ /*
+ * Corrupt case - no SequenceFeature, dataset's dataset is the original
+ * sequence. Test shows no infinite loop results.
+ */
+ seq.getDatasetSequence().setSequenceFeatures(null);
+ seq.getDatasetSequence().setDatasetSequence(seq); // loop!
+ assertNull(seq.getSequenceFeatures());
+ }
}
package jalview.ext.rbvi.chimera;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertTrue;
-import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
-import ext.edu.ucsf.rbvi.strucviz2.*;
+import ext.edu.ucsf.rbvi.strucviz2.ChimeraManager;
+import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel;
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
public class ChimeraConnect
{
@Test
public void test()
{
- StructureManager csm;
+ StructureManager csm;
ext.edu.ucsf.rbvi.strucviz2.ChimeraManager cm = new ChimeraManager(csm = new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true));
- assertTrue("Couldn't launch chimera",cm.launchChimera(csm.getChimeraPaths()));
+ assertTrue("Couldn't launch chimera",
+ cm.launchChimera(StructureManager.getChimeraPaths()));
int n=0;
while (n++<100)
{
import jalview.datamodel.Alignment;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import jalview.viewmodel.AlignmentViewport;
import java.awt.Component;
import java.util.List;
* and SeqCanvas, IdPanel, AlignmentPanel are all registered under the
* sequence set id of the viewport.
*/
- AlignViewport av = new AlignViewport(al);
+ AlignmentViewport av = new AlignViewport(al);
AlignFrame af = new AlignFrame(al, 4, 1);
AlignmentPanel ap1 = af.alignPanel;
AlignmentPanel[] panels = PaintRefresher.getAssociatedPanels(av
--- /dev/null
+package jalview.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import jalview.api.AlignViewportI;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.gui.AlignViewport;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.FormatAdapter;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import org.junit.Test;
+
+public class MappingUtilsTest
+{
+ private AlignViewportI dnaView;
+ private AlignViewportI proteinView;
+
+ /**
+ * Simple test of mapping with no intron involved.
+ */
+ @Test
+ public void testBuildSearchResults()
+ {
+ final Sequence seq1 = new Sequence("Seq1", "C-G-TA-GC");
+ seq1.createDatasetSequence();
+
+ final Sequence aseq1 = new Sequence("Seq1", "-P-R");
+ aseq1.createDatasetSequence();
+
+ /*
+ * Map dna bases 1-6 to protein residues 1-2
+ */
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ MapList map = new MapList(new int[]
+ { 1, 6 }, new int[]
+ { 1, 2 }, 3, 1);
+ acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map);
+ Set<AlignedCodonFrame> acfList = Collections.singleton(acf);
+
+ /*
+ * Check protein residue 1 maps to codon 1-3, 2 to codon 4-6
+ */
+ SearchResults sr = MappingUtils.buildSearchResults(aseq1, 1, acfList);
+ assertEquals(1, sr.getResults().size());
+ Match m = sr.getResults().get(0);
+ assertEquals(seq1.getDatasetSequence(), m.getSequence());
+ assertEquals(1, m.getStart());
+ assertEquals(3, m.getEnd());
+ sr = MappingUtils.buildSearchResults(aseq1, 2, acfList);
+ assertEquals(1, sr.getResults().size());
+ m = sr.getResults().get(0);
+ assertEquals(seq1.getDatasetSequence(), m.getSequence());
+ assertEquals(4, m.getStart());
+ assertEquals(6, m.getEnd());
+
+ /*
+ * Check inverse mappings, from codons 1-3, 4-6 to protein 1, 2
+ */
+ for (int i = 1; i < 7; i++)
+ {
+ sr = MappingUtils.buildSearchResults(seq1, i, acfList);
+ assertEquals(1, sr.getResults().size());
+ m = sr.getResults().get(0);
+ assertEquals(aseq1.getDatasetSequence(), m.getSequence());
+ int residue = i > 3 ? 2 : 1;
+ assertEquals(residue, m.getStart());
+ assertEquals(residue, m.getEnd());
+ }
+ }
+
+ /**
+ * Simple test of mapping with introns involved.
+ */
+ @Test
+ public void testBuildSearchResults_withIntro()
+ {
+ final Sequence seq1 = new Sequence("Seq1", "C-G-TAGA-GCAGCTT");
+ seq1.createDatasetSequence();
+
+ final Sequence aseq1 = new Sequence("Seq1", "-P-R");
+ aseq1.createDatasetSequence();
+
+ /*
+ * Map dna bases [2, 4, 5], [7, 9, 11] to protein residues 1 and 2
+ */
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ MapList map = new MapList(new int[]
+ { 2, 2, 4, 5, 7, 7, 9, 9, 11, 11 }, new int[]
+ { 1, 2 }, 3, 1);
+ acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map);
+ Set<AlignedCodonFrame> acfList = Collections.singleton(acf);
+
+ /*
+ * Check protein residue 1 maps to [2, 4, 5]
+ */
+ SearchResults sr = MappingUtils.buildSearchResults(aseq1, 1, acfList);
+ assertEquals(2, sr.getResults().size());
+ Match m = sr.getResults().get(0);
+ assertEquals(seq1.getDatasetSequence(), m.getSequence());
+ assertEquals(2, m.getStart());
+ assertEquals(2, m.getEnd());
+ m = sr.getResults().get(1);
+ assertEquals(seq1.getDatasetSequence(), m.getSequence());
+ assertEquals(4, m.getStart());
+ assertEquals(5, m.getEnd());
+
+ /*
+ * Check protein residue 2 maps to [7, 9, 11]
+ */
+ sr = MappingUtils.buildSearchResults(aseq1, 2, acfList);
+ assertEquals(3, sr.getResults().size());
+ m = sr.getResults().get(0);
+ assertEquals(seq1.getDatasetSequence(), m.getSequence());
+ assertEquals(7, m.getStart());
+ assertEquals(7, m.getEnd());
+ m = sr.getResults().get(1);
+ assertEquals(seq1.getDatasetSequence(), m.getSequence());
+ assertEquals(9, m.getStart());
+ assertEquals(9, m.getEnd());
+ m = sr.getResults().get(2);
+ assertEquals(seq1.getDatasetSequence(), m.getSequence());
+ assertEquals(11, m.getStart());
+ assertEquals(11, m.getEnd());
+
+ /*
+ * Check inverse mappings, from codons to protein
+ */
+ for (int i = 1; i < 14; i++)
+ {
+ sr = MappingUtils.buildSearchResults(seq1, i, acfList);
+ int residue = (i == 2 || i == 4 || i == 5) ? 1 : (i == 7 || i == 9
+ || i == 11 ? 2 : 0);
+ if (residue == 0)
+ {
+ assertEquals(0, sr.getResults().size());
+ continue;
+ }
+ assertEquals(1, sr.getResults().size());
+ m = sr.getResults().get(0);
+ assertEquals(aseq1.getDatasetSequence(), m.getSequence());
+ assertEquals(residue, m.getStart());
+ assertEquals(residue, m.getEnd());
+ }
+ }
+
+ /**
+ * Test mapping a sequence group.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testMapSequenceGroup() throws IOException
+ {
+ /*
+ * Set up dna and protein Seq1/2/3 with mappings (held on the protein
+ * viewport).
+ */
+ AlignmentI cdna = loadAlignment(">Seq1\nACG\n>Seq2\nTGA\n>Seq3\nTAC\n",
+ "FASTA");
+ cdna.setDataset(null);
+ AlignmentI protein = loadAlignment(">Seq1\nK\n>Seq2\nL\n>Seq3\nQ\n",
+ "FASTA");
+ protein.setDataset(null);
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ MapList map = new MapList(new int[]
+ { 1, 3 }, new int[]
+ { 1, 1 }, 3, 1);
+ for (int seq = 0; seq < 3; seq++)
+ {
+ acf.addMap(cdna.getSequenceAt(seq).getDatasetSequence(), protein
+ .getSequenceAt(seq).getDatasetSequence(), map);
+ }
+ Set<AlignedCodonFrame> acfList = Collections.singleton(acf);
+
+ AlignViewportI dnaView = new AlignViewport(cdna);
+ AlignViewportI proteinView = new AlignViewport(protein);
+ protein.setCodonFrames(acfList);
+
+ /*
+ * Select Seq1 and Seq3 in the protein
+ */
+ SequenceGroup sg = new SequenceGroup();
+ sg.setColourText(true);
+ sg.setIdColour(Color.GREEN);
+ sg.setOutlineColour(Color.LIGHT_GRAY);
+ sg.addSequence(protein.getSequenceAt(0), false);
+ sg.addSequence(protein.getSequenceAt(2), false);
+
+ /*
+ * Verify the mapped sequence group in dna
+ */
+ SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, proteinView, dnaView);
+ assertTrue(mappedGroup.getColourText());
+ assertSame(sg.getIdColour(), mappedGroup.getIdColour());
+ assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour());
+ assertEquals(2, mappedGroup.getSequences().size());
+ assertSame(cdna.getSequenceAt(0), mappedGroup.getSequences().get(0));
+ assertSame(cdna.getSequenceAt(2), mappedGroup.getSequences().get(1));
+
+ /*
+ * Verify mapping sequence group from dna to protein
+ */
+ sg.clear();
+ sg.addSequence(cdna.getSequenceAt(1), false);
+ sg.addSequence(cdna.getSequenceAt(0), false);
+ mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView);
+ assertTrue(mappedGroup.getColourText());
+ assertSame(sg.getIdColour(), mappedGroup.getIdColour());
+ assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour());
+ assertEquals(2, mappedGroup.getSequences().size());
+ assertSame(protein.getSequenceAt(1), mappedGroup.getSequences().get(0));
+ assertSame(protein.getSequenceAt(0), mappedGroup.getSequences().get(1));
+ }
+
+ /**
+ * 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 a column selection in protein to its dna equivalent
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testMapColumnSelection_proteinToDna() throws IOException
+ {
+ setupMappedAlignments();
+
+ ColumnSelection colsel = new ColumnSelection();
+
+ /*
+ * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3
+ * in dna respectively, overall 0-4
+ */
+ colsel.addElement(0);
+ ColumnSelection cs = MappingUtils.mapColumnSelection(colsel,
+ proteinView, dnaView);
+ assertEquals("[0, 1, 2, 3, 4]", cs.getSelected().toString());
+
+ /*
+ * Column 1 in protein picks up Seq1/K which maps to cols 0-3 in dna
+ */
+ colsel.clear();
+ colsel.addElement(1);
+ cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView);
+ assertEquals("[0, 1, 2, 3]", cs.getSelected().toString());
+
+ /*
+ * Column 2 in protein picks up gaps only - no mapping
+ */
+ colsel.clear();
+ colsel.addElement(2);
+ cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView);
+ assertEquals("[]", cs.getSelected().toString());
+
+ /*
+ * Column 3 in protein picks up Seq1/P, Seq2/Q, Seq3/S which map to columns
+ * 6-9, 6-10, 5-8 respectively, overall to 5-10
+ */
+ colsel.clear();
+ colsel.addElement(3);
+ cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView);
+ assertEquals("[5, 6, 7, 8, 9, 10]", cs.getSelected().toString());
+
+ /*
+ * Combine selection of columns 1 and 3 to get a discontiguous mapped
+ * selection
+ */
+ colsel.clear();
+ colsel.addElement(1);
+ colsel.addElement(3);
+ cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView);
+ assertEquals("[0, 1, 2, 3, 5, 6, 7, 8, 9, 10]", cs.getSelected()
+ .toString());
+ }
+
+ /**
+ * @throws IOException
+ */
+ protected void setupMappedAlignments() throws IOException
+ {
+ /*
+ * Set up dna and protein Seq1/2/3 with mappings (held on the protein
+ * viewport). Lower case for introns.
+ */
+ AlignmentI cdna = loadAlignment(">Seq1\nAC-GctGtC-T\n"
+ + ">Seq2\nTc-GA-G-T-Tc\n" + ">Seq3\nTtTT-AaCGg-\n",
+ "FASTA");
+ cdna.setDataset(null);
+ AlignmentI protein = loadAlignment(
+ ">Seq1\n-K-P\n>Seq2\nL--Q\n>Seq3\nG--S\n",
+ "FASTA");
+ protein.setDataset(null);
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ MapList map = new MapList(new int[]
+ { 1, 3, 6, 6, 8, 9 }, new int[]
+ { 1, 2 }, 3, 1);
+ acf.addMap(cdna.getSequenceAt(0).getDatasetSequence(), protein
+ .getSequenceAt(0).getDatasetSequence(), map);
+ map = new MapList(new int[]
+ { 1, 1, 3, 4, 5, 7 }, new int[]
+ { 1, 2 }, 3, 1);
+ acf.addMap(cdna.getSequenceAt(1).getDatasetSequence(), protein
+ .getSequenceAt(1).getDatasetSequence(), map);
+ map = new MapList(new int[]
+ { 1, 1, 3, 4, 5, 5, 7, 8 }, new int[]
+ { 1, 2 }, 3, 1);
+ acf.addMap(cdna.getSequenceAt(2).getDatasetSequence(), protein
+ .getSequenceAt(2).getDatasetSequence(), map);
+ Set<AlignedCodonFrame> acfList = Collections.singleton(acf);
+
+ dnaView = new AlignViewport(cdna);
+ proteinView = new AlignViewport(protein);
+ protein.setCodonFrames(acfList);
+ }
+
+ /**
+ * Test mapping a column selection including hidden columns
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testMapColumnSelection_hiddenColumns() throws IOException
+ {
+ setupMappedAlignments();
+
+ ColumnSelection colsel = new ColumnSelection();
+
+ /*
+ * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3
+ * in dna respectively, overall 0-4
+ */
+ colsel.addElement(0);
+ ColumnSelection cs = MappingUtils.mapColumnSelection(colsel,
+ proteinView, dnaView);
+ assertEquals("[0, 1, 2, 3, 4]", cs.getSelected().toString());
+
+ fail("write me");
+ }
+
+ /**
+ * Test mapping a column selection in dna to its protein equivalent
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testMapColumnSelection_dnaToProtein() throws IOException
+ {
+ setupMappedAlignments();
+
+ ColumnSelection colsel = new ColumnSelection();
+
+ /*
+ * Column 0 in dna picks up first bases which map to residue 1, columns 0-1
+ * in protein.
+ */
+ colsel.addElement(0);
+ ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, dnaView,
+ proteinView);
+ assertEquals("[0, 1]", cs.getSelected().toString());
+
+ /*
+ * Columns 3-5 in dna map to the first residues in protein Seq1, Seq2, and
+ * the first two in Seq3. Overall to columns 0, 1, 3 (col2 is all gaps).
+ */
+ colsel.addElement(3);
+ colsel.addElement(4);
+ colsel.addElement(5);
+ cs = MappingUtils.mapColumnSelection(colsel, dnaView, proteinView);
+ assertEquals("[0, 1, 3]", cs.getSelected().toString());
+ }
+}