From: jprocter Date: Tue, 22 May 2012 11:20:02 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/Tcoffee_JAL-1065' into develop X-Git-Tag: Jalview_2_9~524 X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=a79f9e113c51c032070c670e45ce3eb464691166 Merge remote-tracking branch 'origin/Tcoffee_JAL-1065' into develop conflicts due to refactoring according to JAL-972, JAL-968, JAL-968 Conflicts: .classpath examples/appletParameters.html src/jalview/appletgui/AlignFrame.java src/jalview/appletgui/AlignViewport.java src/jalview/datamodel/SequenceGroup.java src/jalview/gui/AlignFrame.java src/jalview/gui/AlignViewport.java src/jalview/jbgui/GAlignFrame.java --- diff --git a/.classpath b/.classpath index af48f6e..6cffc21 100644 --- a/.classpath +++ b/.classpath @@ -2,6 +2,7 @@ + @@ -45,7 +46,7 @@ - + diff --git a/.project b/.project index b0a39c0..5f4b511 100644 --- a/.project +++ b/.project @@ -37,6 +37,7 @@ + org.eclipse.jdt.groovy.core.groovyNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.jdt.core.javanature org.eclipse.wst.common.project.facet.core.nature diff --git a/examples/appletParameters.html b/examples/appletParameters.html index 261bfa3..39cd9fb 100644 --- a/examples/appletParameters.html +++ b/examples/appletParameters.html @@ -1,7 +1,145 @@ - -Applet Parameters -
       
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-

Quick Links:

  • Download the applet jar file from here
  • Parameters are described below
  • The javascript API is described here

+ + + + +Applet Parameters + + + + + + + + + + + +
+ + + + +
       
+ + + + - -
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Home
Overview
Download
Applet + Version
Screenshots
FAQ
Documentation
Release + history
Source + Code
Development Version
Links
News + Mailing List
Discussion Mailing List

Please send problems
and + bug reports to the discussion list.
+ +
+ +

+
+
+
+

+ Quick Links:

  • Download the applet jar file from here +
  • +
  • Parameters are described below
  • +
  • The javascript API is described here
  • +
+

+

Useful to know!!

  • Package all your data files into a single (or multiple) zip / jar @@ -13,14 +151,53 @@
  • Use Jalview for input to a HTML form. For an example of how to code this using Javascript, click here. -
    -
  • +
    +
  • Embed Jalview into the web page, without the "Start Jalview" button by setting the embed parameter to true;
    <param name="embedded" value="true">
  • -

**NEW FEATURES** in Jalview 2.8

  • Normalised sequence logo display
  • RNA secondary structure annotation row

**NEW FEATURES** in Jalview 2.7.1

  • Jmol compatibility updated to Jmol 12.2.x series - download the JmolApplet here
  • To use Jmol as the structure viewer for Jalview, you must include the jar file in the applet archive argument thus:
    archive="jalviewApplet.jar,Jmol-12.2.4.jar"
  • Jmol 12.2.x requires at least Java 1.6 to run in the clients web browser. If the client does not have Java 1.6, or if the Jmol-12.2.jar is not added to the archive, the original Jalview structure viewer will still be available.

**NEW FEATURES** in Jalview 2.7

  • Javascript callbacks capabilities
    • oninit parameter and methods for registering javascript handlers for selections, mouseovers and linking to Jmol applets on the page.
    • To use javascript callbacks, ensure the applet tag includes the 'mayscript' attribute - either as a parameter (<param name="mayscript" value="true"/;gt;) or as a bare attribute in the applet html tag).
  • New jalviewLite java api methods for selecting, highlighting, scrolling and reordering sequences in an alignment view.

**NEW FEATURES** in Jalview 2.6

  • Jmol compatibility updated to Jmol 12.1.x series
  • Jalview 2.6 works only with Jmol version 12.1.13 or later. You can use the JmolApplet.jar from the Jmol binary distribution available at the Jmol Sourceforge site, or download the Jmol applet from here
  • Minimum recommended version of Java runtime for the applet is now 1.5 (JalviewLite v2.6 without the Jmol viewer may work ok on earlier Java environments but compatibility can no-longer be guaranteed).
-
**NEW FEATURES** in Jalview 2.5

  • New parameters to control display of tree annotation, width of alignment columns, and to disable the jalview button and check for Jmol on startup.

**NEW FEATURES** in Jalview 2.4

+ +

**NEW FEATURES** in Jalview 2.8

+
    +
  • Normalised sequence logo display +
  • +
  • RNA secondary structure annotation row +
  • +
+

**NEW FEATURES** in Jalview 2.7.1

+
    +
  • Jmol compatibility updated to Jmol 12.2.x series - download the JmolApplet here
  • +
  • To use Jmol as the structure viewer for Jalview, you must include + the jar file in the applet archive argument thus:
    +
    archive="jalviewApplet.jar,Jmol-12.2.4.jar"
    +
  • +
  • Jmol 12.2.x requires at least Java 1.6 to run in the clients web browser. If the client does not have + Java 1.6, or if the Jmol-12.2.jar is not added to the archive, the + original Jalview structure viewer will still be available.
    +
  • + +
+

**NEW FEATURES** in Jalview 2.7

+
    +
  • Javascript callbacks capabilities
    • oninit parameter and methods for registering javascript handlers for selections, mouseovers and linking to Jmol applets on the page.
    • +
    • To use javascript callbacks, ensure the applet tag includes the 'mayscript' attribute - either as a parameter (<param name="mayscript" value="true"/;gt;) or as a bare attribute in the applet html tag).
    +
  • +
  • New jalviewLite java api methods for selecting, highlighting, scrolling and reordering sequences in an alignment view. +
+

**NEW FEATURES** in Jalview 2.6

+
    +
  • Jmol compatibility updated to Jmol 12.1.x series
  • +
  • Jalview 2.6 works only with Jmol version 12.1.13 or later. You can use the JmolApplet.jar from + the Jmol binary distribution available at the Jmol Sourceforge site, + or download the Jmol applet from here
  • +
  • Minimum recommended version of Java runtime for the applet is now 1.5 (JalviewLite v2.6 without the Jmol viewer may work ok on earlier Java environments but compatibility can no-longer be guaranteed).
  • +
+
**NEW FEATURES** in Jalview 2.5

+
    +
  • New parameters to control display of tree annotation, width of alignment columns, and to disable the jalview button and check for Jmol on startup.
  • +
+
**NEW FEATURES** in Jalview 2.4

  • New applet API methods for feature display control, views, and obtaining current selection via javascript.
  • Group show and hide parameters: @@ -50,7 +227,7 @@ <param name="PDBFile3" value="Third.pdb D=SeqX B=SeqY C=SeqZ">
  • -
  • Note parameter "PDBSeq" is no longer required.
    +
  • Note parameter "PDBSeq" is no longer required.
  • Jalview 2.3 was updated to work with Jmol 11. See the versions archive if you want to download the old Jmol applet.
  •  

    @@ -68,7 +245,7 @@ <param name="userDefinedColour" value="D,E=red; K,R,H=0022FF; C=yellow">
    -
  • Param showFeatureSettings +
  • Param showFeatureSettings - this will display the feature settings window when the applet starts.
  • Param Application_URL value="http://www.jalview.org/services/launchApp"
    @@ -285,7 +462,105 @@
showbutton true Show the jalview button on the page. When false, JalviewLite will open immediately.
sortByTree true or false (default is false) automatically sort the associated alignment view by the tree when a new tree is opened.
showTreeBootstrapstrue or false (default is true)show or hide branch bootstraps
showTreeDistancestrue or false (default is true)show or hide branch lengths
showUnlinkedTreeNodestrue or false (default is false)indicate if unassociated nodes should be highlighted in the tree view
heightScale 1.0 or greater Adjust the height of each cell in the alignment grid relative to the height of a character in the alignment font. (since 2.5.1)
widthScale 1.0 or greater Adjust the width of each cell in the alignment grid relative to the width of a character in the alignment font. (since 2.5.1)
centrecolumnlabels true of false (default is false) When true, text labels associated with a column in the alignment will be shown centered with respect to the column. (since 2.4)
showUnconserved true of false (default is false) When true, only gaps and symbols different to the consensus sequence for a column will be shown. Useful for visualizing alignments exhibiting low sequence variation, where it is important to highlight mutations. (since 2.5)
upperCase bold or other value Indicate a text style to apply to uppercase sequence symbols. Currently, only bold is supported.
automaticScrolling true of false (default is true) When true, alignment panels will automatically scroll to show any regions of the alignment highlighted due to javascript events or when mousing over a position in an associated structure. (since 2.6)
showGroupConsensus true of false (default is false) When true, shows consensus annotation row for any groups on the alignment. (since 2.7)
showGroupConservation true of false (default is false) When true, shows amino-acid property conservation annotation row for any groups on the alignment. (since 2.7)
showConsensusHistogram true of false (default is true) When true, shows the percentage occurence of the consensus symbol for each column as a histogram above the consensus sequence row. (since 2.7)
showSequenceLogo true of false (default is false) When true, shows a sequence logo above the consensus sequence (overlaid above the Consensus Histogram, if visible, with symbols coloured using the alignment's default colourscheme). (since 2.7)
normaliseLogo true of false (default is false) When true, all sequence logos will be normalised (all symbol stacks add up to full height of annotation row), rather than being scaled according to the fraction of symbols identical to the consensus. (since 2.7.1)
oninit after_init() name of javascript function that will be called after the jalviewLite instance has completed its initialisation. (since 2.7)
relaxedidmatch true or false (default is false) When true, use stem based matching to identify sequences that match features imported from a GFF or Jalview sequence features file, and for associating PDB data (passed on PDBfile parguments) with sequences (based on a given destination sequence ID). (since 2.7)
alignpdbfiles true or false (default is false) When true, and jalviewLite is able to use jmol as a structure viewer, attempt to show a superposition of all structures loaded onto the alignment, superimposed using the aligned regions of corresponding sequences. [experimental] (since 2.7)
externalstructureviewer true or false (default is false) re-route jmol colouring commands, selection and mouseover events to an external viewer using javascript callbacks. [experimental] (since 2.7)
annotationcolour_max colour name or RGB hex triplet (default is red) Default colour used for maximum value when shading by annotation. (since 2.7)
annotationcolour_min colour name or RGB hex triplet (default is orange) Default colour used for minimum value when shading by annotation. (since 2.7)
jalviewhelpurl absolute or relative url or javascript function prefixed by javascript: (default is http://www.jalview.org/help.html) Optional parameter allowing modification of the default Jalview Help URL normally opened when JalviewLite's 'Help' menu item is selected. (since 2.7)
resolvetocodebase True or False (False) Set to true to re-instate pre-JalviewLite 2.7 behaviour where relative URLs were prepended with the applet 'codebase' rather than the current document base URL before resolution. (since 2.7)
+
sortByTreetrue or false (default is false)automatically sort the associated alignment view by the tree when a new tree is opened.
showTreeBootstrapstrue or false (default is true)show or hide branch bootstraps
showTreeDistancestrue or false (default is true)show or hide branch lengths
showUnlinkedTreeNodestrue or false (default is false)indicate if unassociated nodes should be highlighted in the tree view
heightScale1.0 or greaterAdjust the height of each cell in the alignment grid relative to the height of a character in the alignment font. (since 2.5.1)
widthScale1.0 or greaterAdjust the width of each cell in the alignment grid relative to the width of a character in the alignment font. (since 2.5.1)
centrecolumnlabelstrue of false (default is false)When true, text labels associated with a column in the alignment will be shown centered with respect to the column. (since 2.4)
showUnconservedtrue of false (default is false)When true, only gaps and symbols different to the consensus sequence for a column will be shown. Useful for visualizing alignments exhibiting low sequence variation, where it is important to highlight mutations. (since 2.5)
upperCasebold or other valueIndicate a text style to apply to uppercase sequence symbols. Currently, only bold is supported.
automaticScrollingtrue of false (default is true)When true, alignment panels will automatically scroll to show any regions of the alignment highlighted due to javascript events or when mousing over a position in an associated structure. (since 2.6)
showGroupConsensustrue of false (default is false)When true, shows consensus annotation row for any groups on the alignment. (since 2.7)
showGroupConservationtrue of false (default is false)When true, shows amino-acid property conservation annotation row for any groups on the alignment. (since 2.7)
showConsensusHistogramtrue of false (default is true)When true, shows the percentage occurence of the consensus symbol for each column as a histogram above the consensus sequence row. (since 2.7)
showSequenceLogotrue of false (default is false)When true, shows a sequence logo above the consensus sequence (overlaid above the Consensus Histogram, if visible, with symbols coloured using the alignment's default colourscheme). (since 2.7)
normaliseLogotrue of false (default is false)When true, all sequence logos will be normalised (all symbol stacks add up to full height of annotation row), rather than being scaled according to the fraction of symbols identical to the consensus. (since 2.7.1)
oninitafter_init()name of javascript function that will be called after the jalviewLite instance has completed its initialisation. (since 2.7)
relaxedidmatchtrue or false (default is false)When true, use stem based matching to identify sequences that match features imported from a GFF or Jalview sequence features file, and for associating PDB data (passed on PDBfile parguments) with sequences (based on a given destination sequence ID). (since 2.7)
alignpdbfilestrue or false (default is false)When true, and jalviewLite is able to use jmol as a structure viewer, attempt to show a superposition of all structures loaded onto the alignment, superimposed using the aligned regions of corresponding sequences. [experimental] (since 2.7)
externalstructureviewertrue or false (default is false)re-route jmol colouring commands, selection and mouseover events to an external viewer using javascript callbacks. [experimental] (since 2.7)
annotationcolour_maxcolour name or RGB hex triplet (default is red)Default colour used for maximum value when shading by annotation. (since 2.7)
annotationcolour_mincolour name or RGB hex triplet (default is orange)Default colour used for minimum value when shading by annotation. (since 2.7)
jalviewhelpurlabsolute or relative url or javascript function prefixed by javascript: (default is http://www.jalview.org/help.html)Optional parameter allowing modification of the default Jalview Help URL normally opened when JalviewLite's 'Help' menu item is selected. (since 2.7)
resolvetocodebaseTrue or False (False)Set to true to re-instate pre-JalviewLite 2.7 behaviour where relative URLs were prepended with the applet 'codebase' rather than the current document base URL before resolution. (since 2.7)
scoreFilefileMultiple sequences aligment scores file. Currently is supported only the T-Coffee score_ascii file format

 

-
\ No newline at end of file + + + + + + diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index ea5ead8..276fbda 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -17,23 +17,80 @@ */ package jalview.appletgui; -import java.net.*; -import java.util.*; - -import java.awt.*; -import java.awt.event.*; - -import jalview.analysis.*; +import jalview.analysis.AAFrequency; +import jalview.analysis.AlignmentSorter; +import jalview.analysis.Conservation; import jalview.api.SequenceStructureBinding; import jalview.bin.JalviewLite; -import jalview.commands.*; -import jalview.datamodel.*; -import jalview.io.*; -import jalview.schemes.*; +import jalview.commands.CommandI; +import jalview.commands.EditCommand; +import jalview.commands.OrderCommand; +import jalview.commands.RemoveGapColCommand; +import jalview.commands.RemoveGapsCommand; +import jalview.commands.SlideSequencesCommand; +import jalview.commands.TrimRegionCommand; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.AlignmentOrder; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.io.AnnotationFile; +import jalview.io.AppletFormatAdapter; +import jalview.io.FeaturesFile; +import jalview.io.TCoffeeScoreFile; +import jalview.schemes.Blosum62ColourScheme; +import jalview.schemes.BuriedColourScheme; +import jalview.schemes.ClustalxColourScheme; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.HelixColourScheme; +import jalview.schemes.HydrophobicColourScheme; +import jalview.schemes.NucleotideColourScheme; +import jalview.schemes.PIDColourScheme; +import jalview.schemes.PurinePyrimidineColourScheme; +import jalview.schemes.RNAHelicesColourChooser; +import jalview.schemes.ResidueProperties; +import jalview.schemes.StrandColourScheme; +import jalview.schemes.TCoffeeColourScheme; +import jalview.schemes.TaylorColourScheme; +import jalview.schemes.TurnColourScheme; +import jalview.schemes.ZappoColourScheme; import jalview.structure.StructureSelectionManager; -public class AlignFrame extends EmbmenuFrame implements ActionListener, - ItemListener, KeyListener +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.CheckboxMenuItem; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; + +public class AlignFrame extends EmbmenuFrame implements ActionListener, ItemListener, KeyListener { public AlignmentPanel alignPanel; @@ -44,11 +101,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, int DEFAULT_HEIGHT = 500; String jalviewServletURL; + - public AlignFrame(AlignmentI al, jalview.bin.JalviewLite applet, - String title, boolean embedded) + public AlignFrame(AlignmentI al, jalview.bin.JalviewLite applet, String title, boolean embedded) { - if (applet != null) { jalviewServletURL = applet.getParameter("APPLICATION_URL"); @@ -697,6 +753,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, { loadAnnotations(); } + else if( source == loadScores ) { + loadScores(); + } else if (source == outputAnnotations) { outputAnnotations(true); @@ -960,6 +1019,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, { changeColour(new Blosum62ColourScheme()); } + else if (source == tcoffeeColour) { + changeColour(new TCoffeeColourScheme(alignPanel.getAlignment())); + } else if (source == annotationColour) { new AnnotationColourChooser(viewport, alignPanel); @@ -1049,6 +1111,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, jalview.bin.JalviewLite.addFrame(frame, "Paste Annotations ", 400, 300); } + + public void loadScores() { + //TODO + + } public String outputAnnotations(boolean displayTextbox) { @@ -2272,7 +2339,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, cs.setConsensus(viewport.getSequenceConsensusHash()); - } + } viewport.setGlobalColourScheme(cs); if (viewport.getColourAppliesToAllGroups()) @@ -2297,7 +2364,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, { try { - sg.cs = (ColourSchemeI) cs.getClass().newInstance(); + sg.cs = cs.getClass().newInstance(); } catch (Exception ex) { ex.printStackTrace(); @@ -2722,6 +2789,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, MenuItem loadTree = new MenuItem("Load Associated Tree ..."); MenuItem loadAnnotations = new MenuItem("Load Features/Annotations ..."); + + MenuItem loadScores = new MenuItem("Load Associated T-Coffee scores ..."); MenuItem outputFeatures = new MenuItem("Export Features ..."); @@ -2803,6 +2872,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, MenuItem PIDColour = new MenuItem(); MenuItem BLOSUM62Colour = new MenuItem(); + + MenuItem tcoffeeColour = new MenuItem(); MenuItem njTreeBlosumMenuItem = new MenuItem(); @@ -2927,6 +2998,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, loadTree.addActionListener(this); loadAnnotations.addActionListener(this); + loadScores.addActionListener(this); outputFeatures.addActionListener(this); outputAnnotations.addActionListener(this); selectAllSequenceMenuItem.addActionListener(this); @@ -2996,8 +3068,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, PIDColour.addActionListener(this); BLOSUM62Colour.setLabel("BLOSUM62 Score"); BLOSUM62Colour.addActionListener(this); - avDistanceTreeBlosumMenuItem - .setLabel("Average Distance Using BLOSUM62"); + tcoffeeColour.setLabel("T-Coffee Scores"); + tcoffeeColour.setEnabled(false); // it will enabled only if a score file is provided + tcoffeeColour.addActionListener(this); + avDistanceTreeBlosumMenuItem .setLabel("Average Distance Using BLOSUM62"); avDistanceTreeBlosumMenuItem.addActionListener(this); njTreeBlosumMenuItem.setLabel("Neighbour Joining Using BLOSUM62"); njTreeBlosumMenuItem.addActionListener(this); @@ -3142,7 +3216,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, fileMenu.add(inputText); fileMenu.add(loadTree); fileMenu.add(loadAnnotations); - + fileMenu.add(loadScores); + fileMenu.addSeparator(); fileMenu.add(outputTextboxMenu); fileMenu.add(outputFeatures); @@ -3204,6 +3279,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, colourMenu.add(buriedColour); colourMenu.add(nucleotideColour); colourMenu.add(purinePyrimidineColour); + colourMenu.add(tcoffeeColour); colourMenu.add(userDefinedColour); colourMenu.addSeparator(); colourMenu.add(conservationMenuItem); @@ -3632,4 +3708,41 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, public String getSequenceSetId() { return viewport.getSequenceSetId(); } + + + /** + * Load the (T-Coffee) score file from the specified url + * + * @param url The absolute path from where download and read the score file + * @throws IOException + */ + public void loadScoreFile( URL url ) throws IOException { + // TODO: refactor to string/standard jalview data importer + TCoffeeScoreFile file = TCoffeeScoreFile.load( new InputStreamReader( url.openStream() ) ); + if( file == null ) { + // TODO: raise a dialog box here rather than bomb out. + + throw new RuntimeException("The file provided does not match the T-Coffee scores file format"); + } + + /* + * check that the score matrix matches the alignment dimensions + */ + AlignmentI aln; + if( (aln=viewport.getAlignment()) != null && (aln.getHeight() != file.getHeight() || aln.getWidth() != file.getWidth()) ) { + // TODO: raise a dialog box here rather than bomb out. + throw new RuntimeException("The scores matrix does not match the alignment dimensions"); + + } + + // TODO add parameter to indicate if matching should be done + if (file.annotateAlignment(alignPanel.getAlignment(), false)) + { + tcoffeeColour.setEnabled(true); + // switch to this color + changeColour(new TCoffeeColourScheme(alignPanel.getAlignment())); + } + } + + } diff --git a/src/jalview/appletgui/SequenceRenderer.java b/src/jalview/appletgui/SequenceRenderer.java index afbc7e3..044fcbe 100755 --- a/src/jalview/appletgui/SequenceRenderer.java +++ b/src/jalview/appletgui/SequenceRenderer.java @@ -17,10 +17,15 @@ */ package jalview.appletgui; -import java.awt.*; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.schemes.ColourSchemeI; -import jalview.datamodel.*; -import jalview.schemes.*; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; public class SequenceRenderer implements jalview.api.SequenceRenderer { @@ -82,7 +87,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (cs != null) { - resBoxColour = cs.findColour(seq.getCharAt(i), i); + resBoxColour = cs.findColour(seq.getCharAt(i), i, seq); } else if (forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i))) diff --git a/src/jalview/appletgui/UserDefinedColours.java b/src/jalview/appletgui/UserDefinedColours.java index 77fd5ec..73df35f 100755 --- a/src/jalview/appletgui/UserDefinedColours.java +++ b/src/jalview/appletgui/UserDefinedColours.java @@ -17,13 +17,31 @@ */ package jalview.appletgui; -import java.util.*; - -import java.awt.*; -import java.awt.event.*; - -import jalview.datamodel.*; -import jalview.schemes.*; +import jalview.datamodel.SequenceGroup; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.GraduatedColor; +import jalview.schemes.ResidueProperties; +import jalview.schemes.UserColourScheme; + +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dialog; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.Scrollbar; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.MouseEvent; +import java.util.Vector; public class UserDefinedColours extends Panel implements ActionListener, AdjustmentListener @@ -379,7 +397,7 @@ public class UserDefinedColours extends Panel implements ActionListener, { try { - col = oldColourScheme.findColour(aa.charAt(0), -1); + col = oldColourScheme.findColour(aa.charAt(0), -1, null); } catch (Exception ex) { } diff --git a/src/jalview/bin/JalviewLite.java b/src/jalview/bin/JalviewLite.java index 311e48d..342ff4c 100644 --- a/src/jalview/bin/JalviewLite.java +++ b/src/jalview/bin/JalviewLite.java @@ -1823,8 +1823,7 @@ public class JalviewLite extends Applet implements if (protocol == jalview.io.AppletFormatAdapter.PASTE) { - newAlignFrame.setTitle("Sequences from " - + applet.getDocumentBase()); + newAlignFrame.setTitle("Sequences from " + applet.getDocumentBase()); } newAlignFrame.statusBar.setText("Successfully loaded file " + file); @@ -1865,6 +1864,24 @@ public class JalviewLite extends Applet implements } } + + /* + * Try to load T-Coffee score file + */ + String sScoreFile = applet.getParameter("scoreFile"); + if( sScoreFile != null && !"".equals(sScoreFile) ) { + try { + URL urlScore = new URL(sScoreFile); + newAlignFrame.loadScoreFile(urlScore); + + } + catch( Exception e ) { + // TODO error message log (shows a warning dialogbox?) + System.err.printf("Cannot read score file: '%s'. Cause: %s \n", sScoreFile, e.getMessage()); + } + } + + // /////////////////////////// // modify display of features // we do this before any features have been loaded, ensuring any hidden groups are hidden when features first displayed diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java index 04977e8..708e566 100755 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@ -805,10 +805,9 @@ public class Alignment implements AlignmentI annotations = temp; } + @Override /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! + * returns all annotation on the alignment */ public AlignmentAnnotation[] getAlignmentAnnotation() { diff --git a/src/jalview/datamodel/AlignmentI.java b/src/jalview/datamodel/AlignmentI.java index a193997..a79106a 100755 --- a/src/jalview/datamodel/AlignmentI.java +++ b/src/jalview/datamodel/AlignmentI.java @@ -22,7 +22,7 @@ import java.util.*; /** * Data structure to hold and manipulate a multiple sequence alignment */ -public interface AlignmentI +public interface AlignmentI extends AnnotatedCollectionI { /** * Calculates the number of sequences in an alignment diff --git a/src/jalview/datamodel/AnnotatedCollectionI.java b/src/jalview/datamodel/AnnotatedCollectionI.java new file mode 100644 index 0000000..d7a0339 --- /dev/null +++ b/src/jalview/datamodel/AnnotatedCollectionI.java @@ -0,0 +1,14 @@ +package jalview.datamodel; + +import java.util.List; + +public interface AnnotatedCollectionI +{ + + /** + * TODO: decide if null is a valid response if there is no annotation on the object + * @return null + */ + AlignmentAnnotation[] getAlignmentAnnotation(); + +} diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index b0969b5..cdb1921 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -17,9 +17,10 @@ */ package jalview.datamodel; -import java.util.*; +import jalview.analysis.AlignSeq; -import jalview.analysis.*; +import java.util.Enumeration; +import java.util.Vector; /** * @@ -53,6 +54,11 @@ public class Sequence implements SequenceI * to the residues of this sequence */ Vector annotation; + + /** + * The index of the sequence in a MSA + */ + int index = -1; /** array of seuqence features - may not be null for a valid sequence object */ public SequenceFeature[] sequenceFeatures; @@ -1172,4 +1178,17 @@ public class Sequence implements SequenceI } } + /** + * @return The index (zero-based) on this sequence in the MSA. + * It returns {@code -1} if this information is not available. + */ + public int getIndex() { return index; } + + /** + * Defines the position of this sequence in the MSA. + * Use the value {@code -1} if this information is undefined. + * + * @param The position for this sequence. This value is zero-based (zero for this first sequence) + */ + public void setIndex(int value) { index = value; } } diff --git a/src/jalview/datamodel/SequenceGroup.java b/src/jalview/datamodel/SequenceGroup.java index 6bee416..e7c1a85 100755 --- a/src/jalview/datamodel/SequenceGroup.java +++ b/src/jalview/datamodel/SequenceGroup.java @@ -30,7 +30,7 @@ import jalview.schemes.*; * @author $author$ * @version $Revision$ */ -public class SequenceGroup +public class SequenceGroup implements AnnotatedCollectionI { String groupName; @@ -482,7 +482,10 @@ public class SequenceGroup { return; } - + if (cs!=null) + { + cs.alignmentChanged(this); + } try { Hashtable cnsns[] = AAFrequency.calculate(sequences, startRes, @@ -1185,4 +1188,32 @@ public class SequenceGroup { return normaliseSequenceLogo; } + @Override + /** + * returns a new array with all annotation involving this group + */ + public AlignmentAnnotation[] getAlignmentAnnotation() + { + // TODO add in other methods like 'getAlignmentAnnotation(String label), etc' + ArrayList annot = new ArrayList(); + for (SequenceI seq:(Vector)sequences) + { + for (AlignmentAnnotation al: seq.getAnnotation()) + { + if (al.groupRef==this) + { + annot.add(al); + } + } + } + if (consensus!=null) + { + annot.add(consensus); + } + if (conservation!=null) + { + annot.add(conservation); + } + return annot.toArray(new AlignmentAnnotation[0]); + } } diff --git a/src/jalview/datamodel/SequenceI.java b/src/jalview/datamodel/SequenceI.java index 3d91004..33045d0 100755 --- a/src/jalview/datamodel/SequenceI.java +++ b/src/jalview/datamodel/SequenceI.java @@ -17,7 +17,7 @@ */ package jalview.datamodel; -import java.util.*; +import java.util.Vector; /** * DOCUMENT ME! @@ -348,5 +348,15 @@ public interface SequenceI * null or mapping from entry's numbering to local start/end */ public void transferAnnotation(SequenceI entry, Mapping mp); + + /** + * @param index The sequence index in the MSA + */ + public void setIndex(int index); + + /** + * @return The index of the sequence in the alignment + */ + public int getIndex(); } diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 9b571f2..6896fb7 100755 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -55,6 +55,7 @@ import jalview.io.JalviewFileChooser; import jalview.io.JalviewFileView; import jalview.io.JnetAnnotationMaker; import jalview.io.NewickFile; +import jalview.io.TCoffeeScoreFile; import jalview.jbgui.GAlignFrame; import jalview.schemes.Blosum62ColourScheme; import jalview.schemes.BuriedColourScheme; @@ -69,6 +70,7 @@ import jalview.schemes.PurinePyrimidineColourScheme; import jalview.schemes.RNAHelicesColourChooser; import jalview.schemes.ResidueProperties; import jalview.schemes.StrandColourScheme; +import jalview.schemes.TCoffeeColourScheme; import jalview.schemes.TaylorColourScheme; import jalview.schemes.TurnColourScheme; import jalview.schemes.UserColourScheme; @@ -144,7 +146,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, AlignViewport viewport; Vector alignPanels = new Vector(); - + /** * Last format used to load or save alignments in this window */ @@ -3053,6 +3055,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, */ public void changeColour(ColourSchemeI cs) { + // TODO: compare with applet and pull up to model method int threshold = 0; if (cs != null) @@ -3124,7 +3127,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { try { - sg.cs = (ColourSchemeI) cs.getClass().newInstance(); + sg.cs = cs.getClass().newInstance(); } catch (Exception ex) { } @@ -3922,7 +3925,84 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } } - + + @Override + public void loadScores_actionPerformed(ActionEvent e) + { + // Pick the tree file + JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty("LAST_DIRECTORY")); + chooser.setFileView(new JalviewFileView()); + chooser.setDialogTitle("Select a T-Coffee scores ascii file"); + chooser.setToolTipText("Load a score file"); + + int value = chooser.showOpenDialog(null); + + if (value == JalviewFileChooser.APPROVE_OPTION) + { + String sFilePath = chooser.getSelectedFile().getPath(); + jalview.bin.Cache.setProperty("LAST_DIRECTORY", sFilePath); + + + try + { + TCoffeeScoreFile result = TCoffeeScoreFile.load(new File(sFilePath)); + if( result == null ) { + // TODO: raise a dialog box here rather than bomb out. + + throw new RuntimeException("The file provided does not match the T-Coffee scores file format"); + } + + /* + * check that the score matrix matches the alignment dimensions + */ + AlignmentI aln; + if( (aln=viewport.getAlignment()) != null && (aln.getHeight() != result.getHeight() || aln.getWidth() != result.getWidth()) ) { + // TODO: raise a dialog box here rather than bomb out. + throw new RuntimeException("The scores matrix does not match the alignment dimensions"); + } + if (result.annotateAlignment(alignPanel.getAlignment(), true)) + { + tcoffeeColour.setEnabled(true); + tcoffeeColour.setSelected(true); + // switch to this color + changeColour(new TCoffeeColourScheme(alignPanel.getAlignment())); + } else { + tcoffeeColour.setEnabled(false); + tcoffeeColour.setSelected(false); + } + } + catch (Exception ex) { + JOptionPane.showMessageDialog( + Desktop.desktop, + ex.getMessage(), + "Problem reading tree file", + JOptionPane.WARNING_MESSAGE); + + ex.printStackTrace(); + } + } + + } + + + @Override + protected void tcoffeeColorScheme_actionPerformed(ActionEvent e) { + changeColour( new TCoffeeColourScheme(alignPanel.getAlignment()) ); + } + +// /** +// * Load the (T-Coffee) score file from the specified url +// * +// * @param url The absolute path from where download and read the score file +// * @throws IOException +// */ +// public void loadScoreFile(URL url ) throws IOException { +// +// TCoffeeScoreFile result = new TCoffeeScoreFile(); +// result.parse( new InputStreamReader( url.openStream() ) ); +// tcoffeeScoreFile = result; +// } + public TreePanel ShowNewickTree(NewickFile nf, String title) { return ShowNewickTree(nf, title, 600, 500, 4, 5); diff --git a/src/jalview/gui/SequenceRenderer.java b/src/jalview/gui/SequenceRenderer.java index ad704c3..b294282 100755 --- a/src/jalview/gui/SequenceRenderer.java +++ b/src/jalview/gui/SequenceRenderer.java @@ -17,10 +17,14 @@ */ package jalview.gui; -import java.awt.*; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.schemes.ColourSchemeI; -import jalview.datamodel.*; -import jalview.schemes.*; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; /** * DOCUMENT ME! @@ -111,7 +115,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (cs != null) { - resBoxColour = cs.findColour(seq.getCharAt(i), i); + resBoxColour = cs.findColour(seq.getCharAt(i), i, seq); } else if (forOverview && !jalview.util.Comparison.isGap(seq.getCharAt(i))) diff --git a/src/jalview/gui/UserDefinedColours.java b/src/jalview/gui/UserDefinedColours.java index aefc9c8..53e4ad3 100755 --- a/src/jalview/gui/UserDefinedColours.java +++ b/src/jalview/gui/UserDefinedColours.java @@ -17,18 +17,32 @@ */ package jalview.gui; -import java.io.*; -import java.util.*; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; - -import jalview.datamodel.*; -import jalview.io.*; -import jalview.jbgui.*; -import jalview.schemes.*; +import jalview.datamodel.SequenceGroup; +import jalview.io.JalviewFileChooser; +import jalview.jbgui.GUserDefinedColours; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.ResidueProperties; +import jalview.schemes.UserColourScheme; + +import java.awt.Color; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; + +import javax.swing.JButton; +import javax.swing.JInternalFrame; +import javax.swing.JOptionPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; /** * DOCUMENT ME! @@ -372,7 +386,7 @@ public class UserDefinedColours extends GUserDefinedColours implements { try { - col = oldColourScheme.findColour(aa.charAt(0), -1); + col = oldColourScheme.findColour(aa.charAt(0), -1, null); } catch (Exception ex) { } diff --git a/src/jalview/io/AlignFile.java b/src/jalview/io/AlignFile.java index a4fb830..3ef7210 100755 --- a/src/jalview/io/AlignFile.java +++ b/src/jalview/io/AlignFile.java @@ -17,10 +17,15 @@ */ package jalview.io; -import java.io.*; -import java.util.*; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; -import jalview.datamodel.*; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; /** * DOCUMENT ME! @@ -37,7 +42,7 @@ public abstract class AlignFile extends FileParse /** * Sequences to be added to form a new alignment. */ - protected Vector seqs; + protected Vector seqs; /** * annotation to be added to generated alignment object @@ -73,10 +78,12 @@ public abstract class AlignFile extends FileParse public AlignFile(String inFile, String type) throws IOException { super(inFile, type); - initData(); - parse(); + // sets the index of each sequence in the alignment + for( int i=0,c=seqs.size(); i getSeqs() { return seqs; } diff --git a/src/jalview/io/TCoffeeScoreFile.java b/src/jalview/io/TCoffeeScoreFile.java new file mode 100644 index 0000000..6cab3ae --- /dev/null +++ b/src/jalview/io/TCoffeeScoreFile.java @@ -0,0 +1,474 @@ +package jalview.io; + +import jalview.analysis.SequenceIdMatcher; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.Annotation; +import jalview.datamodel.SequenceI; + +import java.awt.Color; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * A file parse for T-Coffee score ascii format. This file contains the alignment consensus + * for each resude in any sequence. + *

+ * This file is procuded by t_coffee providing the option + * -output=score_ascii to the program command line + * + * An example file is the following + * + *

+ * T-COFFEE, Version_9.02.r1228 (2012-02-16 18:15:12 - Revision 1228 - Build 336)
+ * Cedric Notredame 
+ * CPU TIME:0 sec.
+ * SCORE=90
+ * *
+ *  BAD AVG GOOD
+ * *
+ * 1PHT   :  89
+ * 1BB9   :  90
+ * 1UHC   :  94
+ * 1YCS   :  94
+ * 1OOT   :  93
+ * 1ABO   :  94
+ * 1FYN   :  94
+ * 1QCF   :  94
+ * cons   :  90
+ * 
+ * 1PHT   999999999999999999999999998762112222543211112134
+ * 1BB9   99999999999999999999999999987-------4322----2234
+ * 1UHC   99999999999999999999999999987-------5321----2246
+ * 1YCS   99999999999999999999999999986-------4321----1-35
+ * 1OOT   999999999999999999999999999861-------3------1135
+ * 1ABO   99999999999999999999999999986-------422-------34
+ * 1FYN   99999999999999999999999999985-------32--------35
+ * 1QCF   99999999999999999999999999974-------2---------24
+ * cons   999999999999999999999999999851000110321100001134
+ * 
+ * 
+ * 1PHT   ----------5666642367889999999999889
+ * 1BB9   1111111111676653-355679999999999889
+ * 1UHC   ----------788774--66789999999999889
+ * 1YCS   ----------78777--356789999999999889
+ * 1OOT   ----------78877--356789999999997-67
+ * 1ABO   ----------687774--56779999999999889
+ * 1FYN   ----------6888842356789999999999889
+ * 1QCF   ----------6878742356789999999999889
+ * cons   00100000006877641356789999999999889
+ * 
+ * + * + * @author Paolo Di Tommaso + * + */ +public class TCoffeeScoreFile { + + /** The {@link Header} structure holder */ + Header header; + + /** + * Holds the consensues values for each sequences. It uses a LinkedHashMap to maintaint the + * insertion order. + */ + LinkedHashMap scores = new LinkedHashMap(); + + Integer fWidth; + + /** + * Parse the specified file. + * + * @param file The file to be parsed + */ + public static TCoffeeScoreFile load(File file) { + try { + return load(new FileReader(file)); + } + catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + /** + * Parse the provided reader for the T-Coffee scores file format + * + * @param reader + */ + public static TCoffeeScoreFile load(Reader reader) { + + try { + BufferedReader in = (BufferedReader) (reader instanceof BufferedReader ? reader : new BufferedReader(reader)); + TCoffeeScoreFile result = new TCoffeeScoreFile(); + result.doParsing(in); + return result.header != null && result.scores != null ? result : null; + } + catch( Exception e) { + throw new RuntimeException(e); + } + } + + /** + * @return The 'height' of the score matrix i.e. the numbers of score rows that should matches + * the number of sequences in the alignment + */ + public int getHeight() { + // the last entry will always be the 'global' alingment consensus scores, so it is removed + // from the 'height' count to make this value compatible with the number of sequences in the MSA + return scores != null && scores.size() > 0 ? scores.size()-1 : 0; + } + + /** + * @return The 'width' of the score matrix i.e. the number of columns. + * Since teh score value are supposd to be calculated for an 'aligned' MSA, all the entries + * have to have the same width. + */ + public int getWidth() { + return fWidth != null ? fWidth : 0; + } + + /** + * The default constructor is marked as {@code protected} since this class is meant to created + * through the {@link #load(File)} or {@link #load(Reader)} factory methods + */ + protected TCoffeeScoreFile() { } + + /** + * Get the string of score values for the specified seqeunce ID. + * @param id The sequence ID + * @return The scores as a string of values e.g. {@code 99999987-------432}. + * It return an empty string when the specified ID is missing. + */ + public String getScoresFor( String id ) { + return scores.containsKey(id) ? scores.get(id).toString() : ""; + } + + /** + * @return The list of score string as a {@link List} object, in the same ordeer of the insertion i.e. in the MSA + */ + public List getScoresList() { + List result = new ArrayList( scores.size() ); + for( Map.Entry it : scores.entrySet() ) { + result.add(it.getValue().toString()); + } + + return result; + } + + /** + * @return The parsed score values a matrix of bytes + */ + public byte[][] getScoresArray() { + byte[][] result = new byte[ scores.size() ][]; + + int rowCount = 0; + for( Map.Entry it : scores.entrySet() ) { + String line = it.getValue().toString(); + byte[] seqValues = new byte[ line.length() ]; + for( int j=0, c=line.length(); j= 0 && val <= 9 ) ? val : -1; + } + + result[rowCount++] = seqValues; + } + + return result; + } + + + private void doParsing(BufferedReader in) throws IOException { + + /* + * read the header + */ + header = readHeader(in); + + if( header == null ) { return; } + + + /* + * initilize the structure + */ + for( Map.Entry entry : header.scores.entrySet() ) { + scores.put( entry.getKey(), new StringBuilder()); + } + + /* + * go with the reading + */ + Block block; + while( (block = readBlock(in, header.scores.size())) != null ) { + + /* + * append sequences read in the block + */ + for( Map.Entry entry : block.items.entrySet() ) { + StringBuilder scoreStringBuilder = scores.get(entry.getKey()); + if( scoreStringBuilder == null ) { + throw new RuntimeException(String.format("Invalid T-Coffee score file: Sequence ID '%s' is not declared in header section", entry.getKey())); + } + + scoreStringBuilder.append( entry.getValue() ); + } + } + + /* + * verify that all rows have the same width + */ + for( StringBuilder str : scores.values() ) { + if( fWidth == null ) { + fWidth = str.length(); + } + else if( fWidth != str.length() ) { + throw new RuntimeException("Invalid T-Coffee score file: All the score sequences must have the same length"); + } + } + + + + } + + + static int parseInt( String str ) { + try { + return Integer.parseInt(str); + } + catch( NumberFormatException e ) { + // TODO report a warning ? + return 0; + } + } + + /** + * Reaad the header section in the T-Coffee score file format + * + * @param reader The scores reader + * @return The parser {@link Header} instance + * @throws RuntimeException when the header is not in the expected format + */ + static Header readHeader(BufferedReader reader) { + + Header result = null; + try { + result = new Header(); + result.head = reader.readLine(); + + String line; + + while( (line = reader.readLine()) != null ) { + if( line.startsWith("SCORE=")) { + result.score = parseInt( line.substring(6).trim() ); + break; + } + } + + if( (line=reader.readLine())==null || !"*".equals(line.trim())) return null; + if( (line=reader.readLine())==null || !"BAD AVG GOOD".equals(line.trim())) return null; + if( (line=reader.readLine())==null || !"*".equals(line.trim())) return null; + + /* + * now are expected a list if sequences ID up to the first blank line + */ + while( (line=reader.readLine()) != null ) { + if( "".equals(line) ) { + break; + } + + int p = line.indexOf(":"); + if( p == -1 ) { + // TODO report a warning + continue; + } + + String id = line.substring(0,p).trim(); + int val = parseInt(line.substring(p+1).trim()); + if( "".equals(id) ) { + // TODO report warning + continue; + } + + result.scores.put(id,val); + } + + } + catch( IOException e ) { + throw new RuntimeException("Cannot parse T-Coffee score ascii file", e); + } + + return result; + } + + /** + * Read a scores block ihe provided stream. + * + * @param reader The stream to parse + * @param size The expected number of the sequence to be read + * @return The {@link Block} instance read or {link null} null if the end of file has reached. + * @throws IOException Something went wrong on the 'wire' + */ + static Block readBlock( BufferedReader reader, int size ) throws IOException { + Block result = new Block(size); + String line; + + /* + * read blank lines (eventually) + */ + while( (line=reader.readLine()) != null && "".equals(line.trim())) { + // consume blank lines + } + + if( line == null ) return null; + + /* + * read the scores block + */ + do { + if( "".equals(line.trim()) ) { + // terminated + break; + } + + // split the line on the first blank + // the first part have to contain the sequence id + // theramining part are the scores values + int p = line.indexOf(" "); + if( p == -1 ) { + //TODO This is an unexpected condition, log a warning or throw an exception ? + continue; + } + + String id = line.substring(0,p).trim(); + String val = line.substring(p+1).trim(); + + result.items.put(id, val); + + } while( (line = reader.readLine()) != null ); + + + return result; + } + + /* + * The score file header + */ + static class Header { + String head; + int score; + + LinkedHashMap scores = new LinkedHashMap(); + + public int getScoreAvg() { return score; } + + public int getScoreFor( String ID ) { + + return scores.containsKey(ID) ? scores.get(ID) : -1; + + } + } + + /* + * Hold a single block values block in the score file + */ + static class Block { + int size; + Map items; + + public Block( int size ) { + this.size = size; + this.items = new HashMap(size); + } + + String getScoresFor( String id ) { + return items.get(id); + } + + String getConsensus() { + return items.get("cons"); + } + } + /** + * TCOFFEE score colourscheme + */ + static final Color[] colors = { + new Color( 102, 102, 255 ), // #6666FF + new Color( 0, 255, 0), // #00FF00 + new Color( 102, 255, 0), // #66FF00 + new Color( 204, 255, 0), // #CCFF00 + new Color( 255, 255, 0), // #FFFF00 + new Color( 255, 204, 0), // #FFCC00 + new Color( 255, 153, 0), // #FF9900 + new Color( 255, 102, 0), // #FF6600 + new Color( 255, 51, 0), // #FF3300 + new Color( 255, 34, 0) // #FF2000 + }; + public final static String TCOFFEE_SCORE="TCoffeeScore"; + /** + * generate annotation for this TCoffee score set on the given alignment + * @param al alignment to annotate + * @param matchids if true, annotate sequences based on matching sequence names + * @return true if alignment annotation was modified, false otherwise. + */ + public boolean annotateAlignment(AlignmentI al, boolean matchids) + { + boolean added=false; + int i=0; + SequenceIdMatcher sidmatcher = new SequenceIdMatcher(al.getSequencesArray()); + byte[][] scoreMatrix=getScoresArray(); + // for 2.8 - we locate any existing TCoffee annotation and remove it first before adding this. + for (Map.Entry id:scores.entrySet()) + { + byte[] srow=scoreMatrix[i]; + SequenceI s; + if (matchids) + { + s=sidmatcher.findIdMatch(id.getKey()); + } else { + s=al.getSequenceAt(i); + } + i++; + if (s==null && i!=scores.size() && !id.getKey().equals("cons")) + { + System.err.println("No "+(matchids ? "match ":" sequences left ")+" for TCoffee score set : "+id.getKey()); + continue; + } + int jSize=al.getWidth()< srow.length ? al.getWidth() : srow.length; + Annotation[] annotations=new Annotation[al.getWidth()]; + for (int j=0;j= 0 && val < colors.length ? colors[val] : Color.white); + } + AlignmentAnnotation aa=null; + if (s!=null) + { + // TODO - set per sequence score + aa=new AlignmentAnnotation(TCOFFEE_SCORE, "Score for "+id.getKey(), annotations); + + aa.setSequenceRef(s); + aa.visible=false; + aa.belowAlignment=false; + } else { + aa=new AlignmentAnnotation("T-COFFEE", "TCoffee column reliability score", annotations); + aa.belowAlignment=true; + aa.visible=true; + + } + al.addAnnotation(aa); + added=true; + } + return added; + } + + +} diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index 7ea492f..6e8b420 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -17,13 +17,35 @@ */ package jalview.jbgui; -import java.awt.*; -import java.awt.event.*; - -import javax.swing.*; -import javax.swing.event.*; - -import jalview.schemes.*; +import jalview.schemes.ColourSchemeProperty; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GridLayout; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; public class GAlignFrame extends JInternalFrame { @@ -120,6 +142,9 @@ public class GAlignFrame extends JInternalFrame // protected JRadioButtonMenuItem covariationColour = new // JRadioButtonMenuItem(); + protected JRadioButtonMenuItem tcoffeeColour = new JRadioButtonMenuItem(); + + JMenuItem njTreeBlosumMenuItem = new JMenuItem(); JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem(); @@ -181,6 +206,8 @@ public class GAlignFrame extends JInternalFrame JMenuItem epsFile = new JMenuItem(); JMenuItem LoadtreeMenuItem = new JMenuItem(); + + JMenuItem loadScoresMenuItem = new JMenuItem(); public JCheckBoxMenuItem scaleAbove = new JCheckBoxMenuItem(); @@ -428,6 +455,7 @@ public class GAlignFrame extends JInternalFrame colours.add(nucleotideColour); colours.add(purinePyrimidineColour); // colours.add(covariationColour); + colours.add(tcoffeeColour); setColourSelected(jalview.bin.Cache .getDefault("DEFAULT_COLOUR", "None")); @@ -497,6 +525,10 @@ public class GAlignFrame extends JInternalFrame nucleotideColour.setSelected(true); break; + + case ColourSchemeProperty.TCOFFEE: + tcoffeeColour.setSelected(true); + break; case ColourSchemeProperty.PURINEPYRIMIDINE: purinePyrimidineColour.setSelected(true); @@ -1146,6 +1178,18 @@ public class GAlignFrame extends JInternalFrame nucleotideColour_actionPerformed(e); } }); + + tcoffeeColour.setText("T-Coffee scores"); + tcoffeeColour.setEnabled(false); + tcoffeeColour.addActionListener( new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + tcoffeeColorScheme_actionPerformed(e); + } + } ); + + deleteGroups.setText("Undefine groups"); deleteGroups.setAccelerator(javax.swing.KeyStroke.getKeyStroke( java.awt.event.KeyEvent.VK_U, Toolkit.getDefaultToolkit() @@ -1258,7 +1302,7 @@ public class GAlignFrame extends JInternalFrame } }); LoadtreeMenuItem.setActionCommand("Load a tree for this sequence set"); - LoadtreeMenuItem.setText("Load Associated Tree"); + LoadtreeMenuItem.setText("Load Associated Tree"); LoadtreeMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) @@ -1266,6 +1310,17 @@ public class GAlignFrame extends JInternalFrame LoadtreeMenuItem_actionPerformed(e); } }); + + loadScoresMenuItem.setActionCommand("Load T-Coffee scores"); + loadScoresMenuItem.setText("Load T-Coffee scores"); + loadScoresMenuItem.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + loadScores_actionPerformed(e); + } + }); + scaleAbove.setVisible(false); scaleAbove.setText("Scale Above"); scaleAbove.addActionListener(new java.awt.event.ActionListener() @@ -1762,6 +1817,7 @@ public class GAlignFrame extends JInternalFrame fileMenu.add(exportAnnotations); fileMenu.add(LoadtreeMenuItem); fileMenu.add(associatedData); + fileMenu.add(loadScoresMenuItem); fileMenu.addSeparator(); fileMenu.add(closeMenuItem); editMenu.add(undoMenuItem); @@ -1829,6 +1885,7 @@ public class GAlignFrame extends JInternalFrame colourMenu.add(nucleotideColour); colourMenu.add(purinePyrimidineColour); // colourMenu.add(covariationColour); + colourMenu.add(tcoffeeColour); colourMenu.add(userDefinedColour); colourMenu.addSeparator(); colourMenu.add(conservationMenuItem); @@ -2308,7 +2365,32 @@ public class GAlignFrame extends JInternalFrame protected void LoadtreeMenuItem_actionPerformed(ActionEvent e) { + + } + + /** + * Template method to handle the 'load T-Coffee scores' menu event. + *

+ * Subclasses override this method to provide a custom action. + * + * @param event The raised event + */ + protected void loadScores_actionPerformed(ActionEvent event) { + + } + + + /** + * Template method to handle the 'Color T-Coffee scores' menu event. + *

+ * Subclasses override this method to provide a custom action. + * + * @param event The raised event + */ + protected void tcoffeeColorScheme_actionPerformed(ActionEvent event) { + } + protected void jpred_actionPerformed(ActionEvent e) { diff --git a/src/jalview/schemes/AnnotationColourGradient.java b/src/jalview/schemes/AnnotationColourGradient.java index 41ee01c..6c46d0e 100755 --- a/src/jalview/schemes/AnnotationColourGradient.java +++ b/src/jalview/schemes/AnnotationColourGradient.java @@ -17,9 +17,11 @@ */ package jalview.schemes; -import java.awt.*; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.GraphLine; +import jalview.datamodel.SequenceI; -import jalview.datamodel.*; +import java.awt.Color; public class AnnotationColourGradient extends ResidueColourScheme { @@ -152,7 +154,8 @@ public class AnnotationColourGradient extends ResidueColourScheme * * @return DOCUMENT ME! */ - public Color findColour(char c, int j) + @Override + public Color findColour(char c, int j, SequenceI seq) { Color currentColour = Color.white; @@ -202,7 +205,7 @@ public class AnnotationColourGradient extends ResidueColourScheme if (colourScheme != null) { - currentColour = colourScheme.findColour(c, j); + currentColour = colourScheme.findColour(c, j, seq); } else if (range != 0) { diff --git a/src/jalview/schemes/Blosum62ColourScheme.java b/src/jalview/schemes/Blosum62ColourScheme.java index e9ac579..0f04168 100755 --- a/src/jalview/schemes/Blosum62ColourScheme.java +++ b/src/jalview/schemes/Blosum62ColourScheme.java @@ -17,10 +17,10 @@ */ package jalview.schemes; -import java.awt.*; - -import jalview.analysis.*; +import jalview.analysis.AAFrequency; +import java.awt.Color; +import jalview.datamodel.SequenceI; public class Blosum62ColourScheme extends ResidueColourScheme { public Blosum62ColourScheme() @@ -28,7 +28,8 @@ public class Blosum62ColourScheme extends ResidueColourScheme super(); } - public Color findColour(char res, int j) + @Override + public Color findColour(char res, int j, SequenceI seq) { if ('a' <= res && res <= 'z') { diff --git a/src/jalview/schemes/ClustalxColourScheme.java b/src/jalview/schemes/ClustalxColourScheme.java index 14f0ce6..273efb8 100755 --- a/src/jalview/schemes/ClustalxColourScheme.java +++ b/src/jalview/schemes/ClustalxColourScheme.java @@ -17,11 +17,11 @@ */ package jalview.schemes; -import java.util.*; +import jalview.datamodel.SequenceI; -import java.awt.*; - -import jalview.datamodel.*; +import java.awt.Color; +import java.util.Hashtable; +import java.util.Vector; public class ClustalxColourScheme extends ResidueColourScheme // implements // IParameterizable @@ -251,12 +251,14 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements ResidueColour[19] = colours[0]; // V } + @Override public Color findColour(char c) { return Color.pink; } - public Color findColour(char c, int j) + @Override + public Color findColour(char c, int j, SequenceI seq) { Color currentColour; diff --git a/src/jalview/schemes/ColourSchemeI.java b/src/jalview/schemes/ColourSchemeI.java index 5c036e3..9ebe791 100755 --- a/src/jalview/schemes/ColourSchemeI.java +++ b/src/jalview/schemes/ColourSchemeI.java @@ -17,13 +17,16 @@ */ package jalview.schemes; -import java.awt.*; +import java.awt.Color; + +import jalview.datamodel.AnnotatedCollectionI; +import jalview.datamodel.SequenceI; public interface ColourSchemeI { public Color findColour(char c); - public Color findColour(char c, int j); + public Color findColour(char c, int j, SequenceI seq); public void setConsensus(java.util.Hashtable[] h); @@ -39,4 +42,6 @@ public interface ColourSchemeI public void setThreshold(int ct, boolean ignoreGaps); + public void alignmentChanged(AnnotatedCollectionI alignment); + } diff --git a/src/jalview/schemes/ColourSchemeProperty.java b/src/jalview/schemes/ColourSchemeProperty.java index f06c10f..cbd345c 100755 --- a/src/jalview/schemes/ColourSchemeProperty.java +++ b/src/jalview/schemes/ColourSchemeProperty.java @@ -17,7 +17,7 @@ */ package jalview.schemes; -import java.awt.*; +import java.awt.Color; /** * ColourSchemeProperty Binds names to hardwired colourschemes and tries to deal @@ -81,6 +81,9 @@ public class ColourSchemeProperty public static final int PURINEPYRIMIDINE = 13; public static final int COVARIATION = 14; + + public static final int TCOFFEE = 15; + /** * index of first colourscheme (includes 'None') @@ -145,6 +148,11 @@ public class ColourSchemeProperty { ret = NUCLEOTIDE; } + else if (name.equalsIgnoreCase("T-Coffee scores")) + { + ret = TCOFFEE; + } + else if (name.equalsIgnoreCase("User Defined")) { ret = USER_DEFINED; @@ -400,20 +408,21 @@ public class ColourSchemeProperty } /** - * DOCUMENT ME! + * Construct an instance of ColourSchemeI corresponding to the given colourscheme index * * @param seqs - * DOCUMENT ME! + * sequences to be coloured by colourscheme * @param width - * DOCUMENT ME! + * geometry of alignment * @param index - * DOCUMENT ME! + * colourscheme number * - * @return DOCUMENT ME! + * @return null or an instance of the colourscheme configured to colour given sequence set */ public static ColourSchemeI getColour(java.util.Vector seqs, int width, int index) { + // TODO 3.0 2.8 refactor signature to take an alignmentI like container so colourschemes based on annotation can be initialised ColourSchemeI cs = null; switch (index) diff --git a/src/jalview/schemes/NucleotideColourScheme.java b/src/jalview/schemes/NucleotideColourScheme.java index 0e2ecff..2c63ddb 100755 --- a/src/jalview/schemes/NucleotideColourScheme.java +++ b/src/jalview/schemes/NucleotideColourScheme.java @@ -17,7 +17,9 @@ */ package jalview.schemes; -import java.awt.*; +import jalview.datamodel.SequenceI; + +import java.awt.Color; /** * DOCUMENT ME! @@ -43,6 +45,7 @@ public class NucleotideColourScheme extends ResidueColourScheme * * @return DOCUMENT ME! */ + @Override public Color findColour(char c) { // System.out.println("called"); log.debug @@ -59,7 +62,8 @@ public class NucleotideColourScheme extends ResidueColourScheme * * @return DOCUMENT ME! */ - public Color findColour(char c, int j) + @Override + public Color findColour(char c, int j, SequenceI seq) { Color currentColour; if ((threshold == 0) || aboveThreshold(c, j)) diff --git a/src/jalview/schemes/PIDColourScheme.java b/src/jalview/schemes/PIDColourScheme.java index 4e07cba..5301267 100755 --- a/src/jalview/schemes/PIDColourScheme.java +++ b/src/jalview/schemes/PIDColourScheme.java @@ -17,10 +17,11 @@ */ package jalview.schemes; -import java.awt.*; +import jalview.analysis.AAFrequency; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; -import jalview.analysis.*; -import jalview.datamodel.*; +import java.awt.Color; public class PIDColourScheme extends ResidueColourScheme { @@ -36,7 +37,9 @@ public class PIDColourScheme extends ResidueColourScheme this.thresholds = ResidueProperties.pidThresholds; } - public Color findColour(char c, int j) + + @Override + public Color findColour(char c, int j, SequenceI seq) { if ('a' <= c && c <= 'z') { diff --git a/src/jalview/schemes/ResidueColourScheme.java b/src/jalview/schemes/ResidueColourScheme.java index bc1e92b..90833c9 100755 --- a/src/jalview/schemes/ResidueColourScheme.java +++ b/src/jalview/schemes/ResidueColourScheme.java @@ -17,11 +17,13 @@ */ package jalview.schemes; -import java.util.*; +import jalview.analysis.AAFrequency; +import jalview.analysis.Conservation; +import jalview.datamodel.AnnotatedCollectionI; +import jalview.datamodel.SequenceI; -import java.awt.*; - -import jalview.analysis.*; +import java.awt.Color; +import java.util.Hashtable; /** * DOCUMENT ME! @@ -82,7 +84,8 @@ public class ResidueColourScheme implements ColourSchemeI : colors[ResidueProperties.aaIndex[c]]; } - public Color findColour(char c, int j) + @Override + public Color findColour(char c, int j, SequenceI seq) { Color currentColour; @@ -102,6 +105,7 @@ public class ResidueColourScheme implements ColourSchemeI return currentColour; } + @Override public void alignmentChanged(AnnotatedCollectionI alignment) {}; /** * Get the percentage threshold for this colour scheme diff --git a/src/jalview/schemes/ScoreColourScheme.java b/src/jalview/schemes/ScoreColourScheme.java index ca76c8e..116bbd8 100755 --- a/src/jalview/schemes/ScoreColourScheme.java +++ b/src/jalview/schemes/ScoreColourScheme.java @@ -17,7 +17,9 @@ */ package jalview.schemes; -import java.awt.*; +import jalview.datamodel.SequenceI; + +import java.awt.Color; /** * DOCUMENT ME! @@ -85,7 +87,8 @@ public class ScoreColourScheme extends ResidueColourScheme * * @return DOCUMENT ME! */ - public Color findColour(char c, int j) + @Override + public Color findColour(char c, int j, SequenceI seq) { if (threshold > 0) { diff --git a/src/jalview/schemes/TCoffeeColourScheme.java b/src/jalview/schemes/TCoffeeColourScheme.java new file mode 100644 index 0000000..bbd2a23 --- /dev/null +++ b/src/jalview/schemes/TCoffeeColourScheme.java @@ -0,0 +1,84 @@ +package jalview.schemes; + +import jalview.analysis.SequenceIdMatcher; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.AnnotatedCollectionI; +import jalview.datamodel.Annotation; +import jalview.datamodel.SequenceI; +import jalview.io.TCoffeeScoreFile; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.TreeMap; + +/** + * Defines the color score for T-Coffee MSA + *

+ * See http://tcoffee.org + * + * + * @author Paolo Di Tommaso + * + */ +public class TCoffeeColourScheme extends ResidueColourScheme { + + static final Color[] colors = { + new Color( 102, 102, 255 ), // #6666FF + new Color( 0, 255, 0), // #00FF00 + new Color( 102, 255, 0), // #66FF00 + new Color( 204, 255, 0), // #CCFF00 + new Color( 255, 255, 0), // #FFFF00 + new Color( 255, 204, 0), // #FFCC00 + new Color( 255, 153, 0), // #FF9900 + new Color( 255, 102, 0), // #FF6600 + new Color( 255, 51, 0), // #FF3300 + new Color( 255, 34, 0) // #FF2000 + }; + + + IdentityHashMap seqMap; + /** + * the color scheme needs to look at the alignment to get and cache T-COFFEE scores + * + * @param alignment - annotated sequences to be searched + */ + public TCoffeeColourScheme(AnnotatedCollectionI alignment) { + alignmentChanged(alignment); + } + @Override public void alignmentChanged(AnnotatedCollectionI alignment) + { + // assume only one set of TCOFFEE scores - but could have more than one potentially. + ArrayList annots = new ArrayList(); + // Search alignment to get all tcoffee annotation and pick one set of annotation to use to colour seqs. + seqMap = new IdentityHashMap(); + for (AlignmentAnnotation al:alignment.getAlignmentAnnotation()) + { + if (al.sequenceRef!=null && !al.belowAlignment && al.label!=null && (al.label==TCoffeeScoreFile.TCOFFEE_SCORE || al.label.equals(TCoffeeScoreFile.TCOFFEE_SCORE))) + { + annots.add(al); + Color[] scores=new Color[al.annotations.length]; + int i=0; + for (Annotation an:al.annotations) + { + scores[i++]=(an!=null) ? an.colour : Color.white; + } + seqMap.put(al.sequenceRef, scores); + } + } + } + @Override + public Color findColour(char c, int j, SequenceI seq) { + Color[] cols; + + if( seqMap==null || (cols=seqMap.get(seq))==null) { + return Color.white; + } + + if( j < 0 || j>= cols.length ) { + return Color.white; + } + return cols[j]; + } +} diff --git a/src/jalview/schemes/UserColourScheme.java b/src/jalview/schemes/UserColourScheme.java index 5034134..cdc618e 100755 --- a/src/jalview/schemes/UserColourScheme.java +++ b/src/jalview/schemes/UserColourScheme.java @@ -17,9 +17,9 @@ */ package jalview.schemes; -import java.util.*; - -import java.awt.*; +import java.awt.Color; +import java.util.StringTokenizer; +import jalview.datamodel.SequenceI; public class UserColourScheme extends ResidueColourScheme { @@ -201,7 +201,8 @@ public class UserColourScheme extends ResidueColourScheme } - public Color findColour(char c, int j) + @Override + public Color findColour(char c, int j, SequenceI seq) { Color currentColour; int index = ResidueProperties.aaIndex[c]; diff --git a/test/jalview/io/TCoffeeScoreFileTest.java b/test/jalview/io/TCoffeeScoreFileTest.java new file mode 100644 index 0000000..7257e14 --- /dev/null +++ b/test/jalview/io/TCoffeeScoreFileTest.java @@ -0,0 +1,152 @@ +package jalview.io; + +import static org.junit.Assert.*; +import jalview.io.TCoffeeScoreFile.Block; +import jalview.io.TCoffeeScoreFile.Header; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.List; + +import org.junit.Test; + +public class TCoffeeScoreFileTest { + + final static File SCORE_FILE = new File("./test/jalview/io/tcoffee.score_ascii"); + + @Test + public void testReadHeader() throws FileNotFoundException { + + Header header = TCoffeeScoreFile.readHeader( new BufferedReader(new FileReader(SCORE_FILE)) ); + assertNotNull(header); + assertEquals( "T-COFFEE, Version_9.02.r1228 (2012-02-16 18:15:12 - Revision 1228 - Build 336)", header.head ); + assertEquals( 90, header.score ); + assertEquals( 89, header.getScoreFor("1PHT") ); + assertEquals( 90, header.getScoreFor("1BB9") ); + assertEquals( 94, header.getScoreFor("1UHC") ); + assertEquals( 94, header.getScoreFor("1YCS") ); + assertEquals( 93, header.getScoreFor("1OOT") ); + assertEquals( 94, header.getScoreFor("1ABO") ); + assertEquals( 94, header.getScoreFor("1FYN") ); + assertEquals( 94, header.getScoreFor("1QCF") ); + assertEquals( 90, header.getScoreFor("cons") ); + } + + + @Test + public void testWrongFile() { + TCoffeeScoreFile result = TCoffeeScoreFile.load(new File("./test/jalview/io/tcoffee.fasta_aln")); + assertNull(result); + } + + @Test + public void testHeightAndWidth() { + TCoffeeScoreFile result = TCoffeeScoreFile.load(new File("./test/jalview/io/tcoffee.score_ascii")); + assertNotNull(result); + assertEquals( 8, result.getHeight() ); + assertEquals( 83, result.getWidth() ); + } + + @Test + public void testReadBlock( ) throws IOException { + + String BLOCK = "\n" + + "\n" + + "\n" + + "1PHT 999999999999999999999999998762112222543211112134\n" + + "1BB9 99999999999999999999999999987-------4322----2234 \n" + + "1UHC 99999999999999999999999999987-------5321----2246\n" + + "1YCS 99999999999999999999999999986-------4321----1-35\n" + + "1OOT 999999999999999999999999999861-------3------1135 \n" + + "1ABO 99999999999999999999999999986-------422-------34\n" + + "1FYN 99999999999999999999999999985-------32--------35\n" + + "1QCF 99999999999999999999999999974-------2---------24\n" + + "cons 999999999999999999999999999851000110321100001134\n" + + "\n" + + "\n"; + + Block block = TCoffeeScoreFile.readBlock(new BufferedReader(new StringReader(BLOCK)), 0); + assertNotNull(block); + assertEquals( "999999999999999999999999998762112222543211112134", block.getScoresFor("1PHT") ); + assertEquals( "99999999999999999999999999987-------4322----2234", block.getScoresFor("1BB9") ); + assertEquals( "99999999999999999999999999987-------5321----2246", block.getScoresFor("1UHC") ); + assertEquals( "99999999999999999999999999986-------4321----1-35", block.getScoresFor("1YCS") ); + assertEquals( "999999999999999999999999999861-------3------1135", block.getScoresFor("1OOT") ); + assertEquals( "99999999999999999999999999986-------422-------34", block.getScoresFor("1ABO") ); + assertEquals( "99999999999999999999999999985-------32--------35", block.getScoresFor("1FYN") ); + assertEquals( "99999999999999999999999999974-------2---------24", block.getScoresFor("1QCF") ); + assertEquals( "999999999999999999999999999851000110321100001134", block.getConsensus() ); + } + + @Test + public void testParse() throws FileNotFoundException { + + TCoffeeScoreFile parser = TCoffeeScoreFile.load(new BufferedReader(new FileReader(SCORE_FILE)) ); + + assertEquals( "999999999999999999999999998762112222543211112134----------5666642367889999999999889", parser.getScoresFor("1PHT") ); + assertEquals( "99999999999999999999999999987-------4322----22341111111111676653-355679999999999889", parser.getScoresFor("1BB9") ); + assertEquals( "99999999999999999999999999987-------5321----2246----------788774--66789999999999889", parser.getScoresFor("1UHC") ); + assertEquals( "99999999999999999999999999986-------4321----1-35----------78777--356789999999999889", parser.getScoresFor("1YCS") ); + assertEquals( "999999999999999999999999999861-------3------1135----------78877--356789999999997-67", parser.getScoresFor("1OOT") ); + assertEquals( "99999999999999999999999999986-------422-------34----------687774--56779999999999889", parser.getScoresFor("1ABO") ); + assertEquals( "99999999999999999999999999985-------32--------35----------6888842356789999999999889", parser.getScoresFor("1FYN") ); + assertEquals( "99999999999999999999999999974-------2---------24----------6878742356789999999999889", parser.getScoresFor("1QCF") ); + assertEquals( "99999999999999999999999999985100011032110000113400100000006877641356789999999999889", parser.getScoresFor("cons") ); + } + + + @Test + public void testGetAsList() throws FileNotFoundException { + + TCoffeeScoreFile parser = TCoffeeScoreFile.load(new BufferedReader(new FileReader(SCORE_FILE)) ); + + List scores = parser.getScoresList(); + assertEquals( "999999999999999999999999998762112222543211112134----------5666642367889999999999889", scores.get(0) ); + assertEquals( "99999999999999999999999999987-------4322----22341111111111676653-355679999999999889", scores.get(1) ); + assertEquals( "99999999999999999999999999987-------5321----2246----------788774--66789999999999889", scores.get(2) ); + assertEquals( "99999999999999999999999999986-------4321----1-35----------78777--356789999999999889", scores.get(3) ); + assertEquals( "999999999999999999999999999861-------3------1135----------78877--356789999999997-67", scores.get(4) ); + assertEquals( "99999999999999999999999999986-------422-------34----------687774--56779999999999889", scores.get(5) ); + assertEquals( "99999999999999999999999999985-------32--------35----------6888842356789999999999889", scores.get(6) ); + assertEquals( "99999999999999999999999999974-------2---------24----------6878742356789999999999889", scores.get(7) ); + assertEquals( "99999999999999999999999999985100011032110000113400100000006877641356789999999999889", scores.get(8) ); + + } + + + @Test + public void testGetAsArray() throws FileNotFoundException { + + TCoffeeScoreFile parser = TCoffeeScoreFile.load(new BufferedReader(new FileReader(SCORE_FILE)) ); + + byte[][] scores = parser.getScoresArray(); + + assertEquals( 9, scores[0][0] ); + assertEquals( 9, scores[1][0] ); + assertEquals( 9, scores[2][0] ); + assertEquals( 9, scores[3][0] ); + assertEquals( 9, scores[4][0] ); + assertEquals( 9, scores[5][0] ); + assertEquals( 9, scores[6][0] ); + assertEquals( 9, scores[7][0] ); + assertEquals( 9, scores[8][0] ); + + assertEquals( 5, scores[0][36] ); + assertEquals( 4, scores[1][36] ); + assertEquals( 5, scores[2][36] ); + assertEquals( 4, scores[3][36] ); + assertEquals( -1, scores[4][36] ); + assertEquals( 4, scores[5][36] ); + assertEquals( 3, scores[6][36] ); + assertEquals( 2, scores[7][36] ); + assertEquals( 3, scores[8][36] ); + + } + + + +} diff --git a/test/jalview/io/tcoffee.fasta_aln b/test/jalview/io/tcoffee.fasta_aln new file mode 100644 index 0000000..63b12b1 --- /dev/null +++ b/test/jalview/io/tcoffee.fasta_aln @@ -0,0 +1,24 @@ +>1PHT +YQYRALYDYKKEREEDIDLHLGDILTVNKGSLVALGFSDGQEARPEEI-- +--------GWLNGYNETTGERGDFPGTYVEYIG +>1BB9 +FKVQAQHDYTATDTDELQLKAGDVVLVIP-------FQNP----EEQDEG +WLMGVKESDWNQHK-ELEKCRGVFPENFTERVQ +>1UHC +QVYFAVYTFKARNPNELSVSANQKLKILE-------FKDV----TGNT-- +--------EWWLAE--VNGKKGYVPSNYIRKTE +>1YCS +GVIYALWDYEPQNDDELPMKEGDCMTIIH-------REDE----D-EI-- +--------EWWWA--RLNDKEGYVPRNLLGLYP +>1OOT +PKAVALYSFAGEESGDLPFRKGDVITILKK-------S------DSQN-- +--------DWWTG--RVNGREGIFPANYVE-LV +>1ABO +NLFVALYDFVASGDNTLSITKGEKLRVLG-------YNH-------NG-- +--------EWCEAQ--TKNGQGWVPSNYITPVN +>1FYN +TLFVALYDYEARTEDDLSFHKGEKFQILN-------SS--------EG-- +--------DWWEARSLTTGETGYIPSNYVAPVD +>1QCF +IIVVALYDYEAIHHEDLSFQKGDQMVVLE-------E---------SG-- +--------EWWKARSLATRKEGYIPSNYVARVD \ No newline at end of file diff --git a/test/jalview/io/tcoffee.score_ascii b/test/jalview/io/tcoffee.score_ascii new file mode 100644 index 0000000..2b533a3 --- /dev/null +++ b/test/jalview/io/tcoffee.score_ascii @@ -0,0 +1,37 @@ +T-COFFEE, Version_9.02.r1228 (2012-02-16 18:15:12 - Revision 1228 - Build 336) +Cedric Notredame +CPU TIME:0 sec. +SCORE=90 +* + BAD AVG GOOD +* +1PHT : 89 +1BB9 : 90 +1UHC : 94 +1YCS : 94 +1OOT : 93 +1ABO : 94 +1FYN : 94 +1QCF : 94 +cons : 90 + +1PHT 999999999999999999999999998762112222543211112134 +1BB9 99999999999999999999999999987-------4322----2234 +1UHC 99999999999999999999999999987-------5321----2246 +1YCS 99999999999999999999999999986-------4321----1-35 +1OOT 999999999999999999999999999861-------3------1135 +1ABO 99999999999999999999999999986-------422-------34 +1FYN 99999999999999999999999999985-------32--------35 +1QCF 99999999999999999999999999974-------2---------24 +cons 999999999999999999999999999851000110321100001134 + + +1PHT ----------5666642367889999999999889 +1BB9 1111111111676653-355679999999999889 +1UHC ----------788774--66789999999999889 +1YCS ----------78777--356789999999999889 +1OOT ----------78877--356789999999997-67 +1ABO ----------687774--56779999999999889 +1FYN ----------6888842356789999999999889 +1QCF ----------6878742356789999999999889 +cons 00100000006877641356789999999999889