+build
+buildPropertiesFile
+buildTests
+buildextclients
+buildindices
+castorbinding
+clean
+compileApplet
+distclean
help
+init
+linkcheck
+makeApplet
+makedist
+makefulldist
+obfuscate
+packageApplet
+prepare
+prepareTests
+preparejnlp
+prepubapplet_1
+pubapplet
+runenv
+signApplet
+sourcedist
+sourcedoc
+sourcescrub
+testclean
+testng
usage
+writejnlpf
<classpathentry kind="lib" path="lib/VARNAv3-93.jar"/>
<classpathentry kind="lib" path="lib/jfreesvg-2.1.jar"/>
<classpathentry kind="lib" path="lib/quaqua-filechooser-only-8.0.jar"/>
- <classpathentry kind="lib" path="lib/VAqua4.jar"/>
+ <classpathentry kind="lib" path="lib/VAqua5-patch.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin"/>
<classpathentry kind="lib" path="lib/xml-apis.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
The people listed below are 'The Jalview Authors', who collectively
own the copyright to the Jalview source code and permit it to be released under GPL.
-This is the authoritative list. It was correct on 23rd November 2016.
+This is the authoritative list: it was correct on 5th September 2018 (or the last commit date!)
+
If you are releasing a version of Jalview, please make sure any
statement of authorship in the GUI reflects the list shown here.
In particular, check the resources/authors.props file !
Jim Procter
Mungo Carstairs
-Tochukwu 'Charles' Ofoegbu
+Ben Soares
Kira Mourao
+Tochukwu 'Charles' Ofoegbu
Andrew Waterhouse
Jan Engelhardt
Lauren Lui
##################
-To run application:
+To run application...
+[ NOTE: when using the -classpath option with the '*' wildcard, the argument must be quoted to avoid shell expansion of the wildcard,
+ ALSO, the wildcard MUST be as DIR/* and not DIR/*.jar etc or it will not be interpreted correctly ]
-java -Djava.ext.dirs=JALVIEW_HOME/lib -cp JALVIEW_HOME/jalview.jar jalview.bin.Jalview
+on Windows use:
+ java -classpath "JALVIEW_HOME/lib/*;JALVIEW_HOME/jalview.jar" jalview.bin.Jalview
+and on MacOS or Linux:
+ java -classpath "JALVIEW_HOME/lib/*:JALVIEW_HOME/jalview.jar" jalview.bin.Jalview
Replace JALVIEW_HOME with the full path to Jalview Installation Directory. If building from source:
-java -Djava.ext.dirs=JALVIEW_BUILD/dist -cp JALVIEW_BUILD/dist/jalview.jar jalview.bin.Jalview
+ java -classpath "JALVIEW_BUILD/dist/*" jalview.bin.Jalview
##################
quaqua: v.8.0 (latest stable) by Randel S Hofer. LGPL and BSD Modified license: downloaded from http://www.randelshofer.ch/quaqua/
-vaqua: v4 (latest stable) by Alan Snyder et al. GPLv2 with Classpathe xception, also includes contributions from Quaqua: ownloaded from http://violetlib.org/vaqua/overview.html
+vaqua5-patch: This is a patched version of VAqua v5 (latest stable) by Alan Snyder et al. GPLv3 with Classpath exception, also includes contributions from Quaqua: http://violetlib.org/vaqua/overview.html - see doc/patching-vaqua.txt for patch details, and http://issues.jalview.org/browse/JAL-2988 for details of the bug that the patch addresses.
-lib/htsjdk-1.120-SNAPSHOT.jar: (currently not required for 2.10) built from maven master at https://github.com/samtools/htsjdk MIT License to Broad Institute
+lib/htsjdk-2.12.jar: built from maven master at https://github.com/samtools/htsjdk MIT License to Broad Institute
lib/biojava-core-4.1.0.jar LGPLv2.1 - latest license at https://github.com/biojava/biojava/blob/master/LICENSE
</jar>
<antcall target="writejnlpf">
- <param name="jnlpFile" value="${packageDir}/jalview.jnlp" />
+ <param name="jnlpFile" value="${packageDir}/jalview_256M.jnlp" />
<param name="inih" value="10M" />
<param name="maxh" value="256M" />
</antcall>
+ <antcall target="writejnlpf">
+ <param name="jnlpFile" value="${packageDir}/jalview.jnlp" />
+ <param name="inih" value="800M" />
+ <param name="maxh" value="1024M" />
+ </antcall>
<antcall target="writejnlpf">
<param name="jnlpFile" value="${packageDir}/jalview_1G.jnlp" />
<antcall target="writejnlpf">
<param name="jnlpFile" value="${packageDir}/jalview_2G.jnlp" />
- <param name="inih" value="256M" />
+ <param name="inih" value="800M" />
<param name="maxh" value="1024M" />
</antcall>
<association mime-type="application-x/ext-file" extensions="jar"/>-->
</target>
- <target name="-jarsignwithtsa" depends="makedist,preparejnlp" if="timestamp">
+ <target name="-jarsignwithtsa" depends="makedist,preparejnlp" if="timestamp" unless="nosign">
<signjar storepass="${jalview.keystore.pass}" keypass="${jalview.key.pass}" keystore="${jalview.keystore}" alias="${jalview.key}" lazy="false" verbose="false" sigalg="${jalview.keyalg}" digestalg="${jalview.keydig}"
tsaproxyhost="${proxyHost}" tsaproxyport="${proxyPort}" tsaurl="${jalview.tsaurl}">
<fileset dir="${packageDir}">
</fileset>
</signjar>
</target>
- <target name="-jarsignnotsa" depends="makedist,preparejnlp" unless="timestamp">
+ <target name="-jarsignnotsa" depends="makedist,preparejnlp" if:blank="timestamp" unless="nosign">
<signjar storepass="${jalview.keystore.pass}" keypass="${jalview.key.pass}" keystore="${jalview.keystore}" alias="${jalview.key}" lazy="false" verbose="false" sigalg="${jalview.keyalg}" digestalg="${jalview.keydig}">
<fileset dir="${packageDir}">
<include name="*.jar" />
<include name="ap_${jsonSimple}" />
</fileset>
</target>
-<target name="-signappletnotsa" unless="timestamp" depends="-signapplet">
+<target name="-signappletnotsa" if:blank="timestamp" depends="-signapplet" unless="nosign">
<signjar storepass="${jalview.keystore.pass}" keypass="${jalview.key.pass}" keystore="${jalview.keystore}" alias="${jalview.key}" lazy="false" verbose="false">
<fileset refid="signappletjarset" />
</signjar>
</target>
-<target name="-signapplettsa" if="timestamp" depends="-signapplet">
+<target name="-signapplettsa" if="timestamp" depends="-signapplet" unless="nosign">
<signjar storepass="${jalview.keystore.pass}" keypass="${jalview.key.pass}" keystore="${jalview.keystore}" alias="${jalview.key}" lazy="false" verbose="false" tsaproxyhost="${proxyHost}" tsaproxyport="${proxyPort}" tsaurl="${jalview.tsaurl}">
<fileset refid="signappletjarset" />
</signjar>
--- /dev/null
+VAqua5-patched.jar - how the patch was created
+
+1. Download VAqua5 source from https://violetlib.org/release/vaqua/5/VAqua5Source.zip
+2. Unzip to a directory and apply this patch
+
+diff --git a/src/org/violetlib/aqua/fc/AquaFileChooserUI.java b/src/org/violetlib/aqua/fc/AquaFileChooserUI.java
+index 833366d..61f66e5 100644
+--- a/src/org/violetlib/aqua/fc/AquaFileChooserUI.java
++++ b/src/org/violetlib/aqua/fc/AquaFileChooserUI.java
+@@ -1171,7 +1171,8 @@ public class AquaFileChooserUI extends BasicFileChooserUI {
+ goToFolderCancelButtonText = getString("FileChooser.goToFolderCancelButtonText", l, "Cancel");
+ goToFolderAcceptButtonText = getString("FileChooser.goToFolderAcceptButtonText", l, "Accept");
+ goToFolderErrorText = getString("FileChooser.goToFolderErrorText", l, "The folder can\u2019t be found.");
+- defaultInitialSaveFileName = getString("FileChooser.defaultSaveFileName", l, "Untitled");
++ // Don't set an initial filename for saving (or loading) !
++ // defaultInitialSaveFileName = getString("FileChooser.defaultSaveFileName", l, "Untitled");
+ }
+
+ /**
+
+3. Ensure XCode is installed, along with command line tools and the OSX developer packs
+ - you should have /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
+
+4. Download the VAqua rendering library from violetlib.org and save to the VAqua source's lib folder as lib/VAquaRendering.jar
+
+5. change to the release directory and execute 'ant' - a few warnings are generated but providing a final jar is created, all is good!
+
--- /dev/null
+# STOCKHOLM 1.0
+#=GF ID RNA.SS.TEST
+#=GF TP RNA;
+Test.sequence GUACAAAAAAAAAA
+#=GC SS_cons <(EHBheb(E)e)>
+//
SEQUENCE_GROUP Group_B 1 351 2-5
SEQUENCE_GROUP Group_C 12 14 -1 seq1 seq2 seq3
PROPERTIES Group_A description=This is the description colour=Helix Propensity pidThreshold=0 outlineColour=red displayBoxes=true displayText=false colourText=false textCol1=black textCol2=black textColThreshold=0
-PROPERTIES Group_B outlineColour=red colour=None
+PROPERTIES Group_B outlineColour=green colour=None
PROPERTIES Group_C colour=Clustal
provided by InstallAnywhere any output from the application will be
sent to output.txt, not standard out.<br> The Jalview
application also requires a number of additional libraries on the
- class path. The command line below adds the Jalview installation's
- 'lib' directory to the list of directories that are searched for
- jars to be added to the classpath:
+ class path. The command line below adds all the jar files in the
+ Jalview installation's 'lib' directory to the classpath, as well as
+ the Jalview application jar file:
</p>
- <pre>java -Djava.ext.dirs=$INSTALL_DIR$/lib -cp $INSTALL_DIR$/jalview.jar jalview.bin.Jalview -open [FILE] </pre>
+ <pre>java -classpath "$INSTALL_DIR$/lib/*:$INSTALL_DIR$/jalview.jar" jalview.bin.Jalview -open [FILE] </pre>
<p>
Use '-help' to get more information on the <a
href="clarguments.html">command line arguments</a> that
! <string>-Xms2M</string>
! <string>-Xmx64M</string>
</array>
-</pre> Exchange the above two string tags for : <pre>
+</pre>Exchange the above two string tags for : <pre>
<string>-Xms500M</string>
<string>-Xmx1000M</string>
</pre>
the file and try to start Jalview in the normal way. If it doesn't
start, see below...</li>
</ul>
+ <p>
+ <em>Please Note:</em> We do modify the default memory settings in
+ Jalview from time to time, so you may find different numbers to
+ those shown in the examples above.
+ </p>
<font size="3"><em>Jalview doesn't start... What do the
memory settings mean ?<a name="memsetting"></a>
</em></font>
enlighten us if you know better!). Our experiments found 1000m to be
the biggest setting that could be used on a 1GB machine. Just try
reducing the sizes until Jalview starts up properly!</p>
+ <p>
+ We increased the default memory in Jalview 2.10.5 to 1G. To launch
+ Jalview with the pre 2.10.5 default memory allocation, use the <a
+ href="http://www.jalview.org/webstart/jalview_256MB.jnlp">Jalview
+ 256MB JNLP</a>.
+ </p>
<p> </p>
</body>
</html>
</div></td>
</tr>
<tr>
+ <td width="60" nowrap>
+ <div align="center">
+ <strong><a name="Jalview.2.10.5">2.10.5</a><br /> <em>10/09/2018</em></strong>
+ </div>
+ </td>
+ <td><div align="left">
+ <em></em>
+ <ul>
+ <li>
+ <!-- JAL-3101 -->Default memory for Jalview webstart and
+ InstallAnywhere increased to 1G.
+ </li>
+ <li>
+ <!-- JAL-247 -->Hidden sequence markers and representative
+ sequence bolding included when exporting alignment as EPS,
+ SVG, PNG or HTML. <em>Display is configured via the
+ Format menu, or for command-line use via a jalview
+ properties file.</em>
+ </li>
+ <li>
+ <!-- JAL-3076 -->Ensembl client updated to Version 7 REST
+ API and sequence data now imported as JSON.
+ </li>
+ <li>
+ <!-- JAL-3065 -->Change in recommended way of starting
+ Jalview via a Java command line: add jars in lib directory
+ to CLASSPATH, rather than via the deprecated java.ext.dirs
+ property.
+ </li>
+ </ul>
+ <em>Development</em>
+ <ul>
+ <li>
+ <!-- JAL-3047 -->Support added to execute test suite
+ instrumented with <a href="http://openclover.org/">Open
+ Clover</a>
+ </li>
+ </ul>
+ </div></td>
+ <td><div align="left">
+ <em></em>
+ <ul>
+ <li>
+ <!-- JAL-3104 -->Poorly scaled bar in quality annotation
+ row shown in Feredoxin Structure alignment view of example
+ alignment.
+ </li>
+ <li>
+ <!-- JAL-2854 -->Annotation obscures sequences if lots of
+ annotation displayed.
+ </li>
+ <li>
+ <!-- JAL-3107 -->Group conservation/consensus not shown
+ for newly created group when 'Apply to all groups'
+ selected
+ </li>
+ <li>
+ <!-- JAL-3087 -->Corrupted display when switching to
+ wrapped mode when sequence panel's vertical scrollbar is
+ visible.
+ </li>
+ <li>
+ <!-- JAL-3003 -->Alignment is black in exported EPS file
+ when sequences are selected in exported view.</em>
+ </li>
+ <li>
+ <!-- JAL-3059 -->Groups with different coloured borders
+ aren't rendered with correct colour.
+ </li>
+ <li>
+ <!-- JAL-3092 -->Jalview could hang when importing certain
+ types of knotted RNA secondary structure.
+ </li>
+ <li>
+ <!-- JAL-3095 -->Sequence highlight and selection in
+ trimmed VARNA 2D structure is incorrect for sequences that
+ do not start at 1.
+ </li>
+ <li>
+ <!-- JAL-3061 -->'.' inserted into RNA secondary structure
+ annotation when columns are inserted into an alignment,
+ and when exporting as Stockholm flatfile.
+ </li>
+ <li>
+ <!-- JAL-3053 -->Jalview annotation rows containing upper
+ and lower-case 'E' and 'H' do not automatically get
+ treated as RNA secondary structure.
+ </li>
+ <li>
+ <!-- JAL-3106 -->.jvp should be used as default extension
+ (not .jar) when saving a jalview project file.
+ </li>
+ <li>
+ <!-- JAL-3105 -->Mac Users: closing a window correctly
+ transfers focus to previous window on OSX
+ </li>
+ </ul>
+ <em>Java 10 Issues Resolved</em>
+ <ul>
+ <li>
+ <!-- JAL-2988 -->OSX - Can't save new files via the File
+ or export menus by typing in a name into the Save dialog
+ box.
+ </li>
+ <li>
+ <!-- JAL-2988 JAL-2968 -->Jalview now uses patched version
+ of the <a href="https://violetlib.org/vaqua/overview.html">VAqua5</a>
+ 'look and feel' which has improved compatibility with the
+ latest version of OSX.
+ </li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
<td width="60" nowrap>
<div align="center">
<strong><a name="Jalview.2.10.4b1">2.10.4b1</a><br />
- <em>27/05/2018</em></strong>
+ <em>7/06/2018</em></strong>
</div>
</td>
<td><div align="left">
<em></em>
<ul>
<li>
+ <!-- JAL-2920 -->Use HGVS nomenclature for variant
+ annotation retrieved from Uniprot
+ </li>
+ <li>
<!-- JAL-1460 -->Windows File Shortcuts can be dragged
onto the Jalview Desktop
</li>
<em></em>
<ul>
<li>
+ <!-- JAL-3017 -->Cannot import features with multiple
+ variant elements (blocks import of some Uniprot records)
+ </li>
+ <li>
<!-- JAL-2997 -->Clustal files with sequence positions in
right-hand column parsed correctly
</li>
<li>
+ <!-- JAL-2991 -->Wrap view - export to SVG - IDs shown but
+ not alignment area in exported graphic
+ </li>
+ <li>
<!-- JAL-2993 -->F2/Keyboard mode edits work when Overview
window has input focus
</li>
<li>
- <!-- JAL-2991 -->Wrap view - export to SVG - IDs shown but
- not alignment area in exported graphic
+ <!-- JAL-2992 -->Annotation panel set too high when
+ annotation added to view (Windows)
+ </li>
+ <li>
+ <!-- JAL-3009 -->Jalview Desktop is slow to start up when
+ network connectivity is poor
</li>
<li>
<!-- JAL-1460 -->Drag URL from chrome, firefox, IE to
- Jalview desktop on Windows doesn't open file<br />
- <em>Dragging the currently open URL and links from a page viewed in Firefox or Chrome on
- Windows is now fully supported. If you are using Edge, only
- links in the page can be dragged, and with Internet Explorer, only
- the currently open URL in the browser can be dropped onto
- Jalview.</em>
- </li>
- <li>
- <!-- JAL-2992 -->
+ Jalview desktop on Windows doesn't open file<br /> <em>Dragging
+ the currently open URL and links from a page viewed in
+ Firefox or Chrome on Windows is now fully supported. If
+ you are using Edge, only links in the page can be
+ dragged, and with Internet Explorer, only the currently
+ open URL in the browser can be dropped onto Jalview.</em>
</li>
</ul>
</div></td>
</head>
<body>
<p>
- <strong>What's new in Jalview 2.10.4 ?</strong>
- </p>
- <p>
- This is the May 2018 release of Jalview, and the last in the 2.10.x series. Jalview 2.10.4 includes:
+ <strong>What's new in Jalview 2.10.5 ?</strong>
</p>
+ <p>Jalview 2.10.5 is a minor release that includes critical
+ patches for users working with Ensembl, RNA secondary structure
+ annotation, and those running Jalview on OSX with Java 10.</p>
<ul>
- <li>Numerous efficiency improvements in the renderer and overview when working with large alignments with lots of hidden columns</li>
- <li>Use of HTTPS when connecting to Uniprot, Ensembl and other EBI web services</li>
- <li>Critical patches for running Jalview on OSX with Java 10</li>
- <li>Easier adjustment of the Alignment ID panel and Annotation panel</li>
- <li>Improved support for mapping between 3D Structures and Uniprot Protein Sequences</li>
- <li>Improved support for discovering CDS and transcripts for Proteins and Ensembl gene IDs</li>
- <li>New buttons on the Structure Chooser for adding structures
- to an existing view, and disabling automatic superposition
- according to linked alignments</li>
- <li>Annotation transfer between Chimera and Jalview <em>(formerly only
- available in 'Experimental' mode)</em></li>
+ <li>Jalview's default memory limit increased to 1G. <br/>If you have
+ problems starting Jalview 2.10.5 and you have 1G or less
+ physical memory on your machine, you will need to <a
+ href="memory.html#memsetting">reduce the memory</a> allocated to
+ Jalview.
+ </li>
+ <li>EPS, PNG and SVG export now includes hidden sequence
+ markers, and representative sequences are marked in bold.</li>
+ <li>Ensembl Client updated for Ensembl Rest API v7.<br />The
+ latest Ensembl API is not backwards compatible with earlier
+ versions of Jalview, so if you require Ensembl functionality you
+ will need to install this release.
+ </li>
+ <li>Improved support for VIENNA extended dot-bracket notation
+ for RNA secondary structure.</li>
+ <li>Positional and selected region highlighting in VARNA
+ 'trimmed sequence' view made more reliable.</li>
</ul>
<p>
- The full list of bugs fixed in this release can be found in the <a href="releases.html#Jalview.2.10.4">2.10.4
- Release Notes</a>.
+ The full list of bugs fixed in this release can be found in the <a
+ href="releases.html#Jalview.2.10.5">2.10.5 Release Notes</a>. The
+ majority of bug fixes and improvements in 2.10.5 are due to Jalview users
+ contacting us via the jalview-discuss email list. Thanks to everyone
+ who took the time to help make Jalview better !
+ </p>
+ <p>
+ <strong>Jalview and Java 10</strong>
</p>
+ <p>This release addresses a critical bug for OSX users who are
+ running Jalview with Java 10 which can prevent files being saved
+ correctly through the 'Save As' dialog box.</p>
+ <em>Known Issues</em>
+ <ul>
+ <li>OSX: The 'Open File' dialog for Jalview's Groovy Console
+ appears with the title 'Save As', and attempting to select a file to load yields a FileNotFound exception.</br>The workaround is to first clear the 'Untitled' filename before selecting the file you wish to load.
+ </li>
+ <li>OSX: Links don't open when clicked on or via the Sequence or Alignment window popup menu.</li>
+ <li>OSX (Webstart): Jalview only displays old news feed items</li>
+ </ul>
</body>
</html>
-YEAR=2016
-AUTHORS=J Procter, M Carstairs, TC Ofoegbu, K Mourao, AM Waterhouse, J Engelhardt, LM Lui, A Menard, D Barton, N Sherstnev, D Roldan-Martinez, M Clamp, S Searle, G Barton
-AUTHORFNAMES=Jim Procter, Mungo Carstairs, Tochukwu 'Charles' Ofoegbu, Kira Mourao, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Anne Menard, Daniel Barton, Natasha Sherstnev, David Roldan-Martinez, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+YEAR=2018
+AUTHORS=J Procter, M Carstairs, B Soares, K Mourao, TC Ofoegbu, AM Waterhouse, J Engelhardt, LM Lui, A Menard, D Barton, N Sherstnev, D Roldan-Martinez, M Clamp, S Searle, G Barton
+AUTHORFNAMES=Jim Procter, Mungo Carstairs, Ben Soares, Kira Mourao, Tochukwu 'Charles' Ofoegbu, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Anne Menard, Daniel Barton, Natasha Sherstnev, David Roldan-Martinez, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
\ No newline at end of file
* The Jalview Authors are detailed in the 'AUTHORS' file.
-->
<mapping>
+ <!-- see https://www.uniprot.org/docs/uniprot.xsd for latest Uniprot XML schema -->
<class name="jalview.datamodel.xdb.uniprot.UniprotFile">
<map-to xml="uniprot"/>
<field name="UniprotEntries" type="jalview.datamodel.xdb.uniprot.UniprotEntry" collection="vector">
<field name="end">
<bind-xml name="position" node="attribute" location="location/end"/>
</field>
- <field name="variation">
+ <field name="variation" collection="vector" type="string">
<bind-xml name="variation"/>
</field>
<field name="original">
* or not conserved (-1)
* Using TreeMap means properties are displayed in alphabetical order
*/
- SortedMap<String, Integer> resultHash = new TreeMap<String, Integer>();
+ SortedMap<String, Integer> resultHash = new TreeMap<>();
SymbolCounts symbolCounts = values.getSymbolCounts();
char[] symbols = symbolCounts.symbols;
int[] counts = symbolCounts.values;
*/
private void percentIdentity(ScoreMatrix sm)
{
- seqNums = new Vector<int[]>();
+ seqNums = new Vector<>();
int i = 0, iSize = sequences.length;
// Do we need to calculate this again?
for (i = 0; i < iSize; i++)
protected void findQuality(int startCol, int endCol,
ScoreMatrix scoreMatrix)
{
- quality = new Vector<Double>();
+ quality = new Vector<>();
double max = -Double.MAX_VALUE;
float[][] scores = scoreMatrix.getMatrix();
/**
* Complete the given consensus and quuality annotation rows. Note: currently
- * this method will enlarge the given annotation row if it is too small,
- * otherwise will leave its length unchanged.
+ * this method will reallocate the given annotation row if it is different to
+ * the calculated width, otherwise will leave its length unchanged.
*
* @param conservation
* conservation annotation row
float qmax = 0f;
if (conservation != null && conservation.annotations != null
- && conservation.annotations.length < alWidth)
+ && conservation.annotations.length != alWidth)
{
conservation.annotations = new Annotation[alWidth];
}
{
quality2.graphMax = (float) qualityMaximum;
if (quality2.annotations != null
- && quality2.annotations.length < alWidth)
+ && quality2.annotations.length != alWidth)
{
quality2.annotations = new Annotation[alWidth];
}
/*
* catch things like <<..<<..>>..<<..>>>> |
*/
- int j = bps.size() - 1;
- while (j >= 0)
+ int j = bps.size();
+ while (--j >= 0)
{
int popen = bps.get(j).getBP5();
break;
}
}
- j -= 1;
}
// Put positions and helix information into the hashtable
/**
* Main class for Jalview Application <br>
* <br>
- * start with java -Djava.ext.dirs=$PATH_TO_LIB$ jalview.bin.Jalview
+ * start with: java -classpath "$PATH_TO_LIB$/*:$PATH_TO_CLASSES$" \
+ * jalview.bin.Jalview
+ *
+ * or on Windows: java -classpath "$PATH_TO_LIB$/*;$PATH_TO_CLASSES$" \
+ * jalview.bin.Jalview jalview.bin.Jalview
+ *
+ * (ensure -classpath arg is quoted to avoid shell expansion of '*' and do not
+ * embellish '*' to e.g. '*.jar')
*
* @author $author$
* @version $Revision$
{
error.printStackTrace();
System.out.println("\nEssential logging libraries not found."
- + "\nUse: java -Djava.ext.dirs=$PATH_TO_LIB$ jalview.bin.Jalview");
+ + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
System.exit(0);
}
import jalview.analysis.WUSSParseException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
}
/**
+ * Get the RNA Secondary Structure SequenceFeature Array if present
+ */
+ public SequenceFeature[] getRnaSecondaryStructure()
+ {
+ return this._rnasecstr;
+ }
+
+ /**
+ * Check the RNA Secondary Structure is equivalent to one in given
+ * AlignmentAnnotation param
+ */
+ public boolean rnaSecondaryStructureEquivalent(AlignmentAnnotation that)
+ {
+ return rnaSecondaryStructureEquivalent(that, true);
+ }
+
+ public boolean rnaSecondaryStructureEquivalent(AlignmentAnnotation that, boolean compareType)
+ {
+ SequenceFeature[] thisSfArray = this.getRnaSecondaryStructure();
+ SequenceFeature[] thatSfArray = that.getRnaSecondaryStructure();
+ if (thisSfArray == null || thatSfArray == null)
+ {
+ return thisSfArray == null && thatSfArray == null;
+ }
+ if (thisSfArray.length != thatSfArray.length)
+ {
+ return false;
+ }
+ Arrays.sort(thisSfArray, new SFSortByEnd()); // probably already sorted
+ // like this
+ Arrays.sort(thatSfArray, new SFSortByEnd()); // probably already sorted
+ // like this
+ for (int i=0; i < thisSfArray.length; i++) {
+ SequenceFeature thisSf = thisSfArray[i];
+ SequenceFeature thatSf = thatSfArray[i];
+ if (compareType) {
+ if (thisSf.getType() == null || thatSf.getType() == null) {
+ if (thisSf.getType() == null && thatSf.getType() == null) {
+ continue;
+ } else {
+ return false;
+ }
+ }
+ if (! thisSf.getType().equals(thatSf.getType())) {
+ return false;
+ }
+ }
+ if (!(thisSf.getBegin() == thatSf.getBegin()
+ && thisSf.getEnd() == thatSf.getEnd()))
+ {
+ return false;
+ }
+ }
+ return true;
+
+ }
+
+ /**
* map of positions in the associated annotation
*/
private Map<Integer, Annotation> sequenceMapping;
char firstChar = 0;
for (int i = 0; i < annotations.length; i++)
{
+ // DEBUG System.out.println(i + ": " + annotations[i]);
if (annotations[i] == null)
{
continue;
if (annotations[i].secondaryStructure == 'H'
|| annotations[i].secondaryStructure == 'E')
{
+ // DEBUG System.out.println( "/H|E/ '" +
+ // annotations[i].secondaryStructure + "'");
hasIcons |= true;
}
else
// Check for RNA secondary structure
{
- // System.out.println(annotations[i].secondaryStructure);
+ // DEBUG System.out.println( "/else/ '" +
+ // annotations[i].secondaryStructure + "'");
// TODO: 2.8.2 should this ss symbol validation check be a function in
// RNA/ResidueProperties ?
if (annotations[i].secondaryStructure == '('
|| annotations[i].secondaryStructure == 'B'
|| annotations[i].secondaryStructure == 'C'
|| annotations[i].secondaryStructure == 'D'
- || annotations[i].secondaryStructure == 'E'
+ // || annotations[i].secondaryStructure == 'E' // ambiguous on
+ // its own -- already checked above
|| annotations[i].secondaryStructure == 'F'
|| annotations[i].secondaryStructure == 'G'
- || annotations[i].secondaryStructure == 'H'
+ // || annotations[i].secondaryStructure == 'H' // ambiguous on
+ // its own -- already checked above
|| annotations[i].secondaryStructure == 'I'
|| annotations[i].secondaryStructure == 'J'
|| annotations[i].secondaryStructure == 'K'
// &&
// annotations[i].displayCharacter.charAt(0)==annotations[i].secondaryStructure
firstChar != ' ' && firstChar != '$' && firstChar != 0xCE
- && firstChar != '(' && firstChar != '[' && firstChar != '>'
+ && firstChar != '(' && firstChar != '[' && firstChar != '<'
&& firstChar != '{' && firstChar != 'A' && firstChar != 'B'
&& firstChar != 'C' && firstChar != 'D' && firstChar != 'E'
&& firstChar != 'F' && firstChar != 'G' && firstChar != 'H'
}
return aa;
}
+
}
return ((value == 0f)
&& ((description == null) || (description.trim().length() == 0))
&& ((displayCharacter == null)
- || (displayCharacter.trim().length() == 0))
+ || (displayCharacter.trim().length() == 0)
+ || (displayCharacter.equals(" ."))) // RNA Stockholm blank
+ // displayCharacter can
+ // end up like this
&& (secondaryStructure == '\0' || (secondaryStructure == ' '))
&& colour == null);
}
import jalview.datamodel.features.FeatureSources;
import jalview.util.StringUtils;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
source = theSource;
}
}
+
+class SFSortByEnd implements Comparator<SequenceFeature>
+{
+ @Override
+ public int compare(SequenceFeature a, SequenceFeature b)
+ {
+ return a.getEnd() - b.getEnd();
+ }
+}
+
+class SFSortByBegin implements Comparator<SequenceFeature>
+{
+ @Override
+ public int compare(SequenceFeature a, SequenceFeature b)
+ {
+ return a.getBegin() - b.getBegin();
+ }
+}
*/
package jalview.datamodel.xdb.uniprot;
+import java.util.Vector;
+
/**
* A data model class for binding from Uniprot XML via uniprot_mapping.xml
*/
private String original = null;
- private String variation = null;
+ private Vector<String> variation = null;
private String status;
public String getDescription()
{
- if (description == null && variation == null && original == null)
- {
- return null;
- }
- return (description == null ? "" : description)
- + (variation != null
- ? (description != null ? " " : "") + "Variation: '"
- + variation + "'"
- : "")
- + (original != null
- ? ((description != null || variation != null) ? " "
- : "") + "Original: '" + original + "'"
- : "");
+ return description;
}
public void setDescription(String d)
this.original = original;
}
- public String getVariation()
+ public Vector<String> getVariation()
{
return variation;
}
- public void setVariation(String variant)
+ public void setVariation(Vector<String> variant)
{
this.variation = variant;
}
{
if (avc.createGroup())
{
+ if (applyAutoAnnotationSettings.isSelected())
+ {
+ alignPanel.updateAnnotation(true, false);
+ }
alignPanel.alignmentChanged();
}
}
import jalview.structure.StructureSelectionManager;
import jalview.util.Comparison;
import jalview.util.MessageManager;
-import jalview.util.Platform;
import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Graphics2D;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentAdapter;
protected void validateAnnotationDimensions(boolean adjustPanelHeight)
{
int annotationHeight = getAnnotationPanel().adjustPanelHeight();
+ annotationHeight = getAnnotationPanel()
+ .adjustForAlignFrame(adjustPanelHeight, annotationHeight);
- if (adjustPanelHeight)
- {
- int rowHeight = av.getCharHeight();
- int alignmentHeight = rowHeight * av.getAlignment().getHeight();
-
- /*
- * Estimate available height in the AlignFrame for alignment +
- * annotations. Deduct an estimate for title bar, menu bar, scale panel,
- * hscroll, status bar, insets.
- */
- int stuff = Platform.isAMac() ? 120 : 140;
- int availableHeight = alignFrame.getHeight() - stuff;
-
- /*
- * If not enough vertical space, maximize annotation height while keeping
- * at least two rows of alignment visible
- */
- if (annotationHeight + alignmentHeight > availableHeight)
- {
- annotationHeight = Math.min(annotationHeight,
- availableHeight - 2 * rowHeight);
- }
- }
- else
- {
- // maintain same window layout whilst updating sliders
- annotationHeight = annotationScroller.getSize().height;
- }
hscroll.addNotify();
-
annotationScroller.setPreferredSize(
new Dimension(annotationScroller.getWidth(), annotationHeight));
{
annotationScroller.setVisible(true);
annotationSpaceFillerHolder.setVisible(true);
+ validateAnnotationDimensions(false);
}
int canvasWidth = getSeqPanel().seqCanvas.getWidth();
}
/**
- * DOCUMENT ME!
- *
- * @param pg
- * DOCUMENT ME!
- * @param pwidth
- * DOCUMENT ME!
- * @param pheight
- * DOCUMENT ME!
- * @param pi
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws PrinterException
- * DOCUMENT ME!
- */
- /**
* Draws the alignment image, including sequence ids, sequences, and
* annotation labels and annotations if shown, on either one or two Graphics
- * context.
+ * contexts.
*
* @param pageWidth
+ * in pixels
* @param pageHeight
- * @param pi
+ * in pixels
+ * @param pageIndex
+ * (0, 1, ...)
* @param idGraphics
* the graphics context for sequence ids and annotation labels
* @param alignmentGraphics
* @return
* @throws PrinterException
*/
- public int printUnwrapped(int pageWidth, int pageHeight, int pi,
+ public int printUnwrapped(int pageWidth, int pageHeight, int pageIndex,
Graphics idGraphics, Graphics alignmentGraphics)
throws PrinterException
{
: idWidth;
FontMetrics fm = getFontMetrics(av.getFont());
- int charHeight = av.getCharHeight();
- int scaleHeight = charHeight + fm.getDescent();
+ final int charHeight = av.getCharHeight();
+ final int scaleHeight = charHeight + fm.getDescent();
idGraphics.setColor(Color.white);
idGraphics.fillRect(0, 0, pageWidth, pageHeight);
/*
* How many sequences and residues can we fit on a printable page?
*/
- int totalRes = (pageWidth - idWidth) / av.getCharWidth();
+ final int totalRes = (pageWidth - idWidth) / av.getCharWidth();
- int totalSeq = (pageHeight - scaleHeight) / charHeight - 1;
+ final int totalSeq = (pageHeight - scaleHeight) / charHeight - 1;
- int alignmentWidth = av.getAlignment().getWidth();
- int pagesWide = (alignmentWidth / totalRes) + 1;
+ final int alignmentWidth = av.getAlignment().getWidth();
+ final int pagesWide = (alignmentWidth / totalRes) + 1;
- final int startRes = (pi % pagesWide) * totalRes;
- int endRes = (startRes + totalRes) - 1;
+ final int startRes = (pageIndex % pagesWide) * totalRes;
+ final int endRes = Math.min(startRes + totalRes - 1,
+ alignmentWidth - 1);
- if (endRes > (alignmentWidth - 1))
- {
- endRes = alignmentWidth - 1;
- }
-
- final int startSeq = (pi / pagesWide) * totalSeq;
- int endSeq = startSeq + totalSeq;
-
- int alignmentHeight = av.getAlignment().getHeight();
- if (endSeq > alignmentHeight)
- {
- endSeq = alignmentHeight;
- }
+ final int startSeq = (pageIndex / pagesWide) * totalSeq;
+ final int alignmentHeight = av.getAlignment().getHeight();
+ final int endSeq = Math.min(startSeq + totalSeq, alignmentHeight);
int pagesHigh = ((alignmentHeight / totalSeq) + 1) * pageHeight;
pagesHigh /= pageHeight;
- if (pi >= (pagesWide * pagesHigh))
+ if (pageIndex >= (pagesWide * pagesHigh))
{
return Printable.NO_SUCH_PAGE;
}
* then reset to top left (0, 0)
*/
idGraphics.translate(0, scaleHeight);
- idGraphics.setFont(getIdPanel().getIdCanvas().getIdfont());
- Color currentColor = null;
- Color currentTextColor = null;
-
- SequenceI seq;
- for (int i = startSeq; i < endSeq; i++)
- {
- seq = av.getAlignment().getSequenceAt(i);
- if ((av.getSelectionGroup() != null)
- && av.getSelectionGroup().getSequences(null).contains(seq))
- {
- /*
- * gray out ids of sequences in selection group (if any)
- */
- currentColor = Color.gray;
- currentTextColor = Color.black;
- }
- else
- {
- currentColor = av.getSequenceColour(seq);
- currentTextColor = Color.black;
- }
-
- idGraphics.setColor(currentColor);
- idGraphics.fillRect(0, (i - startSeq) * charHeight, idWidth,
- charHeight);
-
- idGraphics.setColor(currentTextColor);
-
- int xPos = 0;
- String displayId = seq.getDisplayId(av.getShowJVSuffix());
- if (av.isRightAlignIds())
- {
- fm = idGraphics.getFontMetrics();
- xPos = idWidth - fm.stringWidth(displayId) - 4;
- }
+ IdCanvas idCanvas = getIdPanel().getIdCanvas();
+ List<SequenceI> selection = av.getSelectionGroup() == null ? null
+ : av.getSelectionGroup().getSequences(null);
+ idCanvas.drawIds((Graphics2D) idGraphics, av, startSeq, endSeq - 1,
+ selection);
- idGraphics.drawString(displayId, xPos,
- (((i - startSeq) * charHeight) + charHeight)
- - (charHeight / 5));
- }
idGraphics.setFont(av.getFont());
idGraphics.translate(0, -scaleHeight);
*/
alignmentGraphics.translate(alignmentGraphicsOffset, scaleHeight);
getSeqPanel().seqCanvas.drawPanelForPrinting(alignmentGraphics, startRes,
- endRes, startSeq, endSeq);
+ endRes, startSeq, endSeq - 1);
alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
if (av.isShowAnnotation() && (endSeq == alignmentHeight))
}
/**
- * DOCUMENT ME!
+ * Prints one page of an alignment in wrapped mode. Returns
+ * Printable.PAGE_EXISTS (0) if a page was drawn, or Printable.NO_SUCH_PAGE if
+ * no page could be drawn (page number out of range).
*
- * @param pg
- * DOCUMENT ME!
- * @param pwidth
- * DOCUMENT ME!
- * @param pheight
- * DOCUMENT ME!
- * @param pi
- * DOCUMENT ME!
+ * @param pageWidth
+ * @param pageHeight
+ * @param pageNumber
+ * (0, 1, ...)
+ * @param g
*
- * @return DOCUMENT ME!
+ * @return
*
* @throws PrinterException
- * DOCUMENT ME!
*/
- public int printWrappedAlignment(int pwidth, int pheight, int pi,
- Graphics pg) throws PrinterException
+ public int printWrappedAlignment(int pageWidth, int pageHeight, int pageNumber,
+ Graphics g) throws PrinterException
{
int annotationHeight = 0;
- AnnotationLabels labels = null;
if (av.isShowAnnotation())
{
annotationHeight = getAnnotationPanel().adjustPanelHeight();
- labels = new AnnotationLabels(av);
}
int hgap = av.getCharHeight();
}
int resWidth = getSeqPanel().seqCanvas
- .getWrappedCanvasWidth(pwidth - idWidth);
+ .getWrappedCanvasWidth(pageWidth - idWidth);
int totalHeight = cHeight * (maxwidth / resWidth + 1);
- pg.setColor(Color.white);
- pg.fillRect(0, 0, pwidth, pheight);
- pg.setFont(av.getFont());
-
- // //////////////
- // Draw the ids
- pg.setColor(Color.black);
+ g.setColor(Color.white);
+ g.fillRect(0, 0, pageWidth, pageHeight);
+ g.setFont(av.getFont());
+ g.setColor(Color.black);
- pg.translate(0, -pi * pheight);
-
- pg.setClip(0, pi * pheight, pwidth, pheight);
-
- int ypos = hgap;
-
- do
- {
- for (int i = 0; i < av.getAlignment().getHeight(); i++)
- {
- pg.setFont(getIdPanel().getIdCanvas().getIdfont());
- SequenceI s = av.getAlignment().getSequenceAt(i);
- String string = s.getDisplayId(av.getShowJVSuffix());
- int xPos = 0;
- if (av.isRightAlignIds())
- {
- FontMetrics fm = pg.getFontMetrics();
- xPos = idWidth - fm.stringWidth(string) - 4;
- }
- pg.drawString(string, xPos,
- ((i * av.getCharHeight()) + ypos + av.getCharHeight())
- - (av.getCharHeight() / 5));
- }
- if (labels != null)
- {
- pg.translate(-3, ypos
- + (av.getAlignment().getHeight() * av.getCharHeight()));
+ /*
+ * method: print the whole wrapped alignment, but with a clip region that
+ * is restricted to the requested page; this supports selective print of
+ * single pages or ranges, (at the cost of some repeated processing in
+ * the 'normal' case, when all pages are printed)
+ */
+ g.translate(0, -pageNumber * pageHeight);
- pg.setFont(av.getFont());
- labels.drawComponent(pg, idWidth);
- pg.translate(+3, -ypos
- - (av.getAlignment().getHeight() * av.getCharHeight()));
- }
+ g.setClip(0, pageNumber * pageHeight, pageWidth, pageHeight);
- ypos += cHeight;
- } while (ypos < totalHeight);
+ /*
+ * draw sequence ids and annotation labels (if shown)
+ */
+ IdCanvas idCanvas = getIdPanel().getIdCanvas();
+ idCanvas.drawIdsWrapped((Graphics2D) g, av, 0, totalHeight);
- pg.translate(idWidth, 0);
+ g.translate(idWidth, 0);
- getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(pg, pwidth - idWidth,
+ getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g, pageWidth - idWidth,
totalHeight, 0);
- if ((pi * pheight) < totalHeight)
+ if ((pageNumber * pageHeight) < totalHeight)
{
return Printable.PAGE_EXISTS;
-
}
else
{
import jalview.schemes.ResidueProperties;
import jalview.util.Comparison;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
@Override
public Dimension getPreferredScrollableViewportSize()
{
- return getPreferredSize();
+ Dimension ps = getPreferredSize();
+ return new Dimension(ps.width, adjustForAlignFrame(false, ps.height));
}
@Override
repaint();
}
}
+
+ /**
+ * computes the visible height of the annotation panel
+ *
+ * @param adjustPanelHeight
+ * - when false, just adjust existing height according to other
+ * windows
+ * @param annotationHeight
+ * @return height to use for the ScrollerPreferredVisibleSize
+ */
+ public int adjustForAlignFrame(boolean adjustPanelHeight,
+ int annotationHeight)
+ {
+ /*
+ * Estimate available height in the AlignFrame for alignment +
+ * annotations. Deduct an estimate for title bar, menu bar, scale panel,
+ * hscroll, status bar, insets.
+ */
+ int stuff = (ap.getViewName() != null ? 30 : 0)
+ + (Platform.isAMac() ? 120 : 140);
+ int availableHeight = ap.alignFrame.getHeight() - stuff;
+ int rowHeight = av.getCharHeight();
+
+ if (adjustPanelHeight)
+ {
+ int alignmentHeight = rowHeight * av.getAlignment().getHeight();
+
+ /*
+ * If not enough vertical space, maximize annotation height while keeping
+ * at least two rows of alignment visible
+ */
+ if (annotationHeight + alignmentHeight > availableHeight)
+ {
+ annotationHeight = Math.min(annotationHeight,
+ availableHeight - 2 * rowHeight);
+ }
+ }
+ else
+ {
+ // maintain same window layout whilst updating sliders
+ annotationHeight = Math.min(ap.annotationScroller.getSize().height,
+ availableHeight - 2 * rowHeight);
+ }
+ return annotationHeight;
+ }
}
}
}
+ /**
+ * highlight a region from start to end (inclusive) on rna
+ *
+ * @param rna
+ * @param start
+ * - first base pair index (from 0)
+ * @param end
+ * - last base pair index (from 0)
+ */
public void highlightRegion(RNA rna, int start, int end)
{
clearLastSelection();
RnaModel rnaModel = models.get(rna);
if (rnaModel.seq == sequence)
{
- int highlightPos = rnaModel.gapped ? index : position - 1;
+ int highlightPos = rnaModel.gapped ? index
+ : position - sequence.getStart();
mouseOverHighlighter.highlightRegion(rna, highlightPos, highlightPos);
vab.updateSelectedRNA(rna);
}
{
return;
}
- if (seqsel != null && seqsel.getSize() > 0)
+
+ RnaModel rnaModel = models.get(rna);
+
+ if (seqsel != null && seqsel.getSize() > 0
+ && seqsel.contains(rnaModel.seq))
{
int start = seqsel.getStartRes(), end = seqsel.getEndRes();
- ShiftList shift = offsets.get(rna);
- if (shift != null)
+ if (rnaModel.gapped)
{
- start = shift.shift(start);
- end = shift.shift(end);
+ ShiftList shift = offsets.get(rna);
+ if (shift != null)
+ {
+ start = shift.shift(start);
+ end = shift.shift(end);
+ }
}
+ else
+ {
+ start = rnaModel.seq.findPosition(start) - rnaModel.seq.getStart();
+ end = rnaModel.seq.findPosition(end) - rnaModel.seq.getStart();
+ }
+
selectionHighlighter.highlightRegion(rna, start, end);
selectionHighlighter.getLastHighlight()
.setOutlineColor(seqsel.getOutlineColour());
super.activateFrame(f);
}
- // If this is the first activation, add to child list.
- if (fChildFrames.indexOf(f) == -1)
+ // add or relocate to top of stack
+ if (fChildFrames.indexOf(f) != -1)
{
- fChildFrames.addElement(f);
+ fChildFrames.remove(f);
}
+ fChildFrames.addElement(f);
if (fCurrentFrame != null && f != fCurrentFrame)
{
{
final Desktop me = this;
// Thread off the news reader, in case there are connection problems.
- addDialogThread(new Runnable()
+ new Thread(new Runnable()
{
@Override
public void run()
showNews.setVisible(true);
Cache.log.debug("Completed news thread.");
}
- });
+ }).start();
}
public void getIdentifiersOrgData()
{
// Thread off the identifiers fetcher
- addDialogThread(new Runnable()
+ new Thread(new Runnable()
{
@Override
public void run()
+ e.getMessage());
}
}
- });
+ }).start();
+ ;
}
@Override
List<SequenceI> searchResults;
- FontMetrics fm;
-
- AnnotationLabels labels = null;
-
AnnotationPanel ap;
private Font idfont;
/**
* DOCUMENT ME!
*
- * @param gg
+ * @param g
* DOCUMENT ME!
* @param hiddenRows
* true - check and display hidden row marker if need be
* @param ypos
* DOCUMENT ME!
*/
- public void drawIdString(Graphics2D gg, boolean hiddenRows, SequenceI s,
+ public void drawIdString(Graphics2D g, boolean hiddenRows, SequenceI s,
int i, int starty, int ypos)
{
int xPos = 0;
if ((searchResults != null) && searchResults.contains(s))
{
- gg.setColor(Color.black);
- gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),
+ g.setColor(Color.black);
+ g.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),
charHeight);
- gg.setColor(Color.white);
+ g.setColor(Color.white);
}
else if ((av.getSelectionGroup() != null)
&& av.getSelectionGroup().getSequences(null).contains(s))
{
- gg.setColor(Color.lightGray);
- gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),
+ g.setColor(Color.lightGray);
+ g.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),
charHeight);
- gg.setColor(Color.white);
+ g.setColor(Color.white);
}
else
{
- gg.setColor(av.getSequenceColour(s));
- gg.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),
+ g.setColor(av.getSequenceColour(s));
+ g.fillRect(0, ((i - starty) * charHeight) + ypos, getWidth(),
charHeight);
- gg.setColor(Color.black);
+ g.setColor(Color.black);
}
if (av.isRightAlignIds())
{
+ FontMetrics fm = g.getFontMetrics();
xPos = panelWidth
- fm.stringWidth(s.getDisplayId(av.getShowJVSuffix())) - 4;
}
- gg.drawString(s.getDisplayId(av.getShowJVSuffix()), xPos,
+ g.drawString(s.getDisplayId(av.getShowJVSuffix()), xPos,
(((i - starty + 1) * charHeight) + ypos) - (charHeight / 5));
if (hiddenRows)
{
- drawMarker(i, starty, ypos);
+ drawMarker(g, av, i, starty, ypos);
}
}
gg.translate(0, transY);
- drawIds(ss, es);
+ drawIds(gg, av, ss, es, searchResults);
gg.translate(0, -transY);
gg.setColor(Color.white);
gg.fillRect(0, 0, getWidth(), imgHeight);
- drawIds(av.getRanges().getStartSeq(), av.getRanges().getEndSeq());
+ drawIds(gg, av, av.getRanges().getStartSeq(), av.getRanges().getEndSeq(), searchResults);
g.drawImage(image, 0, 0, this);
}
/**
- * DOCUMENT ME!
+ * Draws sequence ids from sequence index startSeq to endSeq (inclusive), with
+ * the font and other display settings configured on the viewport. Ids of
+ * sequences included in the selection are coloured grey, otherwise the
+ * current id colour for the sequence id is used.
*
- * @param starty
- * DOCUMENT ME!
- * @param endy
- * DOCUMENT ME!
+ * @param g
+ * @param alignViewport
+ * @param startSeq
+ * @param endSeq
+ * @param selection
*/
- void drawIds(int starty, int endy)
+ void drawIds(Graphics2D g, AlignViewport alignViewport, final int startSeq,
+ final int endSeq, List<SequenceI> selection)
{
- if (av.isSeqNameItalics())
+ Font font = alignViewport.getFont();
+ if (alignViewport.isSeqNameItalics())
{
- setIdfont(new Font(av.getFont().getName(), Font.ITALIC,
- av.getFont().getSize()));
+ setIdfont(new Font(font.getName(), Font.ITALIC,
+ font.getSize()));
}
else
{
- setIdfont(av.getFont());
+ setIdfont(font);
}
- gg.setFont(getIdfont());
- fm = gg.getFontMetrics();
+ g.setFont(getIdfont());
+ FontMetrics fm = g.getFontMetrics();
- if (av.antiAlias)
+ if (alignViewport.antiAlias)
{
- gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
Color currentColor = Color.white;
Color currentTextColor = Color.black;
- boolean hasHiddenRows = av.hasHiddenRows();
+ boolean hasHiddenRows = alignViewport.hasHiddenRows();
- if (av.getWrapAlignment())
+ if (alignViewport.getWrapAlignment())
{
- drawIdsWrapped(starty, hasHiddenRows);
+ drawIdsWrapped(g, alignViewport, startSeq, getHeight());
return;
}
- // No need to hang on to labels if we're not wrapped
- labels = null;
-
// Now draw the id strings
int panelWidth = getWidth();
int xPos = 0;
- SequenceI sequence;
// Now draw the id strings
- for (int i = starty; i <= endy; i++)
+ for (int i = startSeq; i <= endSeq; i++)
{
- sequence = av.getAlignment().getSequenceAt(i);
+ SequenceI sequence = alignViewport.getAlignment().getSequenceAt(i);
if (sequence == null)
{
continue;
}
- if (hasHiddenRows || av.isDisplayReferenceSeq())
+ if (hasHiddenRows || alignViewport.isDisplayReferenceSeq())
{
- setHiddenFont(sequence);
+ g.setFont(getHiddenFont(sequence, alignViewport));
}
// Selected sequence colours
- if ((searchResults != null) && searchResults.contains(sequence))
+ if (selection != null && selection.contains(sequence))
{
currentColor = Color.black;
currentTextColor = Color.white;
}
- else if ((av.getSelectionGroup() != null) && av.getSelectionGroup()
- .getSequences(null).contains(sequence))
+ else if ((alignViewport.getSelectionGroup() != null) && alignViewport
+ .getSelectionGroup().getSequences(null).contains(sequence))
{
currentColor = Color.lightGray;
currentTextColor = Color.black;
}
else
{
- currentColor = av.getSequenceColour(sequence);
+ currentColor = alignViewport.getSequenceColour(sequence);
currentTextColor = Color.black;
}
- gg.setColor(currentColor);
+ g.setColor(currentColor);
- gg.fillRect(0, (i - starty) * av.getCharHeight(), getWidth(),
- av.getCharHeight());
+ int charHeight = alignViewport.getCharHeight();
+ g.fillRect(0, (i - startSeq) * charHeight,
+ getWidth(), charHeight);
- gg.setColor(currentTextColor);
+ g.setColor(currentTextColor);
- String string = sequence.getDisplayId(av.getShowJVSuffix());
+ String string = sequence
+ .getDisplayId(alignViewport.getShowJVSuffix());
- if (av.isRightAlignIds())
+ if (alignViewport.isRightAlignIds())
{
xPos = panelWidth - fm.stringWidth(string) - 4;
}
- gg.drawString(string, xPos,
- (((i - starty) * av.getCharHeight()) + av.getCharHeight())
- - (av.getCharHeight() / 5));
+ g.drawString(string, xPos, (((i - startSeq) * charHeight) + charHeight)
+ - (charHeight / 5));
if (hasHiddenRows)
{
- drawMarker(i, starty, 0);
+ drawMarker(g, alignViewport, i, startSeq, 0);
}
}
}
/**
- * Draws sequence ids in wrapped mode
+ * Draws sequence ids, and annotation labels if annotations are shown, in
+ * wrapped mode
*
- * @param starty
- * @param hasHiddenRows
+ * @param g
+ * @param alignViewport
+ * @param startSeq
*/
- protected void drawIdsWrapped(int starty, boolean hasHiddenRows)
+ void drawIdsWrapped(Graphics2D g, AlignViewport alignViewport,
+ int startSeq, int pageHeight)
{
- int maxwidth = av.getAlignment().getWidth();
- int alheight = av.getAlignment().getHeight();
+ int alignmentWidth = alignViewport.getAlignment().getWidth();
+ final int alheight = alignViewport.getAlignment().getHeight();
- if (av.hasHiddenColumns())
+ if (alignViewport.hasHiddenColumns())
{
- maxwidth = av.getAlignment().getHiddenColumns()
- .absoluteToVisibleColumn(maxwidth) - 1;
+ alignmentWidth = alignViewport.getAlignment().getHiddenColumns()
+ .absoluteToVisibleColumn(alignmentWidth) - 1;
}
int annotationHeight = 0;
- if (av.isShowAnnotation())
+ AnnotationLabels labels = null;
+ if (alignViewport.isShowAnnotation())
{
if (ap == null)
{
- ap = new AnnotationPanel(av);
+ ap = new AnnotationPanel(alignViewport);
}
-
annotationHeight = ap.adjustPanelHeight();
- if (labels == null)
- {
- labels = new AnnotationLabels(av);
- }
+ labels = new AnnotationLabels(alignViewport);
}
- int hgap = av.getCharHeight();
- if (av.getScaleAboveWrapped())
+ final int charHeight = alignViewport.getCharHeight();
+ int hgap = charHeight;
+ if (alignViewport.getScaleAboveWrapped())
{
- hgap += av.getCharHeight();
+ hgap += charHeight;
}
- int cHeight = alheight * av.getCharHeight() + hgap + annotationHeight;
+ /*
+ * height of alignment + gap + annotations (if shown)
+ */
+ int cHeight = alheight * charHeight + hgap
+ + annotationHeight;
- ViewportRanges ranges = av.getRanges();
+ ViewportRanges ranges = alignViewport.getRanges();
int rowSize = ranges.getViewportWidth();
* draw repeating sequence ids until out of sequence data or
* out of visible space, whichever comes first
*/
+ boolean hasHiddenRows = alignViewport.hasHiddenRows();
int ypos = hgap;
- int row = ranges.getStartRes();
- while ((ypos <= getHeight()) && (row < maxwidth))
+ int rowStartRes = ranges.getStartRes();
+ while ((ypos <= pageHeight) && (rowStartRes < alignmentWidth))
{
- for (int i = starty; i < alheight; i++)
+ for (int i = startSeq; i < alheight; i++)
{
- SequenceI s = av.getAlignment().getSequenceAt(i);
- if (hasHiddenRows || av.isDisplayReferenceSeq())
+ SequenceI s = alignViewport.getAlignment().getSequenceAt(i);
+ if (hasHiddenRows || alignViewport.isDisplayReferenceSeq())
{
- setHiddenFont(s);
+ g.setFont(getHiddenFont(s, alignViewport));
}
else
{
- gg.setFont(getIdfont());
+ g.setFont(getIdfont());
}
-
- drawIdString(gg, hasHiddenRows, s, i, 0, ypos);
+ drawIdString(g, hasHiddenRows, s, i, 0, ypos);
}
- if (labels != null && av.isShowAnnotation())
+ if (labels != null && alignViewport.isShowAnnotation())
{
- gg.translate(0, ypos + (alheight * av.getCharHeight()));
- labels.drawComponent(gg, getWidth());
- gg.translate(0, -ypos - (alheight * av.getCharHeight()));
+ g.translate(0, ypos + (alheight * charHeight));
+ labels.drawComponent(g, getWidth());
+ g.translate(0, -ypos - (alheight * charHeight));
}
ypos += cHeight;
- row += rowSize;
+ rowStartRes += rowSize;
}
}
- void drawMarker(int i, int starty, int yoffset)
+ /**
+ * Draws a marker (a blue right-pointing triangle) between sequences to
+ * indicate hidden sequences.
+ *
+ * @param g
+ * @param alignViewport
+ * @param seqIndex
+ * @param starty
+ * @param yoffset
+ */
+ void drawMarker(Graphics2D g, AlignViewport alignViewport, int seqIndex, int starty, int yoffset)
{
-
- SequenceI[] hseqs = av.getAlignment()
+ SequenceI[] hseqs = alignViewport.getAlignment()
.getHiddenSequences().hiddenSequences;
// Use this method here instead of calling hiddenSeq adjust
// 3 times.
int hSize = hseqs.length;
- int hiddenIndex = i;
- int lastIndex = i - 1;
- int nextIndex = i + 1;
+ int hiddenIndex = seqIndex;
+ int lastIndex = seqIndex - 1;
+ int nextIndex = seqIndex + 1;
for (int j = 0; j < hSize; j++)
{
}
}
+ /*
+ * are we below or above the hidden sequences?
+ */
boolean below = (hiddenIndex > lastIndex + 1);
boolean above = (nextIndex > hiddenIndex + 1);
- gg.setColor(Color.blue);
+ g.setColor(Color.blue);
+ int charHeight = av.getCharHeight();
+
+ /*
+ * vertices of the triangle, below or above hidden seqs
+ */
+ int[] xPoints = new int[]
+ { getWidth() - charHeight,
+ getWidth() - charHeight, getWidth() };
+ int yShift = seqIndex - starty;
+
if (below)
{
- gg.fillPolygon(
- new int[]
- { getWidth() - av.getCharHeight(),
- getWidth() - av.getCharHeight(), getWidth() },
- new int[]
- { (i - starty) * av.getCharHeight() + yoffset,
- (i - starty) * av.getCharHeight() + yoffset
- + av.getCharHeight() / 4,
- (i - starty) * av.getCharHeight() + yoffset },
- 3);
+ int[] yPoints = new int[] { yShift * charHeight + yoffset,
+ yShift * charHeight + yoffset + charHeight / 4,
+ yShift * charHeight + yoffset };
+ g.fillPolygon(xPoints, yPoints, 3);
}
if (above)
{
- gg.fillPolygon(
- new int[]
- { getWidth() - av.getCharHeight(),
- getWidth() - av.getCharHeight(), getWidth() },
- new int[]
- { (i - starty + 1) * av.getCharHeight() + yoffset,
- (i - starty + 1) * av.getCharHeight() + yoffset
- - av.getCharHeight() / 4,
- (i - starty + 1) * av.getCharHeight() + yoffset },
- 3);
-
+ yShift++;
+ int[] yPoints = new int[] { yShift * charHeight + yoffset,
+ yShift * charHeight + yoffset - charHeight / 4,
+ yShift * charHeight + yoffset };
+ g.fillPolygon(xPoints, yPoints, 3);
}
}
- void setHiddenFont(SequenceI seq)
+ /**
+ * Answers the standard sequence id font, or a bold font if the sequence is
+ * set as reference or a hidden group representative
+ *
+ * @param seq
+ * @param alignViewport
+ * @return
+ */
+ private Font getHiddenFont(SequenceI seq, AlignViewport alignViewport)
{
- Font bold = new Font(av.getFont().getName(), Font.BOLD,
- av.getFont().getSize());
-
if (av.isReferenceSeq(seq) || av.isHiddenRepSequence(seq))
{
- gg.setFont(bold);
- }
- else
- {
- gg.setFont(getIdfont());
+ return new Font(av.getFont().getName(), Font.BOLD,
+ av.getFont().getSize());
}
+ return getIdfont();
}
/**
import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
-import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
width -= (width % charWidth);
height -= (height % charHeight);
- // selectImage is the selection group outline image
- BufferedImage selectImage = drawSelectionGroup(
- ranges.getStartRes(), ranges.getEndRes(),
- ranges.getStartSeq(), ranges.getEndSeq());
-
if ((img != null) && (fastPaint
|| (getVisibleRect().width != g.getClipBounds().width)
|| (getVisibleRect().height != g.getClipBounds().height)))
{
- BufferedImage lcimg = buildLocalImage(selectImage);
- g.drawImage(lcimg, 0, 0, this);
+ g.drawImage(img, 0, 0, this);
+
+ drawSelectionGroup((Graphics2D) g, ranges.getStartRes(),
+ ranges.getEndRes(), ranges.getStartSeq(), ranges.getEndSeq());
+
fastPaint = false;
}
- else if ((width > 0) && (height > 0))
+ else if (width > 0 && height > 0)
{
- // img is a cached version of the last view we drew, if any
- // if we have no img or the size has changed, make a new one
+ /*
+ * img is a cached version of the last view we drew, if any
+ * if we have no img or the size has changed, make a new one
+ */
if (img == null || width != img.getWidth()
|| height != img.getHeight())
{
- img = setupImage();
- if (img == null)
- {
- return;
- }
+ img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
gg = (Graphics2D) img.getGraphics();
gg.setFont(av.getFont());
}
drawPanel(gg, ranges.getStartRes(), ranges.getEndRes(),
ranges.getStartSeq(), ranges.getEndSeq(), 0);
}
-
- // lcimg is a local *copy* of img which we'll draw selectImage on top of
- BufferedImage lcimg = buildLocalImage(selectImage);
- g.drawImage(lcimg, 0, 0, this);
+ drawSelectionGroup(gg, ranges.getStartRes(),
+ ranges.getEndRes(), ranges.getStartSeq(), ranges.getEndSeq());
+
+ g.drawImage(img, 0, 0, this);
}
if (av.cursorMode)
{
drawPanel(g1, startRes, endRes, startSeq, endSeq, 0);
- BufferedImage selectImage = drawSelectionGroup(startRes, endRes,
+ drawSelectionGroup((Graphics2D) g1, startRes, endRes,
startSeq, endSeq);
- if (selectImage != null)
- {
- ((Graphics2D) g1).setComposite(AlphaComposite
- .getInstance(AlphaComposite.SRC_OVER));
- g1.drawImage(selectImage, 0, 0, this);
- }
}
/**
public void drawWrappedPanelForPrinting(Graphics g, int canvasWidth,
int canvasHeight, int startRes)
{
- SequenceGroup group = av.getSelectionGroup();
-
drawWrappedPanel(g, canvasWidth, canvasHeight, startRes);
+ SequenceGroup group = av.getSelectionGroup();
if (group != null)
{
- BufferedImage selectImage = null;
- try
- {
- selectImage = new BufferedImage(canvasWidth, canvasHeight,
- BufferedImage.TYPE_INT_ARGB); // ARGB so alpha compositing works
- } catch (OutOfMemoryError er)
- {
- System.gc();
- System.err.println("Print image OutOfMemory Error.\n" + er);
- new OOMWarning("Creating wrapped alignment image for printing", er);
- }
- if (selectImage != null)
- {
- Graphics2D g2 = selectImage.createGraphics();
- setupSelectionGroup(g2, selectImage);
- drawWrappedSelection(g2, group, canvasWidth, canvasHeight,
+ drawWrappedSelection((Graphics2D) g, group, canvasWidth, canvasHeight,
startRes);
-
- g2.setComposite(
- AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
- g.drawImage(selectImage, 0, 0, this);
- g2.dispose();
- }
}
}
- /*
- * Make a local image by combining the cached image img
- * with any selection
- */
- private BufferedImage buildLocalImage(BufferedImage selectImage)
- {
- // clone the cached image
- BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
- img.getType());
-
- // BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
- // img.getType());
- Graphics2D g2d = lcimg.createGraphics();
- g2d.drawImage(img, 0, 0, null);
-
- // overlay selection group on lcimg
- if (selectImage != null)
- {
- g2d.setComposite(
- AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
- g2d.drawImage(selectImage, 0, 0, this);
- }
-
- g2d.dispose();
-
- return lcimg;
- }
-
- /*
- * Set up a buffered image of the correct height and size for the sequence canvas
- */
- private BufferedImage setupImage()
- {
- BufferedImage lcimg = null;
-
- int charWidth = av.getCharWidth();
- int charHeight = av.getCharHeight();
-
- int width = getWidth();
- int height = getHeight();
-
- width -= (width % charWidth);
- height -= (height % charHeight);
-
- if ((width < 1) || (height < 1))
- {
- return null;
- }
-
- try
- {
- lcimg = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_ARGB); // ARGB so alpha compositing works
- } catch (OutOfMemoryError er)
- {
- System.gc();
- System.err.println(
- "Group image OutOfMemory Redraw Error.\n" + er);
- new OOMWarning("Creating alignment image for display", er);
-
- return null;
- }
-
- return lcimg;
- }
-
/**
* Returns the visible width of the canvas in residues, after allowing for
* East or West scales (if shown)
calculateWrappedGeometry(canvasWidth, canvasHeight);
/*
- * draw one width at a time (including any scales or annotation shown),
+ * draw one width at a time (excluding any scales or annotation shown),
* until we have run out of either alignment or vertical space available
*/
int ypos = wrappedSpaceAboveAlignment;
*/
wrappedRepeatHeightPx = wrappedSpaceAboveAlignment;
// add sequences
- wrappedRepeatHeightPx += av.getRanges().getViewportHeight()
+ wrappedRepeatHeightPx += av.getAlignment().getHeight()
* charHeight;
// add annotations panel height if shown
wrappedRepeatHeightPx += getAnnotationHeight();
// chop the wrapped alignment extent up into panel-sized blocks and treat
// each block as if it were a block from an unwrapped alignment
+ g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_ROUND, 3f, new float[]
+ { 5f, 3f }, 0f));
+ g.setColor(Color.RED);
while ((ypos <= canvasHeight) && (startx < maxwidth))
{
// set end value to be start + width, or maxwidth, whichever is smaller
// update horizontal offset
startx += cWidth;
}
+ g.setStroke(new BasicStroke());
}
int getAnnotationHeight()
}
+ /**
+ * Draws the outlines of any groups defined on the alignment (excluding the
+ * current selection group, if any)
+ *
+ * @param g1
+ * @param startRes
+ * @param endRes
+ * @param startSeq
+ * @param endSeq
+ * @param offset
+ */
void drawGroupsBoundaries(Graphics g1, int startRes, int endRes,
int startSeq, int endSeq, int offset)
{
Graphics2D g = (Graphics2D) g1;
- //
- // ///////////////////////////////////
- // Now outline any areas if necessary
- // ///////////////////////////////////
SequenceGroup group = null;
int groupIndex = -1;
if (group != null)
{
- g.setStroke(new BasicStroke());
- g.setColor(group.getOutlineColour());
-
do
{
+ g.setColor(group.getOutlineColour());
+
drawPartialGroupOutline(g, group, startRes, endRes, startSeq,
endSeq, offset);
groupIndex++;
- g.setStroke(new BasicStroke());
-
if (groupIndex >= av.getAlignment().getGroups().size())
{
break;
}
-
- /*
- * Draw the selection group as a separate image and overlay
+ /**
+ * Draws the outline of the current selection group (if any)
+ *
+ * @param g
+ * @param startRes
+ * @param endRes
+ * @param startSeq
+ * @param endSeq
*/
- private BufferedImage drawSelectionGroup(int startRes, int endRes,
+ private void drawSelectionGroup(Graphics2D g, int startRes, int endRes,
int startSeq, int endSeq)
{
- // get a new image of the correct size
- BufferedImage selectionImage = setupImage();
-
- if (selectionImage == null)
- {
- return null;
- }
-
SequenceGroup group = av.getSelectionGroup();
if (group == null)
{
- // nothing to draw
- return null;
+ return;
}
- // set up drawing colour
- Graphics2D g = (Graphics2D) selectionImage.getGraphics();
-
- setupSelectionGroup(g, selectionImage);
-
+ g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_ROUND, 3f, new float[]
+ { 5f, 3f }, 0f));
+ g.setColor(Color.RED);
if (!av.getWrapAlignment())
{
drawUnwrappedSelection(g, group, startRes, endRes, startSeq, endSeq,
drawWrappedSelection(g, group, getWidth(), getHeight(),
av.getRanges().getStartRes());
}
-
- g.dispose();
- return selectionImage;
+ g.setStroke(new BasicStroke());
}
/**
}
- /*
- * Set up graphics for selection group
- */
- private void setupSelectionGroup(Graphics2D g,
- BufferedImage selectionImage)
- {
- // set background to transparent
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
- g.fillRect(0, 0, selectionImage.getWidth(), selectionImage.getHeight());
-
- // set up foreground to draw red dashed line
- g.setComposite(AlphaComposite.Src);
- g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
- BasicStroke.JOIN_ROUND, 3f, new float[]
- { 5f, 3f }, 0f));
- g.setColor(Color.RED);
- }
-
- /*
+ /**
* Draw a selection group over an unwrapped alignment
- * @param g graphics object to draw with
- * @param group selection group
- * @param startRes start residue of area to draw
- * @param endRes end residue of area to draw
- * @param startSeq start sequence of area to draw
- * @param endSeq end sequence of area to draw
- * @param offset vertical offset (used when called from wrapped alignment code)
+ *
+ * @param g
+ * graphics object to draw with
+ * @param group
+ * selection group
+ * @param startRes
+ * start residue of area to draw
+ * @param endRes
+ * end residue of area to draw
+ * @param startSeq
+ * start sequence of area to draw
+ * @param endSeq
+ * end sequence of area to draw
+ * @param offset
+ * vertical offset (used when called from wrapped alignment code)
*/
private void drawUnwrappedSelection(Graphics2D g, SequenceGroup group,
int startRes, int endRes, int startSeq, int endSeq, int offset)
}
}
- /*
- * Draw the selection group as a separate image and overlay
+ /**
+ * Draws part of a selection group outline
+ *
+ * @param g
+ * @param group
+ * @param startRes
+ * @param endRes
+ * @param startSeq
+ * @param endSeq
+ * @param verticalOffset
*/
private void drawPartialGroupOutline(Graphics2D g, SequenceGroup group,
int startRes, int endRes, int startSeq, int endSeq,
return true;
}
},
- Jalview("Jalview", "jar,jvp", true, true)
+ Jalview("Jalview", "jvp, jar", true, true)
{
@Override
public AlignmentFileReaderI getReader(FileParse source)
public static JalviewFileChooser forRead(String directory,
String selected)
{
- List<String> extensions = new ArrayList<String>();
- List<String> descs = new ArrayList<String>();
+ List<String> extensions = new ArrayList<>();
+ List<String> descs = new ArrayList<>();
for (FileFormatI format : FileFormats.getInstance().getFormats())
{
if (format.isReadable())
{
// TODO in Java 8, forRead and forWrite can be a single method
// with a lambda expression parameter for isReadable/isWritable
- List<String> extensions = new ArrayList<String>();
- List<String> descs = new ArrayList<String>();
+ List<String> extensions = new ArrayList<>();
+ List<String> descs = new ArrayList<>();
for (FileFormatI format : FileFormats.getInstance().getFormats())
{
if (format.isWritable())
super(safePath(dir));
if (extensions.length == descs.length)
{
- List<String[]> formats = new ArrayList<String[]>();
+ List<String[]> formats = new ArrayList<>();
for (int i = 0; i < extensions.length; i++)
{
formats.add(new String[] { extensions[i], descs[i] });
return null;
}
+ File ourselectedFile = null;
+
+ @Override
+ public File getSelectedFile()
+ {
+ File selfile = super.getSelectedFile();
+ if (selfile == null && ourselectedFile != null)
+ {
+ return ourselectedFile;
+ }
+ return selfile;
+ }
+
@Override
public int showSaveDialog(Component parent) throws HeadlessException
{
setDialogType(SAVE_DIALOG);
+ this.setSelectedFile(null);
int ret = showDialog(parent, MessageManager.getString("action.save"));
+ ourselectedFile = getSelectedFile();
+ if (getSelectedFile() == null)
+ {
+ // Workaround for Java 9,10 on OSX - no selected file, but there is a
+ // filename typed in
+ try
+ {
+ String filename = ((BasicFileChooserUI) getUI()).getFileName();
+ if (filename != null && filename.length() > 0)
+ {
+ ourselectedFile = new File(getCurrentDirectory(), filename);
+ }
+ } catch (Throwable x)
+ {
+ System.err.println(
+ "Unexpected exception when trying to get filename.");
+ x.printStackTrace();
+ }
+ }
+ if (ourselectedFile == null)
+ {
+ return JalviewFileChooser.CANCEL_OPTION;
+ }
if (getFileFilter() instanceof JalviewFileFilter)
{
JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter();
- if (!jvf.accept(getSelectedFile()))
+ if (!jvf.accept(ourselectedFile))
{
- String withExtension = getSelectedFile() + "."
+ String withExtension = getSelectedFile().getName() + "."
+ jvf.getAcceptableExtension();
- setSelectedFile(new File(withExtension));
+ ourselectedFile = (new File(getCurrentDirectory(), withExtension));
+ setSelectedFile(ourselectedFile);
}
}
// TODO: ENSURE THAT FILES SAVED WITH A ':' IN THE NAME ARE REFUSED AND THE
// USER PROMPTED FOR A NEW FILENAME
if ((ret == JalviewFileChooser.APPROVE_OPTION)
- && getSelectedFile().exists())
+ && ourselectedFile.exists())
{
int confirm = JvOptionPane.showConfirmDialog(parent,
MessageManager.getString("label.overwrite_existing_file"),
package jalview.io;
import java.io.File;
-import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.StringTokenizer;
import javax.swing.filechooser.FileFilter;
{
public static Hashtable suffixHash = new Hashtable();
- private Hashtable filters = null;
+ private Map<String, JalviewFileFilter> filters = null;
private String description = "no description";
public String getAcceptableExtension()
{
- return filters.keys().nextElement().toString();
+ return filters.keySet().iterator().next().toString();
}
// takes account of the fact that database is a directory
+ @Override
public boolean accept(File f)
{
if (f != null)
return true;
}
- if ((extension != null) && (filters.get(getExtension(f)) != null))
+ if ((extension != null) && (filters.get(extension) != null))
{
return true;
}
{
if (filters == null)
{
- filters = new Hashtable(5);
+ filters = new LinkedHashMap<>(5);
}
filters.put(extension.toLowerCase(), this);
fullDescription = null;
}
+ @Override
public String getDescription()
{
if (fullDescription == null)
: (description + " (");
// build the description from the extension list
- Enumeration extensions = filters.keys();
+ Iterator<String> extensions = filters.keySet().iterator();
if (extensions != null)
{
- fullDescription += ("." + (String) extensions.nextElement());
+ fullDescription += ("." + extensions.next());
- while (extensions.hasMoreElements())
+ while (extensions.hasNext())
{
- fullDescription += (", " + (String) extensions.nextElement());
+ fullDescription += (", " + extensions.next());
}
}
private void loadExtensions()
{
- extensions = new HashMap<String, String>();
+ extensions = new HashMap<>();
for (FileFormatI ff : FileFormats.getInstance().getFormats())
{
String desc = ff.getName() + " file";
String exts = ff.getExtensions();
for (String ext : exts.split(","))
{
- extensions.put(ext.trim().toLowerCase(),
+ ext = ext.trim().toLowerCase();
+ extensions.put(ext,
desc + ("jar".equals(ext) ? " (old)" : ""));
}
}
{
if (icons == null)
{
- icons = new HashMap<String, ImageIcon>();
+ icons = new HashMap<>();
}
if (!icons.containsKey(filePath))
{
public static final Regex DETECT_BRACKETS = new Regex(
"(<|>|\\[|\\]|\\(|\\)|\\{|\\})");
+ // WUSS extended symbols. Avoid ambiguity with protein SS annotations by using NOT_RNASS first.
+ public static final String RNASS_BRACKETS = "<>[](){}AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
+
+ // use the following regex to decide an annotations (whole) line is NOT an RNA
+ // SS (it contains only E,H,e,h and other non-brace/non-alpha chars)
+ private static final Regex NOT_RNASS = new Regex(
+ "^[^<>[\\](){}A-DF-Za-df-z]*$");
+
StringBuffer out; // output buffer
AlignmentI al;
String version;
// String id;
Hashtable seqAnn = new Hashtable(); // Sequence related annotations
- LinkedHashMap<String, String> seqs = new LinkedHashMap<String, String>();
+ LinkedHashMap<String, String> seqs = new LinkedHashMap<>();
Regex p, r, rend, s, x;
// Temporary line for processing RNA annotation
// String RNAannot = "";
strucAnn = new Hashtable();
}
- Vector<AlignmentAnnotation> newStruc = new Vector<AlignmentAnnotation>();
+ Vector<AlignmentAnnotation> newStruc = new Vector<>();
parseAnnotationRow(newStruc, type, ns);
for (AlignmentAnnotation alan : newStruc)
{
private void guessDatabaseFor(Sequence seqO, String dbr, String dbsource)
{
DBRefEntry dbrf = null;
- List<DBRefEntry> dbrs = new ArrayList<DBRefEntry>();
+ List<DBRefEntry> dbrs = new ArrayList<>();
String seqdb = "Unknown", sdbac = "" + dbr;
int st = -1, en = -1, p;
if ((st = sdbac.indexOf("/")) > -1)
}
boolean ss = false, posterior = false;
type = id2type(type);
+
+ boolean isrnass = false;
if (type.equalsIgnoreCase("secondary structure"))
{
ss = true;
+ isrnass = !NOT_RNASS.search(annots); // sorry about the double negative
+ // here (it's easier for dealing with
+ // other non-alpha-non-brace chars)
}
if (type.equalsIgnoreCase("posterior probability"))
{
{
// if (" .-_".indexOf(pos) == -1)
{
- if (DETECT_BRACKETS.search(pos))
+ if (isrnass && RNASS_BRACKETS.indexOf(pos) >= 0)
{
ann.secondaryStructure = Rna.getRNASecStrucState(pos).charAt(0);
ann.displayCharacter = "" + pos.charAt(0);
String ch = (annot == null)
? ((sequenceI == null) ? "-"
: Character.toString(sequenceI.getCharAt(k)))
- : annot.displayCharacter;
+ : (annot.displayCharacter == null
+ ? String.valueOf(annot.secondaryStructure)
+ : annot.displayCharacter);
+ if (ch == null)
+ {
+ ch = " ";
+ }
if (key != null && key.equals("SS"))
{
+ char ssannotchar = ' ';
+ boolean charset = false;
if (annot == null)
{
// sensible gap character
- return ' ';
+ ssannotchar = ' ';
+ charset = true;
}
else
{
// valid secondary structure AND no alternative label (e.g. ' B')
if (annot.secondaryStructure > ' ' && ch.length() < 2)
{
- return annot.secondaryStructure;
+ ssannotchar = annot.secondaryStructure;
+ charset = true;
}
}
+ if (charset)
+ {
+ return (ssannotchar == ' ' && isrna) ? '.' : ssannotchar;
+ }
}
if (ch.length() == 0)
{
seq = ch.charAt(1);
}
- return seq;
+
+ return (seq == ' ' && key != null && key.equals("SS") && isrna) ? '.'
+ : seq;
}
public String print()
import jalview.datamodel.xdb.uniprot.UniprotEntry;
import jalview.datamodel.xdb.uniprot.UniprotFeature;
import jalview.datamodel.xdb.uniprot.UniprotFile;
+import jalview.schemes.ResidueProperties;
+import jalview.util.StringUtils;
import jalview.ws.seqfetcher.DbSourceProxyImpl;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
+import java.util.List;
import java.util.Vector;
import org.exolab.castor.mapping.Mapping;
for (UniprotFeature uf : entry.getFeature())
{
SequenceFeature copy = new SequenceFeature(uf.getType(),
- uf.getDescription(), uf.getBegin(), uf.getEnd(), "Uniprot");
+ getDescription(uf), uf.getBegin(), uf.getEnd(), "Uniprot");
copy.setStatus(uf.getStatus());
sequence.addSequenceFeature(copy);
}
}
/**
+ * Constructs a feature description from the description and (optionally)
+ * original and variant fields of the Uniprot XML feature
+ *
+ * @param uf
+ * @return
+ */
+ protected static String getDescription(UniprotFeature uf)
+ {
+ String orig = uf.getOriginal();
+ List<String> variants = uf.getVariation();
+ StringBuilder sb = new StringBuilder();
+
+ /*
+ * append variant in standard format if present
+ * e.g. p.Arg59Lys
+ * multiple variants are split over lines using <br>
+ */
+ boolean asHtml = false;
+ if (orig != null && !orig.isEmpty() && variants != null
+ && !variants.isEmpty())
+ {
+ int p = 0;
+ for (String var : variants)
+ {
+ // TODO proper HGVS nomenclature for delins structural variations
+ // http://varnomen.hgvs.org/recommendations/protein/variant/delins/
+ // for now we are pragmatic - any orig/variant sequence longer than
+ // three characters is shown with single-character notation rather than
+ // three-letter notation
+ sb.append("p.");
+ if (orig.length() < 4)
+ {
+ for (int c = 0, clen = orig.length(); c < clen; c++)
+ {
+ char origchar = orig.charAt(c);
+ String orig3 = ResidueProperties.aa2Triplet.get("" + origchar);
+ sb.append(orig3 == null ? origchar
+ : StringUtils.toSentenceCase(orig3));
+ }
+ }
+ else
+ {
+ sb.append(orig);
+ }
+
+ sb.append(Integer.toString(uf.getPosition()));
+
+ if (var.length() < 4)
+ {
+ for (int c = 0, clen = var.length(); c < clen; c++)
+ {
+ char varchar = var.charAt(c);
+ String var3 = ResidueProperties.aa2Triplet.get("" + varchar);
+
+ sb.append(var3 != null ? StringUtils.toSentenceCase(var3)
+ : "" + varchar);
+ }
+ }
+ else
+ {
+ sb.append(var);
+ }
+ if (++p != variants.size())
+ {
+ sb.append("<br/> ");
+ asHtml = true;
+ }
+ else
+ {
+ sb.append(" ");
+ }
+ }
+ }
+ String description = uf.getDescription();
+ if (description != null)
+ {
+ sb.append(description);
+ }
+ if (asHtml)
+ {
+ sb.insert(0, "<html>");
+ sb.append("</html>");
+ }
+
+ return sb.toString();
+ }
+
+ /**
*
* @param entry
* UniportEntry
private static final int MINFILESIZE_BIG = 4096;
- private ArrayList<String> successfulCMDs = new ArrayList<String>();
+ private ArrayList<String> successfulCMDs = new ArrayList<>();
/***
* from
private Worker jalviewDesktopRunner(boolean withAwt, String cmd,
int timeout)
{
+ String cp_sep = ":";
+ if (System.getProperty("os.name").indexOf("Windows") >= 0)
+ {
+ cp_sep = ";";
+ }
+ // Note: JAL-3065 - don't include quotes for lib/* because the arguments are
+ // not expanded by the shell
String _cmd = "java "
+ (withAwt ? "-Djava.awt.headless=true" : "")
- + " -Djava.ext.dirs=./lib -classpath ./classes jalview.bin.Jalview ";
+ + " -classpath ./classes" + cp_sep
+ + "./lib/* jalview.bin.Jalview ";
System.out.println("CMD [" + cmd + "]");
Process ls2_proc = null;
Worker worker = null;
AlignmentI al = av.getAlignment();
assertEquals(al.getWidth(), 157);
assertEquals(al.getHeight(), 15);
+ av.getRanges().setStartEndSeq(0, 14);
+
+ SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
av.setWrapAlignment(true);
- av.getRanges().setStartEndSeq(0, 14);
av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
int charHeight = av.getCharHeight();
int charWidth = av.getCharWidth();
assertEquals(charHeight, 17);
assertEquals(charWidth, 12);
- SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
-
/*
* first with scales above, left, right
*/
testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
}
+
+ /**
+ * Test simulates loading an unwrapped alignment, shrinking it vertically so
+ * not all sequences are visible, then changing to wrapped mode. The ranges
+ * endSeq should be unchanged, but the vertical repeat height should include
+ * all sequences.
+ */
+ @Test(groups = "Functional")
+ public void testCalculateWrappedGeometry_fromScrolled()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+ assertEquals(al.getWidth(), 157);
+ assertEquals(al.getHeight(), 15);
+ av.getRanges().setStartEndSeq(0, 3);
+ av.setShowAnnotation(false);
+ av.setScaleAboveWrapped(true);
+
+ SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
+
+ av.setWrapAlignment(true);
+ av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+ assertEquals(charHeight, 17);
+ assertEquals(charWidth, 12);
+
+ int canvasWidth = 400;
+ int canvasHeight = 300;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+
+ assertEquals(av.getRanges().getEndSeq(), 3); // unchanged
+ int repeatingHeight = (int) PA.getValue(testee,
+ "wrappedRepeatHeightPx");
+ assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
+ }
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
}
static String PfamFile = "examples/PF00111_seed.stk",
- RfamFile = "examples/RF00031_folded.stk";
+ RfamFile = "examples/RF00031_folded.stk",
+ RnaSSTestFile = "examples/rna_ss_test.stk";
@Test(groups = { "Functional" })
public void pfamFileIO() throws Exception
// we might want to revise this in future
int aa_new_size = (aa_new == null ? 0 : aa_new.length);
int aa_original_size = (aa_original == null ? 0 : aa_original.length);
- Map<Integer, BitSet> orig_groups = new HashMap<Integer, BitSet>();
- Map<Integer, BitSet> new_groups = new HashMap<Integer, BitSet>();
+ Map<Integer, BitSet> orig_groups = new HashMap<>();
+ Map<Integer, BitSet> new_groups = new HashMap<>();
if (aa_new != null && aa_original != null)
{
{
for (char ch : new char[] { '{', '}', '[', ']', '(', ')', '<', '>' })
{
- Assert.assertTrue(StockholmFile.DETECT_BRACKETS.matchAt("" + ch, 0),
- "Didn't recognise " + ch + " as a WUSS bracket");
+ Assert.assertTrue(StockholmFile.RNASS_BRACKETS.indexOf(ch) >= 0,
+ "Didn't recognise '" + ch + "' as a WUSS bracket");
}
- for (char ch : new char[] { '@', '!', 'V', 'Q', '*', ' ', '-', '.' })
+ for (char ch : new char[] { '@', '!', '*', ' ', '-', '.' })
{
- Assert.assertFalse(StockholmFile.DETECT_BRACKETS.matchAt("" + ch, 0),
- "Shouldn't recognise " + ch + " as a WUSS bracket");
+ Assert.assertFalse(StockholmFile.RNASS_BRACKETS.indexOf(ch) >= 0,
+ "Shouldn't recognise '" + ch + "' as a WUSS bracket");
}
}
private static void roundTripSSForRNA(String aliFile, String annFile)
testAlignmentEquivalence(al, newAl, true, true, true);
}
+
+ // this is the single sequence alignment and the SS annotations equivalent to
+ // the ones in file RnaSSTestFile
+ String aliFileRnaSS = ">Test.sequence/1-14\n"
+ + "GUACAAAAAAAAAA";
+ String annFileRnaSSAlphaChars = "JALVIEW_ANNOTATION\n"
+ + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n"
+ + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|(,(|E,E|H,H|B,B|h,h|e,e|b,b|(,(|E,E|),)|e,e|),)|>,>|\t2.0\n"
+ + "\n"
+ + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n"
+ + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;";
+ String wrongAnnFileRnaSSAlphaChars = "JALVIEW_ANNOTATION\n"
+ + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n"
+ + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|(,(|H,H|E,E|B,B|h,h|e,e|b,b|(,(|E,E|),)|e,e|),)|>,>|\t2.0\n"
+ + "\n"
+ + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n"
+ + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;";
+ @Test(groups = { "Functional" })
+ public void stockholmFileRnaSSAlphaChars() throws Exception
+ {
+ AppletFormatAdapter af = new AppletFormatAdapter();
+ AlignmentI al = af.readFile(RnaSSTestFile, DataSourceType.FILE,
+ jalview.io.FileFormat.Stockholm);
+ Iterable<AlignmentAnnotation> aai = al.findAnnotations(null, null,
+ "Secondary Structure");
+ AlignmentAnnotation aa = aai.iterator().next();
+ Assert.assertTrue(aa.isRNA(),
+ "'" + RnaSSTestFile + "' not recognised as RNA SS");
+ Assert.assertTrue(aa.isValidStruc(),
+ "'" + RnaSSTestFile + "' not recognised as valid structure");
+ Annotation[] as = aa.annotations;
+ char[] As = new char[as.length];
+ for (int i = 0; i < as.length; i++)
+ {
+ As[i] = as[i].secondaryStructure;
+ }
+ char[] shouldBe = { '<', '(', 'E', 'H', 'B', 'h', 'e', 'b', '(', 'E',
+ ')', 'e', ')', '>' };
+ Assert.assertTrue(
+ Arrays.equals(As, shouldBe),
+ "Annotation is " + new String(As) + " but should be "
+ + new String(shouldBe));
+
+ // this should result in the same RNA SS Annotations
+ AlignmentI newAl = new AppletFormatAdapter().readFile(
+ aliFileRnaSS,
+ DataSourceType.PASTE, jalview.io.FileFormat.Fasta);
+ AnnotationFile aaf = new AnnotationFile();
+ aaf.readAnnotationFile(newAl, annFileRnaSSAlphaChars,
+ DataSourceType.PASTE);
+
+ Assert.assertTrue(
+ testRnaSSAnnotationsEquivalent(al.getAlignmentAnnotation()[0],
+ newAl.getAlignmentAnnotation()[0]),
+ "RNA SS Annotations SHOULD be pair-wise equivalent (but apparently aren't): \n"
+ + "RNA SS A 1:" + al.getAlignmentAnnotation()[0] + "\n"
+ + "RNA SS A 2:" + newAl.getAlignmentAnnotation()[0]);
+
+ // this should NOT result in the same RNA SS Annotations
+ newAl = new AppletFormatAdapter().readFile(
+ aliFileRnaSS, DataSourceType.PASTE,
+ jalview.io.FileFormat.Fasta);
+ aaf = new AnnotationFile();
+ aaf.readAnnotationFile(newAl, wrongAnnFileRnaSSAlphaChars,
+ DataSourceType.PASTE);
+
+ boolean mismatch = testRnaSSAnnotationsEquivalent(al.getAlignmentAnnotation()[0],
+ newAl.getAlignmentAnnotation()[0]);
+ Assert.assertFalse(mismatch,
+ "RNA SS Annotations SHOULD NOT be pair-wise equivalent (but apparently are): \n"
+ + "RNA SS A 1:" + al.getAlignmentAnnotation()[0] + "\n"
+ + "RNA SS A 2:" + newAl.getAlignmentAnnotation()[0]);
+ }
+
+ private static boolean testRnaSSAnnotationsEquivalent(
+ AlignmentAnnotation a1,
+ AlignmentAnnotation a2)
+ {
+ return a1.rnaSecondaryStructureEquivalent(a2);
+ }
+
+ String annFileRnaSSWithSpaceChars = "JALVIEW_ANNOTATION\n"
+ + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n"
+ + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|.,.|H,H| , |B,B|h,h| , |b,b|(,(|E,E|.,.|e,e|),)|>,>|\t2.0\n"
+ + "\n"
+ + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n"
+ + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;";
+ String annFileRnaSSWithoutSpaceChars = "JALVIEW_ANNOTATION\n"
+ + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n"
+ + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|.,.|H,H|.,.|B,B|h,h|.,.|b,b|(,(|E,E|.,.|e,e|),)|>,>|\t2.0\n"
+ + "\n"
+ + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n"
+ + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;";
+
+ String wrongAnnFileRnaSSWithoutSpaceChars = "JALVIEW_ANNOTATION\n"
+ + "# Created: Thu Aug 02 14:54:57 BST 2018\n" + "\n"
+ + "NO_GRAPH\tSecondary Structure\tSecondary Structure\t<,<|.,.|H,H|Z,Z|B,B|h,h|z,z|b,b|(,(|E,E|.,.|e,e|),)|>,>|\t2.0\n"
+ + "\n"
+ + "ROWPROPERTIES\tSecondary Structure\tscaletofit=true\tshowalllabs=true\tcentrelabs=false\n"
+ + "\n" + "\n" + "ALIGNMENT\tID=RNA.SS.TEST\tTP=RNA;";
+
+ @Test(groups = { "Functional" })
+ public void stockholmFileRnaSSSpaceChars() throws Exception
+ {
+ AlignmentI alWithSpaces = new AppletFormatAdapter().readFile(
+ aliFileRnaSS, DataSourceType.PASTE,
+ jalview.io.FileFormat.Fasta);
+ AnnotationFile afWithSpaces = new AnnotationFile();
+ afWithSpaces.readAnnotationFile(alWithSpaces,
+ annFileRnaSSWithSpaceChars, DataSourceType.PASTE);
+
+ Iterable<AlignmentAnnotation> aaiWithSpaces = alWithSpaces
+ .findAnnotations(null, null, "Secondary Structure");
+ AlignmentAnnotation aaWithSpaces = aaiWithSpaces.iterator().next();
+ Assert.assertTrue(aaWithSpaces.isRNA(),
+ "'" + aaWithSpaces + "' not recognised as RNA SS");
+ Assert.assertTrue(aaWithSpaces.isValidStruc(),
+ "'" + aaWithSpaces + "' not recognised as valid structure");
+ Annotation[] annWithSpaces = aaWithSpaces.annotations;
+ char[] As = new char[annWithSpaces.length];
+ for (int i = 0; i < annWithSpaces.length; i++)
+ {
+ As[i] = annWithSpaces[i].secondaryStructure;
+ }
+ // check all spaces and dots are spaces in the internal representation
+ char[] shouldBe = { '<', ' ', 'H', ' ', 'B', 'h', ' ', 'b', '(', 'E',
+ ' ', 'e', ')', '>' };
+ Assert.assertTrue(Arrays.equals(As, shouldBe), "Annotation is "
+ + new String(As) + " but should be " + new String(shouldBe));
+
+ // this should result in the same RNA SS Annotations
+ AlignmentI alWithoutSpaces = new AppletFormatAdapter().readFile(
+ aliFileRnaSS, DataSourceType.PASTE,
+ jalview.io.FileFormat.Fasta);
+ AnnotationFile afWithoutSpaces = new AnnotationFile();
+ afWithoutSpaces.readAnnotationFile(alWithoutSpaces,
+ annFileRnaSSWithoutSpaceChars,
+ DataSourceType.PASTE);
+
+ Assert.assertTrue(
+ testRnaSSAnnotationsEquivalent(
+ alWithSpaces.getAlignmentAnnotation()[0],
+ alWithoutSpaces.getAlignmentAnnotation()[0]),
+ "RNA SS Annotations SHOULD be pair-wise equivalent (but apparently aren't): \n"
+ + "RNA SS A 1:"
+ + alWithSpaces.getAlignmentAnnotation()[0]
+ .getRnaSecondaryStructure()
+ + "\n" + "RNA SS A 2:"
+ + alWithoutSpaces.getAlignmentAnnotation()[0]
+ .getRnaSecondaryStructure());
+
+ // this should NOT result in the same RNA SS Annotations
+ AlignmentI wrongAlWithoutSpaces = new AppletFormatAdapter().readFile(
+ aliFileRnaSS, DataSourceType.PASTE,
+ jalview.io.FileFormat.Fasta);
+ AnnotationFile wrongAfWithoutSpaces = new AnnotationFile();
+ wrongAfWithoutSpaces.readAnnotationFile(wrongAlWithoutSpaces,
+ wrongAnnFileRnaSSWithoutSpaceChars,
+ DataSourceType.PASTE);
+
+ Assert.assertFalse(
+ testRnaSSAnnotationsEquivalent(
+ alWithSpaces.getAlignmentAnnotation()[0],
+ wrongAlWithoutSpaces.getAlignmentAnnotation()[0]),
+ "RNA SS Annotations SHOULD NOT be pair-wise equivalent (but apparently are): \n"
+ + "RNA SS A 1:"
+ + alWithSpaces.getAlignmentAnnotation()[0]
+ .getRnaSecondaryStructure()
+ + "\n" + "RNA SS A 2:"
+ + wrongAlWithoutSpaces.getAlignmentAnnotation()[0]
+ .getRnaSecondaryStructure());
+
+ // check no spaces in the output
+ // TODO: create a better 'save as <format>' pattern
+ alWithSpaces.getAlignmentAnnotation()[0].visible = true;
+ StockholmFile sf = new StockholmFile(alWithSpaces);
+
+ String stockholmFile = sf.print(alWithSpaces.getSequencesArray(), true);
+ Pattern noSpacesInRnaSSAnnotation = Pattern
+ .compile("\\n#=GC SS_cons\\s+\\S{14}\\n");
+ Matcher m = noSpacesInRnaSSAnnotation.matcher(stockholmFile);
+ boolean matches = m.find();
+ Assert.assertTrue(matches,
+ "StockholmFile output does not contain expected output (may contain spaces):\n"
+ + stockholmFile);
+
+ }
}
import java.io.StringReader;
import java.util.Vector;
+import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+ "<feature type=\"sequence variant\"><original>M</original><variation>L</variation><location><position position=\"41\"/></location></feature>"
+ "<feature type=\"sequence variant\" description=\"Pathogenic\"><original>M</original><variation>L</variation><location><position position=\"41\"/></location></feature>"
+ "<feature type=\"sequence variant\" description=\"Pathogenic\"><original>M</original><location><position position=\"41\"/></location></feature>"
+ + "<feature type=\"sequence variant\" description=\"Foo\"><variation>L</variation><variation>LMV</variation><original>M</original><location><position position=\"42\"/></location></feature>"
+ + "<feature type=\"sequence variant\" description=\"Foo\"><variation>LL</variation><variation>LMV</variation><original>ML</original><location><begin position=\"42\"/><end position=\"43\"/></location></feature>"
+ + "<feature type=\"sequence variant\" description=\"Foo Too\"><variation>LL</variation><variation>LMVK</variation><original>MLML</original><location><begin position=\"42\"/><end position=\"45\"/></location></feature>"
+ "<sequence length=\"10\" mass=\"27410\" checksum=\"8CB760AACF88FE6C\" modified=\"2008-01-15\" version=\"1\">MHAPL VSKDL</sequence></entry>"
+ "</uniprot>";
* Check sequence features
*/
Vector<UniprotFeature> features = entry.getFeature();
- assertEquals(6, features.size());
+ assertEquals(9, features.size());
UniprotFeature sf = features.get(0);
assertEquals("signal peptide", sf.getType());
assertNull(sf.getDescription());
sf = features.get(3);
assertEquals("sequence variant", sf.getType());
- assertEquals("Variation: 'L' Original: 'M'", sf.getDescription());
+ assertNull(sf.getDescription());
assertEquals(41, sf.getPosition());
assertEquals(41, sf.getBegin());
assertEquals(41, sf.getEnd());
sf = features.get(4);
assertEquals("sequence variant", sf.getType());
- assertEquals("Pathogenic Variation: 'L' Original: 'M'",
- sf.getDescription());
+ assertEquals("Pathogenic", sf.getDescription());
assertEquals(41, sf.getPosition());
assertEquals(41, sf.getBegin());
assertEquals(41, sf.getEnd());
sf = features.get(5);
assertEquals("sequence variant", sf.getType());
- assertEquals("Pathogenic Original: 'M'", sf.getDescription());
+ assertEquals("Pathogenic", sf.getDescription());
assertEquals(41, sf.getPosition());
assertEquals(41, sf.getBegin());
assertEquals(41, sf.getEnd());
+
+ sf = features.get(6);
+ assertEquals("sequence variant", sf.getType());
+ assertEquals("Foo",
+ sf.getDescription());
+ assertEquals(42, sf.getPosition());
+ assertEquals(42, sf.getBegin());
+ assertEquals(42, sf.getEnd());
+ Assert.assertEquals(Uniprot.getDescription(sf),
+ "<html>p.Met42Leu" + "<br/> "
+ + "p.Met42LeuMetVal Foo</html>");
+
+ sf = features.get(7);
+ assertEquals(42, sf.getBegin());
+ assertEquals(43, sf.getEnd());
+ Assert.assertEquals(Uniprot.getDescription(sf),
+ "<html>p.MetLeu42LeuLeu" + "<br/> "
+ + "p.MetLeu42LeuMetVal Foo</html>");
+
+ sf = features.get(8);
+ assertEquals(42, sf.getBegin());
+ assertEquals(45, sf.getEnd());
+ Assert.assertEquals(Uniprot.getDescription(sf),
+ "<html>p.MLML42LeuLeu" + "<br/> "
+ + "p.MLML42LMVK Foo Too</html>");
+
/*
* Check cross-references
*/
assertEquals(expectedDescription,
Uniprot.getUniprotEntryDescription(entry));
}
+
+ @Test(groups = { "Functional" })
+ public void testGetDescription()
+ {
+ UniprotFeature uf = new UniprotFeature();
+ assertEquals("", Uniprot.getDescription(uf));
+
+ uf.setDescription("Hello");
+ assertEquals("Hello", Uniprot.getDescription(uf));
+
+ uf.setPosition(23);
+ uf.setOriginal("K");
+ Vector<String> vars = new Vector<>();
+ vars.add("y");
+ uf.setVariation(vars);
+ assertEquals("p.Lys23Tyr Hello", Uniprot.getDescription(uf));
+
+ // multiple variants generate an html description over more than one line
+ vars.add("W");
+ assertEquals("<html>p.Lys23Tyr<br/> p.Lys23Trp Hello</html>",
+ Uniprot.getDescription(uf));
+
+ /*
+ * indel cases
+ * up to 3 bases (original or variant) are shown using 3 letter code
+ */
+ vars.clear();
+ vars.add("KWE");
+ uf.setOriginal("KLS");
+ assertEquals("p.LysLeuSer23LysTrpGlu Hello",
+ Uniprot.getDescription(uf));
+
+ // adding a fourth original base switches to single letter code
+ uf.setOriginal("KLST");
+ assertEquals("p.KLST23LysTrpGlu Hello", Uniprot.getDescription(uf));
+
+ // adding a fourth variant switches to single letter code
+ vars.clear();
+ vars.add("KWES");
+ assertEquals("p.KLST23KWES Hello", Uniprot.getDescription(uf));
+
+ vars.clear();
+ vars.add("z"); // unknown variant - fails gracefully
+ uf.setOriginal("K");
+ assertEquals("p.Lys23z Hello", Uniprot.getDescription(uf));
+
+ uf.setVariation(null); // variant missing - is ignored
+ assertEquals("Hello", Uniprot.getDescription(uf));
+ }
}
<method name="addElement">
<object class="com.zerog.ia.installer.util.LAXPropertyData" objectID="97fa91cfa6f7">
<property name="propertyValue">
- <string><![CDATA[268400000]]></string>
+ <string><![CDATA[1060000000]]></string>
</property>
<property name="propertyName">
<string><![CDATA[lax.nl.java.option.java.heap.size.max]]></string>
<method name="addElement">
<object class="com.zerog.ia.installer.util.LAXPropertyData" objectID="97f991ffa6f7">
<property name="propertyValue">
- <string><![CDATA[33554432]]></string>
+ <string><![CDATA[1000000000]]></string>
</property>
<property name="propertyName">
<string><![CDATA[lax.nl.java.option.java.heap.size.initial]]></string>
<string><![CDATA[664]]></string>
</property>
<property name="sourceName">
- <string><![CDATA[VAqua4.jar]]></string>
+ <string><![CDATA[VAqua5-patch.jar]]></string>
</property>
<property name="overrideUnixPermissions">
<boolean>false</boolean>
<boolean>true</boolean>
</property>
<property name="destinationName">
- <string><![CDATA[VAqua4.jar]]></string>
+ <string><![CDATA[VAqua5-patch.jar]]></string>
</property>
<property name="fileSize">
- <long>1355141</long>
+ <long>1370564</long>
</property>
<property name="macBinary">
<boolean>false</boolean>
To run application:
-java -Djava.ext.dirs=JALVIEW_HOME/lib -jar JALVIEW_HOME/jalview.jar [-help ... ]
+java -classpath "JALVIEW_HOME/lib/*" -jar JALVIEW_HOME/jalview.jar [-help ... ]
Replace JALVIEW_HOME with the full path to Jalview Installation Directory.
Use -help to see the available command line arguments.
For best results use a Sun java run time environment (not the gcj gnu java, sorry!).
-If you want to the java runtime bundled with Jalview, then launch jalview like this:
+If you want to use the java runtime bundled with Jalview, then launch jalview like this:
-JAVA_HOME=JALVIEW_HOME/jre JALVIEW_HOME/jre/bin/java -Djava.ext.dirs=JALVIEW_HOME/lib -jar JALVIEW_HOME/jalview.jar
+in Windows:
+JAVA_HOME=JALVIEW_HOME/jre JALVIEW_HOME/jre/bin/java -classpath "JALVIEW_HOME/lib/*;JALVIEW_HOME/jalview.jar" jalview.bin.Jalview
+
+in Linux:
+JAVA_HOME=JALVIEW_HOME/jre JALVIEW_HOME/jre/bin/java -classpath "JALVIEW_HOME/lib/*:JALVIEW_HOME/jalview.jar" jalview.bin.Jalview
+
+in macOS:
+JAVA_HOME=JALVIEW_HOME/jre/Contents/Home JALVIEW_HOME/jre/Contents/Home/bin/java -classpath "JALVIEW_HOME/lib/*:JALVIEW_HOME/jalview.jar" jalview.bin.Jalview
+
+Note: ensure the -classpath argument is quoted and only use a terminating wildcard (e.g. 'DIR/*') to refer to all jar files in a directory, don't use e.g. 'DIR/*.jar'
-Please Note: the -jar jalview.jar option launches the jalview.bin.Jalview class in the jalview.jar
##################